atheros: put atheros wireless drivers into ath/
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Tue, 31 Mar 2009 02:30:33 +0000 (22:30 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 22 Apr 2009 20:54:38 +0000 (16:54 -0400)
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
134 files changed:
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/ar9170/Kconfig [deleted file]
drivers/net/wireless/ar9170/Makefile [deleted file]
drivers/net/wireless/ar9170/ar9170.h [deleted file]
drivers/net/wireless/ar9170/cmd.c [deleted file]
drivers/net/wireless/ar9170/cmd.h [deleted file]
drivers/net/wireless/ar9170/eeprom.h [deleted file]
drivers/net/wireless/ar9170/hw.h [deleted file]
drivers/net/wireless/ar9170/led.c [deleted file]
drivers/net/wireless/ar9170/mac.c [deleted file]
drivers/net/wireless/ar9170/main.c [deleted file]
drivers/net/wireless/ar9170/phy.c [deleted file]
drivers/net/wireless/ar9170/usb.c [deleted file]
drivers/net/wireless/ar9170/usb.h [deleted file]
drivers/net/wireless/ath/Kconfig
drivers/net/wireless/ath/Makefile
drivers/net/wireless/ath/ar9170/Kconfig [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/Makefile [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/ar9170.h [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/cmd.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/cmd.h [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/eeprom.h [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/hw.h [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/led.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/mac.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/main.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/phy.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/usb.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/usb.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/Kconfig [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/Makefile [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/ath5k.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/attach.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/base.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/base.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/caps.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/debug.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/debug.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/desc.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/desc.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/dma.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/eeprom.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/eeprom.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/gpio.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/initvals.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/led.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/pcu.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/phy.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/qcu.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/reg.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/reset.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/rfbuffer.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/rfgain.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/Kconfig [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/Makefile [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ahb.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ani.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ani.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ath9k.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/beacon.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/calib.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/calib.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/debug.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/debug.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/eeprom.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/eeprom.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/hw.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/hw.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/initvals.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/mac.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/mac.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/main.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/pci.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/phy.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/phy.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/rc.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/rc.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/recv.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/reg.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/virtual.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/xmit.c [new file with mode: 0644]
drivers/net/wireless/ath5k/Kconfig [deleted file]
drivers/net/wireless/ath5k/Makefile [deleted file]
drivers/net/wireless/ath5k/ath5k.h [deleted file]
drivers/net/wireless/ath5k/attach.c [deleted file]
drivers/net/wireless/ath5k/base.c [deleted file]
drivers/net/wireless/ath5k/base.h [deleted file]
drivers/net/wireless/ath5k/caps.c [deleted file]
drivers/net/wireless/ath5k/debug.c [deleted file]
drivers/net/wireless/ath5k/debug.h [deleted file]
drivers/net/wireless/ath5k/desc.c [deleted file]
drivers/net/wireless/ath5k/desc.h [deleted file]
drivers/net/wireless/ath5k/dma.c [deleted file]
drivers/net/wireless/ath5k/eeprom.c [deleted file]
drivers/net/wireless/ath5k/eeprom.h [deleted file]
drivers/net/wireless/ath5k/gpio.c [deleted file]
drivers/net/wireless/ath5k/initvals.c [deleted file]
drivers/net/wireless/ath5k/led.c [deleted file]
drivers/net/wireless/ath5k/pcu.c [deleted file]
drivers/net/wireless/ath5k/phy.c [deleted file]
drivers/net/wireless/ath5k/qcu.c [deleted file]
drivers/net/wireless/ath5k/reg.h [deleted file]
drivers/net/wireless/ath5k/reset.c [deleted file]
drivers/net/wireless/ath5k/rfbuffer.h [deleted file]
drivers/net/wireless/ath5k/rfgain.h [deleted file]
drivers/net/wireless/ath9k/Kconfig [deleted file]
drivers/net/wireless/ath9k/Makefile [deleted file]
drivers/net/wireless/ath9k/ahb.c [deleted file]
drivers/net/wireless/ath9k/ani.c [deleted file]
drivers/net/wireless/ath9k/ani.h [deleted file]
drivers/net/wireless/ath9k/ath9k.h [deleted file]
drivers/net/wireless/ath9k/beacon.c [deleted file]
drivers/net/wireless/ath9k/calib.c [deleted file]
drivers/net/wireless/ath9k/calib.h [deleted file]
drivers/net/wireless/ath9k/debug.c [deleted file]
drivers/net/wireless/ath9k/debug.h [deleted file]
drivers/net/wireless/ath9k/eeprom.c [deleted file]
drivers/net/wireless/ath9k/eeprom.h [deleted file]
drivers/net/wireless/ath9k/hw.c [deleted file]
drivers/net/wireless/ath9k/hw.h [deleted file]
drivers/net/wireless/ath9k/initvals.h [deleted file]
drivers/net/wireless/ath9k/mac.c [deleted file]
drivers/net/wireless/ath9k/mac.h [deleted file]
drivers/net/wireless/ath9k/main.c [deleted file]
drivers/net/wireless/ath9k/pci.c [deleted file]
drivers/net/wireless/ath9k/phy.c [deleted file]
drivers/net/wireless/ath9k/phy.h [deleted file]
drivers/net/wireless/ath9k/rc.c [deleted file]
drivers/net/wireless/ath9k/rc.h [deleted file]
drivers/net/wireless/ath9k/recv.c [deleted file]
drivers/net/wireless/ath9k/reg.h [deleted file]
drivers/net/wireless/ath9k/virtual.c [deleted file]
drivers/net/wireless/ath9k/xmit.c [deleted file]

index 9e2c7e2..8f279e7 100644 (file)
@@ -484,9 +484,6 @@ config MWL8K
 
 source "drivers/net/wireless/p54/Kconfig"
 source "drivers/net/wireless/ath/Kconfig"
-source "drivers/net/wireless/ath5k/Kconfig"
-source "drivers/net/wireless/ath9k/Kconfig"
-source "drivers/net/wireless/ar9170/Kconfig"
 source "drivers/net/wireless/ipw2x00/Kconfig"
 source "drivers/net/wireless/iwlwifi/Kconfig"
 source "drivers/net/wireless/hostap/Kconfig"
index 104639e..0625e91 100644 (file)
@@ -56,8 +56,5 @@ obj-$(CONFIG_RT2X00)  += rt2x00/
 obj-$(CONFIG_P54_COMMON)       += p54/
 
 obj-$(CONFIG_ATH_COMMON)       += ath/
-obj-$(CONFIG_ATH5K)    += ath5k/
-obj-$(CONFIG_ATH9K)    += ath9k/
-obj-$(CONFIG_AR9170_USB)       += ar9170/
 
 obj-$(CONFIG_MAC80211_HWSIM)   += mac80211_hwsim.o
diff --git a/drivers/net/wireless/ar9170/Kconfig b/drivers/net/wireless/ar9170/Kconfig
deleted file mode 100644 (file)
index b99e326..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-config AR9170_USB
-       tristate "Atheros AR9170 802.11n USB support"
-       depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
-       select FW_LOADER
-       select ATH_COMMON
-       help
-         This is a driver for the Atheros "otus" 802.11n USB devices.
-
-         These devices require additional firmware (2 files).
-         For now, these files can be downloaded from here:
-         http://wireless.kernel.org/en/users/Drivers/ar9170
-
-         If you choose to build a module, it'll be called ar9170usb.
-
-config AR9170_LEDS
-       bool
-       depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
-       default y
diff --git a/drivers/net/wireless/ar9170/Makefile b/drivers/net/wireless/ar9170/Makefile
deleted file mode 100644 (file)
index 8d91c7e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
-
-obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff --git a/drivers/net/wireless/ar9170/ar9170.h b/drivers/net/wireless/ar9170/ar9170.h
deleted file mode 100644 (file)
index 87c1985..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Driver specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 __AR9170_H
-#define __AR9170_H
-
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <net/wireless.h>
-#include <net/mac80211.h>
-#ifdef CONFIG_AR9170_LEDS
-#include <linux/leds.h>
-#endif /* CONFIG_AR9170_LEDS */
-#include "eeprom.h"
-#include "hw.h"
-
-#include "../ath/regd.h"
-
-#define PAYLOAD_MAX    (AR9170_MAX_CMD_LEN/4 - 1)
-
-enum ar9170_bw {
-       AR9170_BW_20,
-       AR9170_BW_40_BELOW,
-       AR9170_BW_40_ABOVE,
-
-       __AR9170_NUM_BW,
-};
-
-enum ar9170_rf_init_mode {
-       AR9170_RFI_NONE,
-       AR9170_RFI_WARM,
-       AR9170_RFI_COLD,
-};
-
-#define AR9170_MAX_RX_BUFFER_SIZE              8192
-
-#ifdef CONFIG_AR9170_LEDS
-struct ar9170;
-
-struct ar9170_led {
-       struct ar9170 *ar;
-       struct led_classdev l;
-       char name[32];
-       unsigned int toggled;
-       bool registered;
-};
-
-#endif /* CONFIG_AR9170_LEDS */
-
-enum ar9170_device_state {
-       AR9170_UNKNOWN_STATE,
-       AR9170_STOPPED,
-       AR9170_IDLE,
-       AR9170_STARTED,
-       AR9170_ASSOCIATED,
-};
-
-struct ar9170 {
-       struct ieee80211_hw *hw;
-       struct mutex mutex;
-       enum ar9170_device_state state;
-
-       int (*open)(struct ar9170 *);
-       void (*stop)(struct ar9170 *);
-       int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int);
-       int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
-                       void *, u32 , void *);
-       void (*callback_cmd)(struct ar9170 *, u32 , void *);
-
-       /* interface mode settings */
-       struct ieee80211_vif *vif;
-       u8 mac_addr[ETH_ALEN];
-       u8 bssid[ETH_ALEN];
-
-       /* beaconing */
-       struct sk_buff *beacon;
-       struct work_struct beacon_work;
-
-       /* cryptographic engine */
-       u64 usedkeys;
-       bool rx_software_decryption;
-       bool disable_offload;
-
-       /* filter settings */
-       struct work_struct filter_config_work;
-       u64 cur_mc_hash, want_mc_hash;
-       u32 cur_filter, want_filter;
-       unsigned int filter_changed;
-       bool sniffer_enabled;
-
-       /* PHY */
-       struct ieee80211_channel *channel;
-       int noise[4];
-
-       /* power calibration data */
-       u8 power_5G_leg[4];
-       u8 power_2G_cck[4];
-       u8 power_2G_ofdm[4];
-       u8 power_5G_ht20[8];
-       u8 power_5G_ht40[8];
-       u8 power_2G_ht20[8];
-       u8 power_2G_ht40[8];
-
-#ifdef CONFIG_AR9170_LEDS
-       struct delayed_work led_work;
-       struct ar9170_led leds[AR9170_NUM_LEDS];
-#endif /* CONFIG_AR9170_LEDS */
-
-       /* qos queue settings */
-       spinlock_t tx_stats_lock;
-       struct ieee80211_tx_queue_stats tx_stats[5];
-       struct ieee80211_tx_queue_params edcf[5];
-
-       spinlock_t cmdlock;
-       __le32 cmdbuf[PAYLOAD_MAX + 1];
-
-       /* MAC statistics */
-       struct ieee80211_low_level_stats stats;
-
-       /* EEPROM */
-       struct ar9170_eeprom eeprom;
-       struct ath_regulatory regulatory;
-
-       /* global tx status for unregistered Stations. */
-       struct sk_buff_head global_tx_status;
-       struct sk_buff_head global_tx_status_waste;
-       struct delayed_work tx_status_janitor;
-};
-
-struct ar9170_sta_info {
-       struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
-};
-
-#define IS_STARTED(a)          (a->state >= AR9170_STARTED)
-#define IS_ACCEPTING_CMD(a)    (a->state >= AR9170_IDLE)
-
-#define AR9170_FILTER_CHANGED_PROMISC          BIT(0)
-#define AR9170_FILTER_CHANGED_MULTICAST                BIT(1)
-#define AR9170_FILTER_CHANGED_FRAMEFILTER      BIT(2)
-
-/* exported interface */
-void *ar9170_alloc(size_t priv_size);
-int ar9170_register(struct ar9170 *ar, struct device *pdev);
-void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
-void ar9170_unregister(struct ar9170 *ar);
-void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
-                            bool update_statistics, u16 tx_status);
-
-/* MAC */
-int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-int ar9170_init_mac(struct ar9170 *ar);
-int ar9170_set_qos(struct ar9170 *ar);
-int ar9170_update_multicast(struct ar9170 *ar);
-int ar9170_update_frame_filter(struct ar9170 *ar);
-int ar9170_set_operating_mode(struct ar9170 *ar);
-int ar9170_set_beacon_timers(struct ar9170 *ar);
-int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
-int ar9170_update_beacon(struct ar9170 *ar);
-void ar9170_new_beacon(struct work_struct *work);
-int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
-                     u8 keyidx, u8 *keydata, int keylen);
-int ar9170_disable_key(struct ar9170 *ar, u8 id);
-
-/* LEDs */
-#ifdef CONFIG_AR9170_LEDS
-int ar9170_register_leds(struct ar9170 *ar);
-void ar9170_unregister_leds(struct ar9170 *ar);
-#endif /* CONFIG_AR9170_LEDS */
-int ar9170_init_leds(struct ar9170 *ar);
-int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
-
-/* PHY / RF */
-int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
-int ar9170_init_rf(struct ar9170 *ar);
-int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
-                      enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
-
-#endif /* __AR9170_H */
diff --git a/drivers/net/wireless/ar9170/cmd.c b/drivers/net/wireless/ar9170/cmd.c
deleted file mode 100644 (file)
index f57a620..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Basic HW register/memory/command access functions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 "ar9170.h"
-#include "cmd.h"
-
-int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
-{
-       int err;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return 0;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
-       if (err)
-               printk(KERN_DEBUG "%s: writing memory failed\n",
-                      wiphy_name(ar->hw->wiphy));
-       return err;
-}
-
-int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
-{
-       __le32 buf[2] = {
-               cpu_to_le32(reg),
-               cpu_to_le32(val),
-       };
-       int err;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return 0;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
-                          (u8 *) buf, 0, NULL);
-       if (err)
-               printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n",
-                      wiphy_name(ar->hw->wiphy), reg, val);
-       return err;
-}
-
-static int ar9170_read_mreg(struct ar9170 *ar, int nregs,
-                           const u32 *regs, u32 *out)
-{
-       int i, err;
-       __le32 *offs, *res;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return 0;
-
-       /* abuse "out" for the register offsets, must be same length */
-       offs = (__le32 *)out;
-       for (i = 0; i < nregs; i++)
-               offs[i] = cpu_to_le32(regs[i]);
-
-       /* also use the same buffer for the input */
-       res = (__le32 *)out;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_RREG,
-                          4 * nregs, (u8 *)offs,
-                          4 * nregs, (u8 *)res);
-       if (err)
-               return err;
-
-       /* convert result to cpu endian */
-       for (i = 0; i < nregs; i++)
-               out[i] = le32_to_cpu(res[i]);
-
-       return 0;
-}
-
-int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
-{
-       return ar9170_read_mreg(ar, 1, &reg, val);
-}
-
-int ar9170_echo_test(struct ar9170 *ar, u32 v)
-{
-       __le32 echobuf = cpu_to_le32(v);
-       __le32 echores;
-       int err;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return -ENODEV;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
-                          4, (u8 *)&echobuf,
-                          4, (u8 *)&echores);
-       if (err)
-               return err;
-
-       if (echobuf != echores)
-               return -EINVAL;
-
-       return 0;
-}
diff --git a/drivers/net/wireless/ar9170/cmd.h b/drivers/net/wireless/ar9170/cmd.h
deleted file mode 100644 (file)
index a4f0e50..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Basic HW register/memory/command access functions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 __CMD_H
-#define __CMD_H
-
-#include "ar9170.h"
-
-/* basic HW access */
-int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
-int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
-int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
-int ar9170_echo_test(struct ar9170 *ar, u32 v);
-
-/*
- * Macros to facilitate writing multiple registers in a single
- * write-combining USB command. Note that when the first group
- * fails the whole thing will fail without any others attempted,
- * but you won't know which write in the group failed.
- */
-#define ar9170_regwrite_begin(ar)                                      \
-do {                                                                   \
-       int __nreg = 0, __err = 0;                                      \
-       struct ar9170 *__ar = ar;
-
-#define ar9170_regwrite(r, v) do {                                     \
-       __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r);                  \
-       __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v);                  \
-       __nreg++;                                                       \
-       if ((__nreg >= PAYLOAD_MAX/2)) {                                \
-               if (IS_ACCEPTING_CMD(__ar))                             \
-                       __err = ar->exec_cmd(__ar, AR9170_CMD_WREG,     \
-                                            8 * __nreg,                \
-                                            (u8 *) &__ar->cmdbuf[1],   \
-                                            0, NULL);                  \
-               __nreg = 0;                                             \
-               if (__err)                                              \
-                       goto __regwrite_out;                            \
-       }                                                               \
-} while (0)
-
-#define ar9170_regwrite_finish()                                       \
-__regwrite_out :                                                       \
-       if (__nreg) {                                                   \
-               if (IS_ACCEPTING_CMD(__ar))                             \
-                       __err = ar->exec_cmd(__ar, AR9170_CMD_WREG,     \
-                                            8 * __nreg,                \
-                                            (u8 *) &__ar->cmdbuf[1],   \
-                                            0, NULL);                  \
-               __nreg = 0;                                             \
-       }
-
-#define ar9170_regwrite_result()                                       \
-       __err;                                                          \
-} while (0);
-
-#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ar9170/eeprom.h b/drivers/net/wireless/ar9170/eeprom.h
deleted file mode 100644 (file)
index d2c8cc8..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * EEPROM layout
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 __AR9170_EEPROM_H
-#define __AR9170_EEPROM_H
-
-#define AR5416_MAX_CHAINS              2
-#define AR5416_MODAL_SPURS             5
-
-struct ar9170_eeprom_modal {
-       __le32  antCtrlChain[AR5416_MAX_CHAINS];
-       __le32  antCtrlCommon;
-       s8      antennaGainCh[AR5416_MAX_CHAINS];
-       u8      switchSettling;
-       u8      txRxAttenCh[AR5416_MAX_CHAINS];
-       u8      rxTxMarginCh[AR5416_MAX_CHAINS];
-       s8      adcDesiredSize;
-       s8      pgaDesiredSize;
-       u8      xlnaGainCh[AR5416_MAX_CHAINS];
-       u8      txEndToXpaOff;
-       u8      txEndToRxOn;
-       u8      txFrameToXpaOn;
-       u8      thresh62;
-       s8      noiseFloorThreshCh[AR5416_MAX_CHAINS];
-       u8      xpdGain;
-       u8      xpd;
-       s8      iqCalICh[AR5416_MAX_CHAINS];
-       s8      iqCalQCh[AR5416_MAX_CHAINS];
-       u8      pdGainOverlap;
-       u8      ob;
-       u8      db;
-       u8      xpaBiasLvl;
-       u8      pwrDecreaseFor2Chain;
-       u8      pwrDecreaseFor3Chain;
-       u8      txFrameToDataStart;
-       u8      txFrameToPaOn;
-       u8      ht40PowerIncForPdadc;
-       u8      bswAtten[AR5416_MAX_CHAINS];
-       u8      bswMargin[AR5416_MAX_CHAINS];
-       u8      swSettleHt40;
-       u8      reserved[22];
-       struct spur_channel {
-               __le16 spurChan;
-               u8      spurRangeLow;
-               u8      spurRangeHigh;
-       } __packed spur_channels[AR5416_MODAL_SPURS];
-} __packed;
-
-#define AR5416_NUM_PD_GAINS            4
-#define AR5416_PD_GAIN_ICEPTS          5
-
-struct ar9170_calibration_data_per_freq {
-       u8      pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-       u8      vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-} __packed;
-
-#define AR5416_NUM_5G_CAL_PIERS                8
-#define AR5416_NUM_2G_CAL_PIERS                4
-
-#define AR5416_NUM_5G_TARGET_PWRS      8
-#define AR5416_NUM_2G_CCK_TARGET_PWRS  3
-#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4
-#define AR5416_MAX_NUM_TGT_PWRS                8
-
-struct ar9170_calibration_target_power_legacy {
-       u8      freq;
-       u8      power[4];
-} __packed;
-
-struct ar9170_calibration_target_power_ht {
-       u8      freq;
-       u8      power[8];
-} __packed;
-
-#define AR5416_NUM_CTLS                        24
-
-struct ar9170_calctl_edges {
-       u8      channel;
-#define AR9170_CALCTL_EDGE_FLAGS       0xC0
-       u8      power_flags;
-} __packed;
-
-#define AR5416_NUM_BAND_EDGES          8
-
-struct ar9170_calctl_data {
-       struct ar9170_calctl_edges
-               control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
-} __packed;
-
-
-struct ar9170_eeprom {
-       __le16  length;
-       __le16  checksum;
-       __le16  version;
-       u8      operating_flags;
-#define AR9170_OPFLAG_5GHZ             1
-#define AR9170_OPFLAG_2GHZ             2
-       u8      misc;
-       __le16  reg_domain[2];
-       u8      mac_address[6];
-       u8      rx_mask;
-       u8      tx_mask;
-       __le16  rf_silent;
-       __le16  bluetooth_options;
-       __le16  device_capabilities;
-       __le32  build_number;
-       u8      deviceType;
-       u8      reserved[33];
-
-       u8      customer_data[64];
-
-       struct ar9170_eeprom_modal
-               modal_header[2];
-
-       u8      cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
-       u8      cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
-
-       struct ar9170_calibration_data_per_freq
-               cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
-               cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
-
-       /* power calibration data */
-       struct ar9170_calibration_target_power_legacy
-               cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
-       struct ar9170_calibration_target_power_ht
-               cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
-               cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
-
-       struct ar9170_calibration_target_power_legacy
-               cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
-               cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
-       struct ar9170_calibration_target_power_ht
-               cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
-               cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
-
-       /* conformance testing limits */
-       u8      ctl_index[AR5416_NUM_CTLS];
-       struct ar9170_calctl_data
-               ctl_data[AR5416_NUM_CTLS];
-
-       u8      pad;
-       __le16  subsystem_id;
-} __packed;
-
-#endif /* __AR9170_EEPROM_H */
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ar9170/hw.h
deleted file mode 100644 (file)
index 53e250a..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Hardware-specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 __AR9170_HW_H
-#define __AR9170_HW_H
-
-#define AR9170_MAX_CMD_LEN     64
-
-enum ar9170_cmd {
-       AR9170_CMD_RREG         = 0x00,
-       AR9170_CMD_WREG         = 0x01,
-       AR9170_CMD_RMEM         = 0x02,
-       AR9170_CMD_WMEM         = 0x03,
-       AR9170_CMD_BITAND       = 0x04,
-       AR9170_CMD_BITOR        = 0x05,
-       AR9170_CMD_EKEY         = 0x28,
-       AR9170_CMD_DKEY         = 0x29,
-       AR9170_CMD_FREQUENCY    = 0x30,
-       AR9170_CMD_RF_INIT      = 0x31,
-       AR9170_CMD_SYNTH        = 0x32,
-       AR9170_CMD_FREQ_START   = 0x33,
-       AR9170_CMD_ECHO         = 0x80,
-       AR9170_CMD_TALLY        = 0x81,
-       AR9170_CMD_TALLY_APD    = 0x82,
-       AR9170_CMD_CONFIG       = 0x83,
-       AR9170_CMD_RESET        = 0x90,
-       AR9170_CMD_DKRESET      = 0x91,
-       AR9170_CMD_DKTX_STATUS  = 0x92,
-       AR9170_CMD_FDC          = 0xA0,
-       AR9170_CMD_WREEPROM     = 0xB0,
-       AR9170_CMD_WFLASH       = 0xB0,
-       AR9170_CMD_FLASH_ERASE  = 0xB1,
-       AR9170_CMD_FLASH_PROG   = 0xB2,
-       AR9170_CMD_FLASH_CHKSUM = 0xB3,
-       AR9170_CMD_FLASH_READ   = 0xB4,
-       AR9170_CMD_FW_DL_INIT   = 0xB5,
-       AR9170_CMD_MEM_WREEPROM = 0xBB,
-};
-
-/* endpoints */
-#define AR9170_EP_TX                           1
-#define AR9170_EP_RX                           2
-#define AR9170_EP_IRQ                          3
-#define AR9170_EP_CMD                          4
-
-#define AR9170_EEPROM_START                    0x1600
-
-#define AR9170_GPIO_REG_BASE                   0x1d0100
-#define AR9170_GPIO_REG_PORT_TYPE              AR9170_GPIO_REG_BASE
-#define AR9170_GPIO_REG_DATA                   (AR9170_GPIO_REG_BASE + 4)
-#define AR9170_NUM_LEDS                                2
-
-
-#define AR9170_USB_REG_BASE                    0x1e1000
-#define AR9170_USB_REG_DMA_CTL                 (AR9170_USB_REG_BASE + 0x108)
-#define                AR9170_DMA_CTL_ENABLE_TO_DEVICE         0x1
-#define                AR9170_DMA_CTL_ENABLE_FROM_DEVICE       0x2
-#define                AR9170_DMA_CTL_HIGH_SPEED               0x4
-#define                AR9170_DMA_CTL_PACKET_MODE              0x8
-
-#define AR9170_USB_REG_MAX_AGG_UPLOAD          (AR9170_USB_REG_BASE + 0x110)
-#define AR9170_USB_REG_UPLOAD_TIME_CTL         (AR9170_USB_REG_BASE + 0x114)
-
-
-
-#define AR9170_MAC_REG_BASE                    0x1c3000
-
-#define AR9170_MAC_REG_TSF_L                   (AR9170_MAC_REG_BASE + 0x514)
-#define AR9170_MAC_REG_TSF_H                   (AR9170_MAC_REG_BASE + 0x518)
-
-#define AR9170_MAC_REG_ATIM_WINDOW             (AR9170_MAC_REG_BASE + 0x51C)
-#define AR9170_MAC_REG_BCN_PERIOD              (AR9170_MAC_REG_BASE + 0x520)
-#define AR9170_MAC_REG_PRETBTT                 (AR9170_MAC_REG_BASE + 0x524)
-
-#define AR9170_MAC_REG_MAC_ADDR_L              (AR9170_MAC_REG_BASE + 0x610)
-#define AR9170_MAC_REG_MAC_ADDR_H              (AR9170_MAC_REG_BASE + 0x614)
-#define AR9170_MAC_REG_BSSID_L                 (AR9170_MAC_REG_BASE + 0x618)
-#define AR9170_MAC_REG_BSSID_H                 (AR9170_MAC_REG_BASE + 0x61c)
-
-#define AR9170_MAC_REG_GROUP_HASH_TBL_L                (AR9170_MAC_REG_BASE + 0x624)
-#define AR9170_MAC_REG_GROUP_HASH_TBL_H                (AR9170_MAC_REG_BASE + 0x628)
-
-#define AR9170_MAC_REG_RX_TIMEOUT              (AR9170_MAC_REG_BASE + 0x62C)
-
-#define AR9170_MAC_REG_BASIC_RATE              (AR9170_MAC_REG_BASE + 0x630)
-#define AR9170_MAC_REG_MANDATORY_RATE          (AR9170_MAC_REG_BASE + 0x634)
-#define AR9170_MAC_REG_RTS_CTS_RATE            (AR9170_MAC_REG_BASE + 0x638)
-#define AR9170_MAC_REG_BACKOFF_PROTECT         (AR9170_MAC_REG_BASE + 0x63c)
-#define AR9170_MAC_REG_RX_THRESHOLD            (AR9170_MAC_REG_BASE + 0x640)
-#define AR9170_MAC_REG_RX_PE_DELAY             (AR9170_MAC_REG_BASE + 0x64C)
-
-#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK                (AR9170_MAC_REG_BASE + 0x658)
-#define AR9170_MAC_REG_SNIFFER                 (AR9170_MAC_REG_BASE + 0x674)
-#define                AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC   BIT(0)
-#define                AR9170_MAC_REG_SNIFFER_DEFAULTS         0x02000000
-#define AR9170_MAC_REG_ENCRYPTION              (AR9170_MAC_REG_BASE + 0x678)
-#define                AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE   BIT(3)
-#define                AR9170_MAC_REG_ENCRYPTION_DEFAULTS      0x70
-
-#define AR9170_MAC_REG_MISC_680                        (AR9170_MAC_REG_BASE + 0x680)
-#define AR9170_MAC_REG_TX_UNDERRUN             (AR9170_MAC_REG_BASE + 0x688)
-
-#define AR9170_MAC_REG_FRAMETYPE_FILTER                (AR9170_MAC_REG_BASE + 0x68c)
-#define                AR9170_MAC_REG_FTF_ASSOC_REQ            BIT(0)
-#define                AR9170_MAC_REG_FTF_ASSOC_RESP           BIT(1)
-#define                AR9170_MAC_REG_FTF_REASSOC_REQ          BIT(2)
-#define                AR9170_MAC_REG_FTF_REASSOC_RESP         BIT(3)
-#define                AR9170_MAC_REG_FTF_PRB_REQ              BIT(4)
-#define                AR9170_MAC_REG_FTF_PRB_RESP             BIT(5)
-#define                AR9170_MAC_REG_FTF_BIT6                 BIT(6)
-#define                AR9170_MAC_REG_FTF_BIT7                 BIT(7)
-#define                AR9170_MAC_REG_FTF_BEACON               BIT(8)
-#define                AR9170_MAC_REG_FTF_ATIM                 BIT(9)
-#define                AR9170_MAC_REG_FTF_DEASSOC              BIT(10)
-#define                AR9170_MAC_REG_FTF_AUTH                 BIT(11)
-#define                AR9170_MAC_REG_FTF_DEAUTH               BIT(12)
-#define                AR9170_MAC_REG_FTF_BIT13                BIT(13)
-#define                AR9170_MAC_REG_FTF_BIT14                BIT(14)
-#define                AR9170_MAC_REG_FTF_BIT15                BIT(15)
-#define                AR9170_MAC_REG_FTF_BAR                  BIT(24)
-#define                AR9170_MAC_REG_FTF_BIT25                BIT(25)
-#define                AR9170_MAC_REG_FTF_PSPOLL               BIT(26)
-#define                AR9170_MAC_REG_FTF_RTS                  BIT(27)
-#define                AR9170_MAC_REG_FTF_CTS                  BIT(28)
-#define                AR9170_MAC_REG_FTF_ACK                  BIT(29)
-#define                AR9170_MAC_REG_FTF_CFE                  BIT(30)
-#define                AR9170_MAC_REG_FTF_CFE_ACK              BIT(31)
-#define                AR9170_MAC_REG_FTF_DEFAULTS             0x0500ffff
-#define                AR9170_MAC_REG_FTF_MONITOR              0xfd00ffff
-
-#define AR9170_MAC_REG_RX_TOTAL                        (AR9170_MAC_REG_BASE + 0x6A0)
-#define AR9170_MAC_REG_RX_CRC32                        (AR9170_MAC_REG_BASE + 0x6A4)
-#define AR9170_MAC_REG_RX_CRC16                        (AR9170_MAC_REG_BASE + 0x6A8)
-#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI   (AR9170_MAC_REG_BASE + 0x6AC)
-#define AR9170_MAC_REG_RX_OVERRUN              (AR9170_MAC_REG_BASE + 0x6B0)
-#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL   (AR9170_MAC_REG_BASE + 0x6BC)
-#define AR9170_MAC_REG_TX_RETRY                        (AR9170_MAC_REG_BASE + 0x6CC)
-#define AR9170_MAC_REG_TX_TOTAL                        (AR9170_MAC_REG_BASE + 0x6F4)
-
-
-#define AR9170_MAC_REG_ACK_EXTENSION           (AR9170_MAC_REG_BASE + 0x690)
-#define AR9170_MAC_REG_EIFS_AND_SIFS           (AR9170_MAC_REG_BASE + 0x698)
-
-#define AR9170_MAC_REG_SLOT_TIME               (AR9170_MAC_REG_BASE + 0x6F0)
-
-#define AR9170_MAC_REG_POWERMANAGEMENT         (AR9170_MAC_REG_BASE + 0x700)
-#define                AR9170_MAC_REG_POWERMGT_IBSS            0xe0
-#define                AR9170_MAC_REG_POWERMGT_AP              0xa1
-#define                AR9170_MAC_REG_POWERMGT_STA             0x2
-#define                AR9170_MAC_REG_POWERMGT_AP_WDS          0x3
-#define                AR9170_MAC_REG_POWERMGT_DEFAULTS        (0xf << 24)
-
-#define AR9170_MAC_REG_ROLL_CALL_TBL_L         (AR9170_MAC_REG_BASE + 0x704)
-#define AR9170_MAC_REG_ROLL_CALL_TBL_H         (AR9170_MAC_REG_BASE + 0x708)
-
-#define AR9170_MAC_REG_AC0_CW                  (AR9170_MAC_REG_BASE + 0xB00)
-#define AR9170_MAC_REG_AC1_CW                  (AR9170_MAC_REG_BASE + 0xB04)
-#define AR9170_MAC_REG_AC2_CW                  (AR9170_MAC_REG_BASE + 0xB08)
-#define AR9170_MAC_REG_AC3_CW                  (AR9170_MAC_REG_BASE + 0xB0C)
-#define AR9170_MAC_REG_AC4_CW                  (AR9170_MAC_REG_BASE + 0xB10)
-#define AR9170_MAC_REG_AC1_AC0_AIFS            (AR9170_MAC_REG_BASE + 0xB14)
-#define AR9170_MAC_REG_AC3_AC2_AIFS            (AR9170_MAC_REG_BASE + 0xB18)
-
-#define AR9170_MAC_REG_RETRY_MAX               (AR9170_MAC_REG_BASE + 0xB28)
-
-#define AR9170_MAC_REG_FCS_SELECT              (AR9170_MAC_REG_BASE + 0xBB0)
-#define                AR9170_MAC_FCS_SWFCS            0x1
-#define                AR9170_MAC_FCS_FIFO_PROT        0x4
-
-
-#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND     (AR9170_MAC_REG_BASE + 0xB30)
-
-#define AR9170_MAC_REG_AC1_AC0_TXOP            (AR9170_MAC_REG_BASE + 0xB44)
-#define AR9170_MAC_REG_AC3_AC2_TXOP            (AR9170_MAC_REG_BASE + 0xB48)
-
-#define AR9170_MAC_REG_ACK_TABLE               (AR9170_MAC_REG_BASE + 0xC00)
-#define AR9170_MAC_REG_AMPDU_RX_THRESH         (AR9170_MAC_REG_BASE + 0xC50)
-
-#define AR9170_MAC_REG_TXRX_MPI                        (AR9170_MAC_REG_BASE + 0xD7C)
-#define                AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f
-#define                AR9170_MAC_TXRX_MPI_TX_TO_MASK  0x0000fff0
-#define                AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000
-#define                AR9170_MAC_TXRX_MPI_RX_TO_MASK  0xfff00000
-
-#define AR9170_MAC_REG_BCN_ADDR                        (AR9170_MAC_REG_BASE + 0xD84)
-#define AR9170_MAC_REG_BCN_LENGTH              (AR9170_MAC_REG_BASE + 0xD88)
-#define AR9170_MAC_REG_BCN_PLCP                        (AR9170_MAC_REG_BASE + 0xD90)
-#define AR9170_MAC_REG_BCN_CTRL                        (AR9170_MAC_REG_BASE + 0xD94)
-#define AR9170_MAC_REG_BCN_HT1                 (AR9170_MAC_REG_BASE + 0xDA0)
-#define AR9170_MAC_REG_BCN_HT2                 (AR9170_MAC_REG_BASE + 0xDA4)
-
-
-#define AR9170_PWR_REG_BASE                    0x1D4000
-
-#define AR9170_PWR_REG_CLOCK_SEL               (AR9170_PWR_REG_BASE + 0x008)
-#define                AR9170_PWR_CLK_AHB_40MHZ        0
-#define                AR9170_PWR_CLK_AHB_20_22MHZ     1
-#define                AR9170_PWR_CLK_AHB_40_44MHZ     2
-#define                AR9170_PWR_CLK_AHB_80_88MHZ     3
-#define                AR9170_PWR_CLK_DAC_160_INV_DLY  0x70
-
-
-/* put beacon here in memory */
-#define AR9170_BEACON_BUFFER_ADDRESS           0x117900
-
-
-struct ar9170_tx_control {
-       __le16 length;
-       __le16 mac_control;
-       __le32 phy_control;
-       u8 frame_data[0];
-} __packed;
-
-/* these are either-or */
-#define AR9170_TX_MAC_PROT_RTS                 0x0001
-#define AR9170_TX_MAC_PROT_CTS                 0x0002
-
-#define AR9170_TX_MAC_NO_ACK                   0x0004
-/* if unset, MAC will only do SIFS space before frame */
-#define AR9170_TX_MAC_BACKOFF                  0x0008
-#define AR9170_TX_MAC_BURST                    0x0010
-#define AR9170_TX_MAC_AGGR                     0x0020
-
-/* encryption is a two-bit field */
-#define AR9170_TX_MAC_ENCR_NONE                        0x0000
-#define AR9170_TX_MAC_ENCR_RC4                 0x0040
-#define AR9170_TX_MAC_ENCR_CENC                        0x0080
-#define AR9170_TX_MAC_ENCR_AES                 0x00c0
-
-#define AR9170_TX_MAC_MMIC                     0x0100
-#define AR9170_TX_MAC_HW_DURATION              0x0200
-#define AR9170_TX_MAC_QOS_SHIFT                        10
-#define AR9170_TX_MAC_QOS_MASK                 (3 << AR9170_TX_MAC_QOS_SHIFT)
-#define AR9170_TX_MAC_AGGR_QOS_BIT1            0x0400
-#define AR9170_TX_MAC_AGGR_QOS_BIT2            0x0800
-#define AR9170_TX_MAC_DISABLE_TXOP             0x1000
-#define AR9170_TX_MAC_TXOP_RIFS                        0x2000
-#define AR9170_TX_MAC_IMM_AMPDU                        0x4000
-#define AR9170_TX_MAC_RATE_PROBE               0x8000
-
-/* either-or */
-#define AR9170_TX_PHY_MOD_CCK                  0x00000000
-#define AR9170_TX_PHY_MOD_OFDM                 0x00000001
-#define AR9170_TX_PHY_MOD_HT                   0x00000002
-
-/* depends on modulation */
-#define AR9170_TX_PHY_SHORT_PREAMBLE           0x00000004
-#define AR9170_TX_PHY_GREENFIELD               0x00000004
-
-#define AR9170_TX_PHY_BW_SHIFT                 3
-#define AR9170_TX_PHY_BW_MASK                  (3 << AR9170_TX_PHY_BW_SHIFT)
-#define AR9170_TX_PHY_BW_20MHZ                 0
-#define AR9170_TX_PHY_BW_40MHZ                 2
-#define AR9170_TX_PHY_BW_40MHZ_DUP             3
-
-#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT      6
-#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK       (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
-
-#define AR9170_TX_PHY_TX_PWR_SHIFT             9
-#define AR9170_TX_PHY_TX_PWR_MASK              (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
-
-/* not part of the hw-spec */
-#define AR9170_TX_PHY_QOS_SHIFT                        25
-#define AR9170_TX_PHY_QOS_MASK                 (3 << AR9170_TX_PHY_QOS_SHIFT)
-
-#define AR9170_TX_PHY_TXCHAIN_SHIFT            15
-#define AR9170_TX_PHY_TXCHAIN_MASK             (7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
-#define AR9170_TX_PHY_TXCHAIN_1                        1
-/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
-#define AR9170_TX_PHY_TXCHAIN_2                        5
-
-#define AR9170_TX_PHY_MCS_SHIFT                        18
-#define AR9170_TX_PHY_MCS_MASK                 (0x7f << AR9170_TX_PHY_MCS_SHIFT)
-
-#define AR9170_TX_PHY_SHORT_GI                 0x80000000
-
-struct ar9170_rx_head {
-       u8 plcp[12];
-} __packed;
-
-struct ar9170_rx_tail {
-       union {
-               struct {
-                       u8 rssi_ant0, rssi_ant1, rssi_ant2,
-                          rssi_ant0x, rssi_ant1x, rssi_ant2x,
-                          rssi_combined;
-               } __packed;
-               u8 rssi[7];
-       } __packed;
-
-       u8 evm_stream0[6], evm_stream1[6];
-       u8 phy_err;
-       u8 SAidx, DAidx;
-       u8 error;
-       u8 status;
-} __packed;
-
-#define AR9170_ENC_ALG_NONE                    0x0
-#define AR9170_ENC_ALG_WEP64                   0x1
-#define AR9170_ENC_ALG_TKIP                    0x2
-#define AR9170_ENC_ALG_AESCCMP                 0x4
-#define AR9170_ENC_ALG_WEP128                  0x5
-#define AR9170_ENC_ALG_WEP256                  0x6
-#define AR9170_ENC_ALG_CENC                    0x7
-
-#define AR9170_RX_ENC_SOFTWARE                 0x8
-
-static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
-{
-       return (t->SAidx & 0xc0) >> 4 |
-              (t->DAidx & 0xc0) >> 6;
-}
-
-#define AR9170_RX_STATUS_MODULATION_MASK       0x03
-#define AR9170_RX_STATUS_MODULATION_CCK                0x00
-#define AR9170_RX_STATUS_MODULATION_OFDM       0x01
-#define AR9170_RX_STATUS_MODULATION_HT         0x02
-#define AR9170_RX_STATUS_MODULATION_DUPOFDM    0x03
-
-/* depends on modulation */
-#define AR9170_RX_STATUS_SHORT_PREAMBLE                0x08
-#define AR9170_RX_STATUS_GREENFIELD            0x08
-
-#define AR9170_RX_STATUS_MPDU_MASK             0x30
-#define AR9170_RX_STATUS_MPDU_SINGLE           0x00
-#define AR9170_RX_STATUS_MPDU_FIRST            0x10
-#define AR9170_RX_STATUS_MPDU_MIDDLE           0x20
-#define AR9170_RX_STATUS_MPDU_LAST             0x30
-
-
-#define AR9170_RX_ERROR_RXTO                   0x01
-#define AR9170_RX_ERROR_OVERRUN                        0x02
-#define AR9170_RX_ERROR_DECRYPT                        0x04
-#define AR9170_RX_ERROR_FCS                    0x08
-#define AR9170_RX_ERROR_WRONG_RA               0x10
-#define AR9170_RX_ERROR_PLCP                   0x20
-#define AR9170_RX_ERROR_MMIC                   0x40
-
-struct ar9170_cmd_tx_status {
-       __le16 unkn;
-       u8 dst[ETH_ALEN];
-       __le32 rate;
-       __le16 status;
-} __packed;
-
-#define AR9170_TX_STATUS_COMPLETE              0x00
-#define AR9170_TX_STATUS_RETRY                 0x01
-#define AR9170_TX_STATUS_FAILED                        0x02
-
-struct ar9170_cmd_ba_failed_count {
-       __le16 failed;
-       __le16 rate;
-} __packed;
-
-struct ar9170_cmd_response {
-       u8 flag;
-       u8 type;
-
-       union {
-               struct ar9170_cmd_tx_status             tx_status;
-               struct ar9170_cmd_ba_failed_count       ba_fail_cnt;
-               u8 data[0];
-       };
-} __packed;
-
-/* QoS */
-
-/* mac80211 queue to HW/FW map */
-static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
-
-/* HW/FW queue to mac80211 map */
-static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
-
-enum ar9170_txq {
-       AR9170_TXQ_BE,
-       AR9170_TXQ_BK,
-       AR9170_TXQ_VI,
-       AR9170_TXQ_VO,
-
-       __AR9170_NUM_TXQ,
-};
-
-#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ar9170/led.c b/drivers/net/wireless/ar9170/led.c
deleted file mode 100644 (file)
index 341cead..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * LED handling
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 "ar9170.h"
-#include "cmd.h"
-
-int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
-{
-       return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
-}
-
-int ar9170_init_leds(struct ar9170 *ar)
-{
-       int err;
-
-       /* disable LEDs */
-       /* GPIO [0/1 mode: output, 2/3: input] */
-       err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
-       if (err)
-               goto out;
-
-       /* GPIO 0/1 value: off */
-       err = ar9170_set_leds_state(ar, 0);
-
-out:
-       return err;
-}
-
-#ifdef CONFIG_AR9170_LEDS
-static void ar9170_update_leds(struct work_struct *work)
-{
-       struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
-       int i, tmp, blink_delay = 1000;
-       u32 led_val = 0;
-       bool rerun = false;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return ;
-
-       mutex_lock(&ar->mutex);
-       for (i = 0; i < AR9170_NUM_LEDS; i++)
-               if (ar->leds[i].toggled) {
-                       led_val |= 1 << i;
-
-                       tmp = 70 + 200 / (ar->leds[i].toggled);
-                       if (tmp < blink_delay)
-                               blink_delay = tmp;
-
-                       if (ar->leds[i].toggled > 1)
-                               ar->leds[i].toggled = 0;
-
-                       rerun = true;
-               }
-
-       ar9170_set_leds_state(ar, led_val);
-       mutex_unlock(&ar->mutex);
-
-       if (rerun)
-               queue_delayed_work(ar->hw->workqueue, &ar->led_work,
-                                  msecs_to_jiffies(blink_delay));
-}
-
-static void ar9170_led_brightness_set(struct led_classdev *led,
-                                     enum led_brightness brightness)
-{
-       struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
-       struct ar9170 *ar = arl->ar;
-
-       arl->toggled++;
-
-       if (likely(IS_ACCEPTING_CMD(ar) && brightness))
-               queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
-}
-
-static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
-                              char *trigger)
-{
-       int err;
-
-       snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
-                "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
-
-       ar->leds[i].ar = ar;
-       ar->leds[i].l.name = ar->leds[i].name;
-       ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
-       ar->leds[i].l.brightness = 0;
-       ar->leds[i].l.default_trigger = trigger;
-
-       err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
-                                   &ar->leds[i].l);
-       if (err)
-               printk(KERN_ERR "%s: failed to register %s LED (%d).\n",
-                      wiphy_name(ar->hw->wiphy), ar->leds[i].name, err);
-       else
-               ar->leds[i].registered = true;
-
-       return err;
-}
-
-void ar9170_unregister_leds(struct ar9170 *ar)
-{
-       int i;
-
-       cancel_delayed_work_sync(&ar->led_work);
-
-       for (i = 0; i < AR9170_NUM_LEDS; i++)
-               if (ar->leds[i].registered) {
-                       led_classdev_unregister(&ar->leds[i].l);
-                       ar->leds[i].registered = false;
-               }
-}
-
-int ar9170_register_leds(struct ar9170 *ar)
-{
-       int err;
-
-       INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
-
-       err = ar9170_register_led(ar, 0, "tx",
-                                 ieee80211_get_tx_led_name(ar->hw));
-       if (err)
-               goto fail;
-
-       err = ar9170_register_led(ar, 1, "assoc",
-                                ieee80211_get_assoc_led_name(ar->hw));
-       if (err)
-               goto fail;
-
-       return 0;
-
-fail:
-       ar9170_unregister_leds(ar);
-       return err;
-}
-
-#endif /* CONFIG_AR9170_LEDS */
diff --git a/drivers/net/wireless/ar9170/mac.c b/drivers/net/wireless/ar9170/mac.c
deleted file mode 100644 (file)
index c8fa307..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * MAC programming
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 "ar9170.h"
-#include "cmd.h"
-
-int ar9170_set_qos(struct ar9170 *ar)
-{
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
-                       (ar->edcf[0].cw_max << 16));
-       ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
-                       (ar->edcf[1].cw_max << 16));
-       ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
-                       (ar->edcf[2].cw_max << 16));
-       ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
-                       (ar->edcf[3].cw_max << 16));
-       ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
-                       (ar->edcf[4].cw_max << 16));
-
-       ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
-                       ((ar->edcf[0].aifs * 9 + 10)) |
-                       ((ar->edcf[1].aifs * 9 + 10) << 12) |
-                       ((ar->edcf[2].aifs * 9 + 10) << 24));
-       ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
-                       ((ar->edcf[2].aifs * 9 + 10) >> 8) |
-                       ((ar->edcf[3].aifs * 9 + 10) << 4) |
-                       ((ar->edcf[4].aifs * 9 + 10) << 16));
-
-       ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
-                       ar->edcf[0].txop | ar->edcf[1].txop << 16);
-       ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
-                       ar->edcf[1].txop | ar->edcf[3].txop << 16);
-
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-int ar9170_init_mac(struct ar9170 *ar)
-{
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
-
-       ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
-
-       /* enable MMIC */
-       ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
-                       AR9170_MAC_REG_SNIFFER_DEFAULTS);
-
-       ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
-
-       ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
-       ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
-       ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
-
-       /* CF-END mode */
-       ar9170_regwrite(0x1c3b2c, 0x19000000);
-
-       /* NAV protects ACK only (in TXOP) */
-       ar9170_regwrite(0x1c3b38, 0x201);
-
-       /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
-       /* OTUS set AM to 0x1 */
-       ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
-
-       ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
-
-       /* AGG test code*/
-       /* Aggregation MAX number and timeout */
-       ar9170_regwrite(0x1c3b9c, 0x10000a);
-
-       ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
-                       AR9170_MAC_REG_FTF_DEFAULTS);
-
-       /* Enable deaggregator, response in sniffer mode */
-       ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
-
-       /* rate sets */
-       ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
-       ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
-       ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
-
-       /* MIMO response control */
-       ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28  otus-AM */
-
-       /* switch MAC to OTUS interface */
-       ar9170_regwrite(0x1c3600, 0x3);
-
-       ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
-
-       /* set PHY register read timeout (??) */
-       ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
-
-       /* Disable Rx TimeOut, workaround for BB. */
-       ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
-
-       /* Set CPU clock frequency to 88/80MHz */
-       ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
-                       AR9170_PWR_CLK_AHB_80_88MHZ |
-                       AR9170_PWR_CLK_DAC_160_INV_DLY);
-
-       /* Set WLAN DMA interrupt mode: generate int per packet */
-       ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
-
-       ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
-                       AR9170_MAC_FCS_FIFO_PROT);
-
-       /* Disables the CF_END frame, undocumented register */
-       ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
-                       0x141E0F48);
-
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
-{
-       static const u8 zero[ETH_ALEN] = { 0 };
-
-       if (!mac)
-               mac = zero;
-
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(reg,
-                       (mac[3] << 24) | (mac[2] << 16) |
-                       (mac[1] << 8) | mac[0]);
-
-       ar9170_regwrite(reg + 4, (mac[5] << 8) | mac[4]);
-
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-int ar9170_update_multicast(struct ar9170 *ar)
-{
-       int err;
-
-       ar9170_regwrite_begin(ar);
-       ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H,
-               ar->want_mc_hash >> 32);
-       ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
-               ar->want_mc_hash);
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-
-       if (err)
-               return err;
-
-       ar->cur_mc_hash = ar->want_mc_hash;
-
-       return 0;
-}
-
-int ar9170_update_frame_filter(struct ar9170 *ar)
-{
-       int err;
-
-       err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER,
-                              ar->want_filter);
-
-       if (err)
-               return err;
-
-       ar->cur_filter = ar->want_filter;
-
-       return 0;
-}
-
-static int ar9170_set_promiscouous(struct ar9170 *ar)
-{
-       u32 encr_mode, sniffer;
-       int err;
-
-       err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
-       if (err)
-               return err;
-
-       err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
-       if (err)
-               return err;
-
-       if (ar->sniffer_enabled) {
-               sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
-
-               /*
-                * Rx decryption works in place.
-                *
-                * If we don't disable it, the hardware will render all
-                * encrypted frames which are encrypted with an unknown
-                * key useless.
-                */
-
-               encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
-               ar->sniffer_enabled = true;
-       } else {
-               sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
-
-               if (ar->rx_software_decryption)
-                       encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
-               else
-                       encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
-       }
-
-       ar9170_regwrite_begin(ar);
-       ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
-       ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-int ar9170_set_operating_mode(struct ar9170 *ar)
-{
-       u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
-       u8 *mac_addr, *bssid;
-       int err;
-
-       if (ar->vif) {
-               mac_addr = ar->mac_addr;
-               bssid = ar->bssid;
-
-               switch (ar->vif->type) {
-               case NL80211_IFTYPE_MESH_POINT:
-               case NL80211_IFTYPE_ADHOC:
-                       pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
-                       break;
-/*             case NL80211_IFTYPE_AP:
-                       pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
-                       break;*/
-               case NL80211_IFTYPE_WDS:
-                       pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
-                       break;
-               case NL80211_IFTYPE_MONITOR:
-                       ar->sniffer_enabled = true;
-                       ar->rx_software_decryption = true;
-                       break;
-               default:
-                       pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
-                       break;
-               }
-       } else {
-               mac_addr = NULL;
-               bssid = NULL;
-       }
-
-       err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
-       if (err)
-               return err;
-
-       err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
-       if (err)
-               return err;
-
-       err = ar9170_set_promiscouous(ar);
-       if (err)
-               return err;
-
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
-{
-       u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
-
-       return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
-}
-
-int ar9170_set_beacon_timers(struct ar9170 *ar)
-{
-       u32 v = 0;
-       u32 pretbtt = 0;
-
-       v |= ar->hw->conf.beacon_int;
-
-       if (ar->vif) {
-               switch (ar->vif->type) {
-               case NL80211_IFTYPE_MESH_POINT:
-               case NL80211_IFTYPE_ADHOC:
-                       v |= BIT(25);
-                       break;
-               case NL80211_IFTYPE_AP:
-                       v |= BIT(24);
-                       pretbtt = (ar->hw->conf.beacon_int - 6) << 16;
-                       break;
-               default:
-                       break;
-               }
-
-               v |= ar->vif->bss_conf.dtim_period << 16;
-       }
-
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
-       ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
-       ar9170_regwrite_finish();
-       return ar9170_regwrite_result();
-}
-
-int ar9170_update_beacon(struct ar9170 *ar)
-{
-       struct sk_buff *skb;
-       __le32 *data, *old = NULL;
-       u32 word;
-       int i;
-
-       skb = ieee80211_beacon_get(ar->hw, ar->vif);
-       if (!skb)
-               return -ENOMEM;
-
-       data = (__le32 *)skb->data;
-       if (ar->beacon)
-               old = (__le32 *)ar->beacon->data;
-
-       ar9170_regwrite_begin(ar);
-       for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
-               /*
-                * XXX: This accesses beyond skb data for up
-                *      to the last 3 bytes!!
-                */
-
-               if (old && (data[i] == old[i]))
-                       continue;
-
-               word = le32_to_cpu(data[i]);
-               ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
-       }
-
-       /* XXX: use skb->cb info */
-       if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
-               ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
-                               ((skb->len + 4) << (3+16)) + 0x0400);
-       else
-               ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
-                               ((skb->len + 4) << (3+16)) + 0x0400);
-
-       ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
-       ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
-       ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
-
-       ar9170_regwrite_finish();
-
-       dev_kfree_skb(ar->beacon);
-       ar->beacon = skb;
-
-       return ar9170_regwrite_result();
-}
-
-void ar9170_new_beacon(struct work_struct *work)
-{
-       struct ar9170 *ar = container_of(work, struct ar9170,
-                                        beacon_work);
-       struct sk_buff *skb;
-
-       if (unlikely(!IS_STARTED(ar)))
-               return ;
-
-       mutex_lock(&ar->mutex);
-
-       if (!ar->vif)
-               goto out;
-
-       ar9170_update_beacon(ar);
-
-       rcu_read_lock();
-       while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
-               ar9170_op_tx(ar->hw, skb);
-
-       rcu_read_unlock();
-
- out:
-       mutex_unlock(&ar->mutex);
-}
-
-int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
-                     u8 keyidx, u8 *keydata, int keylen)
-{
-       __le32 vals[7];
-       static const u8 bcast[ETH_ALEN] =
-               { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-       u8 dummy;
-
-       mac = mac ? : bcast;
-
-       vals[0] = cpu_to_le32((keyidx << 16) + id);
-       vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
-       vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
-                             mac[3] << 8 | mac[2]);
-       memset(&vals[3], 0, 16);
-       if (keydata)
-               memcpy(&vals[3], keydata, keylen);
-
-       return ar->exec_cmd(ar, AR9170_CMD_EKEY,
-                           sizeof(vals), (u8 *)vals,
-                           1, &dummy);
-}
-
-int ar9170_disable_key(struct ar9170 *ar, u8 id)
-{
-       __le32 val = cpu_to_le32(id);
-       u8 dummy;
-
-       return ar->exec_cmd(ar, AR9170_CMD_EKEY,
-                           sizeof(val), (u8 *)&val,
-                           1, &dummy);
-}
diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ar9170/main.c
deleted file mode 100644 (file)
index 8de0ff9..0000000
+++ /dev/null
@@ -1,1690 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * mac80211 interaction code
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 <linux/init.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-#include <net/mac80211.h>
-#include "ar9170.h"
-#include "hw.h"
-#include "cmd.h"
-
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-
-#define RATE(_bitrate, _hw_rate, _txpidx, _flags) {    \
-       .bitrate        = (_bitrate),                   \
-       .flags          = (_flags),                     \
-       .hw_value       = (_hw_rate) | (_txpidx) << 4,  \
-}
-
-static struct ieee80211_rate __ar9170_ratetable[] = {
-       RATE(10, 0, 0, 0),
-       RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
-       RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
-       RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
-       RATE(60, 0xb, 0, 0),
-       RATE(90, 0xf, 0, 0),
-       RATE(120, 0xa, 0, 0),
-       RATE(180, 0xe, 0, 0),
-       RATE(240, 0x9, 0, 0),
-       RATE(360, 0xd, 1, 0),
-       RATE(480, 0x8, 2, 0),
-       RATE(540, 0xc, 3, 0),
-};
-#undef RATE
-
-#define ar9170_g_ratetable     (__ar9170_ratetable + 0)
-#define ar9170_g_ratetable_size        12
-#define ar9170_a_ratetable     (__ar9170_ratetable + 4)
-#define ar9170_a_ratetable_size        8
-
-/*
- * NB: The hw_value is used as an index into the ar9170_phy_freq_params
- *     array in phy.c so that we don't have to do frequency lookups!
- */
-#define CHAN(_freq, _idx) {            \
-       .center_freq    = (_freq),      \
-       .hw_value       = (_idx),       \
-       .max_power      = 18, /* XXX */ \
-}
-
-static struct ieee80211_channel ar9170_2ghz_chantable[] = {
-       CHAN(2412,  0),
-       CHAN(2417,  1),
-       CHAN(2422,  2),
-       CHAN(2427,  3),
-       CHAN(2432,  4),
-       CHAN(2437,  5),
-       CHAN(2442,  6),
-       CHAN(2447,  7),
-       CHAN(2452,  8),
-       CHAN(2457,  9),
-       CHAN(2462, 10),
-       CHAN(2467, 11),
-       CHAN(2472, 12),
-       CHAN(2484, 13),
-};
-
-static struct ieee80211_channel ar9170_5ghz_chantable[] = {
-       CHAN(4920, 14),
-       CHAN(4940, 15),
-       CHAN(4960, 16),
-       CHAN(4980, 17),
-       CHAN(5040, 18),
-       CHAN(5060, 19),
-       CHAN(5080, 20),
-       CHAN(5180, 21),
-       CHAN(5200, 22),
-       CHAN(5220, 23),
-       CHAN(5240, 24),
-       CHAN(5260, 25),
-       CHAN(5280, 26),
-       CHAN(5300, 27),
-       CHAN(5320, 28),
-       CHAN(5500, 29),
-       CHAN(5520, 30),
-       CHAN(5540, 31),
-       CHAN(5560, 32),
-       CHAN(5580, 33),
-       CHAN(5600, 34),
-       CHAN(5620, 35),
-       CHAN(5640, 36),
-       CHAN(5660, 37),
-       CHAN(5680, 38),
-       CHAN(5700, 39),
-       CHAN(5745, 40),
-       CHAN(5765, 41),
-       CHAN(5785, 42),
-       CHAN(5805, 43),
-       CHAN(5825, 44),
-       CHAN(5170, 45),
-       CHAN(5190, 46),
-       CHAN(5210, 47),
-       CHAN(5230, 48),
-};
-#undef CHAN
-
-static struct ieee80211_supported_band ar9170_band_2GHz = {
-       .channels       = ar9170_2ghz_chantable,
-       .n_channels     = ARRAY_SIZE(ar9170_2ghz_chantable),
-       .bitrates       = ar9170_g_ratetable,
-       .n_bitrates     = ar9170_g_ratetable_size,
-};
-
-#ifdef AR9170_QUEUE_DEBUG
-/*
- * In case some wants works with AR9170's crazy tx_status queueing techniques.
- * He might need this rather useful probing function.
- *
- * NOTE: caller must hold the queue's spinlock!
- */
-
-static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
-{
-       struct ar9170_tx_control *txc = (void *) skb->data;
-       struct ieee80211_hdr *hdr = (void *)txc->frame_data;
-
-       printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] "
-                         "mac_control:%04x, phy_control:%08x]\n",
-              wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
-              ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control),
-              le32_to_cpu(txc->phy_control));
-}
-
-static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
-                                               struct sk_buff_head *queue)
-{
-       struct sk_buff *skb;
-       int i = 0;
-
-       printk(KERN_DEBUG "---[ cut here ]---\n");
-       printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n",
-              wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
-
-       skb_queue_walk(queue, skb) {
-               struct ar9170_tx_control *txc = (void *) skb->data;
-               struct ieee80211_hdr *hdr = (void *)txc->frame_data;
-
-               printk(KERN_DEBUG "index:%d => \n", i);
-               ar9170_print_txheader(ar, skb);
-       }
-       printk(KERN_DEBUG "---[ end ]---\n");
-}
-#endif /* AR9170_QUEUE_DEBUG */
-
-static struct ieee80211_supported_band ar9170_band_5GHz = {
-       .channels       = ar9170_5ghz_chantable,
-       .n_channels     = ARRAY_SIZE(ar9170_5ghz_chantable),
-       .bitrates       = ar9170_a_ratetable,
-       .n_bitrates     = ar9170_a_ratetable_size,
-};
-
-void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
-                            bool valid_status, u16 tx_status)
-{
-       struct ieee80211_tx_info *txinfo;
-       unsigned int retries = 0, queue = skb_get_queue_mapping(skb);
-       unsigned long flags;
-
-       spin_lock_irqsave(&ar->tx_stats_lock, flags);
-       ar->tx_stats[queue].len--;
-       if (ieee80211_queue_stopped(ar->hw, queue))
-               ieee80211_wake_queue(ar->hw, queue);
-       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
-       txinfo = IEEE80211_SKB_CB(skb);
-       ieee80211_tx_info_clear_status(txinfo);
-
-       switch (tx_status) {
-       case AR9170_TX_STATUS_RETRY:
-               retries = 2;
-       case AR9170_TX_STATUS_COMPLETE:
-               txinfo->flags |= IEEE80211_TX_STAT_ACK;
-               break;
-
-       case AR9170_TX_STATUS_FAILED:
-               retries = ar->hw->conf.long_frame_max_tx_count;
-               break;
-
-       default:
-               printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
-                      wiphy_name(ar->hw->wiphy), tx_status);
-               break;
-       }
-
-       if (valid_status)
-               txinfo->status.rates[0].count = retries + 1;
-
-       skb_pull(skb, sizeof(struct ar9170_tx_control));
-       ieee80211_tx_status_irqsafe(ar->hw, skb);
-}
-
-static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar,
-                                               const u8 *mac,
-                                               const u32 queue,
-                                               struct sk_buff_head *q)
-{
-       unsigned long flags;
-       struct sk_buff *skb;
-
-       spin_lock_irqsave(&q->lock, flags);
-       skb_queue_walk(q, skb) {
-               struct ar9170_tx_control *txc = (void *) skb->data;
-               struct ieee80211_hdr *hdr = (void *) txc->frame_data;
-               u32 txc_queue = (le32_to_cpu(txc->phy_control) &
-                               AR9170_TX_PHY_QOS_MASK) >>
-                               AR9170_TX_PHY_QOS_SHIFT;
-
-               if  ((queue != txc_queue) ||
-                    (compare_ether_addr(ieee80211_get_DA(hdr), mac)))
-                       continue;
-
-               __skb_unlink(skb, q);
-               spin_unlock_irqrestore(&q->lock, flags);
-               return skb;
-       }
-       spin_unlock_irqrestore(&q->lock, flags);
-       return NULL;
-}
-
-static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac,
-                                             const u32 queue)
-{
-       struct ieee80211_sta *sta;
-       struct sk_buff *skb;
-
-       /*
-        * Unfortunately, the firmware does not tell to which (queued) frame
-        * this transmission status report belongs to.
-        *
-        * So we have to make risky guesses - with the scarce information
-        * the firmware provided (-> destination MAC, and phy_control) -
-        * and hope that we picked the right one...
-        */
-       rcu_read_lock();
-       sta = ieee80211_find_sta(ar->hw, mac);
-
-       if (likely(sta)) {
-               struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv;
-               skb = skb_dequeue(&sta_priv->tx_status[queue]);
-               rcu_read_unlock();
-               if (likely(skb))
-                       return skb;
-       } else
-               rcu_read_unlock();
-
-       /* scan the waste queue for candidates */
-       skb = ar9170_find_skb_in_queue(ar, mac, queue,
-                                      &ar->global_tx_status_waste);
-       if (!skb) {
-               /* so it still _must_ be in the global list. */
-               skb = ar9170_find_skb_in_queue(ar, mac, queue,
-                                              &ar->global_tx_status);
-       }
-
-#ifdef AR9170_QUEUE_DEBUG
-       if (unlikely((!skb) && net_ratelimit())) {
-               printk(KERN_ERR "%s: ESS:[%pM] does not have any "
-                               "outstanding frames in this queue (%d).\n",
-                               wiphy_name(ar->hw->wiphy), mac, queue);
-       }
-#endif /* AR9170_QUEUE_DEBUG */
-       return skb;
-}
-
-/*
- * This worker tries to keep the global tx_status queue empty.
- * So we can guarantee that incoming tx_status reports for
- * unregistered stations are always synced with the actual
- * frame - which we think - belongs to.
- */
-
-static void ar9170_tx_status_janitor(struct work_struct *work)
-{
-       struct ar9170 *ar = container_of(work, struct ar9170,
-                                        tx_status_janitor.work);
-       struct sk_buff *skb;
-
-       if (unlikely(!IS_STARTED(ar)))
-               return ;
-
-       mutex_lock(&ar->mutex);
-       /* recycle the garbage back to mac80211... one by one. */
-       while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
-#ifdef AR9170_QUEUE_DEBUG
-               printk(KERN_DEBUG "%s: dispose queued frame =>\n",
-                      wiphy_name(ar->hw->wiphy));
-               ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-               ar9170_handle_tx_status(ar, skb, false,
-                                       AR9170_TX_STATUS_FAILED);
-       }
-
-       while ((skb = skb_dequeue(&ar->global_tx_status))) {
-#ifdef AR9170_QUEUE_DEBUG
-               printk(KERN_DEBUG "%s: moving frame into waste queue =>\n",
-                      wiphy_name(ar->hw->wiphy));
-
-               ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-               skb_queue_tail(&ar->global_tx_status_waste, skb);
-       }
-
-       /* recall the janitor in 100ms - if there's garbage in the can. */
-       if (skb_queue_len(&ar->global_tx_status_waste) > 0)
-               queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
-                                  msecs_to_jiffies(100));
-
-       mutex_unlock(&ar->mutex);
-}
-
-static void ar9170_handle_command_response(struct ar9170 *ar,
-                                          void *buf, u32 len)
-{
-       struct ar9170_cmd_response *cmd = (void *) buf;
-
-       if ((cmd->type & 0xc0) != 0xc0) {
-               ar->callback_cmd(ar, len, buf);
-               return;
-       }
-
-       /* hardware event handlers */
-       switch (cmd->type) {
-       case 0xc1: {
-               /*
-                * TX status notification:
-                * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
-                *
-                * XX always 81
-                * YY always 00
-                * M1-M6 is the MAC address
-                * R1-R4 is the transmit rate
-                * S1-S2 is the transmit status
-                */
-
-               struct sk_buff *skb;
-               u32 queue = (le32_to_cpu(cmd->tx_status.rate) &
-                           AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT;
-
-               skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue);
-               if (unlikely(!skb))
-                       return ;
-
-               ar9170_handle_tx_status(ar, skb, true,
-                                       le16_to_cpu(cmd->tx_status.status));
-               break;
-               }
-
-       case 0xc0:
-               /*
-                * pre-TBTT event
-                */
-               if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
-                       queue_work(ar->hw->workqueue, &ar->beacon_work);
-               break;
-
-       case 0xc2:
-               /*
-                * (IBSS) beacon send notification
-                * bytes: 04 c2 XX YY B4 B3 B2 B1
-                *
-                * XX always 80
-                * YY always 00
-                * B1-B4 "should" be the number of send out beacons.
-                */
-               break;
-
-       case 0xc3:
-               /* End of Atim Window */
-               break;
-
-       case 0xc4:
-       case 0xc5:
-               /* BlockACK events */
-               break;
-
-       case 0xc6:
-               /* Watchdog Interrupt */
-               break;
-
-       case 0xc9:
-               /* retransmission issue / SIFS/EIFS collision ?! */
-               break;
-
-       default:
-               printk(KERN_INFO "received unhandled event %x\n", cmd->type);
-               print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
-               break;
-       }
-}
-
-/*
- * If the frame alignment is right (or the kernel has
- * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
- * is only a single MPDU in the USB frame, then we can
- * submit to mac80211 the SKB directly. However, since
- * there may be multiple packets in one SKB in stream
- * mode, and we need to observe the proper ordering,
- * this is non-trivial.
- */
-static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
-{
-       struct sk_buff *skb;
-       struct ar9170_rx_head *head = (void *)buf;
-       struct ar9170_rx_tail *tail;
-       struct ieee80211_rx_status status;
-       int mpdu_len, i;
-       u8 error, antennas = 0, decrypt;
-       __le16 fc;
-       int reserved;
-
-       if (unlikely(!IS_STARTED(ar)))
-               return ;
-
-       /* Received MPDU */
-       mpdu_len = len;
-       mpdu_len -= sizeof(struct ar9170_rx_head);
-       mpdu_len -= sizeof(struct ar9170_rx_tail);
-       BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
-       BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24);
-
-       if (mpdu_len <= FCS_LEN)
-               return;
-
-       tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len);
-
-       for (i = 0; i < 3; i++)
-               if (tail->rssi[i] != 0x80)
-                       antennas |= BIT(i);
-
-       /* post-process RSSI */
-       for (i = 0; i < 7; i++)
-               if (tail->rssi[i] & 0x80)
-                       tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f;
-
-       memset(&status, 0, sizeof(status));
-
-       status.band = ar->channel->band;
-       status.freq = ar->channel->center_freq;
-       status.signal = ar->noise[0] + tail->rssi_combined;
-       status.noise = ar->noise[0];
-       status.antenna = antennas;
-
-       switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) {
-       case AR9170_RX_STATUS_MODULATION_CCK:
-               if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
-                       status.flag |= RX_FLAG_SHORTPRE;
-               switch (head->plcp[0]) {
-               case 0x0a:
-                       status.rate_idx = 0;
-                       break;
-               case 0x14:
-                       status.rate_idx = 1;
-                       break;
-               case 0x37:
-                       status.rate_idx = 2;
-                       break;
-               case 0x6e:
-                       status.rate_idx = 3;
-                       break;
-               default:
-                       if ((!ar->sniffer_enabled) && (net_ratelimit()))
-                               printk(KERN_ERR "%s: invalid plcp cck rate "
-                                      "(%x).\n", wiphy_name(ar->hw->wiphy),
-                                      head->plcp[0]);
-                       return;
-               }
-               break;
-       case AR9170_RX_STATUS_MODULATION_OFDM:
-               switch (head->plcp[0] & 0xF) {
-               case 0xB:
-                       status.rate_idx = 0;
-                       break;
-               case 0xF:
-                       status.rate_idx = 1;
-                       break;
-               case 0xA:
-                       status.rate_idx = 2;
-                       break;
-               case 0xE:
-                       status.rate_idx = 3;
-                       break;
-               case 0x9:
-                       status.rate_idx = 4;
-                       break;
-               case 0xD:
-                       status.rate_idx = 5;
-                       break;
-               case 0x8:
-                       status.rate_idx = 6;
-                       break;
-               case 0xC:
-                       status.rate_idx = 7;
-                       break;
-               default:
-                       if ((!ar->sniffer_enabled) && (net_ratelimit()))
-                               printk(KERN_ERR "%s: invalid plcp ofdm rate "
-                                      "(%x).\n", wiphy_name(ar->hw->wiphy),
-                                      head->plcp[0]);
-                       return;
-               }
-               if (status.band == IEEE80211_BAND_2GHZ)
-                       status.rate_idx += 4;
-               break;
-       case AR9170_RX_STATUS_MODULATION_HT:
-       case AR9170_RX_STATUS_MODULATION_DUPOFDM:
-               /* XXX */
-
-               if (net_ratelimit())
-                       printk(KERN_ERR "%s: invalid modulation\n",
-                              wiphy_name(ar->hw->wiphy));
-               return;
-       }
-
-       error = tail->error;
-
-       if (error & AR9170_RX_ERROR_MMIC) {
-               status.flag |= RX_FLAG_MMIC_ERROR;
-               error &= ~AR9170_RX_ERROR_MMIC;
-       }
-
-       if (error & AR9170_RX_ERROR_PLCP) {
-               status.flag |= RX_FLAG_FAILED_PLCP_CRC;
-               error &= ~AR9170_RX_ERROR_PLCP;
-       }
-
-       if (error & AR9170_RX_ERROR_FCS) {
-               status.flag |= RX_FLAG_FAILED_FCS_CRC;
-               error &= ~AR9170_RX_ERROR_FCS;
-       }
-
-       decrypt = ar9170_get_decrypt_type(tail);
-       if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
-           decrypt != AR9170_ENC_ALG_NONE)
-               status.flag |= RX_FLAG_DECRYPTED;
-
-       /* ignore wrong RA errors */
-       error &= ~AR9170_RX_ERROR_WRONG_RA;
-
-       if (error & AR9170_RX_ERROR_DECRYPT) {
-               error &= ~AR9170_RX_ERROR_DECRYPT;
-
-               /*
-                * Rx decryption is done in place,
-                * the original data is lost anyway.
-                */
-               return ;
-       }
-
-       /* drop any other error frames */
-       if ((error) && (net_ratelimit())) {
-               printk(KERN_DEBUG "%s: errors: %#x\n",
-                      wiphy_name(ar->hw->wiphy), error);
-               return;
-       }
-
-       buf += sizeof(struct ar9170_rx_head);
-       fc = *(__le16 *)buf;
-
-       if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc))
-               reserved = 32 + 2;
-       else
-               reserved = 32;
-
-       skb = dev_alloc_skb(mpdu_len + reserved);
-       if (!skb)
-               return;
-
-       skb_reserve(skb, reserved);
-       memcpy(skb_put(skb, mpdu_len), buf, mpdu_len);
-       ieee80211_rx_irqsafe(ar->hw, skb, &status);
-}
-
-void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
-{
-       unsigned int i, tlen, resplen;
-       u8 *tbuf, *respbuf;
-
-       tbuf = skb->data;
-       tlen = skb->len;
-
-       while (tlen >= 4) {
-               int clen = tbuf[1] << 8 | tbuf[0];
-               int wlen = (clen + 3) & ~3;
-
-               /*
-                * parse stream (if any)
-                */
-               if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
-                       printk(KERN_ERR "%s: missing tag!\n",
-                              wiphy_name(ar->hw->wiphy));
-                       return ;
-               }
-               if (wlen > tlen - 4) {
-                       printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n",
-                              wiphy_name(ar->hw->wiphy), clen, wlen, tlen);
-                       print_hex_dump(KERN_DEBUG, "data: ",
-                                      DUMP_PREFIX_OFFSET,
-                                      16, 1, tbuf, tlen, true);
-                       return ;
-               }
-               resplen = clen;
-               respbuf = tbuf + 4;
-               tbuf += wlen + 4;
-               tlen -= wlen + 4;
-
-               i = 0;
-
-               /* weird thing, but this is the same in the original driver */
-               while (resplen > 2 && i < 12 &&
-                      respbuf[0] == 0xff && respbuf[1] == 0xff) {
-                       i += 2;
-                       resplen -= 2;
-                       respbuf += 2;
-               }
-
-               if (resplen < 4)
-                       continue;
-
-               /* found the 6 * 0xffff marker? */
-               if (i == 12)
-                       ar9170_handle_command_response(ar, respbuf, resplen);
-               else
-                       ar9170_handle_mpdu(ar, respbuf, resplen);
-       }
-
-       if (tlen)
-               printk(KERN_ERR "%s: buffer remains!\n",
-                      wiphy_name(ar->hw->wiphy));
-}
-
-#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop)           \
-do {                                                                   \
-       queue.aifs = ai_fs;                                             \
-       queue.cw_min = cwmin;                                           \
-       queue.cw_max = cwmax;                                           \
-       queue.txop = _txop;                                             \
-} while (0)
-
-static int ar9170_op_start(struct ieee80211_hw *hw)
-{
-       struct ar9170 *ar = hw->priv;
-       int err, i;
-
-       mutex_lock(&ar->mutex);
-
-       /* reinitialize queues statistics */
-       memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
-       for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
-               ar->tx_stats[i].limit = 8;
-
-       /* reset QoS defaults */
-       AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023,  0); /* BEST EFFORT*/
-       AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023,  0); /* BACKGROUND */
-       AR9170_FILL_QUEUE(ar->edcf[2], 2, 7,    15, 94); /* VIDEO */
-       AR9170_FILL_QUEUE(ar->edcf[3], 2, 3,     7, 47); /* VOICE */
-       AR9170_FILL_QUEUE(ar->edcf[4], 2, 3,     7,  0); /* SPECIAL */
-
-       err = ar->open(ar);
-       if (err)
-               goto out;
-
-       err = ar9170_init_mac(ar);
-       if (err)
-               goto out;
-
-       err = ar9170_set_qos(ar);
-       if (err)
-               goto out;
-
-       err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
-       if (err)
-               goto out;
-
-       err = ar9170_init_rf(ar);
-       if (err)
-               goto out;
-
-       /* start DMA */
-       err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
-       if (err)
-               goto out;
-
-       ar->state = AR9170_STARTED;
-
-out:
-       mutex_unlock(&ar->mutex);
-       return err;
-}
-
-static void ar9170_op_stop(struct ieee80211_hw *hw)
-{
-       struct ar9170 *ar = hw->priv;
-
-       if (IS_STARTED(ar))
-               ar->state = AR9170_IDLE;
-
-       flush_workqueue(ar->hw->workqueue);
-
-       mutex_lock(&ar->mutex);
-       cancel_delayed_work_sync(&ar->tx_status_janitor);
-       cancel_work_sync(&ar->filter_config_work);
-       cancel_work_sync(&ar->beacon_work);
-       skb_queue_purge(&ar->global_tx_status_waste);
-       skb_queue_purge(&ar->global_tx_status);
-
-       if (IS_ACCEPTING_CMD(ar)) {
-               ar9170_set_leds_state(ar, 0);
-
-               /* stop DMA */
-               ar9170_write_reg(ar, 0x1c3d30, 0);
-               ar->stop(ar);
-       }
-
-       mutex_unlock(&ar->mutex);
-}
-
-int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct ar9170 *ar = hw->priv;
-       struct ieee80211_hdr *hdr;
-       struct ar9170_tx_control *txc;
-       struct ieee80211_tx_info *info;
-       struct ieee80211_rate *rate = NULL;
-       struct ieee80211_tx_rate *txrate;
-       unsigned int queue = skb_get_queue_mapping(skb);
-       unsigned long flags = 0;
-       struct ar9170_sta_info *sta_info = NULL;
-       u32 power, chains;
-       u16 keytype = 0;
-       u16 len, icv = 0;
-       int err;
-       bool tx_status;
-
-       if (unlikely(!IS_STARTED(ar)))
-               goto err_free;
-
-       hdr = (void *)skb->data;
-       info = IEEE80211_SKB_CB(skb);
-       len = skb->len;
-
-       spin_lock_irqsave(&ar->tx_stats_lock, flags);
-       if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) {
-               spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-               return NETDEV_TX_OK;
-       }
-
-       ar->tx_stats[queue].len++;
-       ar->tx_stats[queue].count++;
-       if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len)
-               ieee80211_stop_queue(hw, queue);
-
-       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
-       txc = (void *)skb_push(skb, sizeof(*txc));
-
-       tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) ||
-                   ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0));
-
-       if (info->control.hw_key) {
-               icv = info->control.hw_key->icv_len;
-
-               switch (info->control.hw_key->alg) {
-               case ALG_WEP:
-                       keytype = AR9170_TX_MAC_ENCR_RC4;
-                       break;
-               case ALG_TKIP:
-                       keytype = AR9170_TX_MAC_ENCR_RC4;
-                       break;
-               case ALG_CCMP:
-                       keytype = AR9170_TX_MAC_ENCR_AES;
-                       break;
-               default:
-                       WARN_ON(1);
-                       goto err_dequeue;
-               }
-       }
-
-       /* Length */
-       txc->length = cpu_to_le16(len + icv + 4);
-
-       txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
-                                      AR9170_TX_MAC_BACKOFF);
-       txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
-                                       AR9170_TX_MAC_QOS_SHIFT);
-       txc->mac_control |= cpu_to_le16(keytype);
-       txc->phy_control = cpu_to_le32(0);
-
-       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
-
-       if (info->flags & IEEE80211_TX_CTL_AMPDU)
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
-
-       txrate = &info->control.rates[0];
-
-       if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
-       else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
-
-       if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
-
-       if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
-
-       if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
-       /* this works because 40 MHz is 2 and dup is 3 */
-       if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
-
-       if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
-
-       if (txrate->flags & IEEE80211_TX_RC_MCS) {
-               u32 r = txrate->idx;
-               u8 *txpower;
-
-               r <<= AR9170_TX_PHY_MCS_SHIFT;
-               if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK))
-                       goto err_dequeue;
-               txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
-
-               if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
-                       if (info->band == IEEE80211_BAND_5GHZ)
-                               txpower = ar->power_5G_ht40;
-                       else
-                               txpower = ar->power_2G_ht40;
-               } else {
-                       if (info->band == IEEE80211_BAND_5GHZ)
-                               txpower = ar->power_5G_ht20;
-                       else
-                               txpower = ar->power_2G_ht20;
-               }
-
-               power = txpower[(txrate->idx) & 7];
-       } else {
-               u8 *txpower;
-               u32 mod;
-               u32 phyrate;
-               u8 idx = txrate->idx;
-
-               if (info->band != IEEE80211_BAND_2GHZ) {
-                       idx += 4;
-                       txpower = ar->power_5G_leg;
-                       mod = AR9170_TX_PHY_MOD_OFDM;
-               } else {
-                       if (idx < 4) {
-                               txpower = ar->power_2G_cck;
-                               mod = AR9170_TX_PHY_MOD_CCK;
-                       } else {
-                               mod = AR9170_TX_PHY_MOD_OFDM;
-                               txpower = ar->power_2G_ofdm;
-                       }
-               }
-
-               rate = &__ar9170_ratetable[idx];
-
-               phyrate = rate->hw_value & 0xF;
-               power = txpower[(rate->hw_value & 0x30) >> 4];
-               phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
-
-               txc->phy_control |= cpu_to_le32(mod);
-               txc->phy_control |= cpu_to_le32(phyrate);
-       }
-
-       power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
-       power &= AR9170_TX_PHY_TX_PWR_MASK;
-       txc->phy_control |= cpu_to_le32(power);
-
-       /* set TX chains */
-       if (ar->eeprom.tx_mask == 1) {
-               chains = AR9170_TX_PHY_TXCHAIN_1;
-       } else {
-               chains = AR9170_TX_PHY_TXCHAIN_2;
-
-               /* >= 36M legacy OFDM - use only one chain */
-               if (rate && rate->bitrate >= 360)
-                       chains = AR9170_TX_PHY_TXCHAIN_1;
-       }
-       txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
-
-       if (tx_status) {
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
-               /*
-                * WARNING:
-                * Putting the QoS queue bits into an unexplored territory is
-                * certainly not elegant.
-                *
-                * In my defense: This idea provides a reasonable way to
-                * smuggle valuable information to the tx_status callback.
-                * Also, the idea behind this bit-abuse came straight from
-                * the original driver code.
-                */
-
-               txc->phy_control |=
-                       cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
-
-               if (info->control.sta) {
-                       sta_info = (void *) info->control.sta->drv_priv;
-                       skb_queue_tail(&sta_info->tx_status[queue], skb);
-               } else {
-                       skb_queue_tail(&ar->global_tx_status, skb);
-
-                       queue_delayed_work(ar->hw->workqueue,
-                                          &ar->tx_status_janitor,
-                                          msecs_to_jiffies(100));
-               }
-       }
-
-       err = ar->tx(ar, skb, tx_status, 0);
-       if (unlikely(tx_status && err)) {
-               if (info->control.sta)
-                       skb_unlink(skb, &sta_info->tx_status[queue]);
-               else
-                       skb_unlink(skb, &ar->global_tx_status);
-       }
-
-       return NETDEV_TX_OK;
-
-err_dequeue:
-       spin_lock_irqsave(&ar->tx_stats_lock, flags);
-       ar->tx_stats[queue].len--;
-       ar->tx_stats[queue].count--;
-       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
-err_free:
-       dev_kfree_skb(skb);
-       return NETDEV_TX_OK;
-}
-
-static int ar9170_op_add_interface(struct ieee80211_hw *hw,
-                                  struct ieee80211_if_init_conf *conf)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0;
-
-       mutex_lock(&ar->mutex);
-
-       if (ar->vif) {
-               err = -EBUSY;
-               goto unlock;
-       }
-
-       ar->vif = conf->vif;
-       memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
-
-       if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
-               ar->rx_software_decryption = true;
-               ar->disable_offload = true;
-       }
-
-       ar->cur_filter = 0;
-       ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
-       err = ar9170_update_frame_filter(ar);
-       if (err)
-               goto unlock;
-
-       err = ar9170_set_operating_mode(ar);
-
-unlock:
-       mutex_unlock(&ar->mutex);
-       return err;
-}
-
-static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
-                                      struct ieee80211_if_init_conf *conf)
-{
-       struct ar9170 *ar = hw->priv;
-
-       mutex_lock(&ar->mutex);
-       ar->vif = NULL;
-       ar->want_filter = 0;
-       ar9170_update_frame_filter(ar);
-       ar9170_set_beacon_timers(ar);
-       dev_kfree_skb(ar->beacon);
-       ar->beacon = NULL;
-       ar->sniffer_enabled = false;
-       ar->rx_software_decryption = false;
-       ar9170_set_operating_mode(ar);
-       mutex_unlock(&ar->mutex);
-}
-
-static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0;
-
-       mutex_lock(&ar->mutex);
-
-       if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_PS) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
-               /*
-                * is it long_frame_max_tx_count or short_frame_max_tx_count?
-                */
-
-               err = ar9170_set_hwretry_limit(ar,
-                       ar->hw->conf.long_frame_max_tx_count);
-               if (err)
-                       goto out;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) {
-               err = ar9170_set_beacon_timers(ar);
-               if (err)
-                       goto out;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               err = ar9170_set_channel(ar, hw->conf.channel,
-                                        AR9170_RFI_NONE, AR9170_BW_20);
-               if (err)
-                       goto out;
-               /* adjust slot time for 5 GHz */
-               if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
-                       err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
-                                              9 << 10);
-       }
-
-out:
-       mutex_unlock(&ar->mutex);
-       return err;
-}
-
-static int ar9170_op_config_interface(struct ieee80211_hw *hw,
-                                     struct ieee80211_vif *vif,
-                                     struct ieee80211_if_conf *conf)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0;
-
-       mutex_lock(&ar->mutex);
-
-       if (conf->changed & IEEE80211_IFCC_BSSID) {
-               memcpy(ar->bssid, conf->bssid, ETH_ALEN);
-               err = ar9170_set_operating_mode(ar);
-       }
-
-       if (conf->changed & IEEE80211_IFCC_BEACON) {
-               err = ar9170_update_beacon(ar);
-
-               if (err)
-                       goto out;
-               err = ar9170_set_beacon_timers(ar);
-       }
-
-out:
-       mutex_unlock(&ar->mutex);
-       return err;
-}
-
-static void ar9170_set_filters(struct work_struct *work)
-{
-       struct ar9170 *ar = container_of(work, struct ar9170,
-                                        filter_config_work);
-       int err;
-
-       if (unlikely(!IS_STARTED(ar)))
-               return ;
-
-       mutex_lock(&ar->mutex);
-       if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) {
-               err = ar9170_set_operating_mode(ar);
-               if (err)
-                       goto unlock;
-       }
-
-       if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) {
-               err = ar9170_update_multicast(ar);
-               if (err)
-                       goto unlock;
-       }
-
-       if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER)
-               err = ar9170_update_frame_filter(ar);
-
-unlock:
-       mutex_unlock(&ar->mutex);
-}
-
-static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
-                                      unsigned int changed_flags,
-                                      unsigned int *new_flags,
-                                      int mc_count, struct dev_mc_list *mclist)
-{
-       struct ar9170 *ar = hw->priv;
-
-       /* mask supported flags */
-       *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
-                     FIF_PROMISC_IN_BSS;
-
-       /*
-        * We can support more by setting the sniffer bit and
-        * then checking the error flags, later.
-        */
-
-       if (changed_flags & FIF_ALLMULTI) {
-               if (*new_flags & FIF_ALLMULTI) {
-                       ar->want_mc_hash = ~0ULL;
-               } else {
-                       u64 mchash;
-                       int i;
-
-                       /* always get broadcast frames */
-                       mchash = 1ULL << (0xff>>2);
-
-                       for (i = 0; i < mc_count; i++) {
-                               if (WARN_ON(!mclist))
-                                       break;
-                               mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
-                               mclist = mclist->next;
-                       }
-               ar->want_mc_hash = mchash;
-               }
-               ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST;
-       }
-
-       if (changed_flags & FIF_CONTROL) {
-               u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
-                            AR9170_MAC_REG_FTF_RTS |
-                            AR9170_MAC_REG_FTF_CTS |
-                            AR9170_MAC_REG_FTF_ACK |
-                            AR9170_MAC_REG_FTF_CFE |
-                            AR9170_MAC_REG_FTF_CFE_ACK;
-
-               if (*new_flags & FIF_CONTROL)
-                       ar->want_filter = ar->cur_filter | filter;
-               else
-                       ar->want_filter = ar->cur_filter & ~filter;
-
-               ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER;
-       }
-
-       if (changed_flags & FIF_PROMISC_IN_BSS) {
-               ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
-               ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC;
-       }
-
-       if (likely(IS_STARTED(ar)))
-               queue_work(ar->hw->workqueue, &ar->filter_config_work);
-}
-
-static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
-                                      struct ieee80211_vif *vif,
-                                      struct ieee80211_bss_conf *bss_conf,
-                                      u32 changed)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0;
-
-       mutex_lock(&ar->mutex);
-
-       ar9170_regwrite_begin(ar);
-
-       if (changed & BSS_CHANGED_ASSOC) {
-               ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
-
-#ifndef CONFIG_AR9170_LEDS
-               /* enable assoc LED. */
-               err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
-#endif /* CONFIG_AR9170_LEDS */
-       }
-
-       if (changed & BSS_CHANGED_HT) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & BSS_CHANGED_ERP_SLOT) {
-               u32 slottime = 20;
-
-               if (bss_conf->use_short_slot)
-                       slottime = 9;
-
-               ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
-       }
-
-       if (changed & BSS_CHANGED_BASIC_RATES) {
-               u32 cck, ofdm;
-
-               if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) {
-                       ofdm = bss_conf->basic_rates;
-                       cck = 0;
-               } else {
-                       /* four cck rates */
-                       cck = bss_conf->basic_rates & 0xf;
-                       ofdm = bss_conf->basic_rates >> 4;
-               }
-               ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
-                               ofdm << 8 | cck);
-       }
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-       mutex_unlock(&ar->mutex);
-}
-
-static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
-{
-       struct ar9170 *ar = hw->priv;
-       int err;
-       u32 tsf_low;
-       u32 tsf_high;
-       u64 tsf;
-
-       mutex_lock(&ar->mutex);
-       err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
-       if (!err)
-               err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
-       mutex_unlock(&ar->mutex);
-
-       if (WARN_ON(err))
-               return 0;
-
-       tsf = tsf_high;
-       tsf = (tsf << 32) | tsf_low;
-       return tsf;
-}
-
-static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-                         struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-                         struct ieee80211_key_conf *key)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0, i;
-       u8 ktype;
-
-       if ((!ar->vif) || (ar->disable_offload))
-               return -EOPNOTSUPP;
-
-       switch (key->alg) {
-       case ALG_WEP:
-               if (key->keylen == LEN_WEP40)
-                       ktype = AR9170_ENC_ALG_WEP64;
-               else
-                       ktype = AR9170_ENC_ALG_WEP128;
-               break;
-       case ALG_TKIP:
-               ktype = AR9170_ENC_ALG_TKIP;
-               break;
-       case ALG_CCMP:
-               ktype = AR9170_ENC_ALG_AESCCMP;
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       mutex_lock(&ar->mutex);
-       if (cmd == SET_KEY) {
-               if (unlikely(!IS_STARTED(ar))) {
-                       err = -EOPNOTSUPP;
-                       goto out;
-               }
-
-               /* group keys need all-zeroes address */
-               if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
-                       sta = NULL;
-
-               if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
-                       for (i = 0; i < 64; i++)
-                               if (!(ar->usedkeys & BIT(i)))
-                                       break;
-                       if (i == 64) {
-                               ar->rx_software_decryption = true;
-                               ar9170_set_operating_mode(ar);
-                               err = -ENOSPC;
-                               goto out;
-                       }
-               } else {
-                       i = 64 + key->keyidx;
-               }
-
-               key->hw_key_idx = i;
-
-               err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
-                                       key->key, min_t(u8, 16, key->keylen));
-               if (err)
-                       goto out;
-
-               if (key->alg == ALG_TKIP) {
-                       err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
-                                               ktype, 1, key->key + 16, 16);
-                       if (err)
-                               goto out;
-
-                       /*
-                        * hardware is not capable generating the MMIC
-                        * for fragmented frames!
-                        */
-                       key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-               }
-
-               if (i < 64)
-                       ar->usedkeys |= BIT(i);
-
-               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-       } else {
-               if (unlikely(!IS_STARTED(ar))) {
-                       /* The device is gone... together with the key ;-) */
-                       err = 0;
-                       goto out;
-               }
-
-               err = ar9170_disable_key(ar, key->hw_key_idx);
-               if (err)
-                       goto out;
-
-               if (key->hw_key_idx < 64) {
-                       ar->usedkeys &= ~BIT(key->hw_key_idx);
-               } else {
-                       err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
-                                               AR9170_ENC_ALG_NONE, 0,
-                                               NULL, 0);
-                       if (err)
-                               goto out;
-
-                       if (key->alg == ALG_TKIP) {
-                               err = ar9170_upload_key(ar, key->hw_key_idx,
-                                                       NULL,
-                                                       AR9170_ENC_ALG_NONE, 1,
-                                                       NULL, 0);
-                               if (err)
-                                       goto out;
-                       }
-
-               }
-       }
-
-       ar9170_regwrite_begin(ar);
-       ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
-       ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-
-out:
-       mutex_unlock(&ar->mutex);
-
-       return err;
-}
-
-static void ar9170_sta_notify(struct ieee80211_hw *hw,
-                             struct ieee80211_vif *vif,
-                             enum sta_notify_cmd cmd,
-                             struct ieee80211_sta *sta)
-{
-       struct ar9170 *ar = hw->priv;
-       struct ar9170_sta_info *info = (void *) sta->drv_priv;
-       struct sk_buff *skb;
-       unsigned int i;
-
-       switch (cmd) {
-       case STA_NOTIFY_ADD:
-               for (i = 0; i < ar->hw->queues; i++)
-                       skb_queue_head_init(&info->tx_status[i]);
-               break;
-
-       case STA_NOTIFY_REMOVE:
-
-               /*
-                * transfer all outstanding frames that need a tx_status
-                * reports to the global tx_status queue
-                */
-
-               for (i = 0; i < ar->hw->queues; i++) {
-                       while ((skb = skb_dequeue(&info->tx_status[i]))) {
-#ifdef AR9170_QUEUE_DEBUG
-                               printk(KERN_DEBUG "%s: queueing frame in "
-                                         "global tx_status queue =>\n",
-                                      wiphy_name(ar->hw->wiphy));
-
-                               ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-                               skb_queue_tail(&ar->global_tx_status, skb);
-                       }
-               }
-               queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
-                                  msecs_to_jiffies(100));
-               break;
-
-       default:
-               break;
-       }
-}
-
-static int ar9170_get_stats(struct ieee80211_hw *hw,
-                           struct ieee80211_low_level_stats *stats)
-{
-       struct ar9170 *ar = hw->priv;
-       u32 val;
-       int err;
-
-       mutex_lock(&ar->mutex);
-       err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
-       ar->stats.dot11ACKFailureCount += val;
-
-       memcpy(stats, &ar->stats, sizeof(*stats));
-       mutex_unlock(&ar->mutex);
-
-       return 0;
-}
-
-static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
-                              struct ieee80211_tx_queue_stats *tx_stats)
-{
-       struct ar9170 *ar = hw->priv;
-
-       spin_lock_bh(&ar->tx_stats_lock);
-       memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
-       spin_unlock_bh(&ar->tx_stats_lock);
-
-       return 0;
-}
-
-static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
-                         const struct ieee80211_tx_queue_params *param)
-{
-       struct ar9170 *ar = hw->priv;
-       int ret;
-
-       mutex_lock(&ar->mutex);
-       if ((param) && !(queue > ar->hw->queues)) {
-               memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
-                      param, sizeof(*param));
-
-               ret = ar9170_set_qos(ar);
-       } else
-               ret = -EINVAL;
-
-       mutex_unlock(&ar->mutex);
-       return ret;
-}
-
-static const struct ieee80211_ops ar9170_ops = {
-       .start                  = ar9170_op_start,
-       .stop                   = ar9170_op_stop,
-       .tx                     = ar9170_op_tx,
-       .add_interface          = ar9170_op_add_interface,
-       .remove_interface       = ar9170_op_remove_interface,
-       .config                 = ar9170_op_config,
-       .config_interface       = ar9170_op_config_interface,
-       .configure_filter       = ar9170_op_configure_filter,
-       .conf_tx                = ar9170_conf_tx,
-       .bss_info_changed       = ar9170_op_bss_info_changed,
-       .get_tsf                = ar9170_op_get_tsf,
-       .set_key                = ar9170_set_key,
-       .sta_notify             = ar9170_sta_notify,
-       .get_stats              = ar9170_get_stats,
-       .get_tx_stats           = ar9170_get_tx_stats,
-};
-
-void *ar9170_alloc(size_t priv_size)
-{
-       struct ieee80211_hw *hw;
-       struct ar9170 *ar;
-       int i;
-
-       hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
-       if (!hw)
-               return ERR_PTR(-ENOMEM);
-
-       ar = hw->priv;
-       ar->hw = hw;
-
-       mutex_init(&ar->mutex);
-       spin_lock_init(&ar->cmdlock);
-       spin_lock_init(&ar->tx_stats_lock);
-       skb_queue_head_init(&ar->global_tx_status);
-       skb_queue_head_init(&ar->global_tx_status_waste);
-       INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
-       INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
-       INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor);
-
-       /* all hw supports 2.4 GHz, so set channel to 1 by default */
-       ar->channel = &ar9170_2ghz_chantable[0];
-
-       /* first part of wiphy init */
-       ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-                                        BIT(NL80211_IFTYPE_WDS) |
-                                        BIT(NL80211_IFTYPE_ADHOC);
-       ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
-                        IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-                        IEEE80211_HW_SIGNAL_DBM |
-                        IEEE80211_HW_NOISE_DBM;
-
-       ar->hw->queues = __AR9170_NUM_TXQ;
-       ar->hw->extra_tx_headroom = 8;
-       ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
-
-       ar->hw->max_rates = 1;
-       ar->hw->max_rate_tries = 3;
-
-       for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
-               ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
-
-       return ar;
-}
-
-static int ar9170_read_eeprom(struct ar9170 *ar)
-{
-#define RW     8       /* number of words to read at once */
-#define RB     (sizeof(u32) * RW)
-       DECLARE_MAC_BUF(mbuf);
-       u8 *eeprom = (void *)&ar->eeprom;
-       u8 *addr = ar->eeprom.mac_address;
-       __le32 offsets[RW];
-       int i, j, err, bands = 0;
-
-       BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
-
-       BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
-#ifndef __CHECKER__
-       /* don't want to handle trailing remains */
-       BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
-#endif
-
-       for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
-               for (j = 0; j < RW; j++)
-                       offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
-                                                RB * i + 4 * j);
-
-               err = ar->exec_cmd(ar, AR9170_CMD_RREG,
-                                  RB, (u8 *) &offsets,
-                                  RB, eeprom + RB * i);
-               if (err)
-                       return err;
-       }
-
-#undef RW
-#undef RB
-
-       if (ar->eeprom.length == cpu_to_le16(0xFFFF))
-               return -ENODATA;
-
-       if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
-               ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
-               bands++;
-       }
-       if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
-               ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
-               bands++;
-       }
-       /*
-        * I measured this, a bandswitch takes roughly
-        * 135 ms and a frequency switch about 80.
-        *
-        * FIXME: measure these values again once EEPROM settings
-        *        are used, that will influence them!
-        */
-       if (bands == 2)
-               ar->hw->channel_change_time = 135 * 1000;
-       else
-               ar->hw->channel_change_time = 80 * 1000;
-
-       ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
-       ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
-
-       /* second part of wiphy init */
-       SET_IEEE80211_PERM_ADDR(ar->hw, addr);
-
-       return bands ? 0 : -EINVAL;
-}
-
-static int ar9170_reg_notifier(struct wiphy *wiphy,
-                       struct regulatory_request *request)
-{
-       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-       struct ar9170 *ar = hw->priv;
-
-       return ath_reg_notifier_apply(wiphy, request, &ar->regulatory);
-}
-
-int ar9170_register(struct ar9170 *ar, struct device *pdev)
-{
-       int err;
-
-       /* try to read EEPROM, init MAC addr */
-       err = ar9170_read_eeprom(ar);
-       if (err)
-               goto err_out;
-
-       err = ath_regd_init(&ar->regulatory, ar->hw->wiphy,
-                           ar9170_reg_notifier);
-
-       err = ieee80211_register_hw(ar->hw);
-       if (err)
-               goto err_out;
-
-       if (!ath_is_world_regd(&ar->regulatory))
-               regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2);
-
-       err = ar9170_init_leds(ar);
-       if (err)
-               goto err_unreg;
-
-#ifdef CONFIG_AR9170_LEDS
-       err = ar9170_register_leds(ar);
-       if (err)
-               goto err_unreg;
-#endif /* CONFIG_AR9170_LEDS */
-
-       dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
-                wiphy_name(ar->hw->wiphy));
-
-       return err;
-
-err_unreg:
-       ieee80211_unregister_hw(ar->hw);
-
-err_out:
-       return err;
-}
-
-void ar9170_unregister(struct ar9170 *ar)
-{
-#ifdef CONFIG_AR9170_LEDS
-       ar9170_unregister_leds(ar);
-#endif /* CONFIG_AR9170_LEDS */
-
-       ieee80211_unregister_hw(ar->hw);
-       mutex_destroy(&ar->mutex);
-}
diff --git a/drivers/net/wireless/ar9170/phy.c b/drivers/net/wireless/ar9170/phy.c
deleted file mode 100644 (file)
index 6ce2075..0000000
+++ /dev/null
@@ -1,1240 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * PHY and RF code
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 <linux/bitrev.h>
-#include "ar9170.h"
-#include "cmd.h"
-
-static int ar9170_init_power_cal(struct ar9170 *ar)
-{
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
-       ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
-
-       ar9170_regwrite_finish();
-       return ar9170_regwrite_result();
-}
-
-struct ar9170_phy_init {
-       u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
-};
-
-static struct ar9170_phy_init ar5416_phy_init[] = {
-       { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-       { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
-       { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
-       { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
-       { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
-       { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
-       { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
-       { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
-       { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
-       { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
-       { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
-       { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-       { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
-       { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
-       { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
-       { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
-       { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
-       { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
-       { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
-       { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
-       { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
-       { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
-       { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
-       { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
-       { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
-       { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
-       { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
-       { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
-       { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
-       { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-       { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
-       { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
-       { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
-       { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
-       { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
-       { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
-       { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
-       { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
-       { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
-       { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
-       { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-       { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-       { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
-       { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
-       { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
-       { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
-       { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
-       { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
-       { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
-       { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
-       { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
-       { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
-       { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
-       { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
-       { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
-       { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
-       { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
-       { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
-       { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
-       { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
-       { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
-       { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
-       { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
-       { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
-       { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
-       { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
-       { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
-       { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
-       { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
-       { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
-       { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
-       { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
-       { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
-       { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
-       { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
-       { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
-       { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
-       { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
-       { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
-       { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
-       { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
-       { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
-       { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
-       { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
-       { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
-       { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
-       { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
-       { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
-       { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
-       { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
-       { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
-       { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
-       { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
-       { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
-       { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
-       { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-       { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
-       { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
-       { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
-       { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
-       { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
-       { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
-       { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
-       { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
-       { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
-       { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
-       { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
-       { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
-       { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
-       { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
-       { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
-       { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
-       { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
-       { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
-       { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
-       { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
-       { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
-       { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
-       { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
-       { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
-       { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
-       { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
-       { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
-       { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
-       { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
-       { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
-       { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
-       { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
-       { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
-       { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
-       { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
-       { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
-       { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
-       { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
-       { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
-       { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
-       { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
-       { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
-       { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
-       { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
-       { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
-       { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
-       { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
-       { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
-       { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
-       { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
-       { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
-       { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
-       { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
-       { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
-       { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
-       { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
-       { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
-       { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-       { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
-       { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
-       { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
-       { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
-       { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
-       { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-       { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
-       { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
-       { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
-       { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
-       { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
-       { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
-       { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
-       { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
-       { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
-       { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
-       { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
-       { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
-       { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
-       { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
-       { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
-       { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
-       { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
-       { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
-       { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
-       { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
-       { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
-       { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
-       { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-       { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
-       { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
-       { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
-       { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
-       { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
-       { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
-       { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-       { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
-       { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
-       { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
-       { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
-       { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-/*     { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
-       { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
-       { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
-       { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
-       { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
-       { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
-       { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
-       { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
-       { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
-       { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
-       { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
-       { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
-       { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
-       { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
-       { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
-       { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
-       { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
-};
-
-int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
-{
-       int i, err;
-       u32 val;
-       bool is_2ghz = band == IEEE80211_BAND_2GHZ;
-       bool is_40mhz = false; /* XXX: for now */
-
-       ar9170_regwrite_begin(ar);
-
-       for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
-               if (is_40mhz) {
-                       if (is_2ghz)
-                               val = ar5416_phy_init[i]._2ghz_40;
-                       else
-                               val = ar5416_phy_init[i]._5ghz_40;
-               } else {
-                       if (is_2ghz)
-                               val = ar5416_phy_init[i]._2ghz_20;
-                       else
-                               val = ar5416_phy_init[i]._5ghz_20;
-               }
-
-               ar9170_regwrite(ar5416_phy_init[i].reg, val);
-       }
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-       if (err)
-               return err;
-
-       /* XXX: use EEPROM data here! */
-
-       err = ar9170_init_power_cal(ar);
-       if (err)
-               return err;
-
-       /* XXX: remove magic! */
-       if (is_2ghz)
-               err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
-       else
-               err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
-
-       return err;
-}
-
-struct ar9170_rf_init {
-       u32 reg, _5ghz, _2ghz;
-};
-
-static struct ar9170_rf_init ar9170_rf_init[] = {
-     /* bank 0 */
-     { 0x1c58b0,  0x1e5795e5,  0x1e5795e5},
-     { 0x1c58e0,  0x02008020,  0x02008020},
-     /* bank 1 */
-     { 0x1c58b0,  0x02108421,  0x02108421},
-     { 0x1c58ec,  0x00000008,  0x00000008},
-     /* bank 2 */
-     { 0x1c58b0,  0x0e73ff17,  0x0e73ff17},
-     { 0x1c58e0,  0x00000420,  0x00000420},
-     /* bank 3 */
-     { 0x1c58f0,  0x01400018,  0x01c00018},
-     /* bank 4 */
-     { 0x1c58b0,  0x000001a1,  0x000001a1},
-     { 0x1c58e8,  0x00000001,  0x00000001},
-     /* bank 5 */
-     { 0x1c58b0,  0x00000013,  0x00000013},
-     { 0x1c58e4,  0x00000002,  0x00000002},
-     /* bank 6 */
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00004000,  0x00004000},
-     { 0x1c58b0,  0x00006c00,  0x00006c00},
-     { 0x1c58b0,  0x00002c00,  0x00002c00},
-     { 0x1c58b0,  0x00004800,  0x00004800},
-     { 0x1c58b0,  0x00004000,  0x00004000},
-     { 0x1c58b0,  0x00006000,  0x00006000},
-     { 0x1c58b0,  0x00001000,  0x00001000},
-     { 0x1c58b0,  0x00004000,  0x00004000},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00087c00,  0x00087c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00005400,  0x00005400},
-     { 0x1c58b0,  0x00000c00,  0x00000c00},
-     { 0x1c58b0,  0x00001800,  0x00001800},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00006c00,  0x00006c00},
-     { 0x1c58b0,  0x00006c00,  0x00006c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00002c00,  0x00002c00},
-     { 0x1c58b0,  0x00003c00,  0x00003c00},
-     { 0x1c58b0,  0x00003800,  0x00003800},
-     { 0x1c58b0,  0x00001c00,  0x00001c00},
-     { 0x1c58b0,  0x00000800,  0x00000800},
-     { 0x1c58b0,  0x00000408,  0x00000408},
-     { 0x1c58b0,  0x00004c15,  0x00004c15},
-     { 0x1c58b0,  0x00004188,  0x00004188},
-     { 0x1c58b0,  0x0000201e,  0x0000201e},
-     { 0x1c58b0,  0x00010408,  0x00010408},
-     { 0x1c58b0,  0x00000801,  0x00000801},
-     { 0x1c58b0,  0x00000c08,  0x00000c08},
-     { 0x1c58b0,  0x0000181e,  0x0000181e},
-     { 0x1c58b0,  0x00001016,  0x00001016},
-     { 0x1c58b0,  0x00002800,  0x00002800},
-     { 0x1c58b0,  0x00004010,  0x00004010},
-     { 0x1c58b0,  0x0000081c,  0x0000081c},
-     { 0x1c58b0,  0x00000115,  0x00000115},
-     { 0x1c58b0,  0x00000015,  0x00000015},
-     { 0x1c58b0,  0x00000066,  0x00000066},
-     { 0x1c58b0,  0x0000001c,  0x0000001c},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000004,  0x00000004},
-     { 0x1c58b0,  0x00000015,  0x00000015},
-     { 0x1c58b0,  0x0000001f,  0x0000001f},
-     { 0x1c58e0,  0x00000000,  0x00000400},
-     /* bank 7 */
-     { 0x1c58b0,  0x000000a0,  0x000000a0},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000040,  0x00000040},
-     { 0x1c58f0,  0x0000001c,  0x0000001c},
-};
-
-static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
-{
-       int err, i;
-
-       ar9170_regwrite_begin(ar);
-
-       for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
-               ar9170_regwrite(ar9170_rf_init[i].reg,
-                               band5ghz ? ar9170_rf_init[i]._5ghz
-                                        : ar9170_rf_init[i]._2ghz);
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-       if (err)
-               printk(KERN_ERR "%s: rf init failed\n",
-                      wiphy_name(ar->hw->wiphy));
-       return err;
-}
-
-static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
-                                   u32 freq, enum ar9170_bw bw)
-{
-       int err;
-       u32 d0, d1, td0, td1, fd0, fd1;
-       u8 chansel;
-       u8 refsel0 = 1, refsel1 = 0;
-       u8 lf_synth = 0;
-
-       switch (bw) {
-       case AR9170_BW_40_ABOVE:
-               freq += 10;
-               break;
-       case AR9170_BW_40_BELOW:
-               freq -= 10;
-               break;
-       case AR9170_BW_20:
-               break;
-       case __AR9170_NUM_BW:
-               BUG();
-       }
-
-       if (band5ghz) {
-               if (freq % 10) {
-                       chansel = (freq - 4800) / 5;
-               } else {
-                       chansel = ((freq - 4800) / 10) * 2;
-                       refsel0 = 0;
-                       refsel1 = 1;
-               }
-               chansel = byte_rev_table[chansel];
-       } else {
-               if (freq == 2484) {
-                       chansel = 10 + (freq - 2274) / 5;
-                       lf_synth = 1;
-               } else
-                       chansel = 16 + (freq - 2272) / 5;
-               chansel *= 4;
-               chansel = byte_rev_table[chansel];
-       }
-
-       d1 =    chansel;
-       d0 =    0x21 |
-               refsel0 << 3 |
-               refsel1 << 2 |
-               lf_synth << 1;
-       td0 =   d0 & 0x1f;
-       td1 =   d1 & 0x1f;
-       fd0 =   td1 << 5 | td0;
-
-       td0 =   (d0 >> 5) & 0x7;
-       td1 =   (d1 >> 5) & 0x7;
-       fd1 =   td1 << 5 | td0;
-
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(0x1c58b0, fd0);
-       ar9170_regwrite(0x1c58e8, fd1);
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-       if (err)
-               return err;
-
-       msleep(10);
-
-       return 0;
-}
-
-struct ar9170_phy_freq_params {
-       u8 coeff_exp;
-       u16 coeff_man;
-       u8 coeff_exp_shgi;
-       u16 coeff_man_shgi;
-};
-
-struct ar9170_phy_freq_entry {
-       u16 freq;
-       struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
-};
-
-/* NB: must be in sync with channel tables in main! */
-static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
-/*
- *     freq,
- *             20MHz,
- *             40MHz (below),
- *             40Mhz (above),
- */
-       { 2412, {
-               { 3, 21737, 3, 19563, },
-               { 3, 21827, 3, 19644, },
-               { 3, 21647, 3, 19482, },
-       } },
-       { 2417, {
-               { 3, 21692, 3, 19523, },
-               { 3, 21782, 3, 19604, },
-               { 3, 21602, 3, 19442, },
-       } },
-       { 2422, {
-               { 3, 21647, 3, 19482, },
-               { 3, 21737, 3, 19563, },
-               { 3, 21558, 3, 19402, },
-       } },
-       { 2427, {
-               { 3, 21602, 3, 19442, },
-               { 3, 21692, 3, 19523, },
-               { 3, 21514, 3, 19362, },
-       } },
-       { 2432, {
-               { 3, 21558, 3, 19402, },
-               { 3, 21647, 3, 19482, },
-               { 3, 21470, 3, 19323, },
-       } },
-       { 2437, {
-               { 3, 21514, 3, 19362, },
-               { 3, 21602, 3, 19442, },
-               { 3, 21426, 3, 19283, },
-       } },
-       { 2442, {
-               { 3, 21470, 3, 19323, },
-               { 3, 21558, 3, 19402, },
-               { 3, 21382, 3, 19244, },
-       } },
-       { 2447, {
-               { 3, 21426, 3, 19283, },
-               { 3, 21514, 3, 19362, },
-               { 3, 21339, 3, 19205, },
-       } },
-       { 2452, {
-               { 3, 21382, 3, 19244, },
-               { 3, 21470, 3, 19323, },
-               { 3, 21295, 3, 19166, },
-       } },
-       { 2457, {
-               { 3, 21339, 3, 19205, },
-               { 3, 21426, 3, 19283, },
-               { 3, 21252, 3, 19127, },
-       } },
-       { 2462, {
-               { 3, 21295, 3, 19166, },
-               { 3, 21382, 3, 19244, },
-               { 3, 21209, 3, 19088, },
-       } },
-       { 2467, {
-               { 3, 21252, 3, 19127, },
-               { 3, 21339, 3, 19205, },
-               { 3, 21166, 3, 19050, },
-       } },
-       { 2472, {
-               { 3, 21209, 3, 19088, },
-               { 3, 21295, 3, 19166, },
-               { 3, 21124, 3, 19011, },
-       } },
-       { 2484, {
-               { 3, 21107, 3, 18996, },
-               { 3, 21192, 3, 19073, },
-               { 3, 21022, 3, 18920, },
-       } },
-       { 4920, {
-               { 4, 21313, 4, 19181, },
-               { 4, 21356, 4, 19220, },
-               { 4, 21269, 4, 19142, },
-       } },
-       { 4940, {
-               { 4, 21226, 4, 19104, },
-               { 4, 21269, 4, 19142, },
-               { 4, 21183, 4, 19065, },
-       } },
-       { 4960, {
-               { 4, 21141, 4, 19027, },
-               { 4, 21183, 4, 19065, },
-               { 4, 21098, 4, 18988, },
-       } },
-       { 4980, {
-               { 4, 21056, 4, 18950, },
-               { 4, 21098, 4, 18988, },
-               { 4, 21014, 4, 18912, },
-       } },
-       { 5040, {
-               { 4, 20805, 4, 18725, },
-               { 4, 20846, 4, 18762, },
-               { 4, 20764, 4, 18687, },
-       } },
-       { 5060, {
-               { 4, 20723, 4, 18651, },
-               { 4, 20764, 4, 18687, },
-               { 4, 20682, 4, 18614, },
-       } },
-       { 5080, {
-               { 4, 20641, 4, 18577, },
-               { 4, 20682, 4, 18614, },
-               { 4, 20601, 4, 18541, },
-       } },
-       { 5180, {
-               { 4, 20243, 4, 18219, },
-               { 4, 20282, 4, 18254, },
-               { 4, 20204, 4, 18183, },
-       } },
-       { 5200, {
-               { 4, 20165, 4, 18148, },
-               { 4, 20204, 4, 18183, },
-               { 4, 20126, 4, 18114, },
-       } },
-       { 5220, {
-               { 4, 20088, 4, 18079, },
-               { 4, 20126, 4, 18114, },
-               { 4, 20049, 4, 18044, },
-       } },
-       { 5240, {
-               { 4, 20011, 4, 18010, },
-               { 4, 20049, 4, 18044, },
-               { 4, 19973, 4, 17976, },
-       } },
-       { 5260, {
-               { 4, 19935, 4, 17941, },
-               { 4, 19973, 4, 17976, },
-               { 4, 19897, 4, 17907, },
-       } },
-       { 5280, {
-               { 4, 19859, 4, 17873, },
-               { 4, 19897, 4, 17907, },
-               { 4, 19822, 4, 17840, },
-       } },
-       { 5300, {
-               { 4, 19784, 4, 17806, },
-               { 4, 19822, 4, 17840, },
-               { 4, 19747, 4, 17772, },
-       } },
-       { 5320, {
-               { 4, 19710, 4, 17739, },
-               { 4, 19747, 4, 17772, },
-               { 4, 19673, 4, 17706, },
-       } },
-       { 5500, {
-               { 4, 19065, 4, 17159, },
-               { 4, 19100, 4, 17190, },
-               { 4, 19030, 4, 17127, },
-       } },
-       { 5520, {
-               { 4, 18996, 4, 17096, },
-               { 4, 19030, 4, 17127, },
-               { 4, 18962, 4, 17065, },
-       } },
-       { 5540, {
-               { 4, 18927, 4, 17035, },
-               { 4, 18962, 4, 17065, },
-               { 4, 18893, 4, 17004, },
-       } },
-       { 5560, {
-               { 4, 18859, 4, 16973, },
-               { 4, 18893, 4, 17004, },
-               { 4, 18825, 4, 16943, },
-       } },
-       { 5580, {
-               { 4, 18792, 4, 16913, },
-               { 4, 18825, 4, 16943, },
-               { 4, 18758, 4, 16882, },
-       } },
-       { 5600, {
-               { 4, 18725, 4, 16852, },
-               { 4, 18758, 4, 16882, },
-               { 4, 18691, 4, 16822, },
-       } },
-       { 5620, {
-               { 4, 18658, 4, 16792, },
-               { 4, 18691, 4, 16822, },
-               { 4, 18625, 4, 16762, },
-       } },
-       { 5640, {
-               { 4, 18592, 4, 16733, },
-               { 4, 18625, 4, 16762, },
-               { 4, 18559, 4, 16703, },
-       } },
-       { 5660, {
-               { 4, 18526, 4, 16673, },
-               { 4, 18559, 4, 16703, },
-               { 4, 18493, 4, 16644, },
-       } },
-       { 5680, {
-               { 4, 18461, 4, 16615, },
-               { 4, 18493, 4, 16644, },
-               { 4, 18428, 4, 16586, },
-       } },
-       { 5700, {
-               { 4, 18396, 4, 16556, },
-               { 4, 18428, 4, 16586, },
-               { 4, 18364, 4, 16527, },
-       } },
-       { 5745, {
-               { 4, 18252, 4, 16427, },
-               { 4, 18284, 4, 16455, },
-               { 4, 18220, 4, 16398, },
-       } },
-       { 5765, {
-               { 4, 18189, 5, 32740, },
-               { 4, 18220, 4, 16398, },
-               { 4, 18157, 5, 32683, },
-       } },
-       { 5785, {
-               { 4, 18126, 5, 32626, },
-               { 4, 18157, 5, 32683, },
-               { 4, 18094, 5, 32570, },
-       } },
-       { 5805, {
-               { 4, 18063, 5, 32514, },
-               { 4, 18094, 5, 32570, },
-               { 4, 18032, 5, 32458, },
-       } },
-       { 5825, {
-               { 4, 18001, 5, 32402, },
-               { 4, 18032, 5, 32458, },
-               { 4, 17970, 5, 32347, },
-       } },
-       { 5170, {
-               { 4, 20282, 4, 18254, },
-               { 4, 20321, 4, 18289, },
-               { 4, 20243, 4, 18219, },
-       } },
-       { 5190, {
-               { 4, 20204, 4, 18183, },
-               { 4, 20243, 4, 18219, },
-               { 4, 20165, 4, 18148, },
-       } },
-       { 5210, {
-               { 4, 20126, 4, 18114, },
-               { 4, 20165, 4, 18148, },
-               { 4, 20088, 4, 18079, },
-       } },
-       { 5230, {
-               { 4, 20049, 4, 18044, },
-               { 4, 20088, 4, 18079, },
-               { 4, 20011, 4, 18010, },
-       } },
-};
-
-static const struct ar9170_phy_freq_params *
-ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
-                        enum ar9170_bw bw)
-{
-       unsigned int chanidx = 0;
-       u16 freq = 2412;
-
-       if (channel) {
-               chanidx = channel->hw_value;
-               freq = channel->center_freq;
-       }
-
-       BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
-
-       BUILD_BUG_ON(__AR9170_NUM_BW != 3);
-
-       WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
-
-       return &ar9170_phy_freq_params[chanidx].params[bw];
-}
-
-
-int ar9170_init_rf(struct ar9170 *ar)
-{
-       const struct ar9170_phy_freq_params *freqpar;
-       __le32 cmd[7];
-       int err;
-
-       err = ar9170_init_rf_banks_0_7(ar, false);
-       if (err)
-               return err;
-
-       err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
-       if (err)
-               return err;
-
-       freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
-
-       cmd[0] = cpu_to_le32(2412 * 1000);
-       cmd[1] = cpu_to_le32(0);
-       cmd[2] = cpu_to_le32(1);
-       cmd[3] = cpu_to_le32(freqpar->coeff_exp);
-       cmd[4] = cpu_to_le32(freqpar->coeff_man);
-       cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
-       cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
-
-       /* RF_INIT echoes the command back to us */
-       err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
-                          sizeof(cmd), (u8 *)cmd,
-                          sizeof(cmd), (u8 *)cmd);
-       if (err)
-               return err;
-
-       msleep(1000);
-
-       return ar9170_echo_test(ar, 0xaabbccdd);
-}
-
-static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
-{
-       int idx = nfreqs - 2;
-
-       while (idx >= 0) {
-               if (f >= freqs[idx])
-                       return idx;
-               idx--;
-       }
-
-       return 0;
-}
-
-static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
-{
-       /* nothing to interpolate, it's horizontal */
-       if (y2 == y1)
-               return y1;
-
-       /* check if we hit one of the edges */
-       if (x == x1)
-               return y1;
-       if (x == x2)
-               return y2;
-
-       /* x1 == x2 is bad, hopefully == x */
-       if (x2 == x1)
-               return y1;
-
-       return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
-}
-
-static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
-{
-#define SHIFT          8
-       s32 y;
-
-       y = ar9170_interpolate_s32(x << SHIFT,
-                                  x1 << SHIFT, y1 << SHIFT,
-                                  x2 << SHIFT, y2 << SHIFT);
-
-       /*
-        * XXX: unwrap this expression
-        *      Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
-        *      Can we rely on the compiler to optimise away the div?
-        */
-       return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
-#undef SHIFT
-}
-
-static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
-{
-       struct ar9170_calibration_target_power_legacy *ctpl;
-       struct ar9170_calibration_target_power_ht *ctph;
-       u8 *ctpres;
-       int ntargets;
-       int idx, i, n;
-       u8 ackpower, ackchains, f;
-       u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
-
-       if (freq < 3000)
-               f = freq - 2300;
-       else
-               f = (freq - 4800)/5;
-
-       /*
-        * cycle through the various modes
-        *
-        * legacy modes first: 5G, 2G CCK, 2G OFDM
-        */
-       for (i = 0; i < 3; i++) {
-               switch (i) {
-               case 0: /* 5 GHz legacy */
-                       ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
-                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
-                       ctpres = ar->power_5G_leg;
-                       break;
-               case 1: /* 2.4 GHz CCK */
-                       ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
-                       ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
-                       ctpres = ar->power_2G_cck;
-                       break;
-               case 2: /* 2.4 GHz OFDM */
-                       ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
-                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
-                       ctpres = ar->power_2G_ofdm;
-                       break;
-               default:
-                       BUG();
-               }
-
-               for (n = 0; n < ntargets; n++) {
-                       if (ctpl[n].freq == 0xff)
-                               break;
-                       pwr_freqs[n] = ctpl[n].freq;
-               }
-               ntargets = n;
-               idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
-               for (n = 0; n < 4; n++)
-                       ctpres[n] = ar9170_interpolate_u8(
-                                       f,
-                                       ctpl[idx + 0].freq,
-                                       ctpl[idx + 0].power[n],
-                                       ctpl[idx + 1].freq,
-                                       ctpl[idx + 1].power[n]);
-       }
-
-       /*
-        * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
-        */
-       for (i = 0; i < 4; i++) {
-               switch (i) {
-               case 0: /* 5 GHz HT 20 */
-                       ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
-                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
-                       ctpres = ar->power_5G_ht20;
-                       break;
-               case 1: /* 5 GHz HT 40 */
-                       ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
-                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
-                       ctpres = ar->power_5G_ht40;
-                       break;
-               case 2: /* 2.4 GHz HT 20 */
-                       ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
-                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
-                       ctpres = ar->power_2G_ht20;
-                       break;
-               case 3: /* 2.4 GHz HT 40 */
-                       ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
-                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
-                       ctpres = ar->power_2G_ht40;
-                       break;
-               default:
-                       BUG();
-               }
-
-               for (n = 0; n < ntargets; n++) {
-                       if (ctph[n].freq == 0xff)
-                               break;
-                       pwr_freqs[n] = ctph[n].freq;
-               }
-               ntargets = n;
-               idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
-               for (n = 0; n < 8; n++)
-                       ctpres[n] = ar9170_interpolate_u8(
-                                       f,
-                                       ctph[idx + 0].freq,
-                                       ctph[idx + 0].power[n],
-                                       ctph[idx + 1].freq,
-                                       ctph[idx + 1].power[n]);
-       }
-
-       /* set ACK/CTS TX power */
-       ar9170_regwrite_begin(ar);
-
-       if (ar->eeprom.tx_mask != 1)
-               ackchains = AR9170_TX_PHY_TXCHAIN_2;
-       else
-               ackchains = AR9170_TX_PHY_TXCHAIN_1;
-
-       if (freq < 3000)
-               ackpower = ar->power_2G_ofdm[0] & 0x3f;
-       else
-               ackpower = ar->power_5G_leg[0] & 0x3f;
-
-       ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
-       ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
-                                 ackpower << 21 | ackchains << 27);
-
-       ar9170_regwrite_finish();
-       return ar9170_regwrite_result();
-}
-
-static int ar9170_calc_noise_dbm(u32 raw_noise)
-{
-       if (raw_noise & 0x100)
-               return ~((raw_noise & 0x0ff) >> 1);
-       else
-               return (raw_noise & 0xff) >> 1;
-}
-
-int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
-                      enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
-{
-       const struct ar9170_phy_freq_params *freqpar;
-       u32 cmd, tmp, offs;
-       __le32 vals[8];
-       int i, err;
-       bool bandswitch;
-
-       /* clear BB heavy clip enable */
-       err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
-       if (err)
-               return err;
-
-       /* may be NULL at first setup */
-       if (ar->channel)
-               bandswitch = ar->channel->band != channel->band;
-       else
-               bandswitch = true;
-
-       /* HW workaround */
-       if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
-           channel->center_freq <= 2417)
-               bandswitch = true;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
-       if (err)
-               return err;
-
-       if (rfi != AR9170_RFI_NONE || bandswitch) {
-               u32 val = 0x400;
-
-               if (rfi == AR9170_RFI_COLD)
-                       val = 0x800;
-
-               /* warm/cold reset BB/ADDA */
-               err = ar9170_write_reg(ar, 0x1d4004, val);
-               if (err)
-                       return err;
-
-               err = ar9170_write_reg(ar, 0x1d4004, 0x0);
-               if (err)
-                       return err;
-
-               err = ar9170_init_phy(ar, channel->band);
-               if (err)
-                       return err;
-
-               err = ar9170_init_rf_banks_0_7(ar,
-                       channel->band == IEEE80211_BAND_5GHZ);
-               if (err)
-                       return err;
-
-               cmd = AR9170_CMD_RF_INIT;
-       } else {
-               cmd = AR9170_CMD_FREQUENCY;
-       }
-
-       err = ar9170_init_rf_bank4_pwr(ar,
-               channel->band == IEEE80211_BAND_5GHZ,
-               channel->center_freq, bw);
-       if (err)
-               return err;
-
-       switch (bw) {
-       case AR9170_BW_20:
-               tmp = 0x240;
-               offs = 0;
-               break;
-       case AR9170_BW_40_BELOW:
-               tmp = 0x2c4;
-               offs = 3;
-               break;
-       case AR9170_BW_40_ABOVE:
-               tmp = 0x2d4;
-               offs = 1;
-               break;
-       default:
-               BUG();
-               return -ENOSYS;
-       }
-
-       if (0 /* 2 streams capable */)
-               tmp |= 0x100;
-
-       err = ar9170_write_reg(ar, 0x1c5804, tmp);
-       if (err)
-               return err;
-
-       err = ar9170_set_power_cal(ar, channel->center_freq, bw);
-       if (err)
-               return err;
-
-       freqpar = ar9170_get_hw_dyn_params(channel, bw);
-
-       vals[0] = cpu_to_le32(channel->center_freq * 1000);
-       vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1);
-       vals[2] = cpu_to_le32(offs << 2 | 1);
-       vals[3] = cpu_to_le32(freqpar->coeff_exp);
-       vals[4] = cpu_to_le32(freqpar->coeff_man);
-       vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
-       vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
-       vals[7] = cpu_to_le32(1000);
-
-       err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
-                          sizeof(vals), (u8 *)vals);
-       if (err)
-               return err;
-
-       for (i = 0; i < 2; i++) {
-               ar->noise[i] = ar9170_calc_noise_dbm(
-                               (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
-
-               ar->noise[i + 2] = ar9170_calc_noise_dbm(
-                                   (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
-       }
-
-       ar->channel = channel;
-       return 0;
-}
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c
deleted file mode 100644 (file)
index fddda47..0000000
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * USB - frontend
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 <linux/module.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <linux/etherdevice.h>
-#include <net/mac80211.h>
-#include "ar9170.h"
-#include "cmd.h"
-#include "hw.h"
-#include "usb.h"
-
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
-MODULE_FIRMWARE("ar9170-1.fw");
-MODULE_FIRMWARE("ar9170-2.fw");
-
-static struct usb_device_id ar9170_usb_ids[] = {
-       /* Atheros 9170 */
-       { USB_DEVICE(0x0cf3, 0x9170) },
-       /* Atheros TG121N */
-       { USB_DEVICE(0x0cf3, 0x1001) },
-       /* Cace Airpcap NX */
-       { USB_DEVICE(0xcace, 0x0300) },
-       /* D-Link DWA 160A */
-       { USB_DEVICE(0x07d1, 0x3c10) },
-       /* Netgear WNDA3100 */
-       { USB_DEVICE(0x0846, 0x9010) },
-       /* Netgear WN111 v2 */
-       { USB_DEVICE(0x0846, 0x9001) },
-       /* Zydas ZD1221 */
-       { USB_DEVICE(0x0ace, 0x1221) },
-       /* ZyXEL NWD271N */
-       { USB_DEVICE(0x0586, 0x3417) },
-       /* Z-Com UB81 BG */
-       { USB_DEVICE(0x0cde, 0x0023) },
-       /* Z-Com UB82 ABG */
-       { USB_DEVICE(0x0cde, 0x0026) },
-       /* Arcadyan WN7512 */
-       { USB_DEVICE(0x083a, 0xf522) },
-       /* Planex GWUS300 */
-       { USB_DEVICE(0x2019, 0x5304) },
-       /* IO-Data WNGDNUS2 */
-       { USB_DEVICE(0x04bb, 0x093f) },
-
-       /* terminate */
-       {}
-};
-MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
-
-static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
-{
-       struct sk_buff *skb = urb->context;
-       struct ar9170_usb *aru = (struct ar9170_usb *)
-             usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
-
-       if (!aru) {
-               dev_kfree_skb_irq(skb);
-               return ;
-       }
-
-       ar9170_handle_tx_status(&aru->common, skb, false,
-                               AR9170_TX_STATUS_COMPLETE);
-}
-
-static void ar9170_usb_tx_urb_complete(struct urb *urb)
-{
-}
-
-static void ar9170_usb_irq_completed(struct urb *urb)
-{
-       struct ar9170_usb *aru = urb->context;
-
-       switch (urb->status) {
-       /* everything is fine */
-       case 0:
-               break;
-
-       /* disconnect */
-       case -ENOENT:
-       case -ECONNRESET:
-       case -ENODEV:
-       case -ESHUTDOWN:
-               goto free;
-
-       default:
-               goto resubmit;
-       }
-
-       print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET,
-                            urb->transfer_buffer, urb->actual_length);
-
-resubmit:
-       usb_anchor_urb(urb, &aru->rx_submitted);
-       if (usb_submit_urb(urb, GFP_ATOMIC)) {
-               usb_unanchor_urb(urb);
-               goto free;
-       }
-
-       return;
-
-free:
-       usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
-}
-
-static void ar9170_usb_rx_completed(struct urb *urb)
-{
-       struct sk_buff *skb = urb->context;
-       struct ar9170_usb *aru = (struct ar9170_usb *)
-               usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
-       int err;
-
-       if (!aru)
-               goto free;
-
-       switch (urb->status) {
-       /* everything is fine */
-       case 0:
-               break;
-
-       /* disconnect */
-       case -ENOENT:
-       case -ECONNRESET:
-       case -ENODEV:
-       case -ESHUTDOWN:
-               goto free;
-
-       default:
-               goto resubmit;
-       }
-
-       skb_put(skb, urb->actual_length);
-       ar9170_rx(&aru->common, skb);
-
-resubmit:
-       skb_reset_tail_pointer(skb);
-       skb_trim(skb, 0);
-
-       usb_anchor_urb(urb, &aru->rx_submitted);
-       err = usb_submit_urb(urb, GFP_ATOMIC);
-       if (err) {
-               usb_unanchor_urb(urb);
-               dev_kfree_skb_irq(skb);
-       }
-
-       return ;
-
-free:
-       dev_kfree_skb_irq(skb);
-       return;
-}
-
-static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
-                                 struct urb *urb, gfp_t gfp)
-{
-       struct sk_buff *skb;
-
-       skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
-       if (!skb)
-               return -ENOMEM;
-
-       /* reserve some space for mac80211's radiotap */
-       skb_reserve(skb, 32);
-
-       usb_fill_bulk_urb(urb, aru->udev,
-                         usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
-                         skb->data, min(skb_tailroom(skb),
-                         AR9170_MAX_RX_BUFFER_SIZE),
-                         ar9170_usb_rx_completed, skb);
-
-       return 0;
-}
-
-static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
-{
-       struct urb *urb = NULL;
-       void *ibuf;
-       int err = -ENOMEM;
-
-       /* initialize interrupt endpoint */
-       urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!urb)
-               goto out;
-
-       ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
-       if (!ibuf)
-               goto out;
-
-       usb_fill_int_urb(urb, aru->udev,
-                        usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
-                        64, ar9170_usb_irq_completed, aru, 1);
-       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-       usb_anchor_urb(urb, &aru->rx_submitted);
-       err = usb_submit_urb(urb, GFP_KERNEL);
-       if (err) {
-               usb_unanchor_urb(urb);
-               usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
-                               urb->transfer_dma);
-       }
-
-out:
-       usb_free_urb(urb);
-       return err;
-}
-
-static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
-{
-       struct urb *urb;
-       int i;
-       int err = -EINVAL;
-
-       for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
-               err = -ENOMEM;
-               urb = usb_alloc_urb(0, GFP_KERNEL);
-               if (!urb)
-                       goto err_out;
-
-               err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
-               if (err) {
-                       usb_free_urb(urb);
-                       goto err_out;
-               }
-
-               usb_anchor_urb(urb, &aru->rx_submitted);
-               err = usb_submit_urb(urb, GFP_KERNEL);
-               if (err) {
-                       usb_unanchor_urb(urb);
-                       dev_kfree_skb_any((void *) urb->transfer_buffer);
-                       usb_free_urb(urb);
-                       goto err_out;
-               }
-               usb_free_urb(urb);
-       }
-
-       /* the device now waiting for a firmware. */
-       aru->common.state = AR9170_IDLE;
-       return 0;
-
-err_out:
-
-       usb_kill_anchored_urbs(&aru->rx_submitted);
-       return err;
-}
-
-static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
-{
-       int ret;
-
-       aru->common.state = AR9170_UNKNOWN_STATE;
-
-       usb_unlink_anchored_urbs(&aru->tx_submitted);
-
-       /* give the LED OFF command and the deauth frame a chance to air. */
-       ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
-                                           msecs_to_jiffies(100));
-       if (ret == 0)
-               dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
-       usb_poison_anchored_urbs(&aru->tx_submitted);
-
-       usb_poison_anchored_urbs(&aru->rx_submitted);
-}
-
-static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
-                              unsigned int plen, void *payload,
-                              unsigned int outlen, void *out)
-{
-       struct ar9170_usb *aru = (void *) ar;
-       struct urb *urb = NULL;
-       unsigned long flags;
-       int err = -ENOMEM;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return -EPERM;
-
-       if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
-               return -EINVAL;
-
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
-       if (unlikely(!urb))
-               goto err_free;
-
-       ar->cmdbuf[0] = cpu_to_le32(plen);
-       ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
-       /* writing multiple regs fills this buffer already */
-       if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
-               memcpy(&ar->cmdbuf[1], payload, plen);
-
-       spin_lock_irqsave(&aru->common.cmdlock, flags);
-       aru->readbuf = (u8 *)out;
-       aru->readlen = outlen;
-       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-
-       usb_fill_int_urb(urb, aru->udev,
-                        usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
-                        aru->common.cmdbuf, plen + 4,
-                        ar9170_usb_tx_urb_complete, NULL, 1);
-
-       usb_anchor_urb(urb, &aru->tx_submitted);
-       err = usb_submit_urb(urb, GFP_ATOMIC);
-       if (err) {
-               usb_unanchor_urb(urb);
-               usb_free_urb(urb);
-               goto err_unbuf;
-       }
-       usb_free_urb(urb);
-
-       err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
-       if (err == 0) {
-               err = -ETIMEDOUT;
-               goto err_unbuf;
-       }
-
-       if (outlen >= 0 && aru->readlen != outlen) {
-               err = -EMSGSIZE;
-               goto err_unbuf;
-       }
-
-       return 0;
-
-err_unbuf:
-       /* Maybe the device was removed in the second we were waiting? */
-       if (IS_STARTED(ar)) {
-               dev_err(&aru->udev->dev, "no command feedback "
-                                        "received (%d).\n", err);
-
-               /* provide some maybe useful debug information */
-               print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
-                                    aru->common.cmdbuf, plen + 4);
-               dump_stack();
-       }
-
-       /* invalidate to avoid completing the next prematurely */
-       spin_lock_irqsave(&aru->common.cmdlock, flags);
-       aru->readbuf = NULL;
-       aru->readlen = 0;
-       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-
-err_free:
-
-       return err;
-}
-
-static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb,
-                        bool txstatus_needed, unsigned int extra_len)
-{
-       struct ar9170_usb *aru = (struct ar9170_usb *) ar;
-       struct urb *urb;
-       int err;
-
-       if (unlikely(!IS_STARTED(ar))) {
-               /* Seriously, what were you drink... err... thinking!? */
-               return -EPERM;
-       }
-
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
-       if (unlikely(!urb))
-               return -ENOMEM;
-
-       usb_fill_bulk_urb(urb, aru->udev,
-                         usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
-                         skb->data, skb->len + extra_len, (txstatus_needed ?
-                         ar9170_usb_tx_urb_complete :
-                         ar9170_usb_tx_urb_complete_free), skb);
-       urb->transfer_flags |= URB_ZERO_PACKET;
-
-       usb_anchor_urb(urb, &aru->tx_submitted);
-       err = usb_submit_urb(urb, GFP_ATOMIC);
-       if (unlikely(err))
-               usb_unanchor_urb(urb);
-
-       usb_free_urb(urb);
-       return err;
-}
-
-static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
-{
-       struct ar9170_usb *aru = (void *) ar;
-       unsigned long flags;
-       u32 in, out;
-
-       if (!buffer)
-               return ;
-
-       in = le32_to_cpup((__le32 *)buffer);
-       out = le32_to_cpu(ar->cmdbuf[0]);
-
-       /* mask off length byte */
-       out &= ~0xFF;
-
-       if (aru->readlen >= 0) {
-               /* add expected length */
-               out |= aru->readlen;
-       } else {
-               /* add obtained length */
-               out |= in & 0xFF;
-       }
-
-       /*
-        * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
-        * length and we cannot predict the correct length in advance.
-        * So we only check if we provided enough space for the data.
-        */
-       if (unlikely(out < in)) {
-               dev_warn(&aru->udev->dev, "received invalid command response "
-                                         "got %d bytes, instead of %d bytes "
-                                         "and the resp length is %d bytes\n",
-                        in, out, len);
-               print_hex_dump_bytes("ar9170 invalid resp: ",
-                                    DUMP_PREFIX_OFFSET, buffer, len);
-               /*
-                * Do not complete, then the command times out,
-                * and we get a stack trace from there.
-                */
-               return ;
-       }
-
-       spin_lock_irqsave(&aru->common.cmdlock, flags);
-       if (aru->readbuf && len > 0) {
-               memcpy(aru->readbuf, buffer + 4, len - 4);
-               aru->readbuf = NULL;
-       }
-       complete(&aru->cmd_wait);
-       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-}
-
-static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
-                            size_t len, u32 addr, bool complete)
-{
-       int transfer, err;
-       u8 *buf = kmalloc(4096, GFP_KERNEL);
-
-       if (!buf)
-               return -ENOMEM;
-
-       while (len) {
-               transfer = min_t(int, len, 4096);
-               memcpy(buf, data, transfer);
-
-               err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
-                                     0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
-                                     addr >> 8, 0, buf, transfer, 1000);
-
-               if (err < 0) {
-                       kfree(buf);
-                       return err;
-               }
-
-               len -= transfer;
-               data += transfer;
-               addr += transfer;
-       }
-       kfree(buf);
-
-       if (complete) {
-               err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
-                                     0x31 /* FW DL COMPLETE */,
-                                     0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
-       }
-
-       return 0;
-}
-
-static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
-{
-       int err = 0;
-
-       err = request_firmware(&aru->init_values, "ar9170-1.fw",
-                              &aru->udev->dev);
-       if (err) {
-               dev_err(&aru->udev->dev, "file with init values not found.\n");
-               return err;
-       }
-
-       err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
-       if (err) {
-               release_firmware(aru->init_values);
-               dev_err(&aru->udev->dev, "firmware file not found.\n");
-               return err;
-       }
-
-       return err;
-}
-
-static int ar9170_usb_reset(struct ar9170_usb *aru)
-{
-       int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
-
-       if (lock) {
-               ret = usb_lock_device_for_reset(aru->udev, aru->intf);
-               if (ret < 0) {
-                       dev_err(&aru->udev->dev, "unable to lock device "
-                               "for reset (%d).\n", ret);
-                       return ret;
-               }
-       }
-
-       ret = usb_reset_device(aru->udev);
-       if (lock)
-               usb_unlock_device(aru->udev);
-
-       /* let it rest - for a second - */
-       msleep(1000);
-
-       return ret;
-}
-
-static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
-{
-       int err;
-
-       /* First, upload initial values to device RAM */
-       err = ar9170_usb_upload(aru, aru->init_values->data,
-                               aru->init_values->size, 0x102800, false);
-       if (err) {
-               dev_err(&aru->udev->dev, "firmware part 1 "
-                       "upload failed (%d).\n", err);
-               return err;
-       }
-
-       /* Then, upload the firmware itself and start it */
-       return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
-                               0x200000, true);
-}
-
-static int ar9170_usb_init_transport(struct ar9170_usb *aru)
-{
-       struct ar9170 *ar = (void *) &aru->common;
-       int err;
-
-       ar9170_regwrite_begin(ar);
-
-       /* Set USB Rx stream mode MAX packet number to 2 */
-       ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
-
-       /* Set USB Rx stream mode timeout to 10us */
-       ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
-
-       ar9170_regwrite_finish();
-
-       err = ar9170_regwrite_result();
-       if (err)
-               dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
-
-       return err;
-}
-
-static void ar9170_usb_stop(struct ar9170 *ar)
-{
-       struct ar9170_usb *aru = (void *) ar;
-       int ret;
-
-       if (IS_ACCEPTING_CMD(ar))
-               aru->common.state = AR9170_STOPPED;
-
-       /* lets wait a while until the tx - queues are dried out */
-       ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
-                                           msecs_to_jiffies(1000));
-       if (ret == 0)
-               dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
-
-       usb_poison_anchored_urbs(&aru->tx_submitted);
-
-       /*
-        * Note:
-        * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
-        * Else we would end up with a unresponsive device...
-        */
-}
-
-static int ar9170_usb_open(struct ar9170 *ar)
-{
-       struct ar9170_usb *aru = (void *) ar;
-       int err;
-
-       usb_unpoison_anchored_urbs(&aru->tx_submitted);
-       err = ar9170_usb_init_transport(aru);
-       if (err) {
-               usb_poison_anchored_urbs(&aru->tx_submitted);
-               return err;
-       }
-
-       aru->common.state = AR9170_IDLE;
-       return 0;
-}
-
-static int ar9170_usb_init_device(struct ar9170_usb *aru)
-{
-       int err;
-
-       err = ar9170_usb_alloc_rx_irq_urb(aru);
-       if (err)
-               goto err_out;
-
-       err = ar9170_usb_alloc_rx_bulk_urbs(aru);
-       if (err)
-               goto err_unrx;
-
-       err = ar9170_usb_upload_firmware(aru);
-       if (err) {
-               err = ar9170_echo_test(&aru->common, 0x60d43110);
-               if (err) {
-                       /* force user invention, by disabling the device */
-                       err = usb_driver_set_configuration(aru->udev, -1);
-                       dev_err(&aru->udev->dev, "device is in a bad state. "
-                                                "please reconnect it!\n");
-                       goto err_unrx;
-               }
-       }
-
-       return 0;
-
-err_unrx:
-       ar9170_usb_cancel_urbs(aru);
-
-err_out:
-       return err;
-}
-
-static int ar9170_usb_probe(struct usb_interface *intf,
-                       const struct usb_device_id *id)
-{
-       struct ar9170_usb *aru;
-       struct ar9170 *ar;
-       struct usb_device *udev;
-       int err;
-
-       aru = ar9170_alloc(sizeof(*aru));
-       if (IS_ERR(aru)) {
-               err = PTR_ERR(aru);
-               goto out;
-       }
-
-       udev = interface_to_usbdev(intf);
-       usb_get_dev(udev);
-       aru->udev = udev;
-       aru->intf = intf;
-       ar = &aru->common;
-
-       usb_set_intfdata(intf, aru);
-       SET_IEEE80211_DEV(ar->hw, &udev->dev);
-
-       init_usb_anchor(&aru->rx_submitted);
-       init_usb_anchor(&aru->tx_submitted);
-       init_completion(&aru->cmd_wait);
-
-       aru->common.stop = ar9170_usb_stop;
-       aru->common.open = ar9170_usb_open;
-       aru->common.tx = ar9170_usb_tx;
-       aru->common.exec_cmd = ar9170_usb_exec_cmd;
-       aru->common.callback_cmd = ar9170_usb_callback_cmd;
-
-       err = ar9170_usb_reset(aru);
-       if (err)
-               goto err_freehw;
-
-       err = ar9170_usb_request_firmware(aru);
-       if (err)
-               goto err_freehw;
-
-       err = ar9170_usb_init_device(aru);
-       if (err)
-               goto err_freefw;
-
-       err = ar9170_usb_open(ar);
-       if (err)
-               goto err_unrx;
-
-       err = ar9170_register(ar, &udev->dev);
-
-       ar9170_usb_stop(ar);
-       if (err)
-               goto err_unrx;
-
-       return 0;
-
-err_unrx:
-       ar9170_usb_cancel_urbs(aru);
-
-err_freefw:
-       release_firmware(aru->init_values);
-       release_firmware(aru->firmware);
-
-err_freehw:
-       usb_set_intfdata(intf, NULL);
-       usb_put_dev(udev);
-       ieee80211_free_hw(ar->hw);
-out:
-       return err;
-}
-
-static void ar9170_usb_disconnect(struct usb_interface *intf)
-{
-       struct ar9170_usb *aru = usb_get_intfdata(intf);
-
-       if (!aru)
-               return;
-
-       aru->common.state = AR9170_IDLE;
-       ar9170_unregister(&aru->common);
-       ar9170_usb_cancel_urbs(aru);
-
-       release_firmware(aru->init_values);
-       release_firmware(aru->firmware);
-
-       usb_put_dev(aru->udev);
-       usb_set_intfdata(intf, NULL);
-       ieee80211_free_hw(aru->common.hw);
-}
-
-#ifdef CONFIG_PM
-static int ar9170_suspend(struct usb_interface *intf,
-                         pm_message_t  message)
-{
-       struct ar9170_usb *aru = usb_get_intfdata(intf);
-
-       if (!aru)
-               return -ENODEV;
-
-       aru->common.state = AR9170_IDLE;
-       ar9170_usb_cancel_urbs(aru);
-
-       return 0;
-}
-
-static int ar9170_resume(struct usb_interface *intf)
-{
-       struct ar9170_usb *aru = usb_get_intfdata(intf);
-       int err;
-
-       if (!aru)
-               return -ENODEV;
-
-       usb_unpoison_anchored_urbs(&aru->rx_submitted);
-       usb_unpoison_anchored_urbs(&aru->tx_submitted);
-
-       /*
-        * FIXME: firmware upload will fail on resume.
-        * but this is better than a hang!
-        */
-
-       err = ar9170_usb_init_device(aru);
-       if (err)
-               goto err_unrx;
-
-       err = ar9170_usb_open(&aru->common);
-       if (err)
-               goto err_unrx;
-
-       return 0;
-
-err_unrx:
-       aru->common.state = AR9170_IDLE;
-       ar9170_usb_cancel_urbs(aru);
-
-       return err;
-}
-#endif /* CONFIG_PM */
-
-static struct usb_driver ar9170_driver = {
-       .name = "ar9170usb",
-       .probe = ar9170_usb_probe,
-       .disconnect = ar9170_usb_disconnect,
-       .id_table = ar9170_usb_ids,
-       .soft_unbind = 1,
-#ifdef CONFIG_PM
-       .suspend = ar9170_suspend,
-       .resume = ar9170_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init ar9170_init(void)
-{
-       return usb_register(&ar9170_driver);
-}
-
-static void __exit ar9170_exit(void)
-{
-       usb_deregister(&ar9170_driver);
-}
-
-module_init(ar9170_init);
-module_exit(ar9170_exit);
diff --git a/drivers/net/wireless/ar9170/usb.h b/drivers/net/wireless/ar9170/usb.h
deleted file mode 100644 (file)
index f585292..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Atheros AR9170 USB driver
- *
- * Driver specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-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 __USB_H
-#define __USB_H
-
-#include <linux/usb.h>
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <linux/leds.h>
-#include <net/wireless.h>
-#include <net/mac80211.h>
-#include <linux/firmware.h>
-#include "eeprom.h"
-#include "hw.h"
-#include "ar9170.h"
-
-#define AR9170_NUM_RX_URBS                     16
-
-struct firmware;
-
-struct ar9170_usb {
-       struct ar9170 common;
-       struct usb_device *udev;
-       struct usb_interface *intf;
-
-       struct usb_anchor rx_submitted;
-       struct usb_anchor tx_submitted;
-
-       spinlock_t cmdlock;
-       struct completion cmd_wait;
-       int readlen;
-       u8 *readbuf;
-
-       const struct firmware *init_values;
-       const struct firmware *firmware;
-};
-
-#endif /* __USB_H */
index 76517a4..d26e7b4 100644 (file)
@@ -1,4 +1,8 @@
 config ATH_COMMON
-       tristate "Atheros Wireless Cards Shared Support"
+       tristate "Atheros Wireless Cards"
        depends on ATH5K || ATH9K || AR9170_USB
 
+source "drivers/net/wireless/ath/ath5k/Kconfig"
+source "drivers/net/wireless/ath/ath9k/Kconfig"
+source "drivers/net/wireless/ath/ar9170/Kconfig"
+
index bc77646..a005b91 100644 (file)
@@ -1,3 +1,7 @@
+obj-$(CONFIG_ATH5K)            += ath5k/
+obj-$(CONFIG_ATH9K)            += ath9k/
+obj-$(CONFIG_AR9170_USB)        += ar9170/
+
 obj-$(CONFIG_ATH_COMMON)       += ath.o
 ath-objs               := regd.o
 
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
new file mode 100644 (file)
index 0000000..b99e326
--- /dev/null
@@ -0,0 +1,18 @@
+config AR9170_USB
+       tristate "Atheros AR9170 802.11n USB support"
+       depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
+       select FW_LOADER
+       select ATH_COMMON
+       help
+         This is a driver for the Atheros "otus" 802.11n USB devices.
+
+         These devices require additional firmware (2 files).
+         For now, these files can be downloaded from here:
+         http://wireless.kernel.org/en/users/Drivers/ar9170
+
+         If you choose to build a module, it'll be called ar9170usb.
+
+config AR9170_LEDS
+       bool
+       depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
+       default y
diff --git a/drivers/net/wireless/ath/ar9170/Makefile b/drivers/net/wireless/ath/ar9170/Makefile
new file mode 100644 (file)
index 0000000..8d91c7e
--- /dev/null
@@ -0,0 +1,3 @@
+ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
+
+obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
new file mode 100644 (file)
index 0000000..f797495
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 __AR9170_H
+#define __AR9170_H
+
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <net/wireless.h>
+#include <net/mac80211.h>
+#ifdef CONFIG_AR9170_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_AR9170_LEDS */
+#include "eeprom.h"
+#include "hw.h"
+
+#include "../regd.h"
+
+#define PAYLOAD_MAX    (AR9170_MAX_CMD_LEN/4 - 1)
+
+enum ar9170_bw {
+       AR9170_BW_20,
+       AR9170_BW_40_BELOW,
+       AR9170_BW_40_ABOVE,
+
+       __AR9170_NUM_BW,
+};
+
+enum ar9170_rf_init_mode {
+       AR9170_RFI_NONE,
+       AR9170_RFI_WARM,
+       AR9170_RFI_COLD,
+};
+
+#define AR9170_MAX_RX_BUFFER_SIZE              8192
+
+#ifdef CONFIG_AR9170_LEDS
+struct ar9170;
+
+struct ar9170_led {
+       struct ar9170 *ar;
+       struct led_classdev l;
+       char name[32];
+       unsigned int toggled;
+       bool registered;
+};
+
+#endif /* CONFIG_AR9170_LEDS */
+
+enum ar9170_device_state {
+       AR9170_UNKNOWN_STATE,
+       AR9170_STOPPED,
+       AR9170_IDLE,
+       AR9170_STARTED,
+       AR9170_ASSOCIATED,
+};
+
+struct ar9170 {
+       struct ieee80211_hw *hw;
+       struct mutex mutex;
+       enum ar9170_device_state state;
+
+       int (*open)(struct ar9170 *);
+       void (*stop)(struct ar9170 *);
+       int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int);
+       int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
+                       void *, u32 , void *);
+       void (*callback_cmd)(struct ar9170 *, u32 , void *);
+
+       /* interface mode settings */
+       struct ieee80211_vif *vif;
+       u8 mac_addr[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+
+       /* beaconing */
+       struct sk_buff *beacon;
+       struct work_struct beacon_work;
+
+       /* cryptographic engine */
+       u64 usedkeys;
+       bool rx_software_decryption;
+       bool disable_offload;
+
+       /* filter settings */
+       struct work_struct filter_config_work;
+       u64 cur_mc_hash, want_mc_hash;
+       u32 cur_filter, want_filter;
+       unsigned int filter_changed;
+       bool sniffer_enabled;
+
+       /* PHY */
+       struct ieee80211_channel *channel;
+       int noise[4];
+
+       /* power calibration data */
+       u8 power_5G_leg[4];
+       u8 power_2G_cck[4];
+       u8 power_2G_ofdm[4];
+       u8 power_5G_ht20[8];
+       u8 power_5G_ht40[8];
+       u8 power_2G_ht20[8];
+       u8 power_2G_ht40[8];
+
+#ifdef CONFIG_AR9170_LEDS
+       struct delayed_work led_work;
+       struct ar9170_led leds[AR9170_NUM_LEDS];
+#endif /* CONFIG_AR9170_LEDS */
+
+       /* qos queue settings */
+       spinlock_t tx_stats_lock;
+       struct ieee80211_tx_queue_stats tx_stats[5];
+       struct ieee80211_tx_queue_params edcf[5];
+
+       spinlock_t cmdlock;
+       __le32 cmdbuf[PAYLOAD_MAX + 1];
+
+       /* MAC statistics */
+       struct ieee80211_low_level_stats stats;
+
+       /* EEPROM */
+       struct ar9170_eeprom eeprom;
+       struct ath_regulatory regulatory;
+
+       /* global tx status for unregistered Stations. */
+       struct sk_buff_head global_tx_status;
+       struct sk_buff_head global_tx_status_waste;
+       struct delayed_work tx_status_janitor;
+};
+
+struct ar9170_sta_info {
+       struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
+};
+
+#define IS_STARTED(a)          (a->state >= AR9170_STARTED)
+#define IS_ACCEPTING_CMD(a)    (a->state >= AR9170_IDLE)
+
+#define AR9170_FILTER_CHANGED_PROMISC          BIT(0)
+#define AR9170_FILTER_CHANGED_MULTICAST                BIT(1)
+#define AR9170_FILTER_CHANGED_FRAMEFILTER      BIT(2)
+
+/* exported interface */
+void *ar9170_alloc(size_t priv_size);
+int ar9170_register(struct ar9170 *ar, struct device *pdev);
+void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
+void ar9170_unregister(struct ar9170 *ar);
+void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+                            bool update_statistics, u16 tx_status);
+
+/* MAC */
+int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ar9170_init_mac(struct ar9170 *ar);
+int ar9170_set_qos(struct ar9170 *ar);
+int ar9170_update_multicast(struct ar9170 *ar);
+int ar9170_update_frame_filter(struct ar9170 *ar);
+int ar9170_set_operating_mode(struct ar9170 *ar);
+int ar9170_set_beacon_timers(struct ar9170 *ar);
+int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
+int ar9170_update_beacon(struct ar9170 *ar);
+void ar9170_new_beacon(struct work_struct *work);
+int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
+                     u8 keyidx, u8 *keydata, int keylen);
+int ar9170_disable_key(struct ar9170 *ar, u8 id);
+
+/* LEDs */
+#ifdef CONFIG_AR9170_LEDS
+int ar9170_register_leds(struct ar9170 *ar);
+void ar9170_unregister_leds(struct ar9170 *ar);
+#endif /* CONFIG_AR9170_LEDS */
+int ar9170_init_leds(struct ar9170 *ar);
+int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
+
+/* PHY / RF */
+int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
+int ar9170_init_rf(struct ar9170 *ar);
+int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+                      enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
+
+#endif /* __AR9170_H */
diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c
new file mode 100644 (file)
index 0000000..f57a620
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 "ar9170.h"
+#include "cmd.h"
+
+int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
+{
+       int err;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return 0;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
+       if (err)
+               printk(KERN_DEBUG "%s: writing memory failed\n",
+                      wiphy_name(ar->hw->wiphy));
+       return err;
+}
+
+int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
+{
+       __le32 buf[2] = {
+               cpu_to_le32(reg),
+               cpu_to_le32(val),
+       };
+       int err;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return 0;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
+                          (u8 *) buf, 0, NULL);
+       if (err)
+               printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n",
+                      wiphy_name(ar->hw->wiphy), reg, val);
+       return err;
+}
+
+static int ar9170_read_mreg(struct ar9170 *ar, int nregs,
+                           const u32 *regs, u32 *out)
+{
+       int i, err;
+       __le32 *offs, *res;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return 0;
+
+       /* abuse "out" for the register offsets, must be same length */
+       offs = (__le32 *)out;
+       for (i = 0; i < nregs; i++)
+               offs[i] = cpu_to_le32(regs[i]);
+
+       /* also use the same buffer for the input */
+       res = (__le32 *)out;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_RREG,
+                          4 * nregs, (u8 *)offs,
+                          4 * nregs, (u8 *)res);
+       if (err)
+               return err;
+
+       /* convert result to cpu endian */
+       for (i = 0; i < nregs; i++)
+               out[i] = le32_to_cpu(res[i]);
+
+       return 0;
+}
+
+int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
+{
+       return ar9170_read_mreg(ar, 1, &reg, val);
+}
+
+int ar9170_echo_test(struct ar9170 *ar, u32 v)
+{
+       __le32 echobuf = cpu_to_le32(v);
+       __le32 echores;
+       int err;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return -ENODEV;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
+                          4, (u8 *)&echobuf,
+                          4, (u8 *)&echores);
+       if (err)
+               return err;
+
+       if (echobuf != echores)
+               return -EINVAL;
+
+       return 0;
+}
diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h
new file mode 100644 (file)
index 0000000..a4f0e50
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 __CMD_H
+#define __CMD_H
+
+#include "ar9170.h"
+
+/* basic HW access */
+int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
+int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
+int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
+int ar9170_echo_test(struct ar9170 *ar, u32 v);
+
+/*
+ * Macros to facilitate writing multiple registers in a single
+ * write-combining USB command. Note that when the first group
+ * fails the whole thing will fail without any others attempted,
+ * but you won't know which write in the group failed.
+ */
+#define ar9170_regwrite_begin(ar)                                      \
+do {                                                                   \
+       int __nreg = 0, __err = 0;                                      \
+       struct ar9170 *__ar = ar;
+
+#define ar9170_regwrite(r, v) do {                                     \
+       __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r);                  \
+       __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v);                  \
+       __nreg++;                                                       \
+       if ((__nreg >= PAYLOAD_MAX/2)) {                                \
+               if (IS_ACCEPTING_CMD(__ar))                             \
+                       __err = ar->exec_cmd(__ar, AR9170_CMD_WREG,     \
+                                            8 * __nreg,                \
+                                            (u8 *) &__ar->cmdbuf[1],   \
+                                            0, NULL);                  \
+               __nreg = 0;                                             \
+               if (__err)                                              \
+                       goto __regwrite_out;                            \
+       }                                                               \
+} while (0)
+
+#define ar9170_regwrite_finish()                                       \
+__regwrite_out :                                                       \
+       if (__nreg) {                                                   \
+               if (IS_ACCEPTING_CMD(__ar))                             \
+                       __err = ar->exec_cmd(__ar, AR9170_CMD_WREG,     \
+                                            8 * __nreg,                \
+                                            (u8 *) &__ar->cmdbuf[1],   \
+                                            0, NULL);                  \
+               __nreg = 0;                                             \
+       }
+
+#define ar9170_regwrite_result()                                       \
+       __err;                                                          \
+} while (0);
+
+#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ath/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h
new file mode 100644 (file)
index 0000000..d2c8cc8
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * EEPROM layout
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 __AR9170_EEPROM_H
+#define __AR9170_EEPROM_H
+
+#define AR5416_MAX_CHAINS              2
+#define AR5416_MODAL_SPURS             5
+
+struct ar9170_eeprom_modal {
+       __le32  antCtrlChain[AR5416_MAX_CHAINS];
+       __le32  antCtrlCommon;
+       s8      antennaGainCh[AR5416_MAX_CHAINS];
+       u8      switchSettling;
+       u8      txRxAttenCh[AR5416_MAX_CHAINS];
+       u8      rxTxMarginCh[AR5416_MAX_CHAINS];
+       s8      adcDesiredSize;
+       s8      pgaDesiredSize;
+       u8      xlnaGainCh[AR5416_MAX_CHAINS];
+       u8      txEndToXpaOff;
+       u8      txEndToRxOn;
+       u8      txFrameToXpaOn;
+       u8      thresh62;
+       s8      noiseFloorThreshCh[AR5416_MAX_CHAINS];
+       u8      xpdGain;
+       u8      xpd;
+       s8      iqCalICh[AR5416_MAX_CHAINS];
+       s8      iqCalQCh[AR5416_MAX_CHAINS];
+       u8      pdGainOverlap;
+       u8      ob;
+       u8      db;
+       u8      xpaBiasLvl;
+       u8      pwrDecreaseFor2Chain;
+       u8      pwrDecreaseFor3Chain;
+       u8      txFrameToDataStart;
+       u8      txFrameToPaOn;
+       u8      ht40PowerIncForPdadc;
+       u8      bswAtten[AR5416_MAX_CHAINS];
+       u8      bswMargin[AR5416_MAX_CHAINS];
+       u8      swSettleHt40;
+       u8      reserved[22];
+       struct spur_channel {
+               __le16 spurChan;
+               u8      spurRangeLow;
+               u8      spurRangeHigh;
+       } __packed spur_channels[AR5416_MODAL_SPURS];
+} __packed;
+
+#define AR5416_NUM_PD_GAINS            4
+#define AR5416_PD_GAIN_ICEPTS          5
+
+struct ar9170_calibration_data_per_freq {
+       u8      pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+       u8      vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+#define AR5416_NUM_5G_CAL_PIERS                8
+#define AR5416_NUM_2G_CAL_PIERS                4
+
+#define AR5416_NUM_5G_TARGET_PWRS      8
+#define AR5416_NUM_2G_CCK_TARGET_PWRS  3
+#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4
+#define AR5416_MAX_NUM_TGT_PWRS                8
+
+struct ar9170_calibration_target_power_legacy {
+       u8      freq;
+       u8      power[4];
+} __packed;
+
+struct ar9170_calibration_target_power_ht {
+       u8      freq;
+       u8      power[8];
+} __packed;
+
+#define AR5416_NUM_CTLS                        24
+
+struct ar9170_calctl_edges {
+       u8      channel;
+#define AR9170_CALCTL_EDGE_FLAGS       0xC0
+       u8      power_flags;
+} __packed;
+
+#define AR5416_NUM_BAND_EDGES          8
+
+struct ar9170_calctl_data {
+       struct ar9170_calctl_edges
+               control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+
+struct ar9170_eeprom {
+       __le16  length;
+       __le16  checksum;
+       __le16  version;
+       u8      operating_flags;
+#define AR9170_OPFLAG_5GHZ             1
+#define AR9170_OPFLAG_2GHZ             2
+       u8      misc;
+       __le16  reg_domain[2];
+       u8      mac_address[6];
+       u8      rx_mask;
+       u8      tx_mask;
+       __le16  rf_silent;
+       __le16  bluetooth_options;
+       __le16  device_capabilities;
+       __le32  build_number;
+       u8      deviceType;
+       u8      reserved[33];
+
+       u8      customer_data[64];
+
+       struct ar9170_eeprom_modal
+               modal_header[2];
+
+       u8      cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
+       u8      cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
+
+       struct ar9170_calibration_data_per_freq
+               cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
+               cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+
+       /* power calibration data */
+       struct ar9170_calibration_target_power_legacy
+               cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
+       struct ar9170_calibration_target_power_ht
+               cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
+               cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
+
+       struct ar9170_calibration_target_power_legacy
+               cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
+               cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+       struct ar9170_calibration_target_power_ht
+               cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
+               cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+
+       /* conformance testing limits */
+       u8      ctl_index[AR5416_NUM_CTLS];
+       struct ar9170_calctl_data
+               ctl_data[AR5416_NUM_CTLS];
+
+       u8      pad;
+       __le16  subsystem_id;
+} __packed;
+
+#endif /* __AR9170_EEPROM_H */
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
new file mode 100644 (file)
index 0000000..53e250a
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Hardware-specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 __AR9170_HW_H
+#define __AR9170_HW_H
+
+#define AR9170_MAX_CMD_LEN     64
+
+enum ar9170_cmd {
+       AR9170_CMD_RREG         = 0x00,
+       AR9170_CMD_WREG         = 0x01,
+       AR9170_CMD_RMEM         = 0x02,
+       AR9170_CMD_WMEM         = 0x03,
+       AR9170_CMD_BITAND       = 0x04,
+       AR9170_CMD_BITOR        = 0x05,
+       AR9170_CMD_EKEY         = 0x28,
+       AR9170_CMD_DKEY         = 0x29,
+       AR9170_CMD_FREQUENCY    = 0x30,
+       AR9170_CMD_RF_INIT      = 0x31,
+       AR9170_CMD_SYNTH        = 0x32,
+       AR9170_CMD_FREQ_START   = 0x33,
+       AR9170_CMD_ECHO         = 0x80,
+       AR9170_CMD_TALLY        = 0x81,
+       AR9170_CMD_TALLY_APD    = 0x82,
+       AR9170_CMD_CONFIG       = 0x83,
+       AR9170_CMD_RESET        = 0x90,
+       AR9170_CMD_DKRESET      = 0x91,
+       AR9170_CMD_DKTX_STATUS  = 0x92,
+       AR9170_CMD_FDC          = 0xA0,
+       AR9170_CMD_WREEPROM     = 0xB0,
+       AR9170_CMD_WFLASH       = 0xB0,
+       AR9170_CMD_FLASH_ERASE  = 0xB1,
+       AR9170_CMD_FLASH_PROG   = 0xB2,
+       AR9170_CMD_FLASH_CHKSUM = 0xB3,
+       AR9170_CMD_FLASH_READ   = 0xB4,
+       AR9170_CMD_FW_DL_INIT   = 0xB5,
+       AR9170_CMD_MEM_WREEPROM = 0xBB,
+};
+
+/* endpoints */
+#define AR9170_EP_TX                           1
+#define AR9170_EP_RX                           2
+#define AR9170_EP_IRQ                          3
+#define AR9170_EP_CMD                          4
+
+#define AR9170_EEPROM_START                    0x1600
+
+#define AR9170_GPIO_REG_BASE                   0x1d0100
+#define AR9170_GPIO_REG_PORT_TYPE              AR9170_GPIO_REG_BASE
+#define AR9170_GPIO_REG_DATA                   (AR9170_GPIO_REG_BASE + 4)
+#define AR9170_NUM_LEDS                                2
+
+
+#define AR9170_USB_REG_BASE                    0x1e1000
+#define AR9170_USB_REG_DMA_CTL                 (AR9170_USB_REG_BASE + 0x108)
+#define                AR9170_DMA_CTL_ENABLE_TO_DEVICE         0x1
+#define                AR9170_DMA_CTL_ENABLE_FROM_DEVICE       0x2
+#define                AR9170_DMA_CTL_HIGH_SPEED               0x4
+#define                AR9170_DMA_CTL_PACKET_MODE              0x8
+
+#define AR9170_USB_REG_MAX_AGG_UPLOAD          (AR9170_USB_REG_BASE + 0x110)
+#define AR9170_USB_REG_UPLOAD_TIME_CTL         (AR9170_USB_REG_BASE + 0x114)
+
+
+
+#define AR9170_MAC_REG_BASE                    0x1c3000
+
+#define AR9170_MAC_REG_TSF_L                   (AR9170_MAC_REG_BASE + 0x514)
+#define AR9170_MAC_REG_TSF_H                   (AR9170_MAC_REG_BASE + 0x518)
+
+#define AR9170_MAC_REG_ATIM_WINDOW             (AR9170_MAC_REG_BASE + 0x51C)
+#define AR9170_MAC_REG_BCN_PERIOD              (AR9170_MAC_REG_BASE + 0x520)
+#define AR9170_MAC_REG_PRETBTT                 (AR9170_MAC_REG_BASE + 0x524)
+
+#define AR9170_MAC_REG_MAC_ADDR_L              (AR9170_MAC_REG_BASE + 0x610)
+#define AR9170_MAC_REG_MAC_ADDR_H              (AR9170_MAC_REG_BASE + 0x614)
+#define AR9170_MAC_REG_BSSID_L                 (AR9170_MAC_REG_BASE + 0x618)
+#define AR9170_MAC_REG_BSSID_H                 (AR9170_MAC_REG_BASE + 0x61c)
+
+#define AR9170_MAC_REG_GROUP_HASH_TBL_L                (AR9170_MAC_REG_BASE + 0x624)
+#define AR9170_MAC_REG_GROUP_HASH_TBL_H                (AR9170_MAC_REG_BASE + 0x628)
+
+#define AR9170_MAC_REG_RX_TIMEOUT              (AR9170_MAC_REG_BASE + 0x62C)
+
+#define AR9170_MAC_REG_BASIC_RATE              (AR9170_MAC_REG_BASE + 0x630)
+#define AR9170_MAC_REG_MANDATORY_RATE          (AR9170_MAC_REG_BASE + 0x634)
+#define AR9170_MAC_REG_RTS_CTS_RATE            (AR9170_MAC_REG_BASE + 0x638)
+#define AR9170_MAC_REG_BACKOFF_PROTECT         (AR9170_MAC_REG_BASE + 0x63c)
+#define AR9170_MAC_REG_RX_THRESHOLD            (AR9170_MAC_REG_BASE + 0x640)
+#define AR9170_MAC_REG_RX_PE_DELAY             (AR9170_MAC_REG_BASE + 0x64C)
+
+#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK                (AR9170_MAC_REG_BASE + 0x658)
+#define AR9170_MAC_REG_SNIFFER                 (AR9170_MAC_REG_BASE + 0x674)
+#define                AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC   BIT(0)
+#define                AR9170_MAC_REG_SNIFFER_DEFAULTS         0x02000000
+#define AR9170_MAC_REG_ENCRYPTION              (AR9170_MAC_REG_BASE + 0x678)
+#define                AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE   BIT(3)
+#define                AR9170_MAC_REG_ENCRYPTION_DEFAULTS      0x70
+
+#define AR9170_MAC_REG_MISC_680                        (AR9170_MAC_REG_BASE + 0x680)
+#define AR9170_MAC_REG_TX_UNDERRUN             (AR9170_MAC_REG_BASE + 0x688)
+
+#define AR9170_MAC_REG_FRAMETYPE_FILTER                (AR9170_MAC_REG_BASE + 0x68c)
+#define                AR9170_MAC_REG_FTF_ASSOC_REQ            BIT(0)
+#define                AR9170_MAC_REG_FTF_ASSOC_RESP           BIT(1)
+#define                AR9170_MAC_REG_FTF_REASSOC_REQ          BIT(2)
+#define                AR9170_MAC_REG_FTF_REASSOC_RESP         BIT(3)
+#define                AR9170_MAC_REG_FTF_PRB_REQ              BIT(4)
+#define                AR9170_MAC_REG_FTF_PRB_RESP             BIT(5)
+#define                AR9170_MAC_REG_FTF_BIT6                 BIT(6)
+#define                AR9170_MAC_REG_FTF_BIT7                 BIT(7)
+#define                AR9170_MAC_REG_FTF_BEACON               BIT(8)
+#define                AR9170_MAC_REG_FTF_ATIM                 BIT(9)
+#define                AR9170_MAC_REG_FTF_DEASSOC              BIT(10)
+#define                AR9170_MAC_REG_FTF_AUTH                 BIT(11)
+#define                AR9170_MAC_REG_FTF_DEAUTH               BIT(12)
+#define                AR9170_MAC_REG_FTF_BIT13                BIT(13)
+#define                AR9170_MAC_REG_FTF_BIT14                BIT(14)
+#define                AR9170_MAC_REG_FTF_BIT15                BIT(15)
+#define                AR9170_MAC_REG_FTF_BAR                  BIT(24)
+#define                AR9170_MAC_REG_FTF_BIT25                BIT(25)
+#define                AR9170_MAC_REG_FTF_PSPOLL               BIT(26)
+#define                AR9170_MAC_REG_FTF_RTS                  BIT(27)
+#define                AR9170_MAC_REG_FTF_CTS                  BIT(28)
+#define                AR9170_MAC_REG_FTF_ACK                  BIT(29)
+#define                AR9170_MAC_REG_FTF_CFE                  BIT(30)
+#define                AR9170_MAC_REG_FTF_CFE_ACK              BIT(31)
+#define                AR9170_MAC_REG_FTF_DEFAULTS             0x0500ffff
+#define                AR9170_MAC_REG_FTF_MONITOR              0xfd00ffff
+
+#define AR9170_MAC_REG_RX_TOTAL                        (AR9170_MAC_REG_BASE + 0x6A0)
+#define AR9170_MAC_REG_RX_CRC32                        (AR9170_MAC_REG_BASE + 0x6A4)
+#define AR9170_MAC_REG_RX_CRC16                        (AR9170_MAC_REG_BASE + 0x6A8)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI   (AR9170_MAC_REG_BASE + 0x6AC)
+#define AR9170_MAC_REG_RX_OVERRUN              (AR9170_MAC_REG_BASE + 0x6B0)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL   (AR9170_MAC_REG_BASE + 0x6BC)
+#define AR9170_MAC_REG_TX_RETRY                        (AR9170_MAC_REG_BASE + 0x6CC)
+#define AR9170_MAC_REG_TX_TOTAL                        (AR9170_MAC_REG_BASE + 0x6F4)
+
+
+#define AR9170_MAC_REG_ACK_EXTENSION           (AR9170_MAC_REG_BASE + 0x690)
+#define AR9170_MAC_REG_EIFS_AND_SIFS           (AR9170_MAC_REG_BASE + 0x698)
+
+#define AR9170_MAC_REG_SLOT_TIME               (AR9170_MAC_REG_BASE + 0x6F0)
+
+#define AR9170_MAC_REG_POWERMANAGEMENT         (AR9170_MAC_REG_BASE + 0x700)
+#define                AR9170_MAC_REG_POWERMGT_IBSS            0xe0
+#define                AR9170_MAC_REG_POWERMGT_AP              0xa1
+#define                AR9170_MAC_REG_POWERMGT_STA             0x2
+#define                AR9170_MAC_REG_POWERMGT_AP_WDS          0x3
+#define                AR9170_MAC_REG_POWERMGT_DEFAULTS        (0xf << 24)
+
+#define AR9170_MAC_REG_ROLL_CALL_TBL_L         (AR9170_MAC_REG_BASE + 0x704)
+#define AR9170_MAC_REG_ROLL_CALL_TBL_H         (AR9170_MAC_REG_BASE + 0x708)
+
+#define AR9170_MAC_REG_AC0_CW                  (AR9170_MAC_REG_BASE + 0xB00)
+#define AR9170_MAC_REG_AC1_CW                  (AR9170_MAC_REG_BASE + 0xB04)
+#define AR9170_MAC_REG_AC2_CW                  (AR9170_MAC_REG_BASE + 0xB08)
+#define AR9170_MAC_REG_AC3_CW                  (AR9170_MAC_REG_BASE + 0xB0C)
+#define AR9170_MAC_REG_AC4_CW                  (AR9170_MAC_REG_BASE + 0xB10)
+#define AR9170_MAC_REG_AC1_AC0_AIFS            (AR9170_MAC_REG_BASE + 0xB14)
+#define AR9170_MAC_REG_AC3_AC2_AIFS            (AR9170_MAC_REG_BASE + 0xB18)
+
+#define AR9170_MAC_REG_RETRY_MAX               (AR9170_MAC_REG_BASE + 0xB28)
+
+#define AR9170_MAC_REG_FCS_SELECT              (AR9170_MAC_REG_BASE + 0xBB0)
+#define                AR9170_MAC_FCS_SWFCS            0x1
+#define                AR9170_MAC_FCS_FIFO_PROT        0x4
+
+
+#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND     (AR9170_MAC_REG_BASE + 0xB30)
+
+#define AR9170_MAC_REG_AC1_AC0_TXOP            (AR9170_MAC_REG_BASE + 0xB44)
+#define AR9170_MAC_REG_AC3_AC2_TXOP            (AR9170_MAC_REG_BASE + 0xB48)
+
+#define AR9170_MAC_REG_ACK_TABLE               (AR9170_MAC_REG_BASE + 0xC00)
+#define AR9170_MAC_REG_AMPDU_RX_THRESH         (AR9170_MAC_REG_BASE + 0xC50)
+
+#define AR9170_MAC_REG_TXRX_MPI                        (AR9170_MAC_REG_BASE + 0xD7C)
+#define                AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f
+#define                AR9170_MAC_TXRX_MPI_TX_TO_MASK  0x0000fff0
+#define                AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000
+#define                AR9170_MAC_TXRX_MPI_RX_TO_MASK  0xfff00000
+
+#define AR9170_MAC_REG_BCN_ADDR                        (AR9170_MAC_REG_BASE + 0xD84)
+#define AR9170_MAC_REG_BCN_LENGTH              (AR9170_MAC_REG_BASE + 0xD88)
+#define AR9170_MAC_REG_BCN_PLCP                        (AR9170_MAC_REG_BASE + 0xD90)
+#define AR9170_MAC_REG_BCN_CTRL                        (AR9170_MAC_REG_BASE + 0xD94)
+#define AR9170_MAC_REG_BCN_HT1                 (AR9170_MAC_REG_BASE + 0xDA0)
+#define AR9170_MAC_REG_BCN_HT2                 (AR9170_MAC_REG_BASE + 0xDA4)
+
+
+#define AR9170_PWR_REG_BASE                    0x1D4000
+
+#define AR9170_PWR_REG_CLOCK_SEL               (AR9170_PWR_REG_BASE + 0x008)
+#define                AR9170_PWR_CLK_AHB_40MHZ        0
+#define                AR9170_PWR_CLK_AHB_20_22MHZ     1
+#define                AR9170_PWR_CLK_AHB_40_44MHZ     2
+#define                AR9170_PWR_CLK_AHB_80_88MHZ     3
+#define                AR9170_PWR_CLK_DAC_160_INV_DLY  0x70
+
+
+/* put beacon here in memory */
+#define AR9170_BEACON_BUFFER_ADDRESS           0x117900
+
+
+struct ar9170_tx_control {
+       __le16 length;
+       __le16 mac_control;
+       __le32 phy_control;
+       u8 frame_data[0];
+} __packed;
+
+/* these are either-or */
+#define AR9170_TX_MAC_PROT_RTS                 0x0001
+#define AR9170_TX_MAC_PROT_CTS                 0x0002
+
+#define AR9170_TX_MAC_NO_ACK                   0x0004
+/* if unset, MAC will only do SIFS space before frame */
+#define AR9170_TX_MAC_BACKOFF                  0x0008
+#define AR9170_TX_MAC_BURST                    0x0010
+#define AR9170_TX_MAC_AGGR                     0x0020
+
+/* encryption is a two-bit field */
+#define AR9170_TX_MAC_ENCR_NONE                        0x0000
+#define AR9170_TX_MAC_ENCR_RC4                 0x0040
+#define AR9170_TX_MAC_ENCR_CENC                        0x0080
+#define AR9170_TX_MAC_ENCR_AES                 0x00c0
+
+#define AR9170_TX_MAC_MMIC                     0x0100
+#define AR9170_TX_MAC_HW_DURATION              0x0200
+#define AR9170_TX_MAC_QOS_SHIFT                        10
+#define AR9170_TX_MAC_QOS_MASK                 (3 << AR9170_TX_MAC_QOS_SHIFT)
+#define AR9170_TX_MAC_AGGR_QOS_BIT1            0x0400
+#define AR9170_TX_MAC_AGGR_QOS_BIT2            0x0800
+#define AR9170_TX_MAC_DISABLE_TXOP             0x1000
+#define AR9170_TX_MAC_TXOP_RIFS                        0x2000
+#define AR9170_TX_MAC_IMM_AMPDU                        0x4000
+#define AR9170_TX_MAC_RATE_PROBE               0x8000
+
+/* either-or */
+#define AR9170_TX_PHY_MOD_CCK                  0x00000000
+#define AR9170_TX_PHY_MOD_OFDM                 0x00000001
+#define AR9170_TX_PHY_MOD_HT                   0x00000002
+
+/* depends on modulation */
+#define AR9170_TX_PHY_SHORT_PREAMBLE           0x00000004
+#define AR9170_TX_PHY_GREENFIELD               0x00000004
+
+#define AR9170_TX_PHY_BW_SHIFT                 3
+#define AR9170_TX_PHY_BW_MASK                  (3 << AR9170_TX_PHY_BW_SHIFT)
+#define AR9170_TX_PHY_BW_20MHZ                 0
+#define AR9170_TX_PHY_BW_40MHZ                 2
+#define AR9170_TX_PHY_BW_40MHZ_DUP             3
+
+#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT      6
+#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK       (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
+
+#define AR9170_TX_PHY_TX_PWR_SHIFT             9
+#define AR9170_TX_PHY_TX_PWR_MASK              (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
+
+/* not part of the hw-spec */
+#define AR9170_TX_PHY_QOS_SHIFT                        25
+#define AR9170_TX_PHY_QOS_MASK                 (3 << AR9170_TX_PHY_QOS_SHIFT)
+
+#define AR9170_TX_PHY_TXCHAIN_SHIFT            15
+#define AR9170_TX_PHY_TXCHAIN_MASK             (7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
+#define AR9170_TX_PHY_TXCHAIN_1                        1
+/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
+#define AR9170_TX_PHY_TXCHAIN_2                        5
+
+#define AR9170_TX_PHY_MCS_SHIFT                        18
+#define AR9170_TX_PHY_MCS_MASK                 (0x7f << AR9170_TX_PHY_MCS_SHIFT)
+
+#define AR9170_TX_PHY_SHORT_GI                 0x80000000
+
+struct ar9170_rx_head {
+       u8 plcp[12];
+} __packed;
+
+struct ar9170_rx_tail {
+       union {
+               struct {
+                       u8 rssi_ant0, rssi_ant1, rssi_ant2,
+                          rssi_ant0x, rssi_ant1x, rssi_ant2x,
+                          rssi_combined;
+               } __packed;
+               u8 rssi[7];
+       } __packed;
+
+       u8 evm_stream0[6], evm_stream1[6];
+       u8 phy_err;
+       u8 SAidx, DAidx;
+       u8 error;
+       u8 status;
+} __packed;
+
+#define AR9170_ENC_ALG_NONE                    0x0
+#define AR9170_ENC_ALG_WEP64                   0x1
+#define AR9170_ENC_ALG_TKIP                    0x2
+#define AR9170_ENC_ALG_AESCCMP                 0x4
+#define AR9170_ENC_ALG_WEP128                  0x5
+#define AR9170_ENC_ALG_WEP256                  0x6
+#define AR9170_ENC_ALG_CENC                    0x7
+
+#define AR9170_RX_ENC_SOFTWARE                 0x8
+
+static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
+{
+       return (t->SAidx & 0xc0) >> 4 |
+              (t->DAidx & 0xc0) >> 6;
+}
+
+#define AR9170_RX_STATUS_MODULATION_MASK       0x03
+#define AR9170_RX_STATUS_MODULATION_CCK                0x00
+#define AR9170_RX_STATUS_MODULATION_OFDM       0x01
+#define AR9170_RX_STATUS_MODULATION_HT         0x02
+#define AR9170_RX_STATUS_MODULATION_DUPOFDM    0x03
+
+/* depends on modulation */
+#define AR9170_RX_STATUS_SHORT_PREAMBLE                0x08
+#define AR9170_RX_STATUS_GREENFIELD            0x08
+
+#define AR9170_RX_STATUS_MPDU_MASK             0x30
+#define AR9170_RX_STATUS_MPDU_SINGLE           0x00
+#define AR9170_RX_STATUS_MPDU_FIRST            0x10
+#define AR9170_RX_STATUS_MPDU_MIDDLE           0x20
+#define AR9170_RX_STATUS_MPDU_LAST             0x30
+
+
+#define AR9170_RX_ERROR_RXTO                   0x01
+#define AR9170_RX_ERROR_OVERRUN                        0x02
+#define AR9170_RX_ERROR_DECRYPT                        0x04
+#define AR9170_RX_ERROR_FCS                    0x08
+#define AR9170_RX_ERROR_WRONG_RA               0x10
+#define AR9170_RX_ERROR_PLCP                   0x20
+#define AR9170_RX_ERROR_MMIC                   0x40
+
+struct ar9170_cmd_tx_status {
+       __le16 unkn;
+       u8 dst[ETH_ALEN];
+       __le32 rate;
+       __le16 status;
+} __packed;
+
+#define AR9170_TX_STATUS_COMPLETE              0x00
+#define AR9170_TX_STATUS_RETRY                 0x01
+#define AR9170_TX_STATUS_FAILED                        0x02
+
+struct ar9170_cmd_ba_failed_count {
+       __le16 failed;
+       __le16 rate;
+} __packed;
+
+struct ar9170_cmd_response {
+       u8 flag;
+       u8 type;
+
+       union {
+               struct ar9170_cmd_tx_status             tx_status;
+               struct ar9170_cmd_ba_failed_count       ba_fail_cnt;
+               u8 data[0];
+       };
+} __packed;
+
+/* QoS */
+
+/* mac80211 queue to HW/FW map */
+static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
+
+/* HW/FW queue to mac80211 map */
+static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
+
+enum ar9170_txq {
+       AR9170_TXQ_BE,
+       AR9170_TXQ_BK,
+       AR9170_TXQ_VI,
+       AR9170_TXQ_VO,
+
+       __AR9170_NUM_TXQ,
+};
+
+#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
new file mode 100644 (file)
index 0000000..341cead
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * LED handling
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 "ar9170.h"
+#include "cmd.h"
+
+int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
+{
+       return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
+}
+
+int ar9170_init_leds(struct ar9170 *ar)
+{
+       int err;
+
+       /* disable LEDs */
+       /* GPIO [0/1 mode: output, 2/3: input] */
+       err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
+       if (err)
+               goto out;
+
+       /* GPIO 0/1 value: off */
+       err = ar9170_set_leds_state(ar, 0);
+
+out:
+       return err;
+}
+
+#ifdef CONFIG_AR9170_LEDS
+static void ar9170_update_leds(struct work_struct *work)
+{
+       struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
+       int i, tmp, blink_delay = 1000;
+       u32 led_val = 0;
+       bool rerun = false;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return ;
+
+       mutex_lock(&ar->mutex);
+       for (i = 0; i < AR9170_NUM_LEDS; i++)
+               if (ar->leds[i].toggled) {
+                       led_val |= 1 << i;
+
+                       tmp = 70 + 200 / (ar->leds[i].toggled);
+                       if (tmp < blink_delay)
+                               blink_delay = tmp;
+
+                       if (ar->leds[i].toggled > 1)
+                               ar->leds[i].toggled = 0;
+
+                       rerun = true;
+               }
+
+       ar9170_set_leds_state(ar, led_val);
+       mutex_unlock(&ar->mutex);
+
+       if (rerun)
+               queue_delayed_work(ar->hw->workqueue, &ar->led_work,
+                                  msecs_to_jiffies(blink_delay));
+}
+
+static void ar9170_led_brightness_set(struct led_classdev *led,
+                                     enum led_brightness brightness)
+{
+       struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
+       struct ar9170 *ar = arl->ar;
+
+       arl->toggled++;
+
+       if (likely(IS_ACCEPTING_CMD(ar) && brightness))
+               queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
+}
+
+static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
+                              char *trigger)
+{
+       int err;
+
+       snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
+                "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
+
+       ar->leds[i].ar = ar;
+       ar->leds[i].l.name = ar->leds[i].name;
+       ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
+       ar->leds[i].l.brightness = 0;
+       ar->leds[i].l.default_trigger = trigger;
+
+       err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
+                                   &ar->leds[i].l);
+       if (err)
+               printk(KERN_ERR "%s: failed to register %s LED (%d).\n",
+                      wiphy_name(ar->hw->wiphy), ar->leds[i].name, err);
+       else
+               ar->leds[i].registered = true;
+
+       return err;
+}
+
+void ar9170_unregister_leds(struct ar9170 *ar)
+{
+       int i;
+
+       cancel_delayed_work_sync(&ar->led_work);
+
+       for (i = 0; i < AR9170_NUM_LEDS; i++)
+               if (ar->leds[i].registered) {
+                       led_classdev_unregister(&ar->leds[i].l);
+                       ar->leds[i].registered = false;
+               }
+}
+
+int ar9170_register_leds(struct ar9170 *ar)
+{
+       int err;
+
+       INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
+
+       err = ar9170_register_led(ar, 0, "tx",
+                                 ieee80211_get_tx_led_name(ar->hw));
+       if (err)
+               goto fail;
+
+       err = ar9170_register_led(ar, 1, "assoc",
+                                ieee80211_get_assoc_led_name(ar->hw));
+       if (err)
+               goto fail;
+
+       return 0;
+
+fail:
+       ar9170_unregister_leds(ar);
+       return err;
+}
+
+#endif /* CONFIG_AR9170_LEDS */
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
new file mode 100644 (file)
index 0000000..c8fa307
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * MAC programming
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 "ar9170.h"
+#include "cmd.h"
+
+int ar9170_set_qos(struct ar9170 *ar)
+{
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
+                       (ar->edcf[0].cw_max << 16));
+       ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
+                       (ar->edcf[1].cw_max << 16));
+       ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
+                       (ar->edcf[2].cw_max << 16));
+       ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
+                       (ar->edcf[3].cw_max << 16));
+       ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
+                       (ar->edcf[4].cw_max << 16));
+
+       ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
+                       ((ar->edcf[0].aifs * 9 + 10)) |
+                       ((ar->edcf[1].aifs * 9 + 10) << 12) |
+                       ((ar->edcf[2].aifs * 9 + 10) << 24));
+       ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
+                       ((ar->edcf[2].aifs * 9 + 10) >> 8) |
+                       ((ar->edcf[3].aifs * 9 + 10) << 4) |
+                       ((ar->edcf[4].aifs * 9 + 10) << 16));
+
+       ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
+                       ar->edcf[0].txop | ar->edcf[1].txop << 16);
+       ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
+                       ar->edcf[1].txop | ar->edcf[3].txop << 16);
+
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+int ar9170_init_mac(struct ar9170 *ar)
+{
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
+
+       ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
+
+       /* enable MMIC */
+       ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
+                       AR9170_MAC_REG_SNIFFER_DEFAULTS);
+
+       ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
+
+       ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
+       ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
+       ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
+
+       /* CF-END mode */
+       ar9170_regwrite(0x1c3b2c, 0x19000000);
+
+       /* NAV protects ACK only (in TXOP) */
+       ar9170_regwrite(0x1c3b38, 0x201);
+
+       /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
+       /* OTUS set AM to 0x1 */
+       ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
+
+       ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
+
+       /* AGG test code*/
+       /* Aggregation MAX number and timeout */
+       ar9170_regwrite(0x1c3b9c, 0x10000a);
+
+       ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
+                       AR9170_MAC_REG_FTF_DEFAULTS);
+
+       /* Enable deaggregator, response in sniffer mode */
+       ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
+
+       /* rate sets */
+       ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
+       ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
+       ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
+
+       /* MIMO response control */
+       ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28  otus-AM */
+
+       /* switch MAC to OTUS interface */
+       ar9170_regwrite(0x1c3600, 0x3);
+
+       ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
+
+       /* set PHY register read timeout (??) */
+       ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
+
+       /* Disable Rx TimeOut, workaround for BB. */
+       ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
+
+       /* Set CPU clock frequency to 88/80MHz */
+       ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
+                       AR9170_PWR_CLK_AHB_80_88MHZ |
+                       AR9170_PWR_CLK_DAC_160_INV_DLY);
+
+       /* Set WLAN DMA interrupt mode: generate int per packet */
+       ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
+
+       ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
+                       AR9170_MAC_FCS_FIFO_PROT);
+
+       /* Disables the CF_END frame, undocumented register */
+       ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
+                       0x141E0F48);
+
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
+{
+       static const u8 zero[ETH_ALEN] = { 0 };
+
+       if (!mac)
+               mac = zero;
+
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(reg,
+                       (mac[3] << 24) | (mac[2] << 16) |
+                       (mac[1] << 8) | mac[0]);
+
+       ar9170_regwrite(reg + 4, (mac[5] << 8) | mac[4]);
+
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+int ar9170_update_multicast(struct ar9170 *ar)
+{
+       int err;
+
+       ar9170_regwrite_begin(ar);
+       ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H,
+               ar->want_mc_hash >> 32);
+       ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
+               ar->want_mc_hash);
+
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+
+       if (err)
+               return err;
+
+       ar->cur_mc_hash = ar->want_mc_hash;
+
+       return 0;
+}
+
+int ar9170_update_frame_filter(struct ar9170 *ar)
+{
+       int err;
+
+       err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER,
+                              ar->want_filter);
+
+       if (err)
+               return err;
+
+       ar->cur_filter = ar->want_filter;
+
+       return 0;
+}
+
+static int ar9170_set_promiscouous(struct ar9170 *ar)
+{
+       u32 encr_mode, sniffer;
+       int err;
+
+       err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
+       if (err)
+               return err;
+
+       err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
+       if (err)
+               return err;
+
+       if (ar->sniffer_enabled) {
+               sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
+
+               /*
+                * Rx decryption works in place.
+                *
+                * If we don't disable it, the hardware will render all
+                * encrypted frames which are encrypted with an unknown
+                * key useless.
+                */
+
+               encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+               ar->sniffer_enabled = true;
+       } else {
+               sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
+
+               if (ar->rx_software_decryption)
+                       encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+               else
+                       encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+       }
+
+       ar9170_regwrite_begin(ar);
+       ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
+       ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+int ar9170_set_operating_mode(struct ar9170 *ar)
+{
+       u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
+       u8 *mac_addr, *bssid;
+       int err;
+
+       if (ar->vif) {
+               mac_addr = ar->mac_addr;
+               bssid = ar->bssid;
+
+               switch (ar->vif->type) {
+               case NL80211_IFTYPE_MESH_POINT:
+               case NL80211_IFTYPE_ADHOC:
+                       pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
+                       break;
+/*             case NL80211_IFTYPE_AP:
+                       pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
+                       break;*/
+               case NL80211_IFTYPE_WDS:
+                       pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
+                       break;
+               case NL80211_IFTYPE_MONITOR:
+                       ar->sniffer_enabled = true;
+                       ar->rx_software_decryption = true;
+                       break;
+               default:
+                       pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
+                       break;
+               }
+       } else {
+               mac_addr = NULL;
+               bssid = NULL;
+       }
+
+       err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
+       if (err)
+               return err;
+
+       err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
+       if (err)
+               return err;
+
+       err = ar9170_set_promiscouous(ar);
+       if (err)
+               return err;
+
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
+{
+       u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
+
+       return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
+}
+
+int ar9170_set_beacon_timers(struct ar9170 *ar)
+{
+       u32 v = 0;
+       u32 pretbtt = 0;
+
+       v |= ar->hw->conf.beacon_int;
+
+       if (ar->vif) {
+               switch (ar->vif->type) {
+               case NL80211_IFTYPE_MESH_POINT:
+               case NL80211_IFTYPE_ADHOC:
+                       v |= BIT(25);
+                       break;
+               case NL80211_IFTYPE_AP:
+                       v |= BIT(24);
+                       pretbtt = (ar->hw->conf.beacon_int - 6) << 16;
+                       break;
+               default:
+                       break;
+               }
+
+               v |= ar->vif->bss_conf.dtim_period << 16;
+       }
+
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
+       ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
+       ar9170_regwrite_finish();
+       return ar9170_regwrite_result();
+}
+
+int ar9170_update_beacon(struct ar9170 *ar)
+{
+       struct sk_buff *skb;
+       __le32 *data, *old = NULL;
+       u32 word;
+       int i;
+
+       skb = ieee80211_beacon_get(ar->hw, ar->vif);
+       if (!skb)
+               return -ENOMEM;
+
+       data = (__le32 *)skb->data;
+       if (ar->beacon)
+               old = (__le32 *)ar->beacon->data;
+
+       ar9170_regwrite_begin(ar);
+       for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
+               /*
+                * XXX: This accesses beyond skb data for up
+                *      to the last 3 bytes!!
+                */
+
+               if (old && (data[i] == old[i]))
+                       continue;
+
+               word = le32_to_cpu(data[i]);
+               ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
+       }
+
+       /* XXX: use skb->cb info */
+       if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+               ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
+                               ((skb->len + 4) << (3+16)) + 0x0400);
+       else
+               ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
+                               ((skb->len + 4) << (3+16)) + 0x0400);
+
+       ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
+       ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
+       ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
+
+       ar9170_regwrite_finish();
+
+       dev_kfree_skb(ar->beacon);
+       ar->beacon = skb;
+
+       return ar9170_regwrite_result();
+}
+
+void ar9170_new_beacon(struct work_struct *work)
+{
+       struct ar9170 *ar = container_of(work, struct ar9170,
+                                        beacon_work);
+       struct sk_buff *skb;
+
+       if (unlikely(!IS_STARTED(ar)))
+               return ;
+
+       mutex_lock(&ar->mutex);
+
+       if (!ar->vif)
+               goto out;
+
+       ar9170_update_beacon(ar);
+
+       rcu_read_lock();
+       while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
+               ar9170_op_tx(ar->hw, skb);
+
+       rcu_read_unlock();
+
+ out:
+       mutex_unlock(&ar->mutex);
+}
+
+int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
+                     u8 keyidx, u8 *keydata, int keylen)
+{
+       __le32 vals[7];
+       static const u8 bcast[ETH_ALEN] =
+               { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+       u8 dummy;
+
+       mac = mac ? : bcast;
+
+       vals[0] = cpu_to_le32((keyidx << 16) + id);
+       vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
+       vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
+                             mac[3] << 8 | mac[2]);
+       memset(&vals[3], 0, 16);
+       if (keydata)
+               memcpy(&vals[3], keydata, keylen);
+
+       return ar->exec_cmd(ar, AR9170_CMD_EKEY,
+                           sizeof(vals), (u8 *)vals,
+                           1, &dummy);
+}
+
+int ar9170_disable_key(struct ar9170 *ar, u8 id)
+{
+       __le32 val = cpu_to_le32(id);
+       u8 dummy;
+
+       return ar->exec_cmd(ar, AR9170_CMD_EKEY,
+                           sizeof(val), (u8 *)&val,
+                           1, &dummy);
+}
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
new file mode 100644 (file)
index 0000000..8de0ff9
--- /dev/null
@@ -0,0 +1,1690 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * mac80211 interaction code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "ar9170.h"
+#include "hw.h"
+#include "cmd.h"
+
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+#define RATE(_bitrate, _hw_rate, _txpidx, _flags) {    \
+       .bitrate        = (_bitrate),                   \
+       .flags          = (_flags),                     \
+       .hw_value       = (_hw_rate) | (_txpidx) << 4,  \
+}
+
+static struct ieee80211_rate __ar9170_ratetable[] = {
+       RATE(10, 0, 0, 0),
+       RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
+       RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
+       RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
+       RATE(60, 0xb, 0, 0),
+       RATE(90, 0xf, 0, 0),
+       RATE(120, 0xa, 0, 0),
+       RATE(180, 0xe, 0, 0),
+       RATE(240, 0x9, 0, 0),
+       RATE(360, 0xd, 1, 0),
+       RATE(480, 0x8, 2, 0),
+       RATE(540, 0xc, 3, 0),
+};
+#undef RATE
+
+#define ar9170_g_ratetable     (__ar9170_ratetable + 0)
+#define ar9170_g_ratetable_size        12
+#define ar9170_a_ratetable     (__ar9170_ratetable + 4)
+#define ar9170_a_ratetable_size        8
+
+/*
+ * NB: The hw_value is used as an index into the ar9170_phy_freq_params
+ *     array in phy.c so that we don't have to do frequency lookups!
+ */
+#define CHAN(_freq, _idx) {            \
+       .center_freq    = (_freq),      \
+       .hw_value       = (_idx),       \
+       .max_power      = 18, /* XXX */ \
+}
+
+static struct ieee80211_channel ar9170_2ghz_chantable[] = {
+       CHAN(2412,  0),
+       CHAN(2417,  1),
+       CHAN(2422,  2),
+       CHAN(2427,  3),
+       CHAN(2432,  4),
+       CHAN(2437,  5),
+       CHAN(2442,  6),
+       CHAN(2447,  7),
+       CHAN(2452,  8),
+       CHAN(2457,  9),
+       CHAN(2462, 10),
+       CHAN(2467, 11),
+       CHAN(2472, 12),
+       CHAN(2484, 13),
+};
+
+static struct ieee80211_channel ar9170_5ghz_chantable[] = {
+       CHAN(4920, 14),
+       CHAN(4940, 15),
+       CHAN(4960, 16),
+       CHAN(4980, 17),
+       CHAN(5040, 18),
+       CHAN(5060, 19),
+       CHAN(5080, 20),
+       CHAN(5180, 21),
+       CHAN(5200, 22),
+       CHAN(5220, 23),
+       CHAN(5240, 24),
+       CHAN(5260, 25),
+       CHAN(5280, 26),
+       CHAN(5300, 27),
+       CHAN(5320, 28),
+       CHAN(5500, 29),
+       CHAN(5520, 30),
+       CHAN(5540, 31),
+       CHAN(5560, 32),
+       CHAN(5580, 33),
+       CHAN(5600, 34),
+       CHAN(5620, 35),
+       CHAN(5640, 36),
+       CHAN(5660, 37),
+       CHAN(5680, 38),
+       CHAN(5700, 39),
+       CHAN(5745, 40),
+       CHAN(5765, 41),
+       CHAN(5785, 42),
+       CHAN(5805, 43),
+       CHAN(5825, 44),
+       CHAN(5170, 45),
+       CHAN(5190, 46),
+       CHAN(5210, 47),
+       CHAN(5230, 48),
+};
+#undef CHAN
+
+static struct ieee80211_supported_band ar9170_band_2GHz = {
+       .channels       = ar9170_2ghz_chantable,
+       .n_channels     = ARRAY_SIZE(ar9170_2ghz_chantable),
+       .bitrates       = ar9170_g_ratetable,
+       .n_bitrates     = ar9170_g_ratetable_size,
+};
+
+#ifdef AR9170_QUEUE_DEBUG
+/*
+ * In case some wants works with AR9170's crazy tx_status queueing techniques.
+ * He might need this rather useful probing function.
+ *
+ * NOTE: caller must hold the queue's spinlock!
+ */
+
+static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
+{
+       struct ar9170_tx_control *txc = (void *) skb->data;
+       struct ieee80211_hdr *hdr = (void *)txc->frame_data;
+
+       printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] "
+                         "mac_control:%04x, phy_control:%08x]\n",
+              wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
+              ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control),
+              le32_to_cpu(txc->phy_control));
+}
+
+static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
+                                               struct sk_buff_head *queue)
+{
+       struct sk_buff *skb;
+       int i = 0;
+
+       printk(KERN_DEBUG "---[ cut here ]---\n");
+       printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n",
+              wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
+
+       skb_queue_walk(queue, skb) {
+               struct ar9170_tx_control *txc = (void *) skb->data;
+               struct ieee80211_hdr *hdr = (void *)txc->frame_data;
+
+               printk(KERN_DEBUG "index:%d => \n", i);
+               ar9170_print_txheader(ar, skb);
+       }
+       printk(KERN_DEBUG "---[ end ]---\n");
+}
+#endif /* AR9170_QUEUE_DEBUG */
+
+static struct ieee80211_supported_band ar9170_band_5GHz = {
+       .channels       = ar9170_5ghz_chantable,
+       .n_channels     = ARRAY_SIZE(ar9170_5ghz_chantable),
+       .bitrates       = ar9170_a_ratetable,
+       .n_bitrates     = ar9170_a_ratetable_size,
+};
+
+void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+                            bool valid_status, u16 tx_status)
+{
+       struct ieee80211_tx_info *txinfo;
+       unsigned int retries = 0, queue = skb_get_queue_mapping(skb);
+       unsigned long flags;
+
+       spin_lock_irqsave(&ar->tx_stats_lock, flags);
+       ar->tx_stats[queue].len--;
+       if (ieee80211_queue_stopped(ar->hw, queue))
+               ieee80211_wake_queue(ar->hw, queue);
+       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+       txinfo = IEEE80211_SKB_CB(skb);
+       ieee80211_tx_info_clear_status(txinfo);
+
+       switch (tx_status) {
+       case AR9170_TX_STATUS_RETRY:
+               retries = 2;
+       case AR9170_TX_STATUS_COMPLETE:
+               txinfo->flags |= IEEE80211_TX_STAT_ACK;
+               break;
+
+       case AR9170_TX_STATUS_FAILED:
+               retries = ar->hw->conf.long_frame_max_tx_count;
+               break;
+
+       default:
+               printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
+                      wiphy_name(ar->hw->wiphy), tx_status);
+               break;
+       }
+
+       if (valid_status)
+               txinfo->status.rates[0].count = retries + 1;
+
+       skb_pull(skb, sizeof(struct ar9170_tx_control));
+       ieee80211_tx_status_irqsafe(ar->hw, skb);
+}
+
+static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar,
+                                               const u8 *mac,
+                                               const u32 queue,
+                                               struct sk_buff_head *q)
+{
+       unsigned long flags;
+       struct sk_buff *skb;
+
+       spin_lock_irqsave(&q->lock, flags);
+       skb_queue_walk(q, skb) {
+               struct ar9170_tx_control *txc = (void *) skb->data;
+               struct ieee80211_hdr *hdr = (void *) txc->frame_data;
+               u32 txc_queue = (le32_to_cpu(txc->phy_control) &
+                               AR9170_TX_PHY_QOS_MASK) >>
+                               AR9170_TX_PHY_QOS_SHIFT;
+
+               if  ((queue != txc_queue) ||
+                    (compare_ether_addr(ieee80211_get_DA(hdr), mac)))
+                       continue;
+
+               __skb_unlink(skb, q);
+               spin_unlock_irqrestore(&q->lock, flags);
+               return skb;
+       }
+       spin_unlock_irqrestore(&q->lock, flags);
+       return NULL;
+}
+
+static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac,
+                                             const u32 queue)
+{
+       struct ieee80211_sta *sta;
+       struct sk_buff *skb;
+
+       /*
+        * Unfortunately, the firmware does not tell to which (queued) frame
+        * this transmission status report belongs to.
+        *
+        * So we have to make risky guesses - with the scarce information
+        * the firmware provided (-> destination MAC, and phy_control) -
+        * and hope that we picked the right one...
+        */
+       rcu_read_lock();
+       sta = ieee80211_find_sta(ar->hw, mac);
+
+       if (likely(sta)) {
+               struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv;
+               skb = skb_dequeue(&sta_priv->tx_status[queue]);
+               rcu_read_unlock();
+               if (likely(skb))
+                       return skb;
+       } else
+               rcu_read_unlock();
+
+       /* scan the waste queue for candidates */
+       skb = ar9170_find_skb_in_queue(ar, mac, queue,
+                                      &ar->global_tx_status_waste);
+       if (!skb) {
+               /* so it still _must_ be in the global list. */
+               skb = ar9170_find_skb_in_queue(ar, mac, queue,
+                                              &ar->global_tx_status);
+       }
+
+#ifdef AR9170_QUEUE_DEBUG
+       if (unlikely((!skb) && net_ratelimit())) {
+               printk(KERN_ERR "%s: ESS:[%pM] does not have any "
+                               "outstanding frames in this queue (%d).\n",
+                               wiphy_name(ar->hw->wiphy), mac, queue);
+       }
+#endif /* AR9170_QUEUE_DEBUG */
+       return skb;
+}
+
+/*
+ * This worker tries to keep the global tx_status queue empty.
+ * So we can guarantee that incoming tx_status reports for
+ * unregistered stations are always synced with the actual
+ * frame - which we think - belongs to.
+ */
+
+static void ar9170_tx_status_janitor(struct work_struct *work)
+{
+       struct ar9170 *ar = container_of(work, struct ar9170,
+                                        tx_status_janitor.work);
+       struct sk_buff *skb;
+
+       if (unlikely(!IS_STARTED(ar)))
+               return ;
+
+       mutex_lock(&ar->mutex);
+       /* recycle the garbage back to mac80211... one by one. */
+       while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
+#ifdef AR9170_QUEUE_DEBUG
+               printk(KERN_DEBUG "%s: dispose queued frame =>\n",
+                      wiphy_name(ar->hw->wiphy));
+               ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+               ar9170_handle_tx_status(ar, skb, false,
+                                       AR9170_TX_STATUS_FAILED);
+       }
+
+       while ((skb = skb_dequeue(&ar->global_tx_status))) {
+#ifdef AR9170_QUEUE_DEBUG
+               printk(KERN_DEBUG "%s: moving frame into waste queue =>\n",
+                      wiphy_name(ar->hw->wiphy));
+
+               ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+               skb_queue_tail(&ar->global_tx_status_waste, skb);
+       }
+
+       /* recall the janitor in 100ms - if there's garbage in the can. */
+       if (skb_queue_len(&ar->global_tx_status_waste) > 0)
+               queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
+                                  msecs_to_jiffies(100));
+
+       mutex_unlock(&ar->mutex);
+}
+
+static void ar9170_handle_command_response(struct ar9170 *ar,
+                                          void *buf, u32 len)
+{
+       struct ar9170_cmd_response *cmd = (void *) buf;
+
+       if ((cmd->type & 0xc0) != 0xc0) {
+               ar->callback_cmd(ar, len, buf);
+               return;
+       }
+
+       /* hardware event handlers */
+       switch (cmd->type) {
+       case 0xc1: {
+               /*
+                * TX status notification:
+                * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
+                *
+                * XX always 81
+                * YY always 00
+                * M1-M6 is the MAC address
+                * R1-R4 is the transmit rate
+                * S1-S2 is the transmit status
+                */
+
+               struct sk_buff *skb;
+               u32 queue = (le32_to_cpu(cmd->tx_status.rate) &
+                           AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT;
+
+               skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue);
+               if (unlikely(!skb))
+                       return ;
+
+               ar9170_handle_tx_status(ar, skb, true,
+                                       le16_to_cpu(cmd->tx_status.status));
+               break;
+               }
+
+       case 0xc0:
+               /*
+                * pre-TBTT event
+                */
+               if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
+                       queue_work(ar->hw->workqueue, &ar->beacon_work);
+               break;
+
+       case 0xc2:
+               /*
+                * (IBSS) beacon send notification
+                * bytes: 04 c2 XX YY B4 B3 B2 B1
+                *
+                * XX always 80
+                * YY always 00
+                * B1-B4 "should" be the number of send out beacons.
+                */
+               break;
+
+       case 0xc3:
+               /* End of Atim Window */
+               break;
+
+       case 0xc4:
+       case 0xc5:
+               /* BlockACK events */
+               break;
+
+       case 0xc6:
+               /* Watchdog Interrupt */
+               break;
+
+       case 0xc9:
+               /* retransmission issue / SIFS/EIFS collision ?! */
+               break;
+
+       default:
+               printk(KERN_INFO "received unhandled event %x\n", cmd->type);
+               print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
+               break;
+       }
+}
+
+/*
+ * If the frame alignment is right (or the kernel has
+ * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
+ * is only a single MPDU in the USB frame, then we can
+ * submit to mac80211 the SKB directly. However, since
+ * there may be multiple packets in one SKB in stream
+ * mode, and we need to observe the proper ordering,
+ * this is non-trivial.
+ */
+static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
+{
+       struct sk_buff *skb;
+       struct ar9170_rx_head *head = (void *)buf;
+       struct ar9170_rx_tail *tail;
+       struct ieee80211_rx_status status;
+       int mpdu_len, i;
+       u8 error, antennas = 0, decrypt;
+       __le16 fc;
+       int reserved;
+
+       if (unlikely(!IS_STARTED(ar)))
+               return ;
+
+       /* Received MPDU */
+       mpdu_len = len;
+       mpdu_len -= sizeof(struct ar9170_rx_head);
+       mpdu_len -= sizeof(struct ar9170_rx_tail);
+       BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
+       BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24);
+
+       if (mpdu_len <= FCS_LEN)
+               return;
+
+       tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len);
+
+       for (i = 0; i < 3; i++)
+               if (tail->rssi[i] != 0x80)
+                       antennas |= BIT(i);
+
+       /* post-process RSSI */
+       for (i = 0; i < 7; i++)
+               if (tail->rssi[i] & 0x80)
+                       tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f;
+
+       memset(&status, 0, sizeof(status));
+
+       status.band = ar->channel->band;
+       status.freq = ar->channel->center_freq;
+       status.signal = ar->noise[0] + tail->rssi_combined;
+       status.noise = ar->noise[0];
+       status.antenna = antennas;
+
+       switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) {
+       case AR9170_RX_STATUS_MODULATION_CCK:
+               if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
+                       status.flag |= RX_FLAG_SHORTPRE;
+               switch (head->plcp[0]) {
+               case 0x0a:
+                       status.rate_idx = 0;
+                       break;
+               case 0x14:
+                       status.rate_idx = 1;
+                       break;
+               case 0x37:
+                       status.rate_idx = 2;
+                       break;
+               case 0x6e:
+                       status.rate_idx = 3;
+                       break;
+               default:
+                       if ((!ar->sniffer_enabled) && (net_ratelimit()))
+                               printk(KERN_ERR "%s: invalid plcp cck rate "
+                                      "(%x).\n", wiphy_name(ar->hw->wiphy),
+                                      head->plcp[0]);
+                       return;
+               }
+               break;
+       case AR9170_RX_STATUS_MODULATION_OFDM:
+               switch (head->plcp[0] & 0xF) {
+               case 0xB:
+                       status.rate_idx = 0;
+                       break;
+               case 0xF:
+                       status.rate_idx = 1;
+                       break;
+               case 0xA:
+                       status.rate_idx = 2;
+                       break;
+               case 0xE:
+                       status.rate_idx = 3;
+                       break;
+               case 0x9:
+                       status.rate_idx = 4;
+                       break;
+               case 0xD:
+                       status.rate_idx = 5;
+                       break;
+               case 0x8:
+                       status.rate_idx = 6;
+                       break;
+               case 0xC:
+                       status.rate_idx = 7;
+                       break;
+               default:
+                       if ((!ar->sniffer_enabled) && (net_ratelimit()))
+                               printk(KERN_ERR "%s: invalid plcp ofdm rate "
+                                      "(%x).\n", wiphy_name(ar->hw->wiphy),
+                                      head->plcp[0]);
+                       return;
+               }
+               if (status.band == IEEE80211_BAND_2GHZ)
+                       status.rate_idx += 4;
+               break;
+       case AR9170_RX_STATUS_MODULATION_HT:
+       case AR9170_RX_STATUS_MODULATION_DUPOFDM:
+               /* XXX */
+
+               if (net_ratelimit())
+                       printk(KERN_ERR "%s: invalid modulation\n",
+                              wiphy_name(ar->hw->wiphy));
+               return;
+       }
+
+       error = tail->error;
+
+       if (error & AR9170_RX_ERROR_MMIC) {
+               status.flag |= RX_FLAG_MMIC_ERROR;
+               error &= ~AR9170_RX_ERROR_MMIC;
+       }
+
+       if (error & AR9170_RX_ERROR_PLCP) {
+               status.flag |= RX_FLAG_FAILED_PLCP_CRC;
+               error &= ~AR9170_RX_ERROR_PLCP;
+       }
+
+       if (error & AR9170_RX_ERROR_FCS) {
+               status.flag |= RX_FLAG_FAILED_FCS_CRC;
+               error &= ~AR9170_RX_ERROR_FCS;
+       }
+
+       decrypt = ar9170_get_decrypt_type(tail);
+       if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
+           decrypt != AR9170_ENC_ALG_NONE)
+               status.flag |= RX_FLAG_DECRYPTED;
+
+       /* ignore wrong RA errors */
+       error &= ~AR9170_RX_ERROR_WRONG_RA;
+
+       if (error & AR9170_RX_ERROR_DECRYPT) {
+               error &= ~AR9170_RX_ERROR_DECRYPT;
+
+               /*
+                * Rx decryption is done in place,
+                * the original data is lost anyway.
+                */
+               return ;
+       }
+
+       /* drop any other error frames */
+       if ((error) && (net_ratelimit())) {
+               printk(KERN_DEBUG "%s: errors: %#x\n",
+                      wiphy_name(ar->hw->wiphy), error);
+               return;
+       }
+
+       buf += sizeof(struct ar9170_rx_head);
+       fc = *(__le16 *)buf;
+
+       if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc))
+               reserved = 32 + 2;
+       else
+               reserved = 32;
+
+       skb = dev_alloc_skb(mpdu_len + reserved);
+       if (!skb)
+               return;
+
+       skb_reserve(skb, reserved);
+       memcpy(skb_put(skb, mpdu_len), buf, mpdu_len);
+       ieee80211_rx_irqsafe(ar->hw, skb, &status);
+}
+
+void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
+{
+       unsigned int i, tlen, resplen;
+       u8 *tbuf, *respbuf;
+
+       tbuf = skb->data;
+       tlen = skb->len;
+
+       while (tlen >= 4) {
+               int clen = tbuf[1] << 8 | tbuf[0];
+               int wlen = (clen + 3) & ~3;
+
+               /*
+                * parse stream (if any)
+                */
+               if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
+                       printk(KERN_ERR "%s: missing tag!\n",
+                              wiphy_name(ar->hw->wiphy));
+                       return ;
+               }
+               if (wlen > tlen - 4) {
+                       printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n",
+                              wiphy_name(ar->hw->wiphy), clen, wlen, tlen);
+                       print_hex_dump(KERN_DEBUG, "data: ",
+                                      DUMP_PREFIX_OFFSET,
+                                      16, 1, tbuf, tlen, true);
+                       return ;
+               }
+               resplen = clen;
+               respbuf = tbuf + 4;
+               tbuf += wlen + 4;
+               tlen -= wlen + 4;
+
+               i = 0;
+
+               /* weird thing, but this is the same in the original driver */
+               while (resplen > 2 && i < 12 &&
+                      respbuf[0] == 0xff && respbuf[1] == 0xff) {
+                       i += 2;
+                       resplen -= 2;
+                       respbuf += 2;
+               }
+
+               if (resplen < 4)
+                       continue;
+
+               /* found the 6 * 0xffff marker? */
+               if (i == 12)
+                       ar9170_handle_command_response(ar, respbuf, resplen);
+               else
+                       ar9170_handle_mpdu(ar, respbuf, resplen);
+       }
+
+       if (tlen)
+               printk(KERN_ERR "%s: buffer remains!\n",
+                      wiphy_name(ar->hw->wiphy));
+}
+
+#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop)           \
+do {                                                                   \
+       queue.aifs = ai_fs;                                             \
+       queue.cw_min = cwmin;                                           \
+       queue.cw_max = cwmax;                                           \
+       queue.txop = _txop;                                             \
+} while (0)
+
+static int ar9170_op_start(struct ieee80211_hw *hw)
+{
+       struct ar9170 *ar = hw->priv;
+       int err, i;
+
+       mutex_lock(&ar->mutex);
+
+       /* reinitialize queues statistics */
+       memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
+       for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
+               ar->tx_stats[i].limit = 8;
+
+       /* reset QoS defaults */
+       AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023,  0); /* BEST EFFORT*/
+       AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023,  0); /* BACKGROUND */
+       AR9170_FILL_QUEUE(ar->edcf[2], 2, 7,    15, 94); /* VIDEO */
+       AR9170_FILL_QUEUE(ar->edcf[3], 2, 3,     7, 47); /* VOICE */
+       AR9170_FILL_QUEUE(ar->edcf[4], 2, 3,     7,  0); /* SPECIAL */
+
+       err = ar->open(ar);
+       if (err)
+               goto out;
+
+       err = ar9170_init_mac(ar);
+       if (err)
+               goto out;
+
+       err = ar9170_set_qos(ar);
+       if (err)
+               goto out;
+
+       err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
+       if (err)
+               goto out;
+
+       err = ar9170_init_rf(ar);
+       if (err)
+               goto out;
+
+       /* start DMA */
+       err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
+       if (err)
+               goto out;
+
+       ar->state = AR9170_STARTED;
+
+out:
+       mutex_unlock(&ar->mutex);
+       return err;
+}
+
+static void ar9170_op_stop(struct ieee80211_hw *hw)
+{
+       struct ar9170 *ar = hw->priv;
+
+       if (IS_STARTED(ar))
+               ar->state = AR9170_IDLE;
+
+       flush_workqueue(ar->hw->workqueue);
+
+       mutex_lock(&ar->mutex);
+       cancel_delayed_work_sync(&ar->tx_status_janitor);
+       cancel_work_sync(&ar->filter_config_work);
+       cancel_work_sync(&ar->beacon_work);
+       skb_queue_purge(&ar->global_tx_status_waste);
+       skb_queue_purge(&ar->global_tx_status);
+
+       if (IS_ACCEPTING_CMD(ar)) {
+               ar9170_set_leds_state(ar, 0);
+
+               /* stop DMA */
+               ar9170_write_reg(ar, 0x1c3d30, 0);
+               ar->stop(ar);
+       }
+
+       mutex_unlock(&ar->mutex);
+}
+
+int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct ar9170 *ar = hw->priv;
+       struct ieee80211_hdr *hdr;
+       struct ar9170_tx_control *txc;
+       struct ieee80211_tx_info *info;
+       struct ieee80211_rate *rate = NULL;
+       struct ieee80211_tx_rate *txrate;
+       unsigned int queue = skb_get_queue_mapping(skb);
+       unsigned long flags = 0;
+       struct ar9170_sta_info *sta_info = NULL;
+       u32 power, chains;
+       u16 keytype = 0;
+       u16 len, icv = 0;
+       int err;
+       bool tx_status;
+
+       if (unlikely(!IS_STARTED(ar)))
+               goto err_free;
+
+       hdr = (void *)skb->data;
+       info = IEEE80211_SKB_CB(skb);
+       len = skb->len;
+
+       spin_lock_irqsave(&ar->tx_stats_lock, flags);
+       if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) {
+               spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+               return NETDEV_TX_OK;
+       }
+
+       ar->tx_stats[queue].len++;
+       ar->tx_stats[queue].count++;
+       if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len)
+               ieee80211_stop_queue(hw, queue);
+
+       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+       txc = (void *)skb_push(skb, sizeof(*txc));
+
+       tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) ||
+                   ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0));
+
+       if (info->control.hw_key) {
+               icv = info->control.hw_key->icv_len;
+
+               switch (info->control.hw_key->alg) {
+               case ALG_WEP:
+                       keytype = AR9170_TX_MAC_ENCR_RC4;
+                       break;
+               case ALG_TKIP:
+                       keytype = AR9170_TX_MAC_ENCR_RC4;
+                       break;
+               case ALG_CCMP:
+                       keytype = AR9170_TX_MAC_ENCR_AES;
+                       break;
+               default:
+                       WARN_ON(1);
+                       goto err_dequeue;
+               }
+       }
+
+       /* Length */
+       txc->length = cpu_to_le16(len + icv + 4);
+
+       txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
+                                      AR9170_TX_MAC_BACKOFF);
+       txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
+                                       AR9170_TX_MAC_QOS_SHIFT);
+       txc->mac_control |= cpu_to_le16(keytype);
+       txc->phy_control = cpu_to_le32(0);
+
+       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
+
+       if (info->flags & IEEE80211_TX_CTL_AMPDU)
+               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+
+       txrate = &info->control.rates[0];
+
+       if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
+       else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
+               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
+
+       if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
+
+       if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
+
+       if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
+       /* this works because 40 MHz is 2 and dup is 3 */
+       if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
+
+       if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
+
+       if (txrate->flags & IEEE80211_TX_RC_MCS) {
+               u32 r = txrate->idx;
+               u8 *txpower;
+
+               r <<= AR9170_TX_PHY_MCS_SHIFT;
+               if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK))
+                       goto err_dequeue;
+               txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
+
+               if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
+                       if (info->band == IEEE80211_BAND_5GHZ)
+                               txpower = ar->power_5G_ht40;
+                       else
+                               txpower = ar->power_2G_ht40;
+               } else {
+                       if (info->band == IEEE80211_BAND_5GHZ)
+                               txpower = ar->power_5G_ht20;
+                       else
+                               txpower = ar->power_2G_ht20;
+               }
+
+               power = txpower[(txrate->idx) & 7];
+       } else {
+               u8 *txpower;
+               u32 mod;
+               u32 phyrate;
+               u8 idx = txrate->idx;
+
+               if (info->band != IEEE80211_BAND_2GHZ) {
+                       idx += 4;
+                       txpower = ar->power_5G_leg;
+                       mod = AR9170_TX_PHY_MOD_OFDM;
+               } else {
+                       if (idx < 4) {
+                               txpower = ar->power_2G_cck;
+                               mod = AR9170_TX_PHY_MOD_CCK;
+                       } else {
+                               mod = AR9170_TX_PHY_MOD_OFDM;
+                               txpower = ar->power_2G_ofdm;
+                       }
+               }
+
+               rate = &__ar9170_ratetable[idx];
+
+               phyrate = rate->hw_value & 0xF;
+               power = txpower[(rate->hw_value & 0x30) >> 4];
+               phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
+
+               txc->phy_control |= cpu_to_le32(mod);
+               txc->phy_control |= cpu_to_le32(phyrate);
+       }
+
+       power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
+       power &= AR9170_TX_PHY_TX_PWR_MASK;
+       txc->phy_control |= cpu_to_le32(power);
+
+       /* set TX chains */
+       if (ar->eeprom.tx_mask == 1) {
+               chains = AR9170_TX_PHY_TXCHAIN_1;
+       } else {
+               chains = AR9170_TX_PHY_TXCHAIN_2;
+
+               /* >= 36M legacy OFDM - use only one chain */
+               if (rate && rate->bitrate >= 360)
+                       chains = AR9170_TX_PHY_TXCHAIN_1;
+       }
+       txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
+
+       if (tx_status) {
+               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
+               /*
+                * WARNING:
+                * Putting the QoS queue bits into an unexplored territory is
+                * certainly not elegant.
+                *
+                * In my defense: This idea provides a reasonable way to
+                * smuggle valuable information to the tx_status callback.
+                * Also, the idea behind this bit-abuse came straight from
+                * the original driver code.
+                */
+
+               txc->phy_control |=
+                       cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
+
+               if (info->control.sta) {
+                       sta_info = (void *) info->control.sta->drv_priv;
+                       skb_queue_tail(&sta_info->tx_status[queue], skb);
+               } else {
+                       skb_queue_tail(&ar->global_tx_status, skb);
+
+                       queue_delayed_work(ar->hw->workqueue,
+                                          &ar->tx_status_janitor,
+                                          msecs_to_jiffies(100));
+               }
+       }
+
+       err = ar->tx(ar, skb, tx_status, 0);
+       if (unlikely(tx_status && err)) {
+               if (info->control.sta)
+                       skb_unlink(skb, &sta_info->tx_status[queue]);
+               else
+                       skb_unlink(skb, &ar->global_tx_status);
+       }
+
+       return NETDEV_TX_OK;
+
+err_dequeue:
+       spin_lock_irqsave(&ar->tx_stats_lock, flags);
+       ar->tx_stats[queue].len--;
+       ar->tx_stats[queue].count--;
+       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+err_free:
+       dev_kfree_skb(skb);
+       return NETDEV_TX_OK;
+}
+
+static int ar9170_op_add_interface(struct ieee80211_hw *hw,
+                                  struct ieee80211_if_init_conf *conf)
+{
+       struct ar9170 *ar = hw->priv;
+       int err = 0;
+
+       mutex_lock(&ar->mutex);
+
+       if (ar->vif) {
+               err = -EBUSY;
+               goto unlock;
+       }
+
+       ar->vif = conf->vif;
+       memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
+
+       if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
+               ar->rx_software_decryption = true;
+               ar->disable_offload = true;
+       }
+
+       ar->cur_filter = 0;
+       ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
+       err = ar9170_update_frame_filter(ar);
+       if (err)
+               goto unlock;
+
+       err = ar9170_set_operating_mode(ar);
+
+unlock:
+       mutex_unlock(&ar->mutex);
+       return err;
+}
+
+static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
+                                      struct ieee80211_if_init_conf *conf)
+{
+       struct ar9170 *ar = hw->priv;
+
+       mutex_lock(&ar->mutex);
+       ar->vif = NULL;
+       ar->want_filter = 0;
+       ar9170_update_frame_filter(ar);
+       ar9170_set_beacon_timers(ar);
+       dev_kfree_skb(ar->beacon);
+       ar->beacon = NULL;
+       ar->sniffer_enabled = false;
+       ar->rx_software_decryption = false;
+       ar9170_set_operating_mode(ar);
+       mutex_unlock(&ar->mutex);
+}
+
+static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct ar9170 *ar = hw->priv;
+       int err = 0;
+
+       mutex_lock(&ar->mutex);
+
+       if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
+               /* TODO */
+               err = 0;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
+               /* TODO */
+               err = 0;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_PS) {
+               /* TODO */
+               err = 0;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_POWER) {
+               /* TODO */
+               err = 0;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+               /*
+                * is it long_frame_max_tx_count or short_frame_max_tx_count?
+                */
+
+               err = ar9170_set_hwretry_limit(ar,
+                       ar->hw->conf.long_frame_max_tx_count);
+               if (err)
+                       goto out;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) {
+               err = ar9170_set_beacon_timers(ar);
+               if (err)
+                       goto out;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+               err = ar9170_set_channel(ar, hw->conf.channel,
+                                        AR9170_RFI_NONE, AR9170_BW_20);
+               if (err)
+                       goto out;
+               /* adjust slot time for 5 GHz */
+               if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+                       err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
+                                              9 << 10);
+       }
+
+out:
+       mutex_unlock(&ar->mutex);
+       return err;
+}
+
+static int ar9170_op_config_interface(struct ieee80211_hw *hw,
+                                     struct ieee80211_vif *vif,
+                                     struct ieee80211_if_conf *conf)
+{
+       struct ar9170 *ar = hw->priv;
+       int err = 0;
+
+       mutex_lock(&ar->mutex);
+
+       if (conf->changed & IEEE80211_IFCC_BSSID) {
+               memcpy(ar->bssid, conf->bssid, ETH_ALEN);
+               err = ar9170_set_operating_mode(ar);
+       }
+
+       if (conf->changed & IEEE80211_IFCC_BEACON) {
+               err = ar9170_update_beacon(ar);
+
+               if (err)
+                       goto out;
+               err = ar9170_set_beacon_timers(ar);
+       }
+
+out:
+       mutex_unlock(&ar->mutex);
+       return err;
+}
+
+static void ar9170_set_filters(struct work_struct *work)
+{
+       struct ar9170 *ar = container_of(work, struct ar9170,
+                                        filter_config_work);
+       int err;
+
+       if (unlikely(!IS_STARTED(ar)))
+               return ;
+
+       mutex_lock(&ar->mutex);
+       if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) {
+               err = ar9170_set_operating_mode(ar);
+               if (err)
+                       goto unlock;
+       }
+
+       if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) {
+               err = ar9170_update_multicast(ar);
+               if (err)
+                       goto unlock;
+       }
+
+       if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER)
+               err = ar9170_update_frame_filter(ar);
+
+unlock:
+       mutex_unlock(&ar->mutex);
+}
+
+static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
+                                      unsigned int changed_flags,
+                                      unsigned int *new_flags,
+                                      int mc_count, struct dev_mc_list *mclist)
+{
+       struct ar9170 *ar = hw->priv;
+
+       /* mask supported flags */
+       *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
+                     FIF_PROMISC_IN_BSS;
+
+       /*
+        * We can support more by setting the sniffer bit and
+        * then checking the error flags, later.
+        */
+
+       if (changed_flags & FIF_ALLMULTI) {
+               if (*new_flags & FIF_ALLMULTI) {
+                       ar->want_mc_hash = ~0ULL;
+               } else {
+                       u64 mchash;
+                       int i;
+
+                       /* always get broadcast frames */
+                       mchash = 1ULL << (0xff>>2);
+
+                       for (i = 0; i < mc_count; i++) {
+                               if (WARN_ON(!mclist))
+                                       break;
+                               mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
+                               mclist = mclist->next;
+                       }
+               ar->want_mc_hash = mchash;
+               }
+               ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST;
+       }
+
+       if (changed_flags & FIF_CONTROL) {
+               u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
+                            AR9170_MAC_REG_FTF_RTS |
+                            AR9170_MAC_REG_FTF_CTS |
+                            AR9170_MAC_REG_FTF_ACK |
+                            AR9170_MAC_REG_FTF_CFE |
+                            AR9170_MAC_REG_FTF_CFE_ACK;
+
+               if (*new_flags & FIF_CONTROL)
+                       ar->want_filter = ar->cur_filter | filter;
+               else
+                       ar->want_filter = ar->cur_filter & ~filter;
+
+               ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER;
+       }
+
+       if (changed_flags & FIF_PROMISC_IN_BSS) {
+               ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
+               ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC;
+       }
+
+       if (likely(IS_STARTED(ar)))
+               queue_work(ar->hw->workqueue, &ar->filter_config_work);
+}
+
+static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
+                                      struct ieee80211_vif *vif,
+                                      struct ieee80211_bss_conf *bss_conf,
+                                      u32 changed)
+{
+       struct ar9170 *ar = hw->priv;
+       int err = 0;
+
+       mutex_lock(&ar->mutex);
+
+       ar9170_regwrite_begin(ar);
+
+       if (changed & BSS_CHANGED_ASSOC) {
+               ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
+
+#ifndef CONFIG_AR9170_LEDS
+               /* enable assoc LED. */
+               err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
+#endif /* CONFIG_AR9170_LEDS */
+       }
+
+       if (changed & BSS_CHANGED_HT) {
+               /* TODO */
+               err = 0;
+       }
+
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               u32 slottime = 20;
+
+               if (bss_conf->use_short_slot)
+                       slottime = 9;
+
+               ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
+       }
+
+       if (changed & BSS_CHANGED_BASIC_RATES) {
+               u32 cck, ofdm;
+
+               if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) {
+                       ofdm = bss_conf->basic_rates;
+                       cck = 0;
+               } else {
+                       /* four cck rates */
+                       cck = bss_conf->basic_rates & 0xf;
+                       ofdm = bss_conf->basic_rates >> 4;
+               }
+               ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
+                               ofdm << 8 | cck);
+       }
+
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+       mutex_unlock(&ar->mutex);
+}
+
+static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
+{
+       struct ar9170 *ar = hw->priv;
+       int err;
+       u32 tsf_low;
+       u32 tsf_high;
+       u64 tsf;
+
+       mutex_lock(&ar->mutex);
+       err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
+       if (!err)
+               err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
+       mutex_unlock(&ar->mutex);
+
+       if (WARN_ON(err))
+               return 0;
+
+       tsf = tsf_high;
+       tsf = (tsf << 32) | tsf_low;
+       return tsf;
+}
+
+static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+                         struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+                         struct ieee80211_key_conf *key)
+{
+       struct ar9170 *ar = hw->priv;
+       int err = 0, i;
+       u8 ktype;
+
+       if ((!ar->vif) || (ar->disable_offload))
+               return -EOPNOTSUPP;
+
+       switch (key->alg) {
+       case ALG_WEP:
+               if (key->keylen == LEN_WEP40)
+                       ktype = AR9170_ENC_ALG_WEP64;
+               else
+                       ktype = AR9170_ENC_ALG_WEP128;
+               break;
+       case ALG_TKIP:
+               ktype = AR9170_ENC_ALG_TKIP;
+               break;
+       case ALG_CCMP:
+               ktype = AR9170_ENC_ALG_AESCCMP;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       mutex_lock(&ar->mutex);
+       if (cmd == SET_KEY) {
+               if (unlikely(!IS_STARTED(ar))) {
+                       err = -EOPNOTSUPP;
+                       goto out;
+               }
+
+               /* group keys need all-zeroes address */
+               if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+                       sta = NULL;
+
+               if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+                       for (i = 0; i < 64; i++)
+                               if (!(ar->usedkeys & BIT(i)))
+                                       break;
+                       if (i == 64) {
+                               ar->rx_software_decryption = true;
+                               ar9170_set_operating_mode(ar);
+                               err = -ENOSPC;
+                               goto out;
+                       }
+               } else {
+                       i = 64 + key->keyidx;
+               }
+
+               key->hw_key_idx = i;
+
+               err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
+                                       key->key, min_t(u8, 16, key->keylen));
+               if (err)
+                       goto out;
+
+               if (key->alg == ALG_TKIP) {
+                       err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
+                                               ktype, 1, key->key + 16, 16);
+                       if (err)
+                               goto out;
+
+                       /*
+                        * hardware is not capable generating the MMIC
+                        * for fragmented frames!
+                        */
+                       key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+               }
+
+               if (i < 64)
+                       ar->usedkeys |= BIT(i);
+
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+       } else {
+               if (unlikely(!IS_STARTED(ar))) {
+                       /* The device is gone... together with the key ;-) */
+                       err = 0;
+                       goto out;
+               }
+
+               err = ar9170_disable_key(ar, key->hw_key_idx);
+               if (err)
+                       goto out;
+
+               if (key->hw_key_idx < 64) {
+                       ar->usedkeys &= ~BIT(key->hw_key_idx);
+               } else {
+                       err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
+                                               AR9170_ENC_ALG_NONE, 0,
+                                               NULL, 0);
+                       if (err)
+                               goto out;
+
+                       if (key->alg == ALG_TKIP) {
+                               err = ar9170_upload_key(ar, key->hw_key_idx,
+                                                       NULL,
+                                                       AR9170_ENC_ALG_NONE, 1,
+                                                       NULL, 0);
+                               if (err)
+                                       goto out;
+                       }
+
+               }
+       }
+
+       ar9170_regwrite_begin(ar);
+       ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
+       ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+
+out:
+       mutex_unlock(&ar->mutex);
+
+       return err;
+}
+
+static void ar9170_sta_notify(struct ieee80211_hw *hw,
+                             struct ieee80211_vif *vif,
+                             enum sta_notify_cmd cmd,
+                             struct ieee80211_sta *sta)
+{
+       struct ar9170 *ar = hw->priv;
+       struct ar9170_sta_info *info = (void *) sta->drv_priv;
+       struct sk_buff *skb;
+       unsigned int i;
+
+       switch (cmd) {
+       case STA_NOTIFY_ADD:
+               for (i = 0; i < ar->hw->queues; i++)
+                       skb_queue_head_init(&info->tx_status[i]);
+               break;
+
+       case STA_NOTIFY_REMOVE:
+
+               /*
+                * transfer all outstanding frames that need a tx_status
+                * reports to the global tx_status queue
+                */
+
+               for (i = 0; i < ar->hw->queues; i++) {
+                       while ((skb = skb_dequeue(&info->tx_status[i]))) {
+#ifdef AR9170_QUEUE_DEBUG
+                               printk(KERN_DEBUG "%s: queueing frame in "
+                                         "global tx_status queue =>\n",
+                                      wiphy_name(ar->hw->wiphy));
+
+                               ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+                               skb_queue_tail(&ar->global_tx_status, skb);
+                       }
+               }
+               queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
+                                  msecs_to_jiffies(100));
+               break;
+
+       default:
+               break;
+       }
+}
+
+static int ar9170_get_stats(struct ieee80211_hw *hw,
+                           struct ieee80211_low_level_stats *stats)
+{
+       struct ar9170 *ar = hw->priv;
+       u32 val;
+       int err;
+
+       mutex_lock(&ar->mutex);
+       err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
+       ar->stats.dot11ACKFailureCount += val;
+
+       memcpy(stats, &ar->stats, sizeof(*stats));
+       mutex_unlock(&ar->mutex);
+
+       return 0;
+}
+
+static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
+                              struct ieee80211_tx_queue_stats *tx_stats)
+{
+       struct ar9170 *ar = hw->priv;
+
+       spin_lock_bh(&ar->tx_stats_lock);
+       memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
+       spin_unlock_bh(&ar->tx_stats_lock);
+
+       return 0;
+}
+
+static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
+                         const struct ieee80211_tx_queue_params *param)
+{
+       struct ar9170 *ar = hw->priv;
+       int ret;
+
+       mutex_lock(&ar->mutex);
+       if ((param) && !(queue > ar->hw->queues)) {
+               memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
+                      param, sizeof(*param));
+
+               ret = ar9170_set_qos(ar);
+       } else
+               ret = -EINVAL;
+
+       mutex_unlock(&ar->mutex);
+       return ret;
+}
+
+static const struct ieee80211_ops ar9170_ops = {
+       .start                  = ar9170_op_start,
+       .stop                   = ar9170_op_stop,
+       .tx                     = ar9170_op_tx,
+       .add_interface          = ar9170_op_add_interface,
+       .remove_interface       = ar9170_op_remove_interface,
+       .config                 = ar9170_op_config,
+       .config_interface       = ar9170_op_config_interface,
+       .configure_filter       = ar9170_op_configure_filter,
+       .conf_tx                = ar9170_conf_tx,
+       .bss_info_changed       = ar9170_op_bss_info_changed,
+       .get_tsf                = ar9170_op_get_tsf,
+       .set_key                = ar9170_set_key,
+       .sta_notify             = ar9170_sta_notify,
+       .get_stats              = ar9170_get_stats,
+       .get_tx_stats           = ar9170_get_tx_stats,
+};
+
+void *ar9170_alloc(size_t priv_size)
+{
+       struct ieee80211_hw *hw;
+       struct ar9170 *ar;
+       int i;
+
+       hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
+       if (!hw)
+               return ERR_PTR(-ENOMEM);
+
+       ar = hw->priv;
+       ar->hw = hw;
+
+       mutex_init(&ar->mutex);
+       spin_lock_init(&ar->cmdlock);
+       spin_lock_init(&ar->tx_stats_lock);
+       skb_queue_head_init(&ar->global_tx_status);
+       skb_queue_head_init(&ar->global_tx_status_waste);
+       INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
+       INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
+       INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor);
+
+       /* all hw supports 2.4 GHz, so set channel to 1 by default */
+       ar->channel = &ar9170_2ghz_chantable[0];
+
+       /* first part of wiphy init */
+       ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                        BIT(NL80211_IFTYPE_WDS) |
+                                        BIT(NL80211_IFTYPE_ADHOC);
+       ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
+                        IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+                        IEEE80211_HW_SIGNAL_DBM |
+                        IEEE80211_HW_NOISE_DBM;
+
+       ar->hw->queues = __AR9170_NUM_TXQ;
+       ar->hw->extra_tx_headroom = 8;
+       ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
+
+       ar->hw->max_rates = 1;
+       ar->hw->max_rate_tries = 3;
+
+       for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
+               ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
+
+       return ar;
+}
+
+static int ar9170_read_eeprom(struct ar9170 *ar)
+{
+#define RW     8       /* number of words to read at once */
+#define RB     (sizeof(u32) * RW)
+       DECLARE_MAC_BUF(mbuf);
+       u8 *eeprom = (void *)&ar->eeprom;
+       u8 *addr = ar->eeprom.mac_address;
+       __le32 offsets[RW];
+       int i, j, err, bands = 0;
+
+       BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
+
+       BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
+#ifndef __CHECKER__
+       /* don't want to handle trailing remains */
+       BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
+#endif
+
+       for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
+               for (j = 0; j < RW; j++)
+                       offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
+                                                RB * i + 4 * j);
+
+               err = ar->exec_cmd(ar, AR9170_CMD_RREG,
+                                  RB, (u8 *) &offsets,
+                                  RB, eeprom + RB * i);
+               if (err)
+                       return err;
+       }
+
+#undef RW
+#undef RB
+
+       if (ar->eeprom.length == cpu_to_le16(0xFFFF))
+               return -ENODATA;
+
+       if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
+               ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
+               bands++;
+       }
+       if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
+               ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
+               bands++;
+       }
+       /*
+        * I measured this, a bandswitch takes roughly
+        * 135 ms and a frequency switch about 80.
+        *
+        * FIXME: measure these values again once EEPROM settings
+        *        are used, that will influence them!
+        */
+       if (bands == 2)
+               ar->hw->channel_change_time = 135 * 1000;
+       else
+               ar->hw->channel_change_time = 80 * 1000;
+
+       ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
+       ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
+
+       /* second part of wiphy init */
+       SET_IEEE80211_PERM_ADDR(ar->hw, addr);
+
+       return bands ? 0 : -EINVAL;
+}
+
+static int ar9170_reg_notifier(struct wiphy *wiphy,
+                       struct regulatory_request *request)
+{
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct ar9170 *ar = hw->priv;
+
+       return ath_reg_notifier_apply(wiphy, request, &ar->regulatory);
+}
+
+int ar9170_register(struct ar9170 *ar, struct device *pdev)
+{
+       int err;
+
+       /* try to read EEPROM, init MAC addr */
+       err = ar9170_read_eeprom(ar);
+       if (err)
+               goto err_out;
+
+       err = ath_regd_init(&ar->regulatory, ar->hw->wiphy,
+                           ar9170_reg_notifier);
+
+       err = ieee80211_register_hw(ar->hw);
+       if (err)
+               goto err_out;
+
+       if (!ath_is_world_regd(&ar->regulatory))
+               regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2);
+
+       err = ar9170_init_leds(ar);
+       if (err)
+               goto err_unreg;
+
+#ifdef CONFIG_AR9170_LEDS
+       err = ar9170_register_leds(ar);
+       if (err)
+               goto err_unreg;
+#endif /* CONFIG_AR9170_LEDS */
+
+       dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
+                wiphy_name(ar->hw->wiphy));
+
+       return err;
+
+err_unreg:
+       ieee80211_unregister_hw(ar->hw);
+
+err_out:
+       return err;
+}
+
+void ar9170_unregister(struct ar9170 *ar)
+{
+#ifdef CONFIG_AR9170_LEDS
+       ar9170_unregister_leds(ar);
+#endif /* CONFIG_AR9170_LEDS */
+
+       ieee80211_unregister_hw(ar->hw);
+       mutex_destroy(&ar->mutex);
+}
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
new file mode 100644 (file)
index 0000000..6ce2075
--- /dev/null
@@ -0,0 +1,1240 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * PHY and RF code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 <linux/bitrev.h>
+#include "ar9170.h"
+#include "cmd.h"
+
+static int ar9170_init_power_cal(struct ar9170 *ar)
+{
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
+       ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
+
+       ar9170_regwrite_finish();
+       return ar9170_regwrite_result();
+}
+
+struct ar9170_phy_init {
+       u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
+};
+
+static struct ar9170_phy_init ar5416_phy_init[] = {
+       { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+       { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
+       { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
+       { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
+       { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
+       { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
+       { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
+       { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+       { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
+       { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+       { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+       { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+       { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
+       { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
+       { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
+       { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
+       { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
+       { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
+       { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
+       { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
+       { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
+       { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
+       { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
+       { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
+       { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
+       { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
+       { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
+       { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
+       { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
+       { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+       { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+       { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
+       { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
+       { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
+       { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
+       { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
+       { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
+       { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+       { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
+       { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
+       { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+       { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+       { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
+       { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
+       { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
+       { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
+       { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
+       { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
+       { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
+       { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
+       { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
+       { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
+       { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
+       { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
+       { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
+       { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
+       { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
+       { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
+       { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
+       { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
+       { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
+       { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
+       { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
+       { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
+       { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
+       { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+       { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
+       { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
+       { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
+       { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
+       { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
+       { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
+       { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
+       { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
+       { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
+       { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
+       { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
+       { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
+       { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
+       { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
+       { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
+       { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
+       { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
+       { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
+       { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
+       { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
+       { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
+       { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
+       { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
+       { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
+       { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
+       { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
+       { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
+       { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
+       { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
+       { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+       { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
+       { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
+       { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+       { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
+       { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
+       { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
+       { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
+       { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
+       { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
+       { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
+       { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+       { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
+       { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
+       { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
+       { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
+       { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
+       { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
+       { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
+       { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+       { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
+       { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
+       { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
+       { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
+       { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
+       { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
+       { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
+       { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
+       { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
+       { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+       { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
+       { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
+       { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
+       { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
+       { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
+       { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
+       { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
+       { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
+       { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
+       { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
+       { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+       { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+       { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
+       { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
+       { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
+       { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+       { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
+       { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
+       { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
+       { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
+       { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
+       { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
+       { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
+       { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
+       { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
+       { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
+       { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
+       { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
+       { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+       { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+       { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
+       { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
+       { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
+       { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
+       { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+       { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
+       { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+       { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
+       { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
+       { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
+       { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
+       { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
+       { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
+       { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
+       { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
+       { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
+       { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
+       { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
+       { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
+       { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+       { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+       { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+       { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
+       { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
+       { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
+       { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+       { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
+       { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+       { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+       { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
+       { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+       { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+       { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+       { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+       { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+       { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+       { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+       { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+       { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+       { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+/*     { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
+       { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
+       { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
+       { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
+       { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
+       { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
+       { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
+       { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
+       { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
+       { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
+       { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
+       { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
+       { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
+       { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
+       { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
+       { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
+       { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
+};
+
+int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
+{
+       int i, err;
+       u32 val;
+       bool is_2ghz = band == IEEE80211_BAND_2GHZ;
+       bool is_40mhz = false; /* XXX: for now */
+
+       ar9170_regwrite_begin(ar);
+
+       for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
+               if (is_40mhz) {
+                       if (is_2ghz)
+                               val = ar5416_phy_init[i]._2ghz_40;
+                       else
+                               val = ar5416_phy_init[i]._5ghz_40;
+               } else {
+                       if (is_2ghz)
+                               val = ar5416_phy_init[i]._2ghz_20;
+                       else
+                               val = ar5416_phy_init[i]._5ghz_20;
+               }
+
+               ar9170_regwrite(ar5416_phy_init[i].reg, val);
+       }
+
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+       if (err)
+               return err;
+
+       /* XXX: use EEPROM data here! */
+
+       err = ar9170_init_power_cal(ar);
+       if (err)
+               return err;
+
+       /* XXX: remove magic! */
+       if (is_2ghz)
+               err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
+       else
+               err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
+
+       return err;
+}
+
+struct ar9170_rf_init {
+       u32 reg, _5ghz, _2ghz;
+};
+
+static struct ar9170_rf_init ar9170_rf_init[] = {
+     /* bank 0 */
+     { 0x1c58b0,  0x1e5795e5,  0x1e5795e5},
+     { 0x1c58e0,  0x02008020,  0x02008020},
+     /* bank 1 */
+     { 0x1c58b0,  0x02108421,  0x02108421},
+     { 0x1c58ec,  0x00000008,  0x00000008},
+     /* bank 2 */
+     { 0x1c58b0,  0x0e73ff17,  0x0e73ff17},
+     { 0x1c58e0,  0x00000420,  0x00000420},
+     /* bank 3 */
+     { 0x1c58f0,  0x01400018,  0x01c00018},
+     /* bank 4 */
+     { 0x1c58b0,  0x000001a1,  0x000001a1},
+     { 0x1c58e8,  0x00000001,  0x00000001},
+     /* bank 5 */
+     { 0x1c58b0,  0x00000013,  0x00000013},
+     { 0x1c58e4,  0x00000002,  0x00000002},
+     /* bank 6 */
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00004000,  0x00004000},
+     { 0x1c58b0,  0x00006c00,  0x00006c00},
+     { 0x1c58b0,  0x00002c00,  0x00002c00},
+     { 0x1c58b0,  0x00004800,  0x00004800},
+     { 0x1c58b0,  0x00004000,  0x00004000},
+     { 0x1c58b0,  0x00006000,  0x00006000},
+     { 0x1c58b0,  0x00001000,  0x00001000},
+     { 0x1c58b0,  0x00004000,  0x00004000},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00087c00,  0x00087c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00005400,  0x00005400},
+     { 0x1c58b0,  0x00000c00,  0x00000c00},
+     { 0x1c58b0,  0x00001800,  0x00001800},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00006c00,  0x00006c00},
+     { 0x1c58b0,  0x00006c00,  0x00006c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00002c00,  0x00002c00},
+     { 0x1c58b0,  0x00003c00,  0x00003c00},
+     { 0x1c58b0,  0x00003800,  0x00003800},
+     { 0x1c58b0,  0x00001c00,  0x00001c00},
+     { 0x1c58b0,  0x00000800,  0x00000800},
+     { 0x1c58b0,  0x00000408,  0x00000408},
+     { 0x1c58b0,  0x00004c15,  0x00004c15},
+     { 0x1c58b0,  0x00004188,  0x00004188},
+     { 0x1c58b0,  0x0000201e,  0x0000201e},
+     { 0x1c58b0,  0x00010408,  0x00010408},
+     { 0x1c58b0,  0x00000801,  0x00000801},
+     { 0x1c58b0,  0x00000c08,  0x00000c08},
+     { 0x1c58b0,  0x0000181e,  0x0000181e},
+     { 0x1c58b0,  0x00001016,  0x00001016},
+     { 0x1c58b0,  0x00002800,  0x00002800},
+     { 0x1c58b0,  0x00004010,  0x00004010},
+     { 0x1c58b0,  0x0000081c,  0x0000081c},
+     { 0x1c58b0,  0x00000115,  0x00000115},
+     { 0x1c58b0,  0x00000015,  0x00000015},
+     { 0x1c58b0,  0x00000066,  0x00000066},
+     { 0x1c58b0,  0x0000001c,  0x0000001c},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000004,  0x00000004},
+     { 0x1c58b0,  0x00000015,  0x00000015},
+     { 0x1c58b0,  0x0000001f,  0x0000001f},
+     { 0x1c58e0,  0x00000000,  0x00000400},
+     /* bank 7 */
+     { 0x1c58b0,  0x000000a0,  0x000000a0},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000040,  0x00000040},
+     { 0x1c58f0,  0x0000001c,  0x0000001c},
+};
+
+static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
+{
+       int err, i;
+
+       ar9170_regwrite_begin(ar);
+
+       for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
+               ar9170_regwrite(ar9170_rf_init[i].reg,
+                               band5ghz ? ar9170_rf_init[i]._5ghz
+                                        : ar9170_rf_init[i]._2ghz);
+
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+       if (err)
+               printk(KERN_ERR "%s: rf init failed\n",
+                      wiphy_name(ar->hw->wiphy));
+       return err;
+}
+
+static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
+                                   u32 freq, enum ar9170_bw bw)
+{
+       int err;
+       u32 d0, d1, td0, td1, fd0, fd1;
+       u8 chansel;
+       u8 refsel0 = 1, refsel1 = 0;
+       u8 lf_synth = 0;
+
+       switch (bw) {
+       case AR9170_BW_40_ABOVE:
+               freq += 10;
+               break;
+       case AR9170_BW_40_BELOW:
+               freq -= 10;
+               break;
+       case AR9170_BW_20:
+               break;
+       case __AR9170_NUM_BW:
+               BUG();
+       }
+
+       if (band5ghz) {
+               if (freq % 10) {
+                       chansel = (freq - 4800) / 5;
+               } else {
+                       chansel = ((freq - 4800) / 10) * 2;
+                       refsel0 = 0;
+                       refsel1 = 1;
+               }
+               chansel = byte_rev_table[chansel];
+       } else {
+               if (freq == 2484) {
+                       chansel = 10 + (freq - 2274) / 5;
+                       lf_synth = 1;
+               } else
+                       chansel = 16 + (freq - 2272) / 5;
+               chansel *= 4;
+               chansel = byte_rev_table[chansel];
+       }
+
+       d1 =    chansel;
+       d0 =    0x21 |
+               refsel0 << 3 |
+               refsel1 << 2 |
+               lf_synth << 1;
+       td0 =   d0 & 0x1f;
+       td1 =   d1 & 0x1f;
+       fd0 =   td1 << 5 | td0;
+
+       td0 =   (d0 >> 5) & 0x7;
+       td1 =   (d1 >> 5) & 0x7;
+       fd1 =   td1 << 5 | td0;
+
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(0x1c58b0, fd0);
+       ar9170_regwrite(0x1c58e8, fd1);
+
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+       if (err)
+               return err;
+
+       msleep(10);
+
+       return 0;
+}
+
+struct ar9170_phy_freq_params {
+       u8 coeff_exp;
+       u16 coeff_man;
+       u8 coeff_exp_shgi;
+       u16 coeff_man_shgi;
+};
+
+struct ar9170_phy_freq_entry {
+       u16 freq;
+       struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
+};
+
+/* NB: must be in sync with channel tables in main! */
+static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
+/*
+ *     freq,
+ *             20MHz,
+ *             40MHz (below),
+ *             40Mhz (above),
+ */
+       { 2412, {
+               { 3, 21737, 3, 19563, },
+               { 3, 21827, 3, 19644, },
+               { 3, 21647, 3, 19482, },
+       } },
+       { 2417, {
+               { 3, 21692, 3, 19523, },
+               { 3, 21782, 3, 19604, },
+               { 3, 21602, 3, 19442, },
+       } },
+       { 2422, {
+               { 3, 21647, 3, 19482, },
+               { 3, 21737, 3, 19563, },
+               { 3, 21558, 3, 19402, },
+       } },
+       { 2427, {
+               { 3, 21602, 3, 19442, },
+               { 3, 21692, 3, 19523, },
+               { 3, 21514, 3, 19362, },
+       } },
+       { 2432, {
+               { 3, 21558, 3, 19402, },
+               { 3, 21647, 3, 19482, },
+               { 3, 21470, 3, 19323, },
+       } },
+       { 2437, {
+               { 3, 21514, 3, 19362, },
+               { 3, 21602, 3, 19442, },
+               { 3, 21426, 3, 19283, },
+       } },
+       { 2442, {
+               { 3, 21470, 3, 19323, },
+               { 3, 21558, 3, 19402, },
+               { 3, 21382, 3, 19244, },
+       } },
+       { 2447, {
+               { 3, 21426, 3, 19283, },
+               { 3, 21514, 3, 19362, },
+               { 3, 21339, 3, 19205, },
+       } },
+       { 2452, {
+               { 3, 21382, 3, 19244, },
+               { 3, 21470, 3, 19323, },
+               { 3, 21295, 3, 19166, },
+       } },
+       { 2457, {
+               { 3, 21339, 3, 19205, },
+               { 3, 21426, 3, 19283, },
+               { 3, 21252, 3, 19127, },
+       } },
+       { 2462, {
+               { 3, 21295, 3, 19166, },
+               { 3, 21382, 3, 19244, },
+               { 3, 21209, 3, 19088, },
+       } },
+       { 2467, {
+               { 3, 21252, 3, 19127, },
+               { 3, 21339, 3, 19205, },
+               { 3, 21166, 3, 19050, },
+       } },
+       { 2472, {
+               { 3, 21209, 3, 19088, },
+               { 3, 21295, 3, 19166, },
+               { 3, 21124, 3, 19011, },
+       } },
+       { 2484, {
+               { 3, 21107, 3, 18996, },
+               { 3, 21192, 3, 19073, },
+               { 3, 21022, 3, 18920, },
+       } },
+       { 4920, {
+               { 4, 21313, 4, 19181, },
+               { 4, 21356, 4, 19220, },
+               { 4, 21269, 4, 19142, },
+       } },
+       { 4940, {
+               { 4, 21226, 4, 19104, },
+               { 4, 21269, 4, 19142, },
+               { 4, 21183, 4, 19065, },
+       } },
+       { 4960, {
+               { 4, 21141, 4, 19027, },
+               { 4, 21183, 4, 19065, },
+               { 4, 21098, 4, 18988, },
+       } },
+       { 4980, {
+               { 4, 21056, 4, 18950, },
+               { 4, 21098, 4, 18988, },
+               { 4, 21014, 4, 18912, },
+       } },
+       { 5040, {
+               { 4, 20805, 4, 18725, },
+               { 4, 20846, 4, 18762, },
+               { 4, 20764, 4, 18687, },
+       } },
+       { 5060, {
+               { 4, 20723, 4, 18651, },
+               { 4, 20764, 4, 18687, },
+               { 4, 20682, 4, 18614, },
+       } },
+       { 5080, {
+               { 4, 20641, 4, 18577, },
+               { 4, 20682, 4, 18614, },
+               { 4, 20601, 4, 18541, },
+       } },
+       { 5180, {
+               { 4, 20243, 4, 18219, },
+               { 4, 20282, 4, 18254, },
+               { 4, 20204, 4, 18183, },
+       } },
+       { 5200, {
+               { 4, 20165, 4, 18148, },
+               { 4, 20204, 4, 18183, },
+               { 4, 20126, 4, 18114, },
+       } },
+       { 5220, {
+               { 4, 20088, 4, 18079, },
+               { 4, 20126, 4, 18114, },
+               { 4, 20049, 4, 18044, },
+       } },
+       { 5240, {
+               { 4, 20011, 4, 18010, },
+               { 4, 20049, 4, 18044, },
+               { 4, 19973, 4, 17976, },
+       } },
+       { 5260, {
+               { 4, 19935, 4, 17941, },
+               { 4, 19973, 4, 17976, },
+               { 4, 19897, 4, 17907, },
+       } },
+       { 5280, {
+               { 4, 19859, 4, 17873, },
+               { 4, 19897, 4, 17907, },
+               { 4, 19822, 4, 17840, },
+       } },
+       { 5300, {
+               { 4, 19784, 4, 17806, },
+               { 4, 19822, 4, 17840, },
+               { 4, 19747, 4, 17772, },
+       } },
+       { 5320, {
+               { 4, 19710, 4, 17739, },
+               { 4, 19747, 4, 17772, },
+               { 4, 19673, 4, 17706, },
+       } },
+       { 5500, {
+               { 4, 19065, 4, 17159, },
+               { 4, 19100, 4, 17190, },
+               { 4, 19030, 4, 17127, },
+       } },
+       { 5520, {
+               { 4, 18996, 4, 17096, },
+               { 4, 19030, 4, 17127, },
+               { 4, 18962, 4, 17065, },
+       } },
+       { 5540, {
+               { 4, 18927, 4, 17035, },
+               { 4, 18962, 4, 17065, },
+               { 4, 18893, 4, 17004, },
+       } },
+       { 5560, {
+               { 4, 18859, 4, 16973, },
+               { 4, 18893, 4, 17004, },
+               { 4, 18825, 4, 16943, },
+       } },
+       { 5580, {
+               { 4, 18792, 4, 16913, },
+               { 4, 18825, 4, 16943, },
+               { 4, 18758, 4, 16882, },
+       } },
+       { 5600, {
+               { 4, 18725, 4, 16852, },
+               { 4, 18758, 4, 16882, },
+               { 4, 18691, 4, 16822, },
+       } },
+       { 5620, {
+               { 4, 18658, 4, 16792, },
+               { 4, 18691, 4, 16822, },
+               { 4, 18625, 4, 16762, },
+       } },
+       { 5640, {
+               { 4, 18592, 4, 16733, },
+               { 4, 18625, 4, 16762, },
+               { 4, 18559, 4, 16703, },
+       } },
+       { 5660, {
+               { 4, 18526, 4, 16673, },
+               { 4, 18559, 4, 16703, },
+               { 4, 18493, 4, 16644, },
+       } },
+       { 5680, {
+               { 4, 18461, 4, 16615, },
+               { 4, 18493, 4, 16644, },
+               { 4, 18428, 4, 16586, },
+       } },
+       { 5700, {
+               { 4, 18396, 4, 16556, },
+               { 4, 18428, 4, 16586, },
+               { 4, 18364, 4, 16527, },
+       } },
+       { 5745, {
+               { 4, 18252, 4, 16427, },
+               { 4, 18284, 4, 16455, },
+               { 4, 18220, 4, 16398, },
+       } },
+       { 5765, {
+               { 4, 18189, 5, 32740, },
+               { 4, 18220, 4, 16398, },
+               { 4, 18157, 5, 32683, },
+       } },
+       { 5785, {
+               { 4, 18126, 5, 32626, },
+               { 4, 18157, 5, 32683, },
+               { 4, 18094, 5, 32570, },
+       } },
+       { 5805, {
+               { 4, 18063, 5, 32514, },
+               { 4, 18094, 5, 32570, },
+               { 4, 18032, 5, 32458, },
+       } },
+       { 5825, {
+               { 4, 18001, 5, 32402, },
+               { 4, 18032, 5, 32458, },
+               { 4, 17970, 5, 32347, },
+       } },
+       { 5170, {
+               { 4, 20282, 4, 18254, },
+               { 4, 20321, 4, 18289, },
+               { 4, 20243, 4, 18219, },
+       } },
+       { 5190, {
+               { 4, 20204, 4, 18183, },
+               { 4, 20243, 4, 18219, },
+               { 4, 20165, 4, 18148, },
+       } },
+       { 5210, {
+               { 4, 20126, 4, 18114, },
+               { 4, 20165, 4, 18148, },
+               { 4, 20088, 4, 18079, },
+       } },
+       { 5230, {
+               { 4, 20049, 4, 18044, },
+               { 4, 20088, 4, 18079, },
+               { 4, 20011, 4, 18010, },
+       } },
+};
+
+static const struct ar9170_phy_freq_params *
+ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
+                        enum ar9170_bw bw)
+{
+       unsigned int chanidx = 0;
+       u16 freq = 2412;
+
+       if (channel) {
+               chanidx = channel->hw_value;
+               freq = channel->center_freq;
+       }
+
+       BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
+
+       BUILD_BUG_ON(__AR9170_NUM_BW != 3);
+
+       WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
+
+       return &ar9170_phy_freq_params[chanidx].params[bw];
+}
+
+
+int ar9170_init_rf(struct ar9170 *ar)
+{
+       const struct ar9170_phy_freq_params *freqpar;
+       __le32 cmd[7];
+       int err;
+
+       err = ar9170_init_rf_banks_0_7(ar, false);
+       if (err)
+               return err;
+
+       err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
+       if (err)
+               return err;
+
+       freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
+
+       cmd[0] = cpu_to_le32(2412 * 1000);
+       cmd[1] = cpu_to_le32(0);
+       cmd[2] = cpu_to_le32(1);
+       cmd[3] = cpu_to_le32(freqpar->coeff_exp);
+       cmd[4] = cpu_to_le32(freqpar->coeff_man);
+       cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
+       cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
+
+       /* RF_INIT echoes the command back to us */
+       err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
+                          sizeof(cmd), (u8 *)cmd,
+                          sizeof(cmd), (u8 *)cmd);
+       if (err)
+               return err;
+
+       msleep(1000);
+
+       return ar9170_echo_test(ar, 0xaabbccdd);
+}
+
+static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
+{
+       int idx = nfreqs - 2;
+
+       while (idx >= 0) {
+               if (f >= freqs[idx])
+                       return idx;
+               idx--;
+       }
+
+       return 0;
+}
+
+static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
+{
+       /* nothing to interpolate, it's horizontal */
+       if (y2 == y1)
+               return y1;
+
+       /* check if we hit one of the edges */
+       if (x == x1)
+               return y1;
+       if (x == x2)
+               return y2;
+
+       /* x1 == x2 is bad, hopefully == x */
+       if (x2 == x1)
+               return y1;
+
+       return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
+}
+
+static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
+{
+#define SHIFT          8
+       s32 y;
+
+       y = ar9170_interpolate_s32(x << SHIFT,
+                                  x1 << SHIFT, y1 << SHIFT,
+                                  x2 << SHIFT, y2 << SHIFT);
+
+       /*
+        * XXX: unwrap this expression
+        *      Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
+        *      Can we rely on the compiler to optimise away the div?
+        */
+       return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
+#undef SHIFT
+}
+
+static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
+{
+       struct ar9170_calibration_target_power_legacy *ctpl;
+       struct ar9170_calibration_target_power_ht *ctph;
+       u8 *ctpres;
+       int ntargets;
+       int idx, i, n;
+       u8 ackpower, ackchains, f;
+       u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
+
+       if (freq < 3000)
+               f = freq - 2300;
+       else
+               f = (freq - 4800)/5;
+
+       /*
+        * cycle through the various modes
+        *
+        * legacy modes first: 5G, 2G CCK, 2G OFDM
+        */
+       for (i = 0; i < 3; i++) {
+               switch (i) {
+               case 0: /* 5 GHz legacy */
+                       ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
+                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
+                       ctpres = ar->power_5G_leg;
+                       break;
+               case 1: /* 2.4 GHz CCK */
+                       ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
+                       ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
+                       ctpres = ar->power_2G_cck;
+                       break;
+               case 2: /* 2.4 GHz OFDM */
+                       ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
+                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+                       ctpres = ar->power_2G_ofdm;
+                       break;
+               default:
+                       BUG();
+               }
+
+               for (n = 0; n < ntargets; n++) {
+                       if (ctpl[n].freq == 0xff)
+                               break;
+                       pwr_freqs[n] = ctpl[n].freq;
+               }
+               ntargets = n;
+               idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
+               for (n = 0; n < 4; n++)
+                       ctpres[n] = ar9170_interpolate_u8(
+                                       f,
+                                       ctpl[idx + 0].freq,
+                                       ctpl[idx + 0].power[n],
+                                       ctpl[idx + 1].freq,
+                                       ctpl[idx + 1].power[n]);
+       }
+
+       /*
+        * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
+        */
+       for (i = 0; i < 4; i++) {
+               switch (i) {
+               case 0: /* 5 GHz HT 20 */
+                       ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
+                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
+                       ctpres = ar->power_5G_ht20;
+                       break;
+               case 1: /* 5 GHz HT 40 */
+                       ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
+                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
+                       ctpres = ar->power_5G_ht40;
+                       break;
+               case 2: /* 2.4 GHz HT 20 */
+                       ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
+                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+                       ctpres = ar->power_2G_ht20;
+                       break;
+               case 3: /* 2.4 GHz HT 40 */
+                       ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
+                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+                       ctpres = ar->power_2G_ht40;
+                       break;
+               default:
+                       BUG();
+               }
+
+               for (n = 0; n < ntargets; n++) {
+                       if (ctph[n].freq == 0xff)
+                               break;
+                       pwr_freqs[n] = ctph[n].freq;
+               }
+               ntargets = n;
+               idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
+               for (n = 0; n < 8; n++)
+                       ctpres[n] = ar9170_interpolate_u8(
+                                       f,
+                                       ctph[idx + 0].freq,
+                                       ctph[idx + 0].power[n],
+                                       ctph[idx + 1].freq,
+                                       ctph[idx + 1].power[n]);
+       }
+
+       /* set ACK/CTS TX power */
+       ar9170_regwrite_begin(ar);
+
+       if (ar->eeprom.tx_mask != 1)
+               ackchains = AR9170_TX_PHY_TXCHAIN_2;
+       else
+               ackchains = AR9170_TX_PHY_TXCHAIN_1;
+
+       if (freq < 3000)
+               ackpower = ar->power_2G_ofdm[0] & 0x3f;
+       else
+               ackpower = ar->power_5G_leg[0] & 0x3f;
+
+       ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
+       ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
+                                 ackpower << 21 | ackchains << 27);
+
+       ar9170_regwrite_finish();
+       return ar9170_regwrite_result();
+}
+
+static int ar9170_calc_noise_dbm(u32 raw_noise)
+{
+       if (raw_noise & 0x100)
+               return ~((raw_noise & 0x0ff) >> 1);
+       else
+               return (raw_noise & 0xff) >> 1;
+}
+
+int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+                      enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
+{
+       const struct ar9170_phy_freq_params *freqpar;
+       u32 cmd, tmp, offs;
+       __le32 vals[8];
+       int i, err;
+       bool bandswitch;
+
+       /* clear BB heavy clip enable */
+       err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
+       if (err)
+               return err;
+
+       /* may be NULL at first setup */
+       if (ar->channel)
+               bandswitch = ar->channel->band != channel->band;
+       else
+               bandswitch = true;
+
+       /* HW workaround */
+       if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
+           channel->center_freq <= 2417)
+               bandswitch = true;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
+       if (err)
+               return err;
+
+       if (rfi != AR9170_RFI_NONE || bandswitch) {
+               u32 val = 0x400;
+
+               if (rfi == AR9170_RFI_COLD)
+                       val = 0x800;
+
+               /* warm/cold reset BB/ADDA */
+               err = ar9170_write_reg(ar, 0x1d4004, val);
+               if (err)
+                       return err;
+
+               err = ar9170_write_reg(ar, 0x1d4004, 0x0);
+               if (err)
+                       return err;
+
+               err = ar9170_init_phy(ar, channel->band);
+               if (err)
+                       return err;
+
+               err = ar9170_init_rf_banks_0_7(ar,
+                       channel->band == IEEE80211_BAND_5GHZ);
+               if (err)
+                       return err;
+
+               cmd = AR9170_CMD_RF_INIT;
+       } else {
+               cmd = AR9170_CMD_FREQUENCY;
+       }
+
+       err = ar9170_init_rf_bank4_pwr(ar,
+               channel->band == IEEE80211_BAND_5GHZ,
+               channel->center_freq, bw);
+       if (err)
+               return err;
+
+       switch (bw) {
+       case AR9170_BW_20:
+               tmp = 0x240;
+               offs = 0;
+               break;
+       case AR9170_BW_40_BELOW:
+               tmp = 0x2c4;
+               offs = 3;
+               break;
+       case AR9170_BW_40_ABOVE:
+               tmp = 0x2d4;
+               offs = 1;
+               break;
+       default:
+               BUG();
+               return -ENOSYS;
+       }
+
+       if (0 /* 2 streams capable */)
+               tmp |= 0x100;
+
+       err = ar9170_write_reg(ar, 0x1c5804, tmp);
+       if (err)
+               return err;
+
+       err = ar9170_set_power_cal(ar, channel->center_freq, bw);
+       if (err)
+               return err;
+
+       freqpar = ar9170_get_hw_dyn_params(channel, bw);
+
+       vals[0] = cpu_to_le32(channel->center_freq * 1000);
+       vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1);
+       vals[2] = cpu_to_le32(offs << 2 | 1);
+       vals[3] = cpu_to_le32(freqpar->coeff_exp);
+       vals[4] = cpu_to_le32(freqpar->coeff_man);
+       vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
+       vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
+       vals[7] = cpu_to_le32(1000);
+
+       err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
+                          sizeof(vals), (u8 *)vals);
+       if (err)
+               return err;
+
+       for (i = 0; i < 2; i++) {
+               ar->noise[i] = ar9170_calc_noise_dbm(
+                               (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
+
+               ar->noise[i + 2] = ar9170_calc_noise_dbm(
+                                   (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
+       }
+
+       ar->channel = channel;
+       return 0;
+}
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
new file mode 100644 (file)
index 0000000..fddda47
--- /dev/null
@@ -0,0 +1,822 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * USB - frontend
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 <linux/module.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "ar9170.h"
+#include "cmd.h"
+#include "hw.h"
+#include "usb.h"
+
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
+MODULE_FIRMWARE("ar9170-1.fw");
+MODULE_FIRMWARE("ar9170-2.fw");
+
+static struct usb_device_id ar9170_usb_ids[] = {
+       /* Atheros 9170 */
+       { USB_DEVICE(0x0cf3, 0x9170) },
+       /* Atheros TG121N */
+       { USB_DEVICE(0x0cf3, 0x1001) },
+       /* Cace Airpcap NX */
+       { USB_DEVICE(0xcace, 0x0300) },
+       /* D-Link DWA 160A */
+       { USB_DEVICE(0x07d1, 0x3c10) },
+       /* Netgear WNDA3100 */
+       { USB_DEVICE(0x0846, 0x9010) },
+       /* Netgear WN111 v2 */
+       { USB_DEVICE(0x0846, 0x9001) },
+       /* Zydas ZD1221 */
+       { USB_DEVICE(0x0ace, 0x1221) },
+       /* ZyXEL NWD271N */
+       { USB_DEVICE(0x0586, 0x3417) },
+       /* Z-Com UB81 BG */
+       { USB_DEVICE(0x0cde, 0x0023) },
+       /* Z-Com UB82 ABG */
+       { USB_DEVICE(0x0cde, 0x0026) },
+       /* Arcadyan WN7512 */
+       { USB_DEVICE(0x083a, 0xf522) },
+       /* Planex GWUS300 */
+       { USB_DEVICE(0x2019, 0x5304) },
+       /* IO-Data WNGDNUS2 */
+       { USB_DEVICE(0x04bb, 0x093f) },
+
+       /* terminate */
+       {}
+};
+MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
+
+static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
+{
+       struct sk_buff *skb = urb->context;
+       struct ar9170_usb *aru = (struct ar9170_usb *)
+             usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+
+       if (!aru) {
+               dev_kfree_skb_irq(skb);
+               return ;
+       }
+
+       ar9170_handle_tx_status(&aru->common, skb, false,
+                               AR9170_TX_STATUS_COMPLETE);
+}
+
+static void ar9170_usb_tx_urb_complete(struct urb *urb)
+{
+}
+
+static void ar9170_usb_irq_completed(struct urb *urb)
+{
+       struct ar9170_usb *aru = urb->context;
+
+       switch (urb->status) {
+       /* everything is fine */
+       case 0:
+               break;
+
+       /* disconnect */
+       case -ENOENT:
+       case -ECONNRESET:
+       case -ENODEV:
+       case -ESHUTDOWN:
+               goto free;
+
+       default:
+               goto resubmit;
+       }
+
+       print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET,
+                            urb->transfer_buffer, urb->actual_length);
+
+resubmit:
+       usb_anchor_urb(urb, &aru->rx_submitted);
+       if (usb_submit_urb(urb, GFP_ATOMIC)) {
+               usb_unanchor_urb(urb);
+               goto free;
+       }
+
+       return;
+
+free:
+       usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
+}
+
+static void ar9170_usb_rx_completed(struct urb *urb)
+{
+       struct sk_buff *skb = urb->context;
+       struct ar9170_usb *aru = (struct ar9170_usb *)
+               usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+       int err;
+
+       if (!aru)
+               goto free;
+
+       switch (urb->status) {
+       /* everything is fine */
+       case 0:
+               break;
+
+       /* disconnect */
+       case -ENOENT:
+       case -ECONNRESET:
+       case -ENODEV:
+       case -ESHUTDOWN:
+               goto free;
+
+       default:
+               goto resubmit;
+       }
+
+       skb_put(skb, urb->actual_length);
+       ar9170_rx(&aru->common, skb);
+
+resubmit:
+       skb_reset_tail_pointer(skb);
+       skb_trim(skb, 0);
+
+       usb_anchor_urb(urb, &aru->rx_submitted);
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err) {
+               usb_unanchor_urb(urb);
+               dev_kfree_skb_irq(skb);
+       }
+
+       return ;
+
+free:
+       dev_kfree_skb_irq(skb);
+       return;
+}
+
+static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
+                                 struct urb *urb, gfp_t gfp)
+{
+       struct sk_buff *skb;
+
+       skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
+       if (!skb)
+               return -ENOMEM;
+
+       /* reserve some space for mac80211's radiotap */
+       skb_reserve(skb, 32);
+
+       usb_fill_bulk_urb(urb, aru->udev,
+                         usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
+                         skb->data, min(skb_tailroom(skb),
+                         AR9170_MAX_RX_BUFFER_SIZE),
+                         ar9170_usb_rx_completed, skb);
+
+       return 0;
+}
+
+static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
+{
+       struct urb *urb = NULL;
+       void *ibuf;
+       int err = -ENOMEM;
+
+       /* initialize interrupt endpoint */
+       urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!urb)
+               goto out;
+
+       ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
+       if (!ibuf)
+               goto out;
+
+       usb_fill_int_urb(urb, aru->udev,
+                        usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
+                        64, ar9170_usb_irq_completed, aru, 1);
+       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       usb_anchor_urb(urb, &aru->rx_submitted);
+       err = usb_submit_urb(urb, GFP_KERNEL);
+       if (err) {
+               usb_unanchor_urb(urb);
+               usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
+                               urb->transfer_dma);
+       }
+
+out:
+       usb_free_urb(urb);
+       return err;
+}
+
+static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
+{
+       struct urb *urb;
+       int i;
+       int err = -EINVAL;
+
+       for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
+               err = -ENOMEM;
+               urb = usb_alloc_urb(0, GFP_KERNEL);
+               if (!urb)
+                       goto err_out;
+
+               err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
+               if (err) {
+                       usb_free_urb(urb);
+                       goto err_out;
+               }
+
+               usb_anchor_urb(urb, &aru->rx_submitted);
+               err = usb_submit_urb(urb, GFP_KERNEL);
+               if (err) {
+                       usb_unanchor_urb(urb);
+                       dev_kfree_skb_any((void *) urb->transfer_buffer);
+                       usb_free_urb(urb);
+                       goto err_out;
+               }
+               usb_free_urb(urb);
+       }
+
+       /* the device now waiting for a firmware. */
+       aru->common.state = AR9170_IDLE;
+       return 0;
+
+err_out:
+
+       usb_kill_anchored_urbs(&aru->rx_submitted);
+       return err;
+}
+
+static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
+{
+       int ret;
+
+       aru->common.state = AR9170_UNKNOWN_STATE;
+
+       usb_unlink_anchored_urbs(&aru->tx_submitted);
+
+       /* give the LED OFF command and the deauth frame a chance to air. */
+       ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
+                                           msecs_to_jiffies(100));
+       if (ret == 0)
+               dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
+       usb_poison_anchored_urbs(&aru->tx_submitted);
+
+       usb_poison_anchored_urbs(&aru->rx_submitted);
+}
+
+static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
+                              unsigned int plen, void *payload,
+                              unsigned int outlen, void *out)
+{
+       struct ar9170_usb *aru = (void *) ar;
+       struct urb *urb = NULL;
+       unsigned long flags;
+       int err = -ENOMEM;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return -EPERM;
+
+       if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
+               return -EINVAL;
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (unlikely(!urb))
+               goto err_free;
+
+       ar->cmdbuf[0] = cpu_to_le32(plen);
+       ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
+       /* writing multiple regs fills this buffer already */
+       if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
+               memcpy(&ar->cmdbuf[1], payload, plen);
+
+       spin_lock_irqsave(&aru->common.cmdlock, flags);
+       aru->readbuf = (u8 *)out;
+       aru->readlen = outlen;
+       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+
+       usb_fill_int_urb(urb, aru->udev,
+                        usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
+                        aru->common.cmdbuf, plen + 4,
+                        ar9170_usb_tx_urb_complete, NULL, 1);
+
+       usb_anchor_urb(urb, &aru->tx_submitted);
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err) {
+               usb_unanchor_urb(urb);
+               usb_free_urb(urb);
+               goto err_unbuf;
+       }
+       usb_free_urb(urb);
+
+       err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
+       if (err == 0) {
+               err = -ETIMEDOUT;
+               goto err_unbuf;
+       }
+
+       if (outlen >= 0 && aru->readlen != outlen) {
+               err = -EMSGSIZE;
+               goto err_unbuf;
+       }
+
+       return 0;
+
+err_unbuf:
+       /* Maybe the device was removed in the second we were waiting? */
+       if (IS_STARTED(ar)) {
+               dev_err(&aru->udev->dev, "no command feedback "
+                                        "received (%d).\n", err);
+
+               /* provide some maybe useful debug information */
+               print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
+                                    aru->common.cmdbuf, plen + 4);
+               dump_stack();
+       }
+
+       /* invalidate to avoid completing the next prematurely */
+       spin_lock_irqsave(&aru->common.cmdlock, flags);
+       aru->readbuf = NULL;
+       aru->readlen = 0;
+       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+
+err_free:
+
+       return err;
+}
+
+static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb,
+                        bool txstatus_needed, unsigned int extra_len)
+{
+       struct ar9170_usb *aru = (struct ar9170_usb *) ar;
+       struct urb *urb;
+       int err;
+
+       if (unlikely(!IS_STARTED(ar))) {
+               /* Seriously, what were you drink... err... thinking!? */
+               return -EPERM;
+       }
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (unlikely(!urb))
+               return -ENOMEM;
+
+       usb_fill_bulk_urb(urb, aru->udev,
+                         usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
+                         skb->data, skb->len + extra_len, (txstatus_needed ?
+                         ar9170_usb_tx_urb_complete :
+                         ar9170_usb_tx_urb_complete_free), skb);
+       urb->transfer_flags |= URB_ZERO_PACKET;
+
+       usb_anchor_urb(urb, &aru->tx_submitted);
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (unlikely(err))
+               usb_unanchor_urb(urb);
+
+       usb_free_urb(urb);
+       return err;
+}
+
+static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
+{
+       struct ar9170_usb *aru = (void *) ar;
+       unsigned long flags;
+       u32 in, out;
+
+       if (!buffer)
+               return ;
+
+       in = le32_to_cpup((__le32 *)buffer);
+       out = le32_to_cpu(ar->cmdbuf[0]);
+
+       /* mask off length byte */
+       out &= ~0xFF;
+
+       if (aru->readlen >= 0) {
+               /* add expected length */
+               out |= aru->readlen;
+       } else {
+               /* add obtained length */
+               out |= in & 0xFF;
+       }
+
+       /*
+        * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
+        * length and we cannot predict the correct length in advance.
+        * So we only check if we provided enough space for the data.
+        */
+       if (unlikely(out < in)) {
+               dev_warn(&aru->udev->dev, "received invalid command response "
+                                         "got %d bytes, instead of %d bytes "
+                                         "and the resp length is %d bytes\n",
+                        in, out, len);
+               print_hex_dump_bytes("ar9170 invalid resp: ",
+                                    DUMP_PREFIX_OFFSET, buffer, len);
+               /*
+                * Do not complete, then the command times out,
+                * and we get a stack trace from there.
+                */
+               return ;
+       }
+
+       spin_lock_irqsave(&aru->common.cmdlock, flags);
+       if (aru->readbuf && len > 0) {
+               memcpy(aru->readbuf, buffer + 4, len - 4);
+               aru->readbuf = NULL;
+       }
+       complete(&aru->cmd_wait);
+       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+}
+
+static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
+                            size_t len, u32 addr, bool complete)
+{
+       int transfer, err;
+       u8 *buf = kmalloc(4096, GFP_KERNEL);
+
+       if (!buf)
+               return -ENOMEM;
+
+       while (len) {
+               transfer = min_t(int, len, 4096);
+               memcpy(buf, data, transfer);
+
+               err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
+                                     0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
+                                     addr >> 8, 0, buf, transfer, 1000);
+
+               if (err < 0) {
+                       kfree(buf);
+                       return err;
+               }
+
+               len -= transfer;
+               data += transfer;
+               addr += transfer;
+       }
+       kfree(buf);
+
+       if (complete) {
+               err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
+                                     0x31 /* FW DL COMPLETE */,
+                                     0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
+       }
+
+       return 0;
+}
+
+static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
+{
+       int err = 0;
+
+       err = request_firmware(&aru->init_values, "ar9170-1.fw",
+                              &aru->udev->dev);
+       if (err) {
+               dev_err(&aru->udev->dev, "file with init values not found.\n");
+               return err;
+       }
+
+       err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
+       if (err) {
+               release_firmware(aru->init_values);
+               dev_err(&aru->udev->dev, "firmware file not found.\n");
+               return err;
+       }
+
+       return err;
+}
+
+static int ar9170_usb_reset(struct ar9170_usb *aru)
+{
+       int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
+
+       if (lock) {
+               ret = usb_lock_device_for_reset(aru->udev, aru->intf);
+               if (ret < 0) {
+                       dev_err(&aru->udev->dev, "unable to lock device "
+                               "for reset (%d).\n", ret);
+                       return ret;
+               }
+       }
+
+       ret = usb_reset_device(aru->udev);
+       if (lock)
+               usb_unlock_device(aru->udev);
+
+       /* let it rest - for a second - */
+       msleep(1000);
+
+       return ret;
+}
+
+static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
+{
+       int err;
+
+       /* First, upload initial values to device RAM */
+       err = ar9170_usb_upload(aru, aru->init_values->data,
+                               aru->init_values->size, 0x102800, false);
+       if (err) {
+               dev_err(&aru->udev->dev, "firmware part 1 "
+                       "upload failed (%d).\n", err);
+               return err;
+       }
+
+       /* Then, upload the firmware itself and start it */
+       return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
+                               0x200000, true);
+}
+
+static int ar9170_usb_init_transport(struct ar9170_usb *aru)
+{
+       struct ar9170 *ar = (void *) &aru->common;
+       int err;
+
+       ar9170_regwrite_begin(ar);
+
+       /* Set USB Rx stream mode MAX packet number to 2 */
+       ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
+
+       /* Set USB Rx stream mode timeout to 10us */
+       ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
+
+       ar9170_regwrite_finish();
+
+       err = ar9170_regwrite_result();
+       if (err)
+               dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
+
+       return err;
+}
+
+static void ar9170_usb_stop(struct ar9170 *ar)
+{
+       struct ar9170_usb *aru = (void *) ar;
+       int ret;
+
+       if (IS_ACCEPTING_CMD(ar))
+               aru->common.state = AR9170_STOPPED;
+
+       /* lets wait a while until the tx - queues are dried out */
+       ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
+                                           msecs_to_jiffies(1000));
+       if (ret == 0)
+               dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
+
+       usb_poison_anchored_urbs(&aru->tx_submitted);
+
+       /*
+        * Note:
+        * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
+        * Else we would end up with a unresponsive device...
+        */
+}
+
+static int ar9170_usb_open(struct ar9170 *ar)
+{
+       struct ar9170_usb *aru = (void *) ar;
+       int err;
+
+       usb_unpoison_anchored_urbs(&aru->tx_submitted);
+       err = ar9170_usb_init_transport(aru);
+       if (err) {
+               usb_poison_anchored_urbs(&aru->tx_submitted);
+               return err;
+       }
+
+       aru->common.state = AR9170_IDLE;
+       return 0;
+}
+
+static int ar9170_usb_init_device(struct ar9170_usb *aru)
+{
+       int err;
+
+       err = ar9170_usb_alloc_rx_irq_urb(aru);
+       if (err)
+               goto err_out;
+
+       err = ar9170_usb_alloc_rx_bulk_urbs(aru);
+       if (err)
+               goto err_unrx;
+
+       err = ar9170_usb_upload_firmware(aru);
+       if (err) {
+               err = ar9170_echo_test(&aru->common, 0x60d43110);
+               if (err) {
+                       /* force user invention, by disabling the device */
+                       err = usb_driver_set_configuration(aru->udev, -1);
+                       dev_err(&aru->udev->dev, "device is in a bad state. "
+                                                "please reconnect it!\n");
+                       goto err_unrx;
+               }
+       }
+
+       return 0;
+
+err_unrx:
+       ar9170_usb_cancel_urbs(aru);
+
+err_out:
+       return err;
+}
+
+static int ar9170_usb_probe(struct usb_interface *intf,
+                       const struct usb_device_id *id)
+{
+       struct ar9170_usb *aru;
+       struct ar9170 *ar;
+       struct usb_device *udev;
+       int err;
+
+       aru = ar9170_alloc(sizeof(*aru));
+       if (IS_ERR(aru)) {
+               err = PTR_ERR(aru);
+               goto out;
+       }
+
+       udev = interface_to_usbdev(intf);
+       usb_get_dev(udev);
+       aru->udev = udev;
+       aru->intf = intf;
+       ar = &aru->common;
+
+       usb_set_intfdata(intf, aru);
+       SET_IEEE80211_DEV(ar->hw, &udev->dev);
+
+       init_usb_anchor(&aru->rx_submitted);
+       init_usb_anchor(&aru->tx_submitted);
+       init_completion(&aru->cmd_wait);
+
+       aru->common.stop = ar9170_usb_stop;
+       aru->common.open = ar9170_usb_open;
+       aru->common.tx = ar9170_usb_tx;
+       aru->common.exec_cmd = ar9170_usb_exec_cmd;
+       aru->common.callback_cmd = ar9170_usb_callback_cmd;
+
+       err = ar9170_usb_reset(aru);
+       if (err)
+               goto err_freehw;
+
+       err = ar9170_usb_request_firmware(aru);
+       if (err)
+               goto err_freehw;
+
+       err = ar9170_usb_init_device(aru);
+       if (err)
+               goto err_freefw;
+
+       err = ar9170_usb_open(ar);
+       if (err)
+               goto err_unrx;
+
+       err = ar9170_register(ar, &udev->dev);
+
+       ar9170_usb_stop(ar);
+       if (err)
+               goto err_unrx;
+
+       return 0;
+
+err_unrx:
+       ar9170_usb_cancel_urbs(aru);
+
+err_freefw:
+       release_firmware(aru->init_values);
+       release_firmware(aru->firmware);
+
+err_freehw:
+       usb_set_intfdata(intf, NULL);
+       usb_put_dev(udev);
+       ieee80211_free_hw(ar->hw);
+out:
+       return err;
+}
+
+static void ar9170_usb_disconnect(struct usb_interface *intf)
+{
+       struct ar9170_usb *aru = usb_get_intfdata(intf);
+
+       if (!aru)
+               return;
+
+       aru->common.state = AR9170_IDLE;
+       ar9170_unregister(&aru->common);
+       ar9170_usb_cancel_urbs(aru);
+
+       release_firmware(aru->init_values);
+       release_firmware(aru->firmware);
+
+       usb_put_dev(aru->udev);
+       usb_set_intfdata(intf, NULL);
+       ieee80211_free_hw(aru->common.hw);
+}
+
+#ifdef CONFIG_PM
+static int ar9170_suspend(struct usb_interface *intf,
+                         pm_message_t  message)
+{
+       struct ar9170_usb *aru = usb_get_intfdata(intf);
+
+       if (!aru)
+               return -ENODEV;
+
+       aru->common.state = AR9170_IDLE;
+       ar9170_usb_cancel_urbs(aru);
+
+       return 0;
+}
+
+static int ar9170_resume(struct usb_interface *intf)
+{
+       struct ar9170_usb *aru = usb_get_intfdata(intf);
+       int err;
+
+       if (!aru)
+               return -ENODEV;
+
+       usb_unpoison_anchored_urbs(&aru->rx_submitted);
+       usb_unpoison_anchored_urbs(&aru->tx_submitted);
+
+       /*
+        * FIXME: firmware upload will fail on resume.
+        * but this is better than a hang!
+        */
+
+       err = ar9170_usb_init_device(aru);
+       if (err)
+               goto err_unrx;
+
+       err = ar9170_usb_open(&aru->common);
+       if (err)
+               goto err_unrx;
+
+       return 0;
+
+err_unrx:
+       aru->common.state = AR9170_IDLE;
+       ar9170_usb_cancel_urbs(aru);
+
+       return err;
+}
+#endif /* CONFIG_PM */
+
+static struct usb_driver ar9170_driver = {
+       .name = "ar9170usb",
+       .probe = ar9170_usb_probe,
+       .disconnect = ar9170_usb_disconnect,
+       .id_table = ar9170_usb_ids,
+       .soft_unbind = 1,
+#ifdef CONFIG_PM
+       .suspend = ar9170_suspend,
+       .resume = ar9170_resume,
+#endif /* CONFIG_PM */
+};
+
+static int __init ar9170_init(void)
+{
+       return usb_register(&ar9170_driver);
+}
+
+static void __exit ar9170_exit(void)
+{
+       usb_deregister(&ar9170_driver);
+}
+
+module_init(ar9170_init);
+module_exit(ar9170_exit);
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h
new file mode 100644 (file)
index 0000000..f585292
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Atheros AR9170 USB driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-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 __USB_H
+#define __USB_H
+
+#include <linux/usb.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <linux/leds.h>
+#include <net/wireless.h>
+#include <net/mac80211.h>
+#include <linux/firmware.h>
+#include "eeprom.h"
+#include "hw.h"
+#include "ar9170.h"
+
+#define AR9170_NUM_RX_URBS                     16
+
+struct firmware;
+
+struct ar9170_usb {
+       struct ar9170 common;
+       struct usb_device *udev;
+       struct usb_interface *intf;
+
+       struct usb_anchor rx_submitted;
+       struct usb_anchor tx_submitted;
+
+       spinlock_t cmdlock;
+       struct completion cmd_wait;
+       int readlen;
+       u8 *readbuf;
+
+       const struct firmware *init_values;
+       const struct firmware *firmware;
+};
+
+#endif /* __USB_H */
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
new file mode 100644 (file)
index 0000000..509b6f9
--- /dev/null
@@ -0,0 +1,41 @@
+config ATH5K
+       tristate "Atheros 5xxx wireless cards support"
+       depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+       select ATH_COMMON
+       select MAC80211_LEDS
+       select LEDS_CLASS
+       select NEW_LEDS
+       ---help---
+         This module adds support for wireless adapters based on
+         Atheros 5xxx chipset.
+
+         Currently the following chip versions are supported:
+
+         MAC: AR5211 AR5212
+         PHY: RF5111/2111 RF5112/2112 RF5413/2413
+
+         This driver uses the kernel's mac80211 subsystem.
+
+         If you choose to build a module, it'll be called ath5k. Say M if
+         unsure.
+
+config ATH5K_DEBUG
+       bool "Atheros 5xxx debugging"
+       depends on ATH5K
+       ---help---
+         Atheros 5xxx debugging messages.
+
+         Say Y, if and you will get debug options for ath5k.
+         To use this, you need to mount debugfs:
+
+         mkdir /debug/
+         mount -t debugfs debug /debug/
+
+         You will get access to files under:
+         /debug/ath5k/phy0/
+
+         To enable debug, pass the debug level to the debug module
+         parameter. For example:
+
+         modprobe ath5k debug=0x00000400
+
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
new file mode 100644 (file)
index 0000000..84a74c5
--- /dev/null
@@ -0,0 +1,15 @@
+ath5k-y                                += caps.o
+ath5k-y                                += initvals.o
+ath5k-y                                += eeprom.o
+ath5k-y                                += gpio.o
+ath5k-y                                += desc.o
+ath5k-y                                += dma.o
+ath5k-y                                += qcu.o
+ath5k-y                                += pcu.o
+ath5k-y                                += phy.o
+ath5k-y                                += reset.o
+ath5k-y                                += attach.o
+ath5k-y                                += base.o
+ath5k-y                                += led.o
+ath5k-$(CONFIG_ATH5K_DEBUG)    += debug.o
+obj-$(CONFIG_ATH5K)            += ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
new file mode 100644 (file)
index 0000000..60c6d2e
--- /dev/null
@@ -0,0 +1,1354 @@
+/*
+ * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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 _ATH5K_H
+#define _ATH5K_H
+
+/* TODO: Clean up channel debuging -doesn't work anyway- and start
+ * working on reg. control code using all available eeprom information
+ * -rev. engineering needed- */
+#define CHAN_DEBUG     0
+
+#include <linux/io.h>
+#include <linux/types.h>
+#include <net/mac80211.h>
+
+#include "../regd.h"
+
+/* RX/TX descriptor hw structs
+ * TODO: Driver part should only see sw structs */
+#include "desc.h"
+
+/* EEPROM structs/offsets
+ * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
+ * and clean up common bits, then introduce set/get functions in eeprom.c */
+#include "eeprom.h"
+
+/* PCI IDs */
+#define PCI_DEVICE_ID_ATHEROS_AR5210           0x0007 /* AR5210 */
+#define PCI_DEVICE_ID_ATHEROS_AR5311           0x0011 /* AR5311 */
+#define PCI_DEVICE_ID_ATHEROS_AR5211           0x0012 /* AR5211 */
+#define PCI_DEVICE_ID_ATHEROS_AR5212           0x0013 /* AR5212 */
+#define PCI_DEVICE_ID_3COM_3CRDAG675           0x0013 /* 3CRDAG675 (Atheros AR5212) */
+#define PCI_DEVICE_ID_3COM_2_3CRPAG175                 0x0013 /* 3CRPAG175 (Atheros AR5212) */
+#define PCI_DEVICE_ID_ATHEROS_AR5210_AP        0x0207 /* AR5210 (Early) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_IBM       0x1014 /* AR5212 (IBM MiniPCI) */
+#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT   0x1107 /* AR5210 (no eeprom) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT   0x1113 /* AR5212 (no eeprom) */
+#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT   0x1112 /* AR5211 (no eeprom) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA      0xf013 /* AR5212 (emulation board) */
+#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY    0xff12 /* AR5211 (emulation board) */
+#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B   0xf11b /* AR5211 (emulation board) */
+#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2      0x0052 /* AR5312 WMAC (AP31) */
+#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7      0x0057 /* AR5312 WMAC (AP30-040) */
+#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8      0x0058 /* AR5312 WMAC (AP43-030) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0014      0x0014 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0015      0x0015 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0016      0x0016 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0017      0x0017 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0018      0x0018 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0019      0x0019 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR2413           0x001a /* AR2413 (Griffin-lite) */
+#define PCI_DEVICE_ID_ATHEROS_AR5413           0x001b /* AR5413 (Eagle) */
+#define PCI_DEVICE_ID_ATHEROS_AR5424           0x001c /* AR5424 (Condor PCI-E) */
+#define PCI_DEVICE_ID_ATHEROS_AR5416           0x0023 /* AR5416 */
+#define PCI_DEVICE_ID_ATHEROS_AR5418           0x0024 /* AR5418 */
+
+/****************************\
+  GENERIC DRIVER DEFINITIONS
+\****************************/
+
+#define ATH5K_PRINTF(fmt, ...)   printk("%s: " fmt, __func__, ##__VA_ARGS__)
+
+#define ATH5K_PRINTK(_sc, _level, _fmt, ...) \
+       printk(_level "ath5k %s: " _fmt, \
+               ((_sc) && (_sc)->hw) ? wiphy_name((_sc)->hw->wiphy) : "", \
+               ##__VA_ARGS__)
+
+#define ATH5K_PRINTK_LIMIT(_sc, _level, _fmt, ...) do { \
+       if (net_ratelimit()) \
+               ATH5K_PRINTK(_sc, _level, _fmt, ##__VA_ARGS__); \
+       } while (0)
+
+#define ATH5K_INFO(_sc, _fmt, ...) \
+       ATH5K_PRINTK(_sc, KERN_INFO, _fmt, ##__VA_ARGS__)
+
+#define ATH5K_WARN(_sc, _fmt, ...) \
+       ATH5K_PRINTK_LIMIT(_sc, KERN_WARNING, _fmt, ##__VA_ARGS__)
+
+#define ATH5K_ERR(_sc, _fmt, ...) \
+       ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__)
+
+/*
+ * AR5K REGISTER ACCESS
+ */
+
+/* Some macros to read/write fields */
+
+/* First shift, then mask */
+#define AR5K_REG_SM(_val, _flags)                                      \
+       (((_val) << _flags##_S) & (_flags))
+
+/* First mask, then shift */
+#define AR5K_REG_MS(_val, _flags)                                      \
+       (((_val) & (_flags)) >> _flags##_S)
+
+/* Some registers can hold multiple values of interest. For this
+ * reason when we want to write to these registers we must first
+ * retrieve the values which we do not want to clear (lets call this
+ * old_data) and then set the register with this and our new_value:
+ * ( old_data | new_value) */
+#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val)                    \
+       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \
+           (((_val) << _flags##_S) & (_flags)), _reg)
+
+#define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask)                  \
+       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) &           \
+                       (_mask)) | (_flags), _reg)
+
+#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)                         \
+       ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg)
+
+#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags)                        \
+       ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg)
+
+/* Access to PHY registers */
+#define AR5K_PHY_READ(ah, _reg)                                        \
+       ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
+
+#define AR5K_PHY_WRITE(ah, _reg, _val)                                 \
+       ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
+
+/* Access QCU registers per queue */
+#define AR5K_REG_READ_Q(ah, _reg, _queue)                              \
+       (ath5k_hw_reg_read(ah, _reg) & (1 << _queue))                   \
+
+#define AR5K_REG_WRITE_Q(ah, _reg, _queue)                             \
+       ath5k_hw_reg_write(ah, (1 << _queue), _reg)
+
+#define AR5K_Q_ENABLE_BITS(_reg, _queue) do {                          \
+       _reg |= 1 << _queue;                                            \
+} while (0)
+
+#define AR5K_Q_DISABLE_BITS(_reg, _queue) do {                         \
+       _reg &= ~(1 << _queue);                                         \
+} while (0)
+
+/* Used while writing initvals */
+#define AR5K_REG_WAIT(_i) do {                                         \
+       if (_i % 64)                                                    \
+               udelay(1);                                              \
+} while (0)
+
+/* Register dumps are done per operation mode */
+#define AR5K_INI_RFGAIN_5GHZ           0
+#define AR5K_INI_RFGAIN_2GHZ           1
+
+/* TODO: Clean this up */
+#define AR5K_INI_VAL_11A               0
+#define AR5K_INI_VAL_11A_TURBO         1
+#define AR5K_INI_VAL_11B               2
+#define AR5K_INI_VAL_11G               3
+#define AR5K_INI_VAL_11G_TURBO         4
+#define AR5K_INI_VAL_XR                        0
+#define AR5K_INI_VAL_MAX               5
+
+/* Used for BSSID etc manipulation */
+#define AR5K_LOW_ID(_a)(                               \
+(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
+)
+
+#define AR5K_HIGH_ID(_a)       ((_a)[4] | (_a)[5] << 8)
+
+/*
+ * Some tuneable values (these should be changeable by the user)
+ * TODO: Make use of them and add more options OR use debug/configfs
+ */
+#define AR5K_TUNE_DMA_BEACON_RESP              2
+#define AR5K_TUNE_SW_BEACON_RESP               10
+#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF      0
+#define AR5K_TUNE_RADAR_ALERT                  false
+#define AR5K_TUNE_MIN_TX_FIFO_THRES            1
+#define AR5K_TUNE_MAX_TX_FIFO_THRES            ((IEEE80211_MAX_LEN / 64) + 1)
+#define AR5K_TUNE_REGISTER_TIMEOUT             20000
+/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
+ * be the max value. */
+#define AR5K_TUNE_RSSI_THRES                   129
+/* This must be set when setting the RSSI threshold otherwise it can
+ * prevent a reset. If AR5K_RSSI_THR is read after writing to it
+ * the BMISS_THRES will be seen as 0, seems harware doesn't keep
+ * track of it. Max value depends on harware. For AR5210 this is just 7.
+ * For AR5211+ this seems to be up to 255. */
+#define AR5K_TUNE_BMISS_THRES                  7
+#define AR5K_TUNE_REGISTER_DWELL_TIME          20000
+#define AR5K_TUNE_BEACON_INTERVAL              100
+#define AR5K_TUNE_AIFS                         2
+#define AR5K_TUNE_AIFS_11B                     2
+#define AR5K_TUNE_AIFS_XR                      0
+#define AR5K_TUNE_CWMIN                                15
+#define AR5K_TUNE_CWMIN_11B                    31
+#define AR5K_TUNE_CWMIN_XR                     3
+#define AR5K_TUNE_CWMAX                                1023
+#define AR5K_TUNE_CWMAX_11B                    1023
+#define AR5K_TUNE_CWMAX_XR                     7
+#define AR5K_TUNE_NOISE_FLOOR                  -72
+#define AR5K_TUNE_MAX_TXPOWER                  63
+#define AR5K_TUNE_DEFAULT_TXPOWER              25
+#define AR5K_TUNE_TPC_TXPOWER                  false
+#define AR5K_TUNE_ANT_DIVERSITY                        true
+#define AR5K_TUNE_HWTXTRIES                    4
+
+#define AR5K_INIT_CARR_SENSE_EN                        1
+
+/*Swap RX/TX Descriptor for big endian archs*/
+#if defined(__BIG_ENDIAN)
+#define AR5K_INIT_CFG  (               \
+       AR5K_CFG_SWTD | AR5K_CFG_SWRD   \
+)
+#else
+#define AR5K_INIT_CFG  0x00000000
+#endif
+
+/* Initial values */
+#define        AR5K_INIT_CYCRSSI_THR1                  2
+#define AR5K_INIT_TX_LATENCY                   502
+#define AR5K_INIT_USEC                         39
+#define AR5K_INIT_USEC_TURBO                   79
+#define AR5K_INIT_USEC_32                      31
+#define AR5K_INIT_SLOT_TIME                    396
+#define AR5K_INIT_SLOT_TIME_TURBO              480
+#define AR5K_INIT_ACK_CTS_TIMEOUT              1024
+#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO                0x08000800
+#define AR5K_INIT_PROG_IFS                     920
+#define AR5K_INIT_PROG_IFS_TURBO               960
+#define AR5K_INIT_EIFS                         3440
+#define AR5K_INIT_EIFS_TURBO                   6880
+#define AR5K_INIT_SIFS                         560
+#define AR5K_INIT_SIFS_TURBO                   480
+#define AR5K_INIT_SH_RETRY                     10
+#define AR5K_INIT_LG_RETRY                     AR5K_INIT_SH_RETRY
+#define AR5K_INIT_SSH_RETRY                    32
+#define AR5K_INIT_SLG_RETRY                    AR5K_INIT_SSH_RETRY
+#define AR5K_INIT_TX_RETRY                     10
+
+#define AR5K_INIT_TRANSMIT_LATENCY             (                       \
+       (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) |       \
+       (AR5K_INIT_USEC)                                                \
+)
+#define AR5K_INIT_TRANSMIT_LATENCY_TURBO       (                       \
+       (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) |       \
+       (AR5K_INIT_USEC_TURBO)                                          \
+)
+#define AR5K_INIT_PROTO_TIME_CNTRL             (                       \
+       (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) |      \
+       (AR5K_INIT_PROG_IFS)                                            \
+)
+#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO       (                       \
+       (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
+       (AR5K_INIT_PROG_IFS_TURBO)                                      \
+)
+
+/* token to use for aifs, cwmin, cwmax in MadWiFi */
+#define        AR5K_TXQ_USEDEFAULT     ((u32) -1)
+
+/* GENERIC CHIPSET DEFINITIONS */
+
+/* MAC Chips */
+enum ath5k_version {
+       AR5K_AR5210     = 0,
+       AR5K_AR5211     = 1,
+       AR5K_AR5212     = 2,
+};
+
+/* PHY Chips */
+enum ath5k_radio {
+       AR5K_RF5110     = 0,
+       AR5K_RF5111     = 1,
+       AR5K_RF5112     = 2,
+       AR5K_RF2413     = 3,
+       AR5K_RF5413     = 4,
+       AR5K_RF2316     = 5,
+       AR5K_RF2317     = 6,
+       AR5K_RF2425     = 7,
+};
+
+/*
+ * Common silicon revision/version values
+ */
+
+enum ath5k_srev_type {
+       AR5K_VERSION_MAC,
+       AR5K_VERSION_RAD,
+};
+
+struct ath5k_srev_name {
+       const char              *sr_name;
+       enum ath5k_srev_type    sr_type;
+       u_int                   sr_val;
+};
+
+#define AR5K_SREV_UNKNOWN      0xffff
+
+#define AR5K_SREV_AR5210       0x00 /* Crete */
+#define AR5K_SREV_AR5311       0x10 /* Maui 1 */
+#define AR5K_SREV_AR5311A      0x20 /* Maui 2 */
+#define AR5K_SREV_AR5311B      0x30 /* Spirit */
+#define AR5K_SREV_AR5211       0x40 /* Oahu */
+#define AR5K_SREV_AR5212       0x50 /* Venice */
+#define AR5K_SREV_AR5213       0x55 /* ??? */
+#define AR5K_SREV_AR5213A      0x59 /* Hainan */
+#define AR5K_SREV_AR2413       0x78 /* Griffin lite */
+#define AR5K_SREV_AR2414       0x70 /* Griffin */
+#define AR5K_SREV_AR5424       0x90 /* Condor */
+#define AR5K_SREV_AR5413       0xa4 /* Eagle lite */
+#define AR5K_SREV_AR5414       0xa0 /* Eagle */
+#define AR5K_SREV_AR2415       0xb0 /* Talon */
+#define AR5K_SREV_AR5416       0xc0 /* PCI-E */
+#define AR5K_SREV_AR5418       0xca /* PCI-E */
+#define AR5K_SREV_AR2425       0xe0 /* Swan */
+#define AR5K_SREV_AR2417       0xf0 /* Nala */
+
+#define AR5K_SREV_RAD_5110     0x00
+#define AR5K_SREV_RAD_5111     0x10
+#define AR5K_SREV_RAD_5111A    0x15
+#define AR5K_SREV_RAD_2111     0x20
+#define AR5K_SREV_RAD_5112     0x30
+#define AR5K_SREV_RAD_5112A    0x35
+#define        AR5K_SREV_RAD_5112B     0x36
+#define AR5K_SREV_RAD_2112     0x40
+#define AR5K_SREV_RAD_2112A    0x45
+#define        AR5K_SREV_RAD_2112B     0x46
+#define AR5K_SREV_RAD_2413     0x50
+#define AR5K_SREV_RAD_5413     0x60
+#define AR5K_SREV_RAD_2316     0x70 /* Cobra SoC */
+#define AR5K_SREV_RAD_2317     0x80
+#define AR5K_SREV_RAD_5424     0xa0 /* Mostly same as 5413 */
+#define AR5K_SREV_RAD_2425     0xa2
+#define AR5K_SREV_RAD_5133     0xc0
+
+#define AR5K_SREV_PHY_5211     0x30
+#define AR5K_SREV_PHY_5212     0x41
+#define        AR5K_SREV_PHY_5212A     0x42
+#define AR5K_SREV_PHY_5212B    0x43
+#define AR5K_SREV_PHY_2413     0x45
+#define AR5K_SREV_PHY_5413     0x61
+#define AR5K_SREV_PHY_2425     0x70
+
+/* IEEE defs */
+#define IEEE80211_MAX_LEN       2500
+
+/* TODO add support to mac80211 for vendor-specific rates and modes */
+
+/*
+ * Some of this information is based on Documentation from:
+ *
+ * http://madwifi.org/wiki/ChipsetFeatures/SuperAG
+ *
+ * Modulation for Atheros' eXtended Range - range enhancing extension that is
+ * supposed to double the distance an Atheros client device can keep a
+ * connection with an Atheros access point. This is achieved by increasing
+ * the receiver sensitivity up to, -105dBm, which is about 20dB above what
+ * the 802.11 specifications demand. In addition, new (proprietary) data rates
+ * are introduced: 3, 2, 1, 0.5 and 0.25 MBit/s.
+ *
+ * Please note that can you either use XR or TURBO but you cannot use both,
+ * they are exclusive.
+ *
+ */
+#define MODULATION_XR          0x00000200
+/*
+ * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a
+ * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s
+ * signaling rate achieved through the bonding of two 54Mbit/s 802.11g
+ * channels. To use this feature your Access Point must also suport it.
+ * There is also a distinction between "static" and "dynamic" turbo modes:
+ *
+ * - Static: is the dumb version: devices set to this mode stick to it until
+ *     the mode is turned off.
+ * - Dynamic: is the intelligent version, the network decides itself if it
+ *     is ok to use turbo. As soon as traffic is detected on adjacent channels
+ *     (which would get used in turbo mode), or when a non-turbo station joins
+ *     the network, turbo mode won't be used until the situation changes again.
+ *     Dynamic mode is achieved by Atheros' Adaptive Radio (AR) feature which
+ *     monitors the used radio band in order to decide whether turbo mode may
+ *     be used or not.
+ *
+ * This article claims Super G sticks to bonding of channels 5 and 6 for
+ * USA:
+ *
+ * http://www.pcworld.com/article/id,113428-page,1/article.html
+ *
+ * The channel bonding seems to be driver specific though. In addition to
+ * deciding what channels will be used, these "Turbo" modes are accomplished
+ * by also enabling the following features:
+ *
+ * - Bursting: allows multiple frames to be sent at once, rather than pausing
+ *     after each frame. Bursting is a standards-compliant feature that can be
+ *     used with any Access Point.
+ * - Fast frames: increases the amount of information that can be sent per
+ *     frame, also resulting in a reduction of transmission overhead. It is a
+ *     proprietary feature that needs to be supported by the Access Point.
+ * - Compression: data frames are compressed in real time using a Lempel Ziv
+ *     algorithm. This is done transparently. Once this feature is enabled,
+ *     compression and decompression takes place inside the chipset, without
+ *     putting additional load on the host CPU.
+ *
+ */
+#define MODULATION_TURBO       0x00000080
+
+enum ath5k_driver_mode {
+       AR5K_MODE_11A           =       0,
+       AR5K_MODE_11A_TURBO     =       1,
+       AR5K_MODE_11B           =       2,
+       AR5K_MODE_11G           =       3,
+       AR5K_MODE_11G_TURBO     =       4,
+       AR5K_MODE_XR            =       0,
+       AR5K_MODE_MAX           =       5
+};
+
+
+/****************\
+  TX DEFINITIONS
+\****************/
+
+/*
+ * TX Status descriptor
+ */
+struct ath5k_tx_status {
+       u16     ts_seqnum;
+       u16     ts_tstamp;
+       u8      ts_status;
+       u8      ts_rate[4];
+       u8      ts_retry[4];
+       u8      ts_final_idx;
+       s8      ts_rssi;
+       u8      ts_shortretry;
+       u8      ts_longretry;
+       u8      ts_virtcol;
+       u8      ts_antenna;
+};
+
+#define AR5K_TXSTAT_ALTRATE    0x80
+#define AR5K_TXERR_XRETRY      0x01
+#define AR5K_TXERR_FILT                0x02
+#define AR5K_TXERR_FIFO                0x04
+
+/**
+ * enum ath5k_tx_queue - Queue types used to classify tx queues.
+ * @AR5K_TX_QUEUE_INACTIVE: q is unused -- see ath5k_hw_release_tx_queue
+ * @AR5K_TX_QUEUE_DATA: A normal data queue
+ * @AR5K_TX_QUEUE_XR_DATA: An XR-data queue
+ * @AR5K_TX_QUEUE_BEACON: The beacon queue
+ * @AR5K_TX_QUEUE_CAB: The after-beacon queue
+ * @AR5K_TX_QUEUE_UAPSD: Unscheduled Automatic Power Save Delivery queue
+ */
+enum ath5k_tx_queue {
+       AR5K_TX_QUEUE_INACTIVE = 0,
+       AR5K_TX_QUEUE_DATA,
+       AR5K_TX_QUEUE_XR_DATA,
+       AR5K_TX_QUEUE_BEACON,
+       AR5K_TX_QUEUE_CAB,
+       AR5K_TX_QUEUE_UAPSD,
+};
+
+#define        AR5K_NUM_TX_QUEUES              10
+#define        AR5K_NUM_TX_QUEUES_NOQCU        2
+
+/*
+ * Queue syb-types to classify normal data queues.
+ * These are the 4 Access Categories as defined in
+ * WME spec. 0 is the lowest priority and 4 is the
+ * highest. Normal data that hasn't been classified
+ * goes to the Best Effort AC.
+ */
+enum ath5k_tx_queue_subtype {
+       AR5K_WME_AC_BK = 0,     /*Background traffic*/
+       AR5K_WME_AC_BE,         /*Best-effort (normal) traffic)*/
+       AR5K_WME_AC_VI,         /*Video traffic*/
+       AR5K_WME_AC_VO,         /*Voice traffic*/
+};
+
+/*
+ * Queue ID numbers as returned by the hw functions, each number
+ * represents a hw queue. If hw does not support hw queues
+ * (eg 5210) all data goes in one queue. These match
+ * d80211 definitions (net80211/MadWiFi don't use them).
+ */
+enum ath5k_tx_queue_id {
+       AR5K_TX_QUEUE_ID_NOQCU_DATA     = 0,
+       AR5K_TX_QUEUE_ID_NOQCU_BEACON   = 1,
+       AR5K_TX_QUEUE_ID_DATA_MIN       = 0, /*IEEE80211_TX_QUEUE_DATA0*/
+       AR5K_TX_QUEUE_ID_DATA_MAX       = 4, /*IEEE80211_TX_QUEUE_DATA4*/
+       AR5K_TX_QUEUE_ID_DATA_SVP       = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/
+       AR5K_TX_QUEUE_ID_CAB            = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/
+       AR5K_TX_QUEUE_ID_BEACON         = 7, /*IEEE80211_TX_QUEUE_BEACON*/
+       AR5K_TX_QUEUE_ID_UAPSD          = 8,
+       AR5K_TX_QUEUE_ID_XR_DATA        = 9,
+};
+
+/*
+ * Flags to set hw queue's parameters...
+ */
+#define AR5K_TXQ_FLAG_TXOKINT_ENABLE           0x0001  /* Enable TXOK interrupt */
+#define AR5K_TXQ_FLAG_TXERRINT_ENABLE          0x0002  /* Enable TXERR interrupt */
+#define AR5K_TXQ_FLAG_TXEOLINT_ENABLE          0x0004  /* Enable TXEOL interrupt -not used- */
+#define AR5K_TXQ_FLAG_TXDESCINT_ENABLE         0x0008  /* Enable TXDESC interrupt -not used- */
+#define AR5K_TXQ_FLAG_TXURNINT_ENABLE          0x0010  /* Enable TXURN interrupt */
+#define AR5K_TXQ_FLAG_CBRORNINT_ENABLE         0x0020  /* Enable CBRORN interrupt */
+#define AR5K_TXQ_FLAG_CBRURNINT_ENABLE         0x0040  /* Enable CBRURN interrupt */
+#define AR5K_TXQ_FLAG_QTRIGINT_ENABLE          0x0080  /* Enable QTRIG interrupt */
+#define AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE                0x0100  /* Enable TXNOFRM interrupt */
+#define AR5K_TXQ_FLAG_BACKOFF_DISABLE          0x0200  /* Disable random post-backoff */
+#define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE        0x0300  /* Enable ready time expiry policy (?)*/
+#define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE        0x0800  /* Enable backoff while bursting */
+#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS                0x1000  /* Disable backoff while bursting */
+#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE       0x2000  /* Enable hw compression -not implemented-*/
+
+/*
+ * A struct to hold tx queue's parameters
+ */
+struct ath5k_txq_info {
+       enum ath5k_tx_queue tqi_type;
+       enum ath5k_tx_queue_subtype tqi_subtype;
+       u16     tqi_flags;      /* Tx queue flags (see above) */
+       u32     tqi_aifs;       /* Arbitrated Interframe Space */
+       s32     tqi_cw_min;     /* Minimum Contention Window */
+       s32     tqi_cw_max;     /* Maximum Contention Window */
+       u32     tqi_cbr_period; /* Constant bit rate period */
+       u32     tqi_cbr_overflow_limit;
+       u32     tqi_burst_time;
+       u32     tqi_ready_time; /* Not used */
+};
+
+/*
+ * Transmit packet types.
+ * used on tx control descriptor
+ * TODO: Use them inside base.c corectly
+ */
+enum ath5k_pkt_type {
+       AR5K_PKT_TYPE_NORMAL            = 0,
+       AR5K_PKT_TYPE_ATIM              = 1,
+       AR5K_PKT_TYPE_PSPOLL            = 2,
+       AR5K_PKT_TYPE_BEACON            = 3,
+       AR5K_PKT_TYPE_PROBE_RESP        = 4,
+       AR5K_PKT_TYPE_PIFS              = 5,
+};
+
+/*
+ * TX power and TPC settings
+ */
+#define AR5K_TXPOWER_OFDM(_r, _v)      (                       \
+       ((0 & 1) << ((_v) + 6)) |                               \
+       (((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v)) \
+)
+
+#define AR5K_TXPOWER_CCK(_r, _v)       (                       \
+       (ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v)     \
+)
+
+/*
+ * DMA size definitions (2^n+2)
+ */
+enum ath5k_dmasize {
+       AR5K_DMASIZE_4B = 0,
+       AR5K_DMASIZE_8B,
+       AR5K_DMASIZE_16B,
+       AR5K_DMASIZE_32B,
+       AR5K_DMASIZE_64B,
+       AR5K_DMASIZE_128B,
+       AR5K_DMASIZE_256B,
+       AR5K_DMASIZE_512B
+};
+
+
+/****************\
+  RX DEFINITIONS
+\****************/
+
+/*
+ * RX Status descriptor
+ */
+struct ath5k_rx_status {
+       u16     rs_datalen;
+       u16     rs_tstamp;
+       u8      rs_status;
+       u8      rs_phyerr;
+       s8      rs_rssi;
+       u8      rs_keyix;
+       u8      rs_rate;
+       u8      rs_antenna;
+       u8      rs_more;
+};
+
+#define AR5K_RXERR_CRC         0x01
+#define AR5K_RXERR_PHY         0x02
+#define AR5K_RXERR_FIFO                0x04
+#define AR5K_RXERR_DECRYPT     0x08
+#define AR5K_RXERR_MIC         0x10
+#define AR5K_RXKEYIX_INVALID   ((u8) - 1)
+#define AR5K_TXKEYIX_INVALID   ((u32) - 1)
+
+
+/**************************\
+ BEACON TIMERS DEFINITIONS
+\**************************/
+
+#define AR5K_BEACON_PERIOD     0x0000ffff
+#define AR5K_BEACON_ENA                0x00800000 /*enable beacon xmit*/
+#define AR5K_BEACON_RESET_TSF  0x01000000 /*force a TSF reset*/
+
+#if 0
+/**
+ * struct ath5k_beacon_state - Per-station beacon timer state.
+ * @bs_interval: in TU's, can also include the above flags
+ * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a
+ *     Point Coordination Function capable AP
+ */
+struct ath5k_beacon_state {
+       u32     bs_next_beacon;
+       u32     bs_next_dtim;
+       u32     bs_interval;
+       u8      bs_dtim_period;
+       u8      bs_cfp_period;
+       u16     bs_cfp_max_duration;
+       u16     bs_cfp_du_remain;
+       u16     bs_tim_offset;
+       u16     bs_sleep_duration;
+       u16     bs_bmiss_threshold;
+       u32     bs_cfp_next;
+};
+#endif
+
+
+/*
+ * TSF to TU conversion:
+ *
+ * TSF is a 64bit value in usec (microseconds).
+ * TU is a 32bit value and defined by IEEE802.11 (page 6) as "A measurement of
+ * time equal to 1024 usec", so it's roughly milliseconds (usec / 1024).
+ */
+#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10)
+
+
+/*******************************\
+  GAIN OPTIMIZATION DEFINITIONS
+\*******************************/
+
+enum ath5k_rfgain {
+       AR5K_RFGAIN_INACTIVE = 0,
+       AR5K_RFGAIN_ACTIVE,
+       AR5K_RFGAIN_READ_REQUESTED,
+       AR5K_RFGAIN_NEED_CHANGE,
+};
+
+struct ath5k_gain {
+       u8                      g_step_idx;
+       u8                      g_current;
+       u8                      g_target;
+       u8                      g_low;
+       u8                      g_high;
+       u8                      g_f_corr;
+       u8                      g_state;
+};
+
+/********************\
+  COMMON DEFINITIONS
+\********************/
+
+#define AR5K_SLOT_TIME_9       396
+#define AR5K_SLOT_TIME_20      880
+#define AR5K_SLOT_TIME_MAX     0xffff
+
+/* channel_flags */
+#define        CHANNEL_CW_INT  0x0008  /* Contention Window interference detected */
+#define        CHANNEL_TURBO   0x0010  /* Turbo Channel */
+#define        CHANNEL_CCK     0x0020  /* CCK channel */
+#define        CHANNEL_OFDM    0x0040  /* OFDM channel */
+#define        CHANNEL_2GHZ    0x0080  /* 2GHz channel. */
+#define        CHANNEL_5GHZ    0x0100  /* 5GHz channel */
+#define        CHANNEL_PASSIVE 0x0200  /* Only passive scan allowed */
+#define        CHANNEL_DYN     0x0400  /* Dynamic CCK-OFDM channel (for g operation) */
+#define        CHANNEL_XR      0x0800  /* XR channel */
+
+#define        CHANNEL_A       (CHANNEL_5GHZ|CHANNEL_OFDM)
+#define        CHANNEL_B       (CHANNEL_2GHZ|CHANNEL_CCK)
+#define        CHANNEL_G       (CHANNEL_2GHZ|CHANNEL_OFDM)
+#define        CHANNEL_T       (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
+#define        CHANNEL_TG      (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
+#define        CHANNEL_108A    CHANNEL_T
+#define        CHANNEL_108G    CHANNEL_TG
+#define        CHANNEL_X       (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
+
+#define        CHANNEL_ALL     (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \
+               CHANNEL_TURBO)
+
+#define        CHANNEL_ALL_NOTURBO     (CHANNEL_ALL & ~CHANNEL_TURBO)
+#define CHANNEL_MODES          CHANNEL_ALL
+
+/*
+ * Used internaly for reset_tx_queue).
+ * Also see struct struct ieee80211_channel.
+ */
+#define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0)
+#define IS_CHAN_B(_c)  ((_c.hw_value & CHANNEL_B) != 0)
+
+/*
+ * The following structure is used to map 2GHz channels to
+ * 5GHz Atheros channels.
+ * TODO: Clean up
+ */
+struct ath5k_athchan_2ghz {
+       u32     a2_flags;
+       u16     a2_athchan;
+};
+
+
+/******************\
+  RATE DEFINITIONS
+\******************/
+
+/**
+ * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32.
+ *
+ * The rate code is used to get the RX rate or set the TX rate on the
+ * hardware descriptors. It is also used for internal modulation control
+ * and settings.
+ *
+ * This is the hardware rate map we are aware of:
+ *
+ * rate_code   0x01    0x02    0x03    0x04    0x05    0x06    0x07    0x08
+ * rate_kbps   3000    1000    ?       ?       ?       2000    500     48000
+ *
+ * rate_code   0x09    0x0A    0x0B    0x0C    0x0D    0x0E    0x0F    0x10
+ * rate_kbps   24000   12000   6000    54000   36000   18000   9000    ?
+ *
+ * rate_code   17      18      19      20      21      22      23      24
+ * rate_kbps   ?       ?       ?       ?       ?       ?       ?       11000
+ *
+ * rate_code   25      26      27      28      29      30      31      32
+ * rate_kbps   5500    2000    1000    11000S  5500S   2000S   ?       ?
+ *
+ * "S" indicates CCK rates with short preamble.
+ *
+ * AR5211 has different rate codes for CCK (802.11B) rates. It only uses the
+ * lowest 4 bits, so they are the same as below with a 0xF mask.
+ * (0xB, 0xA, 0x9 and 0x8 for 1M, 2M, 5.5M and 11M).
+ * We handle this in ath5k_setup_bands().
+ */
+#define AR5K_MAX_RATES 32
+
+/* B */
+#define ATH5K_RATE_CODE_1M     0x1B
+#define ATH5K_RATE_CODE_2M     0x1A
+#define ATH5K_RATE_CODE_5_5M   0x19
+#define ATH5K_RATE_CODE_11M    0x18
+/* A and G */
+#define ATH5K_RATE_CODE_6M     0x0B
+#define ATH5K_RATE_CODE_9M     0x0F
+#define ATH5K_RATE_CODE_12M    0x0A
+#define ATH5K_RATE_CODE_18M    0x0E
+#define ATH5K_RATE_CODE_24M    0x09
+#define ATH5K_RATE_CODE_36M    0x0D
+#define ATH5K_RATE_CODE_48M    0x08
+#define ATH5K_RATE_CODE_54M    0x0C
+/* XR */
+#define ATH5K_RATE_CODE_XR_500K        0x07
+#define ATH5K_RATE_CODE_XR_1M  0x02
+#define ATH5K_RATE_CODE_XR_2M  0x06
+#define ATH5K_RATE_CODE_XR_3M  0x01
+
+/* adding this flag to rate_code enables short preamble */
+#define AR5K_SET_SHORT_PREAMBLE 0x04
+
+/*
+ * Crypto definitions
+ */
+
+#define AR5K_KEYCACHE_SIZE     8
+
+/***********************\
+ HW RELATED DEFINITIONS
+\***********************/
+
+/*
+ * Misc definitions
+ */
+#define        AR5K_RSSI_EP_MULTIPLIER (1<<7)
+
+#define AR5K_ASSERT_ENTRY(_e, _s) do {         \
+       if (_e >= _s)                           \
+               return (false);                 \
+} while (0)
+
+/*
+ * Hardware interrupt abstraction
+ */
+
+/**
+ * enum ath5k_int - Hardware interrupt masks helpers
+ *
+ * @AR5K_INT_RX: mask to identify received frame interrupts, of type
+ *     AR5K_ISR_RXOK or AR5K_ISR_RXERR
+ * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor (?)
+ * @AR5K_INT_RXNOFRM: No frame received (?)
+ * @AR5K_INT_RXEOL: received End Of List for VEOL (Virtual End Of List). The
+ *     Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's
+ *     LinkPtr is NULL. For more details, refer to:
+ *     http://www.freepatentsonline.com/20030225739.html
+ * @AR5K_INT_RXORN: Indicates we got RX overrun (eg. no more descriptors).
+ *     Note that Rx overrun is not always fatal, on some chips we can continue
+ *     operation without reseting the card, that's why int_fatal is not
+ *     common for all chips.
+ * @AR5K_INT_TX: mask to identify received frame interrupts, of type
+ *     AR5K_ISR_TXOK or AR5K_ISR_TXERR
+ * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor (?)
+ * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
+ *     We currently do increments on interrupt by
+ *     (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
+ * @AR5K_INT_MIB: Indicates the Management Information Base counters should be
+ *     checked. We should do this with ath5k_hw_update_mib_counters() but
+ *     it seems we should also then do some noise immunity work.
+ * @AR5K_INT_RXPHY: RX PHY Error
+ * @AR5K_INT_RXKCM: RX Key cache miss
+ * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
+ *     beacon that must be handled in software. The alternative is if you
+ *     have VEOL support, in that case you let the hardware deal with things.
+ * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing
+ *     beacons from the AP have associated with, we should probably try to
+ *     reassociate. When in IBSS mode this might mean we have not received
+ *     any beacons from any local stations. Note that every station in an
+ *     IBSS schedules to send beacons at the Target Beacon Transmission Time
+ *     (TBTT) with a random backoff.
+ * @AR5K_INT_BNR: Beacon Not Ready interrupt - ??
+ * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill, disabled for now
+ *     until properly handled
+ * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA
+ *     errors. These types of errors we can enable seem to be of type
+ *     AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR.
+ * @AR5K_INT_GLOBAL: Used to clear and set the IER
+ * @AR5K_INT_NOCARD: signals the card has been removed
+ * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same
+ *     bit value
+ *
+ * These are mapped to take advantage of some common bits
+ * between the MACs, to be able to set intr properties
+ * easier. Some of them are not used yet inside hw.c. Most map
+ * to the respective hw interrupt value as they are common amogst different
+ * MACs.
+ */
+enum ath5k_int {
+       AR5K_INT_RXOK   = 0x00000001,
+       AR5K_INT_RXDESC = 0x00000002,
+       AR5K_INT_RXERR  = 0x00000004,
+       AR5K_INT_RXNOFRM = 0x00000008,
+       AR5K_INT_RXEOL  = 0x00000010,
+       AR5K_INT_RXORN  = 0x00000020,
+       AR5K_INT_TXOK   = 0x00000040,
+       AR5K_INT_TXDESC = 0x00000080,
+       AR5K_INT_TXERR  = 0x00000100,
+       AR5K_INT_TXNOFRM = 0x00000200,
+       AR5K_INT_TXEOL  = 0x00000400,
+       AR5K_INT_TXURN  = 0x00000800,
+       AR5K_INT_MIB    = 0x00001000,
+       AR5K_INT_SWI    = 0x00002000,
+       AR5K_INT_RXPHY  = 0x00004000,
+       AR5K_INT_RXKCM  = 0x00008000,
+       AR5K_INT_SWBA   = 0x00010000,
+       AR5K_INT_BRSSI  = 0x00020000,
+       AR5K_INT_BMISS  = 0x00040000,
+       AR5K_INT_FATAL  = 0x00080000, /* Non common */
+       AR5K_INT_BNR    = 0x00100000, /* Non common */
+       AR5K_INT_TIM    = 0x00200000, /* Non common */
+       AR5K_INT_DTIM   = 0x00400000, /* Non common */
+       AR5K_INT_DTIM_SYNC =    0x00800000, /* Non common */
+       AR5K_INT_GPIO   =       0x01000000,
+       AR5K_INT_BCN_TIMEOUT =  0x02000000, /* Non common */
+       AR5K_INT_CAB_TIMEOUT =  0x04000000, /* Non common */
+       AR5K_INT_RX_DOPPLER =   0x08000000, /* Non common */
+       AR5K_INT_QCBRORN =      0x10000000, /* Non common */
+       AR5K_INT_QCBRURN =      0x20000000, /* Non common */
+       AR5K_INT_QTRIG  =       0x40000000, /* Non common */
+       AR5K_INT_GLOBAL =       0x80000000,
+
+       AR5K_INT_COMMON  = AR5K_INT_RXOK
+               | AR5K_INT_RXDESC
+               | AR5K_INT_RXERR
+               | AR5K_INT_RXNOFRM
+               | AR5K_INT_RXEOL
+               | AR5K_INT_RXORN
+               | AR5K_INT_TXOK
+               | AR5K_INT_TXDESC
+               | AR5K_INT_TXERR
+               | AR5K_INT_TXNOFRM
+               | AR5K_INT_TXEOL
+               | AR5K_INT_TXURN
+               | AR5K_INT_MIB
+               | AR5K_INT_SWI
+               | AR5K_INT_RXPHY
+               | AR5K_INT_RXKCM
+               | AR5K_INT_SWBA
+               | AR5K_INT_BRSSI
+               | AR5K_INT_BMISS
+               | AR5K_INT_GPIO
+               | AR5K_INT_GLOBAL,
+
+       AR5K_INT_NOCARD = 0xffffffff
+};
+
+/*
+ * Power management
+ */
+enum ath5k_power_mode {
+       AR5K_PM_UNDEFINED = 0,
+       AR5K_PM_AUTO,
+       AR5K_PM_AWAKE,
+       AR5K_PM_FULL_SLEEP,
+       AR5K_PM_NETWORK_SLEEP,
+};
+
+/*
+ * These match net80211 definitions (not used in
+ * mac80211).
+ * TODO: Clean this up
+ */
+#define AR5K_LED_INIT  0 /*IEEE80211_S_INIT*/
+#define AR5K_LED_SCAN  1 /*IEEE80211_S_SCAN*/
+#define AR5K_LED_AUTH  2 /*IEEE80211_S_AUTH*/
+#define AR5K_LED_ASSOC 3 /*IEEE80211_S_ASSOC*/
+#define AR5K_LED_RUN   4 /*IEEE80211_S_RUN*/
+
+/* GPIO-controlled software LED */
+#define AR5K_SOFTLED_PIN       0
+#define AR5K_SOFTLED_ON                0
+#define AR5K_SOFTLED_OFF       1
+
+/*
+ * Chipset capabilities -see ath5k_hw_get_capability-
+ * get_capability function is not yet fully implemented
+ * in ath5k so most of these don't work yet...
+ * TODO: Implement these & merge with _TUNE_ stuff above
+ */
+enum ath5k_capability_type {
+       AR5K_CAP_REG_DMN                = 0,    /* Used to get current reg. domain id */
+       AR5K_CAP_TKIP_MIC               = 2,    /* Can handle TKIP MIC in hardware */
+       AR5K_CAP_TKIP_SPLIT             = 3,    /* TKIP uses split keys */
+       AR5K_CAP_PHYCOUNTERS            = 4,    /* PHY error counters */
+       AR5K_CAP_DIVERSITY              = 5,    /* Supports fast diversity */
+       AR5K_CAP_NUM_TXQUEUES           = 6,    /* Used to get max number of hw txqueues */
+       AR5K_CAP_VEOL                   = 7,    /* Supports virtual EOL */
+       AR5K_CAP_COMPRESSION            = 8,    /* Supports compression */
+       AR5K_CAP_BURST                  = 9,    /* Supports packet bursting */
+       AR5K_CAP_FASTFRAME              = 10,   /* Supports fast frames */
+       AR5K_CAP_TXPOW                  = 11,   /* Used to get global tx power limit */
+       AR5K_CAP_TPC                    = 12,   /* Can do per-packet tx power control (needed for 802.11a) */
+       AR5K_CAP_BSSIDMASK              = 13,   /* Supports bssid mask */
+       AR5K_CAP_MCAST_KEYSRCH          = 14,   /* Supports multicast key search */
+       AR5K_CAP_TSF_ADJUST             = 15,   /* Supports beacon tsf adjust */
+       AR5K_CAP_XR                     = 16,   /* Supports XR mode */
+       AR5K_CAP_WME_TKIPMIC            = 17,   /* Supports TKIP MIC when using WMM */
+       AR5K_CAP_CHAN_HALFRATE          = 18,   /* Supports half rate channels */
+       AR5K_CAP_CHAN_QUARTERRATE       = 19,   /* Supports quarter rate channels */
+       AR5K_CAP_RFSILENT               = 20,   /* Supports RFsilent */
+};
+
+
+/* XXX: we *may* move cap_range stuff to struct wiphy */
+struct ath5k_capabilities {
+       /*
+        * Supported PHY modes
+        * (ie. CHANNEL_A, CHANNEL_B, ...)
+        */
+       DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX);
+
+       /*
+        * Frequency range (without regulation restrictions)
+        */
+       struct {
+               u16     range_2ghz_min;
+               u16     range_2ghz_max;
+               u16     range_5ghz_min;
+               u16     range_5ghz_max;
+       } cap_range;
+
+       /*
+        * Values stored in the EEPROM (some of them...)
+        */
+       struct ath5k_eeprom_info        cap_eeprom;
+
+       /*
+        * Queue information
+        */
+       struct {
+               u8      q_tx_num;
+       } cap_queues;
+};
+
+
+/***************************************\
+  HARDWARE ABSTRACTION LAYER STRUCTURE
+\***************************************/
+
+/*
+ * Misc defines
+ */
+
+#define AR5K_MAX_GPIO          10
+#define AR5K_MAX_RF_BANKS      8
+
+/* TODO: Clean up and merge with ath5k_softc */
+struct ath5k_hw {
+       u32                     ah_magic;
+
+       struct ath5k_softc      *ah_sc;
+       void __iomem            *ah_iobase;
+
+       enum ath5k_int          ah_imr;
+
+       enum nl80211_iftype     ah_op_mode;
+       enum ath5k_power_mode   ah_power_mode;
+       struct ieee80211_channel ah_current_channel;
+       bool                    ah_turbo;
+       bool                    ah_calibration;
+       bool                    ah_running;
+       bool                    ah_single_chip;
+       bool                    ah_combined_mic;
+
+       u32                     ah_mac_srev;
+       u16                     ah_mac_version;
+       u16                     ah_mac_revision;
+       u16                     ah_phy_revision;
+       u16                     ah_radio_5ghz_revision;
+       u16                     ah_radio_2ghz_revision;
+
+       enum ath5k_version      ah_version;
+       enum ath5k_radio        ah_radio;
+       u32                     ah_phy;
+
+       bool                    ah_5ghz;
+       bool                    ah_2ghz;
+
+#define ah_modes               ah_capabilities.cap_mode
+#define ah_ee_version          ah_capabilities.cap_eeprom.ee_version
+
+       u32                     ah_atim_window;
+       u32                     ah_aifs;
+       u32                     ah_cw_min;
+       u32                     ah_cw_max;
+       bool                    ah_software_retry;
+       u32                     ah_limit_tx_retries;
+
+       u32                     ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
+       bool                    ah_ant_diversity;
+
+       u8                      ah_sta_id[ETH_ALEN];
+
+       /* Current BSSID we are trying to assoc to / create.
+        * This is passed by mac80211 on config_interface() and cached here for
+        * use in resets */
+       u8                      ah_bssid[ETH_ALEN];
+       u8                      ah_bssid_mask[ETH_ALEN];
+
+       u32                     ah_gpio[AR5K_MAX_GPIO];
+       int                     ah_gpio_npins;
+
+       struct ath_regulatory   ah_regulatory;
+       struct ath5k_capabilities ah_capabilities;
+
+       struct ath5k_txq_info   ah_txq[AR5K_NUM_TX_QUEUES];
+       u32                     ah_txq_status;
+       u32                     ah_txq_imr_txok;
+       u32                     ah_txq_imr_txerr;
+       u32                     ah_txq_imr_txurn;
+       u32                     ah_txq_imr_txdesc;
+       u32                     ah_txq_imr_txeol;
+       u32                     ah_txq_imr_cbrorn;
+       u32                     ah_txq_imr_cbrurn;
+       u32                     ah_txq_imr_qtrig;
+       u32                     ah_txq_imr_nofrm;
+       u32                     ah_txq_isr;
+       u32                     *ah_rf_banks;
+       size_t                  ah_rf_banks_size;
+       size_t                  ah_rf_regs_count;
+       struct ath5k_gain       ah_gain;
+       u8                      ah_offset[AR5K_MAX_RF_BANKS];
+
+
+       struct {
+               /* Temporary tables used for interpolation */
+               u8              tmpL[AR5K_EEPROM_N_PD_GAINS]
+                                       [AR5K_EEPROM_POWER_TABLE_SIZE];
+               u8              tmpR[AR5K_EEPROM_N_PD_GAINS]
+                                       [AR5K_EEPROM_POWER_TABLE_SIZE];
+               u8              txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2];
+               u16             txp_rates_power_table[AR5K_MAX_RATES];
+               u8              txp_min_idx;
+               bool            txp_tpc;
+               /* Values in 0.25dB units */
+               s16             txp_min_pwr;
+               s16             txp_max_pwr;
+               s16             txp_offset;
+               s16             txp_ofdm;
+               /* Values in dB units */
+               s16             txp_cck_ofdm_pwr_delta;
+               s16             txp_cck_ofdm_gainf_delta;
+       } ah_txpower;
+
+       struct {
+               bool            r_enabled;
+               int             r_last_alert;
+               struct ieee80211_channel r_last_channel;
+       } ah_radar;
+
+       /* noise floor from last periodic calibration */
+       s32                     ah_noise_floor;
+
+       /*
+        * Function pointers
+        */
+       int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc,
+                               u32 size, unsigned int flags);
+       int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
+               unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
+               unsigned int, unsigned int, unsigned int, unsigned int,
+               unsigned int, unsigned int, unsigned int);
+       int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
+               unsigned int, unsigned int, unsigned int, unsigned int,
+               unsigned int, unsigned int);
+       int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
+               struct ath5k_tx_status *);
+       int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *,
+               struct ath5k_rx_status *);
+};
+
+/*
+ * Prototypes
+ */
+
+/* Attach/Detach Functions */
+extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
+extern void ath5k_hw_detach(struct ath5k_hw *ah);
+
+/* LED functions */
+extern int ath5k_init_leds(struct ath5k_softc *sc);
+extern void ath5k_led_enable(struct ath5k_softc *sc);
+extern void ath5k_led_off(struct ath5k_softc *sc);
+extern void ath5k_unregister_leds(struct ath5k_softc *sc);
+
+/* Reset Functions */
+extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
+extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
+/* Power management functions */
+extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
+
+/* DMA Related Functions */
+extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
+extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
+extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
+extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
+extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
+extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
+extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
+extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
+                               u32 phys_addr);
+extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
+/* Interrupt handling */
+extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
+extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
+extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum
+ath5k_int new_mask);
+extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats);
+
+/* EEPROM access functions */
+extern int ath5k_eeprom_init(struct ath5k_hw *ah);
+extern void ath5k_eeprom_detach(struct ath5k_hw *ah);
+extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
+extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
+
+/* Protocol Control Unit Functions */
+extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
+/* BSSID Functions */
+extern void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac);
+extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
+extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id);
+extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
+/* Receive start/stop functions */
+extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
+extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
+/* RX Filter functions */
+extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
+extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
+extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
+extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
+extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
+/* Beacon control functions */
+extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
+extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
+extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
+extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
+extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
+#if 0
+extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state);
+extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
+extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
+#endif
+/* ACK bit rate */
+void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
+/* ACK/CTS Timeouts */
+extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
+extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
+extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
+extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
+/* Key table (WEP) functions */
+extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
+extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
+extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac);
+extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
+
+/* Queue Control Unit, DFS Control Unit Functions */
+extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info);
+extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
+                               const struct ath5k_txq_info *queue_info);
+extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
+                               enum ath5k_tx_queue queue_type,
+                               struct ath5k_txq_info *queue_info);
+extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
+extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
+extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
+extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah);
+extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
+
+/* Hardware Descriptor Functions */
+extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
+
+/* GPIO Functions */
+extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
+extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
+extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
+extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
+extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
+extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
+
+/* Misc functions */
+int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
+extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
+extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
+extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
+
+/* Initial register settings functions */
+extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
+
+/* Initialize RF */
+extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channel,
+                               unsigned int mode);
+extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
+extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
+extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
+/* PHY/RF channel functions */
+extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
+extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
+/* PHY calibration */
+extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
+extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
+/* Misc PHY functions */
+extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
+extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
+extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
+extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
+/* TX power setup */
+extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
+extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower);
+
+/*
+ * Functions used internaly
+ */
+
+/*
+ * Translate usec to hw clock units
+ * TODO: Half/quarter rate
+ */
+static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
+{
+       return turbo ? (usec * 80) : (usec * 40);
+}
+
+/*
+ * Translate hw clock units to usec
+ * TODO: Half/quarter rate
+ */
+static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
+{
+       return turbo ? (clock / 80) : (clock / 40);
+}
+
+/*
+ * Read from a register
+ */
+static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
+{
+       return ioread32(ah->ah_iobase + reg);
+}
+
+/*
+ * Write to a register
+ */
+static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
+{
+       iowrite32(val, ah->ah_iobase + reg);
+}
+
+#if defined(_ATH5K_RESET) || defined(_ATH5K_PHY)
+/*
+ * Check if a register write has been completed
+ */
+static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag,
+               u32 val, bool is_set)
+{
+       int i;
+       u32 data;
+
+       for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
+               data = ath5k_hw_reg_read(ah, reg);
+               if (is_set && (data & flag))
+                       break;
+               else if ((data & flag) == val)
+                       break;
+               udelay(15);
+       }
+
+       return (i <= 0) ? -EAGAIN : 0;
+}
+#endif
+
+static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
+{
+       u32 retval = 0, bit, i;
+
+       for (i = 0; i < bits; i++) {
+               bit = (val >> i) & 1;
+               retval = (retval << 1) | bit;
+       }
+
+       return retval;
+}
+
+static inline int ath5k_pad_size(int hdrlen)
+{
+       return (hdrlen < 24) ? 0 : hdrlen & 3;
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
new file mode 100644 (file)
index 0000000..70d376c
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*************************************\
+* Attach/Detach Functions and helpers *
+\*************************************/
+
+#include <linux/pci.h>
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/**
+ * ath5k_hw_post - Power On Self Test helper function
+ *
+ * @ah: The &struct ath5k_hw
+ */
+static int ath5k_hw_post(struct ath5k_hw *ah)
+{
+
+       static const u32 static_pattern[4] = {
+               0x55555555,     0xaaaaaaaa,
+               0x66666666,     0x99999999
+       };
+       static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
+       int i, c;
+       u16 cur_reg;
+       u32 var_pattern;
+       u32 init_val;
+       u32 cur_val;
+
+       for (c = 0; c < 2; c++) {
+
+               cur_reg = regs[c];
+
+               /* Save previous value */
+               init_val = ath5k_hw_reg_read(ah, cur_reg);
+
+               for (i = 0; i < 256; i++) {
+                       var_pattern = i << 16 | i;
+                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
+                       cur_val = ath5k_hw_reg_read(ah, cur_reg);
+
+                       if (cur_val != var_pattern) {
+                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
+                               return -EAGAIN;
+                       }
+
+                       /* Found on ndiswrapper dumps */
+                       var_pattern = 0x0039080f;
+                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
+               }
+
+               for (i = 0; i < 4; i++) {
+                       var_pattern = static_pattern[i];
+                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
+                       cur_val = ath5k_hw_reg_read(ah, cur_reg);
+
+                       if (cur_val != var_pattern) {
+                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
+                               return -EAGAIN;
+                       }
+
+                       /* Found on ndiswrapper dumps */
+                       var_pattern = 0x003b080f;
+                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
+               }
+
+               /* Restore previous value */
+               ath5k_hw_reg_write(ah, init_val, cur_reg);
+
+       }
+
+       return 0;
+
+}
+
+/**
+ * ath5k_hw_attach - Check if hw is supported and init the needed structs
+ *
+ * @sc: The &struct ath5k_softc we got from the driver's attach function
+ * @mac_version: The mac version id (check out ath5k.h) based on pci id
+ *
+ * Check if the device is supported, perform a POST and initialize the needed
+ * structs. Returns -ENOMEM if we don't have memory for the needed structs,
+ * -ENODEV if the device is not supported or prints an error msg if something
+ * else went wrong.
+ */
+struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
+{
+       struct ath5k_hw *ah;
+       struct pci_dev *pdev = sc->pdev;
+       int ret;
+       u32 srev;
+
+       /*If we passed the test malloc a ath5k_hw struct*/
+       ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
+       if (ah == NULL) {
+               ret = -ENOMEM;
+               ATH5K_ERR(sc, "out of memory\n");
+               goto err;
+       }
+
+       ah->ah_sc = sc;
+       ah->ah_iobase = sc->iobase;
+
+       /*
+        * HW information
+        */
+       ah->ah_op_mode = NL80211_IFTYPE_STATION;
+       ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
+       ah->ah_turbo = false;
+       ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
+       ah->ah_imr = 0;
+       ah->ah_atim_window = 0;
+       ah->ah_aifs = AR5K_TUNE_AIFS;
+       ah->ah_cw_min = AR5K_TUNE_CWMIN;
+       ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
+       ah->ah_software_retry = false;
+       ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
+
+       /*
+        * Set the mac version based on the pci id
+        */
+       ah->ah_version = mac_version;
+
+       /*Fill the ath5k_hw struct with the needed functions*/
+       ret = ath5k_hw_init_desc_functions(ah);
+       if (ret)
+               goto err_free;
+
+       /* Bring device out of sleep and reset it's units */
+       ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
+       if (ret)
+               goto err_free;
+
+       /* Get MAC, PHY and RADIO revisions */
+       srev = ath5k_hw_reg_read(ah, AR5K_SREV);
+       ah->ah_mac_srev = srev;
+       ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
+       ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
+       ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
+                       0xffffffff;
+       ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
+                       CHANNEL_5GHZ);
+       ah->ah_phy = AR5K_PHY(0);
+
+       /* Try to identify radio chip based on it's srev */
+       switch (ah->ah_radio_5ghz_revision & 0xf0) {
+       case AR5K_SREV_RAD_5111:
+               ah->ah_radio = AR5K_RF5111;
+               ah->ah_single_chip = false;
+               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
+                                                       CHANNEL_2GHZ);
+               break;
+       case AR5K_SREV_RAD_5112:
+       case AR5K_SREV_RAD_2112:
+               ah->ah_radio = AR5K_RF5112;
+               ah->ah_single_chip = false;
+               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
+                                                       CHANNEL_2GHZ);
+               break;
+       case AR5K_SREV_RAD_2413:
+               ah->ah_radio = AR5K_RF2413;
+               ah->ah_single_chip = true;
+               break;
+       case AR5K_SREV_RAD_5413:
+               ah->ah_radio = AR5K_RF5413;
+               ah->ah_single_chip = true;
+               break;
+       case AR5K_SREV_RAD_2316:
+               ah->ah_radio = AR5K_RF2316;
+               ah->ah_single_chip = true;
+               break;
+       case AR5K_SREV_RAD_2317:
+               ah->ah_radio = AR5K_RF2317;
+               ah->ah_single_chip = true;
+               break;
+       case AR5K_SREV_RAD_5424:
+               if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
+               ah->ah_mac_version == AR5K_SREV_AR2417){
+                       ah->ah_radio = AR5K_RF2425;
+                       ah->ah_single_chip = true;
+               } else {
+                       ah->ah_radio = AR5K_RF5413;
+                       ah->ah_single_chip = true;
+               }
+               break;
+       default:
+               /* Identify radio based on mac/phy srev */
+               if (ah->ah_version == AR5K_AR5210) {
+                       ah->ah_radio = AR5K_RF5110;
+                       ah->ah_single_chip = false;
+               } else if (ah->ah_version == AR5K_AR5211) {
+                       ah->ah_radio = AR5K_RF5111;
+                       ah->ah_single_chip = false;
+                       ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
+                                                               CHANNEL_2GHZ);
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
+               ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
+               ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
+                       ah->ah_radio = AR5K_RF2425;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
+               } else if (srev == AR5K_SREV_AR5213A &&
+               ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
+                       ah->ah_radio = AR5K_RF5112;
+                       ah->ah_single_chip = false;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
+                       ah->ah_radio = AR5K_RF2316;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
+               ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
+                       ah->ah_radio = AR5K_RF5413;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
+               ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
+                       ah->ah_radio = AR5K_RF2413;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
+               } else {
+                       ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
+                       ret = -ENODEV;
+                       goto err_free;
+               }
+       }
+
+
+       /* Return on unsuported chips (unsupported eeprom etc) */
+       if ((srev >= AR5K_SREV_AR5416) &&
+       (srev < AR5K_SREV_AR2425)) {
+               ATH5K_ERR(sc, "Device not yet supported.\n");
+               ret = -ENODEV;
+               goto err_free;
+       }
+
+       /*
+        * Write PCI-E power save settings
+        */
+       if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
+               ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
+               /* Shut off RX when elecidle is asserted */
+               ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
+               /* TODO: EEPROM work */
+               ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
+               /* Shut off PLL and CLKREQ active in L1 */
+               ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
+               /* Preserce other settings */
+               ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
+               /* Reset SERDES to load new settings */
+               ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
+               mdelay(1);
+       }
+
+       /*
+        * POST
+        */
+       ret = ath5k_hw_post(ah);
+       if (ret)
+               goto err_free;
+
+       /* Enable pci core retry fix on Hainan (5213A) and later chips */
+       if (srev >= AR5K_SREV_AR5213A)
+               ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG);
+
+       /*
+        * Get card capabilities, calibration values etc
+        * TODO: EEPROM work
+        */
+       ret = ath5k_eeprom_init(ah);
+       if (ret) {
+               ATH5K_ERR(sc, "unable to init EEPROM\n");
+               goto err_free;
+       }
+
+       /* Get misc capabilities */
+       ret = ath5k_hw_set_capabilities(ah);
+       if (ret) {
+               ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
+                       sc->pdev->device);
+               goto err_free;
+       }
+
+       if (srev >= AR5K_SREV_AR2414) {
+               ah->ah_combined_mic = true;
+               AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
+                       AR5K_MISC_MODE_COMBINED_MIC);
+       }
+
+       /* MAC address is cleared until add_interface */
+       ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
+
+       /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
+       memset(ah->ah_bssid, 0xff, ETH_ALEN);
+       ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+       ath5k_hw_set_opmode(ah);
+
+       ath5k_hw_rfgain_opt_init(ah);
+
+       return ah;
+err_free:
+       kfree(ah);
+err:
+       return ERR_PTR(ret);
+}
+
+/**
+ * ath5k_hw_detach - Free the ath5k_hw struct
+ *
+ * @ah: The &struct ath5k_hw
+ */
+void ath5k_hw_detach(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
+
+       if (ah->ah_rf_banks != NULL)
+               kfree(ah->ah_rf_banks);
+
+       ath5k_eeprom_detach(ah);
+
+       /* assume interrupts are down */
+       kfree(ah);
+}
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
new file mode 100644 (file)
index 0000000..ff6d4f8
--- /dev/null
@@ -0,0 +1,3110 @@
+/*-
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2006 Devicescape Software, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/hardirq.h>
+#include <linux/if.h>
+#include <linux/io.h>
+#include <linux/netdevice.h>
+#include <linux/cache.h>
+#include <linux/pci.h>
+#include <linux/ethtool.h>
+#include <linux/uaccess.h>
+
+#include <net/ieee80211_radiotap.h>
+
+#include <asm/unaligned.h>
+
+#include "base.h"
+#include "reg.h"
+#include "debug.h"
+
+static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+static int modparam_all_channels;
+module_param_named(all_channels, modparam_all_channels, int, 0444);
+MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
+
+
+/******************\
+* Internal defines *
+\******************/
+
+/* Module info */
+MODULE_AUTHOR("Jiri Slaby");
+MODULE_AUTHOR("Nick Kossifidis");
+MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
+MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
+
+
+/* Known PCI ids */
+static const struct pci_device_id ath5k_pci_id_table[] = {
+       { PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
+       { PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
+       { PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
+       { PCI_VDEVICE(ATHEROS, 0x0012), .driver_data = AR5K_AR5211 }, /* 5211 */
+       { PCI_VDEVICE(ATHEROS, 0x0013), .driver_data = AR5K_AR5212 }, /* 5212 */
+       { PCI_VDEVICE(3COM_2,  0x0013), .driver_data = AR5K_AR5212 }, /* 3com 5212 */
+       { PCI_VDEVICE(3COM,    0x0013), .driver_data = AR5K_AR5212 }, /* 3com 3CRDAG675 5212 */
+       { PCI_VDEVICE(ATHEROS, 0x1014), .driver_data = AR5K_AR5212 }, /* IBM minipci 5212 */
+       { PCI_VDEVICE(ATHEROS, 0x0014), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0015), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0016), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0017), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0018), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */
+       { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */
+       { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */
+       { PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
+
+/* Known SREVs */
+static const struct ath5k_srev_name srev_names[] = {
+       { "5210",       AR5K_VERSION_MAC,       AR5K_SREV_AR5210 },
+       { "5311",       AR5K_VERSION_MAC,       AR5K_SREV_AR5311 },
+       { "5311A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311A },
+       { "5311B",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311B },
+       { "5211",       AR5K_VERSION_MAC,       AR5K_SREV_AR5211 },
+       { "5212",       AR5K_VERSION_MAC,       AR5K_SREV_AR5212 },
+       { "5213",       AR5K_VERSION_MAC,       AR5K_SREV_AR5213 },
+       { "5213A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5213A },
+       { "2413",       AR5K_VERSION_MAC,       AR5K_SREV_AR2413 },
+       { "2414",       AR5K_VERSION_MAC,       AR5K_SREV_AR2414 },
+       { "5424",       AR5K_VERSION_MAC,       AR5K_SREV_AR5424 },
+       { "5413",       AR5K_VERSION_MAC,       AR5K_SREV_AR5413 },
+       { "5414",       AR5K_VERSION_MAC,       AR5K_SREV_AR5414 },
+       { "2415",       AR5K_VERSION_MAC,       AR5K_SREV_AR2415 },
+       { "5416",       AR5K_VERSION_MAC,       AR5K_SREV_AR5416 },
+       { "5418",       AR5K_VERSION_MAC,       AR5K_SREV_AR5418 },
+       { "2425",       AR5K_VERSION_MAC,       AR5K_SREV_AR2425 },
+       { "2417",       AR5K_VERSION_MAC,       AR5K_SREV_AR2417 },
+       { "xxxxx",      AR5K_VERSION_MAC,       AR5K_SREV_UNKNOWN },
+       { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
+       { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
+       { "5111A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111A },
+       { "2111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2111 },
+       { "5112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112 },
+       { "5112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112A },
+       { "5112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112B },
+       { "2112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112 },
+       { "2112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112A },
+       { "2112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112B },
+       { "2413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2413 },
+       { "5413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5413 },
+       { "2316",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2316 },
+       { "2317",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2317 },
+       { "5424",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5424 },
+       { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
+       { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
+};
+
+static const struct ieee80211_rate ath5k_rates[] = {
+       { .bitrate = 10,
+         .hw_value = ATH5K_RATE_CODE_1M, },
+       { .bitrate = 20,
+         .hw_value = ATH5K_RATE_CODE_2M,
+         .hw_value_short = ATH5K_RATE_CODE_2M | AR5K_SET_SHORT_PREAMBLE,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 55,
+         .hw_value = ATH5K_RATE_CODE_5_5M,
+         .hw_value_short = ATH5K_RATE_CODE_5_5M | AR5K_SET_SHORT_PREAMBLE,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 110,
+         .hw_value = ATH5K_RATE_CODE_11M,
+         .hw_value_short = ATH5K_RATE_CODE_11M | AR5K_SET_SHORT_PREAMBLE,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 60,
+         .hw_value = ATH5K_RATE_CODE_6M,
+         .flags = 0 },
+       { .bitrate = 90,
+         .hw_value = ATH5K_RATE_CODE_9M,
+         .flags = 0 },
+       { .bitrate = 120,
+         .hw_value = ATH5K_RATE_CODE_12M,
+         .flags = 0 },
+       { .bitrate = 180,
+         .hw_value = ATH5K_RATE_CODE_18M,
+         .flags = 0 },
+       { .bitrate = 240,
+         .hw_value = ATH5K_RATE_CODE_24M,
+         .flags = 0 },
+       { .bitrate = 360,
+         .hw_value = ATH5K_RATE_CODE_36M,
+         .flags = 0 },
+       { .bitrate = 480,
+         .hw_value = ATH5K_RATE_CODE_48M,
+         .flags = 0 },
+       { .bitrate = 540,
+         .hw_value = ATH5K_RATE_CODE_54M,
+         .flags = 0 },
+       /* XR missing */
+};
+
+/*
+ * Prototypes - PCI stack related functions
+ */
+static int __devinit   ath5k_pci_probe(struct pci_dev *pdev,
+                               const struct pci_device_id *id);
+static void __devexit  ath5k_pci_remove(struct pci_dev *pdev);
+#ifdef CONFIG_PM
+static int             ath5k_pci_suspend(struct pci_dev *pdev,
+                                       pm_message_t state);
+static int             ath5k_pci_resume(struct pci_dev *pdev);
+#else
+#define ath5k_pci_suspend NULL
+#define ath5k_pci_resume NULL
+#endif /* CONFIG_PM */
+
+static struct pci_driver ath5k_pci_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = ath5k_pci_id_table,
+       .probe          = ath5k_pci_probe,
+       .remove         = __devexit_p(ath5k_pci_remove),
+       .suspend        = ath5k_pci_suspend,
+       .resume         = ath5k_pci_resume,
+};
+
+
+
+/*
+ * Prototypes - MAC 802.11 stack related functions
+ */
+static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel);
+static int ath5k_reset_wake(struct ath5k_softc *sc);
+static int ath5k_start(struct ieee80211_hw *hw);
+static void ath5k_stop(struct ieee80211_hw *hw);
+static int ath5k_add_interface(struct ieee80211_hw *hw,
+               struct ieee80211_if_init_conf *conf);
+static void ath5k_remove_interface(struct ieee80211_hw *hw,
+               struct ieee80211_if_init_conf *conf);
+static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
+static int ath5k_config_interface(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif,
+               struct ieee80211_if_conf *conf);
+static void ath5k_configure_filter(struct ieee80211_hw *hw,
+               unsigned int changed_flags,
+               unsigned int *new_flags,
+               int mc_count, struct dev_mc_list *mclist);
+static int ath5k_set_key(struct ieee80211_hw *hw,
+               enum set_key_cmd cmd,
+               struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+               struct ieee80211_key_conf *key);
+static int ath5k_get_stats(struct ieee80211_hw *hw,
+               struct ieee80211_low_level_stats *stats);
+static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
+               struct ieee80211_tx_queue_stats *stats);
+static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
+static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
+static void ath5k_reset_tsf(struct ieee80211_hw *hw);
+static int ath5k_beacon_update(struct ath5k_softc *sc,
+               struct sk_buff *skb);
+static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif,
+               struct ieee80211_bss_conf *bss_conf,
+               u32 changes);
+
+static const struct ieee80211_ops ath5k_hw_ops = {
+       .tx             = ath5k_tx,
+       .start          = ath5k_start,
+       .stop           = ath5k_stop,
+       .add_interface  = ath5k_add_interface,
+       .remove_interface = ath5k_remove_interface,
+       .config         = ath5k_config,
+       .config_interface = ath5k_config_interface,
+       .configure_filter = ath5k_configure_filter,
+       .set_key        = ath5k_set_key,
+       .get_stats      = ath5k_get_stats,
+       .conf_tx        = NULL,
+       .get_tx_stats   = ath5k_get_tx_stats,
+       .get_tsf        = ath5k_get_tsf,
+       .set_tsf        = ath5k_set_tsf,
+       .reset_tsf      = ath5k_reset_tsf,
+       .bss_info_changed = ath5k_bss_info_changed,
+};
+
+/*
+ * Prototypes - Internal functions
+ */
+/* Attach detach */
+static int     ath5k_attach(struct pci_dev *pdev,
+                       struct ieee80211_hw *hw);
+static void    ath5k_detach(struct pci_dev *pdev,
+                       struct ieee80211_hw *hw);
+/* Channel/mode setup */
+static inline short ath5k_ieee2mhz(short chan);
+static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channels,
+                               unsigned int mode,
+                               unsigned int max);
+static int     ath5k_setup_bands(struct ieee80211_hw *hw);
+static int     ath5k_chan_set(struct ath5k_softc *sc,
+                               struct ieee80211_channel *chan);
+static void    ath5k_setcurmode(struct ath5k_softc *sc,
+                               unsigned int mode);
+static void    ath5k_mode_setup(struct ath5k_softc *sc);
+
+/* Descriptor setup */
+static int     ath5k_desc_alloc(struct ath5k_softc *sc,
+                               struct pci_dev *pdev);
+static void    ath5k_desc_free(struct ath5k_softc *sc,
+                               struct pci_dev *pdev);
+/* Buffers setup */
+static int     ath5k_rxbuf_setup(struct ath5k_softc *sc,
+                               struct ath5k_buf *bf);
+static int     ath5k_txbuf_setup(struct ath5k_softc *sc,
+                               struct ath5k_buf *bf);
+static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
+                               struct ath5k_buf *bf)
+{
+       BUG_ON(!bf);
+       if (!bf->skb)
+               return;
+       pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
+                       PCI_DMA_TODEVICE);
+       dev_kfree_skb_any(bf->skb);
+       bf->skb = NULL;
+}
+
+static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
+                               struct ath5k_buf *bf)
+{
+       BUG_ON(!bf);
+       if (!bf->skb)
+               return;
+       pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+                       PCI_DMA_FROMDEVICE);
+       dev_kfree_skb_any(bf->skb);
+       bf->skb = NULL;
+}
+
+
+/* Queues setup */
+static struct  ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
+                               int qtype, int subtype);
+static int     ath5k_beaconq_setup(struct ath5k_hw *ah);
+static int     ath5k_beaconq_config(struct ath5k_softc *sc);
+static void    ath5k_txq_drainq(struct ath5k_softc *sc,
+                               struct ath5k_txq *txq);
+static void    ath5k_txq_cleanup(struct ath5k_softc *sc);
+static void    ath5k_txq_release(struct ath5k_softc *sc);
+/* Rx handling */
+static int     ath5k_rx_start(struct ath5k_softc *sc);
+static void    ath5k_rx_stop(struct ath5k_softc *sc);
+static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
+                                       struct ath5k_desc *ds,
+                                       struct sk_buff *skb,
+                                       struct ath5k_rx_status *rs);
+static void    ath5k_tasklet_rx(unsigned long data);
+/* Tx handling */
+static void    ath5k_tx_processq(struct ath5k_softc *sc,
+                               struct ath5k_txq *txq);
+static void    ath5k_tasklet_tx(unsigned long data);
+/* Beacon handling */
+static int     ath5k_beacon_setup(struct ath5k_softc *sc,
+                                       struct ath5k_buf *bf);
+static void    ath5k_beacon_send(struct ath5k_softc *sc);
+static void    ath5k_beacon_config(struct ath5k_softc *sc);
+static void    ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
+static void    ath5k_tasklet_beacon(unsigned long data);
+
+static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
+{
+       u64 tsf = ath5k_hw_get_tsf64(ah);
+
+       if ((tsf & 0x7fff) < rstamp)
+               tsf -= 0x8000;
+
+       return (tsf & ~0x7fff) | rstamp;
+}
+
+/* Interrupt handling */
+static int     ath5k_init(struct ath5k_softc *sc);
+static int     ath5k_stop_locked(struct ath5k_softc *sc);
+static int     ath5k_stop_hw(struct ath5k_softc *sc);
+static irqreturn_t ath5k_intr(int irq, void *dev_id);
+static void    ath5k_tasklet_reset(unsigned long data);
+
+static void    ath5k_calibrate(unsigned long data);
+
+/*
+ * Module init/exit functions
+ */
+static int __init
+init_ath5k_pci(void)
+{
+       int ret;
+
+       ath5k_debug_init();
+
+       ret = pci_register_driver(&ath5k_pci_driver);
+       if (ret) {
+               printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static void __exit
+exit_ath5k_pci(void)
+{
+       pci_unregister_driver(&ath5k_pci_driver);
+
+       ath5k_debug_finish();
+}
+
+module_init(init_ath5k_pci);
+module_exit(exit_ath5k_pci);
+
+
+/********************\
+* PCI Initialization *
+\********************/
+
+static const char *
+ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
+{
+       const char *name = "xxxxx";
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(srev_names); i++) {
+               if (srev_names[i].sr_type != type)
+                       continue;
+
+               if ((val & 0xf0) == srev_names[i].sr_val)
+                       name = srev_names[i].sr_name;
+
+               if ((val & 0xff) == srev_names[i].sr_val) {
+                       name = srev_names[i].sr_name;
+                       break;
+               }
+       }
+
+       return name;
+}
+
+static int __devinit
+ath5k_pci_probe(struct pci_dev *pdev,
+               const struct pci_device_id *id)
+{
+       void __iomem *mem;
+       struct ath5k_softc *sc;
+       struct ieee80211_hw *hw;
+       int ret;
+       u8 csz;
+
+       ret = pci_enable_device(pdev);
+       if (ret) {
+               dev_err(&pdev->dev, "can't enable device\n");
+               goto err;
+       }
+
+       /* XXX 32-bit addressing only */
+       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (ret) {
+               dev_err(&pdev->dev, "32-bit DMA not available\n");
+               goto err_dis;
+       }
+
+       /*
+        * Cache line size is used to size and align various
+        * structures used to communicate with the hardware.
+        */
+       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+       if (csz == 0) {
+               /*
+                * Linux 2.4.18 (at least) writes the cache line size
+                * register as a 16-bit wide register which is wrong.
+                * We must have this setup properly for rx buffer
+                * DMA to work so force a reasonable value here if it
+                * comes up zero.
+                */
+               csz = L1_CACHE_BYTES / sizeof(u32);
+               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+       }
+       /*
+        * The default setting of latency timer yields poor results,
+        * set it to the value used by other systems.  It may be worth
+        * tweaking this setting more.
+        */
+       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+       /* Enable bus mastering */
+       pci_set_master(pdev);
+
+       /*
+        * Disable the RETRY_TIMEOUT register (0x41) to keep
+        * PCI Tx retries from interfering with C3 CPU state.
+        */
+       pci_write_config_byte(pdev, 0x41, 0);
+
+       ret = pci_request_region(pdev, 0, "ath5k");
+       if (ret) {
+               dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
+               goto err_dis;
+       }
+
+       mem = pci_iomap(pdev, 0, 0);
+       if (!mem) {
+               dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
+               ret = -EIO;
+               goto err_reg;
+       }
+
+       /*
+        * Allocate hw (mac80211 main struct)
+        * and hw->priv (driver private data)
+        */
+       hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
+       if (hw == NULL) {
+               dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
+               ret = -ENOMEM;
+               goto err_map;
+       }
+
+       dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
+
+       /* Initialize driver private data */
+       SET_IEEE80211_DEV(hw, &pdev->dev);
+       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+                   IEEE80211_HW_SIGNAL_DBM |
+                   IEEE80211_HW_NOISE_DBM;
+
+       hw->wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_STATION) |
+               BIT(NL80211_IFTYPE_ADHOC) |
+               BIT(NL80211_IFTYPE_MESH_POINT);
+
+       hw->extra_tx_headroom = 2;
+       hw->channel_change_time = 5000;
+       sc = hw->priv;
+       sc->hw = hw;
+       sc->pdev = pdev;
+
+       ath5k_debug_init_device(sc);
+
+       /*
+        * Mark the device as detached to avoid processing
+        * interrupts until setup is complete.
+        */
+       __set_bit(ATH_STAT_INVALID, sc->status);
+
+       sc->iobase = mem; /* So we can unmap it on detach */
+       sc->cachelsz = csz * sizeof(u32); /* convert to bytes */
+       sc->opmode = NL80211_IFTYPE_STATION;
+       mutex_init(&sc->lock);
+       spin_lock_init(&sc->rxbuflock);
+       spin_lock_init(&sc->txbuflock);
+       spin_lock_init(&sc->block);
+
+       /* Set private data */
+       pci_set_drvdata(pdev, hw);
+
+       /* Setup interrupt handler */
+       ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
+       if (ret) {
+               ATH5K_ERR(sc, "request_irq failed\n");
+               goto err_free;
+       }
+
+       /* Initialize device */
+       sc->ah = ath5k_hw_attach(sc, id->driver_data);
+       if (IS_ERR(sc->ah)) {
+               ret = PTR_ERR(sc->ah);
+               goto err_irq;
+       }
+
+       /* set up multi-rate retry capabilities */
+       if (sc->ah->ah_version == AR5K_AR5212) {
+               hw->max_rates = 4;
+               hw->max_rate_tries = 11;
+       }
+
+       /* Finish private driver data initialization */
+       ret = ath5k_attach(pdev, hw);
+       if (ret)
+               goto err_ah;
+
+       ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
+                       ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
+                                       sc->ah->ah_mac_srev,
+                                       sc->ah->ah_phy_revision);
+
+       if (!sc->ah->ah_single_chip) {
+               /* Single chip radio (!RF5111) */
+               if (sc->ah->ah_radio_5ghz_revision &&
+                       !sc->ah->ah_radio_2ghz_revision) {
+                       /* No 5GHz support -> report 2GHz radio */
+                       if (!test_bit(AR5K_MODE_11A,
+                               sc->ah->ah_capabilities.cap_mode)) {
+                               ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+                                       ath5k_chip_name(AR5K_VERSION_RAD,
+                                               sc->ah->ah_radio_5ghz_revision),
+                                               sc->ah->ah_radio_5ghz_revision);
+                       /* No 2GHz support (5110 and some
+                        * 5Ghz only cards) -> report 5Ghz radio */
+                       } else if (!test_bit(AR5K_MODE_11B,
+                               sc->ah->ah_capabilities.cap_mode)) {
+                               ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+                                       ath5k_chip_name(AR5K_VERSION_RAD,
+                                               sc->ah->ah_radio_5ghz_revision),
+                                               sc->ah->ah_radio_5ghz_revision);
+                       /* Multiband radio */
+                       } else {
+                               ATH5K_INFO(sc, "RF%s multiband radio found"
+                                       " (0x%x)\n",
+                                       ath5k_chip_name(AR5K_VERSION_RAD,
+                                               sc->ah->ah_radio_5ghz_revision),
+                                               sc->ah->ah_radio_5ghz_revision);
+                       }
+               }
+               /* Multi chip radio (RF5111 - RF2111) ->
+                * report both 2GHz/5GHz radios */
+               else if (sc->ah->ah_radio_5ghz_revision &&
+                               sc->ah->ah_radio_2ghz_revision){
+                       ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+                               ath5k_chip_name(AR5K_VERSION_RAD,
+                                       sc->ah->ah_radio_5ghz_revision),
+                                       sc->ah->ah_radio_5ghz_revision);
+                       ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+                               ath5k_chip_name(AR5K_VERSION_RAD,
+                                       sc->ah->ah_radio_2ghz_revision),
+                                       sc->ah->ah_radio_2ghz_revision);
+               }
+       }
+
+
+       /* ready to process interrupts */
+       __clear_bit(ATH_STAT_INVALID, sc->status);
+
+       return 0;
+err_ah:
+       ath5k_hw_detach(sc->ah);
+err_irq:
+       free_irq(pdev->irq, sc);
+err_free:
+       ieee80211_free_hw(hw);
+err_map:
+       pci_iounmap(pdev, mem);
+err_reg:
+       pci_release_region(pdev, 0);
+err_dis:
+       pci_disable_device(pdev);
+err:
+       return ret;
+}
+
+static void __devexit
+ath5k_pci_remove(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath5k_softc *sc = hw->priv;
+
+       ath5k_debug_finish_device(sc);
+       ath5k_detach(pdev, hw);
+       ath5k_hw_detach(sc->ah);
+       free_irq(pdev->irq, sc);
+       pci_iounmap(pdev, sc->iobase);
+       pci_release_region(pdev, 0);
+       pci_disable_device(pdev);
+       ieee80211_free_hw(hw);
+}
+
+#ifdef CONFIG_PM
+static int
+ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath5k_softc *sc = hw->priv;
+
+       ath5k_led_off(sc);
+
+       free_irq(pdev->irq, sc);
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+
+       return 0;
+}
+
+static int
+ath5k_pci_resume(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath5k_softc *sc = hw->priv;
+       int err;
+
+       pci_restore_state(pdev);
+
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
+
+       err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
+       if (err) {
+               ATH5K_ERR(sc, "request_irq failed\n");
+               goto err_no_irq;
+       }
+
+       ath5k_led_enable(sc);
+       return 0;
+
+err_no_irq:
+       pci_disable_device(pdev);
+       return err;
+}
+#endif /* CONFIG_PM */
+
+
+/***********************\
+* Driver Initialization *
+\***********************/
+
+static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+{
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct ath5k_softc *sc = hw->priv;
+       struct ath_regulatory *reg = &sc->ah->ah_regulatory;
+
+       return ath_reg_notifier_apply(wiphy, request, reg);
+}
+
+static int
+ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       u8 mac[ETH_ALEN] = {};
+       int ret;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
+
+       /*
+        * Check if the MAC has multi-rate retry support.
+        * We do this by trying to setup a fake extended
+        * descriptor.  MAC's that don't have support will
+        * return false w/o doing anything.  MAC's that do
+        * support it will return true w/o doing anything.
+        */
+       ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
+       if (ret < 0)
+               goto err;
+       if (ret > 0)
+               __set_bit(ATH_STAT_MRRETRY, sc->status);
+
+       /*
+        * Collect the channel list.  The 802.11 layer
+        * is resposible for filtering this list based
+        * on settings like the phy mode and regulatory
+        * domain restrictions.
+        */
+       ret = ath5k_setup_bands(hw);
+       if (ret) {
+               ATH5K_ERR(sc, "can't get channels\n");
+               goto err;
+       }
+
+       /* NB: setup here so ath5k_rate_update is happy */
+       if (test_bit(AR5K_MODE_11A, ah->ah_modes))
+               ath5k_setcurmode(sc, AR5K_MODE_11A);
+       else
+               ath5k_setcurmode(sc, AR5K_MODE_11B);
+
+       /*
+        * Allocate tx+rx descriptors and populate the lists.
+        */
+       ret = ath5k_desc_alloc(sc, pdev);
+       if (ret) {
+               ATH5K_ERR(sc, "can't allocate descriptors\n");
+               goto err;
+       }
+
+       /*
+        * Allocate hardware transmit queues: one queue for
+        * beacon frames and one data queue for each QoS
+        * priority.  Note that hw functions handle reseting
+        * these queues at the needed time.
+        */
+       ret = ath5k_beaconq_setup(ah);
+       if (ret < 0) {
+               ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
+               goto err_desc;
+       }
+       sc->bhalq = ret;
+
+       sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
+       if (IS_ERR(sc->txq)) {
+               ATH5K_ERR(sc, "can't setup xmit queue\n");
+               ret = PTR_ERR(sc->txq);
+               goto err_bhal;
+       }
+
+       tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
+       tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
+       tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
+       tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
+       setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
+
+       ret = ath5k_eeprom_read_mac(ah, mac);
+       if (ret) {
+               ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
+                       sc->pdev->device);
+               goto err_queues;
+       }
+
+       SET_IEEE80211_PERM_ADDR(hw, mac);
+       /* All MAC address bits matter for ACKs */
+       memset(sc->bssidmask, 0xff, ETH_ALEN);
+       ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
+
+       ah->ah_regulatory.current_rd =
+               ah->ah_capabilities.cap_eeprom.ee_regdomain;
+       ret = ath_regd_init(&ah->ah_regulatory, hw->wiphy, ath5k_reg_notifier);
+       if (ret) {
+               ATH5K_ERR(sc, "can't initialize regulatory system\n");
+               goto err_queues;
+       }
+
+       ret = ieee80211_register_hw(hw);
+       if (ret) {
+               ATH5K_ERR(sc, "can't register ieee80211 hw\n");
+               goto err_queues;
+       }
+
+       if (!ath_is_world_regd(&sc->ah->ah_regulatory))
+               regulatory_hint(hw->wiphy, sc->ah->ah_regulatory.alpha2);
+
+       ath5k_init_leds(sc);
+
+       return 0;
+err_queues:
+       ath5k_txq_release(sc);
+err_bhal:
+       ath5k_hw_release_tx_queue(ah, sc->bhalq);
+err_desc:
+       ath5k_desc_free(sc, pdev);
+err:
+       return ret;
+}
+
+static void
+ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       /*
+        * NB: the order of these is important:
+        * o call the 802.11 layer before detaching ath5k_hw 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
+        * XXX: ??? detach ath5k_hw ???
+        * Other than that, it's straightforward...
+        */
+       ieee80211_unregister_hw(hw);
+       ath5k_desc_free(sc, pdev);
+       ath5k_txq_release(sc);
+       ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
+       ath5k_unregister_leds(sc);
+
+       /*
+        * NB: can't reclaim these until after ieee80211_ifdetach
+        * returns because we'll get called back to reclaim node
+        * state and potentially want to use them.
+        */
+}
+
+
+
+
+/********************\
+* Channel/mode setup *
+\********************/
+
+/*
+ * Convert IEEE channel number to MHz frequency.
+ */
+static inline short
+ath5k_ieee2mhz(short chan)
+{
+       if (chan <= 14 || chan >= 27)
+               return ieee80211chan2mhz(chan);
+       else
+               return 2212 + chan * 20;
+}
+
+/*
+ * Returns true for the channel numbers used without all_channels modparam.
+ */
+static bool ath5k_is_standard_channel(short chan)
+{
+       return ((chan <= 14) ||
+               /* UNII 1,2 */
+               ((chan & 3) == 0 && chan >= 36 && chan <= 64) ||
+               /* midband */
+               ((chan & 3) == 0 && chan >= 100 && chan <= 140) ||
+               /* UNII-3 */
+               ((chan & 3) == 1 && chan >= 149 && chan <= 165));
+}
+
+static unsigned int
+ath5k_copy_channels(struct ath5k_hw *ah,
+               struct ieee80211_channel *channels,
+               unsigned int mode,
+               unsigned int max)
+{
+       unsigned int i, count, size, chfreq, freq, ch;
+
+       if (!test_bit(mode, ah->ah_modes))
+               return 0;
+
+       switch (mode) {
+       case AR5K_MODE_11A:
+       case AR5K_MODE_11A_TURBO:
+               /* 1..220, but 2GHz frequencies are filtered by check_channel */
+               size = 220 ;
+               chfreq = CHANNEL_5GHZ;
+               break;
+       case AR5K_MODE_11B:
+       case AR5K_MODE_11G:
+       case AR5K_MODE_11G_TURBO:
+               size = 26;
+               chfreq = CHANNEL_2GHZ;
+               break;
+       default:
+               ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n");
+               return 0;
+       }
+
+       for (i = 0, count = 0; i < size && max > 0; i++) {
+               ch = i + 1 ;
+               freq = ath5k_ieee2mhz(ch);
+
+               /* Check if channel is supported by the chipset */
+               if (!ath5k_channel_ok(ah, freq, chfreq))
+                       continue;
+
+               if (!modparam_all_channels && !ath5k_is_standard_channel(ch))
+                       continue;
+
+               /* Write channel info and increment counter */
+               channels[count].center_freq = freq;
+               channels[count].band = (chfreq == CHANNEL_2GHZ) ?
+                       IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+               switch (mode) {
+               case AR5K_MODE_11A:
+               case AR5K_MODE_11G:
+                       channels[count].hw_value = chfreq | CHANNEL_OFDM;
+                       break;
+               case AR5K_MODE_11A_TURBO:
+               case AR5K_MODE_11G_TURBO:
+                       channels[count].hw_value = chfreq |
+                               CHANNEL_OFDM | CHANNEL_TURBO;
+                       break;
+               case AR5K_MODE_11B:
+                       channels[count].hw_value = CHANNEL_B;
+               }
+
+               count++;
+               max--;
+       }
+
+       return count;
+}
+
+static void
+ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b)
+{
+       u8 i;
+
+       for (i = 0; i < AR5K_MAX_RATES; i++)
+               sc->rate_idx[b->band][i] = -1;
+
+       for (i = 0; i < b->n_bitrates; i++) {
+               sc->rate_idx[b->band][b->bitrates[i].hw_value] = i;
+               if (b->bitrates[i].hw_value_short)
+                       sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i;
+       }
+}
+
+static int
+ath5k_setup_bands(struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       struct ieee80211_supported_band *sband;
+       int max_c, count_c = 0;
+       int i;
+
+       BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS);
+       max_c = ARRAY_SIZE(sc->channels);
+
+       /* 2GHz band */
+       sband = &sc->sbands[IEEE80211_BAND_2GHZ];
+       sband->band = IEEE80211_BAND_2GHZ;
+       sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0];
+
+       if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) {
+               /* G mode */
+               memcpy(sband->bitrates, &ath5k_rates[0],
+                      sizeof(struct ieee80211_rate) * 12);
+               sband->n_bitrates = 12;
+
+               sband->channels = sc->channels;
+               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
+                                       AR5K_MODE_11G, max_c);
+
+               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+               count_c = sband->n_channels;
+               max_c -= count_c;
+       } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) {
+               /* B mode */
+               memcpy(sband->bitrates, &ath5k_rates[0],
+                      sizeof(struct ieee80211_rate) * 4);
+               sband->n_bitrates = 4;
+
+               /* 5211 only supports B rates and uses 4bit rate codes
+                * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B)
+                * fix them up here:
+                */
+               if (ah->ah_version == AR5K_AR5211) {
+                       for (i = 0; i < 4; i++) {
+                               sband->bitrates[i].hw_value =
+                                       sband->bitrates[i].hw_value & 0xF;
+                               sband->bitrates[i].hw_value_short =
+                                       sband->bitrates[i].hw_value_short & 0xF;
+                       }
+               }
+
+               sband->channels = sc->channels;
+               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
+                                       AR5K_MODE_11B, max_c);
+
+               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+               count_c = sband->n_channels;
+               max_c -= count_c;
+       }
+       ath5k_setup_rate_idx(sc, sband);
+
+       /* 5GHz band, A mode */
+       if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) {
+               sband = &sc->sbands[IEEE80211_BAND_5GHZ];
+               sband->band = IEEE80211_BAND_5GHZ;
+               sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0];
+
+               memcpy(sband->bitrates, &ath5k_rates[4],
+                      sizeof(struct ieee80211_rate) * 8);
+               sband->n_bitrates = 8;
+
+               sband->channels = &sc->channels[count_c];
+               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
+                                       AR5K_MODE_11A, max_c);
+
+               hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+       }
+       ath5k_setup_rate_idx(sc, sband);
+
+       ath5k_debug_dump_bands(sc);
+
+       return 0;
+}
+
+/*
+ * 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 after a la
+ * ath5k_init.
+ *
+ * Called with sc->lock.
+ */
+static int
+ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
+{
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
+               sc->curchan->center_freq, chan->center_freq);
+
+       if (chan->center_freq != sc->curchan->center_freq ||
+               chan->hw_value != sc->curchan->hw_value) {
+
+               sc->curchan = chan;
+               sc->curband = &sc->sbands[chan->band];
+
+               /*
+                * 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.
+                */
+               return ath5k_reset(sc, true, true);
+       }
+
+       return 0;
+}
+
+static void
+ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
+{
+       sc->curmode = mode;
+
+       if (mode == AR5K_MODE_11A) {
+               sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ];
+       } else {
+               sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ];
+       }
+}
+
+static void
+ath5k_mode_setup(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       u32 rfilt;
+
+       /* configure rx filter */
+       rfilt = sc->filter_flags;
+       ath5k_hw_set_rx_filter(ah, rfilt);
+
+       if (ath5k_hw_hasbssidmask(ah))
+               ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
+
+       /* configure operational mode */
+       ath5k_hw_set_opmode(ah);
+
+       ath5k_hw_set_mcast_filter(ah, 0, 0);
+       ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
+}
+
+static inline int
+ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
+{
+       int rix;
+
+       /* return base rate on errors */
+       if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
+                       "hw_rix out of bounds: %x\n", hw_rix))
+               return 0;
+
+       rix = sc->rate_idx[sc->curband->band][hw_rix];
+       if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
+               rix = 0;
+
+       return rix;
+}
+
+/***************\
+* Buffers setup *
+\***************/
+
+static
+struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
+{
+       struct sk_buff *skb;
+       unsigned int off;
+
+       /*
+        * Allocate buffer with headroom_needed space for the
+        * fake physical layer header at the start.
+        */
+       skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
+
+       if (!skb) {
+               ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
+                               sc->rxbufsize + sc->cachelsz - 1);
+               return NULL;
+       }
+       /*
+        * Cache-line-align.  This is important (for the
+        * 5210 at least) as not doing so causes bogus data
+        * in rx'd frames.
+        */
+       off = ((unsigned long)skb->data) % sc->cachelsz;
+       if (off != 0)
+               skb_reserve(skb, sc->cachelsz - off);
+
+       *skb_addr = pci_map_single(sc->pdev,
+               skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
+       if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
+               ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
+               dev_kfree_skb(skb);
+               return NULL;
+       }
+       return skb;
+}
+
+static int
+ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct sk_buff *skb = bf->skb;
+       struct ath5k_desc *ds;
+
+       if (!skb) {
+               skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr);
+               if (!skb)
+                       return -ENOMEM;
+               bf->skb = skb;
+       }
+
+       /*
+        * Setup descriptors.  For receive we always terminate
+        * the descriptor list with a self-linked entry so we'll
+        * not get overrun under high load (as can happen with a
+        * 5212 when ANI processing enables PHY error frames).
+        *
+        * To insure the last descriptor is self-linked we create
+        * each descriptor as self-linked and add it to the end.  As
+        * each additional descriptor is added the previous self-linked
+        * entry is ``fixed'' naturally.  This should be safe even
+        * if DMA is happening.  When processing RX interrupts we
+        * never remove/process the last, self-linked, entry on the
+        * descriptor list.  This insures the hardware always has
+        * someplace to write a new frame.
+        */
+       ds = bf->desc;
+       ds->ds_link = bf->daddr;        /* link to self */
+       ds->ds_data = bf->skbaddr;
+       ah->ah_setup_rx_desc(ah, ds,
+               skb_tailroom(skb),      /* buffer size */
+               0);
+
+       if (sc->rxlink != NULL)
+               *sc->rxlink = bf->daddr;
+       sc->rxlink = &ds->ds_link;
+       return 0;
+}
+
+static int
+ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_txq *txq = sc->txq;
+       struct ath5k_desc *ds = bf->desc;
+       struct sk_buff *skb = bf->skb;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
+       struct ieee80211_rate *rate;
+       unsigned int mrr_rate[3], mrr_tries[3];
+       int i, ret;
+       u16 hw_rate;
+       u16 cts_rate = 0;
+       u16 duration = 0;
+       u8 rc_flags;
+
+       flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
+
+       /* XXX endianness */
+       bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
+                       PCI_DMA_TODEVICE);
+
+       rate = ieee80211_get_tx_rate(sc->hw, info);
+
+       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+               flags |= AR5K_TXDESC_NOACK;
+
+       rc_flags = info->control.rates[0].flags;
+       hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+               rate->hw_value_short : rate->hw_value;
+
+       pktlen = skb->len;
+
+       /* FIXME: If we are in g mode and rate is a CCK rate
+        * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
+        * from tx power (value is in dB units already) */
+       if (info->control.hw_key) {
+               keyidx = info->control.hw_key->hw_key_idx;
+               pktlen += info->control.hw_key->icv_len;
+       }
+       if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+               flags |= AR5K_TXDESC_RTSENA;
+               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+               duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
+                       sc->vif, pktlen, info));
+       }
+       if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+               flags |= AR5K_TXDESC_CTSENA;
+               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+               duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
+                       sc->vif, pktlen, info));
+       }
+       ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
+               ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
+               (sc->power_level * 2),
+               hw_rate,
+               info->control.rates[0].count, keyidx, 0, flags,
+               cts_rate, duration);
+       if (ret)
+               goto err_unmap;
+
+       memset(mrr_rate, 0, sizeof(mrr_rate));
+       memset(mrr_tries, 0, sizeof(mrr_tries));
+       for (i = 0; i < 3; i++) {
+               rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
+               if (!rate)
+                       break;
+
+               mrr_rate[i] = rate->hw_value;
+               mrr_tries[i] = info->control.rates[i + 1].count;
+       }
+
+       ah->ah_setup_mrr_tx_desc(ah, ds,
+               mrr_rate[0], mrr_tries[0],
+               mrr_rate[1], mrr_tries[1],
+               mrr_rate[2], mrr_tries[2]);
+
+       ds->ds_link = 0;
+       ds->ds_data = bf->skbaddr;
+
+       spin_lock_bh(&txq->lock);
+       list_add_tail(&bf->list, &txq->q);
+       sc->tx_stats[txq->qnum].len++;
+       if (txq->link == NULL) /* is this first packet? */
+               ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
+       else /* no, so only link it */
+               *txq->link = bf->daddr;
+
+       txq->link = &ds->ds_link;
+       ath5k_hw_start_tx_dma(ah, txq->qnum);
+       mmiowb();
+       spin_unlock_bh(&txq->lock);
+
+       return 0;
+err_unmap:
+       pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
+       return ret;
+}
+
+/*******************\
+* Descriptors setup *
+\*******************/
+
+static int
+ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
+{
+       struct ath5k_desc *ds;
+       struct ath5k_buf *bf;
+       dma_addr_t da;
+       unsigned int i;
+       int ret;
+
+       /* allocate descriptors */
+       sc->desc_len = sizeof(struct ath5k_desc) *
+                       (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);
+       sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr);
+       if (sc->desc == NULL) {
+               ATH5K_ERR(sc, "can't allocate descriptors\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+       ds = sc->desc;
+       da = sc->desc_daddr;
+       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n",
+               ds, sc->desc_len, (unsigned long long)sc->desc_daddr);
+
+       bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF,
+                       sizeof(struct ath5k_buf), GFP_KERNEL);
+       if (bf == NULL) {
+               ATH5K_ERR(sc, "can't allocate bufptr\n");
+               ret = -ENOMEM;
+               goto err_free;
+       }
+       sc->bufptr = bf;
+
+       INIT_LIST_HEAD(&sc->rxbuf);
+       for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
+               bf->desc = ds;
+               bf->daddr = da;
+               list_add_tail(&bf->list, &sc->rxbuf);
+       }
+
+       INIT_LIST_HEAD(&sc->txbuf);
+       sc->txbuf_len = ATH_TXBUF;
+       for (i = 0; i < ATH_TXBUF; i++, bf++, ds++,
+                       da += sizeof(*ds)) {
+               bf->desc = ds;
+               bf->daddr = da;
+               list_add_tail(&bf->list, &sc->txbuf);
+       }
+
+       /* beacon buffer */
+       bf->desc = ds;
+       bf->daddr = da;
+       sc->bbuf = bf;
+
+       return 0;
+err_free:
+       pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
+err:
+       sc->desc = NULL;
+       return ret;
+}
+
+static void
+ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
+{
+       struct ath5k_buf *bf;
+
+       ath5k_txbuf_free(sc, sc->bbuf);
+       list_for_each_entry(bf, &sc->txbuf, list)
+               ath5k_txbuf_free(sc, bf);
+       list_for_each_entry(bf, &sc->rxbuf, list)
+               ath5k_rxbuf_free(sc, bf);
+
+       /* Free memory associated with all descriptors */
+       pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
+
+       kfree(sc->bufptr);
+       sc->bufptr = NULL;
+}
+
+
+
+
+
+/**************\
+* Queues setup *
+\**************/
+
+static struct ath5k_txq *
+ath5k_txq_setup(struct ath5k_softc *sc,
+               int qtype, int subtype)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_txq *txq;
+       struct ath5k_txq_info qi = {
+               .tqi_subtype = subtype,
+               .tqi_aifs = AR5K_TXQ_USEDEFAULT,
+               .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
+               .tqi_cw_max = AR5K_TXQ_USEDEFAULT
+       };
+       int qnum;
+
+       /*
+        * 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.
+        */
+       qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE |
+                               AR5K_TXQ_FLAG_TXDESCINT_ENABLE;
+       qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi);
+       if (qnum < 0) {
+               /*
+                * NB: don't print a message, this happens
+                * normally on parts with too few tx queues
+                */
+               return ERR_PTR(qnum);
+       }
+       if (qnum >= ARRAY_SIZE(sc->txqs)) {
+               ATH5K_ERR(sc, "hw qnum %u out of range, max %tu!\n",
+                       qnum, ARRAY_SIZE(sc->txqs));
+               ath5k_hw_release_tx_queue(ah, qnum);
+               return ERR_PTR(-EINVAL);
+       }
+       txq = &sc->txqs[qnum];
+       if (!txq->setup) {
+               txq->qnum = qnum;
+               txq->link = NULL;
+               INIT_LIST_HEAD(&txq->q);
+               spin_lock_init(&txq->lock);
+               txq->setup = true;
+       }
+       return &sc->txqs[qnum];
+}
+
+static int
+ath5k_beaconq_setup(struct ath5k_hw *ah)
+{
+       struct ath5k_txq_info qi = {
+               .tqi_aifs = AR5K_TXQ_USEDEFAULT,
+               .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
+               .tqi_cw_max = AR5K_TXQ_USEDEFAULT,
+               /* NB: for dynamic turbo, don't enable any other interrupts */
+               .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE
+       };
+
+       return ath5k_hw_setup_tx_queue(ah, AR5K_TX_QUEUE_BEACON, &qi);
+}
+
+static int
+ath5k_beaconq_config(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_txq_info qi;
+       int ret;
+
+       ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
+       if (ret)
+               return ret;
+       if (sc->opmode == NL80211_IFTYPE_AP ||
+               sc->opmode == NL80211_IFTYPE_MESH_POINT) {
+               /*
+                * Always burst out beacon and CAB traffic
+                * (aifs = cwmin = cwmax = 0)
+                */
+               qi.tqi_aifs = 0;
+               qi.tqi_cw_min = 0;
+               qi.tqi_cw_max = 0;
+       } else if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+               /*
+                * Adhoc mode; backoff between 0 and (2 * cw_min).
+                */
+               qi.tqi_aifs = 0;
+               qi.tqi_cw_min = 0;
+               qi.tqi_cw_max = 2 * ah->ah_cw_min;
+       }
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+               "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n",
+               qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max);
+
+       ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi);
+       if (ret) {
+               ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
+                       "hardware queue!\n", __func__);
+               return ret;
+       }
+
+       return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */;
+}
+
+static void
+ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
+{
+       struct ath5k_buf *bf, *bf0;
+
+       /*
+        * NB: this assumes output has been stopped and
+        *     we do not need to block ath5k_tx_tasklet
+        */
+       spin_lock_bh(&txq->lock);
+       list_for_each_entry_safe(bf, bf0, &txq->q, list) {
+               ath5k_debug_printtxbuf(sc, bf);
+
+               ath5k_txbuf_free(sc, bf);
+
+               spin_lock_bh(&sc->txbuflock);
+               sc->tx_stats[txq->qnum].len--;
+               list_move_tail(&bf->list, &sc->txbuf);
+               sc->txbuf_len++;
+               spin_unlock_bh(&sc->txbuflock);
+       }
+       txq->link = NULL;
+       spin_unlock_bh(&txq->lock);
+}
+
+/*
+ * Drain the transmit queues and reclaim resources.
+ */
+static void
+ath5k_txq_cleanup(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       unsigned int i;
+
+       /* XXX return value */
+       if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) {
+               /* don't touch the hardware if marked invalid */
+               ath5k_hw_stop_tx_dma(ah, sc->bhalq);
+               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",
+                       ath5k_hw_get_txdp(ah, sc->bhalq));
+               for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
+                       if (sc->txqs[i].setup) {
+                               ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
+                               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
+                                       "link %p\n",
+                                       sc->txqs[i].qnum,
+                                       ath5k_hw_get_txdp(ah,
+                                                       sc->txqs[i].qnum),
+                                       sc->txqs[i].link);
+                       }
+       }
+       ieee80211_wake_queues(sc->hw); /* XXX move to callers */
+
+       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
+               if (sc->txqs[i].setup)
+                       ath5k_txq_drainq(sc, &sc->txqs[i]);
+}
+
+static void
+ath5k_txq_release(struct ath5k_softc *sc)
+{
+       struct ath5k_txq *txq = sc->txqs;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++, txq++)
+               if (txq->setup) {
+                       ath5k_hw_release_tx_queue(sc->ah, txq->qnum);
+                       txq->setup = false;
+               }
+}
+
+
+
+
+/*************\
+* RX Handling *
+\*************/
+
+/*
+ * Enable the receive h/w following a reset.
+ */
+static int
+ath5k_rx_start(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_buf *bf;
+       int ret;
+
+       sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->cachelsz);
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
+               sc->cachelsz, sc->rxbufsize);
+
+       sc->rxlink = NULL;
+
+       spin_lock_bh(&sc->rxbuflock);
+       list_for_each_entry(bf, &sc->rxbuf, list) {
+               ret = ath5k_rxbuf_setup(sc, bf);
+               if (ret != 0) {
+                       spin_unlock_bh(&sc->rxbuflock);
+                       goto err;
+               }
+       }
+       bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
+       spin_unlock_bh(&sc->rxbuflock);
+
+       ath5k_hw_set_rxdp(ah, bf->daddr);
+       ath5k_hw_start_rx_dma(ah);      /* enable recv descriptors */
+       ath5k_mode_setup(sc);           /* set filters, etc. */
+       ath5k_hw_start_rx_pcu(ah);      /* re-enable PCU/DMA engine */
+
+       return 0;
+err:
+       return ret;
+}
+
+/*
+ * Disable the receive h/w in preparation for a reset.
+ */
+static void
+ath5k_rx_stop(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+
+       ath5k_hw_stop_rx_pcu(ah);       /* disable PCU */
+       ath5k_hw_set_rx_filter(ah, 0);  /* clear recv filter */
+       ath5k_hw_stop_rx_dma(ah);       /* disable DMA engine */
+
+       ath5k_debug_printrxbuffs(sc, ah);
+
+       sc->rxlink = NULL;              /* just in case */
+}
+
+static unsigned int
+ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
+               struct sk_buff *skb, struct ath5k_rx_status *rs)
+{
+       struct ieee80211_hdr *hdr = (void *)skb->data;
+       unsigned int keyix, hlen;
+
+       if (!(rs->rs_status & AR5K_RXERR_DECRYPT) &&
+                       rs->rs_keyix != AR5K_RXKEYIX_INVALID)
+               return RX_FLAG_DECRYPTED;
+
+       /* Apparently when a default key is used to decrypt the packet
+          the hw does not set the index used to decrypt.  In such cases
+          get the index from the packet. */
+       hlen = ieee80211_hdrlen(hdr->frame_control);
+       if (ieee80211_has_protected(hdr->frame_control) &&
+           !(rs->rs_status & AR5K_RXERR_DECRYPT) &&
+           skb->len >= hlen + 4) {
+               keyix = skb->data[hlen + 3] >> 6;
+
+               if (test_bit(keyix, sc->keymap))
+                       return RX_FLAG_DECRYPTED;
+       }
+
+       return 0;
+}
+
+
+static void
+ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
+                    struct ieee80211_rx_status *rxs)
+{
+       u64 tsf, bc_tstamp;
+       u32 hw_tu;
+       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+
+       if (ieee80211_is_beacon(mgmt->frame_control) &&
+           le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
+           memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
+               /*
+                * Received an IBSS beacon with the same BSSID. Hardware *must*
+                * have updated the local TSF. We have to work around various
+                * hardware bugs, though...
+                */
+               tsf = ath5k_hw_get_tsf64(sc->ah);
+               bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp);
+               hw_tu = TSF_TO_TU(tsf);
+
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "beacon %llx mactime %llx (diff %lld) tsf now %llx\n",
+                       (unsigned long long)bc_tstamp,
+                       (unsigned long long)rxs->mactime,
+                       (unsigned long long)(rxs->mactime - bc_tstamp),
+                       (unsigned long long)tsf);
+
+               /*
+                * Sometimes the HW will give us a wrong tstamp in the rx
+                * status, causing the timestamp extension to go wrong.
+                * (This seems to happen especially with beacon frames bigger
+                * than 78 byte (incl. FCS))
+                * But we know that the receive timestamp must be later than the
+                * timestamp of the beacon since HW must have synced to that.
+                *
+                * NOTE: here we assume mactime to be after the frame was
+                * received, not like mac80211 which defines it at the start.
+                */
+               if (bc_tstamp > rxs->mactime) {
+                       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                               "fixing mactime from %llx to %llx\n",
+                               (unsigned long long)rxs->mactime,
+                               (unsigned long long)tsf);
+                       rxs->mactime = tsf;
+               }
+
+               /*
+                * Local TSF might have moved higher than our beacon timers,
+                * in that case we have to update them to continue sending
+                * beacons. This also takes care of synchronizing beacon sending
+                * times with other stations.
+                */
+               if (hw_tu >= sc->nexttbtt)
+                       ath5k_beacon_update_timers(sc, bc_tstamp);
+       }
+}
+
+static void ath5k_tasklet_beacon(unsigned long data)
+{
+       struct ath5k_softc *sc = (struct ath5k_softc *) data;
+
+       /*
+        * Software beacon alert--time to send a beacon.
+        *
+        * In IBSS mode we use this interrupt just to
+        * keep track of the next TBTT (target beacon
+        * transmission time) in order to detect wether
+        * automatic TSF updates happened.
+        */
+       if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+               /* XXX: only if VEOL suppported */
+               u64 tsf = ath5k_hw_get_tsf64(sc->ah);
+               sc->nexttbtt += sc->bintval;
+               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+                               "SWBA nexttbtt: %x hw_tu: %x "
+                               "TSF: %llx\n",
+                               sc->nexttbtt,
+                               TSF_TO_TU(tsf),
+                               (unsigned long long) tsf);
+       } else {
+               spin_lock(&sc->block);
+               ath5k_beacon_send(sc);
+               spin_unlock(&sc->block);
+       }
+}
+
+static void
+ath5k_tasklet_rx(unsigned long data)
+{
+       struct ieee80211_rx_status rxs = {};
+       struct ath5k_rx_status rs = {};
+       struct sk_buff *skb, *next_skb;
+       dma_addr_t next_skb_addr;
+       struct ath5k_softc *sc = (void *)data;
+       struct ath5k_buf *bf, *bf_last;
+       struct ath5k_desc *ds;
+       int ret;
+       int hdrlen;
+       int padsize;
+
+       spin_lock(&sc->rxbuflock);
+       if (list_empty(&sc->rxbuf)) {
+               ATH5K_WARN(sc, "empty rx buf pool\n");
+               goto unlock;
+       }
+       bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list);
+       do {
+               rxs.flag = 0;
+
+               bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
+               BUG_ON(bf->skb == NULL);
+               skb = bf->skb;
+               ds = bf->desc;
+
+               /*
+                * last buffer must not be freed to ensure proper hardware
+                * function. When the hardware finishes also a packet next to
+                * it, we are sure, it doesn't use it anymore and we can go on.
+                */
+               if (bf_last == bf)
+                       bf->flags |= 1;
+               if (bf->flags) {
+                       struct ath5k_buf *bf_next = list_entry(bf->list.next,
+                                       struct ath5k_buf, list);
+                       ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc,
+                                       &rs);
+                       if (ret)
+                               break;
+                       bf->flags &= ~1;
+                       /* skip the overwritten one (even status is martian) */
+                       goto next;
+               }
+
+               ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
+               if (unlikely(ret == -EINPROGRESS))
+                       break;
+               else if (unlikely(ret)) {
+                       ATH5K_ERR(sc, "error in processing rx descriptor\n");
+                       spin_unlock(&sc->rxbuflock);
+                       return;
+               }
+
+               if (unlikely(rs.rs_more)) {
+                       ATH5K_WARN(sc, "unsupported jumbo\n");
+                       goto next;
+               }
+
+               if (unlikely(rs.rs_status)) {
+                       if (rs.rs_status & AR5K_RXERR_PHY)
+                               goto next;
+                       if (rs.rs_status & AR5K_RXERR_DECRYPT) {
+                               /*
+                                * Decrypt error.  If the error occurred
+                                * because there was no hardware key, then
+                                * let the frame through so the upper layers
+                                * can process it.  This is necessary for 5210
+                                * parts which have no way to setup a ``clear''
+                                * key cache entry.
+                                *
+                                * XXX do key cache faulting
+                                */
+                               if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
+                                   !(rs.rs_status & AR5K_RXERR_CRC))
+                                       goto accept;
+                       }
+                       if (rs.rs_status & AR5K_RXERR_MIC) {
+                               rxs.flag |= RX_FLAG_MMIC_ERROR;
+                               goto accept;
+                       }
+
+                       /* let crypto-error packets fall through in MNTR */
+                       if ((rs.rs_status &
+                               ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
+                                       sc->opmode != NL80211_IFTYPE_MONITOR)
+                               goto next;
+               }
+accept:
+               next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
+
+               /*
+                * If we can't replace bf->skb with a new skb under memory
+                * pressure, just skip this packet
+                */
+               if (!next_skb)
+                       goto next;
+
+               pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+                               PCI_DMA_FROMDEVICE);
+               skb_put(skb, rs.rs_datalen);
+
+               /* The MAC header is padded to have 32-bit boundary if the
+                * packet payload is non-zero. The general calculation for
+                * padsize would take into account odd header lengths:
+                * padsize = (4 - hdrlen % 4) % 4; However, since only
+                * even-length headers are used, padding can only be 0 or 2
+                * bytes and we can optimize this a bit. In addition, we must
+                * not try to remove padding from short control frames that do
+                * not have payload. */
+               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+               padsize = ath5k_pad_size(hdrlen);
+               if (padsize) {
+                       memmove(skb->data + padsize, skb->data, hdrlen);
+                       skb_pull(skb, padsize);
+               }
+
+               /*
+                * always extend the mac timestamp, since this information is
+                * also needed for proper IBSS merging.
+                *
+                * XXX: it might be too late to do it here, since rs_tstamp is
+                * 15bit only. that means TSF extension has to be done within
+                * 32768usec (about 32ms). it might be necessary to move this to
+                * the interrupt handler, like it is done in madwifi.
+                *
+                * Unfortunately we don't know when the hardware takes the rx
+                * timestamp (beginning of phy frame, data frame, end of rx?).
+                * The only thing we know is that it is hardware specific...
+                * On AR5213 it seems the rx timestamp is at the end of the
+                * frame, but i'm not sure.
+                *
+                * NOTE: mac80211 defines mactime at the beginning of the first
+                * data symbol. Since we don't have any time references it's
+                * impossible to comply to that. This affects IBSS merge only
+                * right now, so it's not too bad...
+                */
+               rxs.mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp);
+               rxs.flag |= RX_FLAG_TSFT;
+
+               rxs.freq = sc->curchan->center_freq;
+               rxs.band = sc->curband->band;
+
+               rxs.noise = sc->ah->ah_noise_floor;
+               rxs.signal = rxs.noise + rs.rs_rssi;
+
+               /* An rssi of 35 indicates you should be able use
+                * 54 Mbps reliably. A more elaborate scheme can be used
+                * here but it requires a map of SNR/throughput for each
+                * possible mode used */
+               rxs.qual = rs.rs_rssi * 100 / 35;
+
+               /* rssi can be more than 35 though, anything above that
+                * should be considered at 100% */
+               if (rxs.qual > 100)
+                       rxs.qual = 100;
+
+               rxs.antenna = rs.rs_antenna;
+               rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
+               rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
+
+               if (rxs.rate_idx >= 0 && rs.rs_rate ==
+                   sc->curband->bitrates[rxs.rate_idx].hw_value_short)
+                       rxs.flag |= RX_FLAG_SHORTPRE;
+
+               ath5k_debug_dump_skb(sc, skb, "RX  ", 0);
+
+               /* check beacons in IBSS mode */
+               if (sc->opmode == NL80211_IFTYPE_ADHOC)
+                       ath5k_check_ibss_tsf(sc, skb, &rxs);
+
+               __ieee80211_rx(sc->hw, skb, &rxs);
+
+               bf->skb = next_skb;
+               bf->skbaddr = next_skb_addr;
+next:
+               list_move_tail(&bf->list, &sc->rxbuf);
+       } while (ath5k_rxbuf_setup(sc, bf) == 0);
+unlock:
+       spin_unlock(&sc->rxbuflock);
+}
+
+
+
+
+/*************\
+* TX Handling *
+\*************/
+
+static void
+ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
+{
+       struct ath5k_tx_status ts = {};
+       struct ath5k_buf *bf, *bf0;
+       struct ath5k_desc *ds;
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *info;
+       int i, ret;
+
+       spin_lock(&txq->lock);
+       list_for_each_entry_safe(bf, bf0, &txq->q, list) {
+               ds = bf->desc;
+
+               ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
+               if (unlikely(ret == -EINPROGRESS))
+                       break;
+               else if (unlikely(ret)) {
+                       ATH5K_ERR(sc, "error %d while processing queue %u\n",
+                               ret, txq->qnum);
+                       break;
+               }
+
+               skb = bf->skb;
+               info = IEEE80211_SKB_CB(skb);
+               bf->skb = NULL;
+
+               pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
+                               PCI_DMA_TODEVICE);
+
+               ieee80211_tx_info_clear_status(info);
+               for (i = 0; i < 4; i++) {
+                       struct ieee80211_tx_rate *r =
+                               &info->status.rates[i];
+
+                       if (ts.ts_rate[i]) {
+                               r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
+                               r->count = ts.ts_retry[i];
+                       } else {
+                               r->idx = -1;
+                               r->count = 0;
+                       }
+               }
+
+               /* count the successful attempt as well */
+               info->status.rates[ts.ts_final_idx].count++;
+
+               if (unlikely(ts.ts_status)) {
+                       sc->ll_stats.dot11ACKFailureCount++;
+                       if (ts.ts_status & AR5K_TXERR_FILT)
+                               info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+               } else {
+                       info->flags |= IEEE80211_TX_STAT_ACK;
+                       info->status.ack_signal = ts.ts_rssi;
+               }
+
+               ieee80211_tx_status(sc->hw, skb);
+               sc->tx_stats[txq->qnum].count++;
+
+               spin_lock(&sc->txbuflock);
+               sc->tx_stats[txq->qnum].len--;
+               list_move_tail(&bf->list, &sc->txbuf);
+               sc->txbuf_len++;
+               spin_unlock(&sc->txbuflock);
+       }
+       if (likely(list_empty(&txq->q)))
+               txq->link = NULL;
+       spin_unlock(&txq->lock);
+       if (sc->txbuf_len > ATH_TXBUF / 5)
+               ieee80211_wake_queues(sc->hw);
+}
+
+static void
+ath5k_tasklet_tx(unsigned long data)
+{
+       struct ath5k_softc *sc = (void *)data;
+
+       ath5k_tx_processq(sc, sc->txq);
+}
+
+
+/*****************\
+* Beacon handling *
+\*****************/
+
+/*
+ * Setup the beacon frame for transmit.
+ */
+static int
+ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+       struct sk_buff *skb = bf->skb;
+       struct  ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_desc *ds;
+       int ret, antenna = 0;
+       u32 flags;
+
+       bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
+                       PCI_DMA_TODEVICE);
+       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
+                       "skbaddr %llx\n", skb, skb->data, skb->len,
+                       (unsigned long long)bf->skbaddr);
+       if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) {
+               ATH5K_ERR(sc, "beacon DMA mapping failed\n");
+               return -EIO;
+       }
+
+       ds = bf->desc;
+
+       flags = AR5K_TXDESC_NOACK;
+       if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
+               ds->ds_link = bf->daddr;        /* self-linked */
+               flags |= AR5K_TXDESC_VEOL;
+               /*
+                * Let hardware handle antenna switching if txantenna is not set
+                */
+       } else {
+               ds->ds_link = 0;
+               /*
+                * Switch antenna every 4 beacons if txantenna is not set
+                * XXX assumes two antennas
+                */
+               if (antenna == 0)
+                       antenna = sc->bsent & 4 ? 2 : 1;
+       }
+
+       /* FIXME: If we are in g mode and rate is a CCK rate
+        * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
+        * from tx power (value is in dB units already) */
+       ds->ds_data = bf->skbaddr;
+       ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
+                       ieee80211_get_hdrlen_from_skb(skb),
+                       AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
+                       ieee80211_get_tx_rate(sc->hw, info)->hw_value,
+                       1, AR5K_TXKEYIX_INVALID,
+                       antenna, flags, 0, 0);
+       if (ret)
+               goto err_unmap;
+
+       return 0;
+err_unmap:
+       pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
+       return ret;
+}
+
+/*
+ * Transmit a beacon frame at SWBA.  Dynamic updates to the
+ * frame contents are done as needed and the slot time is
+ * also adjusted based on current state.
+ *
+ * This is called from software irq context (beacontq or restq
+ * tasklets) or user context from ath5k_beacon_config.
+ */
+static void
+ath5k_beacon_send(struct ath5k_softc *sc)
+{
+       struct ath5k_buf *bf = sc->bbuf;
+       struct ath5k_hw *ah = sc->ah;
+
+       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
+
+       if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
+                       sc->opmode == NL80211_IFTYPE_MONITOR)) {
+               ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
+               return;
+       }
+       /*
+        * Check if the previous beacon has gone out.  If
+        * not don't don't try to post another, skip this
+        * period and wait for the next.  Missed beacons
+        * indicate a problem and should not occur.  If we
+        * miss too many consecutive beacons reset the device.
+        */
+       if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
+               sc->bmisscount++;
+               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+                       "missed %u consecutive beacons\n", sc->bmisscount);
+               if (sc->bmisscount > 3) {               /* NB: 3 is a guess */
+                       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+                               "stuck beacon time (%u missed)\n",
+                               sc->bmisscount);
+                       tasklet_schedule(&sc->restq);
+               }
+               return;
+       }
+       if (unlikely(sc->bmisscount != 0)) {
+               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+                       "resume beacon xmit after %u misses\n",
+                       sc->bmisscount);
+               sc->bmisscount = 0;
+       }
+
+       /*
+        * 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 (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
+               ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq);
+               /* NB: hw still stops DMA, so proceed */
+       }
+
+       ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
+       ath5k_hw_start_tx_dma(ah, sc->bhalq);
+       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
+               sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
+
+       sc->bsent++;
+}
+
+
+/**
+ * ath5k_beacon_update_timers - update beacon timers
+ *
+ * @sc: struct ath5k_softc pointer we are operating on
+ * @bc_tsf: the timestamp of the beacon. 0 to reset the TSF. -1 to perform a
+ *          beacon timer update based on the current HW TSF.
+ *
+ * Calculate the next target beacon transmit time (TBTT) based on the timestamp
+ * of a received beacon or the current local hardware TSF and write it to the
+ * beacon timer registers.
+ *
+ * This is called in a variety of situations, e.g. when a beacon is received,
+ * when a TSF update has been detected, but also when an new IBSS is created or
+ * when we otherwise know we have to update the timers, but we keep it in this
+ * function to have it all together in one place.
+ */
+static void
+ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
+{
+       struct ath5k_hw *ah = sc->ah;
+       u32 nexttbtt, intval, hw_tu, bc_tu;
+       u64 hw_tsf;
+
+       intval = sc->bintval & AR5K_BEACON_PERIOD;
+       if (WARN_ON(!intval))
+               return;
+
+       /* beacon TSF converted to TU */
+       bc_tu = TSF_TO_TU(bc_tsf);
+
+       /* current TSF converted to TU */
+       hw_tsf = ath5k_hw_get_tsf64(ah);
+       hw_tu = TSF_TO_TU(hw_tsf);
+
+#define FUDGE 3
+       /* we use FUDGE to make sure the next TBTT is ahead of the current TU */
+       if (bc_tsf == -1) {
+               /*
+                * no beacons received, called internally.
+                * just need to refresh timers based on HW TSF.
+                */
+               nexttbtt = roundup(hw_tu + FUDGE, intval);
+       } else if (bc_tsf == 0) {
+               /*
+                * no beacon received, probably called by ath5k_reset_tsf().
+                * reset TSF to start with 0.
+                */
+               nexttbtt = intval;
+               intval |= AR5K_BEACON_RESET_TSF;
+       } else if (bc_tsf > hw_tsf) {
+               /*
+                * beacon received, SW merge happend but HW TSF not yet updated.
+                * not possible to reconfigure timers yet, but next time we
+                * receive a beacon with the same BSSID, the hardware will
+                * automatically update the TSF and then we need to reconfigure
+                * the timers.
+                */
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "need to wait for HW TSF sync\n");
+               return;
+       } else {
+               /*
+                * most important case for beacon synchronization between STA.
+                *
+                * beacon received and HW TSF has been already updated by HW.
+                * update next TBTT based on the TSF of the beacon, but make
+                * sure it is ahead of our local TSF timer.
+                */
+               nexttbtt = bc_tu + roundup(hw_tu + FUDGE - bc_tu, intval);
+       }
+#undef FUDGE
+
+       sc->nexttbtt = nexttbtt;
+
+       intval |= AR5K_BEACON_ENA;
+       ath5k_hw_init_beacon(ah, nexttbtt, intval);
+
+       /*
+        * debugging output last in order to preserve the time critical aspect
+        * of this function
+        */
+       if (bc_tsf == -1)
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "reconfigured timers based on HW TSF\n");
+       else if (bc_tsf == 0)
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "reset HW TSF and timers\n");
+       else
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "updated timers based on beacon TSF\n");
+
+       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                         "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n",
+                         (unsigned long long) bc_tsf,
+                         (unsigned long long) hw_tsf, bc_tu, hw_tu, nexttbtt);
+       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "intval %u %s %s\n",
+               intval & AR5K_BEACON_PERIOD,
+               intval & AR5K_BEACON_ENA ? "AR5K_BEACON_ENA" : "",
+               intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : "");
+}
+
+
+/**
+ * ath5k_beacon_config - Configure the beacon queues and interrupts
+ *
+ * @sc: struct ath5k_softc pointer we are operating on
+ *
+ * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
+ * interrupts to detect TSF updates only.
+ */
+static void
+ath5k_beacon_config(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       unsigned long flags;
+
+       ath5k_hw_set_imr(ah, 0);
+       sc->bmisscount = 0;
+       sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
+
+       if (sc->opmode == NL80211_IFTYPE_ADHOC ||
+                       sc->opmode == NL80211_IFTYPE_MESH_POINT ||
+                       sc->opmode == NL80211_IFTYPE_AP) {
+               /*
+                * In IBSS mode we use a self-linked tx descriptor and let the
+                * hardware send the beacons automatically. We have to load it
+                * only once here.
+                * We use the SWBA interrupt only to keep track of the beacon
+                * timers in order to detect automatic TSF updates.
+                */
+               ath5k_beaconq_config(sc);
+
+               sc->imask |= AR5K_INT_SWBA;
+
+               if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+                       if (ath5k_hw_hasveol(ah)) {
+                               spin_lock_irqsave(&sc->block, flags);
+                               ath5k_beacon_send(sc);
+                               spin_unlock_irqrestore(&sc->block, flags);
+                       }
+               } else
+                       ath5k_beacon_update_timers(sc, -1);
+       }
+
+       ath5k_hw_set_imr(ah, sc->imask);
+}
+
+
+/********************\
+* Interrupt handling *
+\********************/
+
+static int
+ath5k_init(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       int ret, i;
+
+       mutex_lock(&sc->lock);
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
+
+       /*
+        * Stop anything previously setup.  This is safe
+        * no matter this is the first time through or not.
+        */
+       ath5k_stop_locked(sc);
+
+       /*
+        * 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.
+        */
+       sc->curchan = sc->hw->conf.channel;
+       sc->curband = &sc->sbands[sc->curchan->band];
+       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
+               AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
+               AR5K_INT_FATAL | AR5K_INT_GLOBAL;
+       ret = ath5k_reset(sc, false, false);
+       if (ret)
+               goto done;
+
+       /*
+        * Reset the key cache since some parts do not reset the
+        * contents on initial power up or resume from suspend.
+        */
+       for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
+               ath5k_hw_reset_key(ah, i);
+
+       /* Set ack to be sent at low bit-rates */
+       ath5k_hw_set_ack_bitrate_high(ah, false);
+
+       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
+                       msecs_to_jiffies(ath5k_calinterval * 1000)));
+
+       ret = 0;
+done:
+       mmiowb();
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
+static int
+ath5k_stop_locked(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
+                       test_bit(ATH_STAT_INVALID, sc->status));
+
+       /*
+        * Shutdown the hardware and driver:
+        *    stop output from above
+        *    disable interrupts
+        *    turn off timers
+        *    turn off the radio
+        *    clear transmit machinery
+        *    clear receive machinery
+        *    drain and release tx queues
+        *    reclaim beacon resources
+        *    power down hardware
+        *
+        * Note that some of this work is not possible if the
+        * hardware is gone (invalid).
+        */
+       ieee80211_stop_queues(sc->hw);
+
+       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
+               ath5k_led_off(sc);
+               ath5k_hw_set_imr(ah, 0);
+               synchronize_irq(sc->pdev->irq);
+       }
+       ath5k_txq_cleanup(sc);
+       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
+               ath5k_rx_stop(sc);
+               ath5k_hw_phy_disable(ah);
+       } else
+               sc->rxlink = NULL;
+
+       return 0;
+}
+
+/*
+ * Stop the device, grabbing the top-level lock to protect
+ * against concurrent entry through ath5k_init (which can happen
+ * if another thread does a system call and the thread doing the
+ * stop is preempted).
+ */
+static int
+ath5k_stop_hw(struct ath5k_softc *sc)
+{
+       int ret;
+
+       mutex_lock(&sc->lock);
+       ret = ath5k_stop_locked(sc);
+       if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
+               /*
+                * Set the chip in full sleep mode.  Note that we are
+                * careful to do this only when bringing the interface
+                * completely to a stop.  When the chip is in this state
+                * it must be carefully woken up or references to
+                * registers in the PCI clock domain may freeze the bus
+                * (and system).  This varies by chip and is mostly an
+                * issue with newer parts that go to sleep more quickly.
+                */
+               if (sc->ah->ah_mac_srev >= 0x78) {
+                       /*
+                        * XXX
+                        * don't put newer MAC revisions > 7.8 to sleep because
+                        * of the above mentioned problems
+                        */
+                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, "
+                               "not putting device to sleep\n");
+               } else {
+                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+                               "putting device to full sleep\n");
+                       ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0);
+               }
+       }
+       ath5k_txbuf_free(sc, sc->bbuf);
+
+       mmiowb();
+       mutex_unlock(&sc->lock);
+
+       del_timer_sync(&sc->calib_tim);
+       tasklet_kill(&sc->rxtq);
+       tasklet_kill(&sc->txtq);
+       tasklet_kill(&sc->restq);
+       tasklet_kill(&sc->beacontq);
+
+       return ret;
+}
+
+static irqreturn_t
+ath5k_intr(int irq, void *dev_id)
+{
+       struct ath5k_softc *sc = dev_id;
+       struct ath5k_hw *ah = sc->ah;
+       enum ath5k_int status;
+       unsigned int counter = 1000;
+
+       if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
+                               !ath5k_hw_is_intr_pending(ah)))
+               return IRQ_NONE;
+
+       do {
+               ath5k_hw_get_isr(ah, &status);          /* NB: clears IRQ too */
+               ATH5K_DBG(sc, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
+                               status, sc->imask);
+               if (unlikely(status & AR5K_INT_FATAL)) {
+                       /*
+                        * Fatal errors are unrecoverable.
+                        * Typically these are caused by DMA errors.
+                        */
+                       tasklet_schedule(&sc->restq);
+               } else if (unlikely(status & AR5K_INT_RXORN)) {
+                       tasklet_schedule(&sc->restq);
+               } else {
+                       if (status & AR5K_INT_SWBA) {
+                               tasklet_schedule(&sc->beacontq);
+                       }
+                       if (status & AR5K_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.
+                               */
+                               sc->rxlink = NULL;
+                       }
+                       if (status & AR5K_INT_TXURN) {
+                               /* bump tx trigger level */
+                               ath5k_hw_update_tx_triglevel(ah, true);
+                       }
+                       if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
+                               tasklet_schedule(&sc->rxtq);
+                       if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
+                                       | AR5K_INT_TXERR | AR5K_INT_TXEOL))
+                               tasklet_schedule(&sc->txtq);
+                       if (status & AR5K_INT_BMISS) {
+                               /* TODO */
+                       }
+                       if (status & AR5K_INT_MIB) {
+                               /*
+                                * These stats are also used for ANI i think
+                                * so how about updating them more often ?
+                                */
+                               ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
+                       }
+               }
+       } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0);
+
+       if (unlikely(!counter))
+               ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
+
+       return IRQ_HANDLED;
+}
+
+static void
+ath5k_tasklet_reset(unsigned long data)
+{
+       struct ath5k_softc *sc = (void *)data;
+
+       ath5k_reset_wake(sc);
+}
+
+/*
+ * Periodically recalibrate the PHY to account
+ * for temperature/environment changes.
+ */
+static void
+ath5k_calibrate(unsigned long data)
+{
+       struct ath5k_softc *sc = (void *)data;
+       struct ath5k_hw *ah = sc->ah;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
+               ieee80211_frequency_to_channel(sc->curchan->center_freq),
+               sc->curchan->hw_value);
+
+       if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
+               /*
+                * Rfgain is out of bounds, reset the chip
+                * to load new gain values.
+                */
+               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
+               ath5k_reset_wake(sc);
+       }
+       if (ath5k_hw_phy_calibrate(ah, sc->curchan))
+               ATH5K_ERR(sc, "calibration of channel %u failed\n",
+                       ieee80211_frequency_to_channel(
+                               sc->curchan->center_freq));
+
+       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
+                       msecs_to_jiffies(ath5k_calinterval * 1000)));
+}
+
+
+/********************\
+* Mac80211 functions *
+\********************/
+
+static int
+ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_buf *bf;
+       unsigned long flags;
+       int hdrlen;
+       int padsize;
+
+       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
+
+       if (sc->opmode == NL80211_IFTYPE_MONITOR)
+               ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n");
+
+       /*
+        * the hardware expects the header padded to 4 byte boundaries
+        * if this is not the case we add the padding after the header
+        */
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       padsize = ath5k_pad_size(hdrlen);
+       if (padsize) {
+
+               if (skb_headroom(skb) < padsize) {
+                       ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
+                                 " headroom to pad %d\n", hdrlen, padsize);
+                       goto drop_packet;
+               }
+               skb_push(skb, padsize);
+               memmove(skb->data, skb->data+padsize, hdrlen);
+       }
+
+       spin_lock_irqsave(&sc->txbuflock, flags);
+       if (list_empty(&sc->txbuf)) {
+               ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
+               spin_unlock_irqrestore(&sc->txbuflock, flags);
+               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
+               goto drop_packet;
+       }
+       bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
+       list_del(&bf->list);
+       sc->txbuf_len--;
+       if (list_empty(&sc->txbuf))
+               ieee80211_stop_queues(hw);
+       spin_unlock_irqrestore(&sc->txbuflock, flags);
+
+       bf->skb = skb;
+
+       if (ath5k_txbuf_setup(sc, bf)) {
+               bf->skb = NULL;
+               spin_lock_irqsave(&sc->txbuflock, flags);
+               list_add_tail(&bf->list, &sc->txbuf);
+               sc->txbuf_len++;
+               spin_unlock_irqrestore(&sc->txbuflock, flags);
+               goto drop_packet;
+       }
+       return NETDEV_TX_OK;
+
+drop_packet:
+       dev_kfree_skb_any(skb);
+       return NETDEV_TX_OK;
+}
+
+static int
+ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
+{
+       struct ath5k_hw *ah = sc->ah;
+       int ret;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
+
+       if (stop) {
+               ath5k_hw_set_imr(ah, 0);
+               ath5k_txq_cleanup(sc);
+               ath5k_rx_stop(sc);
+       }
+       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
+       if (ret) {
+               ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
+               goto err;
+       }
+
+       ret = ath5k_rx_start(sc);
+       if (ret) {
+               ATH5K_ERR(sc, "can't start recv logic\n");
+               goto err;
+       }
+
+       /*
+        * Change channels and update the h/w rate map if we're switching;
+        * e.g. 11a to 11b/g.
+        *
+        * We may be doing a reset in response to an ioctl that changes the
+        * channel so update any state that might change as a result.
+        *
+        * XXX needed?
+        */
+/*     ath5k_chan_change(sc, c); */
+
+       ath5k_beacon_config(sc);
+       /* intrs are enabled by ath5k_beacon_config */
+
+       return 0;
+err:
+       return ret;
+}
+
+static int
+ath5k_reset_wake(struct ath5k_softc *sc)
+{
+       int ret;
+
+       ret = ath5k_reset(sc, true, true);
+       if (!ret)
+               ieee80211_wake_queues(sc->hw);
+
+       return ret;
+}
+
+static int ath5k_start(struct ieee80211_hw *hw)
+{
+       return ath5k_init(hw->priv);
+}
+
+static void ath5k_stop(struct ieee80211_hw *hw)
+{
+       ath5k_stop_hw(hw->priv);
+}
+
+static int ath5k_add_interface(struct ieee80211_hw *hw,
+               struct ieee80211_if_init_conf *conf)
+{
+       struct ath5k_softc *sc = hw->priv;
+       int ret;
+
+       mutex_lock(&sc->lock);
+       if (sc->vif) {
+               ret = 0;
+               goto end;
+       }
+
+       sc->vif = conf->vif;
+
+       switch (conf->type) {
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
+       case NL80211_IFTYPE_MONITOR:
+               sc->opmode = conf->type;
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+               goto end;
+       }
+
+       /* Set to a reasonable value. Note that this will
+        * be set to mac80211's value at ath5k_config(). */
+       sc->bintval = 1000;
+       ath5k_hw_set_lladdr(sc->ah, conf->mac_addr);
+
+       ret = 0;
+end:
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
+static void
+ath5k_remove_interface(struct ieee80211_hw *hw,
+                       struct ieee80211_if_init_conf *conf)
+{
+       struct ath5k_softc *sc = hw->priv;
+       u8 mac[ETH_ALEN] = {};
+
+       mutex_lock(&sc->lock);
+       if (sc->vif != conf->vif)
+               goto end;
+
+       ath5k_hw_set_lladdr(sc->ah, mac);
+       sc->vif = NULL;
+end:
+       mutex_unlock(&sc->lock);
+}
+
+/*
+ * TODO: Phy disable/diversity etc
+ */
+static int
+ath5k_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
+       int ret;
+
+       mutex_lock(&sc->lock);
+
+       sc->bintval = conf->beacon_int;
+       sc->power_level = conf->power_level;
+
+       ret = ath5k_chan_set(sc, conf->channel);
+
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
+static int
+ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                       struct ieee80211_if_conf *conf)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       int ret = 0;
+
+       mutex_lock(&sc->lock);
+       if (sc->vif != vif) {
+               ret = -EIO;
+               goto unlock;
+       }
+       if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
+               /* Cache for later use during resets */
+               memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
+               /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
+                * a clean way of letting us retrieve this yet. */
+               ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+               mmiowb();
+       }
+       if (conf->changed & IEEE80211_IFCC_BEACON &&
+                       (vif->type == NL80211_IFTYPE_ADHOC ||
+                        vif->type == NL80211_IFTYPE_MESH_POINT ||
+                        vif->type == NL80211_IFTYPE_AP)) {
+               struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+               if (!beacon) {
+                       ret = -ENOMEM;
+                       goto unlock;
+               }
+               ath5k_beacon_update(sc, beacon);
+       }
+
+unlock:
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
+#define SUPPORTED_FIF_FLAGS \
+       FIF_PROMISC_IN_BSS |  FIF_ALLMULTI | FIF_FCSFAIL | \
+       FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
+       FIF_BCN_PRBRESP_PROMISC
+/*
+ * o always accept unicast, broadcast, and multicast traffic
+ * o multicast traffic for all BSSIDs will be enabled if mac80211
+ *   says it should be
+ * o maintain current state of phy ofdm or phy cck error reception.
+ *   If the hardware detects any of these type of errors then
+ *   ath5k_hw_get_rx_filter() will pass to us the respective
+ *   hardware filters to be able to receive these type of frames.
+ * 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 scanning
+ */
+static void ath5k_configure_filter(struct ieee80211_hw *hw,
+               unsigned int changed_flags,
+               unsigned int *new_flags,
+               int mc_count, struct dev_mc_list *mclist)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       u32 mfilt[2], val, rfilt;
+       u8 pos;
+       int i;
+
+       mfilt[0] = 0;
+       mfilt[1] = 0;
+
+       /* Only deal with supported flags */
+       changed_flags &= SUPPORTED_FIF_FLAGS;
+       *new_flags &= SUPPORTED_FIF_FLAGS;
+
+       /* If HW detects any phy or radar errors, leave those filters on.
+        * Also, always enable Unicast, Broadcasts and Multicast
+        * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
+       rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
+               (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
+               AR5K_RX_FILTER_MCAST);
+
+       if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
+               if (*new_flags & FIF_PROMISC_IN_BSS) {
+                       rfilt |= AR5K_RX_FILTER_PROM;
+                       __set_bit(ATH_STAT_PROMISC, sc->status);
+               } else {
+                       __clear_bit(ATH_STAT_PROMISC, sc->status);
+               }
+       }
+
+       /* Note, AR5K_RX_FILTER_MCAST is already enabled */
+       if (*new_flags & FIF_ALLMULTI) {
+               mfilt[0] =  ~0;
+               mfilt[1] =  ~0;
+       } else {
+               for (i = 0; i < mc_count; i++) {
+                       if (!mclist)
+                               break;
+                       /* calculate XOR of eight 6-bit values */
+                       val = get_unaligned_le32(mclist->dmi_addr + 0);
+                       pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+                       val = get_unaligned_le32(mclist->dmi_addr + 3);
+                       pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+                       pos &= 0x3f;
+                       mfilt[pos / 32] |= (1 << (pos % 32));
+                       /* XXX: we might be able to just do this instead,
+                       * but not sure, needs testing, if we do use this we'd
+                       * neet to inform below to not reset the mcast */
+                       /* ath5k_hw_set_mcast_filterindex(ah,
+                        *      mclist->dmi_addr[5]); */
+                       mclist = mclist->next;
+               }
+       }
+
+       /* This is the best we can do */
+       if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
+               rfilt |= AR5K_RX_FILTER_PHYERR;
+
+       /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
+       * and probes for any BSSID, this needs testing */
+       if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
+               rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ;
+
+       /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
+        * set we should only pass on control frames for this
+        * station. This needs testing. I believe right now this
+        * enables *all* control frames, which is OK.. but
+        * but we should see if we can improve on granularity */
+       if (*new_flags & FIF_CONTROL)
+               rfilt |= AR5K_RX_FILTER_CONTROL;
+
+       /* Additional settings per mode -- this is per ath5k */
+
+       /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
+
+       if (sc->opmode == NL80211_IFTYPE_MONITOR)
+               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
+                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
+       if (sc->opmode != NL80211_IFTYPE_STATION)
+               rfilt |= AR5K_RX_FILTER_PROBEREQ;
+       if (sc->opmode != NL80211_IFTYPE_AP &&
+               sc->opmode != NL80211_IFTYPE_MESH_POINT &&
+               test_bit(ATH_STAT_PROMISC, sc->status))
+               rfilt |= AR5K_RX_FILTER_PROM;
+       if ((sc->opmode == NL80211_IFTYPE_STATION && sc->assoc) ||
+               sc->opmode == NL80211_IFTYPE_ADHOC ||
+               sc->opmode == NL80211_IFTYPE_AP)
+               rfilt |= AR5K_RX_FILTER_BEACON;
+       if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
+               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
+                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
+
+       /* Set filters */
+       ath5k_hw_set_rx_filter(ah, rfilt);
+
+       /* Set multicast bits */
+       ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
+       /* Set the cached hw filter flags, this will alter actually
+        * be set in HW */
+       sc->filter_flags = rfilt;
+}
+
+static int
+ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+             struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+             struct ieee80211_key_conf *key)
+{
+       struct ath5k_softc *sc = hw->priv;
+       int ret = 0;
+
+       if (modparam_nohwcrypt)
+               return -EOPNOTSUPP;
+
+       switch (key->alg) {
+       case ALG_WEP:
+       case ALG_TKIP:
+               break;
+       case ALG_CCMP:
+               return -EOPNOTSUPP;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       mutex_lock(&sc->lock);
+
+       switch (cmd) {
+       case SET_KEY:
+               ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
+                                      sta ? sta->addr : NULL);
+               if (ret) {
+                       ATH5K_ERR(sc, "can't set the key\n");
+                       goto unlock;
+               }
+               __set_bit(key->keyidx, sc->keymap);
+               key->hw_key_idx = key->keyidx;
+               key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
+                              IEEE80211_KEY_FLAG_GENERATE_MMIC);
+               break;
+       case DISABLE_KEY:
+               ath5k_hw_reset_key(sc->ah, key->keyidx);
+               __clear_bit(key->keyidx, sc->keymap);
+               break;
+       default:
+               ret = -EINVAL;
+               goto unlock;
+       }
+
+unlock:
+       mmiowb();
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
+static int
+ath5k_get_stats(struct ieee80211_hw *hw,
+               struct ieee80211_low_level_stats *stats)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+
+       /* Force update */
+       ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
+
+       memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats));
+
+       return 0;
+}
+
+static int
+ath5k_get_tx_stats(struct ieee80211_hw *hw,
+               struct ieee80211_tx_queue_stats *stats)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats));
+
+       return 0;
+}
+
+static u64
+ath5k_get_tsf(struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       return ath5k_hw_get_tsf64(sc->ah);
+}
+
+static void
+ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       ath5k_hw_set_tsf64(sc->ah, tsf);
+}
+
+static void
+ath5k_reset_tsf(struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       /*
+        * in IBSS mode we need to update the beacon timers too.
+        * this will also reset the TSF if we call it with 0
+        */
+       if (sc->opmode == NL80211_IFTYPE_ADHOC)
+               ath5k_beacon_update_timers(sc, 0);
+       else
+               ath5k_hw_reset_tsf(sc->ah);
+}
+
+static int
+ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb)
+{
+       unsigned long flags;
+       int ret;
+
+       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
+
+       spin_lock_irqsave(&sc->block, flags);
+       ath5k_txbuf_free(sc, sc->bbuf);
+       sc->bbuf->skb = skb;
+       ret = ath5k_beacon_setup(sc, sc->bbuf);
+       if (ret)
+               sc->bbuf->skb = NULL;
+       spin_unlock_irqrestore(&sc->block, flags);
+       if (!ret) {
+               ath5k_beacon_config(sc);
+               mmiowb();
+       }
+
+       return ret;
+}
+static void
+set_beacon_filter(struct ieee80211_hw *hw, bool enable)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       u32 rfilt;
+       rfilt = ath5k_hw_get_rx_filter(ah);
+       if (enable)
+               rfilt |= AR5K_RX_FILTER_BEACON;
+       else
+               rfilt &= ~AR5K_RX_FILTER_BEACON;
+       ath5k_hw_set_rx_filter(ah, rfilt);
+       sc->filter_flags = rfilt;
+}
+
+static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+                                   struct ieee80211_bss_conf *bss_conf,
+                                   u32 changes)
+{
+       struct ath5k_softc *sc = hw->priv;
+       if (changes & BSS_CHANGED_ASSOC) {
+               mutex_lock(&sc->lock);
+               sc->assoc = bss_conf->assoc;
+               if (sc->opmode == NL80211_IFTYPE_STATION)
+                       set_beacon_filter(hw, sc->assoc);
+               mutex_unlock(&sc->lock);
+       }
+}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
new file mode 100644 (file)
index 0000000..8229561
--- /dev/null
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+/*
+ * Defintions for the Atheros Wireless LAN controller driver.
+ */
+#ifndef _DEV_ATH_ATHVAR_H
+#define _DEV_ATH_ATHVAR_H
+
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/wireless.h>
+#include <linux/if_ether.h>
+#include <linux/leds.h>
+
+#include "ath5k.h"
+#include "debug.h"
+
+#define        ATH_RXBUF       40              /* number of RX buffers */
+#define        ATH_TXBUF       200             /* number of TX buffers */
+#define ATH_BCBUF      1               /* number of beacon buffers */
+
+struct ath5k_buf {
+       struct list_head        list;
+       unsigned int            flags;  /* rx descriptor flags */
+       struct ath5k_desc       *desc;  /* virtual addr of desc */
+       dma_addr_t              daddr;  /* physical addr of desc */
+       struct sk_buff          *skb;   /* skbuff for buf */
+       dma_addr_t              skbaddr;/* physical addr of skb data */
+};
+
+/*
+ * 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 ath5k_txq {
+       unsigned int            qnum;   /* hardware q number */
+       u32                     *link;  /* link ptr in last TX desc */
+       struct list_head        q;      /* transmit queue */
+       spinlock_t              lock;   /* lock on q and link */
+       bool                    setup;
+};
+
+#define ATH5K_LED_MAX_NAME_LEN 31
+
+/*
+ * State for LED triggers
+ */
+struct ath5k_led
+{
+       char name[ATH5K_LED_MAX_NAME_LEN + 1];  /* name of the LED in sysfs */
+       struct ath5k_softc *sc;                 /* driver state */
+       struct led_classdev led_dev;            /* led classdev */
+};
+
+
+#if CHAN_DEBUG
+#define ATH_CHAN_MAX   (26+26+26+200+200)
+#else
+#define ATH_CHAN_MAX   (14+14+14+252+20)
+#endif
+
+/* Software Carrier, keeps track of the driver state
+ * associated with an instance of a device */
+struct ath5k_softc {
+       struct pci_dev          *pdev;          /* for dma mapping */
+       void __iomem            *iobase;        /* address of the device */
+       struct mutex            lock;           /* dev-level lock */
+       /* FIXME: how many does it really need? */
+       struct ieee80211_tx_queue_stats tx_stats[16];
+       struct ieee80211_low_level_stats ll_stats;
+       struct ieee80211_hw     *hw;            /* IEEE 802.11 common */
+       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+       struct ieee80211_channel channels[ATH_CHAN_MAX];
+       struct ieee80211_rate   rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
+       s8                      rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
+       enum nl80211_iftype     opmode;
+       struct ath5k_hw         *ah;            /* Atheros HW */
+
+       struct ieee80211_supported_band         *curband;
+
+#ifdef CONFIG_ATH5K_DEBUG
+       struct ath5k_dbg_info   debug;          /* debug info */
+#endif /* CONFIG_ATH5K_DEBUG */
+
+       struct ath5k_buf        *bufptr;        /* allocated buffer ptr */
+       struct ath5k_desc       *desc;          /* TX/RX descriptors */
+       dma_addr_t              desc_daddr;     /* DMA (physical) address */
+       size_t                  desc_len;       /* size of TX/RX descriptors */
+       u16                     cachelsz;       /* cache line size */
+
+       DECLARE_BITMAP(status, 5);
+#define ATH_STAT_INVALID       0               /* disable hardware accesses */
+#define ATH_STAT_MRRETRY       1               /* multi-rate retry support */
+#define ATH_STAT_PROMISC       2
+#define ATH_STAT_LEDSOFT       3               /* enable LED gpio status */
+#define ATH_STAT_STARTED       4               /* opened & irqs enabled */
+
+       unsigned int            filter_flags;   /* HW flags, AR5K_RX_FILTER_* */
+       unsigned int            curmode;        /* current phy mode */
+       struct ieee80211_channel *curchan;      /* current h/w channel */
+
+       struct ieee80211_vif *vif;
+
+       enum ath5k_int          imask;          /* interrupt mask copy */
+
+       DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
+
+       u8                      bssidmask[ETH_ALEN];
+
+       unsigned int            led_pin,        /* GPIO pin for driving LED */
+                               led_on;         /* pin setting for LED on */
+
+       struct tasklet_struct   restq;          /* reset tasklet */
+
+       unsigned int            rxbufsize;      /* rx size based on mtu */
+       struct list_head        rxbuf;          /* receive buffer */
+       spinlock_t              rxbuflock;
+       u32                     *rxlink;        /* link ptr in last RX desc */
+       struct tasklet_struct   rxtq;           /* rx intr tasklet */
+       struct ath5k_led        rx_led;         /* rx led */
+
+       struct list_head        txbuf;          /* transmit buffer */
+       spinlock_t              txbuflock;
+       unsigned int            txbuf_len;      /* buf count in txbuf list */
+       struct ath5k_txq        txqs[2];        /* beacon and tx */
+
+       struct ath5k_txq        *txq;           /* beacon and tx*/
+       struct tasklet_struct   txtq;           /* tx intr tasklet */
+       struct ath5k_led        tx_led;         /* tx led */
+
+       spinlock_t              block;          /* protects beacon */
+       struct tasklet_struct   beacontq;       /* beacon intr tasklet */
+       struct ath5k_buf        *bbuf;          /* beacon buffer */
+       unsigned int            bhalq,          /* SW q for outgoing beacons */
+                               bmisscount,     /* missed beacon transmits */
+                               bintval,        /* beacon interval in TU */
+                               bsent;
+       unsigned int            nexttbtt;       /* next beacon time in TU */
+
+       struct timer_list       calib_tim;      /* calibration timer */
+       int                     power_level;    /* Requested tx power in dbm */
+       bool                    assoc;          /* assocate state */
+};
+
+#define ath5k_hw_hasbssidmask(_ah) \
+       (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0)
+#define ath5k_hw_hasveol(_ah) \
+       (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
+
+#endif
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
new file mode 100644 (file)
index 0000000..367a6c7
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/**************\
+* Capabilities *
+\**************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Fill the capabilities struct
+ * TODO: Merge this with EEPROM code when we are done with it
+ */
+int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
+{
+       u16 ee_header;
+
+       ATH5K_TRACE(ah->ah_sc);
+       /* Capabilities stored in the EEPROM */
+       ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
+
+       if (ah->ah_version == AR5K_AR5210) {
+               /*
+                * Set radio capabilities
+                * (The AR5110 only supports the middle 5GHz band)
+                */
+               ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
+               ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
+               ah->ah_capabilities.cap_range.range_2ghz_min = 0;
+               ah->ah_capabilities.cap_range.range_2ghz_max = 0;
+
+               /* Set supported modes */
+               __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
+               __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
+       } else {
+               /*
+                * XXX The tranceiver supports frequencies from 4920 to 6100GHz
+                * XXX and from 2312 to 2732GHz. There are problems with the
+                * XXX current ieee80211 implementation because the IEEE
+                * XXX channel mapping does not support negative channel
+                * XXX numbers (2312MHz is channel -19). Of course, this
+                * XXX doesn't matter because these channels are out of range
+                * XXX but some regulation domains like MKK (Japan) will
+                * XXX support frequencies somewhere around 4.8GHz.
+                */
+
+               /*
+                * Set radio capabilities
+                */
+
+               if (AR5K_EEPROM_HDR_11A(ee_header)) {
+                       /* 4920 */
+                       ah->ah_capabilities.cap_range.range_5ghz_min = 5005;
+                       ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
+
+                       /* Set supported modes */
+                       __set_bit(AR5K_MODE_11A,
+                                       ah->ah_capabilities.cap_mode);
+                       __set_bit(AR5K_MODE_11A_TURBO,
+                                       ah->ah_capabilities.cap_mode);
+                       if (ah->ah_version == AR5K_AR5212)
+                               __set_bit(AR5K_MODE_11G_TURBO,
+                                               ah->ah_capabilities.cap_mode);
+               }
+
+               /* Enable  802.11b if a 2GHz capable radio (2111/5112) is
+                * connected */
+               if (AR5K_EEPROM_HDR_11B(ee_header) ||
+                   (AR5K_EEPROM_HDR_11G(ee_header) &&
+                    ah->ah_version != AR5K_AR5211)) {
+                       /* 2312 */
+                       ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
+                       ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
+
+                       if (AR5K_EEPROM_HDR_11B(ee_header))
+                               __set_bit(AR5K_MODE_11B,
+                                               ah->ah_capabilities.cap_mode);
+
+                       if (AR5K_EEPROM_HDR_11G(ee_header) &&
+                           ah->ah_version != AR5K_AR5211)
+                               __set_bit(AR5K_MODE_11G,
+                                               ah->ah_capabilities.cap_mode);
+               }
+       }
+
+       /* GPIO */
+       ah->ah_gpio_npins = AR5K_NUM_GPIO;
+
+       /* Set number of supported TX queues */
+       if (ah->ah_version == AR5K_AR5210)
+               ah->ah_capabilities.cap_queues.q_tx_num =
+                       AR5K_NUM_TX_QUEUES_NOQCU;
+       else
+               ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
+
+       return 0;
+}
+
+/* Main function used by the driver part to check caps */
+int ath5k_hw_get_capability(struct ath5k_hw *ah,
+               enum ath5k_capability_type cap_type,
+               u32 capability, u32 *result)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       switch (cap_type) {
+       case AR5K_CAP_NUM_TXQUEUES:
+               if (result) {
+                       if (ah->ah_version == AR5K_AR5210)
+                               *result = AR5K_NUM_TX_QUEUES_NOQCU;
+                       else
+                               *result = AR5K_NUM_TX_QUEUES;
+                       goto yes;
+               }
+       case AR5K_CAP_VEOL:
+               goto yes;
+       case AR5K_CAP_COMPRESSION:
+               if (ah->ah_version == AR5K_AR5212)
+                       goto yes;
+               else
+                       goto no;
+       case AR5K_CAP_BURST:
+               goto yes;
+       case AR5K_CAP_TPC:
+               goto yes;
+       case AR5K_CAP_BSSIDMASK:
+               if (ah->ah_version == AR5K_AR5212)
+                       goto yes;
+               else
+                       goto no;
+       case AR5K_CAP_XR:
+               if (ah->ah_version == AR5K_AR5212)
+                       goto yes;
+               else
+                       goto no;
+       default:
+               goto no;
+       }
+
+no:
+       return -EINVAL;
+yes:
+       return 0;
+}
+
+/*
+ * TODO: Following functions should be part of a new function
+ * set_capability
+ */
+
+int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
+               u16 assoc_id)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_version == AR5K_AR5210) {
+               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
+                       AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
+               return 0;
+       }
+
+       return -EIO;
+}
+
+int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_version == AR5K_AR5210) {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
+                       AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
+               return 0;
+       }
+
+       return -EIO;
+}
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
new file mode 100644 (file)
index 0000000..9770bb3
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
+ *
+ *  This file is free software: you may copy, redistribute and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation, either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  This file is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2006 Devicescape Software, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "base.h"
+#include "debug.h"
+
+static unsigned int ath5k_debug;
+module_param_named(debug, ath5k_debug, uint, 0);
+
+
+#ifdef CONFIG_ATH5K_DEBUG
+
+#include <linux/seq_file.h>
+#include "reg.h"
+
+static struct dentry *ath5k_global_debugfs;
+
+static int ath5k_debugfs_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+
+/* debugfs: registers */
+
+struct reg {
+       const char *name;
+       int addr;
+};
+
+#define REG_STRUCT_INIT(r) { #r, r }
+
+/* just a few random registers, might want to add more */
+static const struct reg regs[] = {
+       REG_STRUCT_INIT(AR5K_CR),
+       REG_STRUCT_INIT(AR5K_RXDP),
+       REG_STRUCT_INIT(AR5K_CFG),
+       REG_STRUCT_INIT(AR5K_IER),
+       REG_STRUCT_INIT(AR5K_BCR),
+       REG_STRUCT_INIT(AR5K_RTSD0),
+       REG_STRUCT_INIT(AR5K_RTSD1),
+       REG_STRUCT_INIT(AR5K_TXCFG),
+       REG_STRUCT_INIT(AR5K_RXCFG),
+       REG_STRUCT_INIT(AR5K_RXJLA),
+       REG_STRUCT_INIT(AR5K_MIBC),
+       REG_STRUCT_INIT(AR5K_TOPS),
+       REG_STRUCT_INIT(AR5K_RXNOFRM),
+       REG_STRUCT_INIT(AR5K_TXNOFRM),
+       REG_STRUCT_INIT(AR5K_RPGTO),
+       REG_STRUCT_INIT(AR5K_RFCNT),
+       REG_STRUCT_INIT(AR5K_MISC),
+       REG_STRUCT_INIT(AR5K_QCUDCU_CLKGT),
+       REG_STRUCT_INIT(AR5K_ISR),
+       REG_STRUCT_INIT(AR5K_PISR),
+       REG_STRUCT_INIT(AR5K_SISR0),
+       REG_STRUCT_INIT(AR5K_SISR1),
+       REG_STRUCT_INIT(AR5K_SISR2),
+       REG_STRUCT_INIT(AR5K_SISR3),
+       REG_STRUCT_INIT(AR5K_SISR4),
+       REG_STRUCT_INIT(AR5K_IMR),
+       REG_STRUCT_INIT(AR5K_PIMR),
+       REG_STRUCT_INIT(AR5K_SIMR0),
+       REG_STRUCT_INIT(AR5K_SIMR1),
+       REG_STRUCT_INIT(AR5K_SIMR2),
+       REG_STRUCT_INIT(AR5K_SIMR3),
+       REG_STRUCT_INIT(AR5K_SIMR4),
+       REG_STRUCT_INIT(AR5K_DCM_ADDR),
+       REG_STRUCT_INIT(AR5K_DCCFG),
+       REG_STRUCT_INIT(AR5K_CCFG),
+       REG_STRUCT_INIT(AR5K_CPC0),
+       REG_STRUCT_INIT(AR5K_CPC1),
+       REG_STRUCT_INIT(AR5K_CPC2),
+       REG_STRUCT_INIT(AR5K_CPC3),
+       REG_STRUCT_INIT(AR5K_CPCOVF),
+       REG_STRUCT_INIT(AR5K_RESET_CTL),
+       REG_STRUCT_INIT(AR5K_SLEEP_CTL),
+       REG_STRUCT_INIT(AR5K_INTPEND),
+       REG_STRUCT_INIT(AR5K_SFR),
+       REG_STRUCT_INIT(AR5K_PCICFG),
+       REG_STRUCT_INIT(AR5K_GPIOCR),
+       REG_STRUCT_INIT(AR5K_GPIODO),
+       REG_STRUCT_INIT(AR5K_SREV),
+};
+
+static void *reg_start(struct seq_file *seq, loff_t *pos)
+{
+       return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
+}
+
+static void reg_stop(struct seq_file *seq, void *p)
+{
+       /* nothing to do */
+}
+
+static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
+{
+       ++*pos;
+       return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
+}
+
+static int reg_show(struct seq_file *seq, void *p)
+{
+       struct ath5k_softc *sc = seq->private;
+       struct reg *r = p;
+       seq_printf(seq, "%-25s0x%08x\n", r->name,
+               ath5k_hw_reg_read(sc->ah, r->addr));
+       return 0;
+}
+
+static const struct seq_operations register_seq_ops = {
+       .start = reg_start,
+       .next  = reg_next,
+       .stop  = reg_stop,
+       .show  = reg_show
+};
+
+static int open_file_registers(struct inode *inode, struct file *file)
+{
+       struct seq_file *s;
+       int res;
+       res = seq_open(file, &register_seq_ops);
+       if (res == 0) {
+               s = file->private_data;
+               s->private = inode->i_private;
+       }
+       return res;
+}
+
+static const struct file_operations fops_registers = {
+       .open = open_file_registers,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+       .owner = THIS_MODULE,
+};
+
+
+/* debugfs: beacons */
+
+static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
+                                  size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = sc->ah;
+       char buf[500];
+       unsigned int len = 0;
+       unsigned int v;
+       u64 tsf;
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON);
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
+               "AR5K_BEACON", v, v & AR5K_BEACON_PERIOD,
+               (v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S);
+
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n",
+               "AR5K_LAST_TSTP", ath5k_hw_reg_read(sc->ah, AR5K_LAST_TSTP));
+
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n\n",
+               "AR5K_BEACON_CNT", ath5k_hw_reg_read(sc->ah, AR5K_BEACON_CNT));
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER0);
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+               "AR5K_TIMER0 (TBTT)", v, v);
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER1);
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+               "AR5K_TIMER1 (DMA)", v, v >> 3);
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER2);
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+               "AR5K_TIMER2 (SWBA)", v, v >> 3);
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER3);
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+               "AR5K_TIMER3 (ATIM)", v, v);
+
+       tsf = ath5k_hw_get_tsf64(sc->ah);
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "TSF\t\t0x%016llx\tTU: %08x\n",
+               (unsigned long long)tsf, TSF_TO_TU(tsf));
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_beacon(struct file *file,
+                                const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = sc->ah;
+       char buf[20];
+
+       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+               return -EFAULT;
+
+       if (strncmp(buf, "disable", 7) == 0) {
+               AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
+               printk(KERN_INFO "debugfs disable beacons\n");
+       } else if (strncmp(buf, "enable", 6) == 0) {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
+               printk(KERN_INFO "debugfs enable beacons\n");
+       }
+       return count;
+}
+
+static const struct file_operations fops_beacon = {
+       .read = read_file_beacon,
+       .write = write_file_beacon,
+       .open = ath5k_debugfs_open,
+       .owner = THIS_MODULE,
+};
+
+
+/* debugfs: reset */
+
+static ssize_t write_file_reset(struct file *file,
+                                const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       tasklet_schedule(&sc->restq);
+       return count;
+}
+
+static const struct file_operations fops_reset = {
+       .write = write_file_reset,
+       .open = ath5k_debugfs_open,
+       .owner = THIS_MODULE,
+};
+
+
+/* debugfs: debug level */
+
+static const struct {
+       enum ath5k_debug_level level;
+       const char *name;
+       const char *desc;
+} dbg_info[] = {
+       { ATH5K_DEBUG_RESET,    "reset",        "reset and initialization" },
+       { ATH5K_DEBUG_INTR,     "intr",         "interrupt handling" },
+       { ATH5K_DEBUG_MODE,     "mode",         "mode init/setup" },
+       { ATH5K_DEBUG_XMIT,     "xmit",         "basic xmit operation" },
+       { ATH5K_DEBUG_BEACON,   "beacon",       "beacon handling" },
+       { ATH5K_DEBUG_CALIBRATE, "calib",       "periodic calibration" },
+       { ATH5K_DEBUG_TXPOWER,  "txpower",      "transmit power setting" },
+       { ATH5K_DEBUG_LED,      "led",          "LED management" },
+       { ATH5K_DEBUG_DUMP_RX,  "dumprx",       "print received skb content" },
+       { ATH5K_DEBUG_DUMP_TX,  "dumptx",       "print transmit skb content" },
+       { ATH5K_DEBUG_DUMPBANDS, "dumpbands",   "dump bands" },
+       { ATH5K_DEBUG_TRACE,    "trace",        "trace function calls" },
+       { ATH5K_DEBUG_ANY,      "all",          "show all debug levels" },
+};
+
+static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+                                  size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       char buf[700];
+       unsigned int len = 0;
+       unsigned int i;
+
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
+
+       for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
+               len += snprintf(buf+len, sizeof(buf)-len,
+                       "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+                       sc->debug.level & dbg_info[i].level ? '+' : ' ',
+                       dbg_info[i].level, dbg_info[i].desc);
+       }
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+               sc->debug.level == dbg_info[i].level ? '+' : ' ',
+               dbg_info[i].level, dbg_info[i].desc);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_debug(struct file *file,
+                                const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       unsigned int i;
+       char buf[20];
+
+       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+               return -EFAULT;
+
+       for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
+               if (strncmp(buf, dbg_info[i].name,
+                                       strlen(dbg_info[i].name)) == 0) {
+                       sc->debug.level ^= dbg_info[i].level; /* toggle bit */
+                       break;
+               }
+       }
+       return count;
+}
+
+static const struct file_operations fops_debug = {
+       .read = read_file_debug,
+       .write = write_file_debug,
+       .open = ath5k_debugfs_open,
+       .owner = THIS_MODULE,
+};
+
+
+/* init */
+
+void
+ath5k_debug_init(void)
+{
+       ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
+}
+
+void
+ath5k_debug_init_device(struct ath5k_softc *sc)
+{
+       sc->debug.level = ath5k_debug;
+
+       sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
+                               ath5k_global_debugfs);
+
+       sc->debug.debugfs_debug = debugfs_create_file("debug", S_IWUSR | S_IRUGO,
+                               sc->debug.debugfs_phydir, sc, &fops_debug);
+
+       sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO,
+                               sc->debug.debugfs_phydir, sc, &fops_registers);
+
+       sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO,
+                               sc->debug.debugfs_phydir, sc, &fops_beacon);
+
+       sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
+                               sc->debug.debugfs_phydir, sc, &fops_reset);
+}
+
+void
+ath5k_debug_finish(void)
+{
+       debugfs_remove(ath5k_global_debugfs);
+}
+
+void
+ath5k_debug_finish_device(struct ath5k_softc *sc)
+{
+       debugfs_remove(sc->debug.debugfs_debug);
+       debugfs_remove(sc->debug.debugfs_registers);
+       debugfs_remove(sc->debug.debugfs_beacon);
+       debugfs_remove(sc->debug.debugfs_reset);
+       debugfs_remove(sc->debug.debugfs_phydir);
+}
+
+
+/* functions used in other places */
+
+void
+ath5k_debug_dump_bands(struct ath5k_softc *sc)
+{
+       unsigned int b, i;
+
+       if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPBANDS)))
+               return;
+
+       BUG_ON(!sc->sbands);
+
+       for (b = 0; b < IEEE80211_NUM_BANDS; b++) {
+               struct ieee80211_supported_band *band = &sc->sbands[b];
+               char bname[5];
+               switch (band->band) {
+               case IEEE80211_BAND_2GHZ:
+                       strcpy(bname, "2 GHz");
+                       break;
+               case IEEE80211_BAND_5GHZ:
+                       strcpy(bname, "5 GHz");
+                       break;
+               default:
+                       printk(KERN_DEBUG "Band not supported: %d\n",
+                               band->band);
+                       return;
+               }
+               printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname,
+                               band->n_channels, band->n_bitrates);
+               printk(KERN_DEBUG " channels:\n");
+               for (i = 0; i < band->n_channels; i++)
+                       printk(KERN_DEBUG "  %3d %d %.4x %.4x\n",
+                                       ieee80211_frequency_to_channel(
+                                               band->channels[i].center_freq),
+                                       band->channels[i].center_freq,
+                                       band->channels[i].hw_value,
+                                       band->channels[i].flags);
+               printk(KERN_DEBUG " rates:\n");
+               for (i = 0; i < band->n_bitrates; i++)
+                       printk(KERN_DEBUG "  %4d %.4x %.4x %.4x\n",
+                                       band->bitrates[i].bitrate,
+                                       band->bitrates[i].hw_value,
+                                       band->bitrates[i].flags,
+                                       band->bitrates[i].hw_value_short);
+       }
+}
+
+static inline void
+ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
+                      struct ath5k_rx_status *rs)
+{
+       struct ath5k_desc *ds = bf->desc;
+       struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx;
+
+       printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n",
+               ds, (unsigned long long)bf->daddr,
+               ds->ds_link, ds->ds_data,
+               rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1,
+               rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0,
+               !done ? ' ' : (rs->rs_status == 0) ? '*' : '!');
+}
+
+void
+ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
+{
+       struct ath5k_desc *ds;
+       struct ath5k_buf *bf;
+       struct ath5k_rx_status rs = {};
+       int status;
+
+       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
+               return;
+
+       printk(KERN_DEBUG "rx queue %x, link %p\n",
+               ath5k_hw_get_rxdp(ah), sc->rxlink);
+
+       spin_lock_bh(&sc->rxbuflock);
+       list_for_each_entry(bf, &sc->rxbuf, list) {
+               ds = bf->desc;
+               status = ah->ah_proc_rx_desc(ah, ds, &rs);
+               if (!status)
+                       ath5k_debug_printrxbuf(bf, status == 0, &rs);
+       }
+       spin_unlock_bh(&sc->rxbuflock);
+}
+
+void
+ath5k_debug_dump_skb(struct ath5k_softc *sc,
+                       struct sk_buff *skb, const char *prefix, int tx)
+{
+       char buf[16];
+
+       if (likely(!((tx && (sc->debug.level & ATH5K_DEBUG_DUMP_TX)) ||
+                    (!tx && (sc->debug.level & ATH5K_DEBUG_DUMP_RX)))))
+               return;
+
+       snprintf(buf, sizeof(buf), "%s %s", wiphy_name(sc->hw->wiphy), prefix);
+
+       print_hex_dump_bytes(buf, DUMP_PREFIX_NONE, skb->data,
+               min(200U, skb->len));
+
+       printk(KERN_DEBUG "\n");
+}
+
+void
+ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+       struct ath5k_desc *ds = bf->desc;
+       struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212;
+       struct ath5k_tx_status ts = {};
+       int done;
+
+       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
+               return;
+
+       done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
+
+       printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
+               "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
+               ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1,
+               td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3,
+               td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
+               done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
+}
+
+#endif /* ifdef CONFIG_ATH5K_DEBUG */
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
new file mode 100644 (file)
index 0000000..66f69f0
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com>
+ *
+ *  This file is free software: you may copy, redistribute and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation, either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  This file is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2006 Devicescape Software, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef _ATH5K_DEBUG_H
+#define _ATH5K_DEBUG_H
+
+struct ath5k_softc;
+struct ath5k_hw;
+struct sk_buff;
+struct ath5k_buf;
+
+struct ath5k_dbg_info {
+       unsigned int            level;          /* debug level */
+       /* debugfs entries */
+       struct dentry           *debugfs_phydir;
+       struct dentry           *debugfs_debug;
+       struct dentry           *debugfs_registers;
+       struct dentry           *debugfs_beacon;
+       struct dentry           *debugfs_reset;
+};
+
+/**
+ * enum ath5k_debug_level - ath5k debug level
+ *
+ * @ATH5K_DEBUG_RESET: reset processing
+ * @ATH5K_DEBUG_INTR: interrupt handling
+ * @ATH5K_DEBUG_MODE: mode init/setup
+ * @ATH5K_DEBUG_XMIT: basic xmit operation
+ * @ATH5K_DEBUG_BEACON: beacon handling
+ * @ATH5K_DEBUG_CALIBRATE: periodic calibration
+ * @ATH5K_DEBUG_TXPOWER: transmit power setting
+ * @ATH5K_DEBUG_LED: led management
+ * @ATH5K_DEBUG_DUMP_RX: print received skb content
+ * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
+ * @ATH5K_DEBUG_DUMPBANDS: dump bands
+ * @ATH5K_DEBUG_TRACE: trace function calls
+ * @ATH5K_DEBUG_ANY: show at any debug level
+ *
+ * The debug level is used to control the amount and type of debugging output
+ * we want to see. The debug level is given in calls to ATH5K_DBG to specify
+ * where the message should appear, and the user can control the debugging
+ * messages he wants to see, either by the module parameter 'debug' on module
+ * load, or dynamically by using debugfs 'ath5k/phyX/debug'. these levels can
+ * be combined together by bitwise OR.
+ */
+enum ath5k_debug_level {
+       ATH5K_DEBUG_RESET       = 0x00000001,
+       ATH5K_DEBUG_INTR        = 0x00000002,
+       ATH5K_DEBUG_MODE        = 0x00000004,
+       ATH5K_DEBUG_XMIT        = 0x00000008,
+       ATH5K_DEBUG_BEACON      = 0x00000010,
+       ATH5K_DEBUG_CALIBRATE   = 0x00000020,
+       ATH5K_DEBUG_TXPOWER     = 0x00000040,
+       ATH5K_DEBUG_LED         = 0x00000080,
+       ATH5K_DEBUG_DUMP_RX     = 0x00000100,
+       ATH5K_DEBUG_DUMP_TX     = 0x00000200,
+       ATH5K_DEBUG_DUMPBANDS   = 0x00000400,
+       ATH5K_DEBUG_TRACE       = 0x00001000,
+       ATH5K_DEBUG_ANY         = 0xffffffff
+};
+
+#ifdef CONFIG_ATH5K_DEBUG
+
+#define ATH5K_TRACE(_sc) do { \
+       if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \
+               printk(KERN_DEBUG "ath5k trace %s:%d\n", __func__, __LINE__); \
+       } while (0)
+
+#define ATH5K_DBG(_sc, _m, _fmt, ...) do { \
+       if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \
+               ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
+                       __func__, __LINE__, ##__VA_ARGS__); \
+       } while (0)
+
+#define ATH5K_DBG_UNLIMIT(_sc, _m, _fmt, ...) do { \
+       if (unlikely((_sc)->debug.level & (_m))) \
+               ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
+                       __func__, __LINE__, ##__VA_ARGS__); \
+       } while (0)
+
+void
+ath5k_debug_init(void);
+
+void
+ath5k_debug_init_device(struct ath5k_softc *sc);
+
+void
+ath5k_debug_finish(void);
+
+void
+ath5k_debug_finish_device(struct ath5k_softc *sc);
+
+void
+ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
+
+void
+ath5k_debug_dump_bands(struct ath5k_softc *sc);
+
+void
+ath5k_debug_dump_skb(struct ath5k_softc *sc,
+                       struct sk_buff *skb, const char *prefix, int tx);
+
+void
+ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
+
+#else /* no debugging */
+
+#include <linux/compiler.h>
+
+#define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc))
+
+static inline void __attribute__ ((format (printf, 3, 4)))
+ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {}
+
+static inline void __attribute__ ((format (printf, 3, 4)))
+ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
+{}
+
+static inline void
+ath5k_debug_init(void) {}
+
+static inline void
+ath5k_debug_init_device(struct ath5k_softc *sc) {}
+
+static inline void
+ath5k_debug_finish(void) {}
+
+static inline void
+ath5k_debug_finish_device(struct ath5k_softc *sc) {}
+
+static inline void
+ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
+
+static inline void
+ath5k_debug_dump_bands(struct ath5k_softc *sc) {}
+
+static inline void
+ath5k_debug_dump_skb(struct ath5k_softc *sc,
+                       struct sk_buff *skb, const char *prefix, int tx) {}
+
+static inline void
+ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {}
+
+#endif /* ifdef CONFIG_ATH5K_DEBUG */
+
+#endif /* ifndef _ATH5K_DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
new file mode 100644 (file)
index 0000000..dc30a2b
--- /dev/null
@@ -0,0 +1,696 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/******************************\
+ Hardware Descriptor Functions
+\******************************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * TX Descriptors
+ */
+
+/*
+ * Initialize the 2-word tx control descriptor on 5210/5211
+ */
+static int
+ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
+       unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
+       unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
+       unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
+       unsigned int rtscts_rate, unsigned int rtscts_duration)
+{
+       u32 frame_type;
+       struct ath5k_hw_2w_tx_ctl *tx_ctl;
+       unsigned int frame_len;
+
+       tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
+
+       /*
+        * Validate input
+        * - Zero retries don't make sense.
+        * - A zero rate will put the HW into a mode where it continously sends
+        *   noise on the channel, so it is important to avoid this.
+        */
+       if (unlikely(tx_tries0 == 0)) {
+               ATH5K_ERR(ah->ah_sc, "zero retries\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       if (unlikely(tx_rate0 == 0)) {
+               ATH5K_ERR(ah->ah_sc, "zero rate\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       /* Clear descriptor */
+       memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
+
+       /* Setup control descriptor */
+
+       /* Verify and set frame length */
+
+       /* remove padding we might have added before */
+       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
+
+       if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
+               return -EINVAL;
+
+       tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
+
+       /* Verify and set buffer length */
+
+       /* NB: beacon's BufLen must be a multiple of 4 bytes */
+       if (type == AR5K_PKT_TYPE_BEACON)
+               pkt_len = roundup(pkt_len, 4);
+
+       if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
+               return -EINVAL;
+
+       tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
+
+       /*
+        * Verify and set header length
+        * XXX: I only found that on 5210 code, does it work on 5211 ?
+        */
+       if (ah->ah_version == AR5K_AR5210) {
+               if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
+                       return -EINVAL;
+               tx_ctl->tx_control_0 |=
+                       AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
+       }
+
+       /*Diferences between 5210-5211*/
+       if (ah->ah_version == AR5K_AR5210) {
+               switch (type) {
+               case AR5K_PKT_TYPE_BEACON:
+               case AR5K_PKT_TYPE_PROBE_RESP:
+                       frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
+               case AR5K_PKT_TYPE_PIFS:
+                       frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
+               default:
+                       frame_type = type /*<< 2 ?*/;
+               }
+
+               tx_ctl->tx_control_0 |=
+               AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
+               AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
+
+       } else {
+               tx_ctl->tx_control_0 |=
+                       AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
+                       AR5K_REG_SM(antenna_mode,
+                               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
+               tx_ctl->tx_control_1 |=
+                       AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
+       }
+#define _TX_FLAGS(_c, _flag)                                   \
+       if (flags & AR5K_TXDESC_##_flag) {                      \
+               tx_ctl->tx_control_##_c |=                      \
+                       AR5K_2W_TX_DESC_CTL##_c##_##_flag;      \
+       }
+
+       _TX_FLAGS(0, CLRDMASK);
+       _TX_FLAGS(0, VEOL);
+       _TX_FLAGS(0, INTREQ);
+       _TX_FLAGS(0, RTSENA);
+       _TX_FLAGS(1, NOACK);
+
+#undef _TX_FLAGS
+
+       /*
+        * WEP crap
+        */
+       if (key_index != AR5K_TXKEYIX_INVALID) {
+               tx_ctl->tx_control_0 |=
+                       AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
+               tx_ctl->tx_control_1 |=
+                       AR5K_REG_SM(key_index,
+                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
+       }
+
+       /*
+        * RTS/CTS Duration [5210 ?]
+        */
+       if ((ah->ah_version == AR5K_AR5210) &&
+                       (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
+               tx_ctl->tx_control_1 |= rtscts_duration &
+                               AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
+
+       return 0;
+}
+
+/*
+ * Initialize the 4-word tx control descriptor on 5212
+ */
+static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
+       struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
+       enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
+       unsigned int tx_tries0, unsigned int key_index,
+       unsigned int antenna_mode, unsigned int flags,
+       unsigned int rtscts_rate,
+       unsigned int rtscts_duration)
+{
+       struct ath5k_hw_4w_tx_ctl *tx_ctl;
+       unsigned int frame_len;
+
+       ATH5K_TRACE(ah->ah_sc);
+       tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
+
+       /*
+        * Validate input
+        * - Zero retries don't make sense.
+        * - A zero rate will put the HW into a mode where it continously sends
+        *   noise on the channel, so it is important to avoid this.
+        */
+       if (unlikely(tx_tries0 == 0)) {
+               ATH5K_ERR(ah->ah_sc, "zero retries\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       if (unlikely(tx_rate0 == 0)) {
+               ATH5K_ERR(ah->ah_sc, "zero rate\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       tx_power += ah->ah_txpower.txp_offset;
+       if (tx_power > AR5K_TUNE_MAX_TXPOWER)
+               tx_power = AR5K_TUNE_MAX_TXPOWER;
+
+       /* Clear descriptor */
+       memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
+
+       /* Setup control descriptor */
+
+       /* Verify and set frame length */
+
+       /* remove padding we might have added before */
+       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
+
+       if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
+               return -EINVAL;
+
+       tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
+
+       /* Verify and set buffer length */
+
+       /* NB: beacon's BufLen must be a multiple of 4 bytes */
+       if (type == AR5K_PKT_TYPE_BEACON)
+               pkt_len = roundup(pkt_len, 4);
+
+       if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
+               return -EINVAL;
+
+       tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
+
+       tx_ctl->tx_control_0 |=
+               AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
+               AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
+       tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
+                                       AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
+       tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
+                                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
+       tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
+
+#define _TX_FLAGS(_c, _flag)                                   \
+       if (flags & AR5K_TXDESC_##_flag) {                      \
+               tx_ctl->tx_control_##_c |=                      \
+                       AR5K_4W_TX_DESC_CTL##_c##_##_flag;      \
+       }
+
+       _TX_FLAGS(0, CLRDMASK);
+       _TX_FLAGS(0, VEOL);
+       _TX_FLAGS(0, INTREQ);
+       _TX_FLAGS(0, RTSENA);
+       _TX_FLAGS(0, CTSENA);
+       _TX_FLAGS(1, NOACK);
+
+#undef _TX_FLAGS
+
+       /*
+        * WEP crap
+        */
+       if (key_index != AR5K_TXKEYIX_INVALID) {
+               tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
+               tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
+                               AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
+       }
+
+       /*
+        * RTS/CTS
+        */
+       if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
+               if ((flags & AR5K_TXDESC_RTSENA) &&
+                               (flags & AR5K_TXDESC_CTSENA))
+                       return -EINVAL;
+               tx_ctl->tx_control_2 |= rtscts_duration &
+                               AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
+               tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
+                               AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
+       }
+
+       return 0;
+}
+
+/*
+ * Initialize a 4-word multi rate retry tx control descriptor on 5212
+ */
+static int
+ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
+       unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
+       u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
+{
+       struct ath5k_hw_4w_tx_ctl *tx_ctl;
+
+       /*
+        * Rates can be 0 as long as the retry count is 0 too.
+        * A zero rate and nonzero retry count will put the HW into a mode where
+        * it continously sends noise on the channel, so it is important to
+        * avoid this.
+        */
+       if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
+                    (tx_rate2 == 0 && tx_tries2 != 0) ||
+                    (tx_rate3 == 0 && tx_tries3 != 0))) {
+               ATH5K_ERR(ah->ah_sc, "zero rate\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       if (ah->ah_version == AR5K_AR5212) {
+               tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
+
+#define _XTX_TRIES(_n)                                                 \
+       if (tx_tries##_n) {                                             \
+               tx_ctl->tx_control_2 |=                                 \
+                   AR5K_REG_SM(tx_tries##_n,                           \
+                   AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n);               \
+               tx_ctl->tx_control_3 |=                                 \
+                   AR5K_REG_SM(tx_rate##_n,                            \
+                   AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n);                \
+       }
+
+               _XTX_TRIES(1);
+               _XTX_TRIES(2);
+               _XTX_TRIES(3);
+
+#undef _XTX_TRIES
+
+               return 1;
+       }
+
+       return 0;
+}
+
+/* no mrr support for cards older than 5212 */
+static int
+ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
+       unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
+       u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
+{
+       return 0;
+}
+
+/*
+ * Proccess the tx status descriptor on 5210/5211
+ */
+static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc, struct ath5k_tx_status *ts)
+{
+       struct ath5k_hw_2w_tx_ctl *tx_ctl;
+       struct ath5k_hw_tx_status *tx_status;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
+       tx_status = &desc->ud.ds_tx5210.tx_stat;
+
+       /* No frame has been send or error */
+       if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
+               return -EINPROGRESS;
+
+       /*
+        * Get descriptor status
+        */
+       ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
+       ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
+       ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
+       /*TODO: ts->ts_virtcol + test*/
+       ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_SEQ_NUM);
+       ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
+       ts->ts_antenna = 1;
+       ts->ts_status = 0;
+       ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
+               AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
+       ts->ts_retry[0] = ts->ts_longretry;
+       ts->ts_final_idx = 0;
+
+       if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
+               if (tx_status->tx_status_0 &
+                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
+                       ts->ts_status |= AR5K_TXERR_XRETRY;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
+                       ts->ts_status |= AR5K_TXERR_FIFO;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
+                       ts->ts_status |= AR5K_TXERR_FILT;
+       }
+
+       return 0;
+}
+
+/*
+ * Proccess a tx status descriptor on 5212
+ */
+static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc, struct ath5k_tx_status *ts)
+{
+       struct ath5k_hw_4w_tx_ctl *tx_ctl;
+       struct ath5k_hw_tx_status *tx_status;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
+       tx_status = &desc->ud.ds_tx5212.tx_stat;
+
+       /* No frame has been send or error */
+       if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE)))
+               return -EINPROGRESS;
+
+       /*
+        * Get descriptor status
+        */
+       ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
+       ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
+       ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
+       ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_SEQ_NUM);
+       ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
+       ts->ts_antenna = (tx_status->tx_status_1 &
+               AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
+       ts->ts_status = 0;
+
+       ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
+                       AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX);
+
+       /* The longretry counter has the number of un-acked retries
+        * for the final rate. To get the total number of retries
+        * we have to add the retry counters for the other rates
+        * as well
+        */
+       ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
+       switch (ts->ts_final_idx) {
+       case 3:
+               ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
+
+               ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
+                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
+               ts->ts_longretry += ts->ts_retry[2];
+               /* fall through */
+       case 2:
+               ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
+
+               ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
+                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
+               ts->ts_longretry += ts->ts_retry[1];
+               /* fall through */
+       case 1:
+               ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
+
+               ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
+                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
+               ts->ts_longretry += ts->ts_retry[0];
+               /* fall through */
+       case 0:
+               ts->ts_rate[0] = tx_ctl->tx_control_3 &
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
+               break;
+       }
+
+       /* TX error */
+       if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
+               if (tx_status->tx_status_0 &
+                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
+                       ts->ts_status |= AR5K_TXERR_XRETRY;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
+                       ts->ts_status |= AR5K_TXERR_FIFO;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
+                       ts->ts_status |= AR5K_TXERR_FILT;
+       }
+
+       return 0;
+}
+
+/*
+ * RX Descriptors
+ */
+
+/*
+ * Initialize an rx control descriptor
+ */
+static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
+                       u32 size, unsigned int flags)
+{
+       struct ath5k_hw_rx_ctl *rx_ctl;
+
+       ATH5K_TRACE(ah->ah_sc);
+       rx_ctl = &desc->ud.ds_rx.rx_ctl;
+
+       /*
+        * Clear the descriptor
+        * If we don't clean the status descriptor,
+        * while scanning we get too many results,
+        * most of them virtual, after some secs
+        * of scanning system hangs. M.F.
+       */
+       memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
+
+       /* Setup descriptor */
+       rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
+       if (unlikely(rx_ctl->rx_control_1 != size))
+               return -EINVAL;
+
+       if (flags & AR5K_RXDESC_INTREQ)
+               rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
+
+       return 0;
+}
+
+/*
+ * Proccess the rx status descriptor on 5210/5211
+ */
+static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc, struct ath5k_rx_status *rs)
+{
+       struct ath5k_hw_rx_status *rx_status;
+
+       rx_status = &desc->ud.ds_rx.u.rx_stat;
+
+       /* No frame received / not ready */
+       if (unlikely(!(rx_status->rx_status_1 &
+       AR5K_5210_RX_DESC_STATUS1_DONE)))
+               return -EINPROGRESS;
+
+       /*
+        * Frame receive status
+        */
+       rs->rs_datalen = rx_status->rx_status_0 &
+               AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
+       rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
+       rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
+       rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA);
+       rs->rs_more = !!(rx_status->rx_status_0 &
+               AR5K_5210_RX_DESC_STATUS0_MORE);
+       /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
+       rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
+               AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
+       rs->rs_status = 0;
+       rs->rs_phyerr = 0;
+
+       /*
+        * Key table status
+        */
+       if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
+               rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
+                       AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
+       else
+               rs->rs_keyix = AR5K_RXKEYIX_INVALID;
+
+       /*
+        * Receive/descriptor errors
+        */
+       if (!(rx_status->rx_status_1 &
+       AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
+               if (rx_status->rx_status_1 &
+                               AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_CRC;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
+                       rs->rs_status |= AR5K_RXERR_FIFO;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
+                       rs->rs_status |= AR5K_RXERR_PHY;
+                       rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1,
+                               AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
+               }
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_DECRYPT;
+       }
+
+       return 0;
+}
+
+/*
+ * Proccess the rx status descriptor on 5212
+ */
+static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc, struct ath5k_rx_status *rs)
+{
+       struct ath5k_hw_rx_status *rx_status;
+       struct ath5k_hw_rx_error *rx_err;
+
+       ATH5K_TRACE(ah->ah_sc);
+       rx_status = &desc->ud.ds_rx.u.rx_stat;
+
+       /* Overlay on error */
+       rx_err = &desc->ud.ds_rx.u.rx_err;
+
+       /* No frame received / not ready */
+       if (unlikely(!(rx_status->rx_status_1 &
+       AR5K_5212_RX_DESC_STATUS1_DONE)))
+               return -EINPROGRESS;
+
+       /*
+        * Frame receive status
+        */
+       rs->rs_datalen = rx_status->rx_status_0 &
+               AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
+       rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
+       rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
+       rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
+       rs->rs_more = !!(rx_status->rx_status_0 &
+               AR5K_5212_RX_DESC_STATUS0_MORE);
+       rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
+               AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
+       rs->rs_status = 0;
+       rs->rs_phyerr = 0;
+
+       /*
+        * Key table status
+        */
+       if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
+               rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
+                               AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
+       else
+               rs->rs_keyix = AR5K_RXKEYIX_INVALID;
+
+       /*
+        * Receive/descriptor errors
+        */
+       if (!(rx_status->rx_status_1 &
+       AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
+               if (rx_status->rx_status_1 &
+                               AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_CRC;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
+                       rs->rs_status |= AR5K_RXERR_PHY;
+                       rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
+                                          AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
+               }
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_DECRYPT;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_MIC;
+       }
+
+       return 0;
+}
+
+/*
+ * Init function pointers inside ath5k_hw struct
+ */
+int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
+{
+
+       if (ah->ah_version != AR5K_AR5210 &&
+               ah->ah_version != AR5K_AR5211 &&
+               ah->ah_version != AR5K_AR5212)
+                       return -ENOTSUPP;
+
+       /* XXX: What is this magic value and where is it used ? */
+       if (ah->ah_version == AR5K_AR5212)
+               ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
+       else if (ah->ah_version == AR5K_AR5211)
+               ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
+
+       if (ah->ah_version == AR5K_AR5212) {
+               ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
+               ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
+               ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
+               ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
+       } else {
+               ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
+               ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
+               ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
+               ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
+       }
+
+       if (ah->ah_version == AR5K_AR5212)
+               ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
+       else if (ah->ah_version <= AR5K_AR5211)
+               ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
+
+       return 0;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
new file mode 100644 (file)
index 0000000..56158c8
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*
+ * Internal RX/TX descriptor structures
+ * (rX: reserved fields possibily used by future versions of the ar5k chipset)
+ */
+
+/*
+ * common hardware RX control descriptor
+ */
+struct ath5k_hw_rx_ctl {
+       u32     rx_control_0; /* RX control word 0 */
+       u32     rx_control_1; /* RX control word 1 */
+} __packed;
+
+/* RX control word 0 field/sflags */
+#define AR5K_DESC_RX_CTL0                      0x00000000
+
+/* RX control word 1 fields/flags */
+#define AR5K_DESC_RX_CTL1_BUF_LEN              0x00000fff
+#define AR5K_DESC_RX_CTL1_INTREQ               0x00002000
+
+/*
+ * common hardware RX status descriptor
+ * 5210/11 and 5212 differ only in the flags defined below
+ */
+struct ath5k_hw_rx_status {
+       u32     rx_status_0; /* RX status word 0 */
+       u32     rx_status_1; /* RX status word 1 */
+} __packed;
+
+/* 5210/5211 */
+/* RX status word 0 fields/flags */
+#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN             0x00000fff
+#define AR5K_5210_RX_DESC_STATUS0_MORE                 0x00001000
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE         0x00078000
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S       15
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL       0x07f80000
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S     19
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA      0x38000000
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S    27
+
+/* RX status word 1 fields/flags */
+#define AR5K_5210_RX_DESC_STATUS1_DONE                 0x00000001
+#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK     0x00000002
+#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR            0x00000004
+#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN         0x00000008
+#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR    0x00000010
+#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR            0x000000e0
+#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S          5
+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID      0x00000100
+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX            0x00007e00
+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S          9
+#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP    0x0fff8000
+#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S  15
+#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS       0x10000000
+
+/* 5212 */
+/* RX status word 0 fields/flags */
+#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN             0x00000fff
+#define AR5K_5212_RX_DESC_STATUS0_MORE                 0x00001000
+#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR     0x00002000
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE         0x000f8000
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S       15
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL       0x0ff00000
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S     20
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA      0xf0000000
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S    28
+
+/* RX status word 1 fields/flags */
+#define AR5K_5212_RX_DESC_STATUS1_DONE                 0x00000001
+#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK     0x00000002
+#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR            0x00000004
+#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR    0x00000008
+#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR            0x00000010
+#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR            0x00000020
+#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID      0x00000100
+#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX            0x0000fe00
+#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S          9
+#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP    0x7fff0000
+#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S  16
+#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS       0x80000000
+
+/*
+ * common hardware RX error descriptor
+ */
+struct ath5k_hw_rx_error {
+       u32     rx_error_0; /* RX status word 0 */
+       u32     rx_error_1; /* RX status word 1 */
+} __packed;
+
+/* RX error word 0 fields/flags */
+#define AR5K_RX_DESC_ERROR0                    0x00000000
+
+/* RX error word 1 fields/flags */
+#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE     0x0000ff00
+#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S   8
+
+/* PHY Error codes */
+#define AR5K_DESC_RX_PHY_ERROR_NONE            0x00
+#define AR5K_DESC_RX_PHY_ERROR_TIMING          0x20
+#define AR5K_DESC_RX_PHY_ERROR_PARITY          0x40
+#define AR5K_DESC_RX_PHY_ERROR_RATE            0x60
+#define AR5K_DESC_RX_PHY_ERROR_LENGTH          0x80
+#define AR5K_DESC_RX_PHY_ERROR_64QAM           0xa0
+#define AR5K_DESC_RX_PHY_ERROR_SERVICE         0xc0
+#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR     0xe0
+
+/*
+ * 5210/5211 hardware 2-word TX control descriptor
+ */
+struct ath5k_hw_2w_tx_ctl {
+       u32     tx_control_0; /* TX control word 0 */
+       u32     tx_control_1; /* TX control word 1 */
+} __packed;
+
+/* TX control word 0 fields/flags */
+#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN         0x00000fff
+#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN                0x0003f000 /*[5210 ?]*/
+#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S      12
+#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE         0x003c0000
+#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S       18
+#define AR5K_2W_TX_DESC_CTL0_RTSENA            0x00400000
+#define AR5K_2W_TX_DESC_CTL0_CLRDMASK          0x01000000
+#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET       0x00800000 /*[5210]*/
+#define AR5K_2W_TX_DESC_CTL0_VEOL              0x00800000 /*[5211]*/
+#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE                0x1c000000 /*[5210]*/
+#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S      26
+#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210        0x02000000
+#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211        0x1e000000
+
+#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT                     \
+               (ah->ah_version == AR5K_AR5210 ?                \
+               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 :       \
+               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211)
+
+#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S   25
+#define AR5K_2W_TX_DESC_CTL0_INTREQ            0x20000000
+#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
+
+/* TX control word 1 fields/flags */
+#define AR5K_2W_TX_DESC_CTL1_BUF_LEN           0x00000fff
+#define AR5K_2W_TX_DESC_CTL1_MORE              0x00001000
+#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210    0x0007e000
+#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211    0x000fe000
+
+#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX                         \
+                       (ah->ah_version == AR5K_AR5210 ?                \
+                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 :   \
+                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211)
+
+#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S       13
+#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE                0x00700000 /*[5211]*/
+#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S      20
+#define AR5K_2W_TX_DESC_CTL1_NOACK             0x00800000 /*[5211]*/
+#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION      0xfff80000 /*[5210 ?]*/
+
+/* Frame types */
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL   0x00
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM     0x04
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL   0x08
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 0x0c
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS     0x10
+
+/*
+ * 5212 hardware 4-word TX control descriptor
+ */
+struct ath5k_hw_4w_tx_ctl {
+       u32     tx_control_0; /* TX control word 0 */
+
+#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN         0x00000fff
+#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER                0x003f0000
+#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S      16
+#define AR5K_4W_TX_DESC_CTL0_RTSENA            0x00400000
+#define AR5K_4W_TX_DESC_CTL0_VEOL              0x00800000
+#define AR5K_4W_TX_DESC_CTL0_CLRDMASK          0x01000000
+#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT     0x1e000000
+#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S   25
+#define AR5K_4W_TX_DESC_CTL0_INTREQ            0x20000000
+#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
+#define AR5K_4W_TX_DESC_CTL0_CTSENA            0x80000000
+
+       u32     tx_control_1; /* TX control word 1 */
+
+#define AR5K_4W_TX_DESC_CTL1_BUF_LEN           0x00000fff
+#define AR5K_4W_TX_DESC_CTL1_MORE              0x00001000
+#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX 0x000fe000
+#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S       13
+#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE                0x00f00000
+#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S      20
+#define AR5K_4W_TX_DESC_CTL1_NOACK             0x01000000
+#define AR5K_4W_TX_DESC_CTL1_COMP_PROC         0x06000000
+#define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S       25
+#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN       0x18000000
+#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S     27
+#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN      0x60000000
+#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S    29
+
+       u32     tx_control_2; /* TX control word 2 */
+
+#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION              0x00007fff
+#define AR5K_4W_TX_DESC_CTL2_DURATION_UPDATE_ENABLE    0x00008000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0               0x000f0000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S             16
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1               0x00f00000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S             20
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2               0x0f000000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S             24
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3               0xf0000000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S             28
+
+       u32     tx_control_3; /* TX control word 3 */
+
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0                0x0000001f
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1                0x000003e0
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S      5
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2                0x00007c00
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S      10
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3                0x000f8000
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S      15
+#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE      0x01f00000
+#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S    20
+} __packed;
+
+/*
+ * Common TX status descriptor
+ */
+struct ath5k_hw_tx_status {
+       u32     tx_status_0; /* TX status word 0 */
+       u32     tx_status_1; /* TX status word 1 */
+} __packed;
+
+/* TX status word 0 fields/flags */
+#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK     0x00000001
+#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002
+#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN     0x00000004
+#define AR5K_DESC_TX_STATUS0_FILTERED          0x00000008
+/*???
+#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT    0x000000f0
+#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT_S  4
+*/
+#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0
+#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S       4
+/*???
+#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT   0x00000f00
+#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT_S 8
+*/
+#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT  0x00000f00
+#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S        8
+#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT   0x0000f000
+#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT_S 12
+#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP    0xffff0000
+#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S  16
+
+/* TX status word 1 fields/flags */
+#define AR5K_DESC_TX_STATUS1_DONE              0x00000001
+#define AR5K_DESC_TX_STATUS1_SEQ_NUM           0x00001ffe
+#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S         1
+#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH  0x001fe000
+#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S        13
+#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX    0x00600000
+#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S  21
+#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS      0x00800000
+#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA      0x01000000
+
+/*
+ * 5210/5211 hardware TX descriptor
+ */
+struct ath5k_hw_5210_tx_desc {
+       struct ath5k_hw_2w_tx_ctl       tx_ctl;
+       struct ath5k_hw_tx_status       tx_stat;
+} __packed;
+
+/*
+ * 5212 hardware TX descriptor
+ */
+struct ath5k_hw_5212_tx_desc {
+       struct ath5k_hw_4w_tx_ctl       tx_ctl;
+       struct ath5k_hw_tx_status       tx_stat;
+} __packed;
+
+/*
+ * common hardware RX descriptor
+ */
+struct ath5k_hw_all_rx_desc {
+       struct ath5k_hw_rx_ctl                  rx_ctl;
+       union {
+               struct ath5k_hw_rx_status       rx_stat;
+               struct ath5k_hw_rx_error        rx_err;
+       } u;
+} __packed;
+
+/*
+ * Atheros hardware descriptor
+ * This is read and written to by the hardware
+ */
+struct ath5k_desc {
+       u32     ds_link;        /* physical address of the next descriptor */
+       u32     ds_data;        /* physical address of data buffer (skb) */
+
+       union {
+               struct ath5k_hw_5210_tx_desc    ds_tx5210;
+               struct ath5k_hw_5212_tx_desc    ds_tx5212;
+               struct ath5k_hw_all_rx_desc     ds_rx;
+       } ud;
+} __packed;
+
+#define AR5K_RXDESC_INTREQ     0x0020
+
+#define AR5K_TXDESC_CLRDMASK   0x0001
+#define AR5K_TXDESC_NOACK      0x0002  /*[5211+]*/
+#define AR5K_TXDESC_RTSENA     0x0004
+#define AR5K_TXDESC_CTSENA     0x0008
+#define AR5K_TXDESC_INTREQ     0x0010
+#define AR5K_TXDESC_VEOL       0x0020  /*[5211+]*/
+
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
new file mode 100644 (file)
index 0000000..b65b4fe
--- /dev/null
@@ -0,0 +1,705 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*************************************\
+* DMA and interrupt masking functions *
+\*************************************/
+
+/*
+ * dma.c - DMA and interrupt masking functions
+ *
+ * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and
+ * handle queue setup for 5210 chipset (rest are handled on qcu.c).
+ * Also we setup interrupt mask register (IMR) and read the various iterrupt
+ * status registers (ISR).
+ *
+ * TODO: Handle SISR on 5211+ and introduce a function to return the queue
+ * number that resulted the interrupt.
+ */
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*********\
+* Receive *
+\*********/
+
+/**
+ * ath5k_hw_start_rx_dma - Start DMA receive
+ *
+ * @ah:        The &struct ath5k_hw
+ */
+void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
+       ath5k_hw_reg_read(ah, AR5K_CR);
+}
+
+/**
+ * ath5k_hw_stop_rx_dma - Stop DMA receive
+ *
+ * @ah:        The &struct ath5k_hw
+ */
+int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
+{
+       unsigned int i;
+
+       ATH5K_TRACE(ah->ah_sc);
+       ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
+
+       /*
+        * It may take some time to disable the DMA receive unit
+        */
+       for (i = 1000; i > 0 &&
+                       (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
+                       i--)
+               udelay(10);
+
+       return i ? 0 : -EBUSY;
+}
+
+/**
+ * ath5k_hw_get_rxdp - Get RX Descriptor's address
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * XXX: Is RXDP read and clear ?
+ */
+u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
+{
+       return ath5k_hw_reg_read(ah, AR5K_RXDP);
+}
+
+/**
+ * ath5k_hw_set_rxdp - Set RX Descriptor's address
+ *
+ * @ah: The &struct ath5k_hw
+ * @phys_addr: RX descriptor address
+ *
+ * XXX: Should we check if rx is enabled before setting rxdp ?
+ */
+void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
+}
+
+
+/**********\
+* Transmit *
+\**********/
+
+/**
+ * ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue
+ *
+ * @ah: The &struct ath5k_hw
+ * @queue: The hw queue number
+ *
+ * Start DMA transmit for a specific queue and since 5210 doesn't have
+ * QCU/DCU, set up queue parameters for 5210 here based on queue type (one
+ * queue for normal data and one queue for beacons). For queue setup
+ * on newer chips check out qcu.c. Returns -EINVAL if queue number is out
+ * of range or if queue is already disabled.
+ *
+ * NOTE: Must be called after setting up tx control descriptor for that
+ * queue (see below).
+ */
+int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
+{
+       u32 tx_queue;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /* Return if queue is declared inactive */
+       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return -EIO;
+
+       if (ah->ah_version == AR5K_AR5210) {
+               tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
+
+               /*
+                * Set the queue by type on 5210
+                */
+               switch (ah->ah_txq[queue].tqi_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+                       tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
+                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
+                                       AR5K_BSR);
+                       break;
+               case AR5K_TX_QUEUE_CAB:
+                       tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
+                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
+                               AR5K_BCR_BDMAE, AR5K_BSR);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               /* Start queue */
+               ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
+               ath5k_hw_reg_read(ah, AR5K_CR);
+       } else {
+               /* Return if queue is disabled */
+               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
+                       return -EIO;
+
+               /* Start queue */
+               AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
+       }
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue
+ *
+ * @ah: The &struct ath5k_hw
+ * @queue: The hw queue number
+ *
+ * Stop DMA transmit on a specific hw queue and drain queue so we don't
+ * have any pending frames. Returns -EBUSY if we still have pending frames,
+ * -EINVAL if queue number is out of range.
+ *
+ */
+int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
+{
+       unsigned int i = 40;
+       u32 tx_queue, pending;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /* Return if queue is declared inactive */
+       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return -EIO;
+
+       if (ah->ah_version == AR5K_AR5210) {
+               tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
+
+               /*
+                * Set by queue type
+                */
+               switch (ah->ah_txq[queue].tqi_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+               case AR5K_TX_QUEUE_CAB:
+                       /* XXX Fix me... */
+                       tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
+                       ath5k_hw_reg_write(ah, 0, AR5K_BSR);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               /* Stop queue */
+               ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
+               ath5k_hw_reg_read(ah, AR5K_CR);
+       } else {
+               /*
+                * Schedule TX disable and wait until queue is empty
+                */
+               AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
+
+               /*Check for pending frames*/
+               do {
+                       pending = ath5k_hw_reg_read(ah,
+                               AR5K_QUEUE_STATUS(queue)) &
+                               AR5K_QCU_STS_FRMPENDCNT;
+                       udelay(100);
+               } while (--i && pending);
+
+               /* For 2413+ order PCU to drop packets using
+                * QUIET mechanism */
+               if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) &&
+               pending){
+                       /* Set periodicity and duration */
+                       ath5k_hw_reg_write(ah,
+                               AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)|
+                               AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR),
+                               AR5K_QUIET_CTL2);
+
+                       /* Enable quiet period for current TSF */
+                       ath5k_hw_reg_write(ah,
+                               AR5K_QUIET_CTL1_QT_EN |
+                               AR5K_REG_SM(ath5k_hw_reg_read(ah,
+                                               AR5K_TSF_L32_5211) >> 10,
+                                               AR5K_QUIET_CTL1_NEXT_QT_TSF),
+                               AR5K_QUIET_CTL1);
+
+                       /* Force channel idle high */
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
+                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
+
+                       /* Wait a while and disable mechanism */
+                       udelay(200);
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
+                                               AR5K_QUIET_CTL1_QT_EN);
+
+                       /* Re-check for pending frames */
+                       i = 40;
+                       do {
+                               pending = ath5k_hw_reg_read(ah,
+                                       AR5K_QUEUE_STATUS(queue)) &
+                                       AR5K_QCU_STS_FRMPENDCNT;
+                               udelay(100);
+                       } while (--i && pending);
+
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
+                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
+               }
+
+               /* Clear register */
+               ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
+               if (pending)
+                       return -EBUSY;
+       }
+
+       /* TODO: Check for success on 5210 else return error */
+       return 0;
+}
+
+/**
+ * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
+ *
+ * @ah: The &struct ath5k_hw
+ * @queue: The hw queue number
+ *
+ * Get TX descriptor's address for a specific queue. For 5210 we ignore
+ * the queue number and use tx queue type since we only have 2 queues.
+ * We use TXDP0 for normal data queue and TXDP1 for beacon queue.
+ * For newer chips with QCU/DCU we just read the corresponding TXDP register.
+ *
+ * XXX: Is TXDP read and clear ?
+ */
+u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue)
+{
+       u16 tx_reg;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /*
+        * Get the transmit queue descriptor pointer from the selected queue
+        */
+       /*5210 doesn't have QCU*/
+       if (ah->ah_version == AR5K_AR5210) {
+               switch (ah->ah_txq[queue].tqi_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       tx_reg = AR5K_NOQCU_TXDP0;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+               case AR5K_TX_QUEUE_CAB:
+                       tx_reg = AR5K_NOQCU_TXDP1;
+                       break;
+               default:
+                       return 0xffffffff;
+               }
+       } else {
+               tx_reg = AR5K_QUEUE_TXDP(queue);
+       }
+
+       return ath5k_hw_reg_read(ah, tx_reg);
+}
+
+/**
+ * ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue
+ *
+ * @ah: The &struct ath5k_hw
+ * @queue: The hw queue number
+ *
+ * Set TX descriptor's address for a specific queue. For 5210 we ignore
+ * the queue number and we use tx queue type since we only have 2 queues
+ * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue.
+ * For newer chips with QCU/DCU we just set the corresponding TXDP register.
+ * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still
+ * active.
+ */
+int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
+{
+       u16 tx_reg;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /*
+        * Set the transmit queue descriptor pointer register by type
+        * on 5210
+        */
+       if (ah->ah_version == AR5K_AR5210) {
+               switch (ah->ah_txq[queue].tqi_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       tx_reg = AR5K_NOQCU_TXDP0;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+               case AR5K_TX_QUEUE_CAB:
+                       tx_reg = AR5K_NOQCU_TXDP1;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       } else {
+               /*
+                * Set the transmit queue descriptor pointer for
+                * the selected queue on QCU for 5211+
+                * (this won't work if the queue is still active)
+                */
+               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+                       return -EIO;
+
+               tx_reg = AR5K_QUEUE_TXDP(queue);
+       }
+
+       /* Set descriptor pointer */
+       ath5k_hw_reg_write(ah, phys_addr, tx_reg);
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_update_tx_triglevel - Update tx trigger level
+ *
+ * @ah: The &struct ath5k_hw
+ * @increase: Flag to force increase of trigger level
+ *
+ * This function increases/decreases the tx trigger level for the tx fifo
+ * buffer (aka FIFO threshold) that is used to indicate when PCU flushes
+ * the buffer and transmits it's data. Lowering this results sending small
+ * frames more quickly but can lead to tx underruns, raising it a lot can
+ * result other problems (i think bmiss is related). Right now we start with
+ * the lowest possible (64Bytes) and if we get tx underrun we increase it using
+ * the increase flag. Returns -EIO if we have have reached maximum/minimum.
+ *
+ * XXX: Link this with tx DMA size ?
+ * XXX: Use it to save interrupts ?
+ * TODO: Needs testing, i think it's related to bmiss...
+ */
+int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
+{
+       u32 trigger_level, imr;
+       int ret = -EIO;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*
+        * Disable interrupts by setting the mask
+        */
+       imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
+
+       trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
+                       AR5K_TXCFG_TXFULL);
+
+       if (!increase) {
+               if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
+                       goto done;
+       } else
+               trigger_level +=
+                       ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
+
+       /*
+        * Update trigger level on success
+        */
+       if (ah->ah_version == AR5K_AR5210)
+               ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
+       else
+               AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+                               AR5K_TXCFG_TXFULL, trigger_level);
+
+       ret = 0;
+
+done:
+       /*
+        * Restore interrupt mask
+        */
+       ath5k_hw_set_imr(ah, imr);
+
+       return ret;
+}
+
+/*******************\
+* Interrupt masking *
+\*******************/
+
+/**
+ * ath5k_hw_is_intr_pending - Check if we have pending interrupts
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Check if we have pending interrupts to process. Returns 1 if we
+ * have pending interrupts and 0 if we haven't.
+ */
+bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
+}
+
+/**
+ * ath5k_hw_get_isr - Get interrupt status
+ *
+ * @ah: The @struct ath5k_hw
+ * @interrupt_mask: Driver's interrupt mask used to filter out
+ * interrupts in sw.
+ *
+ * This function is used inside our interrupt handler to determine the reason
+ * for the interrupt by reading Primary Interrupt Status Register. Returns an
+ * abstract interrupt status mask which is mostly ISR with some uncommon bits
+ * being mapped on some standard non hw-specific positions
+ * (check out &ath5k_int).
+ *
+ * NOTE: We use read-and-clear register, so after this function is called ISR
+ * is zeroed.
+ */
+int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
+{
+       u32 data;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*
+        * Read interrupt status from the Interrupt Status register
+        * on 5210
+        */
+       if (ah->ah_version == AR5K_AR5210) {
+               data = ath5k_hw_reg_read(ah, AR5K_ISR);
+               if (unlikely(data == AR5K_INT_NOCARD)) {
+                       *interrupt_mask = data;
+                       return -ENODEV;
+               }
+       } else {
+               /*
+                * Read interrupt status from Interrupt
+                * Status Register shadow copy (Read And Clear)
+                *
+                * Note: PISR/SISR Not available on 5210
+                */
+               data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
+               if (unlikely(data == AR5K_INT_NOCARD)) {
+                       *interrupt_mask = data;
+                       return -ENODEV;
+               }
+       }
+
+       /*
+        * Get abstract interrupt mask (driver-compatible)
+        */
+       *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
+
+       if (ah->ah_version != AR5K_AR5210) {
+               u32 sisr2 = ath5k_hw_reg_read(ah, AR5K_RAC_SISR2);
+
+               /*HIU = Host Interface Unit (PCI etc)*/
+               if (unlikely(data & (AR5K_ISR_HIUERR)))
+                       *interrupt_mask |= AR5K_INT_FATAL;
+
+               /*Beacon Not Ready*/
+               if (unlikely(data & (AR5K_ISR_BNR)))
+                       *interrupt_mask |= AR5K_INT_BNR;
+
+               if (unlikely(sisr2 & (AR5K_SISR2_SSERR |
+                                       AR5K_SISR2_DPERR |
+                                       AR5K_SISR2_MCABT)))
+                       *interrupt_mask |= AR5K_INT_FATAL;
+
+               if (data & AR5K_ISR_TIM)
+                       *interrupt_mask |= AR5K_INT_TIM;
+
+               if (data & AR5K_ISR_BCNMISC) {
+                       if (sisr2 & AR5K_SISR2_TIM)
+                               *interrupt_mask |= AR5K_INT_TIM;
+                       if (sisr2 & AR5K_SISR2_DTIM)
+                               *interrupt_mask |= AR5K_INT_DTIM;
+                       if (sisr2 & AR5K_SISR2_DTIM_SYNC)
+                               *interrupt_mask |= AR5K_INT_DTIM_SYNC;
+                       if (sisr2 & AR5K_SISR2_BCN_TIMEOUT)
+                               *interrupt_mask |= AR5K_INT_BCN_TIMEOUT;
+                       if (sisr2 & AR5K_SISR2_CAB_TIMEOUT)
+                               *interrupt_mask |= AR5K_INT_CAB_TIMEOUT;
+               }
+
+               if (data & AR5K_ISR_RXDOPPLER)
+                       *interrupt_mask |= AR5K_INT_RX_DOPPLER;
+               if (data & AR5K_ISR_QCBRORN) {
+                       *interrupt_mask |= AR5K_INT_QCBRORN;
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
+                                       AR5K_SISR3_QCBRORN);
+               }
+               if (data & AR5K_ISR_QCBRURN) {
+                       *interrupt_mask |= AR5K_INT_QCBRURN;
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
+                                       AR5K_SISR3_QCBRURN);
+               }
+               if (data & AR5K_ISR_QTRIG) {
+                       *interrupt_mask |= AR5K_INT_QTRIG;
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR4),
+                                       AR5K_SISR4_QTRIG);
+               }
+
+               if (data & AR5K_ISR_TXOK)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
+                                       AR5K_SISR0_QCU_TXOK);
+
+               if (data & AR5K_ISR_TXDESC)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
+                                       AR5K_SISR0_QCU_TXDESC);
+
+               if (data & AR5K_ISR_TXERR)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
+                                       AR5K_SISR1_QCU_TXERR);
+
+               if (data & AR5K_ISR_TXEOL)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
+                                       AR5K_SISR1_QCU_TXEOL);
+
+               if (data & AR5K_ISR_TXURN)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR2),
+                                       AR5K_SISR2_QCU_TXURN);
+       } else {
+               if (unlikely(data & (AR5K_ISR_SSERR | AR5K_ISR_MCABT
+                               | AR5K_ISR_HIUERR | AR5K_ISR_DPERR)))
+                       *interrupt_mask |= AR5K_INT_FATAL;
+
+               /*
+                * XXX: BMISS interrupts may occur after association.
+                * I found this on 5210 code but it needs testing. If this is
+                * true we should disable them before assoc and re-enable them
+                * after a successful assoc + some jiffies.
+                       interrupt_mask &= ~AR5K_INT_BMISS;
+                */
+       }
+
+       /*
+        * In case we didn't handle anything,
+        * print the register value.
+        */
+       if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
+               ATH5K_PRINTF("ISR: 0x%08x IMR: 0x%08x\n", data, ah->ah_imr);
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_set_imr - Set interrupt mask
+ *
+ * @ah: The &struct ath5k_hw
+ * @new_mask: The new interrupt mask to be set
+ *
+ * Set the interrupt mask in hw to save interrupts. We do that by mapping
+ * ath5k_int bits to hw-specific bits to remove abstraction and writing
+ * Interrupt Mask Register.
+ */
+enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
+{
+       enum ath5k_int old_mask, int_mask;
+
+       old_mask = ah->ah_imr;
+
+       /*
+        * Disable card interrupts to prevent any race conditions
+        * (they will be re-enabled afterwards if AR5K_INT GLOBAL
+        * is set again on the new mask).
+        */
+       if (old_mask & AR5K_INT_GLOBAL) {
+               ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
+               ath5k_hw_reg_read(ah, AR5K_IER);
+       }
+
+       /*
+        * Add additional, chipset-dependent interrupt mask flags
+        * and write them to the IMR (interrupt mask register).
+        */
+       int_mask = new_mask & AR5K_INT_COMMON;
+
+       if (ah->ah_version != AR5K_AR5210) {
+               /* Preserve per queue TXURN interrupt mask */
+               u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2)
+                               & AR5K_SIMR2_QCU_TXURN;
+
+               if (new_mask & AR5K_INT_FATAL) {
+                       int_mask |= AR5K_IMR_HIUERR;
+                       simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR
+                               | AR5K_SIMR2_DPERR);
+               }
+
+               /*Beacon Not Ready*/
+               if (new_mask & AR5K_INT_BNR)
+                       int_mask |= AR5K_INT_BNR;
+
+               if (new_mask & AR5K_INT_TIM)
+                       int_mask |= AR5K_IMR_TIM;
+
+               if (new_mask & AR5K_INT_TIM)
+                       simr2 |= AR5K_SISR2_TIM;
+               if (new_mask & AR5K_INT_DTIM)
+                       simr2 |= AR5K_SISR2_DTIM;
+               if (new_mask & AR5K_INT_DTIM_SYNC)
+                       simr2 |= AR5K_SISR2_DTIM_SYNC;
+               if (new_mask & AR5K_INT_BCN_TIMEOUT)
+                       simr2 |= AR5K_SISR2_BCN_TIMEOUT;
+               if (new_mask & AR5K_INT_CAB_TIMEOUT)
+                       simr2 |= AR5K_SISR2_CAB_TIMEOUT;
+
+               if (new_mask & AR5K_INT_RX_DOPPLER)
+                       int_mask |= AR5K_IMR_RXDOPPLER;
+
+               /* Note: Per queue interrupt masks
+                * are set via reset_tx_queue (qcu.c) */
+               ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
+               ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2);
+
+       } else {
+               if (new_mask & AR5K_INT_FATAL)
+                       int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT
+                               | AR5K_IMR_HIUERR | AR5K_IMR_DPERR);
+
+               ath5k_hw_reg_write(ah, int_mask, AR5K_IMR);
+       }
+
+       /* If RXNOFRM interrupt is masked disable it
+        * by setting AR5K_RXNOFRM to zero */
+       if (!(new_mask & AR5K_INT_RXNOFRM))
+               ath5k_hw_reg_write(ah, 0, AR5K_RXNOFRM);
+
+       /* Store new interrupt mask */
+       ah->ah_imr = new_mask;
+
+       /* ..re-enable interrupts if AR5K_INT_GLOBAL is set */
+       if (new_mask & AR5K_INT_GLOBAL) {
+               ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
+               ath5k_hw_reg_read(ah, AR5K_IER);
+       }
+
+       return old_mask;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
new file mode 100644 (file)
index 0000000..c0fb3b0
--- /dev/null
@@ -0,0 +1,1769 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*************************************\
+* EEPROM access functions and helpers *
+\*************************************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Read from eeprom
+ */
+static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
+{
+       u32 status, timeout;
+
+       ATH5K_TRACE(ah->ah_sc);
+       /*
+        * Initialize EEPROM access
+        */
+       if (ah->ah_version == AR5K_AR5210) {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
+               (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
+       } else {
+               ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
+               AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
+                               AR5K_EEPROM_CMD_READ);
+       }
+
+       for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
+               status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
+               if (status & AR5K_EEPROM_STAT_RDDONE) {
+                       if (status & AR5K_EEPROM_STAT_RDERR)
+                               return -EIO;
+                       *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
+                                       0xffff);
+                       return 0;
+               }
+               udelay(15);
+       }
+
+       return -ETIMEDOUT;
+}
+
+/*
+ * Translate binary channel representation in EEPROM to frequency
+ */
+static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
+                                 unsigned int mode)
+{
+       u16 val;
+
+       if (bin == AR5K_EEPROM_CHANNEL_DIS)
+               return bin;
+
+       if (mode == AR5K_EEPROM_MODE_11A) {
+               if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
+                       val = (5 * bin) + 4800;
+               else
+                       val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
+                               (bin * 10) + 5100;
+       } else {
+               if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
+                       val = bin + 2300;
+               else
+                       val = bin + 2400;
+       }
+
+       return val;
+}
+
+/*
+ * Initialize eeprom & capabilities structs
+ */
+static int
+ath5k_eeprom_init_header(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       int ret;
+       u16 val;
+
+       /*
+        * Read values from EEPROM and store them in the capability structure
+        */
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
+
+       /* Return if we have an old EEPROM */
+       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
+               return 0;
+
+#ifdef notyet
+       /*
+        * Validate the checksum of the EEPROM date. There are some
+        * devices with invalid EEPROMs.
+        */
+       for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
+               AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
+               cksum ^= val;
+       }
+       if (cksum != AR5K_EEPROM_INFO_CKSUM) {
+               ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
+               return -EIO;
+       }
+#endif
+
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
+           ee_ant_gain);
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
+               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
+               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
+
+               /* XXX: Don't know which versions include these two */
+               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
+
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
+
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
+               }
+       }
+
+       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
+               AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
+               ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
+               ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
+
+               AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
+               ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
+               ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
+       }
+
+       return 0;
+}
+
+
+/*
+ * Read antenna infos from eeprom
+ */
+static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
+               unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 o = *offset;
+       u16 val;
+       int ret, i = 0;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_switch_settling[mode]    = (val >> 8) & 0x7f;
+       ee->ee_atn_tx_rx[mode]          = (val >> 2) & 0x3f;
+       ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
+       ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
+       ee->ee_ant_control[mode][i++]   = val & 0x3f;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_ant_control[mode][i++]   = (val >> 10) & 0x3f;
+       ee->ee_ant_control[mode][i++]   = (val >> 4) & 0x3f;
+       ee->ee_ant_control[mode][i]     = (val << 2) & 0x3f;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_ant_control[mode][i++]   |= (val >> 14) & 0x3;
+       ee->ee_ant_control[mode][i++]   = (val >> 8) & 0x3f;
+       ee->ee_ant_control[mode][i++]   = (val >> 2) & 0x3f;
+       ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
+       ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
+       ee->ee_ant_control[mode][i++]   = val & 0x3f;
+
+       /* Get antenna modes */
+       ah->ah_antenna[mode][0] =
+           (ee->ee_ant_control[mode][0] << 4);
+       ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
+            ee->ee_ant_control[mode][1]        |
+           (ee->ee_ant_control[mode][2] << 6)  |
+           (ee->ee_ant_control[mode][3] << 12) |
+           (ee->ee_ant_control[mode][4] << 18) |
+           (ee->ee_ant_control[mode][5] << 24);
+       ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
+            ee->ee_ant_control[mode][6]        |
+           (ee->ee_ant_control[mode][7] << 6)  |
+           (ee->ee_ant_control[mode][8] << 12) |
+           (ee->ee_ant_control[mode][9] << 18) |
+           (ee->ee_ant_control[mode][10] << 24);
+
+       /* return new offset */
+       *offset = o;
+
+       return 0;
+}
+
+/*
+ * Read supported modes and some mode-specific calibration data
+ * from eeprom
+ */
+static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
+               unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 o = *offset;
+       u16 val;
+       int ret;
+
+       ee->ee_n_piers[mode] = 0;
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_adc_desired_size[mode]   = (s8)((val >> 8) & 0xff);
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11A:
+               ee->ee_ob[mode][3]      = (val >> 5) & 0x7;
+               ee->ee_db[mode][3]      = (val >> 2) & 0x7;
+               ee->ee_ob[mode][2]      = (val << 1) & 0x7;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_ob[mode][2]      |= (val >> 15) & 0x1;
+               ee->ee_db[mode][2]      = (val >> 12) & 0x7;
+               ee->ee_ob[mode][1]      = (val >> 9) & 0x7;
+               ee->ee_db[mode][1]      = (val >> 6) & 0x7;
+               ee->ee_ob[mode][0]      = (val >> 3) & 0x7;
+               ee->ee_db[mode][0]      = val & 0x7;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+       case AR5K_EEPROM_MODE_11B:
+               ee->ee_ob[mode][1]      = (val >> 4) & 0x7;
+               ee->ee_db[mode][1]      = val & 0x7;
+               break;
+       }
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
+       ee->ee_thr_62[mode]             = val & 0xff;
+
+       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
+               ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
+       ee->ee_tx_frm2xpa_enable[mode]  = val & 0xff;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_pga_desired_size[mode]   = (val >> 8) & 0xff;
+
+       if ((val & 0xff) & 0x80)
+               ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
+       else
+               ee->ee_noise_floor_thr[mode] = val & 0xff;
+
+       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
+               ee->ee_noise_floor_thr[mode] =
+                   mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_xlna_gain[mode]          = (val >> 5) & 0xff;
+       ee->ee_x_gain[mode]             = (val >> 1) & 0xf;
+       ee->ee_xpd[mode]                = val & 0x1;
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
+               ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
+
+               if (mode == AR5K_EEPROM_MODE_11A)
+                       ee->ee_xr_power[mode] = val & 0x3f;
+               else {
+                       ee->ee_ob[mode][0] = val & 0x7;
+                       ee->ee_db[mode][0] = (val >> 3) & 0x7;
+               }
+       }
+
+       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
+               ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
+               ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
+       } else {
+               ee->ee_i_gain[mode] = (val >> 13) & 0x7;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_i_gain[mode] |= (val << 3) & 0x38;
+
+               if (mode == AR5K_EEPROM_MODE_11G) {
+                       ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
+                       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
+                               ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
+               }
+       }
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
+                       mode == AR5K_EEPROM_MODE_11A) {
+               ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
+               ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
+       }
+
+       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
+               goto done;
+
+       /* Note: >= v5 have bg freq piers on another location
+        * so these freq piers are ignored for >= v5 (should be 0xff
+        * anyway) */
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11A:
+               if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
+                       break;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_margin_tx_rx[mode] = val & 0x3f;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               AR5K_EEPROM_READ(o++, val);
+
+               ee->ee_pwr_cal_b[0].freq =
+                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
+               if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               ee->ee_pwr_cal_b[1].freq =
+                       ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
+               if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_pwr_cal_b[2].freq =
+                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
+               if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+                       ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               AR5K_EEPROM_READ(o++, val);
+
+               ee->ee_pwr_cal_g[0].freq =
+                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
+               if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               ee->ee_pwr_cal_g[1].freq =
+                       ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
+               if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_turbo_max_power[mode] = val & 0x7f;
+               ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_pwr_cal_g[2].freq =
+                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
+               if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+                       ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
+               ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
+
+               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
+                       AR5K_EEPROM_READ(o++, val);
+                       ee->ee_cck_ofdm_gain_delta = val & 0xff;
+               }
+               break;
+       }
+
+done:
+       /* return new offset */
+       *offset = o;
+
+       return 0;
+}
+
+/*
+ * Read turbo mode information on newer EEPROM versions
+ */
+static int
+ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
+                             u32 *offset, unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 o = *offset;
+       u16 val;
+       int ret;
+
+       if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
+               return 0;
+
+       switch (mode){
+       case AR5K_EEPROM_MODE_11A:
+               ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
+
+               ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
+               ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
+
+               ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
+               ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
+
+               if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2)
+                       ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
+
+               ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
+               ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
+
+               ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
+               ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
+               break;
+       }
+
+       /* return new offset */
+       *offset = o;
+
+       return 0;
+}
+
+/* Read mode-specific data (except power calibration data) */
+static int
+ath5k_eeprom_init_modes(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 mode_offset[3];
+       unsigned int mode;
+       u32 offset;
+       int ret;
+
+       /*
+        * Get values for all modes
+        */
+       mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
+       mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
+       mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
+
+       ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] =
+               AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
+
+       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
+               offset = mode_offset[mode];
+
+               ret = ath5k_eeprom_read_ants(ah, &offset, mode);
+               if (ret)
+                       return ret;
+
+               ret = ath5k_eeprom_read_modes(ah, &offset, mode);
+               if (ret)
+                       return ret;
+
+               ret = ath5k_eeprom_read_turbo_modes(ah, &offset, mode);
+               if (ret)
+                       return ret;
+       }
+
+       /* override for older eeprom versions for better performance */
+       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
+               ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15;
+               ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28;
+               ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28;
+       }
+
+       return 0;
+}
+
+/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
+ * frequency mask) */
+static inline int
+ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
+                       struct ath5k_chan_pcal_info *pc, unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       int o = *offset;
+       int i = 0;
+       u8 freq1, freq2;
+       int ret;
+       u16 val;
+
+       ee->ee_n_piers[mode] = 0;
+       while(i < max) {
+               AR5K_EEPROM_READ(o++, val);
+
+               freq1 = val & 0xff;
+               if (!freq1)
+                       break;
+
+               pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+                               freq1, mode);
+               ee->ee_n_piers[mode]++;
+
+               freq2 = (val >> 8) & 0xff;
+               if (!freq2)
+                       break;
+
+               pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+                               freq2, mode);
+               ee->ee_n_piers[mode]++;
+       }
+
+       /* return new offset */
+       *offset = o;
+
+       return 0;
+}
+
+/* Read frequency piers for 802.11a */
+static int
+ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
+       int i, ret;
+       u16 val;
+       u8 mask;
+
+       if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
+               ath5k_eeprom_read_freq_list(ah, &offset,
+                       AR5K_EEPROM_N_5GHZ_CHAN, pcal,
+                       AR5K_EEPROM_MODE_11A);
+       } else {
+               mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[0].freq  = (val >> 9) & mask;
+               pcal[1].freq  = (val >> 2) & mask;
+               pcal[2].freq  = (val << 5) & mask;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[2].freq |= (val >> 11) & 0x1f;
+               pcal[3].freq  = (val >> 4) & mask;
+               pcal[4].freq  = (val << 3) & mask;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[4].freq |= (val >> 13) & 0x7;
+               pcal[5].freq  = (val >> 6) & mask;
+               pcal[6].freq  = (val << 1) & mask;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[6].freq |= (val >> 15) & 0x1;
+               pcal[7].freq  = (val >> 8) & mask;
+               pcal[8].freq  = (val >> 1) & mask;
+               pcal[9].freq  = (val << 6) & mask;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[9].freq |= (val >> 10) & 0x3f;
+
+               /* Fixed number of piers */
+               ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
+
+               for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
+                       pcal[i].freq = ath5k_eeprom_bin2freq(ee,
+                               pcal[i].freq, AR5K_EEPROM_MODE_11A);
+               }
+       }
+
+       return 0;
+}
+
+/* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
+static inline int
+ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *pcal;
+
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11B:
+               pcal = ee->ee_pwr_cal_b;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               pcal = ee->ee_pwr_cal_g;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ath5k_eeprom_read_freq_list(ah, &offset,
+               AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
+               mode);
+
+       return 0;
+}
+
+/*
+ * Read power calibration for RF5111 chips
+ *
+ * For RF5111 we have an XPD -eXternal Power Detector- curve
+ * for each calibrated channel. Each curve has 0,5dB Power steps
+ * on x axis and PCDAC steps (offsets) on y axis and looks like an
+ * exponential function. To recreate the curve we read 11 points
+ * here and interpolate later.
+ */
+
+/* Used to match PCDAC steps with power values on RF5111 chips
+ * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
+ * steps that match with the power values we read from eeprom. On
+ * older eeprom versions (< 3.2) these steps are equaly spaced at
+ * 10% of the pcdac curve -until the curve reaches it's maximum-
+ * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
+ * these 11 steps are spaced in a different way. This function returns
+ * the pcdac steps based on eeprom version and curve min/max so that we
+ * can have pcdac/pwr points.
+ */
+static inline void
+ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
+{
+       const static u16 intercepts3[] =
+               { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
+       const static u16 intercepts3_2[] =
+               { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
+       const u16 *ip;
+       int i;
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
+               ip = intercepts3_2;
+       else
+               ip = intercepts3;
+
+       for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
+               vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
+}
+
+/* Convert RF5111 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
+                               struct ath5k_chan_pcal_info *chinfo)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf5111 *pcinfo;
+       struct ath5k_pdgain_info *pd;
+       u8 pier, point, idx;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+
+       /* Fill raw data for each calibration pier */
+       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+               pcinfo = &chinfo[pier].rf5111_info;
+
+               /* Allocate pd_curves for this cal pier */
+               chinfo[pier].pd_curves =
+                       kcalloc(AR5K_EEPROM_N_PD_CURVES,
+                               sizeof(struct ath5k_pdgain_info),
+                               GFP_KERNEL);
+
+               if (!chinfo[pier].pd_curves)
+                       return -ENOMEM;
+
+               /* Only one curve for RF5111
+                * find out which one and place
+                * in in pd_curves.
+                * Note: ee_x_gain is reversed here */
+               for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
+
+                       if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
+                               pdgain_idx[0] = idx;
+                               break;
+                       }
+               }
+
+               ee->ee_pd_gains[mode] = 1;
+
+               pd = &chinfo[pier].pd_curves[idx];
+
+               pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
+
+               /* Allocate pd points for this curve */
+               pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
+                                       sizeof(u8), GFP_KERNEL);
+               if (!pd->pd_step)
+                       return -ENOMEM;
+
+               pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
+                                       sizeof(s16), GFP_KERNEL);
+               if (!pd->pd_pwr)
+                       return -ENOMEM;
+
+               /* Fill raw dataset
+                * (convert power to 0.25dB units
+                * for RF5112 combatibility) */
+               for (point = 0; point < pd->pd_points; point++) {
+
+                       /* Absolute values */
+                       pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
+
+                       /* Already sorted */
+                       pd->pd_step[point] = pcinfo->pcdac[point];
+               }
+
+               /* Set min/max pwr */
+               chinfo[pier].min_pwr = pd->pd_pwr[0];
+               chinfo[pier].max_pwr = pd->pd_pwr[10];
+
+       }
+
+       return 0;
+}
+
+/* Parse EEPROM data */
+static int
+ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *pcal;
+       int offset, ret;
+       int i;
+       u16 val;
+
+       offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11A:
+               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       return 0;
+
+               ret = ath5k_eeprom_init_11a_pcal_freq(ah,
+                       offset + AR5K_EEPROM_GROUP1_OFFSET);
+               if (ret < 0)
+                       return ret;
+
+               offset += AR5K_EEPROM_GROUP2_OFFSET;
+               pcal = ee->ee_pwr_cal_a;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
+                   !AR5K_EEPROM_HDR_11G(ee->ee_header))
+                       return 0;
+
+               pcal = ee->ee_pwr_cal_b;
+               offset += AR5K_EEPROM_GROUP3_OFFSET;
+
+               /* fixed piers */
+               pcal[0].freq = 2412;
+               pcal[1].freq = 2447;
+               pcal[2].freq = 2484;
+               ee->ee_n_piers[mode] = 3;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+                       return 0;
+
+               pcal = ee->ee_pwr_cal_g;
+               offset += AR5K_EEPROM_GROUP4_OFFSET;
+
+               /* fixed piers */
+               pcal[0].freq = 2312;
+               pcal[1].freq = 2412;
+               pcal[2].freq = 2484;
+               ee->ee_n_piers[mode] = 3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
+               struct ath5k_chan_pcal_info_rf5111 *cdata =
+                       &pcal[i].rf5111_info;
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
+               cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
+               cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pwr[0] |= ((val >> 14) & 0x3);
+               cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pwr[3] |= ((val >> 12) & 0xf);
+               cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[5] = (val  & AR5K_EEPROM_POWER_M);
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pwr[8] |= ((val >> 14) & 0x3);
+               cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
+
+               ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
+                       cdata->pcdac_max, cdata->pcdac);
+       }
+
+       return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
+}
+
+
+/*
+ * Read power calibration for RF5112 chips
+ *
+ * For RF5112 we have 4 XPD -eXternal Power Detector- curves
+ * for each calibrated channel on 0, -6, -12 and -18dbm but we only
+ * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
+ * power steps on x axis and PCDAC steps on y axis and looks like a
+ * linear function. To recreate the curve and pass the power values
+ * on hw, we read 4 points for xpd 0 (lower gain -> max power)
+ * and 3 points for xpd 3 (higher gain -> lower power) here and
+ * interpolate later.
+ *
+ * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
+ */
+
+/* Convert RF5112 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
+                               struct ath5k_chan_pcal_info *chinfo)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf5112 *pcinfo;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+       unsigned int pier, pdg, point;
+
+       /* Fill raw data for each calibration pier */
+       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+               pcinfo = &chinfo[pier].rf5112_info;
+
+               /* Allocate pd_curves for this cal pier */
+               chinfo[pier].pd_curves =
+                               kcalloc(AR5K_EEPROM_N_PD_CURVES,
+                                       sizeof(struct ath5k_pdgain_info),
+                                       GFP_KERNEL);
+
+               if (!chinfo[pier].pd_curves)
+                       return -ENOMEM;
+
+               /* Fill pd_curves */
+               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+
+                       u8 idx = pdgain_idx[pdg];
+                       struct ath5k_pdgain_info *pd =
+                                       &chinfo[pier].pd_curves[idx];
+
+                       /* Lowest gain curve (max power) */
+                       if (pdg == 0) {
+                               /* One more point for better accuracy */
+                               pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
+
+                               /* Allocate pd points for this curve */
+                               pd->pd_step = kcalloc(pd->pd_points,
+                                               sizeof(u8), GFP_KERNEL);
+
+                               if (!pd->pd_step)
+                                       return -ENOMEM;
+
+                               pd->pd_pwr = kcalloc(pd->pd_points,
+                                               sizeof(s16), GFP_KERNEL);
+
+                               if (!pd->pd_pwr)
+                                       return -ENOMEM;
+
+
+                               /* Fill raw dataset
+                                * (all power levels are in 0.25dB units) */
+                               pd->pd_step[0] = pcinfo->pcdac_x0[0];
+                               pd->pd_pwr[0] = pcinfo->pwr_x0[0];
+
+                               for (point = 1; point < pd->pd_points;
+                               point++) {
+                                       /* Absolute values */
+                                       pd->pd_pwr[point] =
+                                               pcinfo->pwr_x0[point];
+
+                                       /* Deltas */
+                                       pd->pd_step[point] =
+                                               pd->pd_step[point - 1] +
+                                               pcinfo->pcdac_x0[point];
+                               }
+
+                               /* Set min power for this frequency */
+                               chinfo[pier].min_pwr = pd->pd_pwr[0];
+
+                       /* Highest gain curve (min power) */
+                       } else if (pdg == 1) {
+
+                               pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
+
+                               /* Allocate pd points for this curve */
+                               pd->pd_step = kcalloc(pd->pd_points,
+                                               sizeof(u8), GFP_KERNEL);
+
+                               if (!pd->pd_step)
+                                       return -ENOMEM;
+
+                               pd->pd_pwr = kcalloc(pd->pd_points,
+                                               sizeof(s16), GFP_KERNEL);
+
+                               if (!pd->pd_pwr)
+                                       return -ENOMEM;
+
+                               /* Fill raw dataset
+                                * (all power levels are in 0.25dB units) */
+                               for (point = 0; point < pd->pd_points;
+                               point++) {
+                                       /* Absolute values */
+                                       pd->pd_pwr[point] =
+                                               pcinfo->pwr_x3[point];
+
+                                       /* Fixed points */
+                                       pd->pd_step[point] =
+                                               pcinfo->pcdac_x3[point];
+                               }
+
+                               /* Since we have a higher gain curve
+                                * override min power */
+                               chinfo[pier].min_pwr = pd->pd_pwr[0];
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/* Parse EEPROM data */
+static int
+ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
+       struct ath5k_chan_pcal_info *gen_chan_info;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+       u32 offset;
+       u8 i, c;
+       u16 val;
+       int ret;
+       u8 pd_gains = 0;
+
+       /* Count how many curves we have and
+        * identify them (which one of the 4
+        * available curves we have on each count).
+        * Curves are stored from lower (x0) to
+        * higher (x3) gain */
+       for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
+               /* ee_x_gain[mode] is x gain mask */
+               if ((ee->ee_x_gain[mode] >> i) & 0x1)
+                       pdgain_idx[pd_gains++] = i;
+       }
+       ee->ee_pd_gains[mode] = pd_gains;
+
+       if (pd_gains == 0 || pd_gains > 2)
+               return -EINVAL;
+
+       switch (mode) {
+       case AR5K_EEPROM_MODE_11A:
+               /*
+                * Read 5GHz EEPROM channels
+                */
+               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
+               ath5k_eeprom_init_11a_pcal_freq(ah, offset);
+
+               offset += AR5K_EEPROM_GROUP2_OFFSET;
+               gen_chan_info = ee->ee_pwr_cal_a;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
+               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       offset += AR5K_EEPROM_GROUP3_OFFSET;
+
+               /* NB: frequency piers parsed during mode init */
+               gen_chan_info = ee->ee_pwr_cal_b;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
+               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       offset += AR5K_EEPROM_GROUP4_OFFSET;
+               else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
+                       offset += AR5K_EEPROM_GROUP2_OFFSET;
+
+               /* NB: frequency piers parsed during mode init */
+               gen_chan_info = ee->ee_pwr_cal_g;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
+               chan_pcal_info = &gen_chan_info[i].rf5112_info;
+
+               /* Power values in quarter dB
+                * for the lower xpd gain curve
+                * (0 dBm -> higher output power) */
+               for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
+                       AR5K_EEPROM_READ(offset++, val);
+                       chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
+                       chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
+               }
+
+               /* PCDAC steps
+                * corresponding to the above power
+                * measurements */
+               AR5K_EEPROM_READ(offset++, val);
+               chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
+               chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
+               chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
+
+               /* Power values in quarter dB
+                * for the higher xpd gain curve
+                * (18 dBm -> lower output power) */
+               AR5K_EEPROM_READ(offset++, val);
+               chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
+               chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
+
+               AR5K_EEPROM_READ(offset++, val);
+               chan_pcal_info->pwr_x3[2] = (val & 0xff);
+
+               /* PCDAC steps
+                * corresponding to the above power
+                * measurements (fixed) */
+               chan_pcal_info->pcdac_x3[0] = 20;
+               chan_pcal_info->pcdac_x3[1] = 35;
+               chan_pcal_info->pcdac_x3[2] = 63;
+
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
+                       chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
+
+                       /* Last xpd0 power level is also channel maximum */
+                       gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
+               } else {
+                       chan_pcal_info->pcdac_x0[0] = 1;
+                       gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
+               }
+
+       }
+
+       return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
+}
+
+
+/*
+ * Read power calibration for RF2413 chips
+ *
+ * For RF2413 we have a Power to PDDAC table (Power Detector)
+ * instead of a PCDAC and 4 pd gain curves for each calibrated channel.
+ * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y
+ * axis and looks like an exponential function like the RF5111 curve.
+ *
+ * To recreate the curves we read here the points and interpolate
+ * later. Note that in most cases only 2 (higher and lower) curves are
+ * used (like RF5112) but vendors have the oportunity to include all
+ * 4 curves on eeprom. The final curve (higher power) has an extra
+ * point for better accuracy like RF5112.
+ */
+
+/* For RF2413 power calibration data doesn't start on a fixed location and
+ * if a mode is not supported, it's section is missing -not zeroed-.
+ * So we need to calculate the starting offset for each section by using
+ * these two functions */
+
+/* Return the size of each section based on the mode and the number of pd
+ * gains available (maximum 4). */
+static inline unsigned int
+ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
+{
+       static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
+       unsigned int sz;
+
+       sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
+       sz *= ee->ee_n_piers[mode];
+
+       return sz;
+}
+
+/* Return the starting offset for a section based on the modes supported
+ * and each section's size. */
+static unsigned int
+ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
+{
+       u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
+
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11G:
+               if (AR5K_EEPROM_HDR_11B(ee->ee_header))
+                       offset += ath5k_pdgains_size_2413(ee,
+                                       AR5K_EEPROM_MODE_11B) +
+                                       AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
+               /* fall through */
+       case AR5K_EEPROM_MODE_11B:
+               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       offset += ath5k_pdgains_size_2413(ee,
+                                       AR5K_EEPROM_MODE_11A) +
+                                       AR5K_EEPROM_N_5GHZ_CHAN / 2;
+               /* fall through */
+       case AR5K_EEPROM_MODE_11A:
+               break;
+       default:
+               break;
+       }
+
+       return offset;
+}
+
+/* Convert RF2413 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
+                               struct ath5k_chan_pcal_info *chinfo)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+       unsigned int pier, pdg, point;
+
+       /* Fill raw data for each calibration pier */
+       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+               pcinfo = &chinfo[pier].rf2413_info;
+
+               /* Allocate pd_curves for this cal pier */
+               chinfo[pier].pd_curves =
+                               kcalloc(AR5K_EEPROM_N_PD_CURVES,
+                                       sizeof(struct ath5k_pdgain_info),
+                                       GFP_KERNEL);
+
+               if (!chinfo[pier].pd_curves)
+                       return -ENOMEM;
+
+               /* Fill pd_curves */
+               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+
+                       u8 idx = pdgain_idx[pdg];
+                       struct ath5k_pdgain_info *pd =
+                                       &chinfo[pier].pd_curves[idx];
+
+                       /* One more point for the highest power
+                        * curve (lowest gain) */
+                       if (pdg == ee->ee_pd_gains[mode] - 1)
+                               pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
+                       else
+                               pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
+
+                       /* Allocate pd points for this curve */
+                       pd->pd_step = kcalloc(pd->pd_points,
+                                       sizeof(u8), GFP_KERNEL);
+
+                       if (!pd->pd_step)
+                               return -ENOMEM;
+
+                       pd->pd_pwr = kcalloc(pd->pd_points,
+                                       sizeof(s16), GFP_KERNEL);
+
+                       if (!pd->pd_pwr)
+                               return -ENOMEM;
+
+                       /* Fill raw dataset
+                        * convert all pwr levels to
+                        * quarter dB for RF5112 combatibility */
+                       pd->pd_step[0] = pcinfo->pddac_i[pdg];
+                       pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
+
+                       for (point = 1; point < pd->pd_points; point++) {
+
+                               pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
+                                       2 * pcinfo->pwr[pdg][point - 1];
+
+                               pd->pd_step[point] = pd->pd_step[point - 1] +
+                                               pcinfo->pddac[pdg][point - 1];
+
+                       }
+
+                       /* Highest gain curve -> min power */
+                       if (pdg == 0)
+                               chinfo[pier].min_pwr = pd->pd_pwr[0];
+
+                       /* Lowest gain curve -> max power */
+                       if (pdg == ee->ee_pd_gains[mode] - 1)
+                               chinfo[pier].max_pwr =
+                                       pd->pd_pwr[pd->pd_points - 1];
+               }
+       }
+
+       return 0;
+}
+
+/* Parse EEPROM data */
+static int
+ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+       struct ath5k_chan_pcal_info *chinfo;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+       u32 offset;
+       int idx, i, ret;
+       u16 val;
+       u8 pd_gains = 0;
+
+       /* Count how many curves we have and
+        * identify them (which one of the 4
+        * available curves we have on each count).
+        * Curves are stored from higher to
+        * lower gain so we go backwards */
+       for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
+               /* ee_x_gain[mode] is x gain mask */
+               if ((ee->ee_x_gain[mode] >> idx) & 0x1)
+                       pdgain_idx[pd_gains++] = idx;
+
+       }
+       ee->ee_pd_gains[mode] = pd_gains;
+
+       if (pd_gains == 0)
+               return -EINVAL;
+
+       offset = ath5k_cal_data_offset_2413(ee, mode);
+       switch (mode) {
+       case AR5K_EEPROM_MODE_11A:
+               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       return 0;
+
+               ath5k_eeprom_init_11a_pcal_freq(ah, offset);
+               offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
+               chinfo = ee->ee_pwr_cal_a;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
+                       return 0;
+
+               ath5k_eeprom_init_11bg_2413(ah, mode, offset);
+               offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
+               chinfo = ee->ee_pwr_cal_b;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+                       return 0;
+
+               ath5k_eeprom_init_11bg_2413(ah, mode, offset);
+               offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
+               chinfo = ee->ee_pwr_cal_g;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
+               pcinfo = &chinfo[i].rf2413_info;
+
+               /*
+                * Read pwr_i, pddac_i and the first
+                * 2 pd points (pwr, pddac)
+                */
+               AR5K_EEPROM_READ(offset++, val);
+               pcinfo->pwr_i[0] = val & 0x1f;
+               pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
+               pcinfo->pwr[0][0] = (val >> 12) & 0xf;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcinfo->pddac[0][0] = val & 0x3f;
+               pcinfo->pwr[0][1] = (val >> 6) & 0xf;
+               pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcinfo->pwr[0][2] = val & 0xf;
+               pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
+
+               pcinfo->pwr[0][3] = 0;
+               pcinfo->pddac[0][3] = 0;
+
+               if (pd_gains > 1) {
+                       /*
+                        * Pd gain 0 is not the last pd gain
+                        * so it only has 2 pd points.
+                        * Continue wih pd gain 1.
+                        */
+                       pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
+
+                       pcinfo->pddac_i[1] = (val >> 15) & 0x1;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
+
+                       pcinfo->pwr[1][0] = (val >> 6) & 0xf;
+                       pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr[1][1] = val & 0xf;
+                       pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
+                       pcinfo->pwr[1][2] = (val >> 10) & 0xf;
+
+                       pcinfo->pddac[1][2] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[1][2] |= (val & 0xF) << 2;
+
+                       pcinfo->pwr[1][3] = 0;
+                       pcinfo->pddac[1][3] = 0;
+               } else if (pd_gains == 1) {
+                       /*
+                        * Pd gain 0 is the last one so
+                        * read the extra point.
+                        */
+                       pcinfo->pwr[0][3] = (val >> 10) & 0xf;
+
+                       pcinfo->pddac[0][3] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[0][3] |= (val & 0xF) << 2;
+               }
+
+               /*
+                * Proceed with the other pd_gains
+                * as above.
+                */
+               if (pd_gains > 2) {
+                       pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
+                       pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr[2][0] = (val >> 0) & 0xf;
+                       pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
+                       pcinfo->pwr[2][1] = (val >> 10) & 0xf;
+
+                       pcinfo->pddac[2][1] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[2][1] |= (val & 0xF) << 2;
+
+                       pcinfo->pwr[2][2] = (val >> 4) & 0xf;
+                       pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
+
+                       pcinfo->pwr[2][3] = 0;
+                       pcinfo->pddac[2][3] = 0;
+               } else if (pd_gains == 2) {
+                       pcinfo->pwr[1][3] = (val >> 4) & 0xf;
+                       pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
+               }
+
+               if (pd_gains > 3) {
+                       pcinfo->pwr_i[3] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
+
+                       pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
+                       pcinfo->pwr[3][0] = (val >> 10) & 0xf;
+                       pcinfo->pddac[3][0] = (val >> 14) & 0x3;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[3][0] |= (val & 0xF) << 2;
+                       pcinfo->pwr[3][1] = (val >> 4) & 0xf;
+                       pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
+
+                       pcinfo->pwr[3][2] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
+
+                       pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
+                       pcinfo->pwr[3][3] = (val >> 8) & 0xf;
+
+                       pcinfo->pddac[3][3] = (val >> 12) & 0xF;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
+               } else if (pd_gains == 3) {
+                       pcinfo->pwr[2][3] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
+
+                       pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
+               }
+       }
+
+       return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
+}
+
+
+/*
+ * Read per rate target power (this is the maximum tx power
+ * supported by the card). This info is used when setting
+ * tx power, no matter the channel.
+ *
+ * This also works for v5 EEPROMs.
+ */
+static int
+ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_rate_pcal_info *rate_pcal_info;
+       u8 *rate_target_pwr_num;
+       u32 offset;
+       u16 val;
+       int ret, i;
+
+       offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
+       rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
+       switch (mode) {
+       case AR5K_EEPROM_MODE_11A:
+               offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
+               rate_pcal_info = ee->ee_rate_tpwr_a;
+               ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
+               rate_pcal_info = ee->ee_rate_tpwr_b;
+               ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
+               rate_pcal_info = ee->ee_rate_tpwr_g;
+               ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Different freq mask for older eeproms (<= v3.2) */
+       if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
+               for (i = 0; i < (*rate_target_pwr_num); i++) {
+                       AR5K_EEPROM_READ(offset++, val);
+                       rate_pcal_info[i].freq =
+                           ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
+
+                       rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
+                       rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
+
+                       AR5K_EEPROM_READ(offset++, val);
+
+                       if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
+                           val == 0) {
+                               (*rate_target_pwr_num) = i;
+                               break;
+                       }
+
+                       rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
+                       rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
+                       rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
+               }
+       } else {
+               for (i = 0; i < (*rate_target_pwr_num); i++) {
+                       AR5K_EEPROM_READ(offset++, val);
+                       rate_pcal_info[i].freq =
+                           ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
+
+                       rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
+                       rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
+
+                       AR5K_EEPROM_READ(offset++, val);
+
+                       if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
+                           val == 0) {
+                               (*rate_target_pwr_num) = i;
+                               break;
+                       }
+
+                       rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
+                       rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
+                       rate_pcal_info[i].target_power_54 = (val & 0x3f);
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Read per channel calibration info from EEPROM
+ *
+ * This info is used to calibrate the baseband power table. Imagine
+ * that for each channel there is a power curve that's hw specific
+ * (depends on amplifier etc) and we try to "correct" this curve using
+ * offests we pass on to phy chip (baseband -> before amplifier) so that
+ * it can use accurate power values when setting tx power (takes amplifier's
+ * performance on each channel into account).
+ *
+ * EEPROM provides us with the offsets for some pre-calibrated channels
+ * and we have to interpolate to create the full table for these channels and
+ * also the table for any channel.
+ */
+static int
+ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       int (*read_pcal)(struct ath5k_hw *hw, int mode);
+       int mode;
+       int err;
+
+       if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
+                       (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
+               read_pcal = ath5k_eeprom_read_pcal_info_5112;
+       else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
+                       (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
+               read_pcal = ath5k_eeprom_read_pcal_info_2413;
+       else
+               read_pcal = ath5k_eeprom_read_pcal_info_5111;
+
+
+       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
+       mode++) {
+               err = read_pcal(ah, mode);
+               if (err)
+                       return err;
+
+               err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode);
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int
+ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *chinfo;
+       u8 pier, pdg;
+
+       switch (mode) {
+       case AR5K_EEPROM_MODE_11A:
+               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       return 0;
+               chinfo = ee->ee_pwr_cal_a;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
+                       return 0;
+               chinfo = ee->ee_pwr_cal_b;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+                       return 0;
+               chinfo = ee->ee_pwr_cal_g;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+               if (!chinfo[pier].pd_curves)
+                       continue;
+
+               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+                       struct ath5k_pdgain_info *pd =
+                                       &chinfo[pier].pd_curves[pdg];
+
+                       if (pd != NULL) {
+                               kfree(pd->pd_step);
+                               kfree(pd->pd_pwr);
+                       }
+               }
+
+               kfree(chinfo[pier].pd_curves);
+       }
+
+       return 0;
+}
+
+void
+ath5k_eeprom_detach(struct ath5k_hw *ah)
+{
+       u8 mode;
+
+       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
+               ath5k_eeprom_free_pcal_info(ah, mode);
+}
+
+/* Read conformance test limits used for regulatory control */
+static int
+ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_edge_power *rep;
+       unsigned int fmask, pmask;
+       unsigned int ctl_mode;
+       int ret, i, j;
+       u32 offset;
+       u16 val;
+
+       pmask = AR5K_EEPROM_POWER_M;
+       fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
+       offset = AR5K_EEPROM_CTL(ee->ee_version);
+       ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version);
+       for (i = 0; i < ee->ee_ctls; i += 2) {
+               AR5K_EEPROM_READ(offset++, val);
+               ee->ee_ctl[i] = (val >> 8) & 0xff;
+               ee->ee_ctl[i + 1] = val & 0xff;
+       }
+
+       offset = AR5K_EEPROM_GROUP8_OFFSET;
+       if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
+               offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) -
+                       AR5K_EEPROM_GROUP5_OFFSET;
+       else
+               offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
+
+       rep = ee->ee_ctl_pwr;
+       for(i = 0; i < ee->ee_ctls; i++) {
+               switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
+               case AR5K_CTL_11A:
+               case AR5K_CTL_TURBO:
+                       ctl_mode = AR5K_EEPROM_MODE_11A;
+                       break;
+               default:
+                       ctl_mode = AR5K_EEPROM_MODE_11G;
+                       break;
+               }
+               if (ee->ee_ctl[i] == 0) {
+                       if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3)
+                               offset += 8;
+                       else
+                               offset += 7;
+                       rep += AR5K_EEPROM_N_EDGES;
+                       continue;
+               }
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
+                       for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
+                               AR5K_EEPROM_READ(offset++, val);
+                               rep[j].freq = (val >> 8) & fmask;
+                               rep[j + 1].freq = val & fmask;
+                       }
+                       for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
+                               AR5K_EEPROM_READ(offset++, val);
+                               rep[j].edge = (val >> 8) & pmask;
+                               rep[j].flag = (val >> 14) & 1;
+                               rep[j + 1].edge = val & pmask;
+                               rep[j + 1].flag = (val >> 6) & 1;
+                       }
+               } else {
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[0].freq = (val >> 9) & fmask;
+                       rep[1].freq = (val >> 2) & fmask;
+                       rep[2].freq = (val << 5) & fmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[2].freq |= (val >> 11) & 0x1f;
+                       rep[3].freq = (val >> 4) & fmask;
+                       rep[4].freq = (val << 3) & fmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[4].freq |= (val >> 13) & 0x7;
+                       rep[5].freq = (val >> 6) & fmask;
+                       rep[6].freq = (val << 1) & fmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[6].freq |= (val >> 15) & 0x1;
+                       rep[7].freq = (val >> 8) & fmask;
+
+                       rep[0].edge = (val >> 2) & pmask;
+                       rep[1].edge = (val << 4) & pmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[1].edge |= (val >> 12) & 0xf;
+                       rep[2].edge = (val >> 6) & pmask;
+                       rep[3].edge = val & pmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[4].edge = (val >> 10) & pmask;
+                       rep[5].edge = (val >> 4) & pmask;
+                       rep[6].edge = (val << 2) & pmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[6].edge |= (val >> 14) & 0x3;
+                       rep[7].edge = (val >> 8) & pmask;
+               }
+               for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
+                       rep[j].freq = ath5k_eeprom_bin2freq(ee,
+                               rep[j].freq, ctl_mode);
+               }
+               rep += AR5K_EEPROM_N_EDGES;
+       }
+
+       return 0;
+}
+
+
+/*
+ * Initialize eeprom power tables
+ */
+int
+ath5k_eeprom_init(struct ath5k_hw *ah)
+{
+       int err;
+
+       err = ath5k_eeprom_init_header(ah);
+       if (err < 0)
+               return err;
+
+       err = ath5k_eeprom_init_modes(ah);
+       if (err < 0)
+               return err;
+
+       err = ath5k_eeprom_read_pcal_info(ah);
+       if (err < 0)
+               return err;
+
+       err = ath5k_eeprom_read_ctl_info(ah);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
+/*
+ * Read the MAC address from eeprom
+ */
+int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+       u8 mac_d[ETH_ALEN] = {};
+       u32 total, offset;
+       u16 data;
+       int octet, ret;
+
+       ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
+       if (ret)
+               return ret;
+
+       for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
+               ret = ath5k_hw_eeprom_read(ah, offset, &data);
+               if (ret)
+                       return ret;
+
+               total += data;
+               mac_d[octet + 1] = data & 0xff;
+               mac_d[octet] = data >> 8;
+               octet += 2;
+       }
+
+       if (!total || total == 3 * 0xffff)
+               return -EINVAL;
+
+       memcpy(mac, mac_d, ETH_ALEN);
+
+       return 0;
+}
+
+bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
+{
+       u16 data;
+
+       ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
+
+       if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
+               return true;
+       else
+               return false;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
new file mode 100644 (file)
index 0000000..b0c0606
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*
+ * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
+ */
+#define AR5K_EEPROM_MAGIC              0x003d  /* EEPROM Magic number */
+#define AR5K_EEPROM_MAGIC_VALUE                0x5aa5  /* Default - found on EEPROM */
+#define AR5K_EEPROM_MAGIC_5212         0x0000145c /* 5212 */
+#define AR5K_EEPROM_MAGIC_5211         0x0000145b /* 5211 */
+#define AR5K_EEPROM_MAGIC_5210         0x0000145a /* 5210 */
+
+#define        AR5K_EEPROM_IS_HB63             0x000b  /* Talon detect */
+#define AR5K_EEPROM_REG_DOMAIN         0x00bf  /* EEPROM regdom */
+#define AR5K_EEPROM_CHECKSUM           0x00c0  /* EEPROM checksum */
+#define AR5K_EEPROM_INFO_BASE          0x00c0  /* EEPROM header */
+#define AR5K_EEPROM_INFO_MAX           (0x400 - AR5K_EEPROM_INFO_BASE)
+#define AR5K_EEPROM_INFO_CKSUM         0xffff
+#define AR5K_EEPROM_INFO(_n)           (AR5K_EEPROM_INFO_BASE + (_n))
+
+#define AR5K_EEPROM_VERSION            AR5K_EEPROM_INFO(1)     /* EEPROM Version */
+#define AR5K_EEPROM_VERSION_3_0                0x3000  /* No idea what's going on before this version */
+#define AR5K_EEPROM_VERSION_3_1                0x3001  /* ob/db values for 2Ghz (ar5211_rfregs) */
+#define AR5K_EEPROM_VERSION_3_2                0x3002  /* different frequency representation (eeprom_bin2freq) */
+#define AR5K_EEPROM_VERSION_3_3                0x3003  /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
+#define AR5K_EEPROM_VERSION_3_4                0x3004  /* has ee_i_gain, ee_cck_ofdm_power_delta (eeprom_read_modes) */
+#define AR5K_EEPROM_VERSION_4_0                0x4000  /* has ee_misc, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
+#define AR5K_EEPROM_VERSION_4_1                0x4001  /* has ee_margin_tx_rx (eeprom_init) */
+#define AR5K_EEPROM_VERSION_4_2                0x4002  /* has ee_cck_ofdm_gain_delta (eeprom_init) */
+#define AR5K_EEPROM_VERSION_4_3                0x4003  /* power calibration changes */
+#define AR5K_EEPROM_VERSION_4_4                0x4004
+#define AR5K_EEPROM_VERSION_4_5                0x4005
+#define AR5K_EEPROM_VERSION_4_6                0x4006  /* has ee_scaled_cck_delta */
+#define AR5K_EEPROM_VERSION_4_7                0x3007  /* 4007 ? */
+#define AR5K_EEPROM_VERSION_4_9                0x4009  /* EAR futureproofing */
+#define AR5K_EEPROM_VERSION_5_0                0x5000  /* Has 2413 PDADC calibration etc */
+#define AR5K_EEPROM_VERSION_5_1                0x5001  /* Has capability values */
+#define AR5K_EEPROM_VERSION_5_3                0x5003  /* Has spur mitigation tables */
+
+#define AR5K_EEPROM_MODE_11A           0
+#define AR5K_EEPROM_MODE_11B           1
+#define AR5K_EEPROM_MODE_11G           2
+
+#define AR5K_EEPROM_HDR                        AR5K_EEPROM_INFO(2)     /* Header that contains the device caps */
+#define AR5K_EEPROM_HDR_11A(_v)                (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
+#define AR5K_EEPROM_HDR_11B(_v)                (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
+#define AR5K_EEPROM_HDR_11G(_v)                (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
+#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1)     /* Disable turbo for 2Ghz (?) */
+#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f)    /* Max turbo power for a/XR mode (eeprom_init) */
+#define AR5K_EEPROM_HDR_DEVICE(_v)     (((_v) >> 11) & 0x7)
+#define AR5K_EEPROM_HDR_RFKILL(_v)     (((_v) >> 14) & 0x1)    /* Device has RFKill support */
+#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1)    /* Disable turbo for 5Ghz */
+
+#define AR5K_EEPROM_RFKILL_GPIO_SEL    0x0000001c
+#define AR5K_EEPROM_RFKILL_GPIO_SEL_S  2
+#define AR5K_EEPROM_RFKILL_POLARITY    0x00000002
+#define AR5K_EEPROM_RFKILL_POLARITY_S  1
+
+/* Newer EEPROMs are using a different offset */
+#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
+       (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
+
+#define AR5K_EEPROM_ANT_GAIN(_v)       AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
+#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v)  ((s8)(((_v) >> 8) & 0xff))
+#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v)  ((s8)((_v) & 0xff))
+
+/* Misc values available since EEPROM 4.0 */
+#define AR5K_EEPROM_MISC0              AR5K_EEPROM_INFO(4)
+#define AR5K_EEPROM_EARSTART(_v)       ((_v) & 0xfff)
+#define AR5K_EEPROM_HDR_XR2_DIS(_v)    (((_v) >> 12) & 0x1)
+#define AR5K_EEPROM_HDR_XR5_DIS(_v)    (((_v) >> 13) & 0x1)
+#define AR5K_EEPROM_EEMAP(_v)          (((_v) >> 14) & 0x3)
+
+#define AR5K_EEPROM_MISC1                      AR5K_EEPROM_INFO(5)
+#define AR5K_EEPROM_TARGET_PWRSTART(_v)                ((_v) & 0xfff)
+#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v)                (((_v) >> 14) & 0x1)
+#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v)    (((_v) >> 15) & 0x1)
+
+#define AR5K_EEPROM_MISC2                      AR5K_EEPROM_INFO(6)
+#define AR5K_EEPROM_EEP_FILE_VERSION(_v)       (((_v) >> 8) & 0xff)
+#define AR5K_EEPROM_EAR_FILE_VERSION(_v)       ((_v) & 0xff)
+
+#define AR5K_EEPROM_MISC3              AR5K_EEPROM_INFO(7)
+#define AR5K_EEPROM_ART_BUILD_NUM(_v)  (((_v) >> 10) & 0x3f)
+#define AR5K_EEPROM_EAR_FILE_ID(_v)    ((_v) & 0xff)
+
+#define AR5K_EEPROM_MISC4              AR5K_EEPROM_INFO(8)
+#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff)
+#define AR5K_EEPROM_MASK_R0(_v)                (((_v) >> 2) & 0x3)
+#define AR5K_EEPROM_MASK_R1(_v)                ((_v) & 0x3)
+
+#define AR5K_EEPROM_MISC5              AR5K_EEPROM_INFO(9)
+#define AR5K_EEPROM_COMP_DIS(_v)       ((_v) & 0x1)
+#define AR5K_EEPROM_AES_DIS(_v)                (((_v) >> 1) & 0x1)
+#define AR5K_EEPROM_FF_DIS(_v)         (((_v) >> 2) & 0x1)
+#define AR5K_EEPROM_BURST_DIS(_v)      (((_v) >> 3) & 0x1)
+#define AR5K_EEPROM_MAX_QCU(_v)                (((_v) >> 4) & 0xf)
+#define AR5K_EEPROM_HEAVY_CLIP_EN(_v)  (((_v) >> 8) & 0x1)
+#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf)
+
+#define AR5K_EEPROM_MISC6              AR5K_EEPROM_INFO(10)
+#define AR5K_EEPROM_TX_CHAIN_DIS       ((_v) & 0x8)
+#define AR5K_EEPROM_RX_CHAIN_DIS       (((_v) >> 3) & 0x8)
+#define AR5K_EEPROM_FCC_MID_EN         (((_v) >> 6) & 0x1)
+#define AR5K_EEPROM_JAP_U1EVEN_EN      (((_v) >> 7) & 0x1)
+#define AR5K_EEPROM_JAP_U2_EN          (((_v) >> 8) & 0x1)
+#define AR5K_EEPROM_JAP_U1ODD_EN       (((_v) >> 9) & 0x1)
+#define AR5K_EEPROM_JAP_11A_NEW_EN     (((_v) >> 10) & 0x1)
+
+/* calibration settings */
+#define AR5K_EEPROM_MODES_11A(_v)      AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
+#define AR5K_EEPROM_MODES_11B(_v)      AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
+#define AR5K_EEPROM_MODES_11G(_v)      AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
+#define AR5K_EEPROM_CTL(_v)            AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128)     /* Conformance test limits */
+#define AR5K_EEPROM_GROUPS_START(_v)   AR5K_EEPROM_OFF(_v, 0x0100, 0x0150)     /* Start of Groups */
+#define AR5K_EEPROM_GROUP1_OFFSET      0x0
+#define AR5K_EEPROM_GROUP2_OFFSET      0x5
+#define AR5K_EEPROM_GROUP3_OFFSET      0x37
+#define AR5K_EEPROM_GROUP4_OFFSET      0x46
+#define AR5K_EEPROM_GROUP5_OFFSET      0x55
+#define AR5K_EEPROM_GROUP6_OFFSET      0x65
+#define AR5K_EEPROM_GROUP7_OFFSET      0x69
+#define AR5K_EEPROM_GROUP8_OFFSET      0x6f
+
+#define AR5K_EEPROM_TARGET_PWR_OFF_11A(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
+                                                               AR5K_EEPROM_GROUP5_OFFSET, 0x0000)
+#define AR5K_EEPROM_TARGET_PWR_OFF_11B(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
+                                                               AR5K_EEPROM_GROUP6_OFFSET, 0x0010)
+#define AR5K_EEPROM_TARGET_PWR_OFF_11G(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
+                                                               AR5K_EEPROM_GROUP7_OFFSET, 0x0014)
+
+/* [3.1 - 3.3] */
+#define AR5K_EEPROM_OBDB0_2GHZ         0x00ec
+#define AR5K_EEPROM_OBDB1_2GHZ         0x00ed
+
+#define AR5K_EEPROM_PROTECT            0x003f  /* EEPROM protect status */
+#define AR5K_EEPROM_PROTECT_RD_0_31    0x0001  /* Read protection bit for offsets 0x0 - 0x1f */
+#define AR5K_EEPROM_PROTECT_WR_0_31    0x0002  /* Write protection bit for offsets 0x0 - 0x1f */
+#define AR5K_EEPROM_PROTECT_RD_32_63   0x0004  /* 0x20 - 0x3f */
+#define AR5K_EEPROM_PROTECT_WR_32_63   0x0008
+#define AR5K_EEPROM_PROTECT_RD_64_127  0x0010  /* 0x40 - 0x7f */
+#define AR5K_EEPROM_PROTECT_WR_64_127  0x0020
+#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040  /* 0x80 - 0xbf (regdom) */
+#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
+#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100  /* 0xc0 - 0xcf */
+#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
+#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400  /* 0xd0 - 0xdf */
+#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
+#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000  /* 0xe0 - 0xef */
+#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
+#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000  /* 0xf0 - 0xff */
+#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
+
+/* Some EEPROM defines */
+#define AR5K_EEPROM_EEP_SCALE          100
+#define AR5K_EEPROM_EEP_DELTA          10
+#define AR5K_EEPROM_N_MODES            3
+#define AR5K_EEPROM_N_5GHZ_CHAN                10
+#define AR5K_EEPROM_N_2GHZ_CHAN                3
+#define AR5K_EEPROM_N_2GHZ_CHAN_2413   4
+#define        AR5K_EEPROM_N_2GHZ_CHAN_MAX     4
+#define AR5K_EEPROM_MAX_CHAN           10
+#define AR5K_EEPROM_N_PWR_POINTS_5111  11
+#define AR5K_EEPROM_N_PCDAC            11
+#define AR5K_EEPROM_N_PHASE_CAL                5
+#define AR5K_EEPROM_N_TEST_FREQ                8
+#define AR5K_EEPROM_N_EDGES            8
+#define AR5K_EEPROM_N_INTERCEPTS       11
+#define AR5K_EEPROM_FREQ_M(_v)         AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
+#define AR5K_EEPROM_PCDAC_M            0x3f
+#define AR5K_EEPROM_PCDAC_START                1
+#define AR5K_EEPROM_PCDAC_STOP         63
+#define AR5K_EEPROM_PCDAC_STEP         1
+#define AR5K_EEPROM_NON_EDGE_M         0x40
+#define AR5K_EEPROM_CHANNEL_POWER      8
+#define AR5K_EEPROM_N_OBDB             4
+#define AR5K_EEPROM_OBDB_DIS           0xffff
+#define AR5K_EEPROM_CHANNEL_DIS                0xff
+#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
+#define AR5K_EEPROM_N_CTLS(_v)         AR5K_EEPROM_OFF(_v, 16, 32)
+#define AR5K_EEPROM_MAX_CTLS           32
+#define AR5K_EEPROM_N_PD_CURVES                4
+#define AR5K_EEPROM_N_XPD0_POINTS      4
+#define AR5K_EEPROM_N_XPD3_POINTS      3
+#define AR5K_EEPROM_N_PD_GAINS         4
+#define AR5K_EEPROM_N_PD_POINTS                5
+#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ        35
+#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ        55
+#define AR5K_EEPROM_POWER_M            0x3f
+#define AR5K_EEPROM_POWER_MIN          0
+#define AR5K_EEPROM_POWER_MAX          3150
+#define AR5K_EEPROM_POWER_STEP         50
+#define AR5K_EEPROM_POWER_TABLE_SIZE   64
+#define AR5K_EEPROM_N_POWER_LOC_11B    4
+#define AR5K_EEPROM_N_POWER_LOC_11G    6
+#define AR5K_EEPROM_I_GAIN             10
+#define AR5K_EEPROM_CCK_OFDM_DELTA     15
+#define AR5K_EEPROM_N_IQ_CAL           2
+
+#define AR5K_EEPROM_READ(_o, _v) do {                  \
+       ret = ath5k_hw_eeprom_read(ah, (_o), &(_v));    \
+       if (ret)                                        \
+               return ret;                             \
+} while (0)
+
+#define AR5K_EEPROM_READ_HDR(_o, _v)                                   \
+       AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v);        \
+
+enum ath5k_ant_setting {
+       AR5K_ANT_VARIABLE       = 0,    /* variable by programming */
+       AR5K_ANT_FIXED_A        = 1,    /* fixed to 11a frequencies */
+       AR5K_ANT_FIXED_B        = 2,    /* fixed to 11b frequencies */
+       AR5K_ANT_MAX            = 3,
+};
+
+enum ath5k_ctl_mode {
+       AR5K_CTL_11A = 0,
+       AR5K_CTL_11B = 1,
+       AR5K_CTL_11G = 2,
+       AR5K_CTL_TURBO = 3,
+       AR5K_CTL_TURBOG = 4,
+       AR5K_CTL_2GHT20 = 5,
+       AR5K_CTL_5GHT20 = 6,
+       AR5K_CTL_2GHT40 = 7,
+       AR5K_CTL_5GHT40 = 8,
+       AR5K_CTL_MODE_M = 15,
+};
+
+/* Default CTL ids for the 3 main reg domains.
+ * Atheros only uses these by default but vendors
+ * can have up to 32 different CTLs for different
+ * scenarios. Note that theese values are ORed with
+ * the mode id (above) so we can have up to 24 CTL
+ * datasets out of these 3 main regdomains. That leaves
+ * 8 ids that can be used by vendors and since 0x20 is
+ * missing from HAL sources i guess this is the set of
+ * custom CTLs vendors can use. */
+#define        AR5K_CTL_FCC    0x10
+#define        AR5K_CTL_CUSTOM 0x20
+#define        AR5K_CTL_ETSI   0x30
+#define        AR5K_CTL_MKK    0x40
+
+/* Indicates a CTL with only mode set and
+ * no reg domain mapping, such CTLs are used
+ * for world roaming domains or simply when
+ * a reg domain is not set */
+#define        AR5K_CTL_NO_REGDOMAIN   0xf0
+
+/* Indicates an empty (invalid) CTL */
+#define AR5K_CTL_NO_CTL                0xff
+
+/* Per channel calibration data, used for power table setup */
+struct ath5k_chan_pcal_info_rf5111 {
+       /* Power levels in half dbm units
+        * for one power curve. */
+       u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
+       /* PCDAC table steps
+        * for the above values */
+       u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111];
+       /* Starting PCDAC step */
+       u8 pcdac_min;
+       /* Final PCDAC step */
+       u8 pcdac_max;
+};
+
+struct ath5k_chan_pcal_info_rf5112 {
+       /* Power levels in quarter dBm units
+        * for lower (0) and higher (3)
+        * level curves in 0.25dB units */
+       s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
+       s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
+       /* PCDAC table steps
+        * for the above values */
+       u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
+       u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
+};
+
+struct ath5k_chan_pcal_info_rf2413 {
+       /* Starting pwr/pddac values */
+       s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
+       u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
+       /* (pwr,pddac) points
+        * power levels in 0.5dB units */
+       s8 pwr[AR5K_EEPROM_N_PD_GAINS]
+               [AR5K_EEPROM_N_PD_POINTS];
+       u8 pddac[AR5K_EEPROM_N_PD_GAINS]
+               [AR5K_EEPROM_N_PD_POINTS];
+};
+
+enum ath5k_powertable_type {
+       AR5K_PWRTABLE_PWR_TO_PCDAC = 0,
+       AR5K_PWRTABLE_LINEAR_PCDAC = 1,
+       AR5K_PWRTABLE_PWR_TO_PDADC = 2,
+};
+
+struct ath5k_pdgain_info {
+       u8 pd_points;
+       u8 *pd_step;
+       /* Power values are in
+        * 0.25dB units */
+       s16 *pd_pwr;
+};
+
+struct ath5k_chan_pcal_info {
+       /* Frequency */
+       u16     freq;
+       /* Tx power boundaries */
+       s16     max_pwr;
+       s16     min_pwr;
+       union {
+               struct ath5k_chan_pcal_info_rf5111 rf5111_info;
+               struct ath5k_chan_pcal_info_rf5112 rf5112_info;
+               struct ath5k_chan_pcal_info_rf2413 rf2413_info;
+       };
+       /* Raw values used by phy code
+        * Curves are stored in order from lower
+        * gain to higher gain (max txpower -> min txpower) */
+       struct ath5k_pdgain_info *pd_curves;
+};
+
+/* Per rate calibration data for each mode,
+ * used for rate power table setup.
+ * Note: Values in 0.5dB units */
+struct ath5k_rate_pcal_info {
+       u16     freq; /* Frequency */
+       /* Power level for 6-24Mbit/s rates or
+        * 1Mb rate */
+       u16     target_power_6to24;
+       /* Power level for 36Mbit rate or
+        * 2Mb rate */
+       u16     target_power_36;
+       /* Power level for 48Mbit rate or
+        * 5.5Mbit rate */
+       u16     target_power_48;
+       /* Power level for 54Mbit rate or
+        * 11Mbit rate */
+       u16     target_power_54;
+};
+
+/* Power edges for conformance test limits */
+struct ath5k_edge_power {
+       u16 freq;
+       u16 edge; /* in half dBm */
+       bool flag;
+};
+
+/* EEPROM calibration data */
+struct ath5k_eeprom_info {
+
+       /* Header information */
+       u16     ee_magic;
+       u16     ee_protect;
+       u16     ee_regdomain;
+       u16     ee_version;
+       u16     ee_header;
+       u16     ee_ant_gain;
+       u16     ee_misc0;
+       u16     ee_misc1;
+       u16     ee_misc2;
+       u16     ee_misc3;
+       u16     ee_misc4;
+       u16     ee_misc5;
+       u16     ee_misc6;
+       u16     ee_cck_ofdm_gain_delta;
+       u16     ee_cck_ofdm_power_delta;
+       u16     ee_scaled_cck_delta;
+
+       /* RF Calibration settings (reset, rfregs) */
+       u16     ee_i_cal[AR5K_EEPROM_N_MODES];
+       u16     ee_q_cal[AR5K_EEPROM_N_MODES];
+       u16     ee_fixed_bias[AR5K_EEPROM_N_MODES];
+       u16     ee_turbo_max_power[AR5K_EEPROM_N_MODES];
+       u16     ee_xr_power[AR5K_EEPROM_N_MODES];
+       u16     ee_switch_settling[AR5K_EEPROM_N_MODES];
+       u16     ee_atn_tx_rx[AR5K_EEPROM_N_MODES];
+       u16     ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
+       u16     ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
+       u16     ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
+       u16     ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
+       u16     ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
+       u16     ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
+       u16     ee_thr_62[AR5K_EEPROM_N_MODES];
+       u16     ee_xlna_gain[AR5K_EEPROM_N_MODES];
+       u16     ee_xpd[AR5K_EEPROM_N_MODES];
+       u16     ee_x_gain[AR5K_EEPROM_N_MODES];
+       u16     ee_i_gain[AR5K_EEPROM_N_MODES];
+       u16     ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
+       u16     ee_switch_settling_turbo[AR5K_EEPROM_N_MODES];
+       u16     ee_margin_tx_rx_turbo[AR5K_EEPROM_N_MODES];
+       u16     ee_atn_tx_rx_turbo[AR5K_EEPROM_N_MODES];
+
+       /* Power calibration data */
+       u16     ee_false_detect[AR5K_EEPROM_N_MODES];
+
+       /* Number of pd gain curves per mode */
+       u8      ee_pd_gains[AR5K_EEPROM_N_MODES];
+       /* Back mapping pdcurve number -> pdcurve index in pd->pd_curves */
+       u8      ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS];
+
+       u8      ee_n_piers[AR5K_EEPROM_N_MODES];
+       struct ath5k_chan_pcal_info     ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
+       struct ath5k_chan_pcal_info     ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+       struct ath5k_chan_pcal_info     ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+
+       /* Per rate target power levels */
+       u8      ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES];
+       struct ath5k_rate_pcal_info     ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
+       struct ath5k_rate_pcal_info     ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+       struct ath5k_rate_pcal_info     ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+
+       /* Conformance test limits (Unused) */
+       u8      ee_ctls;
+       u8      ee_ctl[AR5K_EEPROM_MAX_CTLS];
+       struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS];
+
+       /* Noise Floor Calibration settings */
+       s16     ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
+       s8      ee_adc_desired_size[AR5K_EEPROM_N_MODES];
+       s8      ee_pga_desired_size[AR5K_EEPROM_N_MODES];
+       s8      ee_adc_desired_size_turbo[AR5K_EEPROM_N_MODES];
+       s8      ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES];
+       s8      ee_pd_gain_overlap;
+
+       u32     ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
+};
+
diff --git a/drivers/net/wireless/ath/ath5k/gpio.c b/drivers/net/wireless/ath/ath5k/gpio.c
new file mode 100644 (file)
index 0000000..64a27e7
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/****************\
+  GPIO Functions
+\****************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Set led state
+ */
+void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
+{
+       u32 led;
+       /*5210 has different led mode handling*/
+       u32 led_5210;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*Reset led status*/
+       if (ah->ah_version != AR5K_AR5210)
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
+                       AR5K_PCICFG_LEDMODE |  AR5K_PCICFG_LED);
+       else
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
+
+       /*
+        * Some blinking values, define at your wish
+        */
+       switch (state) {
+       case AR5K_LED_SCAN:
+       case AR5K_LED_AUTH:
+               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
+               led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
+               break;
+
+       case AR5K_LED_INIT:
+               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
+               led_5210 = AR5K_PCICFG_LED_PEND;
+               break;
+
+       case AR5K_LED_ASSOC:
+       case AR5K_LED_RUN:
+               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
+               led_5210 = AR5K_PCICFG_LED_ASSOC;
+               break;
+
+       default:
+               led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
+               led_5210 = AR5K_PCICFG_LED_PEND;
+               break;
+       }
+
+       /*Write new status to the register*/
+       if (ah->ah_version != AR5K_AR5210)
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
+       else
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
+}
+
+/*
+ * Set GPIO inputs
+ */
+int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (gpio >= AR5K_NUM_GPIO)
+               return -EINVAL;
+
+       ath5k_hw_reg_write(ah,
+               (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
+               | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
+
+       return 0;
+}
+
+/*
+ * Set GPIO outputs
+ */
+int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (gpio >= AR5K_NUM_GPIO)
+               return -EINVAL;
+
+       ath5k_hw_reg_write(ah,
+               (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
+               | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
+
+       return 0;
+}
+
+/*
+ * Get GPIO state
+ */
+u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (gpio >= AR5K_NUM_GPIO)
+               return 0xffffffff;
+
+       /* GPIO input magic */
+       return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
+               0x1;
+}
+
+/*
+ * Set GPIO state
+ */
+int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
+{
+       u32 data;
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (gpio >= AR5K_NUM_GPIO)
+               return -EINVAL;
+
+       /* GPIO output magic */
+       data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
+
+       data &= ~(1 << gpio);
+       data |= (val & 1) << gpio;
+
+       ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
+
+       return 0;
+}
+
+/*
+ * Initialize the GPIO interrupt (RFKill switch)
+ */
+void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
+               u32 interrupt_level)
+{
+       u32 data;
+
+       ATH5K_TRACE(ah->ah_sc);
+       if (gpio >= AR5K_NUM_GPIO)
+               return;
+
+       /*
+        * Set the GPIO interrupt
+        */
+       data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
+               ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
+               AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
+               (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
+
+       ath5k_hw_reg_write(ah, interrupt_level ? data :
+               (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
+
+       ah->ah_imr |= AR5K_IMR_GPIO;
+
+       /* Enable GPIO interrupts */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
new file mode 100644 (file)
index 0000000..61fb621
--- /dev/null
@@ -0,0 +1,1557 @@
+/*
+ * Initial register settings functions
+ *
+ * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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 "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Mode-independent initial register writes
+ */
+
+struct ath5k_ini {
+       u16     ini_register;
+       u32     ini_value;
+
+       enum {
+               AR5K_INI_WRITE = 0,     /* Default */
+               AR5K_INI_READ = 1,      /* Cleared on read */
+       } ini_mode;
+};
+
+/*
+ * Mode specific initial register values
+ */
+
+struct ath5k_ini_mode {
+       u16     mode_register;
+       u32     mode_value[5];
+};
+
+/* Initial register settings for AR5210 */
+static const struct ath5k_ini ar5210_ini[] = {
+       /* PCU and MAC registers */
+       { AR5K_NOQCU_TXDP0,     0 },
+       { AR5K_NOQCU_TXDP1,     0 },
+       { AR5K_RXDP,            0 },
+       { AR5K_CR,              0 },
+       { AR5K_ISR,             0, AR5K_INI_READ },
+       { AR5K_IMR,             0 },
+       { AR5K_IER,             AR5K_IER_DISABLE },
+       { AR5K_BSR,             0, AR5K_INI_READ },
+       { AR5K_TXCFG,           AR5K_DMASIZE_128B },
+       { AR5K_RXCFG,           AR5K_DMASIZE_128B },
+       { AR5K_CFG,             AR5K_INIT_CFG },
+       { AR5K_TOPS,            8 },
+       { AR5K_RXNOFRM,         8 },
+       { AR5K_RPGTO,           0 },
+       { AR5K_TXNOFRM,         0 },
+       { AR5K_SFR,             0 },
+       { AR5K_MIBC,            0 },
+       { AR5K_MISC,            0 },
+       { AR5K_RX_FILTER_5210,  0 },
+       { AR5K_MCAST_FILTER0_5210, 0 },
+       { AR5K_MCAST_FILTER1_5210, 0 },
+       { AR5K_TX_MASK0,        0 },
+       { AR5K_TX_MASK1,        0 },
+       { AR5K_CLR_TMASK,       0 },
+       { AR5K_TRIG_LVL,        AR5K_TUNE_MIN_TX_FIFO_THRES },
+       { AR5K_DIAG_SW_5210,    0 },
+       { AR5K_RSSI_THR,        AR5K_TUNE_RSSI_THRES },
+       { AR5K_TSF_L32_5210,    0 },
+       { AR5K_TIMER0_5210,     0 },
+       { AR5K_TIMER1_5210,     0xffffffff },
+       { AR5K_TIMER2_5210,     0xffffffff },
+       { AR5K_TIMER3_5210,     1 },
+       { AR5K_CFP_DUR_5210,    0 },
+       { AR5K_CFP_PERIOD_5210, 0 },
+       /* PHY registers */
+       { AR5K_PHY(0),  0x00000047 },
+       { AR5K_PHY_AGC, 0x00000000 },
+       { AR5K_PHY(3),  0x09848ea6 },
+       { AR5K_PHY(4),  0x3d32e000 },
+       { AR5K_PHY(5),  0x0000076b },
+       { AR5K_PHY_ACT, AR5K_PHY_ACT_DISABLE },
+       { AR5K_PHY(8),  0x02020200 },
+       { AR5K_PHY(9),  0x00000e0e },
+       { AR5K_PHY(10), 0x0a020201 },
+       { AR5K_PHY(11), 0x00036ffc },
+       { AR5K_PHY(12), 0x00000000 },
+       { AR5K_PHY(13), 0x00000e0e },
+       { AR5K_PHY(14), 0x00000007 },
+       { AR5K_PHY(15), 0x00020100 },
+       { AR5K_PHY(16), 0x89630000 },
+       { AR5K_PHY(17), 0x1372169c },
+       { AR5K_PHY(18), 0x0018b633 },
+       { AR5K_PHY(19), 0x1284613c },
+       { AR5K_PHY(20), 0x0de8b8e0 },
+       { AR5K_PHY(21), 0x00074859 },
+       { AR5K_PHY(22), 0x7e80beba },
+       { AR5K_PHY(23), 0x313a665e },
+       { AR5K_PHY_AGCCTL, 0x00001d08 },
+       { AR5K_PHY(25), 0x0001ce00 },
+       { AR5K_PHY(26), 0x409a4190 },
+       { AR5K_PHY(28), 0x0000000f },
+       { AR5K_PHY(29), 0x00000080 },
+       { AR5K_PHY(30), 0x00000004 },
+       { AR5K_PHY(31), 0x00000018 },   /* 0x987c */
+       { AR5K_PHY(64), 0x00000000 },   /* 0x9900 */
+       { AR5K_PHY(65), 0x00000000 },
+       { AR5K_PHY(66), 0x00000000 },
+       { AR5K_PHY(67), 0x00800000 },
+       { AR5K_PHY(68), 0x00000003 },
+       /* BB gain table (64bytes) */
+       { AR5K_BB_GAIN(0), 0x00000000 },
+       { AR5K_BB_GAIN(1), 0x00000020 },
+       { AR5K_BB_GAIN(2), 0x00000010 },
+       { AR5K_BB_GAIN(3), 0x00000030 },
+       { AR5K_BB_GAIN(4), 0x00000008 },
+       { AR5K_BB_GAIN(5), 0x00000028 },
+       { AR5K_BB_GAIN(6), 0x00000028 },
+       { AR5K_BB_GAIN(7), 0x00000004 },
+       { AR5K_BB_GAIN(8), 0x00000024 },
+       { AR5K_BB_GAIN(9), 0x00000014 },
+       { AR5K_BB_GAIN(10), 0x00000034 },
+       { AR5K_BB_GAIN(11), 0x0000000c },
+       { AR5K_BB_GAIN(12), 0x0000002c },
+       { AR5K_BB_GAIN(13), 0x00000002 },
+       { AR5K_BB_GAIN(14), 0x00000022 },
+       { AR5K_BB_GAIN(15), 0x00000012 },
+       { AR5K_BB_GAIN(16), 0x00000032 },
+       { AR5K_BB_GAIN(17), 0x0000000a },
+       { AR5K_BB_GAIN(18), 0x0000002a },
+       { AR5K_BB_GAIN(19), 0x00000001 },
+       { AR5K_BB_GAIN(20), 0x00000021 },
+       { AR5K_BB_GAIN(21), 0x00000011 },
+       { AR5K_BB_GAIN(22), 0x00000031 },
+       { AR5K_BB_GAIN(23), 0x00000009 },
+       { AR5K_BB_GAIN(24), 0x00000029 },
+       { AR5K_BB_GAIN(25), 0x00000005 },
+       { AR5K_BB_GAIN(26), 0x00000025 },
+       { AR5K_BB_GAIN(27), 0x00000015 },
+       { AR5K_BB_GAIN(28), 0x00000035 },
+       { AR5K_BB_GAIN(29), 0x0000000d },
+       { AR5K_BB_GAIN(30), 0x0000002d },
+       { AR5K_BB_GAIN(31), 0x00000003 },
+       { AR5K_BB_GAIN(32), 0x00000023 },
+       { AR5K_BB_GAIN(33), 0x00000013 },
+       { AR5K_BB_GAIN(34), 0x00000033 },
+       { AR5K_BB_GAIN(35), 0x0000000b },
+       { AR5K_BB_GAIN(36), 0x0000002b },
+       { AR5K_BB_GAIN(37), 0x00000007 },
+       { AR5K_BB_GAIN(38), 0x00000027 },
+       { AR5K_BB_GAIN(39), 0x00000017 },
+       { AR5K_BB_GAIN(40), 0x00000037 },
+       { AR5K_BB_GAIN(41), 0x0000000f },
+       { AR5K_BB_GAIN(42), 0x0000002f },
+       { AR5K_BB_GAIN(43), 0x0000002f },
+       { AR5K_BB_GAIN(44), 0x0000002f },
+       { AR5K_BB_GAIN(45), 0x0000002f },
+       { AR5K_BB_GAIN(46), 0x0000002f },
+       { AR5K_BB_GAIN(47), 0x0000002f },
+       { AR5K_BB_GAIN(48), 0x0000002f },
+       { AR5K_BB_GAIN(49), 0x0000002f },
+       { AR5K_BB_GAIN(50), 0x0000002f },
+       { AR5K_BB_GAIN(51), 0x0000002f },
+       { AR5K_BB_GAIN(52), 0x0000002f },
+       { AR5K_BB_GAIN(53), 0x0000002f },
+       { AR5K_BB_GAIN(54), 0x0000002f },
+       { AR5K_BB_GAIN(55), 0x0000002f },
+       { AR5K_BB_GAIN(56), 0x0000002f },
+       { AR5K_BB_GAIN(57), 0x0000002f },
+       { AR5K_BB_GAIN(58), 0x0000002f },
+       { AR5K_BB_GAIN(59), 0x0000002f },
+       { AR5K_BB_GAIN(60), 0x0000002f },
+       { AR5K_BB_GAIN(61), 0x0000002f },
+       { AR5K_BB_GAIN(62), 0x0000002f },
+       { AR5K_BB_GAIN(63), 0x0000002f },
+       /* 5110 RF gain table (64btes) */
+       { AR5K_RF_GAIN(0), 0x0000001d },
+       { AR5K_RF_GAIN(1), 0x0000005d },
+       { AR5K_RF_GAIN(2), 0x0000009d },
+       { AR5K_RF_GAIN(3), 0x000000dd },
+       { AR5K_RF_GAIN(4), 0x0000011d },
+       { AR5K_RF_GAIN(5), 0x00000021 },
+       { AR5K_RF_GAIN(6), 0x00000061 },
+       { AR5K_RF_GAIN(7), 0x000000a1 },
+       { AR5K_RF_GAIN(8), 0x000000e1 },
+       { AR5K_RF_GAIN(9), 0x00000031 },
+       { AR5K_RF_GAIN(10), 0x00000071 },
+       { AR5K_RF_GAIN(11), 0x000000b1 },
+       { AR5K_RF_GAIN(12), 0x0000001c },
+       { AR5K_RF_GAIN(13), 0x0000005c },
+       { AR5K_RF_GAIN(14), 0x00000029 },
+       { AR5K_RF_GAIN(15), 0x00000069 },
+       { AR5K_RF_GAIN(16), 0x000000a9 },
+       { AR5K_RF_GAIN(17), 0x00000020 },
+       { AR5K_RF_GAIN(18), 0x00000019 },
+       { AR5K_RF_GAIN(19), 0x00000059 },
+       { AR5K_RF_GAIN(20), 0x00000099 },
+       { AR5K_RF_GAIN(21), 0x00000030 },
+       { AR5K_RF_GAIN(22), 0x00000005 },
+       { AR5K_RF_GAIN(23), 0x00000025 },
+       { AR5K_RF_GAIN(24), 0x00000065 },
+       { AR5K_RF_GAIN(25), 0x000000a5 },
+       { AR5K_RF_GAIN(26), 0x00000028 },
+       { AR5K_RF_GAIN(27), 0x00000068 },
+       { AR5K_RF_GAIN(28), 0x0000001f },
+       { AR5K_RF_GAIN(29), 0x0000001e },
+       { AR5K_RF_GAIN(30), 0x00000018 },
+       { AR5K_RF_GAIN(31), 0x00000058 },
+       { AR5K_RF_GAIN(32), 0x00000098 },
+       { AR5K_RF_GAIN(33), 0x00000003 },
+       { AR5K_RF_GAIN(34), 0x00000004 },
+       { AR5K_RF_GAIN(35), 0x00000044 },
+       { AR5K_RF_GAIN(36), 0x00000084 },
+       { AR5K_RF_GAIN(37), 0x00000013 },
+       { AR5K_RF_GAIN(38), 0x00000012 },
+       { AR5K_RF_GAIN(39), 0x00000052 },
+       { AR5K_RF_GAIN(40), 0x00000092 },
+       { AR5K_RF_GAIN(41), 0x000000d2 },
+       { AR5K_RF_GAIN(42), 0x0000002b },
+       { AR5K_RF_GAIN(43), 0x0000002a },
+       { AR5K_RF_GAIN(44), 0x0000006a },
+       { AR5K_RF_GAIN(45), 0x000000aa },
+       { AR5K_RF_GAIN(46), 0x0000001b },
+       { AR5K_RF_GAIN(47), 0x0000001a },
+       { AR5K_RF_GAIN(48), 0x0000005a },
+       { AR5K_RF_GAIN(49), 0x0000009a },
+       { AR5K_RF_GAIN(50), 0x000000da },
+       { AR5K_RF_GAIN(51), 0x00000006 },
+       { AR5K_RF_GAIN(52), 0x00000006 },
+       { AR5K_RF_GAIN(53), 0x00000006 },
+       { AR5K_RF_GAIN(54), 0x00000006 },
+       { AR5K_RF_GAIN(55), 0x00000006 },
+       { AR5K_RF_GAIN(56), 0x00000006 },
+       { AR5K_RF_GAIN(57), 0x00000006 },
+       { AR5K_RF_GAIN(58), 0x00000006 },
+       { AR5K_RF_GAIN(59), 0x00000006 },
+       { AR5K_RF_GAIN(60), 0x00000006 },
+       { AR5K_RF_GAIN(61), 0x00000006 },
+       { AR5K_RF_GAIN(62), 0x00000006 },
+       { AR5K_RF_GAIN(63), 0x00000006 },
+       /* PHY activation */
+       { AR5K_PHY(53), 0x00000020 },
+       { AR5K_PHY(51), 0x00000004 },
+       { AR5K_PHY(50), 0x00060106 },
+       { AR5K_PHY(39), 0x0000006d },
+       { AR5K_PHY(48), 0x00000000 },
+       { AR5K_PHY(52), 0x00000014 },
+       { AR5K_PHY_ACT, AR5K_PHY_ACT_ENABLE },
+};
+
+/* Initial register settings for AR5211 */
+static const struct ath5k_ini ar5211_ini[] = {
+       { AR5K_RXDP,            0x00000000 },
+       { AR5K_RTSD0,           0x84849c9c },
+       { AR5K_RTSD1,           0x7c7c7c7c },
+       { AR5K_RXCFG,           0x00000005 },
+       { AR5K_MIBC,            0x00000000 },
+       { AR5K_TOPS,            0x00000008 },
+       { AR5K_RXNOFRM,         0x00000008 },
+       { AR5K_TXNOFRM,         0x00000010 },
+       { AR5K_RPGTO,           0x00000000 },
+       { AR5K_RFCNT,           0x0000001f },
+       { AR5K_QUEUE_TXDP(0),   0x00000000 },
+       { AR5K_QUEUE_TXDP(1),   0x00000000 },
+       { AR5K_QUEUE_TXDP(2),   0x00000000 },
+       { AR5K_QUEUE_TXDP(3),   0x00000000 },
+       { AR5K_QUEUE_TXDP(4),   0x00000000 },
+       { AR5K_QUEUE_TXDP(5),   0x00000000 },
+       { AR5K_QUEUE_TXDP(6),   0x00000000 },
+       { AR5K_QUEUE_TXDP(7),   0x00000000 },
+       { AR5K_QUEUE_TXDP(8),   0x00000000 },
+       { AR5K_QUEUE_TXDP(9),   0x00000000 },
+       { AR5K_DCU_FP,          0x00000000 },
+       { AR5K_STA_ID1,         0x00000000 },
+       { AR5K_BSS_ID0,         0x00000000 },
+       { AR5K_BSS_ID1,         0x00000000 },
+       { AR5K_RSSI_THR,        0x00000000 },
+       { AR5K_CFP_PERIOD_5211, 0x00000000 },
+       { AR5K_TIMER0_5211,     0x00000030 },
+       { AR5K_TIMER1_5211,     0x0007ffff },
+       { AR5K_TIMER2_5211,     0x01ffffff },
+       { AR5K_TIMER3_5211,     0x00000031 },
+       { AR5K_CFP_DUR_5211,    0x00000000 },
+       { AR5K_RX_FILTER_5211,  0x00000000 },
+       { AR5K_MCAST_FILTER0_5211, 0x00000000 },
+       { AR5K_MCAST_FILTER1_5211, 0x00000002 },
+       { AR5K_DIAG_SW_5211,    0x00000000 },
+       { AR5K_ADDAC_TEST,      0x00000000 },
+       { AR5K_DEFAULT_ANTENNA, 0x00000000 },
+       /* PHY registers */
+       { AR5K_PHY_AGC, 0x00000000 },
+       { AR5K_PHY(3),  0x2d849093 },
+       { AR5K_PHY(4),  0x7d32e000 },
+       { AR5K_PHY(5),  0x00000f6b },
+       { AR5K_PHY_ACT, 0x00000000 },
+       { AR5K_PHY(11), 0x00026ffe },
+       { AR5K_PHY(12), 0x00000000 },
+       { AR5K_PHY(15), 0x00020100 },
+       { AR5K_PHY(16), 0x206a017a },
+       { AR5K_PHY(19), 0x1284613c },
+       { AR5K_PHY(21), 0x00000859 },
+       { AR5K_PHY(26), 0x409a4190 },   /* 0x9868 */
+       { AR5K_PHY(27), 0x050cb081 },
+       { AR5K_PHY(28), 0x0000000f },
+       { AR5K_PHY(29), 0x00000080 },
+       { AR5K_PHY(30), 0x0000000c },
+       { AR5K_PHY(64), 0x00000000 },
+       { AR5K_PHY(65), 0x00000000 },
+       { AR5K_PHY(66), 0x00000000 },
+       { AR5K_PHY(67), 0x00800000 },
+       { AR5K_PHY(68), 0x00000001 },
+       { AR5K_PHY(71), 0x0000092a },
+       { AR5K_PHY_IQ,  0x00000000 },
+       { AR5K_PHY(73), 0x00058a05 },
+       { AR5K_PHY(74), 0x00000001 },
+       { AR5K_PHY(75), 0x00000000 },
+       { AR5K_PHY_PAPD_PROBE, 0x00000000 },
+       { AR5K_PHY(77), 0x00000000 },   /* 0x9934 */
+       { AR5K_PHY(78), 0x00000000 },   /* 0x9938 */
+       { AR5K_PHY(79), 0x0000003f },   /* 0x993c */
+       { AR5K_PHY(80), 0x00000004 },
+       { AR5K_PHY(82), 0x00000000 },
+       { AR5K_PHY(83), 0x00000000 },
+       { AR5K_PHY(84), 0x00000000 },
+       { AR5K_PHY_RADAR, 0x5d50f14c },
+       { AR5K_PHY(86), 0x00000018 },
+       { AR5K_PHY(87), 0x004b6a8e },
+       /* Initial Power table (32bytes)
+        * common on all cards/modes.
+        * Note: Table is rewritten during
+        * txpower setup later using calibration
+        * data etc. so next write is non-common */
+       { AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff },
+       { AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff },
+       { AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff },
+       { AR5K_PHY_PCDAC_TXPOWER(4), 0x09ff09ff },
+       { AR5K_PHY_PCDAC_TXPOWER(5), 0x0aff0aff },
+       { AR5K_PHY_PCDAC_TXPOWER(6), 0x0bff0bff },
+       { AR5K_PHY_PCDAC_TXPOWER(7), 0x0cff0cff },
+       { AR5K_PHY_PCDAC_TXPOWER(8), 0x0dff0dff },
+       { AR5K_PHY_PCDAC_TXPOWER(9), 0x0fff0eff },
+       { AR5K_PHY_PCDAC_TXPOWER(10), 0x12ff12ff },
+       { AR5K_PHY_PCDAC_TXPOWER(11), 0x14ff13ff },
+       { AR5K_PHY_PCDAC_TXPOWER(12), 0x16ff15ff },
+       { AR5K_PHY_PCDAC_TXPOWER(13), 0x19ff17ff },
+       { AR5K_PHY_PCDAC_TXPOWER(14), 0x1bff1aff },
+       { AR5K_PHY_PCDAC_TXPOWER(15), 0x1eff1dff },
+       { AR5K_PHY_PCDAC_TXPOWER(16), 0x23ff20ff },
+       { AR5K_PHY_PCDAC_TXPOWER(17), 0x27ff25ff },
+       { AR5K_PHY_PCDAC_TXPOWER(18), 0x2cff29ff },
+       { AR5K_PHY_PCDAC_TXPOWER(19), 0x31ff2fff },
+       { AR5K_PHY_PCDAC_TXPOWER(20), 0x37ff34ff },
+       { AR5K_PHY_PCDAC_TXPOWER(21), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(22), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(23), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(24), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(25), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(26), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(27), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },
+       { AR5K_PHY_CCKTXCTL, 0x00000000 },
+       { AR5K_PHY(642), 0x503e4646 },
+       { AR5K_PHY_GAIN_2GHZ, 0x6480416c },
+       { AR5K_PHY(644), 0x0199a003 },
+       { AR5K_PHY(645), 0x044cd610 },
+       { AR5K_PHY(646), 0x13800040 },
+       { AR5K_PHY(647), 0x1be00060 },
+       { AR5K_PHY(648), 0x0c53800a },
+       { AR5K_PHY(649), 0x0014df3b },
+       { AR5K_PHY(650), 0x000001b5 },
+       { AR5K_PHY(651), 0x00000020 },
+};
+
+/* Initial mode-specific settings for AR5211
+ * 5211 supports OFDM-only g (draft g) but we
+ * need to test it !
+ */
+static const struct ath5k_ini_mode ar5211_ini_mode[] = {
+       { AR5K_TXCFG,
+       /*        a         aTurbo        b       g (OFDM)    */
+          { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(1),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(2),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(3),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(4),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(5),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(6),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(7),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(8),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(9),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_DCU_GBL_IFS_SLOT,
+          { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
+       { AR5K_DCU_GBL_IFS_SIFS,
+          { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
+       { AR5K_DCU_GBL_IFS_EIFS,
+          { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
+       { AR5K_DCU_GBL_IFS_MISC,
+          { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
+       { AR5K_TIME_OUT,
+          { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
+       { AR5K_USEC_5211,
+          { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
+       { AR5K_PHY_TURBO,
+          { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
+       { AR5K_PHY(8),
+          { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
+       { AR5K_PHY(9),
+          { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
+       { AR5K_PHY(10),
+          { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
+       { AR5K_PHY(13),
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY(14),
+          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY(17),
+          { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
+       { AR5K_PHY(18),
+          { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
+       { AR5K_PHY(20),
+          { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
+       { AR5K_PHY_SIG,
+          { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
+       { AR5K_PHY_AGCCTL,
+          { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
+       { AR5K_PHY_NF,
+          { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
+       { AR5K_PHY(70),
+          { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
+       { AR5K_PHY_PCDAC_TXPOWER_BASE,
+          { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
+       { AR5K_RF_BUFFER_CONTROL_4,
+          { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
+};
+
+/* Initial register settings for AR5212 */
+static const struct ath5k_ini ar5212_ini_common_start[] = {
+       { AR5K_RXDP,            0x00000000 },
+       { AR5K_RXCFG,           0x00000005 },
+       { AR5K_MIBC,            0x00000000 },
+       { AR5K_TOPS,            0x00000008 },
+       { AR5K_RXNOFRM,         0x00000008 },
+       { AR5K_TXNOFRM,         0x00000010 },
+       { AR5K_RPGTO,           0x00000000 },
+       { AR5K_RFCNT,           0x0000001f },
+       { AR5K_QUEUE_TXDP(0),   0x00000000 },
+       { AR5K_QUEUE_TXDP(1),   0x00000000 },
+       { AR5K_QUEUE_TXDP(2),   0x00000000 },
+       { AR5K_QUEUE_TXDP(3),   0x00000000 },
+       { AR5K_QUEUE_TXDP(4),   0x00000000 },
+       { AR5K_QUEUE_TXDP(5),   0x00000000 },
+       { AR5K_QUEUE_TXDP(6),   0x00000000 },
+       { AR5K_QUEUE_TXDP(7),   0x00000000 },
+       { AR5K_QUEUE_TXDP(8),   0x00000000 },
+       { AR5K_QUEUE_TXDP(9),   0x00000000 },
+       { AR5K_DCU_FP,          0x00000000 },
+       { AR5K_DCU_TXP,         0x00000000 },
+       /* Tx filter table 0 (32 entries) */
+       { AR5K_DCU_TX_FILTER_0(0),  0x00000000 }, /* DCU 0 */
+       { AR5K_DCU_TX_FILTER_0(1),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(2),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(3),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(4),  0x00000000 }, /* DCU 1 */
+       { AR5K_DCU_TX_FILTER_0(5),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(6),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(7),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(8),  0x00000000 }, /* DCU 2 */
+       { AR5K_DCU_TX_FILTER_0(9),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(10), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(11), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(12), 0x00000000 }, /* DCU 3 */
+       { AR5K_DCU_TX_FILTER_0(13), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(14), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(15), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(16), 0x00000000 }, /* DCU 4 */
+       { AR5K_DCU_TX_FILTER_0(17), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(18), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(19), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(20), 0x00000000 }, /* DCU 5 */
+       { AR5K_DCU_TX_FILTER_0(21), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(22), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(23), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(24), 0x00000000 }, /* DCU 6 */
+       { AR5K_DCU_TX_FILTER_0(25), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(26), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(27), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(28), 0x00000000 }, /* DCU 7 */
+       { AR5K_DCU_TX_FILTER_0(29), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(30), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(31), 0x00000000 },
+       /* Tx filter table 1 (16 entries) */
+       { AR5K_DCU_TX_FILTER_1(0),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(1),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(2),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(3),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(4),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(5),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(6),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(7),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(8),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(9),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(10), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(11), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(12), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(13), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(14), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
+       { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
+       { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
+       { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
+       { AR5K_STA_ID1,         0x00000000 },
+       { AR5K_BSS_ID0,         0x00000000 },
+       { AR5K_BSS_ID1,         0x00000000 },
+       { AR5K_BEACON_5211,     0x00000000 },
+       { AR5K_CFP_PERIOD_5211, 0x00000000 },
+       { AR5K_TIMER0_5211,     0x00000030 },
+       { AR5K_TIMER1_5211,     0x0007ffff },
+       { AR5K_TIMER2_5211,     0x01ffffff },
+       { AR5K_TIMER3_5211,     0x00000031 },
+       { AR5K_CFP_DUR_5211,    0x00000000 },
+       { AR5K_RX_FILTER_5211,  0x00000000 },
+       { AR5K_DIAG_SW_5211,    0x00000000 },
+       { AR5K_ADDAC_TEST,      0x00000000 },
+       { AR5K_DEFAULT_ANTENNA, 0x00000000 },
+       { AR5K_FRAME_CTL_QOSM,  0x000fc78f },
+       { AR5K_XRMODE,          0x2a82301a },
+       { AR5K_XRDELAY,         0x05dc01e0 },
+       { AR5K_XRTIMEOUT,       0x1f402710 },
+       { AR5K_XRCHIRP,         0x01f40000 },
+       { AR5K_XRSTOMP,         0x00001e1c },
+       { AR5K_SLEEP0,          0x0002aaaa },
+       { AR5K_SLEEP1,          0x02005555 },
+       { AR5K_SLEEP2,          0x00000000 },
+       { AR5K_BSS_IDM0,        0xffffffff },
+       { AR5K_BSS_IDM1,        0x0000ffff },
+       { AR5K_TXPC,            0x00000000 },
+       { AR5K_PROFCNT_TX,      0x00000000 },
+       { AR5K_PROFCNT_RX,      0x00000000 },
+       { AR5K_PROFCNT_RXCLR,   0x00000000 },
+       { AR5K_PROFCNT_CYCLE,   0x00000000 },
+       { AR5K_QUIET_CTL1,      0x00000088 },
+       /* Initial rate duration table (32 entries )*/
+       { AR5K_RATE_DUR(0),     0x00000000 },
+       { AR5K_RATE_DUR(1),     0x0000008c },
+       { AR5K_RATE_DUR(2),     0x000000e4 },
+       { AR5K_RATE_DUR(3),     0x000002d5 },
+       { AR5K_RATE_DUR(4),     0x00000000 },
+       { AR5K_RATE_DUR(5),     0x00000000 },
+       { AR5K_RATE_DUR(6),     0x000000a0 },
+       { AR5K_RATE_DUR(7),     0x000001c9 },
+       { AR5K_RATE_DUR(8),     0x0000002c },
+       { AR5K_RATE_DUR(9),     0x0000002c },
+       { AR5K_RATE_DUR(10),    0x00000030 },
+       { AR5K_RATE_DUR(11),    0x0000003c },
+       { AR5K_RATE_DUR(12),    0x0000002c },
+       { AR5K_RATE_DUR(13),    0x0000002c },
+       { AR5K_RATE_DUR(14),    0x00000030 },
+       { AR5K_RATE_DUR(15),    0x0000003c },
+       { AR5K_RATE_DUR(16),    0x00000000 },
+       { AR5K_RATE_DUR(17),    0x00000000 },
+       { AR5K_RATE_DUR(18),    0x00000000 },
+       { AR5K_RATE_DUR(19),    0x00000000 },
+       { AR5K_RATE_DUR(20),    0x00000000 },
+       { AR5K_RATE_DUR(21),    0x00000000 },
+       { AR5K_RATE_DUR(22),    0x00000000 },
+       { AR5K_RATE_DUR(23),    0x00000000 },
+       { AR5K_RATE_DUR(24),    0x000000d5 },
+       { AR5K_RATE_DUR(25),    0x000000df },
+       { AR5K_RATE_DUR(26),    0x00000102 },
+       { AR5K_RATE_DUR(27),    0x0000013a },
+       { AR5K_RATE_DUR(28),    0x00000075 },
+       { AR5K_RATE_DUR(29),    0x0000007f },
+       { AR5K_RATE_DUR(30),    0x000000a2 },
+       { AR5K_RATE_DUR(31),    0x00000000 },
+       { AR5K_QUIET_CTL2,      0x00010002 },
+       { AR5K_TSF_PARM,        0x00000001 },
+       { AR5K_QOS_NOACK,       0x000000c0 },
+       { AR5K_PHY_ERR_FIL,     0x00000000 },
+       { AR5K_XRLAT_TX,        0x00000168 },
+       { AR5K_ACKSIFS,         0x00000000 },
+       /* Rate -> db table
+        * notice ...03<-02<-01<-00 ! */
+       { AR5K_RATE2DB(0),      0x03020100 },
+       { AR5K_RATE2DB(1),      0x07060504 },
+       { AR5K_RATE2DB(2),      0x0b0a0908 },
+       { AR5K_RATE2DB(3),      0x0f0e0d0c },
+       { AR5K_RATE2DB(4),      0x13121110 },
+       { AR5K_RATE2DB(5),      0x17161514 },
+       { AR5K_RATE2DB(6),      0x1b1a1918 },
+       { AR5K_RATE2DB(7),      0x1f1e1d1c },
+       /* Db -> Rate table */
+       { AR5K_DB2RATE(0),      0x03020100 },
+       { AR5K_DB2RATE(1),      0x07060504 },
+       { AR5K_DB2RATE(2),      0x0b0a0908 },
+       { AR5K_DB2RATE(3),      0x0f0e0d0c },
+       { AR5K_DB2RATE(4),      0x13121110 },
+       { AR5K_DB2RATE(5),      0x17161514 },
+       { AR5K_DB2RATE(6),      0x1b1a1918 },
+       { AR5K_DB2RATE(7),      0x1f1e1d1c },
+       /* PHY registers (Common settings
+        * for all chips/modes) */
+       { AR5K_PHY(3),          0xad848e19 },
+       { AR5K_PHY(4),          0x7d28e000 },
+       { AR5K_PHY_TIMING_3,    0x9c0a9f6b },
+       { AR5K_PHY_ACT,         0x00000000 },
+       { AR5K_PHY(16),         0x206a017a },
+       { AR5K_PHY(21),         0x00000859 },
+       { AR5K_PHY_BIN_MASK_1,  0x00000000 },
+       { AR5K_PHY_BIN_MASK_2,  0x00000000 },
+       { AR5K_PHY_BIN_MASK_3,  0x00000000 },
+       { AR5K_PHY_BIN_MASK_CTL, 0x00800000 },
+       { AR5K_PHY_ANT_CTL,     0x00000001 },
+       /*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
+       { AR5K_PHY_MAX_RX_LEN,  0x00000c80 },
+       { AR5K_PHY_IQ,          0x05100000 },
+       { AR5K_PHY_WARM_RESET,  0x00000001 },
+       { AR5K_PHY_CTL,         0x00000004 },
+       { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
+       { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
+       { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
+       { AR5K_PHY(82),         0x9280b212 },
+       { AR5K_PHY_RADAR,       0x5d50e188 },
+       /*{ AR5K_PHY(86), 0x000000ff },*/
+       { AR5K_PHY(87),         0x004b6a8e },
+       { AR5K_PHY_NFTHRES,     0x000003ce },
+       { AR5K_PHY_RESTART,     0x192fb515 },
+       { AR5K_PHY(94),         0x00000001 },
+       { AR5K_PHY_RFBUS_REQ,   0x00000000 },
+       /*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */
+       /*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */
+       { AR5K_PHY(644),        0x00806333 },
+       { AR5K_PHY(645),        0x00106c10 },
+       { AR5K_PHY(646),        0x009c4060 },
+       /* { AR5K_PHY(647), 0x1483800a }, */
+       /* { AR5K_PHY(648), 0x01831061 }, */ /* Old value */
+       { AR5K_PHY(648),        0x018830c6 },
+       { AR5K_PHY(649),        0x00000400 },
+       /*{ AR5K_PHY(650), 0x000001b5 },*/
+       { AR5K_PHY(651),        0x00000000 },
+       { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
+       { AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
+       /*{ AR5K_PHY(655), 0x13c889af },*/
+       { AR5K_PHY(656),        0x38490a20 },
+       { AR5K_PHY(657),        0x00007bb6 },
+       { AR5K_PHY(658),        0x0fff3ffc },
+};
+
+/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
+static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
+       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(1),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(2),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(3),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(4),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(5),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(6),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(7),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(8),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(9),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_DCU_GBL_IFS_SIFS,
+          { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
+       { AR5K_DCU_GBL_IFS_SLOT,
+          { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
+       { AR5K_DCU_GBL_IFS_EIFS,
+          { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
+       { AR5K_DCU_GBL_IFS_MISC,
+          { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
+       { AR5K_TIME_OUT,
+          { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
+       { AR5K_PHY_TURBO,
+          { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
+       { AR5K_PHY(8),
+          { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
+       { AR5K_PHY_RF_CTL2,
+          { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_SETTLING,
+          { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
+       { AR5K_PHY_AGCCTL,
+          { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
+       { AR5K_PHY_NF,
+          { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+       { AR5K_PHY_WEAK_OFDM_HIGH_THR,
+          { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
+       { AR5K_PHY(70),
+          { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
+       { AR5K_PHY_OFDM_SELFCORR,
+          { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
+       { 0xa230,
+          { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
+};
+
+/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
+static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+       { AR5K_USEC_5211,
+          { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY_GAIN,
+          { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+       { AR5K_PHY_SIG,
+          { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5111_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x00022ffe },
+       { 0x983c,               0x00020100 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
+       { AR5K_PHY_PAPD_PROBE,  0x00004883 },
+       { 0x9940,               0x00000004 },
+       { 0x9958,               0x000000ff },
+       { 0x9974,               0x00000000 },
+       { AR5K_PHY_SPENDING,    0x00000018 },
+       { AR5K_PHY_CCKTXCTL,    0x00000000 },
+       { AR5K_PHY_CCK_CROSSCORR, 0xd03e6788 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
+       { 0xa23c,               0x13c889af },
+};
+
+/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
+static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+       { AR5K_USEC_5211,
+          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY_GAIN,
+          { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+       { AR5K_PHY_SIG,
+          { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
+       { AR5K_PHY_CCKTXCTL,
+          { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
+       { AR5K_PHY_CCK_CROSSCORR,
+          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5112_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x00022ffe },
+       { 0x983c,               0x00020100 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
+       { AR5K_PHY_PAPD_PROBE,  0x00004882 },
+       { 0x9940,               0x00000004 },
+       { 0x9958,               0x000000ff },
+       { 0x9974,               0x00000000 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
+       { 0xa23c,               0x13c889af },
+};
+
+/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
+static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+       { AR5K_USEC_5211,
+          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY_GAIN,
+          { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+       { AR5K_PHY_SIG,
+          { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+       { AR5K_PHY_CCKTXCTL,
+          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_CCK_CROSSCORR,
+          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+       { 0xa300,
+          { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
+       { 0xa304,
+          { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
+       { 0xa308,
+          { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
+       { 0xa30c,
+          { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
+       { 0xa310,
+          { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
+       { 0xa314,
+          { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
+       { 0xa318,
+          { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
+       { 0xa31c,
+          { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
+       { 0xa320,
+          { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
+       { 0xa324,
+          { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
+       { 0xa328,
+          { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
+       { 0xa32c,
+          { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
+       { 0xa330,
+          { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
+       { 0xa334,
+          { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
+};
+
+static const struct ath5k_ini rf5413_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x000003e0 },
+       { AR5K_5414_CBCFG,      0x00000010 },
+       { AR5K_SEQ_MASK,        0x0000000f },
+       { 0x809c,               0x00000000 },
+       { 0x80a0,               0x00000000 },
+       { AR5K_MIC_QOS_CTL,     0x00000000 },
+       { AR5K_MIC_QOS_SEL,     0x00000000 },
+       { AR5K_MISC_MODE,       0x00000000 },
+       { AR5K_OFDM_FIL_CNT,    0x00000000 },
+       { AR5K_CCK_FIL_CNT,     0x00000000 },
+       { AR5K_PHYERR_CNT1,     0x00000000 },
+       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+       { AR5K_PHYERR_CNT2,     0x00000000 },
+       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+       { AR5K_TSF_THRES,       0x00000000 },
+       { 0x8140,               0x800003f9 },
+       { 0x8144,               0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x0000a000 },
+       { 0x983c,               0x00200400 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+       { AR5K_PHY_SCR,         0x0000001f },
+       { AR5K_PHY_SLMT,        0x00000080 },
+       { AR5K_PHY_SCAL,        0x0000000e },
+       { 0x9958,               0x00081fff },
+       { AR5K_PHY_TIMING_7,    0x00000000 },
+       { AR5K_PHY_TIMING_8,    0x02800000 },
+       { AR5K_PHY_TIMING_11,   0x00000000 },
+       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+       { 0x99e4,               0xaaaaaaaa },
+       { 0x99e8,               0x3c466478 },
+       { 0x99ec,               0x000000aa },
+       { AR5K_PHY_SCLOCK,      0x0000000c },
+       { AR5K_PHY_SDELAY,      0x000000ff },
+       { AR5K_PHY_SPENDING,    0x00000014 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+       { 0xa23c,               0x93c889af },
+       { AR5K_PHY_FAST_ADC,    0x00000001 },
+       { 0xa250,               0x0000a000 },
+       { AR5K_PHY_BLUETOOTH,   0x00000000 },
+       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
+       { 0xa25c,               0x0f0f0f01 },
+       { 0xa260,               0x5f690f01 },
+       { 0xa264,               0x00418a11 },
+       { 0xa268,               0x00000000 },
+       { AR5K_PHY_TPC_RG5,     0x0c30c16a },
+       { 0xa270, 0x00820820 },
+       { 0xa274, 0x081b7caa },
+       { 0xa278, 0x1ce739ce },
+       { 0xa27c, 0x051701ce },
+       { 0xa338, 0x00000000 },
+       { 0xa33c, 0x00000000 },
+       { 0xa340, 0x00000000 },
+       { 0xa344, 0x00000000 },
+       { 0xa348, 0x3fffffff },
+       { 0xa34c, 0x3fffffff },
+       { 0xa350, 0x3fffffff },
+       { 0xa354, 0x0003ffff },
+       { 0xa358, 0x79a8aa1f },
+       { 0xa35c, 0x066c420f },
+       { 0xa360, 0x0f282207 },
+       { 0xa364, 0x17601685 },
+       { 0xa368, 0x1f801104 },
+       { 0xa36c, 0x37a00c03 },
+       { 0xa370, 0x3fc40883 },
+       { 0xa374, 0x57c00803 },
+       { 0xa378, 0x5fd80682 },
+       { 0xa37c, 0x7fe00482 },
+       { 0xa380, 0x7f3c7bba },
+       { 0xa384, 0xf3307ff0 },
+};
+
+/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
+/* XXX: a mode ? */
+static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+       { AR5K_USEC_5211,
+          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
+       { AR5K_PHY_GAIN,
+          { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
+       { AR5K_PHY_SIG,
+          { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+       { AR5K_PHY_CCKTXCTL,
+          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_CCK_CROSSCORR,
+          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf2413_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x000003e0 },
+       { AR5K_SEQ_MASK,        0x0000000f },
+       { AR5K_MIC_QOS_CTL,     0x00000000 },
+       { AR5K_MIC_QOS_SEL,     0x00000000 },
+       { AR5K_MISC_MODE,       0x00000000 },
+       { AR5K_OFDM_FIL_CNT,    0x00000000 },
+       { AR5K_CCK_FIL_CNT,     0x00000000 },
+       { AR5K_PHYERR_CNT1,     0x00000000 },
+       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+       { AR5K_PHYERR_CNT2,     0x00000000 },
+       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+       { AR5K_TSF_THRES,       0x00000000 },
+       { 0x8140,               0x800000a8 },
+       { 0x8144,               0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x0000a000 },
+       { 0x983c,               0x00200400 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+       { AR5K_PHY_SCR,         0x0000001f },
+       { AR5K_PHY_SLMT,        0x00000080 },
+       { AR5K_PHY_SCAL,        0x0000000e },
+       { 0x9958,               0x000000ff },
+       { AR5K_PHY_TIMING_7,    0x00000000 },
+       { AR5K_PHY_TIMING_8,    0x02800000 },
+       { AR5K_PHY_TIMING_11,   0x00000000 },
+       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+       { 0x99e4,               0xaaaaaaaa },
+       { 0x99e8,               0x3c466478 },
+       { 0x99ec,               0x000000aa },
+       { AR5K_PHY_SCLOCK,      0x0000000c },
+       { AR5K_PHY_SDELAY,      0x000000ff },
+       { AR5K_PHY_SPENDING,    0x00000014 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+       { 0xa23c,               0x93c889af },
+       { AR5K_PHY_FAST_ADC,    0x00000001 },
+       { 0xa250,               0x0000a000 },
+       { AR5K_PHY_BLUETOOTH,   0x00000000 },
+       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
+       { 0xa25c,               0x0f0f0f01 },
+       { 0xa260,               0x5f690f01 },
+       { 0xa264,               0x00418a11 },
+       { 0xa268,               0x00000000 },
+       { AR5K_PHY_TPC_RG5,     0x0c30c16a },
+       { 0xa270, 0x00820820 },
+       { 0xa274, 0x001b7caa },
+       { 0xa278, 0x1ce739ce },
+       { 0xa27c, 0x051701ce },
+       { 0xa300, 0x18010000 },
+       { 0xa304, 0x30032602 },
+       { 0xa308, 0x48073e06 },
+       { 0xa30c, 0x560b4c0a },
+       { 0xa310, 0x641a600f },
+       { 0xa314, 0x784f6e1b },
+       { 0xa318, 0x868f7c5a },
+       { 0xa31c, 0x8ecf865b },
+       { 0xa320, 0x9d4f970f },
+       { 0xa324, 0xa5cfa18f },
+       { 0xa328, 0xb55faf1f },
+       { 0xa32c, 0xbddfb99f },
+       { 0xa330, 0xcd7fc73f },
+       { 0xa334, 0xd5ffd1bf },
+       { 0xa338, 0x00000000 },
+       { 0xa33c, 0x00000000 },
+       { 0xa340, 0x00000000 },
+       { 0xa344, 0x00000000 },
+       { 0xa348, 0x3fffffff },
+       { 0xa34c, 0x3fffffff },
+       { 0xa350, 0x3fffffff },
+       { 0xa354, 0x0003ffff },
+       { 0xa358, 0x79a8aa1f },
+       { 0xa35c, 0x066c420f },
+       { 0xa360, 0x0f282207 },
+       { 0xa364, 0x17601685 },
+       { 0xa368, 0x1f801104 },
+       { 0xa36c, 0x37a00c03 },
+       { 0xa370, 0x3fc40883 },
+       { 0xa374, 0x57c00803 },
+       { 0xa378, 0x5fd80682 },
+       { 0xa37c, 0x7fe00482 },
+       { 0xa380, 0x7f3c7bba },
+       { 0xa384, 0xf3307ff0 },
+};
+
+/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */
+/* XXX: a mode ? */
+static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+       { AR5K_USEC_5211,
+          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+       { AR5K_PHY_TURBO,
+          { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY_SETTLING,
+          { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
+       { AR5K_PHY_GAIN,
+          { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+       { AR5K_PHY_SIG,
+          { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+       { AR5K_PHY_CCKTXCTL,
+          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_CCK_CROSSCORR,
+          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+       { 0xa324,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+       { 0xa328,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+       { 0xa32c,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+       { 0xa330,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+       { 0xa334,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+};
+
+static const struct ath5k_ini rf2425_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x000003e0 },
+       { AR5K_SEQ_MASK,        0x0000000f },
+       { 0x809c,               0x00000000 },
+       { 0x80a0,               0x00000000 },
+       { AR5K_MIC_QOS_CTL,     0x00000000 },
+       { AR5K_MIC_QOS_SEL,     0x00000000 },
+       { AR5K_MISC_MODE,       0x00000000 },
+       { AR5K_OFDM_FIL_CNT,    0x00000000 },
+       { AR5K_CCK_FIL_CNT,     0x00000000 },
+       { AR5K_PHYERR_CNT1,     0x00000000 },
+       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+       { AR5K_PHYERR_CNT2,     0x00000000 },
+       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+       { AR5K_TSF_THRES,       0x00000000 },
+       { 0x8140,               0x800003f9 },
+       { 0x8144,               0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x0000a000 },
+       { 0x983c,               0x00200400 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+       { AR5K_PHY_SCR,         0x0000001f },
+       { AR5K_PHY_SLMT,        0x00000080 },
+       { AR5K_PHY_SCAL,        0x0000000e },
+       { 0x9958,               0x00081fff },
+       { AR5K_PHY_TIMING_7,    0x00000000 },
+       { AR5K_PHY_TIMING_8,    0x02800000 },
+       { AR5K_PHY_TIMING_11,   0x00000000 },
+       { 0x99dc,               0xfebadbe8 },
+       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+       { 0x99e4,               0xaaaaaaaa },
+       { 0x99e8,               0x3c466478 },
+       { 0x99ec,               0x000000aa },
+       { AR5K_PHY_SCLOCK,      0x0000000c },
+       { AR5K_PHY_SDELAY,      0x000000ff },
+       { AR5K_PHY_SPENDING,    0x00000014 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+       { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
+       { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
+       { 0xa23c,               0x93c889af },
+       { AR5K_PHY_FAST_ADC,    0x00000001 },
+       { 0xa250,               0x0000a000 },
+       { AR5K_PHY_BLUETOOTH,   0x00000000 },
+       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
+       { 0xa25c,               0x0f0f0f01 },
+       { 0xa260,               0x5f690f01 },
+       { 0xa264,               0x00418a11 },
+       { 0xa268,               0x00000000 },
+       { AR5K_PHY_TPC_RG5,     0x0c30c166 },
+       { 0xa270, 0x00820820 },
+       { 0xa274, 0x081a3caa },
+       { 0xa278, 0x1ce739ce },
+       { 0xa27c, 0x051701ce },
+       { 0xa300, 0x16010000 },
+       { 0xa304, 0x2c032402 },
+       { 0xa308, 0x48433e42 },
+       { 0xa30c, 0x5a0f500b },
+       { 0xa310, 0x6c4b624a },
+       { 0xa314, 0x7e8b748a },
+       { 0xa318, 0x96cf8ccb },
+       { 0xa31c, 0xa34f9d0f },
+       { 0xa320, 0xa7cfa58f },
+       { 0xa348, 0x3fffffff },
+       { 0xa34c, 0x3fffffff },
+       { 0xa350, 0x3fffffff },
+       { 0xa354, 0x0003ffff },
+       { 0xa358, 0x79a8aa1f },
+       { 0xa35c, 0x066c420f },
+       { 0xa360, 0x0f282207 },
+       { 0xa364, 0x17601685 },
+       { 0xa368, 0x1f801104 },
+       { 0xa36c, 0x37a00c03 },
+       { 0xa370, 0x3fc40883 },
+       { 0xa374, 0x57c00803 },
+       { 0xa378, 0x5fd80682 },
+       { 0xa37c, 0x7fe00482 },
+       { 0xa380, 0x7f3c7bba },
+       { 0xa384, 0xf3307ff0 },
+};
+
+/*
+ * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with
+ * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI)
+ */
+
+/* RF5111 Initial BaseBand Gain settings */
+static const struct ath5k_ini rf5111_ini_bbgain[] = {
+       { AR5K_BB_GAIN(0), 0x00000000 },
+       { AR5K_BB_GAIN(1), 0x00000020 },
+       { AR5K_BB_GAIN(2), 0x00000010 },
+       { AR5K_BB_GAIN(3), 0x00000030 },
+       { AR5K_BB_GAIN(4), 0x00000008 },
+       { AR5K_BB_GAIN(5), 0x00000028 },
+       { AR5K_BB_GAIN(6), 0x00000004 },
+       { AR5K_BB_GAIN(7), 0x00000024 },
+       { AR5K_BB_GAIN(8), 0x00000014 },
+       { AR5K_BB_GAIN(9), 0x00000034 },
+       { AR5K_BB_GAIN(10), 0x0000000c },
+       { AR5K_BB_GAIN(11), 0x0000002c },
+       { AR5K_BB_GAIN(12), 0x00000002 },
+       { AR5K_BB_GAIN(13), 0x00000022 },
+       { AR5K_BB_GAIN(14), 0x00000012 },
+       { AR5K_BB_GAIN(15), 0x00000032 },
+       { AR5K_BB_GAIN(16), 0x0000000a },
+       { AR5K_BB_GAIN(17), 0x0000002a },
+       { AR5K_BB_GAIN(18), 0x00000006 },
+       { AR5K_BB_GAIN(19), 0x00000026 },
+       { AR5K_BB_GAIN(20), 0x00000016 },
+       { AR5K_BB_GAIN(21), 0x00000036 },
+       { AR5K_BB_GAIN(22), 0x0000000e },
+       { AR5K_BB_GAIN(23), 0x0000002e },
+       { AR5K_BB_GAIN(24), 0x00000001 },
+       { AR5K_BB_GAIN(25), 0x00000021 },
+       { AR5K_BB_GAIN(26), 0x00000011 },
+       { AR5K_BB_GAIN(27), 0x00000031 },
+       { AR5K_BB_GAIN(28), 0x00000009 },
+       { AR5K_BB_GAIN(29), 0x00000029 },
+       { AR5K_BB_GAIN(30), 0x00000005 },
+       { AR5K_BB_GAIN(31), 0x00000025 },
+       { AR5K_BB_GAIN(32), 0x00000015 },
+       { AR5K_BB_GAIN(33), 0x00000035 },
+       { AR5K_BB_GAIN(34), 0x0000000d },
+       { AR5K_BB_GAIN(35), 0x0000002d },
+       { AR5K_BB_GAIN(36), 0x00000003 },
+       { AR5K_BB_GAIN(37), 0x00000023 },
+       { AR5K_BB_GAIN(38), 0x00000013 },
+       { AR5K_BB_GAIN(39), 0x00000033 },
+       { AR5K_BB_GAIN(40), 0x0000000b },
+       { AR5K_BB_GAIN(41), 0x0000002b },
+       { AR5K_BB_GAIN(42), 0x0000002b },
+       { AR5K_BB_GAIN(43), 0x0000002b },
+       { AR5K_BB_GAIN(44), 0x0000002b },
+       { AR5K_BB_GAIN(45), 0x0000002b },
+       { AR5K_BB_GAIN(46), 0x0000002b },
+       { AR5K_BB_GAIN(47), 0x0000002b },
+       { AR5K_BB_GAIN(48), 0x0000002b },
+       { AR5K_BB_GAIN(49), 0x0000002b },
+       { AR5K_BB_GAIN(50), 0x0000002b },
+       { AR5K_BB_GAIN(51), 0x0000002b },
+       { AR5K_BB_GAIN(52), 0x0000002b },
+       { AR5K_BB_GAIN(53), 0x0000002b },
+       { AR5K_BB_GAIN(54), 0x0000002b },
+       { AR5K_BB_GAIN(55), 0x0000002b },
+       { AR5K_BB_GAIN(56), 0x0000002b },
+       { AR5K_BB_GAIN(57), 0x0000002b },
+       { AR5K_BB_GAIN(58), 0x0000002b },
+       { AR5K_BB_GAIN(59), 0x0000002b },
+       { AR5K_BB_GAIN(60), 0x0000002b },
+       { AR5K_BB_GAIN(61), 0x0000002b },
+       { AR5K_BB_GAIN(62), 0x00000002 },
+       { AR5K_BB_GAIN(63), 0x00000016 },
+};
+
+/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */
+static const struct ath5k_ini rf5112_ini_bbgain[] = {
+       { AR5K_BB_GAIN(0), 0x00000000 },
+       { AR5K_BB_GAIN(1), 0x00000001 },
+       { AR5K_BB_GAIN(2), 0x00000002 },
+       { AR5K_BB_GAIN(3), 0x00000003 },
+       { AR5K_BB_GAIN(4), 0x00000004 },
+       { AR5K_BB_GAIN(5), 0x00000005 },
+       { AR5K_BB_GAIN(6), 0x00000008 },
+       { AR5K_BB_GAIN(7), 0x00000009 },
+       { AR5K_BB_GAIN(8), 0x0000000a },
+       { AR5K_BB_GAIN(9), 0x0000000b },
+       { AR5K_BB_GAIN(10), 0x0000000c },
+       { AR5K_BB_GAIN(11), 0x0000000d },
+       { AR5K_BB_GAIN(12), 0x00000010 },
+       { AR5K_BB_GAIN(13), 0x00000011 },
+       { AR5K_BB_GAIN(14), 0x00000012 },
+       { AR5K_BB_GAIN(15), 0x00000013 },
+       { AR5K_BB_GAIN(16), 0x00000014 },
+       { AR5K_BB_GAIN(17), 0x00000015 },
+       { AR5K_BB_GAIN(18), 0x00000018 },
+       { AR5K_BB_GAIN(19), 0x00000019 },
+       { AR5K_BB_GAIN(20), 0x0000001a },
+       { AR5K_BB_GAIN(21), 0x0000001b },
+       { AR5K_BB_GAIN(22), 0x0000001c },
+       { AR5K_BB_GAIN(23), 0x0000001d },
+       { AR5K_BB_GAIN(24), 0x00000020 },
+       { AR5K_BB_GAIN(25), 0x00000021 },
+       { AR5K_BB_GAIN(26), 0x00000022 },
+       { AR5K_BB_GAIN(27), 0x00000023 },
+       { AR5K_BB_GAIN(28), 0x00000024 },
+       { AR5K_BB_GAIN(29), 0x00000025 },
+       { AR5K_BB_GAIN(30), 0x00000028 },
+       { AR5K_BB_GAIN(31), 0x00000029 },
+       { AR5K_BB_GAIN(32), 0x0000002a },
+       { AR5K_BB_GAIN(33), 0x0000002b },
+       { AR5K_BB_GAIN(34), 0x0000002c },
+       { AR5K_BB_GAIN(35), 0x0000002d },
+       { AR5K_BB_GAIN(36), 0x00000030 },
+       { AR5K_BB_GAIN(37), 0x00000031 },
+       { AR5K_BB_GAIN(38), 0x00000032 },
+       { AR5K_BB_GAIN(39), 0x00000033 },
+       { AR5K_BB_GAIN(40), 0x00000034 },
+       { AR5K_BB_GAIN(41), 0x00000035 },
+       { AR5K_BB_GAIN(42), 0x00000035 },
+       { AR5K_BB_GAIN(43), 0x00000035 },
+       { AR5K_BB_GAIN(44), 0x00000035 },
+       { AR5K_BB_GAIN(45), 0x00000035 },
+       { AR5K_BB_GAIN(46), 0x00000035 },
+       { AR5K_BB_GAIN(47), 0x00000035 },
+       { AR5K_BB_GAIN(48), 0x00000035 },
+       { AR5K_BB_GAIN(49), 0x00000035 },
+       { AR5K_BB_GAIN(50), 0x00000035 },
+       { AR5K_BB_GAIN(51), 0x00000035 },
+       { AR5K_BB_GAIN(52), 0x00000035 },
+       { AR5K_BB_GAIN(53), 0x00000035 },
+       { AR5K_BB_GAIN(54), 0x00000035 },
+       { AR5K_BB_GAIN(55), 0x00000035 },
+       { AR5K_BB_GAIN(56), 0x00000035 },
+       { AR5K_BB_GAIN(57), 0x00000035 },
+       { AR5K_BB_GAIN(58), 0x00000035 },
+       { AR5K_BB_GAIN(59), 0x00000035 },
+       { AR5K_BB_GAIN(60), 0x00000035 },
+       { AR5K_BB_GAIN(61), 0x00000035 },
+       { AR5K_BB_GAIN(62), 0x00000010 },
+       { AR5K_BB_GAIN(63), 0x0000001a },
+};
+
+
+/*
+ * Write initial register dump
+ */
+static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
+               const struct ath5k_ini *ini_regs, bool change_channel)
+{
+       unsigned int i;
+
+       /* Write initial registers */
+       for (i = 0; i < size; i++) {
+               /* On channel change there is
+                * no need to mess with PCU */
+               if (change_channel &&
+                               ini_regs[i].ini_register >= AR5K_PCU_MIN &&
+                               ini_regs[i].ini_register <= AR5K_PCU_MAX)
+                       continue;
+
+               switch (ini_regs[i].ini_mode) {
+               case AR5K_INI_READ:
+                       /* Cleared on read */
+                       ath5k_hw_reg_read(ah, ini_regs[i].ini_register);
+                       break;
+               case AR5K_INI_WRITE:
+               default:
+                       AR5K_REG_WAIT(i);
+                       ath5k_hw_reg_write(ah, ini_regs[i].ini_value,
+                                       ini_regs[i].ini_register);
+               }
+       }
+}
+
+static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah,
+               unsigned int size, const struct ath5k_ini_mode *ini_mode,
+               u8 mode)
+{
+       unsigned int i;
+
+       for (i = 0; i < size; i++) {
+               AR5K_REG_WAIT(i);
+               ath5k_hw_reg_write(ah, ini_mode[i].mode_value[mode],
+                       (u32)ini_mode[i].mode_register);
+       }
+
+}
+
+int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
+{
+       /*
+        * Write initial register settings
+        */
+
+       /* For AR5212 and combatible */
+       if (ah->ah_version == AR5K_AR5212) {
+
+               /* First set of mode-specific settings */
+               ath5k_hw_ini_mode_registers(ah,
+                       ARRAY_SIZE(ar5212_ini_mode_start),
+                       ar5212_ini_mode_start, mode);
+
+               /*
+                * Write initial settings common for all modes
+                */
+               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
+                               ar5212_ini_common_start, change_channel);
+
+               /* Second set of mode-specific settings */
+               switch (ah->ah_radio) {
+               case AR5K_RF5111:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf5111_ini_mode_end),
+                                       rf5111_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5111_ini_common_end),
+                                       rf5111_ini_common_end, change_channel);
+
+                       /* Baseband gain table */
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5111_ini_bbgain),
+                                       rf5111_ini_bbgain, change_channel);
+
+                       break;
+               case AR5K_RF5112:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_mode_end),
+                                       rf5112_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_common_end),
+                                       rf5112_ini_common_end, change_channel);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+
+                       break;
+               case AR5K_RF5413:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf5413_ini_mode_end),
+                                       rf5413_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5413_ini_common_end),
+                                       rf5413_ini_common_end, change_channel);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+
+                       break;
+               case AR5K_RF2316:
+               case AR5K_RF2413:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf2413_ini_mode_end),
+                                       rf2413_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf2413_ini_common_end),
+                                       rf2413_ini_common_end, change_channel);
+
+                       /* Override settings from rf2413_ini_common_end */
+                       if (ah->ah_radio == AR5K_RF2316) {
+                               ath5k_hw_reg_write(ah, 0x00004000,
+                                                       AR5K_PHY_AGC);
+                               ath5k_hw_reg_write(ah, 0x081b7caa,
+                                                       0xa274);
+                       }
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+                       break;
+               case AR5K_RF2317:
+               case AR5K_RF2425:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf2425_ini_mode_end),
+                                       rf2425_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf2425_ini_common_end),
+                                       rf2425_ini_common_end, change_channel);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+                       break;
+               default:
+                       return -EINVAL;
+
+               }
+
+       /* For AR5211 */
+       } else if (ah->ah_version == AR5K_AR5211) {
+
+               /* AR5K_MODE_11B */
+               if (mode > 2) {
+                       ATH5K_ERR(ah->ah_sc,
+                               "unsupported channel mode: %d\n", mode);
+                       return -EINVAL;
+               }
+
+               /* Mode-specific settings */
+               ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5211_ini_mode),
+                               ar5211_ini_mode, mode);
+
+               /*
+                * Write initial settings common for all modes
+                */
+               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini),
+                               ar5211_ini, change_channel);
+
+               /* AR5211 only comes with 5111 */
+
+               /* Baseband gain table */
+               ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain),
+                               rf5111_ini_bbgain, change_channel);
+       /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */
+       } else if (ah->ah_version == AR5K_AR5210) {
+               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini),
+                               ar5210_ini, change_channel);
+       }
+
+       return 0;
+}
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
new file mode 100644 (file)
index 0000000..19555fb
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2009 Bob Copeland <me@bobcopeland.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/pci.h>
+#include "ath5k.h"
+#include "base.h"
+
+#define ATH_SDEVICE(subv,subd) \
+       .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
+       .subvendor = (subv), .subdevice = (subd)
+
+#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity))
+#define ATH_PIN(data) ((data) >> 8)
+#define ATH_POLARITY(data) ((data) & 0xff)
+
+/* Devices we match on for LED config info (typically laptops) */
+static const struct pci_device_id ath5k_led_devices[] = {
+       /* IBM-specific AR5212 */
+       { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
+       /* AR5211 */
+       { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
+       /* HP Compaq nc6xx, nc4000, nx6000 */
+       { ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) },
+       /* Acer Aspire One A150 (maximlevitsky@gmail.com) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) },
+       /* Acer Ferrari 5000 (russ.dill@gmail.com) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
+       /* E-machines E510 (tuliom@gmail.com) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
+       /* Acer Extensa 5620z (nekoreeve@gmail.com) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
+       { }
+};
+
+void ath5k_led_enable(struct ath5k_softc *sc)
+{
+       if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
+               ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
+               ath5k_led_off(sc);
+       }
+}
+
+void ath5k_led_on(struct ath5k_softc *sc)
+{
+       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+               return;
+       ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
+}
+
+void ath5k_led_off(struct ath5k_softc *sc)
+{
+       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+               return;
+       ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
+}
+
+static void
+ath5k_led_brightness_set(struct led_classdev *led_dev,
+       enum led_brightness brightness)
+{
+       struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
+               led_dev);
+
+       if (brightness == LED_OFF)
+               ath5k_led_off(led->sc);
+       else
+               ath5k_led_on(led->sc);
+}
+
+static int
+ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
+                  const char *name, char *trigger)
+{
+       int err;
+
+       led->sc = sc;
+       strncpy(led->name, name, sizeof(led->name));
+       led->led_dev.name = led->name;
+       led->led_dev.default_trigger = trigger;
+       led->led_dev.brightness_set = ath5k_led_brightness_set;
+
+       err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
+       if (err) {
+               ATH5K_WARN(sc, "could not register LED %s\n", name);
+               led->sc = NULL;
+       }
+       return err;
+}
+
+static void
+ath5k_unregister_led(struct ath5k_led *led)
+{
+       if (!led->sc)
+               return;
+       led_classdev_unregister(&led->led_dev);
+       ath5k_led_off(led->sc);
+       led->sc = NULL;
+}
+
+void ath5k_unregister_leds(struct ath5k_softc *sc)
+{
+       ath5k_unregister_led(&sc->rx_led);
+       ath5k_unregister_led(&sc->tx_led);
+}
+
+int ath5k_init_leds(struct ath5k_softc *sc)
+{
+       int ret = 0;
+       struct ieee80211_hw *hw = sc->hw;
+       struct pci_dev *pdev = sc->pdev;
+       char name[ATH5K_LED_MAX_NAME_LEN + 1];
+       const struct pci_device_id *match;
+
+       match = pci_match_id(&ath5k_led_devices[0], pdev);
+       if (match) {
+               __set_bit(ATH_STAT_LEDSOFT, sc->status);
+               sc->led_pin = ATH_PIN(match->driver_data);
+               sc->led_on = ATH_POLARITY(match->driver_data);
+       }
+
+       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+               goto out;
+
+       ath5k_led_enable(sc);
+
+       snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
+       ret = ath5k_register_led(sc, &sc->rx_led, name,
+               ieee80211_get_rx_led_name(hw));
+       if (ret)
+               goto out;
+
+       snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
+       ret = ath5k_register_led(sc, &sc->tx_led, name,
+               ieee80211_get_tx_led_name(hw));
+out:
+       return ret;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
new file mode 100644 (file)
index 0000000..55122f1
--- /dev/null
@@ -0,0 +1,1174 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Matthew W. S. Bell  <mentor@madwifi.org>
+ * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
+ * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*********************************\
+* Protocol Control Unit Functions *
+\*********************************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*******************\
+* Generic functions *
+\*******************/
+
+/**
+ * ath5k_hw_set_opmode - Set PCU operating mode
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Initialize PCU for the various operating modes (AP/STA etc)
+ *
+ * NOTE: ah->ah_op_mode must be set before calling this.
+ */
+int ath5k_hw_set_opmode(struct ath5k_hw *ah)
+{
+       u32 pcu_reg, beacon_reg, low_id, high_id;
+
+
+       /* Preserve rest settings */
+       pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
+       pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
+                       | AR5K_STA_ID1_KEYSRCH_MODE
+                       | (ah->ah_version == AR5K_AR5210 ?
+                       (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
+
+       beacon_reg = 0;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       switch (ah->ah_op_mode) {
+       case NL80211_IFTYPE_ADHOC:
+               pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
+               beacon_reg |= AR5K_BCR_ADHOC;
+               if (ah->ah_version == AR5K_AR5210)
+                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+               else
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
+               break;
+
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_MESH_POINT:
+               pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
+               beacon_reg |= AR5K_BCR_AP;
+               if (ah->ah_version == AR5K_AR5210)
+                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+               else
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
+               break;
+
+       case NL80211_IFTYPE_STATION:
+               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+                       | (ah->ah_version == AR5K_AR5210 ?
+                               AR5K_STA_ID1_PWR_SV : 0);
+       case NL80211_IFTYPE_MONITOR:
+               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+                       | (ah->ah_version == AR5K_AR5210 ?
+                               AR5K_STA_ID1_NO_PSPOLL : 0);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       /*
+        * Set PCU registers
+        */
+       low_id = AR5K_LOW_ID(ah->ah_sta_id);
+       high_id = AR5K_HIGH_ID(ah->ah_sta_id);
+       ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
+       ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
+
+       /*
+        * Set Beacon Control Register on 5210
+        */
+       if (ah->ah_version == AR5K_AR5210)
+               ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_update - Update mib counters (mac layer statistics)
+ *
+ * @ah: The &struct ath5k_hw
+ * @stats: The &struct ieee80211_low_level_stats we use to track
+ * statistics on the driver
+ *
+ * Reads MIB counters from PCU and updates sw statistics. Must be
+ * called after a MIB interrupt.
+ */
+void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
+               struct ieee80211_low_level_stats  *stats)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Read-And-Clear */
+       stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
+       stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
+       stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
+       stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
+
+       /* XXX: Should we use this to track beacon count ?
+        * -we read it anyway to clear the register */
+       ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
+
+       /* Reset profile count registers on 5212*/
+       if (ah->ah_version == AR5K_AR5212) {
+               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
+               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
+               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
+               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
+       }
+
+       /* TODO: Handle ANI stats */
+}
+
+/**
+ * ath5k_hw_set_ack_bitrate - set bitrate for ACKs
+ *
+ * @ah: The &struct ath5k_hw
+ * @high: Flag to determine if we want to use high transmition rate
+ * for ACKs or not
+ *
+ * If high flag is set, we tell hw to use a set of control rates based on
+ * the current transmition rate (check out control_rates array inside reset.c).
+ * If not hw just uses the lowest rate available for the current modulation
+ * scheme being used (1Mbit for CCK and 6Mbits for OFDM).
+ */
+void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
+{
+       if (ah->ah_version != AR5K_AR5212)
+               return;
+       else {
+               u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
+               if (high)
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
+               else
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
+       }
+}
+
+
+/******************\
+* ACK/CTS Timeouts *
+\******************/
+
+/**
+ * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
+                       AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
+}
+
+/**
+ * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
+ *
+ * @ah: The &struct ath5k_hw
+ * @timeout: Timeout in usec
+ */
+int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
+                       ah->ah_turbo) <= timeout)
+               return -EINVAL;
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
+               ath5k_hw_htoclock(timeout, ah->ah_turbo));
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
+                       AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
+}
+
+/**
+ * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
+ *
+ * @ah: The &struct ath5k_hw
+ * @timeout: Timeout in usec
+ */
+int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
+                       ah->ah_turbo) <= timeout)
+               return -EINVAL;
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
+                       ath5k_hw_htoclock(timeout, ah->ah_turbo));
+
+       return 0;
+}
+
+
+/****************\
+* BSSID handling *
+\****************/
+
+/**
+ * ath5k_hw_get_lladdr - Get station id
+ *
+ * @ah: The &struct ath5k_hw
+ * @mac: The card's mac address
+ *
+ * Initialize ah->ah_sta_id using the mac address provided
+ * (just a memcpy).
+ *
+ * TODO: Remove it once we merge ath5k_softc and ath5k_hw
+ */
+void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       memcpy(mac, ah->ah_sta_id, ETH_ALEN);
+}
+
+/**
+ * ath5k_hw_set_lladdr - Set station id
+ *
+ * @ah: The &struct ath5k_hw
+ * @mac: The card's mac address
+ *
+ * Set station id on hw using the provided mac address
+ */
+int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
+{
+       u32 low_id, high_id;
+       u32 pcu_reg;
+
+       ATH5K_TRACE(ah->ah_sc);
+       /* Set new station ID */
+       memcpy(ah->ah_sta_id, mac, ETH_ALEN);
+
+       pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
+
+       low_id = AR5K_LOW_ID(mac);
+       high_id = AR5K_HIGH_ID(mac);
+
+       ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
+       ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_set_associd - Set BSSID for association
+ *
+ * @ah: The &struct ath5k_hw
+ * @bssid: BSSID
+ * @assoc_id: Assoc id
+ *
+ * Sets the BSSID which trigers the "SME Join" operation
+ */
+void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
+{
+       u32 low_id, high_id;
+       u16 tim_offset = 0;
+
+       /*
+        * Set simple BSSID mask on 5212
+        */
+       if (ah->ah_version == AR5K_AR5212) {
+               ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask),
+                                                       AR5K_BSS_IDM0);
+               ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask),
+                                                       AR5K_BSS_IDM1);
+       }
+
+       /*
+        * Set BSSID which triggers the "SME Join" operation
+        */
+       low_id = AR5K_LOW_ID(bssid);
+       high_id = AR5K_HIGH_ID(bssid);
+       ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
+       ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
+                               AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
+
+       if (assoc_id == 0) {
+               ath5k_hw_disable_pspoll(ah);
+               return;
+       }
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
+                       tim_offset ? tim_offset + 4 : 0);
+
+       ath5k_hw_enable_pspoll(ah, NULL, 0);
+}
+
+/**
+ * ath5k_hw_set_bssid_mask - filter out bssids we listen
+ *
+ * @ah: the &struct ath5k_hw
+ * @mask: the bssid_mask, a u8 array of size ETH_ALEN
+ *
+ * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
+ * which bits of the interface's MAC address should be looked at when trying
+ * to decide which packets to ACK. In station mode and AP mode with a single
+ * BSS every bit matters since we lock to only one BSS. In AP mode with
+ * multiple BSSes (virtual interfaces) not every bit matters because hw must
+ * accept frames for all BSSes and so we tweak some bits of our mac address
+ * in order to have multiple BSSes.
+ *
+ * NOTE: This is a simple filter and does *not* filter out all
+ * relevant frames. Some frames that are not for us might get ACKed from us
+ * by PCU because they just match the mask.
+ *
+ * When handling multiple BSSes you can get the BSSID mask by computing the
+ * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
+ *
+ * When you do this you are essentially computing the common bits of all your
+ * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
+ * the MAC address to obtain the relevant bits and compare the result with
+ * (frame's BSSID & mask) to see if they match.
+ */
+/*
+ * Simple example: on your card you have have two BSSes you have created with
+ * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
+ * There is another BSSID-03 but you are not part of it. For simplicity's sake,
+ * assuming only 4 bits for a mac address and for BSSIDs you can then have:
+ *
+ *                  \
+ * MAC:                0001 |
+ * BSSID-01:   0100 | --> Belongs to us
+ * BSSID-02:   1001 |
+ *                  /
+ * -------------------
+ * BSSID-03:   0110  | --> External
+ * -------------------
+ *
+ * Our bssid_mask would then be:
+ *
+ *             On loop iteration for BSSID-01:
+ *             ~(0001 ^ 0100)  -> ~(0101)
+ *                             ->   1010
+ *             bssid_mask      =    1010
+ *
+ *             On loop iteration for BSSID-02:
+ *             bssid_mask &= ~(0001   ^   1001)
+ *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
+ *             bssid_mask =   (1010)  & ~(1001)
+ *             bssid_mask =   (1010)  &  (0110)
+ *             bssid_mask =   0010
+ *
+ * A bssid_mask of 0010 means "only pay attention to the second least
+ * significant bit". This is because its the only bit common
+ * amongst the MAC and all BSSIDs we support. To findout what the real
+ * common bit is we can simply "&" the bssid_mask now with any BSSID we have
+ * or our MAC address (we assume the hardware uses the MAC address).
+ *
+ * Now, suppose there's an incoming frame for BSSID-03:
+ *
+ * IFRAME-01:  0110
+ *
+ * An easy eye-inspeciton of this already should tell you that this frame
+ * will not pass our check. This is beacuse the bssid_mask tells the
+ * hardware to only look at the second least significant bit and the
+ * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
+ * as 1, which does not match 0.
+ *
+ * So with IFRAME-01 we *assume* the hardware will do:
+ *
+ *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
+ *  --> allow = (0010) == 0000 ? 1 : 0;
+ *  --> allow = 0
+ *
+ *  Lets now test a frame that should work:
+ *
+ * IFRAME-02:  0001 (we should allow)
+ *
+ *     allow = (0001 & 1010) == 1010
+ *
+ *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
+ *  --> allow = (0010) == (0010)
+ *  --> allow = 1
+ *
+ * Other examples:
+ *
+ * IFRAME-03:  0100 --> allowed
+ * IFRAME-04:  1001 --> allowed
+ * IFRAME-05:  1101 --> allowed but its not for us!!!
+ *
+ */
+int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
+{
+       u32 low_id, high_id;
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Cache bssid mask so that we can restore it
+        * on reset */
+       memcpy(ah->ah_bssid_mask, mask, ETH_ALEN);
+       if (ah->ah_version == AR5K_AR5212) {
+               low_id = AR5K_LOW_ID(mask);
+               high_id = AR5K_HIGH_ID(mask);
+
+               ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
+               ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
+
+               return 0;
+       }
+
+       return -EIO;
+}
+
+
+/************\
+* RX Control *
+\************/
+
+/**
+ * ath5k_hw_start_rx_pcu - Start RX engine
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Starts RX engine on PCU so that hw can process RXed frames
+ * (ACK etc).
+ *
+ * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
+ * TODO: Init ANI here
+ */
+void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
+}
+
+/**
+ * at5k_hw_stop_rx_pcu - Stop RX engine
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Stops RX engine on PCU
+ *
+ * TODO: Detach ANI here
+ */
+void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
+}
+
+/*
+ * Set multicast filter
+ */
+void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       /* Set the multicat filter */
+       ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
+       ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
+}
+
+/*
+ * Set multicast filter by index
+ */
+int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
+{
+
+       ATH5K_TRACE(ah->ah_sc);
+       if (index >= 64)
+               return -EINVAL;
+       else if (index >= 32)
+               AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
+                               (1 << (index - 32)));
+       else
+               AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
+
+       return 0;
+}
+
+/*
+ * Clear Multicast filter by index
+ */
+int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
+{
+
+       ATH5K_TRACE(ah->ah_sc);
+       if (index >= 64)
+               return -EINVAL;
+       else if (index >= 32)
+               AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
+                               (1 << (index - 32)));
+       else
+               AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_get_rx_filter - Get current rx filter
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Returns the RX filter by reading rx filter and
+ * phy error filter registers. RX filter is used
+ * to set the allowed frame types that PCU will accept
+ * and pass to the driver. For a list of frame types
+ * check out reg.h.
+ */
+u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
+{
+       u32 data, filter = 0;
+
+       ATH5K_TRACE(ah->ah_sc);
+       filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
+
+       /*Radar detection for 5212*/
+       if (ah->ah_version == AR5K_AR5212) {
+               data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
+
+               if (data & AR5K_PHY_ERR_FIL_RADAR)
+                       filter |= AR5K_RX_FILTER_RADARERR;
+               if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
+                       filter |= AR5K_RX_FILTER_PHYERR;
+       }
+
+       return filter;
+}
+
+/**
+ * ath5k_hw_set_rx_filter - Set rx filter
+ *
+ * @ah: The &struct ath5k_hw
+ * @filter: RX filter mask (see reg.h)
+ *
+ * Sets RX filter register and also handles PHY error filter
+ * register on 5212 and newer chips so that we have proper PHY
+ * error reporting.
+ */
+void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
+{
+       u32 data = 0;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Set PHY error filter register on 5212*/
+       if (ah->ah_version == AR5K_AR5212) {
+               if (filter & AR5K_RX_FILTER_RADARERR)
+                       data |= AR5K_PHY_ERR_FIL_RADAR;
+               if (filter & AR5K_RX_FILTER_PHYERR)
+                       data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
+       }
+
+       /*
+        * The AR5210 uses promiscous mode to detect radar activity
+        */
+       if (ah->ah_version == AR5K_AR5210 &&
+                       (filter & AR5K_RX_FILTER_RADARERR)) {
+               filter &= ~AR5K_RX_FILTER_RADARERR;
+               filter |= AR5K_RX_FILTER_PROM;
+       }
+
+       /*Zero length DMA (phy error reporting) */
+       if (data)
+               AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
+       else
+               AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
+
+       /*Write RX Filter register*/
+       ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
+
+       /*Write PHY error filter register on 5212*/
+       if (ah->ah_version == AR5K_AR5212)
+               ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
+
+}
+
+
+/****************\
+* Beacon control *
+\****************/
+
+/**
+ * ath5k_hw_get_tsf32 - Get a 32bit TSF
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Returns lower 32 bits of current TSF
+ */
+u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+}
+
+/**
+ * ath5k_hw_get_tsf64 - Get the full 64bit TSF
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Returns the current TSF
+ */
+u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
+{
+       u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+       ATH5K_TRACE(ah->ah_sc);
+
+       return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
+}
+
+/**
+ * ath5k_hw_set_tsf64 - Set a new 64bit TSF
+ *
+ * @ah: The &struct ath5k_hw
+ * @tsf64: The new 64bit TSF
+ *
+ * Sets the new TSF
+ */
+void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
+       ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
+}
+
+/**
+ * ath5k_hw_reset_tsf - Force a TSF reset
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Forces a TSF reset on PCU
+ */
+void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
+{
+       u32 val;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
+
+       /*
+        * Each write to the RESET_TSF bit toggles a hardware internal
+        * signal to reset TSF, but if left high it will cause a TSF reset
+        * on the next chip reset as well.  Thus we always write the value
+        * twice to clear the signal.
+        */
+       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
+       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
+}
+
+/*
+ * Initialize beacon timers
+ */
+void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
+{
+       u32 timer1, timer2, timer3;
+
+       ATH5K_TRACE(ah->ah_sc);
+       /*
+        * Set the additional timers by mode
+        */
+       switch (ah->ah_op_mode) {
+       case NL80211_IFTYPE_MONITOR:
+       case NL80211_IFTYPE_STATION:
+               /* In STA mode timer1 is used as next wakeup
+                * timer and timer2 as next CFP duration start
+                * timer. Both in 1/8TUs. */
+               /* TODO: PCF handling */
+               if (ah->ah_version == AR5K_AR5210) {
+                       timer1 = 0xffffffff;
+                       timer2 = 0xffffffff;
+               } else {
+                       timer1 = 0x0000ffff;
+                       timer2 = 0x0007ffff;
+               }
+               /* Mark associated AP as PCF incapable for now */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PCF);
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_ADHOC_BCN_ATIM);
+       default:
+               /* On non-STA modes timer1 is used as next DMA
+                * beacon alert (DBA) timer and timer2 as next
+                * software beacon alert. Both in 1/8TUs. */
+               timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
+               timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
+               break;
+       }
+
+       /* Timer3 marks the end of our ATIM window
+        * a zero length window is not allowed because
+        * we 'll get no beacons */
+       timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
+
+       /*
+        * Set the beacon register and enable all timers.
+        */
+       /* When in AP mode zero timer0 to start TSF */
+       if (ah->ah_op_mode == NL80211_IFTYPE_AP)
+               ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
+       else
+               ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
+       ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
+       ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
+       ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
+
+       /* Force a TSF reset if requested and enable beacons */
+       if (interval & AR5K_BEACON_RESET_TSF)
+               ath5k_hw_reset_tsf(ah);
+
+       ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
+                                       AR5K_BEACON_ENABLE),
+                                               AR5K_BEACON);
+
+       /* Flush any pending BMISS interrupts on ISR by
+        * performing a clear-on-write operation on PISR
+        * register for the BMISS bit (writing a bit on
+        * ISR togles a reset for that bit and leaves
+        * the rest bits intact) */
+       if (ah->ah_version == AR5K_AR5210)
+               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR);
+       else
+               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR);
+
+       /* TODO: Set enchanced sleep registers on AR5212
+        * based on vif->bss_conf params, until then
+        * disable power save reporting.*/
+       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV);
+
+}
+
+#if 0
+/*
+ * Set beacon timers
+ */
+int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
+               const struct ath5k_beacon_state *state)
+{
+       u32 cfp_period, next_cfp, dtim, interval, next_beacon;
+
+       /*
+        * TODO: should be changed through *state
+        * review struct ath5k_beacon_state struct
+        *
+        * XXX: These are used for cfp period bellow, are they
+        * ok ? Is it O.K. for tsf here to be 0 or should we use
+        * get_tsf ?
+        */
+       u32 dtim_count = 0; /* XXX */
+       u32 cfp_count = 0; /* XXX */
+       u32 tsf = 0; /* XXX */
+
+       ATH5K_TRACE(ah->ah_sc);
+       /* Return on an invalid beacon state */
+       if (state->bs_interval < 1)
+               return -EINVAL;
+
+       interval = state->bs_interval;
+       dtim = state->bs_dtim_period;
+
+       /*
+        * PCF support?
+        */
+       if (state->bs_cfp_period > 0) {
+               /*
+                * Enable PCF mode and set the CFP
+                * (Contention Free Period) and timer registers
+                */
+               cfp_period = state->bs_cfp_period * state->bs_dtim_period *
+                       state->bs_interval;
+               next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
+                       state->bs_interval;
+
+               AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
+                               AR5K_STA_ID1_DEFAULT_ANTENNA |
+                               AR5K_STA_ID1_PCF);
+               ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
+               ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
+                               AR5K_CFP_DUR);
+               ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
+                                               next_cfp)) << 3, AR5K_TIMER2);
+       } else {
+               /* Disable PCF mode */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
+                               AR5K_STA_ID1_DEFAULT_ANTENNA |
+                               AR5K_STA_ID1_PCF);
+       }
+
+       /*
+        * Enable the beacon timer register
+        */
+       ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
+
+       /*
+        * Start the beacon timers
+        */
+       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &
+               ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
+               AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
+               AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
+               AR5K_BEACON_PERIOD), AR5K_BEACON);
+
+       /*
+        * Write new beacon miss threshold, if it appears to be valid
+        * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
+        * and return if its not in range. We can test this by reading value and
+        * setting value to a largest value and seeing which values register.
+        */
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
+                       state->bs_bmiss_threshold);
+
+       /*
+        * Set sleep control register
+        * XXX: Didn't find this in 5210 code but since this register
+        * exists also in ar5k's 5210 headers i leave it as common code.
+        */
+       AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
+                       (state->bs_sleep_duration - 3) << 3);
+
+       /*
+        * Set enhanced sleep registers on 5212
+        */
+       if (ah->ah_version == AR5K_AR5212) {
+               if (state->bs_sleep_duration > state->bs_interval &&
+                               roundup(state->bs_sleep_duration, interval) ==
+                               state->bs_sleep_duration)
+                       interval = state->bs_sleep_duration;
+
+               if (state->bs_sleep_duration > dtim && (dtim == 0 ||
+                               roundup(state->bs_sleep_duration, dtim) ==
+                               state->bs_sleep_duration))
+                       dtim = state->bs_sleep_duration;
+
+               if (interval > dtim)
+                       return -EINVAL;
+
+               next_beacon = interval == dtim ? state->bs_next_dtim :
+                       state->bs_next_beacon;
+
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
+                       AR5K_SLEEP0_NEXT_DTIM) |
+                       AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
+                       AR5K_SLEEP0_ENH_SLEEP_EN |
+                       AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
+
+               ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
+                       AR5K_SLEEP1_NEXT_TIM) |
+                       AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
+
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
+                       AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
+       }
+
+       return 0;
+}
+
+/*
+ * Reset beacon timers
+ */
+void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       /*
+        * Disable beacon timer
+        */
+       ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
+
+       /*
+        * Disable some beacon register values
+        */
+       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
+                       AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
+       ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
+}
+
+/*
+ * Wait for beacon queue to finish
+ */
+int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
+{
+       unsigned int i;
+       int ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* 5210 doesn't have QCU*/
+       if (ah->ah_version == AR5K_AR5210) {
+               /*
+                * Wait for beaconn queue to finish by checking
+                * Control Register and Beacon Status Register.
+                */
+               for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
+                       if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
+                                       ||
+                           !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
+                               break;
+                       udelay(10);
+               }
+
+               /* Timeout... */
+               if (i <= 0) {
+                       /*
+                        * Re-schedule the beacon queue
+                        */
+                       ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
+                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
+                                       AR5K_BCR);
+
+                       return -EIO;
+               }
+               ret = 0;
+       } else {
+       /*5211/5212*/
+               ret = ath5k_hw_register_timeout(ah,
+                       AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
+                       AR5K_QCU_STS_FRMPENDCNT, 0, false);
+
+               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
+                       return -EIO;
+       }
+
+       return ret;
+}
+#endif
+
+
+/*********************\
+* Key table functions *
+\*********************/
+
+/*
+ * Reset a key entry on the table
+ */
+int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
+{
+       unsigned int i, type;
+       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+
+       type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry));
+
+       for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
+               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
+
+       /* Reset associated MIC entry if TKIP
+        * is enabled located at offset (entry + 64) */
+       if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+               AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE);
+               for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
+                       ath5k_hw_reg_write(ah, 0,
+                               AR5K_KEYTABLE_OFF(micentry, i));
+       }
+
+       /*
+        * Set NULL encryption on AR5212+
+        *
+        * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
+        *       AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
+        *
+        * Note2: Windows driver (ndiswrapper) sets this to
+        *        0x00000714 instead of 0x00000007
+        */
+       if (ah->ah_version > AR5K_AR5211) {
+               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                               AR5K_KEYTABLE_TYPE(entry));
+
+               if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+                       ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                               AR5K_KEYTABLE_TYPE(micentry));
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Check if a table entry is valid
+ */
+int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+
+       /* Check the validation flag at the end of the entry */
+       return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
+               AR5K_KEYTABLE_VALID;
+}
+
+static
+int ath5k_keycache_type(const struct ieee80211_key_conf *key)
+{
+       switch (key->alg) {
+       case ALG_TKIP:
+               return AR5K_KEYTABLE_TYPE_TKIP;
+       case ALG_CCMP:
+               return AR5K_KEYTABLE_TYPE_CCM;
+       case ALG_WEP:
+               if (key->keylen == LEN_WEP40)
+                       return AR5K_KEYTABLE_TYPE_40;
+               else if (key->keylen == LEN_WEP104)
+                       return AR5K_KEYTABLE_TYPE_104;
+               return -EINVAL;
+       default:
+               return -EINVAL;
+       }
+       return -EINVAL;
+}
+
+/*
+ * Set a key entry on the table
+ */
+int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
+               const struct ieee80211_key_conf *key, const u8 *mac)
+{
+       unsigned int i;
+       int keylen;
+       __le32 key_v[5] = {};
+       __le32 key0 = 0, key1 = 0;
+       __le32 *rxmic, *txmic;
+       int keytype;
+       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
+       bool is_tkip;
+       const u8 *key_ptr;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       is_tkip = (key->alg == ALG_TKIP);
+
+       /*
+        * key->keylen comes in from mac80211 in bytes.
+        * TKIP is 128 bit + 128 bit mic
+        */
+       keylen = (is_tkip) ? (128 / 8) : key->keylen;
+
+       if (entry > AR5K_KEYTABLE_SIZE ||
+               (is_tkip && micentry > AR5K_KEYTABLE_SIZE))
+               return -EOPNOTSUPP;
+
+       if (unlikely(keylen > 16))
+               return -EOPNOTSUPP;
+
+       keytype = ath5k_keycache_type(key);
+       if (keytype < 0)
+               return keytype;
+
+       /*
+        * each key block is 6 bytes wide, written as pairs of
+        * alternating 32 and 16 bit le values.
+        */
+       key_ptr = key->key;
+       for (i = 0; keylen >= 6; keylen -= 6) {
+               memcpy(&key_v[i], key_ptr, 6);
+               i += 2;
+               key_ptr += 6;
+       }
+       if (keylen)
+               memcpy(&key_v[i], key_ptr, keylen);
+
+       /* intentionally corrupt key until mic is installed */
+       if (is_tkip) {
+               key0 = key_v[0] = ~key_v[0];
+               key1 = key_v[1] = ~key_v[1];
+       }
+
+       for (i = 0; i < ARRAY_SIZE(key_v); i++)
+               ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
+                               AR5K_KEYTABLE_OFF(entry, i));
+
+       ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
+
+       if (is_tkip) {
+               /* Install rx/tx MIC */
+               rxmic = (__le32 *) &key->key[16];
+               txmic = (__le32 *) &key->key[24];
+
+               if (ah->ah_combined_mic) {
+                       key_v[0] = rxmic[0];
+                       key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16);
+                       key_v[2] = rxmic[1];
+                       key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff);
+                       key_v[4] = txmic[1];
+               } else {
+                       key_v[0] = rxmic[0];
+                       key_v[1] = 0;
+                       key_v[2] = rxmic[1];
+                       key_v[3] = 0;
+                       key_v[4] = 0;
+               }
+               for (i = 0; i < ARRAY_SIZE(key_v); i++)
+                       ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
+                               AR5K_KEYTABLE_OFF(micentry, i));
+
+               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                       AR5K_KEYTABLE_TYPE(micentry));
+               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry));
+               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry));
+
+               /* restore first 2 words of key */
+               ath5k_hw_reg_write(ah, le32_to_cpu(~key0),
+                       AR5K_KEYTABLE_OFF(entry, 0));
+               ath5k_hw_reg_write(ah, le32_to_cpu(~key1),
+                       AR5K_KEYTABLE_OFF(entry, 1));
+       }
+
+       return ath5k_hw_set_key_lladdr(ah, entry, mac);
+}
+
+int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
+{
+       u32 low_id, high_id;
+
+       ATH5K_TRACE(ah->ah_sc);
+        /* Invalid entry (key table overflow) */
+       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+
+       /* MAC may be NULL if it's a broadcast key. In this case no need to
+        * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
+       if (!mac) {
+               low_id = 0xffffffff;
+               high_id = 0xffff | AR5K_KEYTABLE_VALID;
+       } else {
+               low_id = AR5K_LOW_ID(mac);
+               high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
+       }
+
+       ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
+       ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
+
+       return 0;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
new file mode 100644 (file)
index 0000000..9e2faae
--- /dev/null
@@ -0,0 +1,2599 @@
+/*
+ * PHY functions
+ *
+ * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+#define _ATH5K_PHY
+
+#include <linux/delay.h>
+
+#include "ath5k.h"
+#include "reg.h"
+#include "base.h"
+#include "rfbuffer.h"
+#include "rfgain.h"
+
+/*
+ * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
+ */
+static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
+                                       const struct ath5k_rf_reg *rf_regs,
+                                       u32 val, u8 reg_id, bool set)
+{
+       const struct ath5k_rf_reg *rfreg = NULL;
+       u8 offset, bank, num_bits, col, position;
+       u16 entry;
+       u32 mask, data, last_bit, bits_shifted, first_bit;
+       u32 *rfb;
+       s32 bits_left;
+       int i;
+
+       data = 0;
+       rfb = ah->ah_rf_banks;
+
+       for (i = 0; i < ah->ah_rf_regs_count; i++) {
+               if (rf_regs[i].index == reg_id) {
+                       rfreg = &rf_regs[i];
+                       break;
+               }
+       }
+
+       if (rfb == NULL || rfreg == NULL) {
+               ATH5K_PRINTF("Rf register not found!\n");
+               /* should not happen */
+               return 0;
+       }
+
+       bank = rfreg->bank;
+       num_bits = rfreg->field.len;
+       first_bit = rfreg->field.pos;
+       col = rfreg->field.col;
+
+       /* first_bit is an offset from bank's
+        * start. Since we have all banks on
+        * the same array, we use this offset
+        * to mark each bank's start */
+       offset = ah->ah_offset[bank];
+
+       /* Boundary check */
+       if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
+               ATH5K_PRINTF("invalid values at offset %u\n", offset);
+               return 0;
+       }
+
+       entry = ((first_bit - 1) / 8) + offset;
+       position = (first_bit - 1) % 8;
+
+       if (set)
+               data = ath5k_hw_bitswap(val, num_bits);
+
+       for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
+       position = 0, entry++) {
+
+               last_bit = (position + bits_left > 8) ? 8 :
+                                       position + bits_left;
+
+               mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
+                                                               (col * 8);
+
+               if (set) {
+                       rfb[entry] &= ~mask;
+                       rfb[entry] |= ((data << position) << (col * 8)) & mask;
+                       data >>= (8 - position);
+               } else {
+                       data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
+                               << bits_shifted;
+                       bits_shifted += last_bit - position;
+               }
+
+               bits_left -= 8 - position;
+       }
+
+       data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
+
+       return data;
+}
+
+/**********************\
+* RF Gain optimization *
+\**********************/
+
+/*
+ * This code is used to optimize rf gain on different environments
+ * (temprature mostly) based on feedback from a power detector.
+ *
+ * It's only used on RF5111 and RF5112, later RF chips seem to have
+ * auto adjustment on hw -notice they have a much smaller BANK 7 and
+ * no gain optimization ladder-.
+ *
+ * For more infos check out this patent doc
+ * http://www.freepatentsonline.com/7400691.html
+ *
+ * This paper describes power drops as seen on the receiver due to
+ * probe packets
+ * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
+ * %20of%20Power%20Control.pdf
+ *
+ * And this is the MadWiFi bug entry related to the above
+ * http://madwifi-project.org/ticket/1659
+ * with various measurements and diagrams
+ *
+ * TODO: Deal with power drops due to probes by setting an apropriate
+ * tx power on the probe packets ! Make this part of the calibration process.
+ */
+
+/* Initialize ah_gain durring attach */
+int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
+{
+       /* Initialize the gain optimization values */
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
+               ah->ah_gain.g_low = 20;
+               ah->ah_gain.g_high = 35;
+               ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+               break;
+       case AR5K_RF5112:
+               ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
+               ah->ah_gain.g_low = 20;
+               ah->ah_gain.g_high = 85;
+               ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* Schedule a gain probe check on the next transmited packet.
+ * That means our next packet is going to be sent with lower
+ * tx power and a Peak to Average Power Detector (PAPD) will try
+ * to measure the gain.
+ *
+ * TODO: Use propper tx power setting for the probe packet so
+ * that we don't observe a serious power drop on the receiver
+ *
+ * XXX:  How about forcing a tx packet (bypassing PCU arbitrator etc)
+ * just after we enable the probe so that we don't mess with
+ * standard traffic ? Maybe it's time to use sw interrupts and
+ * a probe tasklet !!!
+ */
+static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
+{
+
+       /* Skip if gain calibration is inactive or
+        * we already handle a probe request */
+       if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
+               return;
+
+       /* Send the packet with 2dB below max power as
+        * patent doc suggest */
+       ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4,
+                       AR5K_PHY_PAPD_PROBE_TXPOWER) |
+                       AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
+
+       ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
+
+}
+
+/* Calculate gain_F measurement correction
+ * based on the current step for RF5112 rev. 2 */
+static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
+{
+       u32 mix, step;
+       u32 *rf;
+       const struct ath5k_gain_opt *go;
+       const struct ath5k_gain_opt_step *g_step;
+       const struct ath5k_rf_reg *rf_regs;
+
+       /* Only RF5112 Rev. 2 supports it */
+       if ((ah->ah_radio != AR5K_RF5112) ||
+       (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
+               return 0;
+
+       go = &rfgain_opt_5112;
+       rf_regs = rf_regs_5112a;
+       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+
+       g_step = &go->go_step[ah->ah_gain.g_step_idx];
+
+       if (ah->ah_rf_banks == NULL)
+               return 0;
+
+       rf = ah->ah_rf_banks;
+       ah->ah_gain.g_f_corr = 0;
+
+       /* No VGA (Variable Gain Amplifier) override, skip */
+       if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
+               return 0;
+
+       /* Mix gain stepping */
+       step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
+
+       /* Mix gain override */
+       mix = g_step->gos_param[0];
+
+       switch (mix) {
+       case 3:
+               ah->ah_gain.g_f_corr = step * 2;
+               break;
+       case 2:
+               ah->ah_gain.g_f_corr = (step - 5) * 2;
+               break;
+       case 1:
+               ah->ah_gain.g_f_corr = step;
+               break;
+       default:
+               ah->ah_gain.g_f_corr = 0;
+               break;
+       }
+
+       return ah->ah_gain.g_f_corr;
+}
+
+/* Check if current gain_F measurement is in the range of our
+ * power detector windows. If we get a measurement outside range
+ * we know it's not accurate (detectors can't measure anything outside
+ * their detection window) so we must ignore it */
+static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
+{
+       const struct ath5k_rf_reg *rf_regs;
+       u32 step, mix_ovr, level[4];
+       u32 *rf;
+
+       if (ah->ah_rf_banks == NULL)
+               return false;
+
+       rf = ah->ah_rf_banks;
+
+       if (ah->ah_radio == AR5K_RF5111) {
+
+               rf_regs = rf_regs_5111;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+
+               step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
+                       false);
+
+               level[0] = 0;
+               level[1] = (step == 63) ? 50 : step + 4;
+               level[2] = (step != 63) ? 64 : level[0];
+               level[3] = level[2] + 50 ;
+
+               ah->ah_gain.g_high = level[3] -
+                       (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
+               ah->ah_gain.g_low = level[0] +
+                       (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
+       } else {
+
+               rf_regs = rf_regs_5112;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+
+               mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
+                       false);
+
+               level[0] = level[2] = 0;
+
+               if (mix_ovr == 1) {
+                       level[1] = level[3] = 83;
+               } else {
+                       level[1] = level[3] = 107;
+                       ah->ah_gain.g_high = 55;
+               }
+       }
+
+       return (ah->ah_gain.g_current >= level[0] &&
+                       ah->ah_gain.g_current <= level[1]) ||
+               (ah->ah_gain.g_current >= level[2] &&
+                       ah->ah_gain.g_current <= level[3]);
+}
+
+/* Perform gain_F adjustment by choosing the right set
+ * of parameters from rf gain optimization ladder */
+static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
+{
+       const struct ath5k_gain_opt *go;
+       const struct ath5k_gain_opt_step *g_step;
+       int ret = 0;
+
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               go = &rfgain_opt_5111;
+               break;
+       case AR5K_RF5112:
+               go = &rfgain_opt_5112;
+               break;
+       default:
+               return 0;
+       }
+
+       g_step = &go->go_step[ah->ah_gain.g_step_idx];
+
+       if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
+
+               /* Reached maximum */
+               if (ah->ah_gain.g_step_idx == 0)
+                       return -1;
+
+               for (ah->ah_gain.g_target = ah->ah_gain.g_current;
+                               ah->ah_gain.g_target >=  ah->ah_gain.g_high &&
+                               ah->ah_gain.g_step_idx > 0;
+                               g_step = &go->go_step[ah->ah_gain.g_step_idx])
+                       ah->ah_gain.g_target -= 2 *
+                           (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
+                           g_step->gos_gain);
+
+               ret = 1;
+               goto done;
+       }
+
+       if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
+
+               /* Reached minimum */
+               if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
+                       return -2;
+
+               for (ah->ah_gain.g_target = ah->ah_gain.g_current;
+                               ah->ah_gain.g_target <= ah->ah_gain.g_low &&
+                               ah->ah_gain.g_step_idx < go->go_steps_count-1;
+                               g_step = &go->go_step[ah->ah_gain.g_step_idx])
+                       ah->ah_gain.g_target -= 2 *
+                           (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
+                           g_step->gos_gain);
+
+               ret = 2;
+               goto done;
+       }
+
+done:
+       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+               "ret %d, gain step %u, current gain %u, target gain %u\n",
+               ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
+               ah->ah_gain.g_target);
+
+       return ret;
+}
+
+/* Main callback for thermal rf gain calibration engine
+ * Check for a new gain reading and schedule an adjustment
+ * if needed.
+ *
+ * TODO: Use sw interrupt to schedule reset if gain_F needs
+ * adjustment */
+enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
+{
+       u32 data, type;
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_rf_banks == NULL ||
+       ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
+               return AR5K_RFGAIN_INACTIVE;
+
+       /* No check requested, either engine is inactive
+        * or an adjustment is already requested */
+       if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
+               goto done;
+
+       /* Read the PAPD (Peak to Average Power Detector)
+        * register */
+       data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
+
+       /* No probe is scheduled, read gain_F measurement */
+       if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
+               ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
+               type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
+
+               /* If tx packet is CCK correct the gain_F measurement
+                * by cck ofdm gain delta */
+               if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
+                       if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
+                               ah->ah_gain.g_current +=
+                                       ee->ee_cck_ofdm_gain_delta;
+                       else
+                               ah->ah_gain.g_current +=
+                                       AR5K_GAIN_CCK_PROBE_CORR;
+               }
+
+               /* Further correct gain_F measurement for
+                * RF5112A radios */
+               if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+                       ath5k_hw_rf_gainf_corr(ah);
+                       ah->ah_gain.g_current =
+                               ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
+                               (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
+                               0;
+               }
+
+               /* Check if measurement is ok and if we need
+                * to adjust gain, schedule a gain adjustment,
+                * else switch back to the acive state */
+               if (ath5k_hw_rf_check_gainf_readback(ah) &&
+               AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
+               ath5k_hw_rf_gainf_adjust(ah)) {
+                       ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
+               } else {
+                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+               }
+       }
+
+done:
+       return ah->ah_gain.g_state;
+}
+
+/* Write initial rf gain table to set the RF sensitivity
+ * this one works on all RF chips and has nothing to do
+ * with gain_F calibration */
+int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
+{
+       const struct ath5k_ini_rfgain *ath5k_rfg;
+       unsigned int i, size;
+
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               ath5k_rfg = rfgain_5111;
+               size = ARRAY_SIZE(rfgain_5111);
+               break;
+       case AR5K_RF5112:
+               ath5k_rfg = rfgain_5112;
+               size = ARRAY_SIZE(rfgain_5112);
+               break;
+       case AR5K_RF2413:
+               ath5k_rfg = rfgain_2413;
+               size = ARRAY_SIZE(rfgain_2413);
+               break;
+       case AR5K_RF2316:
+               ath5k_rfg = rfgain_2316;
+               size = ARRAY_SIZE(rfgain_2316);
+               break;
+       case AR5K_RF5413:
+               ath5k_rfg = rfgain_5413;
+               size = ARRAY_SIZE(rfgain_5413);
+               break;
+       case AR5K_RF2317:
+       case AR5K_RF2425:
+               ath5k_rfg = rfgain_2425;
+               size = ARRAY_SIZE(rfgain_2425);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (freq) {
+       case AR5K_INI_RFGAIN_2GHZ:
+       case AR5K_INI_RFGAIN_5GHZ:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (i = 0; i < size; i++) {
+               AR5K_REG_WAIT(i);
+               ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
+                       (u32)ath5k_rfg[i].rfg_register);
+       }
+
+       return 0;
+}
+
+
+
+/********************\
+* RF Registers setup *
+\********************/
+
+
+/*
+ * Setup RF registers by writing rf buffer on hw
+ */
+int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+               unsigned int mode)
+{
+       const struct ath5k_rf_reg *rf_regs;
+       const struct ath5k_ini_rfbuffer *ini_rfb;
+       const struct ath5k_gain_opt *go = NULL;
+       const struct ath5k_gain_opt_step *g_step;
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u8 ee_mode = 0;
+       u32 *rfb;
+       int i, obdb = -1, bank = -1;
+
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               rf_regs = rf_regs_5111;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+               ini_rfb = rfb_5111;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
+               go = &rfgain_opt_5111;
+               break;
+       case AR5K_RF5112:
+               if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+                       rf_regs = rf_regs_5112a;
+                       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+                       ini_rfb = rfb_5112a;
+                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
+               } else {
+                       rf_regs = rf_regs_5112;
+                       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+                       ini_rfb = rfb_5112;
+                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
+               }
+               go = &rfgain_opt_5112;
+               break;
+       case AR5K_RF2413:
+               rf_regs = rf_regs_2413;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
+               ini_rfb = rfb_2413;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
+               break;
+       case AR5K_RF2316:
+               rf_regs = rf_regs_2316;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
+               ini_rfb = rfb_2316;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
+               break;
+       case AR5K_RF5413:
+               rf_regs = rf_regs_5413;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
+               ini_rfb = rfb_5413;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
+               break;
+       case AR5K_RF2317:
+               rf_regs = rf_regs_2425;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+               ini_rfb = rfb_2317;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
+               break;
+       case AR5K_RF2425:
+               rf_regs = rf_regs_2425;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+               if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
+                       ini_rfb = rfb_2425;
+                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
+               } else {
+                       ini_rfb = rfb_2417;
+                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* If it's the first time we set rf buffer, allocate
+        * ah->ah_rf_banks based on ah->ah_rf_banks_size
+        * we set above */
+       if (ah->ah_rf_banks == NULL) {
+               ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
+                                                               GFP_KERNEL);
+               if (ah->ah_rf_banks == NULL) {
+                       ATH5K_ERR(ah->ah_sc, "out of memory\n");
+                       return -ENOMEM;
+               }
+       }
+
+       /* Copy values to modify them */
+       rfb = ah->ah_rf_banks;
+
+       for (i = 0; i < ah->ah_rf_banks_size; i++) {
+               if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
+                       ATH5K_ERR(ah->ah_sc, "invalid bank\n");
+                       return -EINVAL;
+               }
+
+               /* Bank changed, write down the offset */
+               if (bank != ini_rfb[i].rfb_bank) {
+                       bank = ini_rfb[i].rfb_bank;
+                       ah->ah_offset[bank] = i;
+               }
+
+               rfb[i] = ini_rfb[i].rfb_mode_data[mode];
+       }
+
+       /* Set Output and Driver bias current (OB/DB) */
+       if (channel->hw_value & CHANNEL_2GHZ) {
+
+               if (channel->hw_value & CHANNEL_CCK)
+                       ee_mode = AR5K_EEPROM_MODE_11B;
+               else
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+
+               /* For RF511X/RF211X combination we
+                * use b_OB and b_DB parameters stored
+                * in eeprom on ee->ee_ob[ee_mode][0]
+                *
+                * For all other chips we use OB/DB for 2Ghz
+                * stored in the b/g modal section just like
+                * 802.11a on ee->ee_ob[ee_mode][1] */
+               if ((ah->ah_radio == AR5K_RF5111) ||
+               (ah->ah_radio == AR5K_RF5112))
+                       obdb = 0;
+               else
+                       obdb = 1;
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+                                               AR5K_RF_OB_2GHZ, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+                                               AR5K_RF_DB_2GHZ, true);
+
+       /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
+       } else if ((channel->hw_value & CHANNEL_5GHZ) ||
+                       (ah->ah_radio == AR5K_RF5111)) {
+
+               /* For 11a, Turbo and XR we need to choose
+                * OB/DB based on frequency range */
+               ee_mode = AR5K_EEPROM_MODE_11A;
+               obdb =   channel->center_freq >= 5725 ? 3 :
+                       (channel->center_freq >= 5500 ? 2 :
+                       (channel->center_freq >= 5260 ? 1 :
+                        (channel->center_freq > 4000 ? 0 : -1)));
+
+               if (obdb < 0)
+                       return -EINVAL;
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+                                               AR5K_RF_OB_5GHZ, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+                                               AR5K_RF_DB_5GHZ, true);
+       }
+
+       g_step = &go->go_step[ah->ah_gain.g_step_idx];
+
+       /* Bank Modifications (chip-specific) */
+       if (ah->ah_radio == AR5K_RF5111) {
+
+               /* Set gain_F settings according to current step */
+               if (channel->hw_value & CHANNEL_OFDM) {
+
+                       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
+                                       AR5K_PHY_FRAME_CTL_TX_CLIP,
+                                       g_step->gos_param[0]);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+                                                       AR5K_RF_PWD_90, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+                                                       AR5K_RF_PWD_84, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+                                               AR5K_RF_RFGAIN_SEL, true);
+
+                       /* We programmed gain_F parameters, switch back
+                        * to active state */
+                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+
+               }
+
+               /* Bank 6/7 setup */
+
+               ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
+                                               AR5K_RF_PWD_XPD, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
+                                               AR5K_RF_XPD_GAIN, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+                                               AR5K_RF_GAIN_I, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+                                               AR5K_RF_PLO_SEL, true);
+
+               /* TODO: Half/quarter channel support */
+       }
+
+       if (ah->ah_radio == AR5K_RF5112) {
+
+               /* Set gain_F settings according to current step */
+               if (channel->hw_value & CHANNEL_OFDM) {
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
+                                               AR5K_RF_MIXGAIN_OVR, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+                                               AR5K_RF_PWD_138, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+                                               AR5K_RF_PWD_137, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+                                               AR5K_RF_PWD_136, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
+                                               AR5K_RF_PWD_132, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
+                                               AR5K_RF_PWD_131, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
+                                               AR5K_RF_PWD_130, true);
+
+                       /* We programmed gain_F parameters, switch back
+                        * to active state */
+                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+               }
+
+               /* Bank 6/7 setup */
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+                                               AR5K_RF_XPD_SEL, true);
+
+               if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
+                       /* Rev. 1 supports only one xpd */
+                       ath5k_hw_rfb_op(ah, rf_regs,
+                                               ee->ee_x_gain[ee_mode],
+                                               AR5K_RF_XPD_GAIN, true);
+
+               } else {
+                       /* TODO: Set high and low gain bits */
+                       ath5k_hw_rfb_op(ah, rf_regs,
+                                               ee->ee_x_gain[ee_mode],
+                                               AR5K_RF_PD_GAIN_LO, true);
+                       ath5k_hw_rfb_op(ah, rf_regs,
+                                               ee->ee_x_gain[ee_mode],
+                                               AR5K_RF_PD_GAIN_HI, true);
+
+                       /* Lower synth voltage on Rev 2 */
+                       ath5k_hw_rfb_op(ah, rf_regs, 2,
+                                       AR5K_RF_HIGH_VC_CP, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, 2,
+                                       AR5K_RF_MID_VC_CP, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, 2,
+                                       AR5K_RF_LOW_VC_CP, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, 2,
+                                       AR5K_RF_PUSH_UP, true);
+
+                       /* Decrease power consumption on 5213+ BaseBand */
+                       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_PAD2GND, true);
+
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_XB2_LVL, true);
+
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_XB5_LVL, true);
+
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_PWD_167, true);
+
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_PWD_166, true);
+                       }
+               }
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+                                               AR5K_RF_GAIN_I, true);
+
+               /* TODO: Half/quarter channel support */
+
+       }
+
+       if (ah->ah_radio == AR5K_RF5413 &&
+       channel->hw_value & CHANNEL_2GHZ) {
+
+               ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
+                                                                       true);
+
+               /* Set optimum value for early revisions (on pci-e chips) */
+               if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
+               ah->ah_mac_srev < AR5K_SREV_AR5413)
+                       ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
+                                               AR5K_RF_PWD_ICLOBUF_2G, true);
+
+       }
+
+       /* Write RF banks on hw */
+       for (i = 0; i < ah->ah_rf_banks_size; i++) {
+               AR5K_REG_WAIT(i);
+               ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
+       }
+
+       return 0;
+}
+
+
+/**************************\
+  PHY/RF channel functions
+\**************************/
+
+/*
+ * Check if a channel is supported
+ */
+bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
+{
+       /* Check if the channel is in our supported range */
+       if (flags & CHANNEL_2GHZ) {
+               if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
+                   (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
+                       return true;
+       } else if (flags & CHANNEL_5GHZ)
+               if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
+                   (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
+                       return true;
+
+       return false;
+}
+
+/*
+ * Convertion needed for RF5110
+ */
+static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
+{
+       u32 athchan;
+
+       /*
+        * Convert IEEE channel/MHz to an internal channel value used
+        * by the AR5210 chipset. This has not been verified with
+        * newer chipsets like the AR5212A who have a completely
+        * different RF/PHY part.
+        */
+       athchan = (ath5k_hw_bitswap(
+                       (ieee80211_frequency_to_channel(
+                               channel->center_freq) - 24) / 2, 5)
+                               << 1) | (1 << 6) | 0x1;
+       return athchan;
+}
+
+/*
+ * Set channel on RF5110
+ */
+static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 data;
+
+       /*
+        * Set the channel and wait
+        */
+       data = ath5k_hw_rf5110_chan2athchan(channel);
+       ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER);
+       ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0);
+       mdelay(1);
+
+       return 0;
+}
+
+/*
+ * Convertion needed for 5111
+ */
+static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
+               struct ath5k_athchan_2ghz *athchan)
+{
+       int channel;
+
+       /* Cast this value to catch negative channel numbers (>= -19) */
+       channel = (int)ieee;
+
+       /*
+        * Map 2GHz IEEE channel to 5GHz Atheros channel
+        */
+       if (channel <= 13) {
+               athchan->a2_athchan = 115 + channel;
+               athchan->a2_flags = 0x46;
+       } else if (channel == 14) {
+               athchan->a2_athchan = 124;
+               athchan->a2_flags = 0x44;
+       } else if (channel >= 15 && channel <= 26) {
+               athchan->a2_athchan = ((channel - 14) * 4) + 132;
+               athchan->a2_flags = 0x46;
+       } else
+               return -EINVAL;
+
+       return 0;
+}
+
+/*
+ * Set channel on 5111
+ */
+static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       struct ath5k_athchan_2ghz ath5k_channel_2ghz;
+       unsigned int ath5k_channel =
+               ieee80211_frequency_to_channel(channel->center_freq);
+       u32 data0, data1, clock;
+       int ret;
+
+       /*
+        * Set the channel on the RF5111 radio
+        */
+       data0 = data1 = 0;
+
+       if (channel->hw_value & CHANNEL_2GHZ) {
+               /* Map 2GHz channel to 5GHz Atheros channel ID */
+               ret = ath5k_hw_rf5111_chan2athchan(
+                       ieee80211_frequency_to_channel(channel->center_freq),
+                       &ath5k_channel_2ghz);
+               if (ret)
+                       return ret;
+
+               ath5k_channel = ath5k_channel_2ghz.a2_athchan;
+               data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
+                   << 5) | (1 << 4);
+       }
+
+       if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
+               clock = 1;
+               data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
+                       (clock << 1) | (1 << 10) | 1;
+       } else {
+               clock = 0;
+               data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
+                       << 2) | (clock << 1) | (1 << 10) | 1;
+       }
+
+       ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
+                       AR5K_RF_BUFFER);
+       ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
+                       AR5K_RF_BUFFER_CONTROL_3);
+
+       return 0;
+}
+
+/*
+ * Set channel on 5112 and newer
+ */
+static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 data, data0, data1, data2;
+       u16 c;
+
+       data = data0 = data1 = data2 = 0;
+       c = channel->center_freq;
+
+       if (c < 4800) {
+               if (!((c - 2224) % 5)) {
+                       data0 = ((2 * (c - 704)) - 3040) / 10;
+                       data1 = 1;
+               } else if (!((c - 2192) % 5)) {
+                       data0 = ((2 * (c - 672)) - 3040) / 10;
+                       data1 = 0;
+               } else
+                       return -EINVAL;
+
+               data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
+       } else if ((c - (c % 5)) != 2 || c > 5435) {
+               if (!(c % 20) && c >= 5120) {
+                       data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
+                       data2 = ath5k_hw_bitswap(3, 2);
+               } else if (!(c % 10)) {
+                       data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
+                       data2 = ath5k_hw_bitswap(2, 2);
+               } else if (!(c % 5)) {
+                       data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
+                       data2 = ath5k_hw_bitswap(1, 2);
+               } else
+                       return -EINVAL;
+       } else {
+               data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
+               data2 = ath5k_hw_bitswap(0, 2);
+       }
+
+       data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
+
+       ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
+       ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
+
+       return 0;
+}
+
+/*
+ * Set the channel on the RF2425
+ */
+static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 data, data0, data2;
+       u16 c;
+
+       data = data0 = data2 = 0;
+       c = channel->center_freq;
+
+       if (c < 4800) {
+               data0 = ath5k_hw_bitswap((c - 2272), 8);
+               data2 = 0;
+       /* ? 5GHz ? */
+       } else if ((c - (c % 5)) != 2 || c > 5435) {
+               if (!(c % 20) && c < 5120)
+                       data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
+               else if (!(c % 10))
+                       data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
+               else if (!(c % 5))
+                       data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
+               else
+                       return -EINVAL;
+               data2 = ath5k_hw_bitswap(1, 2);
+       } else {
+               data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
+               data2 = ath5k_hw_bitswap(0, 2);
+       }
+
+       data = (data0 << 4) | data2 << 2 | 0x1001;
+
+       ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
+       ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
+
+       return 0;
+}
+
+/*
+ * Set a channel on the radio chip
+ */
+int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
+{
+       int ret;
+       /*
+        * Check bounds supported by the PHY (we don't care about regultory
+        * restrictions at this point). Note: hw_value already has the band
+        * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok()
+        * of the band by that */
+       if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) {
+               ATH5K_ERR(ah->ah_sc,
+                       "channel frequency (%u MHz) out of supported "
+                       "band range\n",
+                       channel->center_freq);
+                       return -EINVAL;
+       }
+
+       /*
+        * Set the channel and wait
+        */
+       switch (ah->ah_radio) {
+       case AR5K_RF5110:
+               ret = ath5k_hw_rf5110_channel(ah, channel);
+               break;
+       case AR5K_RF5111:
+               ret = ath5k_hw_rf5111_channel(ah, channel);
+               break;
+       case AR5K_RF2425:
+               ret = ath5k_hw_rf2425_channel(ah, channel);
+               break;
+       default:
+               ret = ath5k_hw_rf5112_channel(ah, channel);
+               break;
+       }
+
+       if (ret)
+               return ret;
+
+       /* Set JAPAN setting for channel 14 */
+       if (channel->center_freq == 2484) {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
+                               AR5K_PHY_CCKTXCTL_JAPAN);
+       } else {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
+                               AR5K_PHY_CCKTXCTL_WORLD);
+       }
+
+       ah->ah_current_channel.center_freq = channel->center_freq;
+       ah->ah_current_channel.hw_value = channel->hw_value;
+       ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
+
+       return 0;
+}
+
+/*****************\
+  PHY calibration
+\*****************/
+
+/**
+ * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
+ *
+ * @ah: struct ath5k_hw pointer we are operating on
+ * @freq: the channel frequency, just used for error logging
+ *
+ * This function performs a noise floor calibration of the PHY and waits for
+ * it to complete. Then the noise floor value is compared to some maximum
+ * noise floor we consider valid.
+ *
+ * Note that this is different from what the madwifi HAL does: it reads the
+ * noise floor and afterwards initiates the calibration. Since the noise floor
+ * calibration can take some time to finish, depending on the current channel
+ * use, that avoids the occasional timeout warnings we are seeing now.
+ *
+ * See the following link for an Atheros patent on noise floor calibration:
+ * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \
+ * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7
+ *
+ * XXX: Since during noise floor calibration antennas are detached according to
+ * the patent, we should stop tx queues here.
+ */
+int
+ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
+{
+       int ret;
+       unsigned int i;
+       s32 noise_floor;
+
+       /*
+        * Enable noise floor calibration
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+                               AR5K_PHY_AGCCTL_NF);
+
+       ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
+                       AR5K_PHY_AGCCTL_NF, 0, false);
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc,
+                       "noise floor calibration timeout (%uMHz)\n", freq);
+               return -EAGAIN;
+       }
+
+       /* Wait until the noise floor is calibrated and read the value */
+       for (i = 20; i > 0; i--) {
+               mdelay(1);
+               noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
+               noise_floor = AR5K_PHY_NF_RVAL(noise_floor);
+               if (noise_floor & AR5K_PHY_NF_ACTIVE) {
+                       noise_floor = AR5K_PHY_NF_AVAL(noise_floor);
+
+                       if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
+                               break;
+               }
+       }
+
+       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+               "noise floor %d\n", noise_floor);
+
+       if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
+               ATH5K_ERR(ah->ah_sc,
+                       "noise floor calibration failed (%uMHz)\n", freq);
+               return -EAGAIN;
+       }
+
+       ah->ah_noise_floor = noise_floor;
+
+       return 0;
+}
+
+/*
+ * Perform a PHY calibration on RF5110
+ * -Fix BPSK/QAM Constellation (I/Q correction)
+ * -Calculate Noise Floor
+ */
+static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 phy_sig, phy_agc, phy_sat, beacon;
+       int ret;
+
+       /*
+        * Disable beacons and RX/TX queues, wait
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
+               AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
+       beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
+       ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
+
+       mdelay(2);
+
+       /*
+        * Set the channel (with AGC turned off)
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
+       udelay(10);
+       ret = ath5k_hw_channel(ah, channel);
+
+       /*
+        * Activate PHY and wait
+        */
+       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
+       mdelay(1);
+
+       AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
+
+       if (ret)
+               return ret;
+
+       /*
+        * Calibrate the radio chip
+        */
+
+       /* Remember normal state */
+       phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG);
+       phy_agc = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCOARSE);
+       phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT);
+
+       /* Update radio registers */
+       ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
+               AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG);
+
+       ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI |
+                       AR5K_PHY_AGCCOARSE_LO)) |
+               AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) |
+               AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE);
+
+       ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT |
+                       AR5K_PHY_ADCSAT_THR)) |
+               AR5K_REG_SM(2, AR5K_PHY_ADCSAT_ICNT) |
+               AR5K_REG_SM(12, AR5K_PHY_ADCSAT_THR), AR5K_PHY_ADCSAT);
+
+       udelay(20);
+
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
+       udelay(10);
+       ath5k_hw_reg_write(ah, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG);
+       AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
+
+       mdelay(1);
+
+       /*
+        * Enable calibration and wait until completion
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL);
+
+       ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
+                       AR5K_PHY_AGCCTL_CAL, 0, false);
+
+       /* Reset to normal state */
+       ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG);
+       ath5k_hw_reg_write(ah, phy_agc, AR5K_PHY_AGCCOARSE);
+       ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT);
+
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
+                               channel->center_freq);
+               return ret;
+       }
+
+       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+
+       /*
+        * Re-enable RX/TX and beacons
+        */
+       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
+               AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
+       ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
+
+       return 0;
+}
+
+/*
+ * Perform a PHY calibration on RF5111/5112 and newer chips
+ */
+static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 i_pwr, q_pwr;
+       s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
+       int i;
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (!ah->ah_calibration ||
+               ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
+               goto done;
+
+       /* Calibration has finished, get the results and re-run */
+       for (i = 0; i <= 10; i++) {
+               iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
+               i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
+               q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
+       }
+
+       i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
+       q_coffd = q_pwr >> 7;
+
+       /* No correction */
+       if (i_coffd == 0 || q_coffd == 0)
+               goto done;
+
+       i_coff = ((-iq_corr) / i_coffd) & 0x3f;
+
+       /* Boundary check */
+       if (i_coff > 31)
+               i_coff = 31;
+       if (i_coff < -32)
+               i_coff = -32;
+
+       q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f;
+
+       /* Boundary check */
+       if (q_coff > 15)
+               q_coff = 15;
+       if (q_coff < -16)
+               q_coff = -16;
+
+       /* Commit new I/Q value */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
+               ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
+
+       /* Re-enable calibration -if we don't we'll commit
+        * the same values again and again */
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
+                       AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
+
+done:
+
+       /* TODO: Separate noise floor calibration from I/Q calibration
+        * since noise floor calibration interrupts rx path while I/Q
+        * calibration doesn't. We don't need to run noise floor calibration
+        * as often as I/Q calibration.*/
+       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+
+       /* Initiate a gain_F calibration */
+       ath5k_hw_request_rfgain_probe(ah);
+
+       return 0;
+}
+
+/*
+ * Perform a PHY calibration
+ */
+int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       int ret;
+
+       if (ah->ah_radio == AR5K_RF5110)
+               ret = ath5k_hw_rf5110_calibrate(ah, channel);
+       else
+               ret = ath5k_hw_rf511x_calibrate(ah, channel);
+
+       return ret;
+}
+
+int ath5k_hw_phy_disable(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       /*Just a try M.F.*/
+       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
+
+       return 0;
+}
+
+/********************\
+  Misc PHY functions
+\********************/
+
+/*
+ * Get the PHY Chip revision
+ */
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
+{
+       unsigned int i;
+       u32 srev;
+       u16 ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*
+        * Set the radio chip access register
+        */
+       switch (chan) {
+       case CHANNEL_2GHZ:
+               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
+               break;
+       case CHANNEL_5GHZ:
+               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+               break;
+       default:
+               return 0;
+       }
+
+       mdelay(2);
+
+       /* ...wait until PHY is ready and read the selected radio revision */
+       ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
+
+       for (i = 0; i < 8; i++)
+               ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
+
+       if (ah->ah_version == AR5K_AR5210) {
+               srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
+               ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
+       } else {
+               srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
+               ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
+                               ((srev & 0x0f) << 4), 8);
+       }
+
+       /* Reset to the 5GHz mode */
+       ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+
+       return ret;
+}
+
+void /*TODO:Boundary check*/
+ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       /*Just a try M.F.*/
+       if (ah->ah_version != AR5K_AR5210)
+               ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA);
+}
+
+unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       /*Just a try M.F.*/
+       if (ah->ah_version != AR5K_AR5210)
+               return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
+
+       return false; /*XXX: What do we return for 5210 ?*/
+}
+
+
+/****************\
+* TX power setup *
+\****************/
+
+/*
+ * Helper functions
+ */
+
+/*
+ * Do linear interpolation between two given (x, y) points
+ */
+static s16
+ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
+                                       s16 y_left, s16 y_right)
+{
+       s16 ratio, result;
+
+       /* Avoid divide by zero and skip interpolation
+        * if we have the same point */
+       if ((x_left == x_right) || (y_left == y_right))
+               return y_left;
+
+       /*
+        * Since we use ints and not fps, we need to scale up in
+        * order to get a sane ratio value (or else we 'll eg. get
+        * always 1 instead of 1.25, 1.75 etc). We scale up by 100
+        * to have some accuracy both for 0.5 and 0.25 steps.
+        */
+       ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left));
+
+       /* Now scale down to be in range */
+       result = y_left + (ratio * (target - x_left) / 100);
+
+       return result;
+}
+
+/*
+ * Find vertical boundary (min pwr) for the linear PCDAC curve.
+ *
+ * Since we have the top of the curve and we draw the line below
+ * until we reach 1 (1 pcdac step) we need to know which point
+ * (x value) that is so that we don't go below y axis and have negative
+ * pcdac values when creating the curve, or fill the table with zeroes.
+ */
+static s16
+ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
+                               const s16 *pwrL, const s16 *pwrR)
+{
+       s8 tmp;
+       s16 min_pwrL, min_pwrR;
+       s16 pwr_i = pwrL[0];
+
+       do {
+               pwr_i--;
+               tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+                                               pwrL[0], pwrL[1],
+                                               stepL[0], stepL[1]);
+
+       } while (tmp > 1);
+
+       min_pwrL = pwr_i;
+
+       pwr_i = pwrR[0];
+       do {
+               pwr_i--;
+               tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+                                               pwrR[0], pwrR[1],
+                                               stepR[0], stepR[1]);
+
+       } while (tmp > 1);
+
+       min_pwrR = pwr_i;
+
+       /* Keep the right boundary so that it works for both curves */
+       return max(min_pwrL, min_pwrR);
+}
+
+/*
+ * Interpolate (pwr,vpd) points to create a Power to PDADC or a
+ * Power to PCDAC curve.
+ *
+ * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC
+ * steps (offsets) on y axis. Power can go up to 31.5dB and max
+ * PCDAC/PDADC step for each curve is 64 but we can write more than
+ * one curves on hw so we can go up to 128 (which is the max step we
+ * can write on the final table).
+ *
+ * We write y values (PCDAC/PDADC steps) on hw.
+ */
+static void
+ath5k_create_power_curve(s16 pmin, s16 pmax,
+                       const s16 *pwr, const u8 *vpd,
+                       u8 num_points,
+                       u8 *vpd_table, u8 type)
+{
+       u8 idx[2] = { 0, 1 };
+       s16 pwr_i = 2*pmin;
+       int i;
+
+       if (num_points < 2)
+               return;
+
+       /* We want the whole line, so adjust boundaries
+        * to cover the entire power range. Note that
+        * power values are already 0.25dB so no need
+        * to multiply pwr_i by 2 */
+       if (type == AR5K_PWRTABLE_LINEAR_PCDAC) {
+               pwr_i = pmin;
+               pmin = 0;
+               pmax = 63;
+       }
+
+       /* Find surrounding turning points (TPs)
+        * and interpolate between them */
+       for (i = 0; (i <= (u16) (pmax - pmin)) &&
+       (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
+
+               /* We passed the right TP, move to the next set of TPs
+                * if we pass the last TP, extrapolate above using the last
+                * two TPs for ratio */
+               if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
+                       idx[0]++;
+                       idx[1]++;
+               }
+
+               vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
+                                               pwr[idx[0]], pwr[idx[1]],
+                                               vpd[idx[0]], vpd[idx[1]]);
+
+               /* Increase by 0.5dB
+                * (0.25 dB units) */
+               pwr_i += 2;
+       }
+}
+
+/*
+ * Get the surrounding per-channel power calibration piers
+ * for a given frequency so that we can interpolate between
+ * them and come up with an apropriate dataset for our current
+ * channel.
+ */
+static void
+ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
+                       struct ieee80211_channel *channel,
+                       struct ath5k_chan_pcal_info **pcinfo_l,
+                       struct ath5k_chan_pcal_info **pcinfo_r)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *pcinfo;
+       u8 idx_l, idx_r;
+       u8 mode, max, i;
+       u32 target = channel->center_freq;
+
+       idx_l = 0;
+       idx_r = 0;
+
+       if (!(channel->hw_value & CHANNEL_OFDM)) {
+               pcinfo = ee->ee_pwr_cal_b;
+               mode = AR5K_EEPROM_MODE_11B;
+       } else if (channel->hw_value & CHANNEL_2GHZ) {
+               pcinfo = ee->ee_pwr_cal_g;
+               mode = AR5K_EEPROM_MODE_11G;
+       } else {
+               pcinfo = ee->ee_pwr_cal_a;
+               mode = AR5K_EEPROM_MODE_11A;
+       }
+       max = ee->ee_n_piers[mode] - 1;
+
+       /* Frequency is below our calibrated
+        * range. Use the lowest power curve
+        * we have */
+       if (target < pcinfo[0].freq) {
+               idx_l = idx_r = 0;
+               goto done;
+       }
+
+       /* Frequency is above our calibrated
+        * range. Use the highest power curve
+        * we have */
+       if (target > pcinfo[max].freq) {
+               idx_l = idx_r = max;
+               goto done;
+       }
+
+       /* Frequency is inside our calibrated
+        * channel range. Pick the surrounding
+        * calibration piers so that we can
+        * interpolate */
+       for (i = 0; i <= max; i++) {
+
+               /* Frequency matches one of our calibration
+                * piers, no need to interpolate, just use
+                * that calibration pier */
+               if (pcinfo[i].freq == target) {
+                       idx_l = idx_r = i;
+                       goto done;
+               }
+
+               /* We found a calibration pier that's above
+                * frequency, use this pier and the previous
+                * one to interpolate */
+               if (target < pcinfo[i].freq) {
+                       idx_r = i;
+                       idx_l = idx_r - 1;
+                       goto done;
+               }
+       }
+
+done:
+       *pcinfo_l = &pcinfo[idx_l];
+       *pcinfo_r = &pcinfo[idx_r];
+
+       return;
+}
+
+/*
+ * Get the surrounding per-rate power calibration data
+ * for a given frequency and interpolate between power
+ * values to set max target power supported by hw for
+ * each rate.
+ */
+static void
+ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
+                       struct ieee80211_channel *channel,
+                       struct ath5k_rate_pcal_info *rates)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_rate_pcal_info *rpinfo;
+       u8 idx_l, idx_r;
+       u8 mode, max, i;
+       u32 target = channel->center_freq;
+
+       idx_l = 0;
+       idx_r = 0;
+
+       if (!(channel->hw_value & CHANNEL_OFDM)) {
+               rpinfo = ee->ee_rate_tpwr_b;
+               mode = AR5K_EEPROM_MODE_11B;
+       } else if (channel->hw_value & CHANNEL_2GHZ) {
+               rpinfo = ee->ee_rate_tpwr_g;
+               mode = AR5K_EEPROM_MODE_11G;
+       } else {
+               rpinfo = ee->ee_rate_tpwr_a;
+               mode = AR5K_EEPROM_MODE_11A;
+       }
+       max = ee->ee_rate_target_pwr_num[mode] - 1;
+
+       /* Get the surrounding calibration
+        * piers - same as above */
+       if (target < rpinfo[0].freq) {
+               idx_l = idx_r = 0;
+               goto done;
+       }
+
+       if (target > rpinfo[max].freq) {
+               idx_l = idx_r = max;
+               goto done;
+       }
+
+       for (i = 0; i <= max; i++) {
+
+               if (rpinfo[i].freq == target) {
+                       idx_l = idx_r = i;
+                       goto done;
+               }
+
+               if (target < rpinfo[i].freq) {
+                       idx_r = i;
+                       idx_l = idx_r - 1;
+                       goto done;
+               }
+       }
+
+done:
+       /* Now interpolate power value, based on the frequency */
+       rates->freq = target;
+
+       rates->target_power_6to24 =
+               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+                                       rpinfo[idx_r].freq,
+                                       rpinfo[idx_l].target_power_6to24,
+                                       rpinfo[idx_r].target_power_6to24);
+
+       rates->target_power_36 =
+               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+                                       rpinfo[idx_r].freq,
+                                       rpinfo[idx_l].target_power_36,
+                                       rpinfo[idx_r].target_power_36);
+
+       rates->target_power_48 =
+               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+                                       rpinfo[idx_r].freq,
+                                       rpinfo[idx_l].target_power_48,
+                                       rpinfo[idx_r].target_power_48);
+
+       rates->target_power_54 =
+               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+                                       rpinfo[idx_r].freq,
+                                       rpinfo[idx_l].target_power_54,
+                                       rpinfo[idx_r].target_power_54);
+}
+
+/*
+ * Get the max edge power for this channel if
+ * we have such data from EEPROM's Conformance Test
+ * Limits (CTL), and limit max power if needed.
+ *
+ * FIXME: Only works for world regulatory domains
+ */
+static void
+ath5k_get_max_ctl_power(struct ath5k_hw *ah,
+                       struct ieee80211_channel *channel)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
+       u8 *ctl_val = ee->ee_ctl;
+       s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
+       s16 edge_pwr = 0;
+       u8 rep_idx;
+       u8 i, ctl_mode;
+       u8 ctl_idx = 0xFF;
+       u32 target = channel->center_freq;
+
+       /* Find out a CTL for our mode that's not mapped
+        * on a specific reg domain.
+        *
+        * TODO: Map our current reg domain to one of the 3 available
+        * reg domain ids so that we can support more CTLs. */
+       switch (channel->hw_value & CHANNEL_MODES) {
+       case CHANNEL_A:
+               ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN;
+               break;
+       case CHANNEL_G:
+               ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN;
+               break;
+       case CHANNEL_B:
+               ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN;
+               break;
+       case CHANNEL_T:
+               ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN;
+               break;
+       case CHANNEL_TG:
+               ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN;
+               break;
+       case CHANNEL_XR:
+               /* Fall through */
+       default:
+               return;
+       }
+
+       for (i = 0; i < ee->ee_ctls; i++) {
+               if (ctl_val[i] == ctl_mode) {
+                       ctl_idx = i;
+                       break;
+               }
+       }
+
+       /* If we have a CTL dataset available grab it and find the
+        * edge power for our frequency */
+       if (ctl_idx == 0xFF)
+               return;
+
+       /* Edge powers are sorted by frequency from lower
+        * to higher. Each CTL corresponds to 8 edge power
+        * measurements. */
+       rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
+
+       /* Don't do boundaries check because we
+        * might have more that one bands defined
+        * for this mode */
+
+       /* Get the edge power that's closer to our
+        * frequency */
+       for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
+               rep_idx += i;
+               if (target <= rep[rep_idx].freq)
+                       edge_pwr = (s16) rep[rep_idx].edge;
+       }
+
+       if (edge_pwr)
+               ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr);
+}
+
+
+/*
+ * Power to PCDAC table functions
+ */
+
+/*
+ * Fill Power to PCDAC table on RF5111
+ *
+ * No further processing is needed for RF5111, the only thing we have to
+ * do is fill the values below and above calibration range since eeprom data
+ * may not cover the entire PCDAC table.
+ */
+static void
+ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
+                                                       s16 *table_max)
+{
+       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
+       u8      *pcdac_tmp = ah->ah_txpower.tmpL[0];
+       u8      pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
+       s16     min_pwr, max_pwr;
+
+       /* Get table boundaries */
+       min_pwr = table_min[0];
+       pcdac_0 = pcdac_tmp[0];
+
+       max_pwr = table_max[0];
+       pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
+
+       /* Extrapolate below minimum using pcdac_0 */
+       pcdac_i = 0;
+       for (i = 0; i < min_pwr; i++)
+               pcdac_out[pcdac_i++] = pcdac_0;
+
+       /* Copy values from pcdac_tmp */
+       pwr_idx = min_pwr;
+       for (i = 0 ; pwr_idx <= max_pwr &&
+       pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
+               pcdac_out[pcdac_i++] = pcdac_tmp[i];
+               pwr_idx++;
+       }
+
+       /* Extrapolate above maximum */
+       while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
+               pcdac_out[pcdac_i++] = pcdac_n;
+
+}
+
+/*
+ * Combine available XPD Curves and fill Linear Power to PCDAC table
+ * on RF5112
+ *
+ * RFX112 can have up to 2 curves (one for low txpower range and one for
+ * higher txpower range). We need to put them both on pcdac_out and place
+ * them in the correct location. In case we only have one curve available
+ * just fit it on pcdac_out (it's supposed to cover the entire range of
+ * available pwr levels since it's always the higher power curve). Extrapolate
+ * below and above final table if needed.
+ */
+static void
+ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
+                                               s16 *table_max, u8 pdcurves)
+{
+       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
+       u8      *pcdac_low_pwr;
+       u8      *pcdac_high_pwr;
+       u8      *pcdac_tmp;
+       u8      pwr;
+       s16     max_pwr_idx;
+       s16     min_pwr_idx;
+       s16     mid_pwr_idx = 0;
+       /* Edge flag turs on the 7nth bit on the PCDAC
+        * to delcare the higher power curve (force values
+        * to be greater than 64). If we only have one curve
+        * we don't need to set this, if we have 2 curves and
+        * fill the table backwards this can also be used to
+        * switch from higher power curve to lower power curve */
+       u8      edge_flag;
+       int     i;
+
+       /* When we have only one curve available
+        * that's the higher power curve. If we have
+        * two curves the first is the high power curve
+        * and the next is the low power curve. */
+       if (pdcurves > 1) {
+               pcdac_low_pwr = ah->ah_txpower.tmpL[1];
+               pcdac_high_pwr = ah->ah_txpower.tmpL[0];
+               mid_pwr_idx = table_max[1] - table_min[1] - 1;
+               max_pwr_idx = (table_max[0] - table_min[0]) / 2;
+
+               /* If table size goes beyond 31.5dB, keep the
+                * upper 31.5dB range when setting tx power.
+                * Note: 126 = 31.5 dB in quarter dB steps */
+               if (table_max[0] - table_min[1] > 126)
+                       min_pwr_idx = table_max[0] - 126;
+               else
+                       min_pwr_idx = table_min[1];
+
+               /* Since we fill table backwards
+                * start from high power curve */
+               pcdac_tmp = pcdac_high_pwr;
+
+               edge_flag = 0x40;
+#if 0
+               /* If both min and max power limits are in lower
+                * power curve's range, only use the low power curve.
+                * TODO: min/max levels are related to target
+                * power values requested from driver/user
+                * XXX: Is this really needed ? */
+               if (min_pwr < table_max[1] &&
+               max_pwr < table_max[1]) {
+                       edge_flag = 0;
+                       pcdac_tmp = pcdac_low_pwr;
+                       max_pwr_idx = (table_max[1] - table_min[1])/2;
+               }
+#endif
+       } else {
+               pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
+               pcdac_high_pwr = ah->ah_txpower.tmpL[0];
+               min_pwr_idx = table_min[0];
+               max_pwr_idx = (table_max[0] - table_min[0]) / 2;
+               pcdac_tmp = pcdac_high_pwr;
+               edge_flag = 0;
+       }
+
+       /* This is used when setting tx power*/
+       ah->ah_txpower.txp_min_idx = min_pwr_idx/2;
+
+       /* Fill Power to PCDAC table backwards */
+       pwr = max_pwr_idx;
+       for (i = 63; i >= 0; i--) {
+               /* Entering lower power range, reset
+                * edge flag and set pcdac_tmp to lower
+                * power curve.*/
+               if (edge_flag == 0x40 &&
+               (2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
+                       edge_flag = 0x00;
+                       pcdac_tmp = pcdac_low_pwr;
+                       pwr = mid_pwr_idx/2;
+               }
+
+               /* Don't go below 1, extrapolate below if we have
+                * already swithced to the lower power curve -or
+                * we only have one curve and edge_flag is zero
+                * anyway */
+               if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
+                       while (i >= 0) {
+                               pcdac_out[i] = pcdac_out[i + 1];
+                               i--;
+                       }
+                       break;
+               }
+
+               pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
+
+               /* Extrapolate above if pcdac is greater than
+                * 126 -this can happen because we OR pcdac_out
+                * value with edge_flag on high power curve */
+               if (pcdac_out[i] > 126)
+                       pcdac_out[i] = 126;
+
+               /* Decrease by a 0.5dB step */
+               pwr--;
+       }
+}
+
+/* Write PCDAC values on hw */
+static void
+ath5k_setup_pcdac_table(struct ath5k_hw *ah)
+{
+       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
+       int     i;
+
+       /*
+        * Write TX power values
+        */
+       for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
+               ath5k_hw_reg_write(ah,
+                       (((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) |
+                       (((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16),
+                       AR5K_PHY_PCDAC_TXPOWER(i));
+       }
+}
+
+
+/*
+ * Power to PDADC table functions
+ */
+
+/*
+ * Set the gain boundaries and create final Power to PDADC table
+ *
+ * We can have up to 4 pd curves, we need to do a simmilar process
+ * as we do for RF5112. This time we don't have an edge_flag but we
+ * set the gain boundaries on a separate register.
+ */
+static void
+ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
+                       s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
+{
+       u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
+       u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+       u8 *pdadc_tmp;
+       s16 pdadc_0;
+       u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
+       u8 pd_gain_overlap;
+
+       /* Note: Register value is initialized on initvals
+        * there is no feedback from hw.
+        * XXX: What about pd_gain_overlap from EEPROM ? */
+       pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
+               AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
+
+       /* Create final PDADC table */
+       for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
+               pdadc_tmp = ah->ah_txpower.tmpL[pdg];
+
+               if (pdg == pdcurves - 1)
+                       /* 2 dB boundary stretch for last
+                        * (higher power) curve */
+                       gain_boundaries[pdg] = pwr_max[pdg] + 4;
+               else
+                       /* Set gain boundary in the middle
+                        * between this curve and the next one */
+                       gain_boundaries[pdg] =
+                               (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
+
+               /* Sanity check in case our 2 db stretch got out of
+                * range. */
+               if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
+                       gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
+
+               /* For the first curve (lower power)
+                * start from 0 dB */
+               if (pdg == 0)
+                       pdadc_0 = 0;
+               else
+                       /* For the other curves use the gain overlap */
+                       pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
+                                                       pd_gain_overlap;
+
+               /* Force each power step to be at least 0.5 dB */
+               if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
+                       pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
+               else
+                       pwr_step = 1;
+
+               /* If pdadc_0 is negative, we need to extrapolate
+                * below this pdgain by a number of pwr_steps */
+               while ((pdadc_0 < 0) && (pdadc_i < 128)) {
+                       s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
+                       pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
+                       pdadc_0++;
+               }
+
+               /* Set last pwr level, using gain boundaries */
+               pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
+               /* Limit it to be inside pwr range */
+               table_size = pwr_max[pdg] - pwr_min[pdg];
+               max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
+
+               /* Fill pdadc_out table */
+               while (pdadc_0 < max_idx)
+                       pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
+
+               /* Need to extrapolate above this pdgain? */
+               if (pdadc_n <= max_idx)
+                       continue;
+
+               /* Force each power step to be at least 0.5 dB */
+               if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
+                       pwr_step = pdadc_tmp[table_size - 1] -
+                                               pdadc_tmp[table_size - 2];
+               else
+                       pwr_step = 1;
+
+               /* Extrapolate above */
+               while ((pdadc_0 < (s16) pdadc_n) &&
+               (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
+                       s16 tmp = pdadc_tmp[table_size - 1] +
+                                       (pdadc_0 - max_idx) * pwr_step;
+                       pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
+                       pdadc_0++;
+               }
+       }
+
+       while (pdg < AR5K_EEPROM_N_PD_GAINS) {
+               gain_boundaries[pdg] = gain_boundaries[pdg - 1];
+               pdg++;
+       }
+
+       while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
+               pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
+               pdadc_i++;
+       }
+
+       /* Set gain boundaries */
+       ath5k_hw_reg_write(ah,
+               AR5K_REG_SM(pd_gain_overlap,
+                       AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
+               AR5K_REG_SM(gain_boundaries[0],
+                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
+               AR5K_REG_SM(gain_boundaries[1],
+                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
+               AR5K_REG_SM(gain_boundaries[2],
+                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
+               AR5K_REG_SM(gain_boundaries[3],
+                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
+               AR5K_PHY_TPC_RG5);
+
+       /* Used for setting rate power table */
+       ah->ah_txpower.txp_min_idx = pwr_min[0];
+
+}
+
+/* Write PDADC values on hw */
+static void
+ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah,
+                       u8 pdcurves, u8 *pdg_to_idx)
+{
+       u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+       u32 reg;
+       u8 i;
+
+       /* Select the right pdgain curves */
+
+       /* Clear current settings */
+       reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
+       reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
+               AR5K_PHY_TPC_RG1_PDGAIN_2 |
+               AR5K_PHY_TPC_RG1_PDGAIN_3 |
+               AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
+
+       /*
+        * Use pd_gains curve from eeprom
+        *
+        * This overrides the default setting from initvals
+        * in case some vendors (e.g. Zcomax) don't use the default
+        * curves. If we don't honor their settings we 'll get a
+        * 5dB (1 * gain overlap ?) drop.
+        */
+       reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
+
+       switch (pdcurves) {
+       case 3:
+               reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
+               /* Fall through */
+       case 2:
+               reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
+               /* Fall through */
+       case 1:
+               reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
+               break;
+       }
+       ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
+
+       /*
+        * Write TX power values
+        */
+       for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
+               ath5k_hw_reg_write(ah,
+                       ((pdadc_out[4*i + 0] & 0xff) << 0) |
+                       ((pdadc_out[4*i + 1] & 0xff) << 8) |
+                       ((pdadc_out[4*i + 2] & 0xff) << 16) |
+                       ((pdadc_out[4*i + 3] & 0xff) << 24),
+                       AR5K_PHY_PDADC_TXPOWER(i));
+       }
+}
+
+
+/*
+ * Common code for PCDAC/PDADC tables
+ */
+
+/*
+ * This is the main function that uses all of the above
+ * to set PCDAC/PDADC table on hw for the current channel.
+ * This table is used for tx power calibration on the basband,
+ * without it we get weird tx power levels and in some cases
+ * distorted spectral mask
+ */
+static int
+ath5k_setup_channel_powertable(struct ath5k_hw *ah,
+                       struct ieee80211_channel *channel,
+                       u8 ee_mode, u8 type)
+{
+       struct ath5k_pdgain_info *pdg_L, *pdg_R;
+       struct ath5k_chan_pcal_info *pcinfo_L;
+       struct ath5k_chan_pcal_info *pcinfo_R;
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
+       s16 table_min[AR5K_EEPROM_N_PD_GAINS];
+       s16 table_max[AR5K_EEPROM_N_PD_GAINS];
+       u8 *tmpL;
+       u8 *tmpR;
+       u32 target = channel->center_freq;
+       int pdg, i;
+
+       /* Get surounding freq piers for this channel */
+       ath5k_get_chan_pcal_surrounding_piers(ah, channel,
+                                               &pcinfo_L,
+                                               &pcinfo_R);
+
+       /* Loop over pd gain curves on
+        * surounding freq piers by index */
+       for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
+
+               /* Fill curves in reverse order
+                * from lower power (max gain)
+                * to higher power. Use curve -> idx
+                * backmaping we did on eeprom init */
+               u8 idx = pdg_curve_to_idx[pdg];
+
+               /* Grab the needed curves by index */
+               pdg_L = &pcinfo_L->pd_curves[idx];
+               pdg_R = &pcinfo_R->pd_curves[idx];
+
+               /* Initialize the temp tables */
+               tmpL = ah->ah_txpower.tmpL[pdg];
+               tmpR = ah->ah_txpower.tmpR[pdg];
+
+               /* Set curve's x boundaries and create
+                * curves so that they cover the same
+                * range (if we don't do that one table
+                * will have values on some range and the
+                * other one won't have any so interpolation
+                * will fail) */
+               table_min[pdg] = min(pdg_L->pd_pwr[0],
+                                       pdg_R->pd_pwr[0]) / 2;
+
+               table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
+                               pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
+
+               /* Now create the curves on surrounding channels
+                * and interpolate if needed to get the final
+                * curve for this gain on this channel */
+               switch (type) {
+               case AR5K_PWRTABLE_LINEAR_PCDAC:
+                       /* Override min/max so that we don't loose
+                        * accuracy (don't divide by 2) */
+                       table_min[pdg] = min(pdg_L->pd_pwr[0],
+                                               pdg_R->pd_pwr[0]);
+
+                       table_max[pdg] =
+                               max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
+                                       pdg_R->pd_pwr[pdg_R->pd_points - 1]);
+
+                       /* Override minimum so that we don't get
+                        * out of bounds while extrapolating
+                        * below. Don't do this when we have 2
+                        * curves and we are on the high power curve
+                        * because table_min is ok in this case */
+                       if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
+
+                               table_min[pdg] =
+                                       ath5k_get_linear_pcdac_min(pdg_L->pd_step,
+                                                               pdg_R->pd_step,
+                                                               pdg_L->pd_pwr,
+                                                               pdg_R->pd_pwr);
+
+                               /* Don't go too low because we will
+                                * miss the upper part of the curve.
+                                * Note: 126 = 31.5dB (max power supported)
+                                * in 0.25dB units */
+                               if (table_max[pdg] - table_min[pdg] > 126)
+                                       table_min[pdg] = table_max[pdg] - 126;
+                       }
+
+                       /* Fall through */
+               case AR5K_PWRTABLE_PWR_TO_PCDAC:
+               case AR5K_PWRTABLE_PWR_TO_PDADC:
+
+                       ath5k_create_power_curve(table_min[pdg],
+                                               table_max[pdg],
+                                               pdg_L->pd_pwr,
+                                               pdg_L->pd_step,
+                                               pdg_L->pd_points, tmpL, type);
+
+                       /* We are in a calibration
+                        * pier, no need to interpolate
+                        * between freq piers */
+                       if (pcinfo_L == pcinfo_R)
+                               continue;
+
+                       ath5k_create_power_curve(table_min[pdg],
+                                               table_max[pdg],
+                                               pdg_R->pd_pwr,
+                                               pdg_R->pd_step,
+                                               pdg_R->pd_points, tmpR, type);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               /* Interpolate between curves
+                * of surounding freq piers to
+                * get the final curve for this
+                * pd gain. Re-use tmpL for interpolation
+                * output */
+               for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
+               (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
+                       tmpL[i] = (u8) ath5k_get_interpolated_value(target,
+                                                       (s16) pcinfo_L->freq,
+                                                       (s16) pcinfo_R->freq,
+                                                       (s16) tmpL[i],
+                                                       (s16) tmpR[i]);
+               }
+       }
+
+       /* Now we have a set of curves for this
+        * channel on tmpL (x range is table_max - table_min
+        * and y values are tmpL[pdg][]) sorted in the same
+        * order as EEPROM (because we've used the backmaping).
+        * So for RF5112 it's from higher power to lower power
+        * and for RF2413 it's from lower power to higher power.
+        * For RF5111 we only have one curve. */
+
+       /* Fill min and max power levels for this
+        * channel by interpolating the values on
+        * surounding channels to complete the dataset */
+       ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
+                                       (s16) pcinfo_L->freq,
+                                       (s16) pcinfo_R->freq,
+                                       pcinfo_L->min_pwr, pcinfo_R->min_pwr);
+
+       ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
+                                       (s16) pcinfo_L->freq,
+                                       (s16) pcinfo_R->freq,
+                                       pcinfo_L->max_pwr, pcinfo_R->max_pwr);
+
+       /* We are ready to go, fill PCDAC/PDADC
+        * table and write settings on hardware */
+       switch (type) {
+       case AR5K_PWRTABLE_LINEAR_PCDAC:
+               /* For RF5112 we can have one or two curves
+                * and each curve covers a certain power lvl
+                * range so we need to do some more processing */
+               ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
+                                               ee->ee_pd_gains[ee_mode]);
+
+               /* Set txp.offset so that we can
+                * match max power value with max
+                * table index */
+               ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
+
+               /* Write settings on hw */
+               ath5k_setup_pcdac_table(ah);
+               break;
+       case AR5K_PWRTABLE_PWR_TO_PCDAC:
+               /* We are done for RF5111 since it has only
+                * one curve, just fit the curve on the table */
+               ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
+
+               /* No rate powertable adjustment for RF5111 */
+               ah->ah_txpower.txp_min_idx = 0;
+               ah->ah_txpower.txp_offset = 0;
+
+               /* Write settings on hw */
+               ath5k_setup_pcdac_table(ah);
+               break;
+       case AR5K_PWRTABLE_PWR_TO_PDADC:
+               /* Set PDADC boundaries and fill
+                * final PDADC table */
+               ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
+                                               ee->ee_pd_gains[ee_mode]);
+
+               /* Write settings on hw */
+               ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
+
+               /* Set txp.offset, note that table_min
+                * can be negative */
+               ah->ah_txpower.txp_offset = table_min[0];
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+
+/*
+ * Per-rate tx power setting
+ *
+ * This is the code that sets the desired tx power (below
+ * maximum) on hw for each rate (we also have TPC that sets
+ * power per packet). We do that by providing an index on the
+ * PCDAC/PDADC table we set up.
+ */
+
+/*
+ * Set rate power table
+ *
+ * For now we only limit txpower based on maximum tx power
+ * supported by hw (what's inside rate_info). We need to limit
+ * this even more, based on regulatory domain etc.
+ *
+ * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps)
+ * and is indexed as follows:
+ * rates[0] - rates[7] -> OFDM rates
+ * rates[8] - rates[14] -> CCK rates
+ * rates[15] -> XR rates (they all have the same power)
+ */
+static void
+ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
+                       struct ath5k_rate_pcal_info *rate_info,
+                       u8 ee_mode)
+{
+       unsigned int i;
+       u16 *rates;
+
+       /* max_pwr is power level we got from driver/user in 0.5dB
+        * units, switch to 0.25dB units so we can compare */
+       max_pwr *= 2;
+       max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
+
+       /* apply rate limits */
+       rates = ah->ah_txpower.txp_rates_power_table;
+
+       /* OFDM rates 6 to 24Mb/s */
+       for (i = 0; i < 5; i++)
+               rates[i] = min(max_pwr, rate_info->target_power_6to24);
+
+       /* Rest OFDM rates */
+       rates[5] = min(rates[0], rate_info->target_power_36);
+       rates[6] = min(rates[0], rate_info->target_power_48);
+       rates[7] = min(rates[0], rate_info->target_power_54);
+
+       /* CCK rates */
+       /* 1L */
+       rates[8] = min(rates[0], rate_info->target_power_6to24);
+       /* 2L */
+       rates[9] = min(rates[0], rate_info->target_power_36);
+       /* 2S */
+       rates[10] = min(rates[0], rate_info->target_power_36);
+       /* 5L */
+       rates[11] = min(rates[0], rate_info->target_power_48);
+       /* 5S */
+       rates[12] = min(rates[0], rate_info->target_power_48);
+       /* 11L */
+       rates[13] = min(rates[0], rate_info->target_power_54);
+       /* 11S */
+       rates[14] = min(rates[0], rate_info->target_power_54);
+
+       /* XR rates */
+       rates[15] = min(rates[0], rate_info->target_power_6to24);
+
+       /* CCK rates have different peak to average ratio
+        * so we have to tweak their power so that gainf
+        * correction works ok. For this we use OFDM to
+        * CCK delta from eeprom */
+       if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
+       (ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
+               for (i = 8; i <= 15; i++)
+                       rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
+
+       ah->ah_txpower.txp_min_pwr = rates[7];
+       ah->ah_txpower.txp_max_pwr = rates[0];
+       ah->ah_txpower.txp_ofdm = rates[7];
+}
+
+
+/*
+ * Set transmition power
+ */
+int
+ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+               u8 ee_mode, u8 txpower)
+{
+       struct ath5k_rate_pcal_info rate_info;
+       u8 type;
+       int ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+       if (txpower > AR5K_TUNE_MAX_TXPOWER) {
+               ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
+               return -EINVAL;
+       }
+       if (txpower == 0)
+               txpower = AR5K_TUNE_DEFAULT_TXPOWER;
+
+       /* Reset TX power values */
+       memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
+       ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
+       ah->ah_txpower.txp_min_pwr = 0;
+       ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
+
+       /* Initialize TX power table */
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               type = AR5K_PWRTABLE_PWR_TO_PCDAC;
+               break;
+       case AR5K_RF5112:
+               type = AR5K_PWRTABLE_LINEAR_PCDAC;
+               break;
+       case AR5K_RF2413:
+       case AR5K_RF5413:
+       case AR5K_RF2316:
+       case AR5K_RF2317:
+       case AR5K_RF2425:
+               type = AR5K_PWRTABLE_PWR_TO_PDADC;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* FIXME: Only on channel/mode change */
+       ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
+       if (ret)
+               return ret;
+
+       /* Limit max power if we have a CTL available */
+       ath5k_get_max_ctl_power(ah, channel);
+
+       /* FIXME: Tx power limit for this regdomain
+        * XXX: Mac80211/CRDA will do that anyway ? */
+
+       /* FIXME: Antenna reduction stuff */
+
+       /* FIXME: Limit power on turbo modes */
+
+       /* FIXME: TPC scale reduction */
+
+       /* Get surounding channels for per-rate power table
+        * calibration */
+       ath5k_get_rate_pcal_data(ah, channel, &rate_info);
+
+       /* Setup rate power table */
+       ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
+
+       /* Write rate power table on hw */
+       ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
+               AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
+               AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
+
+       ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(7, 24) |
+               AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) |
+               AR5K_TXPOWER_OFDM(4, 0), AR5K_PHY_TXPOWER_RATE2);
+
+       ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(10, 24) |
+               AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) |
+               AR5K_TXPOWER_CCK(8, 0), AR5K_PHY_TXPOWER_RATE3);
+
+       ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(14, 24) |
+               AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
+               AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
+
+       /* FIXME: TPC support */
+       if (ah->ah_txpower.txp_tpc) {
+               ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
+                       AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
+
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
+                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
+                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
+                       AR5K_TPC);
+       } else {
+               ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
+                       AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
+       }
+
+       return 0;
+}
+
+int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower)
+{
+       /*Just a try M.F.*/
+       struct ieee80211_channel *channel = &ah->ah_current_channel;
+
+       ATH5K_TRACE(ah->ah_sc);
+       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
+               "changing txpower to %d\n", txpower);
+
+       return ath5k_hw_txpower(ah, channel, mode, txpower);
+}
+
+#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
new file mode 100644 (file)
index 0000000..5094c39
--- /dev/null
@@ -0,0 +1,546 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/********************************************\
+Queue Control Unit, DFS Control Unit Functions
+\********************************************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Get properties for a transmit queue
+ */
+int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
+               struct ath5k_txq_info *queue_info)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
+       return 0;
+}
+
+/*
+ * Set properties for a transmit queue
+ */
+int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
+                               const struct ath5k_txq_info *queue_info)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return -EIO;
+
+       memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
+
+       /*XXX: Is this supported on 5210 ?*/
+       if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
+                       ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
+                       (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
+                       queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
+               ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
+
+       return 0;
+}
+
+/*
+ * Initialize a transmit queue
+ */
+int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
+               struct ath5k_txq_info *queue_info)
+{
+       unsigned int queue;
+       int ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*
+        * Get queue by type
+        */
+       /*5210 only has 2 queues*/
+       if (ah->ah_version == AR5K_AR5210) {
+               switch (queue_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+               case AR5K_TX_QUEUE_CAB:
+                       queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       } else {
+               switch (queue_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
+                               ah->ah_txq[queue].tqi_type !=
+                               AR5K_TX_QUEUE_INACTIVE; queue++) {
+
+                               if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
+                                       return -EINVAL;
+                       }
+                       break;
+               case AR5K_TX_QUEUE_UAPSD:
+                       queue = AR5K_TX_QUEUE_ID_UAPSD;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+                       queue = AR5K_TX_QUEUE_ID_BEACON;
+                       break;
+               case AR5K_TX_QUEUE_CAB:
+                       queue = AR5K_TX_QUEUE_ID_CAB;
+                       break;
+               case AR5K_TX_QUEUE_XR_DATA:
+                       if (ah->ah_version != AR5K_AR5212)
+                               ATH5K_ERR(ah->ah_sc,
+                                       "XR data queues only supported in"
+                                       " 5212!\n");
+                       queue = AR5K_TX_QUEUE_ID_XR_DATA;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       /*
+        * Setup internal queue structure
+        */
+       memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
+       ah->ah_txq[queue].tqi_type = queue_type;
+
+       if (queue_info != NULL) {
+               queue_info->tqi_type = queue_type;
+               ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
+               if (ret)
+                       return ret;
+       }
+
+       /*
+        * We use ah_txq_status to hold a temp value for
+        * the Secondary interrupt mask registers on 5211+
+        * check out ath5k_hw_reset_tx_queue
+        */
+       AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
+
+       return queue;
+}
+
+/*
+ * Get number of pending frames
+ * for a specific queue [5211+]
+ */
+u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
+{
+       u32 pending;
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /* Return if queue is declared inactive */
+       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return false;
+
+       /* XXX: How about AR5K_CFG_TXCNT ? */
+       if (ah->ah_version == AR5K_AR5210)
+               return false;
+
+       pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT);
+
+       /* It's possible to have no frames pending even if TXE
+        * is set. To indicate that q has not stopped return
+        * true */
+       if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+               return true;
+
+       return pending;
+}
+
+/*
+ * Set a transmit queue inactive
+ */
+void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
+               return;
+
+       /* This queue will be skipped in further operations */
+       ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
+       /*For SIMR setup*/
+       AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
+}
+
+/*
+ * Set DFS properties for a transmit queue on DCU
+ */
+int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+       u32 cw_min, cw_max, retry_lg, retry_sh;
+       struct ath5k_txq_info *tq = &ah->ah_txq[queue];
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       tq = &ah->ah_txq[queue];
+
+       if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return 0;
+
+       if (ah->ah_version == AR5K_AR5210) {
+               /* Only handle data queues, others will be ignored */
+               if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
+                       return 0;
+
+               /* Set Slot time */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
+                       AR5K_SLOT_TIME);
+               /* Set ACK_CTS timeout */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
+                       AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
+               /* Set Transmit Latency */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       AR5K_INIT_TRANSMIT_LATENCY_TURBO :
+                       AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
+
+               /* Set IFS0 */
+               if (ah->ah_turbo) {
+                        ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
+                               (ah->ah_aifs + tq->tqi_aifs) *
+                               AR5K_INIT_SLOT_TIME_TURBO) <<
+                               AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
+                               AR5K_IFS0);
+               } else {
+                       ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
+                               (ah->ah_aifs + tq->tqi_aifs) *
+                               AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
+                               AR5K_INIT_SIFS, AR5K_IFS0);
+               }
+
+               /* Set IFS1 */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
+                       AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
+               /* Set AR5K_PHY_SETTLING */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
+                       | 0x38 :
+                       (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
+                       | 0x1C,
+                       AR5K_PHY_SETTLING);
+               /* Set Frame Control Register */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
+                       AR5K_PHY_TURBO_SHORT | 0x2020) :
+                       (AR5K_PHY_FRAME_CTL_INI | 0x1020),
+                       AR5K_PHY_FRAME_CTL_5210);
+       }
+
+       /*
+        * Calculate cwmin/max by channel mode
+        */
+       cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
+       cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
+       ah->ah_aifs = AR5K_TUNE_AIFS;
+       /*XR is only supported on 5212*/
+       if (IS_CHAN_XR(ah->ah_current_channel) &&
+                       ah->ah_version == AR5K_AR5212) {
+               cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
+               cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
+               ah->ah_aifs = AR5K_TUNE_AIFS_XR;
+       /*B mode is not supported on 5210*/
+       } else if (IS_CHAN_B(ah->ah_current_channel) &&
+                       ah->ah_version != AR5K_AR5210) {
+               cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
+               cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
+               ah->ah_aifs = AR5K_TUNE_AIFS_11B;
+       }
+
+       cw_min = 1;
+       while (cw_min < ah->ah_cw_min)
+               cw_min = (cw_min << 1) | 1;
+
+       cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
+               ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
+       cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
+               ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
+
+       /*
+        * Calculate and set retry limits
+        */
+       if (ah->ah_software_retry) {
+               /* XXX Need to test this */
+               retry_lg = ah->ah_limit_tx_retries;
+               retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
+                       AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
+       } else {
+               retry_lg = AR5K_INIT_LG_RETRY;
+               retry_sh = AR5K_INIT_SH_RETRY;
+       }
+
+       /*No QCU/DCU [5210]*/
+       if (ah->ah_version == AR5K_AR5210) {
+               ath5k_hw_reg_write(ah,
+                       (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
+                       | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
+                               AR5K_NODCU_RETRY_LMT_SLG_RETRY)
+                       | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
+                               AR5K_NODCU_RETRY_LMT_SSH_RETRY)
+                       | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
+                       | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
+                       AR5K_NODCU_RETRY_LMT);
+       } else {
+               /*QCU/DCU [5211+]*/
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
+                               AR5K_DCU_RETRY_LMT_SLG_RETRY) |
+                       AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
+                               AR5K_DCU_RETRY_LMT_SSH_RETRY) |
+                       AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
+                       AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
+                       AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
+
+       /*===Rest is also for QCU/DCU only [5211+]===*/
+
+               /*
+                * Set initial content window (cw_min/cw_max)
+                * and arbitrated interframe space (aifs)...
+                */
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
+                       AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
+                       AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
+                               AR5K_DCU_LCL_IFS_AIFS),
+                       AR5K_QUEUE_DFS_LOCAL_IFS(queue));
+
+               /*
+                * Set misc registers
+                */
+               /* Enable DCU early termination for this queue */
+               AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                                       AR5K_QCU_MISC_DCU_EARLY);
+
+               /* Enable DCU to wait for next fragment from QCU */
+               AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+                                       AR5K_DCU_MISC_FRAG_WAIT);
+
+               /* On Maui and Spirit use the global seqnum on DCU */
+               if (ah->ah_mac_version < AR5K_SREV_AR5211)
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+                                               AR5K_DCU_MISC_SEQNUM_CTL);
+
+               if (tq->tqi_cbr_period) {
+                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
+                               AR5K_QCU_CBRCFG_INTVAL) |
+                               AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
+                               AR5K_QCU_CBRCFG_ORN_THRES),
+                               AR5K_QUEUE_CBRCFG(queue));
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                               AR5K_QCU_MISC_FRSHED_CBR);
+                       if (tq->tqi_cbr_overflow_limit)
+                               AR5K_REG_ENABLE_BITS(ah,
+                                       AR5K_QUEUE_MISC(queue),
+                                       AR5K_QCU_MISC_CBR_THRES_ENABLE);
+               }
+
+               if (tq->tqi_ready_time &&
+               (tq->tqi_type != AR5K_TX_QUEUE_ID_CAB))
+                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
+                               AR5K_QCU_RDYTIMECFG_INTVAL) |
+                               AR5K_QCU_RDYTIMECFG_ENABLE,
+                               AR5K_QUEUE_RDYTIMECFG(queue));
+
+               if (tq->tqi_burst_time) {
+                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
+                               AR5K_DCU_CHAN_TIME_DUR) |
+                               AR5K_DCU_CHAN_TIME_ENABLE,
+                               AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
+
+                       if (tq->tqi_flags
+                       & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
+                               AR5K_REG_ENABLE_BITS(ah,
+                                       AR5K_QUEUE_MISC(queue),
+                                       AR5K_QCU_MISC_RDY_VEOL_POLICY);
+               }
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
+                       ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
+                               AR5K_QUEUE_DFS_MISC(queue));
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
+                       ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
+                               AR5K_QUEUE_DFS_MISC(queue));
+
+               /*
+                * Set registers by queue type
+                */
+               switch (tq->tqi_type) {
+               case AR5K_TX_QUEUE_BEACON:
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                               AR5K_QCU_MISC_FRSHED_DBA_GT |
+                               AR5K_QCU_MISC_CBREXP_BCN_DIS |
+                               AR5K_QCU_MISC_BCN_ENABLE);
+
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+                               (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
+                               AR5K_DCU_MISC_ARBLOCK_CTL_S) |
+                               AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
+                               AR5K_DCU_MISC_BCN_ENABLE);
+                       break;
+
+               case AR5K_TX_QUEUE_CAB:
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                               AR5K_QCU_MISC_FRSHED_DBA_GT |
+                               AR5K_QCU_MISC_CBREXP_DIS |
+                               AR5K_QCU_MISC_CBREXP_BCN_DIS);
+
+                       ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
+                               (AR5K_TUNE_SW_BEACON_RESP -
+                               AR5K_TUNE_DMA_BEACON_RESP) -
+                               AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
+                               AR5K_QCU_RDYTIMECFG_ENABLE,
+                               AR5K_QUEUE_RDYTIMECFG(queue));
+
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+                               (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
+                               AR5K_DCU_MISC_ARBLOCK_CTL_S));
+                       break;
+
+               case AR5K_TX_QUEUE_UAPSD:
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                               AR5K_QCU_MISC_CBREXP_DIS);
+                       break;
+
+               case AR5K_TX_QUEUE_DATA:
+               default:
+                       break;
+               }
+
+               /* TODO: Handle frame compression */
+
+               /*
+                * Enable interrupts for this tx queue
+                * in the secondary interrupt mask registers
+                */
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
+
+               /* Update secondary interrupt mask registers */
+
+               /* Filter out inactive queues */
+               ah->ah_txq_imr_txok &= ah->ah_txq_status;
+               ah->ah_txq_imr_txerr &= ah->ah_txq_status;
+               ah->ah_txq_imr_txurn &= ah->ah_txq_status;
+               ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
+               ah->ah_txq_imr_txeol &= ah->ah_txq_status;
+               ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
+               ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
+               ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
+               ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
+
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
+                       AR5K_SIMR0_QCU_TXOK) |
+                       AR5K_REG_SM(ah->ah_txq_imr_txdesc,
+                       AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
+                       AR5K_SIMR1_QCU_TXERR) |
+                       AR5K_REG_SM(ah->ah_txq_imr_txeol,
+                       AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
+               /* Update simr2 but don't overwrite rest simr2 settings */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
+               AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
+                       AR5K_REG_SM(ah->ah_txq_imr_txurn,
+                       AR5K_SIMR2_QCU_TXURN));
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
+                       AR5K_SIMR3_QCBRORN) |
+                       AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
+                       AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
+                       AR5K_SIMR4_QTRIG), AR5K_SIMR4);
+               /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
+                       AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
+               /* No queue has TXNOFRM enabled, disable the interrupt
+                * by setting AR5K_TXNOFRM to zero */
+               if (ah->ah_txq_imr_nofrm == 0)
+                       ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
+
+               /* Set QCU mask for this DCU to save power */
+               AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
+       }
+
+       return 0;
+}
+
+/*
+ * Get slot time from DCU
+ */
+unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (ah->ah_version == AR5K_AR5210)
+               return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
+                               AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
+       else
+               return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
+}
+
+/*
+ * Set slot time on DCU
+ */
+int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
+               return -EINVAL;
+
+       if (ah->ah_version == AR5K_AR5210)
+               ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
+                               ah->ah_turbo), AR5K_SLOT_TIME);
+       else
+               ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
+
+       return 0;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
new file mode 100644 (file)
index 0000000..7070d15
--- /dev/null
@@ -0,0 +1,2589 @@
+/*
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*
+ * Register values for Atheros 5210/5211/5212 cards from OpenBSD's ar5k
+ * maintained by Reyk Floeter
+ *
+ * I tried to document those registers by looking at ar5k code, some
+ * 802.11 (802.11e mostly) papers and by reading various public available
+ * Atheros presentations and papers like these:
+ *
+ * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf
+ *        http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf
+ *
+ * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf
+ *
+ * This file also contains register values found on a memory dump of
+ * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal
+ * released by Atheros and on various debug messages found on the net.
+ */
+
+
+
+/*====MAC DMA REGISTERS====*/
+
+/*
+ * AR5210-Specific TXDP registers
+ * 5210 has only 2 transmit queues so no DCU/QCU, just
+ * 2 transmit descriptor pointers...
+ */
+#define AR5K_NOQCU_TXDP0       0x0000          /* Queue 0 - data */
+#define AR5K_NOQCU_TXDP1       0x0004          /* Queue 1 - beacons */
+
+/*
+ * Mac Control Register
+ */
+#define        AR5K_CR         0x0008                  /* Register Address */
+#define AR5K_CR_TXE0   0x00000001      /* TX Enable for queue 0 on 5210 */
+#define AR5K_CR_TXE1   0x00000002      /* TX Enable for queue 1 on 5210 */
+#define        AR5K_CR_RXE     0x00000004      /* RX Enable */
+#define AR5K_CR_TXD0   0x00000008      /* TX Disable for queue 0 on 5210 */
+#define AR5K_CR_TXD1   0x00000010      /* TX Disable for queue 1 on 5210 */
+#define        AR5K_CR_RXD     0x00000020      /* RX Disable */
+#define        AR5K_CR_SWI     0x00000040      /* Software Interrupt */
+
+/*
+ * RX Descriptor Pointer register
+ */
+#define        AR5K_RXDP       0x000c
+
+/*
+ * Configuration and status register
+ */
+#define        AR5K_CFG                0x0014                  /* Register Address */
+#define        AR5K_CFG_SWTD           0x00000001      /* Byte-swap TX descriptor (for big endian archs) */
+#define        AR5K_CFG_SWTB           0x00000002      /* Byte-swap TX buffer */
+#define        AR5K_CFG_SWRD           0x00000004      /* Byte-swap RX descriptor */
+#define        AR5K_CFG_SWRB           0x00000008      /* Byte-swap RX buffer */
+#define        AR5K_CFG_SWRG           0x00000010      /* Byte-swap Register access */
+#define AR5K_CFG_IBSS          0x00000020      /* 0-BSS, 1-IBSS [5211+] */
+#define AR5K_CFG_PHY_OK                0x00000100      /* [5211+] */
+#define AR5K_CFG_EEBS          0x00000200      /* EEPROM is busy */
+#define        AR5K_CFG_CLKGD          0x00000400      /* Clock gated (Disable dynamic clock) */
+#define AR5K_CFG_TXCNT         0x00007800      /* Tx frame count (?) [5210] */
+#define AR5K_CFG_TXCNT_S       11
+#define AR5K_CFG_TXFSTAT       0x00008000      /* Tx frame status (?) [5210] */
+#define AR5K_CFG_TXFSTRT       0x00010000      /* [5210] */
+#define        AR5K_CFG_PCI_THRES      0x00060000      /* PCI Master req q threshold [5211+] */
+#define        AR5K_CFG_PCI_THRES_S    17
+
+/*
+ * Interrupt enable register
+ */
+#define AR5K_IER               0x0024          /* Register Address */
+#define AR5K_IER_DISABLE       0x00000000      /* Disable card interrupts */
+#define AR5K_IER_ENABLE                0x00000001      /* Enable card interrupts */
+
+
+/*
+ * 0x0028 is Beacon Control Register on 5210
+ * and first RTS duration register on 5211
+ */
+
+/*
+ * Beacon control register [5210]
+ */
+#define AR5K_BCR               0x0028          /* Register Address */
+#define AR5K_BCR_AP            0x00000000      /* AP mode */
+#define AR5K_BCR_ADHOC         0x00000001      /* Ad-Hoc mode */
+#define AR5K_BCR_BDMAE         0x00000002      /* DMA enable */
+#define AR5K_BCR_TQ1FV         0x00000004      /* Use Queue1 for CAB traffic */
+#define AR5K_BCR_TQ1V          0x00000008      /* Use Queue1 for Beacon traffic */
+#define AR5K_BCR_BCGET         0x00000010
+
+/*
+ * First RTS duration register [5211]
+ */
+#define AR5K_RTSD0             0x0028          /* Register Address */
+#define        AR5K_RTSD0_6            0x000000ff      /* 6Mb RTS duration mask (?) */
+#define        AR5K_RTSD0_6_S          0               /* 6Mb RTS duration shift (?) */
+#define        AR5K_RTSD0_9            0x0000ff00      /* 9Mb*/
+#define        AR5K_RTSD0_9_S          8
+#define        AR5K_RTSD0_12           0x00ff0000      /* 12Mb*/
+#define        AR5K_RTSD0_12_S         16
+#define        AR5K_RTSD0_18           0xff000000      /* 16Mb*/
+#define        AR5K_RTSD0_18_S         24
+
+
+/*
+ * 0x002c is Beacon Status Register on 5210
+ * and second RTS duration register on 5211
+ */
+
+/*
+ * Beacon status register [5210]
+ *
+ * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR
+ * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning
+ * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR).
+ * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i
+ * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what
+ * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR.
+ */
+#define AR5K_BSR               0x002c                  /* Register Address */
+#define AR5K_BSR_BDLYSW                0x00000001      /* SW Beacon delay (?) */
+#define AR5K_BSR_BDLYDMA       0x00000002      /* DMA Beacon delay (?) */
+#define AR5K_BSR_TXQ1F         0x00000004      /* Beacon queue (1) finished */
+#define AR5K_BSR_ATIMDLY       0x00000008      /* ATIM delay (?) */
+#define AR5K_BSR_SNPADHOC      0x00000100      /* Ad-hoc mode set (?) */
+#define AR5K_BSR_SNPBDMAE      0x00000200      /* Beacon DMA enabled (?) */
+#define AR5K_BSR_SNPTQ1FV      0x00000400      /* Queue1 is used for CAB traffic (?) */
+#define AR5K_BSR_SNPTQ1V       0x00000800      /* Queue1 is used for Beacon traffic (?) */
+#define AR5K_BSR_SNAPSHOTSVALID        0x00001000      /* BCR snapshots are valid (?) */
+#define AR5K_BSR_SWBA_CNT      0x00ff0000
+
+/*
+ * Second RTS duration register [5211]
+ */
+#define AR5K_RTSD1             0x002c                  /* Register Address */
+#define        AR5K_RTSD1_24           0x000000ff      /* 24Mb */
+#define        AR5K_RTSD1_24_S         0
+#define        AR5K_RTSD1_36           0x0000ff00      /* 36Mb */
+#define        AR5K_RTSD1_36_S         8
+#define        AR5K_RTSD1_48           0x00ff0000      /* 48Mb */
+#define        AR5K_RTSD1_48_S         16
+#define        AR5K_RTSD1_54           0xff000000      /* 54Mb */
+#define        AR5K_RTSD1_54_S         24
+
+
+/*
+ * Transmit configuration register
+ */
+#define AR5K_TXCFG                     0x0030                  /* Register Address */
+#define AR5K_TXCFG_SDMAMR              0x00000007      /* DMA size (read) */
+#define AR5K_TXCFG_SDMAMR_S            0
+#define AR5K_TXCFG_B_MODE              0x00000008      /* Set b mode for 5111 (enable 2111) */
+#define AR5K_TXCFG_TXFSTP              0x00000008      /* TX DMA full Stop [5210] */
+#define AR5K_TXCFG_TXFULL              0x000003f0      /* TX Triger level mask */
+#define AR5K_TXCFG_TXFULL_S            4
+#define AR5K_TXCFG_TXFULL_0B           0x00000000
+#define AR5K_TXCFG_TXFULL_64B          0x00000010
+#define AR5K_TXCFG_TXFULL_128B         0x00000020
+#define AR5K_TXCFG_TXFULL_192B         0x00000030
+#define AR5K_TXCFG_TXFULL_256B         0x00000040
+#define AR5K_TXCFG_TXCONT_EN           0x00000080
+#define AR5K_TXCFG_DMASIZE             0x00000100      /* Flag for passing DMA size [5210] */
+#define AR5K_TXCFG_JUMBO_DESC_EN       0x00000400      /* Enable jumbo tx descriptors [5211+] */
+#define AR5K_TXCFG_ADHOC_BCN_ATIM      0x00000800      /* Adhoc Beacon ATIM Policy */
+#define AR5K_TXCFG_ATIM_WINDOW_DEF_DIS 0x00001000      /* Disable ATIM window defer [5211+] */
+#define AR5K_TXCFG_RTSRND              0x00001000      /* [5211+] */
+#define AR5K_TXCFG_FRMPAD_DIS          0x00002000      /* [5211+] */
+#define AR5K_TXCFG_RDY_CBR_DIS         0x00004000      /* Ready time CBR disable [5211+] */
+#define AR5K_TXCFG_JUMBO_FRM_MODE      0x00008000      /* Jumbo frame mode [5211+] */
+#define        AR5K_TXCFG_DCU_DBL_BUF_DIS      0x00008000      /* Disable double buffering on DCU */
+#define AR5K_TXCFG_DCU_CACHING_DIS     0x00010000      /* Disable DCU caching */
+
+/*
+ * Receive configuration register
+ */
+#define AR5K_RXCFG             0x0034                  /* Register Address */
+#define AR5K_RXCFG_SDMAMW      0x00000007      /* DMA size (write) */
+#define AR5K_RXCFG_SDMAMW_S    0
+#define AR5K_RXCFG_ZLFDMA      0x00000008      /* Enable Zero-length frame DMA */
+#define        AR5K_RXCFG_DEF_ANTENNA  0x00000010      /* Default antenna (?) */
+#define AR5K_RXCFG_JUMBO_RXE   0x00000020      /* Enable jumbo rx descriptors [5211+] */
+#define AR5K_RXCFG_JUMBO_WRAP  0x00000040      /* Wrap jumbo frames [5211+] */
+#define AR5K_RXCFG_SLE_ENTRY   0x00000080      /* Sleep entry policy */
+
+/*
+ * Receive jumbo descriptor last address register
+ * Only found in 5211 (?)
+ */
+#define AR5K_RXJLA             0x0038
+
+/*
+ * MIB control register
+ */
+#define AR5K_MIBC              0x0040                  /* Register Address */
+#define AR5K_MIBC_COW          0x00000001      /* Warn test indicator */
+#define AR5K_MIBC_FMC          0x00000002      /* Freeze MIB Counters  */
+#define AR5K_MIBC_CMC          0x00000004      /* Clean MIB Counters  */
+#define AR5K_MIBC_MCS          0x00000008      /* MIB counter strobe */
+
+/*
+ * Timeout prescale register
+ */
+#define AR5K_TOPS              0x0044
+#define        AR5K_TOPS_M             0x0000ffff
+
+/*
+ * Receive timeout register (no frame received)
+ */
+#define AR5K_RXNOFRM           0x0048
+#define        AR5K_RXNOFRM_M          0x000003ff
+
+/*
+ * Transmit timeout register (no frame sent)
+ */
+#define AR5K_TXNOFRM           0x004c
+#define        AR5K_TXNOFRM_M          0x000003ff
+#define        AR5K_TXNOFRM_QCU        0x000ffc00
+#define        AR5K_TXNOFRM_QCU_S      10
+
+/*
+ * Receive frame gap timeout register
+ */
+#define AR5K_RPGTO             0x0050
+#define AR5K_RPGTO_M           0x000003ff
+
+/*
+ * Receive frame count limit register
+ */
+#define AR5K_RFCNT             0x0054
+#define AR5K_RFCNT_M           0x0000001f      /* [5211+] (?) */
+#define AR5K_RFCNT_RFCL                0x0000000f      /* [5210] */
+
+/*
+ * Misc settings register
+ * (reserved0-3)
+ */
+#define AR5K_MISC              0x0058                  /* Register Address */
+#define        AR5K_MISC_DMA_OBS_M     0x000001e0
+#define        AR5K_MISC_DMA_OBS_S     5
+#define        AR5K_MISC_MISC_OBS_M    0x00000e00
+#define        AR5K_MISC_MISC_OBS_S    9
+#define        AR5K_MISC_MAC_OBS_LSB_M 0x00007000
+#define        AR5K_MISC_MAC_OBS_LSB_S 12
+#define        AR5K_MISC_MAC_OBS_MSB_M 0x00038000
+#define        AR5K_MISC_MAC_OBS_MSB_S 15
+#define AR5K_MISC_LED_DECAY    0x001c0000      /* [5210] */
+#define AR5K_MISC_LED_BLINK    0x00e00000      /* [5210] */
+
+/*
+ * QCU/DCU clock gating register (5311)
+ * (reserved4-5)
+ */
+#define        AR5K_QCUDCU_CLKGT       0x005c                  /* Register Address (?) */
+#define        AR5K_QCUDCU_CLKGT_QCU   0x0000ffff      /* Mask for QCU clock */
+#define        AR5K_QCUDCU_CLKGT_DCU   0x07ff0000      /* Mask for DCU clock */
+
+/*
+ * Interrupt Status Registers
+ *
+ * For 5210 there is only one status register but for
+ * 5211/5212 we have one primary and 4 secondary registers.
+ * So we have AR5K_ISR for 5210 and AR5K_PISR /SISRx for 5211/5212.
+ * Most of these bits are common for all chipsets.
+ */
+#define AR5K_ISR               0x001c                  /* Register Address [5210] */
+#define AR5K_PISR              0x0080                  /* Register Address [5211+] */
+#define AR5K_ISR_RXOK          0x00000001      /* Frame successfuly recieved */
+#define AR5K_ISR_RXDESC                0x00000002      /* RX descriptor request */
+#define AR5K_ISR_RXERR         0x00000004      /* Receive error */
+#define AR5K_ISR_RXNOFRM       0x00000008      /* No frame received (receive timeout) */
+#define AR5K_ISR_RXEOL         0x00000010      /* Empty RX descriptor */
+#define AR5K_ISR_RXORN         0x00000020      /* Receive FIFO overrun */
+#define AR5K_ISR_TXOK          0x00000040      /* Frame successfuly transmited */
+#define AR5K_ISR_TXDESC                0x00000080      /* TX descriptor request */
+#define AR5K_ISR_TXERR         0x00000100      /* Transmit error */
+#define AR5K_ISR_TXNOFRM       0x00000200      /* No frame transmited (transmit timeout) */
+#define AR5K_ISR_TXEOL         0x00000400      /* Empty TX descriptor */
+#define AR5K_ISR_TXURN         0x00000800      /* Transmit FIFO underrun */
+#define AR5K_ISR_MIB           0x00001000      /* Update MIB counters */
+#define AR5K_ISR_SWI           0x00002000      /* Software interrupt */
+#define AR5K_ISR_RXPHY         0x00004000      /* PHY error */
+#define AR5K_ISR_RXKCM         0x00008000      /* RX Key cache miss */
+#define AR5K_ISR_SWBA          0x00010000      /* Software beacon alert */
+#define AR5K_ISR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
+#define AR5K_ISR_BMISS         0x00040000      /* Beacon missed */
+#define AR5K_ISR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
+#define AR5K_ISR_BNR           0x00100000      /* Beacon not ready [5211+] */
+#define AR5K_ISR_MCABT         0x00100000      /* Master Cycle Abort [5210] */
+#define AR5K_ISR_RXCHIRP       0x00200000      /* CHIRP Received [5212+] */
+#define AR5K_ISR_SSERR         0x00200000      /* Signaled System Error [5210] */
+#define AR5K_ISR_DPERR         0x00400000      /* Det par Error (?) [5210] */
+#define AR5K_ISR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
+#define AR5K_ISR_TIM           0x00800000      /* [5211+] */
+#define AR5K_ISR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
+                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
+#define AR5K_ISR_GPIO          0x01000000      /* GPIO (rf kill) */
+#define AR5K_ISR_QCBRORN       0x02000000      /* QCU CBR overrun [5211+] */
+#define AR5K_ISR_QCBRURN       0x04000000      /* QCU CBR underrun [5211+] */
+#define AR5K_ISR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
+
+/*
+ * Secondary status registers [5211+] (0 - 4)
+ *
+ * These give the status for each QCU, only QCUs 0-9 are
+ * represented.
+ */
+#define AR5K_SISR0             0x0084                  /* Register Address [5211+] */
+#define AR5K_SISR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
+#define AR5K_SISR0_QCU_TXOK_S  0
+#define AR5K_SISR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
+#define AR5K_SISR0_QCU_TXDESC_S        16
+
+#define AR5K_SISR1             0x0088                  /* Register Address [5211+] */
+#define AR5K_SISR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
+#define AR5K_SISR1_QCU_TXERR_S 0
+#define AR5K_SISR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
+#define AR5K_SISR1_QCU_TXEOL_S 16
+
+#define AR5K_SISR2             0x008c                  /* Register Address [5211+] */
+#define AR5K_SISR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
+#define        AR5K_SISR2_QCU_TXURN_S  0
+#define        AR5K_SISR2_MCABT        0x00100000      /* Master Cycle Abort */
+#define        AR5K_SISR2_SSERR        0x00200000      /* Signaled System Error */
+#define        AR5K_SISR2_DPERR        0x00400000      /* Bus parity error */
+#define        AR5K_SISR2_TIM          0x01000000      /* [5212+] */
+#define        AR5K_SISR2_CAB_END      0x02000000      /* [5212+] */
+#define        AR5K_SISR2_DTIM_SYNC    0x04000000      /* DTIM sync lost [5212+] */
+#define        AR5K_SISR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
+#define        AR5K_SISR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
+#define        AR5K_SISR2_DTIM         0x20000000      /* [5212+] */
+#define        AR5K_SISR2_TSFOOR       0x80000000      /* TSF OOR (?) */
+
+#define AR5K_SISR3             0x0090                  /* Register Address [5211+] */
+#define AR5K_SISR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
+#define AR5K_SISR3_QCBRORN_S   0
+#define AR5K_SISR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
+#define AR5K_SISR3_QCBRURN_S   16
+
+#define AR5K_SISR4             0x0094                  /* Register Address [5211+] */
+#define AR5K_SISR4_QTRIG       0x000003ff      /* Mask for QTRIG */
+#define AR5K_SISR4_QTRIG_S     0
+
+/*
+ * Shadow read-and-clear interrupt status registers [5211+]
+ */
+#define AR5K_RAC_PISR          0x00c0          /* Read and clear PISR */
+#define AR5K_RAC_SISR0         0x00c4          /* Read and clear SISR0 */
+#define AR5K_RAC_SISR1         0x00c8          /* Read and clear SISR1 */
+#define AR5K_RAC_SISR2         0x00cc          /* Read and clear SISR2 */
+#define AR5K_RAC_SISR3         0x00d0          /* Read and clear SISR3 */
+#define AR5K_RAC_SISR4         0x00d4          /* Read and clear SISR4 */
+
+/*
+ * Interrupt Mask Registers
+ *
+ * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary
+ * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match.
+ */
+#define        AR5K_IMR                0x0020                  /* Register Address [5210] */
+#define AR5K_PIMR              0x00a0                  /* Register Address [5211+] */
+#define AR5K_IMR_RXOK          0x00000001      /* Frame successfuly recieved*/
+#define AR5K_IMR_RXDESC                0x00000002      /* RX descriptor request*/
+#define AR5K_IMR_RXERR         0x00000004      /* Receive error*/
+#define AR5K_IMR_RXNOFRM       0x00000008      /* No frame received (receive timeout)*/
+#define AR5K_IMR_RXEOL         0x00000010      /* Empty RX descriptor*/
+#define AR5K_IMR_RXORN         0x00000020      /* Receive FIFO overrun*/
+#define AR5K_IMR_TXOK          0x00000040      /* Frame successfuly transmited*/
+#define AR5K_IMR_TXDESC                0x00000080      /* TX descriptor request*/
+#define AR5K_IMR_TXERR         0x00000100      /* Transmit error*/
+#define AR5K_IMR_TXNOFRM       0x00000200      /* No frame transmited (transmit timeout)*/
+#define AR5K_IMR_TXEOL         0x00000400      /* Empty TX descriptor*/
+#define AR5K_IMR_TXURN         0x00000800      /* Transmit FIFO underrun*/
+#define AR5K_IMR_MIB           0x00001000      /* Update MIB counters*/
+#define AR5K_IMR_SWI           0x00002000      /* Software interrupt */
+#define AR5K_IMR_RXPHY         0x00004000      /* PHY error*/
+#define AR5K_IMR_RXKCM         0x00008000      /* RX Key cache miss */
+#define AR5K_IMR_SWBA          0x00010000      /* Software beacon alert*/
+#define AR5K_IMR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
+#define AR5K_IMR_BMISS         0x00040000      /* Beacon missed*/
+#define AR5K_IMR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
+#define AR5K_IMR_BNR           0x00100000      /* Beacon not ready [5211+] */
+#define AR5K_IMR_MCABT         0x00100000      /* Master Cycle Abort [5210] */
+#define AR5K_IMR_RXCHIRP       0x00200000      /* CHIRP Received [5212+]*/
+#define AR5K_IMR_SSERR         0x00200000      /* Signaled System Error [5210] */
+#define AR5K_IMR_DPERR         0x00400000      /* Det par Error (?) [5210] */
+#define AR5K_IMR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
+#define AR5K_IMR_TIM           0x00800000      /* [5211+] */
+#define AR5K_IMR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
+                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
+#define AR5K_IMR_GPIO          0x01000000      /* GPIO (rf kill)*/
+#define AR5K_IMR_QCBRORN       0x02000000      /* QCU CBR overrun (?) [5211+] */
+#define AR5K_IMR_QCBRURN       0x04000000      /* QCU CBR underrun (?) [5211+] */
+#define AR5K_IMR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
+
+/*
+ * Secondary interrupt mask registers [5211+] (0 - 4)
+ */
+#define AR5K_SIMR0             0x00a4                  /* Register Address [5211+] */
+#define AR5K_SIMR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
+#define AR5K_SIMR0_QCU_TXOK_S  0
+#define AR5K_SIMR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
+#define AR5K_SIMR0_QCU_TXDESC_S        16
+
+#define AR5K_SIMR1             0x00a8                  /* Register Address [5211+] */
+#define AR5K_SIMR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
+#define AR5K_SIMR1_QCU_TXERR_S 0
+#define AR5K_SIMR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
+#define AR5K_SIMR1_QCU_TXEOL_S 16
+
+#define AR5K_SIMR2             0x00ac                  /* Register Address [5211+] */
+#define AR5K_SIMR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
+#define AR5K_SIMR2_QCU_TXURN_S 0
+#define        AR5K_SIMR2_MCABT        0x00100000      /* Master Cycle Abort */
+#define        AR5K_SIMR2_SSERR        0x00200000      /* Signaled System Error */
+#define        AR5K_SIMR2_DPERR        0x00400000      /* Bus parity error */
+#define        AR5K_SIMR2_TIM          0x01000000      /* [5212+] */
+#define        AR5K_SIMR2_CAB_END      0x02000000      /* [5212+] */
+#define        AR5K_SIMR2_DTIM_SYNC    0x04000000      /* DTIM Sync lost [5212+] */
+#define        AR5K_SIMR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
+#define        AR5K_SIMR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
+#define        AR5K_SIMR2_DTIM         0x20000000      /* [5212+] */
+#define        AR5K_SIMR2_TSFOOR       0x80000000      /* TSF OOR (?) */
+
+#define AR5K_SIMR3             0x00b0                  /* Register Address [5211+] */
+#define AR5K_SIMR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
+#define AR5K_SIMR3_QCBRORN_S   0
+#define AR5K_SIMR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
+#define AR5K_SIMR3_QCBRURN_S   16
+
+#define AR5K_SIMR4             0x00b4                  /* Register Address [5211+] */
+#define AR5K_SIMR4_QTRIG       0x000003ff      /* Mask for QTRIG */
+#define AR5K_SIMR4_QTRIG_S     0
+
+/*
+ * DMA Debug registers 0-7
+ * 0xe0 - 0xfc
+ */
+
+/*
+ * Decompression mask registers [5212+]
+ */
+#define AR5K_DCM_ADDR          0x0400          /*Decompression mask address (index) */
+#define AR5K_DCM_DATA          0x0404          /*Decompression mask data */
+
+/*
+ * Wake On Wireless pattern control register [5212+]
+ */
+#define        AR5K_WOW_PCFG                   0x0410                  /* Register Address */
+#define        AR5K_WOW_PCFG_PAT_MATCH_EN      0x00000001      /* Pattern match enable */
+#define        AR5K_WOW_PCFG_LONG_FRAME_POL    0x00000002      /* Long frame policy */
+#define        AR5K_WOW_PCFG_WOBMISS           0x00000004      /* Wake on bea(con) miss (?) */
+#define        AR5K_WOW_PCFG_PAT_0_EN          0x00000100      /* Enable pattern 0 */
+#define        AR5K_WOW_PCFG_PAT_1_EN          0x00000200      /* Enable pattern 1 */
+#define        AR5K_WOW_PCFG_PAT_2_EN          0x00000400      /* Enable pattern 2 */
+#define        AR5K_WOW_PCFG_PAT_3_EN          0x00000800      /* Enable pattern 3 */
+#define        AR5K_WOW_PCFG_PAT_4_EN          0x00001000      /* Enable pattern 4 */
+#define        AR5K_WOW_PCFG_PAT_5_EN          0x00002000      /* Enable pattern 5 */
+
+/*
+ * Wake On Wireless pattern index register (?) [5212+]
+ */
+#define        AR5K_WOW_PAT_IDX        0x0414
+
+/*
+ * Wake On Wireless pattern data register [5212+]
+ */
+#define        AR5K_WOW_PAT_DATA       0x0418                  /* Register Address */
+#define        AR5K_WOW_PAT_DATA_0_3_V 0x00000001      /* Pattern 0, 3 value */
+#define        AR5K_WOW_PAT_DATA_1_4_V 0x00000100      /* Pattern 1, 4 value */
+#define        AR5K_WOW_PAT_DATA_2_5_V 0x00010000      /* Pattern 2, 5 value */
+#define        AR5K_WOW_PAT_DATA_0_3_M 0x01000000      /* Pattern 0, 3 mask */
+#define        AR5K_WOW_PAT_DATA_1_4_M 0x04000000      /* Pattern 1, 4 mask */
+#define        AR5K_WOW_PAT_DATA_2_5_M 0x10000000      /* Pattern 2, 5 mask */
+
+/*
+ * Decompression configuration registers [5212+]
+ */
+#define AR5K_DCCFG             0x0420                  /* Register Address */
+#define AR5K_DCCFG_GLOBAL_EN   0x00000001      /* Enable decompression on all queues */
+#define AR5K_DCCFG_BYPASS_EN   0x00000002      /* Bypass decompression */
+#define AR5K_DCCFG_BCAST_EN    0x00000004      /* Enable decompression for bcast frames */
+#define AR5K_DCCFG_MCAST_EN    0x00000008      /* Enable decompression for mcast frames */
+
+/*
+ * Compression configuration registers [5212+]
+ */
+#define AR5K_CCFG              0x0600                  /* Register Address */
+#define        AR5K_CCFG_WINDOW_SIZE   0x00000007      /* Compression window size */
+#define        AR5K_CCFG_CPC_EN        0x00000008      /* Enable performance counters */
+
+#define AR5K_CCFG_CCU          0x0604                  /* Register Address */
+#define AR5K_CCFG_CCU_CUP_EN   0x00000001      /* CCU Catchup enable */
+#define AR5K_CCFG_CCU_CREDIT   0x00000002      /* CCU Credit (field) */
+#define AR5K_CCFG_CCU_CD_THRES 0x00000080      /* CCU Cyc(lic?) debt threshold (field) */
+#define AR5K_CCFG_CCU_CUP_LCNT 0x00010000      /* CCU Catchup lit(?) count */
+#define        AR5K_CCFG_CCU_INIT      0x00100200      /* Initial value during reset */
+
+/*
+ * Compression performance counter registers [5212+]
+ */
+#define AR5K_CPC0              0x0610          /* Compression performance counter 0 */
+#define AR5K_CPC1              0x0614          /* Compression performance counter 1*/
+#define AR5K_CPC2              0x0618          /* Compression performance counter 2 */
+#define AR5K_CPC3              0x061c          /* Compression performance counter 3 */
+#define AR5K_CPCOVF            0x0620          /* Compression performance overflow */
+
+
+/*
+ * Queue control unit (QCU) registers [5211+]
+ *
+ * Card has 12 TX Queues but i see that only 0-9 are used (?)
+ * both in binary HAL (see ah.h) and ar5k. Each queue has it's own
+ * TXDP at addresses 0x0800 - 0x082c, a CBR (Constant Bit Rate)
+ * configuration register (0x08c0 - 0x08ec), a ready time configuration
+ * register (0x0900 - 0x092c), a misc configuration register (0x09c0 -
+ * 0x09ec) and a status register (0x0a00 - 0x0a2c). We also have some
+ * global registers, QCU transmit enable/disable and "one shot arm (?)"
+ * set/clear, which contain status for all queues (we shift by 1 for each
+ * queue). To access these registers easily we define some macros here
+ * that are used inside HAL. For more infos check out *_tx_queue functs.
+ */
+
+/*
+ * Generic QCU Register access macros
+ */
+#define        AR5K_QUEUE_REG(_r, _q)          (((_q) << 2) + _r)
+#define AR5K_QCU_GLOBAL_READ(_r, _q)   (AR5K_REG_READ(_r) & (1 << _q))
+#define AR5K_QCU_GLOBAL_WRITE(_r, _q)  AR5K_REG_WRITE(_r, (1 << _q))
+
+/*
+ * QCU Transmit descriptor pointer registers
+ */
+#define AR5K_QCU_TXDP_BASE     0x0800          /* Register Address - Queue0 TXDP */
+#define AR5K_QUEUE_TXDP(_q)    AR5K_QUEUE_REG(AR5K_QCU_TXDP_BASE, _q)
+
+/*
+ * QCU Transmit enable register
+ */
+#define AR5K_QCU_TXE           0x0840
+#define AR5K_ENABLE_QUEUE(_q)  AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXE, _q)
+#define AR5K_QUEUE_ENABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXE, _q)
+
+/*
+ * QCU Transmit disable register
+ */
+#define AR5K_QCU_TXD           0x0880
+#define AR5K_DISABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXD, _q)
+#define AR5K_QUEUE_DISABLED(_q)        AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXD, _q)
+
+/*
+ * QCU Constant Bit Rate configuration registers
+ */
+#define        AR5K_QCU_CBRCFG_BASE            0x08c0  /* Register Address - Queue0 CBRCFG */
+#define        AR5K_QCU_CBRCFG_INTVAL          0x00ffffff      /* CBR Interval mask */
+#define AR5K_QCU_CBRCFG_INTVAL_S       0
+#define        AR5K_QCU_CBRCFG_ORN_THRES       0xff000000      /* CBR overrun threshold mask */
+#define AR5K_QCU_CBRCFG_ORN_THRES_S    24
+#define        AR5K_QUEUE_CBRCFG(_q)           AR5K_QUEUE_REG(AR5K_QCU_CBRCFG_BASE, _q)
+
+/*
+ * QCU Ready time configuration registers
+ */
+#define        AR5K_QCU_RDYTIMECFG_BASE        0x0900  /* Register Address - Queue0 RDYTIMECFG */
+#define        AR5K_QCU_RDYTIMECFG_INTVAL      0x00ffffff      /* Ready time interval mask */
+#define AR5K_QCU_RDYTIMECFG_INTVAL_S   0
+#define        AR5K_QCU_RDYTIMECFG_ENABLE      0x01000000      /* Ready time enable mask */
+#define AR5K_QUEUE_RDYTIMECFG(_q)      AR5K_QUEUE_REG(AR5K_QCU_RDYTIMECFG_BASE, _q)
+
+/*
+ * QCU one shot arm set registers
+ */
+#define        AR5K_QCU_ONESHOTARM_SET         0x0940  /* Register Address -QCU "one shot arm set (?)" */
+#define        AR5K_QCU_ONESHOTARM_SET_M       0x0000ffff
+
+/*
+ * QCU one shot arm clear registers
+ */
+#define        AR5K_QCU_ONESHOTARM_CLEAR       0x0980  /* Register Address -QCU "one shot arm clear (?)" */
+#define        AR5K_QCU_ONESHOTARM_CLEAR_M     0x0000ffff
+
+/*
+ * QCU misc registers
+ */
+#define AR5K_QCU_MISC_BASE             0x09c0                  /* Register Address -Queue0 MISC */
+#define        AR5K_QCU_MISC_FRSHED_M          0x0000000f      /* Frame sheduling mask */
+#define        AR5K_QCU_MISC_FRSHED_ASAP               0       /* ASAP */
+#define        AR5K_QCU_MISC_FRSHED_CBR                1       /* Constant Bit Rate */
+#define        AR5K_QCU_MISC_FRSHED_DBA_GT             2       /* DMA Beacon alert gated */
+#define        AR5K_QCU_MISC_FRSHED_TIM_GT             3       /* TIMT gated */
+#define        AR5K_QCU_MISC_FRSHED_BCN_SENT_GT        4       /* Beacon sent gated */
+#define        AR5K_QCU_MISC_ONESHOT_ENABLE    0x00000010      /* Oneshot enable */
+#define        AR5K_QCU_MISC_CBREXP_DIS        0x00000020      /* Disable CBR expired counter (normal queue) */
+#define        AR5K_QCU_MISC_CBREXP_BCN_DIS    0x00000040      /* Disable CBR expired counter (beacon queue) */
+#define        AR5K_QCU_MISC_BCN_ENABLE        0x00000080      /* Enable Beacon use */
+#define        AR5K_QCU_MISC_CBR_THRES_ENABLE  0x00000100      /* CBR expired threshold enabled */
+#define        AR5K_QCU_MISC_RDY_VEOL_POLICY   0x00000200      /* TXE reset when RDYTIME expired or VEOL */
+#define        AR5K_QCU_MISC_CBR_RESET_CNT     0x00000400      /* CBR threshold (counter) reset */
+#define        AR5K_QCU_MISC_DCU_EARLY         0x00000800      /* DCU early termination */
+#define AR5K_QCU_MISC_DCU_CMP_EN       0x00001000      /* Enable frame compression */
+#define AR5K_QUEUE_MISC(_q)            AR5K_QUEUE_REG(AR5K_QCU_MISC_BASE, _q)
+
+
+/*
+ * QCU status registers
+ */
+#define AR5K_QCU_STS_BASE      0x0a00                  /* Register Address - Queue0 STS */
+#define        AR5K_QCU_STS_FRMPENDCNT 0x00000003      /* Frames pending counter */
+#define        AR5K_QCU_STS_CBREXPCNT  0x0000ff00      /* CBR expired counter */
+#define        AR5K_QUEUE_STATUS(_q)   AR5K_QUEUE_REG(AR5K_QCU_STS_BASE, _q)
+
+/*
+ * QCU ready time shutdown register
+ */
+#define AR5K_QCU_RDYTIMESHDN   0x0a40
+#define AR5K_QCU_RDYTIMESHDN_M 0x000003ff
+
+/*
+ * QCU compression buffer base registers [5212+]
+ */
+#define AR5K_QCU_CBB_SELECT    0x0b00
+#define AR5K_QCU_CBB_ADDR      0x0b04
+#define AR5K_QCU_CBB_ADDR_S    9
+
+/*
+ * QCU compression buffer configuration register [5212+]
+ * (buffer size)
+ */
+#define AR5K_QCU_CBCFG         0x0b08
+
+
+
+/*
+ * Distributed Coordination Function (DCF) control unit (DCU)
+ * registers [5211+]
+ *
+ * These registers control the various characteristics of each queue
+ * for 802.11e (WME) combatibility so they go together with
+ * QCU registers in pairs. For each queue we have a QCU mask register,
+ * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c),
+ * a retry limit register (0x1080 - 0x10ac), a channel time register
+ * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and
+ * a sequence number register (0x1140 - 0x116c). It seems that "global"
+ * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k).
+ * We use the same macros here for easier register access.
+ *
+ */
+
+/*
+ * DCU QCU mask registers
+ */
+#define AR5K_DCU_QCUMASK_BASE  0x1000          /* Register Address -Queue0 DCU_QCUMASK */
+#define AR5K_DCU_QCUMASK_M     0x000003ff
+#define AR5K_QUEUE_QCUMASK(_q) AR5K_QUEUE_REG(AR5K_DCU_QCUMASK_BASE, _q)
+
+/*
+ * DCU local Inter Frame Space settings register
+ */
+#define AR5K_DCU_LCL_IFS_BASE          0x1040                  /* Register Address -Queue0 DCU_LCL_IFS */
+#define        AR5K_DCU_LCL_IFS_CW_MIN         0x000003ff      /* Minimum Contention Window */
+#define        AR5K_DCU_LCL_IFS_CW_MIN_S       0
+#define        AR5K_DCU_LCL_IFS_CW_MAX         0x000ffc00      /* Maximum Contention Window */
+#define        AR5K_DCU_LCL_IFS_CW_MAX_S       10
+#define        AR5K_DCU_LCL_IFS_AIFS           0x0ff00000      /* Arbitrated Interframe Space */
+#define        AR5K_DCU_LCL_IFS_AIFS_S         20
+#define        AR5K_DCU_LCL_IFS_AIFS_MAX       0xfc            /* Anything above that can cause DCU to hang */
+#define        AR5K_QUEUE_DFS_LOCAL_IFS(_q)    AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q)
+
+/*
+ * DCU retry limit registers
+ */
+#define AR5K_DCU_RETRY_LMT_BASE                0x1080                  /* Register Address -Queue0 DCU_RETRY_LMT */
+#define AR5K_DCU_RETRY_LMT_SH_RETRY    0x0000000f      /* Short retry limit mask */
+#define AR5K_DCU_RETRY_LMT_SH_RETRY_S  0
+#define AR5K_DCU_RETRY_LMT_LG_RETRY    0x000000f0      /* Long retry limit mask */
+#define AR5K_DCU_RETRY_LMT_LG_RETRY_S  4
+#define AR5K_DCU_RETRY_LMT_SSH_RETRY   0x00003f00      /* Station short retry limit mask (?) */
+#define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8
+#define AR5K_DCU_RETRY_LMT_SLG_RETRY   0x000fc000      /* Station long retry limit mask (?) */
+#define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14
+#define        AR5K_QUEUE_DFS_RETRY_LIMIT(_q)  AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q)
+
+/*
+ * DCU channel time registers
+ */
+#define AR5K_DCU_CHAN_TIME_BASE                0x10c0                  /* Register Address -Queue0 DCU_CHAN_TIME */
+#define        AR5K_DCU_CHAN_TIME_DUR          0x000fffff      /* Channel time duration */
+#define        AR5K_DCU_CHAN_TIME_DUR_S        0
+#define        AR5K_DCU_CHAN_TIME_ENABLE       0x00100000      /* Enable channel time */
+#define AR5K_QUEUE_DFS_CHANNEL_TIME(_q)        AR5K_QUEUE_REG(AR5K_DCU_CHAN_TIME_BASE, _q)
+
+/*
+ * DCU misc registers [5211+]
+ *
+ * Note: Arbiter lockout control controls the
+ * behaviour on low priority queues when we have multiple queues
+ * with pending frames. Intra-frame lockout means we wait until
+ * the queue's current frame transmits (with post frame backoff and bursting)
+ * before we transmit anything else and global lockout means we
+ * wait for the whole queue to finish before higher priority queues
+ * can transmit (this is used on beacon and CAB queues).
+ * No lockout means there is no special handling.
+ */
+#define AR5K_DCU_MISC_BASE             0x1100                  /* Register Address -Queue0 DCU_MISC */
+#define        AR5K_DCU_MISC_BACKOFF           0x0000003f      /* Mask for backoff threshold */
+#define        AR5K_DCU_MISC_ETS_RTS_POL       0x00000040      /* End of transmission series
+                                                       station RTS/data failure count
+                                                       reset policy (?) */
+#define AR5K_DCU_MISC_ETS_CW_POL       0x00000080      /* End of transmission series
+                                                       CW reset policy */
+#define        AR5K_DCU_MISC_FRAG_WAIT         0x00000100      /* Wait for next fragment */
+#define AR5K_DCU_MISC_BACKOFF_FRAG     0x00000200      /* Enable backoff while bursting */
+#define        AR5K_DCU_MISC_HCFPOLL_ENABLE    0x00000800      /* CF - Poll enable */
+#define        AR5K_DCU_MISC_BACKOFF_PERSIST   0x00001000      /* Persistent backoff */
+#define        AR5K_DCU_MISC_FRMPRFTCH_ENABLE  0x00002000      /* Enable frame pre-fetch */
+#define        AR5K_DCU_MISC_VIRTCOL           0x0000c000      /* Mask for Virtual Collision (?) */
+#define        AR5K_DCU_MISC_VIRTCOL_NORMAL    0
+#define        AR5K_DCU_MISC_VIRTCOL_IGNORE    1
+#define        AR5K_DCU_MISC_BCN_ENABLE        0x00010000      /* Enable Beacon use */
+#define        AR5K_DCU_MISC_ARBLOCK_CTL       0x00060000      /* Arbiter lockout control mask */
+#define        AR5K_DCU_MISC_ARBLOCK_CTL_S     17
+#define        AR5K_DCU_MISC_ARBLOCK_CTL_NONE          0       /* No arbiter lockout */
+#define        AR5K_DCU_MISC_ARBLOCK_CTL_INTFRM        1       /* Intra-frame lockout */
+#define        AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL        2       /* Global lockout */
+#define        AR5K_DCU_MISC_ARBLOCK_IGNORE    0x00080000      /* Ignore Arbiter lockout */
+#define        AR5K_DCU_MISC_SEQ_NUM_INCR_DIS  0x00100000      /* Disable sequence number increment */
+#define        AR5K_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000      /* Disable post-frame backoff */
+#define        AR5K_DCU_MISC_VIRT_COLL_POLICY  0x00400000      /* Virtual Collision cw policy */
+#define        AR5K_DCU_MISC_BLOWN_IFS_POLICY  0x00800000      /* Blown IFS policy (?) */
+#define        AR5K_DCU_MISC_SEQNUM_CTL        0x01000000      /* Sequence number control (?) */
+#define AR5K_QUEUE_DFS_MISC(_q)                AR5K_QUEUE_REG(AR5K_DCU_MISC_BASE, _q)
+
+/*
+ * DCU frame sequence number registers
+ */
+#define AR5K_DCU_SEQNUM_BASE           0x1140
+#define        AR5K_DCU_SEQNUM_M               0x00000fff
+#define        AR5K_QUEUE_DCU_SEQNUM(_q)       AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
+
+/*
+ * DCU global IFS SIFS register
+ */
+#define AR5K_DCU_GBL_IFS_SIFS  0x1030
+#define AR5K_DCU_GBL_IFS_SIFS_M        0x0000ffff
+
+/*
+ * DCU global IFS slot interval register
+ */
+#define AR5K_DCU_GBL_IFS_SLOT  0x1070
+#define AR5K_DCU_GBL_IFS_SLOT_M        0x0000ffff
+
+/*
+ * DCU global IFS EIFS register
+ */
+#define AR5K_DCU_GBL_IFS_EIFS  0x10b0
+#define AR5K_DCU_GBL_IFS_EIFS_M        0x0000ffff
+
+/*
+ * DCU global IFS misc register
+ *
+ * LFSR stands for Linear Feedback Shift Register
+ * and it's used for generating pseudo-random
+ * number sequences.
+ *
+ * (If i understand corectly, random numbers are
+ * used for idle sensing -multiplied with cwmin/max etc-)
+ */
+#define AR5K_DCU_GBL_IFS_MISC                  0x10f0                  /* Register Address */
+#define        AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE        0x00000007      /* LFSR Slice Select */
+#define        AR5K_DCU_GBL_IFS_MISC_TURBO_MODE        0x00000008      /* Turbo mode */
+#define        AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC     0x000003f0      /* SIFS Duration mask */
+#define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR          0x000ffc00      /* USEC Duration mask */
+#define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S        10
+#define        AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY     0x00300000      /* DCU Arbiter delay mask */
+#define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST     0x00400000      /* SIFS cnt reset policy (?) */
+#define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST     0x00800000      /* AIFS cnt reset policy (?) */
+#define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS  0x01000000      /* Disable random LFSR slice */
+
+/*
+ * DCU frame prefetch control register
+ */
+#define AR5K_DCU_FP                    0x1230                  /* Register Address */
+#define AR5K_DCU_FP_NOBURST_DCU_EN     0x00000001      /* Enable non-burst prefetch on DCU (?) */
+#define AR5K_DCU_FP_NOBURST_EN         0x00000010      /* Enable non-burst prefetch (?) */
+#define AR5K_DCU_FP_BURST_DCU_EN       0x00000020      /* Enable burst prefetch on DCU (?) */
+
+/*
+ * DCU transmit pause control/status register
+ */
+#define AR5K_DCU_TXP           0x1270                  /* Register Address */
+#define        AR5K_DCU_TXP_M          0x000003ff      /* Tx pause mask */
+#define        AR5K_DCU_TXP_STATUS     0x00010000      /* Tx pause status */
+
+/*
+ * DCU transmit filter table 0 (32 entries)
+ * each entry contains a 32bit slice of the
+ * 128bit tx filter for each DCU (4 slices per DCU)
+ */
+#define AR5K_DCU_TX_FILTER_0_BASE      0x1038
+#define        AR5K_DCU_TX_FILTER_0(_n)        (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64))
+
+/*
+ * DCU transmit filter table 1 (16 entries)
+ */
+#define AR5K_DCU_TX_FILTER_1_BASE      0x103c
+#define        AR5K_DCU_TX_FILTER_1(_n)        (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64))
+
+/*
+ * DCU clear transmit filter register
+ */
+#define AR5K_DCU_TX_FILTER_CLR 0x143c
+
+/*
+ * DCU set transmit filter register
+ */
+#define AR5K_DCU_TX_FILTER_SET 0x147c
+
+/*
+ * Reset control register
+ */
+#define AR5K_RESET_CTL         0x4000                  /* Register Address */
+#define AR5K_RESET_CTL_PCU     0x00000001      /* Protocol Control Unit reset */
+#define AR5K_RESET_CTL_DMA     0x00000002      /* DMA (Rx/Tx) reset [5210] */
+#define        AR5K_RESET_CTL_BASEBAND 0x00000002      /* Baseband reset [5211+] */
+#define AR5K_RESET_CTL_MAC     0x00000004      /* MAC reset (PCU+Baseband ?) [5210] */
+#define AR5K_RESET_CTL_PHY     0x00000008      /* PHY reset [5210] */
+#define AR5K_RESET_CTL_PCI     0x00000010      /* PCI Core reset (interrupts etc) */
+
+/*
+ * Sleep control register
+ */
+#define AR5K_SLEEP_CTL                 0x4004                  /* Register Address */
+#define AR5K_SLEEP_CTL_SLDUR           0x0000ffff      /* Sleep duration mask */
+#define AR5K_SLEEP_CTL_SLDUR_S         0
+#define AR5K_SLEEP_CTL_SLE             0x00030000      /* Sleep enable mask */
+#define AR5K_SLEEP_CTL_SLE_S           16
+#define AR5K_SLEEP_CTL_SLE_WAKE                0x00000000      /* Force chip awake */
+#define AR5K_SLEEP_CTL_SLE_SLP         0x00010000      /* Force chip sleep */
+#define AR5K_SLEEP_CTL_SLE_ALLOW       0x00020000      /* Normal sleep policy */
+#define AR5K_SLEEP_CTL_SLE_UNITS       0x00000008      /* [5211+] */
+#define AR5K_SLEEP_CTL_DUR_TIM_POL     0x00040000      /* Sleep duration timing policy */
+#define AR5K_SLEEP_CTL_DUR_WRITE_POL   0x00080000      /* Sleep duration write policy */
+#define AR5K_SLEEP_CTL_SLE_POL         0x00100000      /* Sleep policy mode */
+
+/*
+ * Interrupt pending register
+ */
+#define AR5K_INTPEND   0x4008
+#define AR5K_INTPEND_M 0x00000001
+
+/*
+ * Sleep force register
+ */
+#define AR5K_SFR       0x400c
+#define AR5K_SFR_EN    0x00000001
+
+/*
+ * PCI configuration register
+ * TODO: Fix LED stuff
+ */
+#define AR5K_PCICFG                    0x4010                  /* Register Address */
+#define AR5K_PCICFG_EEAE               0x00000001      /* Eeprom access enable [5210] */
+#define AR5K_PCICFG_SLEEP_CLOCK_EN     0x00000002      /* Enable sleep clock */
+#define AR5K_PCICFG_CLKRUNEN           0x00000004      /* CLKRUN enable [5211+] */
+#define AR5K_PCICFG_EESIZE             0x00000018      /* Mask for EEPROM size [5211+] */
+#define AR5K_PCICFG_EESIZE_S           3
+#define AR5K_PCICFG_EESIZE_4K          0               /* 4K */
+#define AR5K_PCICFG_EESIZE_8K          1               /* 8K */
+#define AR5K_PCICFG_EESIZE_16K         2               /* 16K */
+#define AR5K_PCICFG_EESIZE_FAIL                3               /* Failed to get size [5211+] */
+#define AR5K_PCICFG_LED                        0x00000060      /* Led status [5211+] */
+#define AR5K_PCICFG_LED_NONE           0x00000000      /* Default [5211+] */
+#define AR5K_PCICFG_LED_PEND           0x00000020      /* Scan / Auth pending */
+#define AR5K_PCICFG_LED_ASSOC          0x00000040      /* Associated */
+#define        AR5K_PCICFG_BUS_SEL             0x00000380      /* Mask for "bus select" [5211+] (?) */
+#define AR5K_PCICFG_CBEFIX_DIS         0x00000400      /* Disable CBE fix */
+#define AR5K_PCICFG_SL_INTEN           0x00000800      /* Enable interrupts when asleep */
+#define AR5K_PCICFG_LED_BCTL           0x00001000      /* Led blink (?) [5210] */
+#define AR5K_PCICFG_RETRY_FIX          0x00001000      /* Enable pci core retry fix */
+#define AR5K_PCICFG_SL_INPEN           0x00002000      /* Sleep even whith pending interrupts*/
+#define AR5K_PCICFG_SPWR_DN            0x00010000      /* Mask for power status */
+#define AR5K_PCICFG_LEDMODE            0x000e0000      /* Ledmode [5211+] */
+#define AR5K_PCICFG_LEDMODE_PROP       0x00000000      /* Blink on standard traffic [5211+] */
+#define AR5K_PCICFG_LEDMODE_PROM       0x00020000      /* Default mode (blink on any traffic) [5211+] */
+#define AR5K_PCICFG_LEDMODE_PWR                0x00040000      /* Some other blinking mode  (?) [5211+] */
+#define AR5K_PCICFG_LEDMODE_RAND       0x00060000      /* Random blinking (?) [5211+] */
+#define AR5K_PCICFG_LEDBLINK           0x00700000      /* Led blink rate */
+#define AR5K_PCICFG_LEDBLINK_S         20
+#define AR5K_PCICFG_LEDSLOW            0x00800000      /* Slowest led blink rate [5211+] */
+#define AR5K_PCICFG_LEDSTATE                           \
+       (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE |        \
+       AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW)
+#define        AR5K_PCICFG_SLEEP_CLOCK_RATE    0x03000000      /* Sleep clock rate */
+#define        AR5K_PCICFG_SLEEP_CLOCK_RATE_S  24
+
+/*
+ * "General Purpose Input/Output" (GPIO) control register
+ *
+ * I'm not sure about this but after looking at the code
+ * for all chipsets here is what i got.
+ *
+ * We have 6 GPIOs (pins), each GPIO has 4 modes (2 bits)
+ * Mode 0 -> always input
+ * Mode 1 -> output when GPIODO for this GPIO is set to 0
+ * Mode 2 -> output when GPIODO for this GPIO is set to 1
+ * Mode 3 -> always output
+ *
+ * For more infos check out get_gpio/set_gpio and
+ * set_gpio_input/set_gpio_output functs.
+ * For more infos on gpio interrupt check out set_gpio_intr.
+ */
+#define AR5K_NUM_GPIO  6
+
+#define AR5K_GPIOCR            0x4014                          /* Register Address */
+#define AR5K_GPIOCR_INT_ENA    0x00008000              /* Enable GPIO interrupt */
+#define AR5K_GPIOCR_INT_SELL   0x00000000              /* Generate interrupt when pin is low */
+#define AR5K_GPIOCR_INT_SELH   0x00010000              /* Generate interrupt when pin is high */
+#define AR5K_GPIOCR_IN(n)      (0 << ((n) * 2))        /* Mode 0 for pin n */
+#define AR5K_GPIOCR_OUT0(n)    (1 << ((n) * 2))        /* Mode 1 for pin n */
+#define AR5K_GPIOCR_OUT1(n)    (2 << ((n) * 2))        /* Mode 2 for pin n */
+#define AR5K_GPIOCR_OUT(n)     (3 << ((n) * 2))        /* Mode 3 for pin n */
+#define AR5K_GPIOCR_INT_SEL(n) ((n) << 12)             /* Interrupt for GPIO pin n */
+
+/*
+ * "General Purpose Input/Output" (GPIO) data output register
+ */
+#define AR5K_GPIODO    0x4018
+
+/*
+ * "General Purpose Input/Output" (GPIO) data input register
+ */
+#define AR5K_GPIODI    0x401c
+#define AR5K_GPIODI_M  0x0000002f
+
+/*
+ * Silicon revision register
+ */
+#define AR5K_SREV              0x4020                  /* Register Address */
+#define AR5K_SREV_REV          0x0000000f      /* Mask for revision */
+#define AR5K_SREV_REV_S                0
+#define AR5K_SREV_VER          0x000000ff      /* Mask for version */
+#define AR5K_SREV_VER_S                4
+
+/*
+ * TXE write posting register
+ */
+#define        AR5K_TXEPOST    0x4028
+
+/*
+ * QCU sleep mask
+ */
+#define        AR5K_QCU_SLEEP_MASK     0x402c
+
+/* 0x4068 is compression buffer configuration
+ * register on 5414 and pm configuration register
+ * on 5424 and newer pci-e chips. */
+
+/*
+ * Compression buffer configuration
+ * register (enable/disable) [5414]
+ */
+#define AR5K_5414_CBCFG                0x4068
+#define AR5K_5414_CBCFG_BUF_DIS        0x10    /* Disable buffer */
+
+/*
+ * PCI-E Power managment configuration
+ * and status register [5424+]
+ */
+#define        AR5K_PCIE_PM_CTL                0x4068                  /* Register address */
+/* Only 5424 */
+#define        AR5K_PCIE_PM_CTL_L1_WHEN_D2     0x00000001      /* enable PCIe core enter L1
+                                                       when d2_sleep_en is asserted */
+#define        AR5K_PCIE_PM_CTL_L0_L0S_CLEAR   0x00000002      /* Clear L0 and L0S counters */
+#define        AR5K_PCIE_PM_CTL_L0_L0S_EN      0x00000004      /* Start L0 nd L0S counters */
+#define        AR5K_PCIE_PM_CTL_LDRESET_EN     0x00000008      /* Enable reset when link goes
+                                                       down */
+/* Wake On Wireless */
+#define        AR5K_PCIE_PM_CTL_PME_EN         0x00000010      /* PME Enable */
+#define        AR5K_PCIE_PM_CTL_AUX_PWR_DET    0x00000020      /* Aux power detect */
+#define        AR5K_PCIE_PM_CTL_PME_CLEAR      0x00000040      /* Clear PME */
+#define        AR5K_PCIE_PM_CTL_PSM_D0         0x00000080
+#define        AR5K_PCIE_PM_CTL_PSM_D1         0x00000100
+#define        AR5K_PCIE_PM_CTL_PSM_D2         0x00000200
+#define        AR5K_PCIE_PM_CTL_PSM_D3         0x00000400
+
+/*
+ * PCI-E Workaround enable register
+ */
+#define        AR5K_PCIE_WAEN  0x407c
+
+/*
+ * PCI-E Serializer/Desirializer
+ * registers
+ */
+#define        AR5K_PCIE_SERDES        0x4080
+#define        AR5K_PCIE_SERDES_RESET  0x4084
+
+/*====EEPROM REGISTERS====*/
+
+/*
+ * EEPROM access registers
+ *
+ * Here we got a difference between 5210/5211-12
+ * read data register for 5210 is at 0x6800 and
+ * status register is at 0x6c00. There is also
+ * no eeprom command register on 5210 and the
+ * offsets are different.
+ *
+ * To read eeprom data for a specific offset:
+ * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
+ *        read AR5K_EEPROM_BASE +(4 * offset)
+ *        check the eeprom status register
+ *        and read eeprom data register.
+ *
+ * 5211 - write offset to AR5K_EEPROM_BASE
+ * 5212   write AR5K_EEPROM_CMD_READ on AR5K_EEPROM_CMD
+ *        check the eeprom status register
+ *        and read eeprom data register.
+ *
+ * To write eeprom data for a specific offset:
+ * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
+ *        write data to AR5K_EEPROM_BASE +(4 * offset)
+ *        check the eeprom status register
+ * 5211 - write AR5K_EEPROM_CMD_RESET on AR5K_EEPROM_CMD
+ * 5212   write offset to AR5K_EEPROM_BASE
+ *        write data to data register
+ *       write AR5K_EEPROM_CMD_WRITE on AR5K_EEPROM_CMD
+ *        check the eeprom status register
+ *
+ * For more infos check eeprom_* functs and the ar5k.c
+ * file posted in madwifi-devel mailing list.
+ * http://sourceforge.net/mailarchive/message.php?msg_id=8966525
+ *
+ */
+#define AR5K_EEPROM_BASE       0x6000
+
+/*
+ * EEPROM data register
+ */
+#define AR5K_EEPROM_DATA_5211  0x6004
+#define AR5K_EEPROM_DATA_5210  0x6800
+#define        AR5K_EEPROM_DATA        (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211)
+
+/*
+ * EEPROM command register
+ */
+#define AR5K_EEPROM_CMD                0x6008                  /* Register Addres */
+#define AR5K_EEPROM_CMD_READ   0x00000001      /* EEPROM read */
+#define AR5K_EEPROM_CMD_WRITE  0x00000002      /* EEPROM write */
+#define AR5K_EEPROM_CMD_RESET  0x00000004      /* EEPROM reset */
+
+/*
+ * EEPROM status register
+ */
+#define AR5K_EEPROM_STAT_5210  0x6c00                  /* Register Address [5210] */
+#define AR5K_EEPROM_STAT_5211  0x600c                  /* Register Address [5211+] */
+#define        AR5K_EEPROM_STATUS      (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211)
+#define AR5K_EEPROM_STAT_RDERR 0x00000001      /* EEPROM read failed */
+#define AR5K_EEPROM_STAT_RDDONE        0x00000002      /* EEPROM read successful */
+#define AR5K_EEPROM_STAT_WRERR 0x00000004      /* EEPROM write failed */
+#define AR5K_EEPROM_STAT_WRDONE        0x00000008      /* EEPROM write successful */
+
+/*
+ * EEPROM config register
+ */
+#define AR5K_EEPROM_CFG                        0x6010                  /* Register Addres */
+#define AR5K_EEPROM_CFG_SIZE           0x00000003              /* Size determination override */
+#define AR5K_EEPROM_CFG_SIZE_AUTO      0
+#define AR5K_EEPROM_CFG_SIZE_4KBIT     1
+#define AR5K_EEPROM_CFG_SIZE_8KBIT     2
+#define AR5K_EEPROM_CFG_SIZE_16KBIT    3
+#define AR5K_EEPROM_CFG_WR_WAIT_DIS    0x00000004      /* Disable write wait */
+#define AR5K_EEPROM_CFG_CLK_RATE       0x00000018      /* Clock rate */
+#define AR5K_EEPROM_CFG_CLK_RATE_S             3
+#define AR5K_EEPROM_CFG_CLK_RATE_156KHZ        0
+#define AR5K_EEPROM_CFG_CLK_RATE_312KHZ        1
+#define AR5K_EEPROM_CFG_CLK_RATE_625KHZ        2
+#define AR5K_EEPROM_CFG_PROT_KEY       0x00ffff00      /* Protection key */
+#define AR5K_EEPROM_CFG_PROT_KEY_S     8
+#define AR5K_EEPROM_CFG_LIND_EN                0x01000000      /* Enable length indicator (?) */
+
+
+/*
+ * TODO: Wake On Wireless registers
+ * Range 0x7000 - 0x7ce0
+ */
+
+/*
+ * Protocol Control Unit (PCU) registers
+ */
+/*
+ * Used for checking initial register writes
+ * during channel reset (see reset func)
+ */
+#define AR5K_PCU_MIN   0x8000
+#define AR5K_PCU_MAX   0x8fff
+
+/*
+ * First station id register (Lower 32 bits of MAC address)
+ */
+#define AR5K_STA_ID0           0x8000
+#define        AR5K_STA_ID0_ARRD_L32   0xffffffff
+
+/*
+ * Second station id register (Upper 16 bits of MAC address + PCU settings)
+ */
+#define AR5K_STA_ID1                   0x8004                  /* Register Address */
+#define        AR5K_STA_ID1_ADDR_U16           0x0000ffff      /* Upper 16 bits of MAC addres */
+#define AR5K_STA_ID1_AP                        0x00010000      /* Set AP mode */
+#define AR5K_STA_ID1_ADHOC             0x00020000      /* Set Ad-Hoc mode */
+#define AR5K_STA_ID1_PWR_SV            0x00040000      /* Power save reporting */
+#define AR5K_STA_ID1_NO_KEYSRCH                0x00080000      /* No key search */
+#define AR5K_STA_ID1_NO_PSPOLL         0x00100000      /* No power save polling [5210] */
+#define AR5K_STA_ID1_PCF_5211          0x00100000      /* Enable PCF on [5211+] */
+#define AR5K_STA_ID1_PCF_5210          0x00200000      /* Enable PCF on [5210]*/
+#define        AR5K_STA_ID1_PCF                (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_STA_ID1_PCF_5210 : AR5K_STA_ID1_PCF_5211)
+#define AR5K_STA_ID1_DEFAULT_ANTENNA   0x00200000      /* Use default antenna */
+#define AR5K_STA_ID1_DESC_ANTENNA      0x00400000      /* Update antenna from descriptor */
+#define AR5K_STA_ID1_RTS_DEF_ANTENNA   0x00800000      /* Use default antenna for RTS */
+#define AR5K_STA_ID1_ACKCTS_6MB                0x01000000      /* Use 6Mbit/s for ACK/CTS */
+#define AR5K_STA_ID1_BASE_RATE_11B     0x02000000      /* Use 11b base rate for ACK/CTS [5211+] */
+#define AR5K_STA_ID1_SELFGEN_DEF_ANT   0x04000000      /* Use def. antenna for self generated frames */
+#define AR5K_STA_ID1_CRYPT_MIC_EN      0x08000000      /* Enable MIC */
+#define AR5K_STA_ID1_KEYSRCH_MODE      0x10000000      /* Look up key when key id != 0 */
+#define AR5K_STA_ID1_PRESERVE_SEQ_NUM  0x20000000      /* Preserve sequence number */
+#define AR5K_STA_ID1_CBCIV_ENDIAN      0x40000000      /* ??? */
+#define AR5K_STA_ID1_KEYSRCH_MCAST     0x80000000      /* Do key cache search for mcast frames */
+
+/*
+ * First BSSID register (MAC address, lower 32bits)
+ */
+#define AR5K_BSS_ID0   0x8008
+
+/*
+ * Second BSSID register (MAC address in upper 16 bits)
+ *
+ * AID: Association ID
+ */
+#define AR5K_BSS_ID1           0x800c
+#define AR5K_BSS_ID1_AID       0xffff0000
+#define AR5K_BSS_ID1_AID_S     16
+
+/*
+ * Backoff slot time register
+ */
+#define AR5K_SLOT_TIME 0x8010
+
+/*
+ * ACK/CTS timeout register
+ */
+#define AR5K_TIME_OUT          0x8014                  /* Register Address */
+#define AR5K_TIME_OUT_ACK      0x00001fff      /* ACK timeout mask */
+#define AR5K_TIME_OUT_ACK_S    0
+#define AR5K_TIME_OUT_CTS      0x1fff0000      /* CTS timeout mask */
+#define AR5K_TIME_OUT_CTS_S    16
+
+/*
+ * RSSI threshold register
+ */
+#define AR5K_RSSI_THR                  0x8018          /* Register Address */
+#define AR5K_RSSI_THR_M                        0x000000ff      /* Mask for RSSI threshold [5211+] */
+#define AR5K_RSSI_THR_BMISS_5210       0x00000700      /* Mask for Beacon Missed threshold [5210] */
+#define AR5K_RSSI_THR_BMISS_5210_S     8
+#define AR5K_RSSI_THR_BMISS_5211       0x0000ff00      /* Mask for Beacon Missed threshold [5211+] */
+#define AR5K_RSSI_THR_BMISS_5211_S     8
+#define        AR5K_RSSI_THR_BMISS             (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_RSSI_THR_BMISS_5210 : AR5K_RSSI_THR_BMISS_5211)
+#define        AR5K_RSSI_THR_BMISS_S           8
+
+/*
+ * 5210 has more PCU registers because there is no QCU/DCU
+ * so queue parameters are set here, this way a lot common
+ * registers have different address for 5210. To make things
+ * easier we define a macro based on ah->ah_version for common
+ * registers with different addresses and common flags.
+ */
+
+/*
+ * Retry limit register
+ *
+ * Retry limit register for 5210 (no QCU/DCU so it's done in PCU)
+ */
+#define AR5K_NODCU_RETRY_LMT           0x801c                  /* Register Address */
+#define AR5K_NODCU_RETRY_LMT_SH_RETRY  0x0000000f      /* Short retry limit mask */
+#define AR5K_NODCU_RETRY_LMT_SH_RETRY_S        0
+#define AR5K_NODCU_RETRY_LMT_LG_RETRY  0x000000f0      /* Long retry mask */
+#define AR5K_NODCU_RETRY_LMT_LG_RETRY_S        4
+#define AR5K_NODCU_RETRY_LMT_SSH_RETRY 0x00003f00      /* Station short retry limit mask */
+#define AR5K_NODCU_RETRY_LMT_SSH_RETRY_S       8
+#define AR5K_NODCU_RETRY_LMT_SLG_RETRY 0x000fc000      /* Station long retry limit mask */
+#define AR5K_NODCU_RETRY_LMT_SLG_RETRY_S       14
+#define AR5K_NODCU_RETRY_LMT_CW_MIN    0x3ff00000      /* Minimum contention window mask */
+#define AR5K_NODCU_RETRY_LMT_CW_MIN_S  20
+
+/*
+ * Transmit latency register
+ */
+#define AR5K_USEC_5210                 0x8020                  /* Register Address [5210] */
+#define AR5K_USEC_5211                 0x801c                  /* Register Address [5211+] */
+#define AR5K_USEC                      (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_USEC_5210 : AR5K_USEC_5211)
+#define AR5K_USEC_1                    0x0000007f      /* clock cycles for 1us */
+#define AR5K_USEC_1_S                  0
+#define AR5K_USEC_32                   0x00003f80      /* clock cycles for 1us while on 32Mhz clock */
+#define AR5K_USEC_32_S                 7
+#define AR5K_USEC_TX_LATENCY_5211      0x007fc000
+#define AR5K_USEC_TX_LATENCY_5211_S    14
+#define AR5K_USEC_RX_LATENCY_5211      0x1f800000
+#define AR5K_USEC_RX_LATENCY_5211_S    23
+#define AR5K_USEC_TX_LATENCY_5210      0x000fc000      /* also for 5311 */
+#define AR5K_USEC_TX_LATENCY_5210_S    14
+#define AR5K_USEC_RX_LATENCY_5210      0x03f00000      /* also for 5311 */
+#define AR5K_USEC_RX_LATENCY_5210_S    20
+
+/*
+ * PCU beacon control register
+ */
+#define AR5K_BEACON_5210       0x8024                  /*Register Address [5210] */
+#define AR5K_BEACON_5211       0x8020                  /*Register Address [5211+] */
+#define AR5K_BEACON            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_BEACON_5210 : AR5K_BEACON_5211)
+#define AR5K_BEACON_PERIOD     0x0000ffff      /* Mask for beacon period */
+#define AR5K_BEACON_PERIOD_S   0
+#define AR5K_BEACON_TIM                0x007f0000      /* Mask for TIM offset */
+#define AR5K_BEACON_TIM_S      16
+#define AR5K_BEACON_ENABLE     0x00800000      /* Enable beacons */
+#define AR5K_BEACON_RESET_TSF  0x01000000      /* Force TSF reset */
+
+/*
+ * CFP period register
+ */
+#define AR5K_CFP_PERIOD_5210   0x8028
+#define AR5K_CFP_PERIOD_5211   0x8024
+#define AR5K_CFP_PERIOD                (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_CFP_PERIOD_5210 : AR5K_CFP_PERIOD_5211)
+
+/*
+ * Next beacon time register
+ */
+#define AR5K_TIMER0_5210       0x802c
+#define AR5K_TIMER0_5211       0x8028
+#define AR5K_TIMER0            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TIMER0_5210 : AR5K_TIMER0_5211)
+
+/*
+ * Next DMA beacon alert register
+ */
+#define AR5K_TIMER1_5210       0x8030
+#define AR5K_TIMER1_5211       0x802c
+#define AR5K_TIMER1            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TIMER1_5210 : AR5K_TIMER1_5211)
+
+/*
+ * Next software beacon alert register
+ */
+#define AR5K_TIMER2_5210       0x8034
+#define AR5K_TIMER2_5211       0x8030
+#define AR5K_TIMER2            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TIMER2_5210 : AR5K_TIMER2_5211)
+
+/*
+ * Next ATIM window time register
+ */
+#define AR5K_TIMER3_5210       0x8038
+#define AR5K_TIMER3_5211       0x8034
+#define AR5K_TIMER3            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TIMER3_5210 : AR5K_TIMER3_5211)
+
+
+/*
+ * 5210 First inter frame spacing register (IFS)
+ */
+#define AR5K_IFS0              0x8040
+#define AR5K_IFS0_SIFS         0x000007ff
+#define AR5K_IFS0_SIFS_S       0
+#define AR5K_IFS0_DIFS         0x007ff800
+#define AR5K_IFS0_DIFS_S       11
+
+/*
+ * 5210 Second inter frame spacing register (IFS)
+ */
+#define AR5K_IFS1              0x8044
+#define AR5K_IFS1_PIFS         0x00000fff
+#define AR5K_IFS1_PIFS_S       0
+#define AR5K_IFS1_EIFS         0x03fff000
+#define AR5K_IFS1_EIFS_S       12
+#define AR5K_IFS1_CS_EN                0x04000000
+
+
+/*
+ * CFP duration register
+ */
+#define AR5K_CFP_DUR_5210      0x8048
+#define AR5K_CFP_DUR_5211      0x8038
+#define AR5K_CFP_DUR           (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_CFP_DUR_5210 : AR5K_CFP_DUR_5211)
+
+/*
+ * Receive filter register
+ */
+#define AR5K_RX_FILTER_5210    0x804c                  /* Register Address [5210] */
+#define AR5K_RX_FILTER_5211    0x803c                  /* Register Address [5211+] */
+#define AR5K_RX_FILTER         (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211)
+#define        AR5K_RX_FILTER_UCAST    0x00000001      /* Don't filter unicast frames */
+#define        AR5K_RX_FILTER_MCAST    0x00000002      /* Don't filter multicast frames */
+#define        AR5K_RX_FILTER_BCAST    0x00000004      /* Don't filter broadcast frames */
+#define        AR5K_RX_FILTER_CONTROL  0x00000008      /* Don't filter control frames */
+#define        AR5K_RX_FILTER_BEACON   0x00000010      /* Don't filter beacon frames */
+#define        AR5K_RX_FILTER_PROM     0x00000020      /* Set promiscuous mode */
+#define        AR5K_RX_FILTER_XRPOLL   0x00000040      /* Don't filter XR poll frame [5212+] */
+#define        AR5K_RX_FILTER_PROBEREQ 0x00000080      /* Don't filter probe requests [5212+] */
+#define        AR5K_RX_FILTER_PHYERR_5212      0x00000100      /* Don't filter phy errors [5212+] */
+#define        AR5K_RX_FILTER_RADARERR_5212    0x00000200      /* Don't filter phy radar errors [5212+] */
+#define AR5K_RX_FILTER_PHYERR_5211     0x00000040      /* [5211] */
+#define AR5K_RX_FILTER_RADARERR_5211   0x00000080      /* [5211] */
+#define AR5K_RX_FILTER_PHYERR  \
+       ((ah->ah_version == AR5K_AR5211 ? \
+       AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212))
+#define        AR5K_RX_FILTER_RADARERR \
+       ((ah->ah_version == AR5K_AR5211 ? \
+       AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212))
+
+/*
+ * Multicast filter register (lower 32 bits)
+ */
+#define AR5K_MCAST_FILTER0_5210        0x8050
+#define AR5K_MCAST_FILTER0_5211        0x8040
+#define AR5K_MCAST_FILTER0     (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_MCAST_FILTER0_5210 : AR5K_MCAST_FILTER0_5211)
+
+/*
+ * Multicast filter register (higher 16 bits)
+ */
+#define AR5K_MCAST_FILTER1_5210        0x8054
+#define AR5K_MCAST_FILTER1_5211        0x8044
+#define AR5K_MCAST_FILTER1     (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_MCAST_FILTER1_5210 : AR5K_MCAST_FILTER1_5211)
+
+
+/*
+ * Transmit mask register (lower 32 bits) [5210]
+ */
+#define AR5K_TX_MASK0  0x8058
+
+/*
+ * Transmit mask register (higher 16 bits) [5210]
+ */
+#define AR5K_TX_MASK1  0x805c
+
+/*
+ * Clear transmit mask [5210]
+ */
+#define AR5K_CLR_TMASK 0x8060
+
+/*
+ * Trigger level register (before transmission) [5210]
+ */
+#define AR5K_TRIG_LVL  0x8064
+
+
+/*
+ * PCU control register
+ *
+ * Only DIS_RX is used in the code, the rest i guess are
+ * for tweaking/diagnostics.
+ */
+#define AR5K_DIAG_SW_5210              0x8068                  /* Register Address [5210] */
+#define AR5K_DIAG_SW_5211              0x8048                  /* Register Address [5211+] */
+#define AR5K_DIAG_SW                   (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_5210 : AR5K_DIAG_SW_5211)
+#define AR5K_DIAG_SW_DIS_WEP_ACK       0x00000001      /* Disable ACKs if WEP key is invalid */
+#define AR5K_DIAG_SW_DIS_ACK           0x00000002      /* Disable ACKs */
+#define AR5K_DIAG_SW_DIS_CTS           0x00000004      /* Disable CTSs */
+#define AR5K_DIAG_SW_DIS_ENC           0x00000008      /* Disable encryption */
+#define AR5K_DIAG_SW_DIS_DEC           0x00000010      /* Disable decryption */
+#define AR5K_DIAG_SW_DIS_TX            0x00000020      /* Disable transmit [5210] */
+#define AR5K_DIAG_SW_DIS_RX_5210       0x00000040      /* Disable recieve */
+#define AR5K_DIAG_SW_DIS_RX_5211       0x00000020
+#define        AR5K_DIAG_SW_DIS_RX             (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211)
+#define AR5K_DIAG_SW_LOOP_BACK_5210    0x00000080      /* Loopback (i guess it goes with DIS_TX) [5210] */
+#define AR5K_DIAG_SW_LOOP_BACK_5211    0x00000040
+#define AR5K_DIAG_SW_LOOP_BACK         (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211)
+#define AR5K_DIAG_SW_CORR_FCS_5210     0x00000100      /* Corrupted FCS */
+#define AR5K_DIAG_SW_CORR_FCS_5211     0x00000080
+#define AR5K_DIAG_SW_CORR_FCS          (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211)
+#define AR5K_DIAG_SW_CHAN_INFO_5210    0x00000200      /* Dump channel info */
+#define AR5K_DIAG_SW_CHAN_INFO_5211    0x00000100
+#define AR5K_DIAG_SW_CHAN_INFO         (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211)
+#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210        0x00000400      /* Enable fixed scrambler seed */
+#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211        0x00000200
+#define AR5K_DIAG_SW_EN_SCRAM_SEED     (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211)
+#define AR5K_DIAG_SW_ECO_ENABLE                0x00000400      /* [5211+] */
+#define AR5K_DIAG_SW_SCVRAM_SEED       0x0003f800      /* [5210] */
+#define AR5K_DIAG_SW_SCRAM_SEED_M      0x0001fc00      /* Scrambler seed mask */
+#define AR5K_DIAG_SW_SCRAM_SEED_S      10
+#define AR5K_DIAG_SW_DIS_SEQ_INC       0x00040000      /* Disable seqnum increment (?)[5210] */
+#define AR5K_DIAG_SW_FRAME_NV0_5210    0x00080000
+#define AR5K_DIAG_SW_FRAME_NV0_5211    0x00020000      /* Accept frames of non-zero protocol number */
+#define        AR5K_DIAG_SW_FRAME_NV0          (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211)
+#define AR5K_DIAG_SW_OBSPT_M           0x000c0000      /* Observation point select (?) */
+#define AR5K_DIAG_SW_OBSPT_S           18
+#define AR5K_DIAG_SW_RX_CLEAR_HIGH     0x0010000       /* Force RX Clear high */
+#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000       /* Ignore virtual carrier sense */
+#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH  0x0040000       /* Force channel idle high */
+#define AR5K_DIAG_SW_PHEAR_ME          0x0080000       /* ??? */
+
+/*
+ * TSF (clock) register (lower 32 bits)
+ */
+#define AR5K_TSF_L32_5210      0x806c
+#define AR5K_TSF_L32_5211      0x804c
+#define        AR5K_TSF_L32            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
+
+/*
+ * TSF (clock) register (higher 32 bits)
+ */
+#define AR5K_TSF_U32_5210      0x8070
+#define AR5K_TSF_U32_5211      0x8050
+#define        AR5K_TSF_U32            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
+
+/*
+ * Last beacon timestamp register (Read Only)
+ */
+#define AR5K_LAST_TSTP 0x8080
+
+/*
+ * ADDAC test register [5211+]
+ */
+#define AR5K_ADDAC_TEST                        0x8054                  /* Register Address */
+#define AR5K_ADDAC_TEST_TXCONT                 0x00000001      /* Test continuous tx */
+#define AR5K_ADDAC_TEST_TST_MODE       0x00000002      /* Test mode */
+#define AR5K_ADDAC_TEST_LOOP_EN                0x00000004      /* Enable loop */
+#define AR5K_ADDAC_TEST_LOOP_LEN       0x00000008      /* Loop length (field) */
+#define AR5K_ADDAC_TEST_USE_U8         0x00004000      /* Use upper 8 bits */
+#define AR5K_ADDAC_TEST_MSB            0x00008000      /* State of MSB */
+#define AR5K_ADDAC_TEST_TRIG_SEL       0x00010000      /* Trigger select */
+#define AR5K_ADDAC_TEST_TRIG_PTY       0x00020000      /* Trigger polarity */
+#define AR5K_ADDAC_TEST_RXCONT         0x00040000      /* Continuous capture */
+#define AR5K_ADDAC_TEST_CAPTURE                0x00080000      /* Begin capture */
+#define AR5K_ADDAC_TEST_TST_ARM                0x00100000      /* ARM rx buffer for capture */
+
+/*
+ * Default antenna register [5211+]
+ */
+#define AR5K_DEFAULT_ANTENNA   0x8058
+
+/*
+ * Frame control QoS mask register (?) [5211+]
+ * (FC_QOS_MASK)
+ */
+#define AR5K_FRAME_CTL_QOSM    0x805c
+
+/*
+ * Seq mask register (?) [5211+]
+ */
+#define AR5K_SEQ_MASK  0x8060
+
+/*
+ * Retry count register [5210]
+ */
+#define AR5K_RETRY_CNT         0x8084                  /* Register Address [5210] */
+#define AR5K_RETRY_CNT_SSH     0x0000003f      /* Station short retry count (?) */
+#define AR5K_RETRY_CNT_SLG     0x00000fc0      /* Station long retry count (?) */
+
+/*
+ * Back-off status register [5210]
+ */
+#define AR5K_BACKOFF           0x8088                  /* Register Address [5210] */
+#define AR5K_BACKOFF_CW                0x000003ff      /* Backoff Contention Window (?) */
+#define AR5K_BACKOFF_CNT       0x03ff0000      /* Backoff count (?) */
+
+
+
+/*
+ * NAV register (current)
+ */
+#define AR5K_NAV_5210          0x808c
+#define AR5K_NAV_5211          0x8084
+#define        AR5K_NAV                (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_NAV_5210 : AR5K_NAV_5211)
+
+/*
+ * RTS success register
+ */
+#define AR5K_RTS_OK_5210       0x8090
+#define AR5K_RTS_OK_5211       0x8088
+#define        AR5K_RTS_OK             (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211)
+
+/*
+ * RTS failure register
+ */
+#define AR5K_RTS_FAIL_5210     0x8094
+#define AR5K_RTS_FAIL_5211     0x808c
+#define        AR5K_RTS_FAIL           (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211)
+
+/*
+ * ACK failure register
+ */
+#define AR5K_ACK_FAIL_5210     0x8098
+#define AR5K_ACK_FAIL_5211     0x8090
+#define        AR5K_ACK_FAIL           (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211)
+
+/*
+ * FCS failure register
+ */
+#define AR5K_FCS_FAIL_5210     0x809c
+#define AR5K_FCS_FAIL_5211     0x8094
+#define        AR5K_FCS_FAIL           (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_FCS_FAIL_5210 : AR5K_FCS_FAIL_5211)
+
+/*
+ * Beacon count register
+ */
+#define AR5K_BEACON_CNT_5210   0x80a0
+#define AR5K_BEACON_CNT_5211   0x8098
+#define        AR5K_BEACON_CNT         (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_BEACON_CNT_5210 : AR5K_BEACON_CNT_5211)
+
+
+/*===5212 Specific PCU registers===*/
+
+/*
+ * Transmit power control register
+ */
+#define AR5K_TPC                       0x80e8
+#define AR5K_TPC_ACK                   0x0000003f      /* ack frames */
+#define AR5K_TPC_ACK_S                 0
+#define AR5K_TPC_CTS                   0x00003f00      /* cts frames */
+#define AR5K_TPC_CTS_S                 8
+#define AR5K_TPC_CHIRP                 0x003f0000      /* chirp frames */
+#define AR5K_TPC_CHIRP_S               16
+#define AR5K_TPC_DOPPLER               0x0f000000      /* doppler chirp span */
+#define AR5K_TPC_DOPPLER_S             24
+
+/*
+ * XR (eXtended Range) mode register
+ */
+#define AR5K_XRMODE                    0x80c0                  /* Register Address */
+#define        AR5K_XRMODE_POLL_TYPE_M         0x0000003f      /* Mask for Poll type (?) */
+#define        AR5K_XRMODE_POLL_TYPE_S         0
+#define        AR5K_XRMODE_POLL_SUBTYPE_M      0x0000003c      /* Mask for Poll subtype (?) */
+#define        AR5K_XRMODE_POLL_SUBTYPE_S      2
+#define        AR5K_XRMODE_POLL_WAIT_ALL       0x00000080      /* Wait for poll */
+#define        AR5K_XRMODE_SIFS_DELAY          0x000fff00      /* Mask for SIFS delay */
+#define        AR5K_XRMODE_FRAME_HOLD_M        0xfff00000      /* Mask for frame hold (?) */
+#define        AR5K_XRMODE_FRAME_HOLD_S        20
+
+/*
+ * XR delay register
+ */
+#define AR5K_XRDELAY                   0x80c4                  /* Register Address */
+#define AR5K_XRDELAY_SLOT_DELAY_M      0x0000ffff      /* Mask for slot delay */
+#define AR5K_XRDELAY_SLOT_DELAY_S      0
+#define AR5K_XRDELAY_CHIRP_DELAY_M     0xffff0000      /* Mask for CHIRP data delay */
+#define AR5K_XRDELAY_CHIRP_DELAY_S     16
+
+/*
+ * XR timeout register
+ */
+#define AR5K_XRTIMEOUT                 0x80c8                  /* Register Address */
+#define AR5K_XRTIMEOUT_CHIRP_M         0x0000ffff      /* Mask for CHIRP timeout */
+#define AR5K_XRTIMEOUT_CHIRP_S         0
+#define AR5K_XRTIMEOUT_POLL_M          0xffff0000      /* Mask for Poll timeout */
+#define AR5K_XRTIMEOUT_POLL_S          16
+
+/*
+ * XR chirp register
+ */
+#define AR5K_XRCHIRP                   0x80cc                  /* Register Address */
+#define AR5K_XRCHIRP_SEND              0x00000001      /* Send CHIRP */
+#define AR5K_XRCHIRP_GAP               0xffff0000      /* Mask for CHIRP gap (?) */
+
+/*
+ * XR stomp register
+ */
+#define AR5K_XRSTOMP                   0x80d0                  /* Register Address */
+#define AR5K_XRSTOMP_TX                        0x00000001      /* Stomp Tx (?) */
+#define AR5K_XRSTOMP_RX                        0x00000002      /* Stomp Rx (?) */
+#define AR5K_XRSTOMP_TX_RSSI           0x00000004      /* Stomp Tx RSSI (?) */
+#define AR5K_XRSTOMP_TX_BSSID          0x00000008      /* Stomp Tx BSSID (?) */
+#define AR5K_XRSTOMP_DATA              0x00000010      /* Stomp data (?)*/
+#define AR5K_XRSTOMP_RSSI_THRES                0x0000ff00      /* Mask for XR RSSI threshold */
+
+/*
+ * First enhanced sleep register
+ */
+#define AR5K_SLEEP0                    0x80d4                  /* Register Address */
+#define AR5K_SLEEP0_NEXT_DTIM          0x0007ffff      /* Mask for next DTIM (?) */
+#define AR5K_SLEEP0_NEXT_DTIM_S                0
+#define AR5K_SLEEP0_ASSUME_DTIM                0x00080000      /* Assume DTIM */
+#define AR5K_SLEEP0_ENH_SLEEP_EN       0x00100000      /* Enable enchanced sleep control */
+#define AR5K_SLEEP0_CABTO              0xff000000      /* Mask for CAB Time Out */
+#define AR5K_SLEEP0_CABTO_S            24
+
+/*
+ * Second enhanced sleep register
+ */
+#define AR5K_SLEEP1                    0x80d8                  /* Register Address */
+#define AR5K_SLEEP1_NEXT_TIM           0x0007ffff      /* Mask for next TIM (?) */
+#define AR5K_SLEEP1_NEXT_TIM_S         0
+#define AR5K_SLEEP1_BEACON_TO          0xff000000      /* Mask for Beacon Time Out */
+#define AR5K_SLEEP1_BEACON_TO_S                24
+
+/*
+ * Third enhanced sleep register
+ */
+#define AR5K_SLEEP2                    0x80dc                  /* Register Address */
+#define AR5K_SLEEP2_TIM_PER            0x0000ffff      /* Mask for TIM period (?) */
+#define AR5K_SLEEP2_TIM_PER_S          0
+#define AR5K_SLEEP2_DTIM_PER           0xffff0000      /* Mask for DTIM period (?) */
+#define AR5K_SLEEP2_DTIM_PER_S         16
+
+/*
+ * BSSID mask registers
+ */
+#define AR5K_BSS_IDM0                  0x80e0  /* Upper bits */
+#define AR5K_BSS_IDM1                  0x80e4  /* Lower bits */
+
+/*
+ * TX power control (TPC) register
+ *
+ * XXX: PCDAC steps (0.5dbm) or DBM ?
+ *
+ */
+#define AR5K_TXPC                      0x80e8                  /* Register Address */
+#define AR5K_TXPC_ACK_M                        0x0000003f      /* ACK tx power */
+#define AR5K_TXPC_ACK_S                        0
+#define AR5K_TXPC_CTS_M                        0x00003f00      /* CTS tx power */
+#define AR5K_TXPC_CTS_S                        8
+#define AR5K_TXPC_CHIRP_M              0x003f0000      /* CHIRP tx power */
+#define AR5K_TXPC_CHIRP_S              16
+#define AR5K_TXPC_DOPPLER              0x0f000000      /* Doppler chirp span (?) */
+#define AR5K_TXPC_DOPPLER_S            24
+
+/*
+ * Profile count registers
+ */
+#define AR5K_PROFCNT_TX                        0x80ec  /* Tx count */
+#define AR5K_PROFCNT_RX                        0x80f0  /* Rx count */
+#define AR5K_PROFCNT_RXCLR             0x80f4  /* Clear Rx count */
+#define AR5K_PROFCNT_CYCLE             0x80f8  /* Cycle count (?) */
+
+/*
+ * Quiet period control registers
+ */
+#define AR5K_QUIET_CTL1                        0x80fc                  /* Register Address */
+#define AR5K_QUIET_CTL1_NEXT_QT_TSF    0x0000ffff      /* Next quiet period TSF (TU) */
+#define AR5K_QUIET_CTL1_NEXT_QT_TSF_S  0
+#define AR5K_QUIET_CTL1_QT_EN          0x00010000      /* Enable quiet period */
+#define AR5K_QUIET_CTL1_ACK_CTS_EN     0x00020000      /* Send ACK/CTS during quiet period */
+
+#define AR5K_QUIET_CTL2                        0x8100                  /* Register Address */
+#define AR5K_QUIET_CTL2_QT_PER         0x0000ffff      /* Mask for quiet period periodicity */
+#define AR5K_QUIET_CTL2_QT_PER_S       0
+#define AR5K_QUIET_CTL2_QT_DUR         0xffff0000      /* Mask for quiet period duration */
+#define AR5K_QUIET_CTL2_QT_DUR_S       16
+
+/*
+ * TSF parameter register
+ */
+#define AR5K_TSF_PARM                  0x8104                  /* Register Address */
+#define AR5K_TSF_PARM_INC              0x000000ff      /* Mask for TSF increment */
+#define AR5K_TSF_PARM_INC_S            0
+
+/*
+ * QoS NOACK policy
+ */
+#define AR5K_QOS_NOACK                 0x8108                  /* Register Address */
+#define AR5K_QOS_NOACK_2BIT_VALUES     0x0000000f      /* ??? */
+#define AR5K_QOS_NOACK_2BIT_VALUES_S   0
+#define AR5K_QOS_NOACK_BIT_OFFSET      0x00000070      /* ??? */
+#define AR5K_QOS_NOACK_BIT_OFFSET_S    4
+#define AR5K_QOS_NOACK_BYTE_OFFSET     0x00000180      /* ??? */
+#define AR5K_QOS_NOACK_BYTE_OFFSET_S   7
+
+/*
+ * PHY error filter register
+ */
+#define AR5K_PHY_ERR_FIL               0x810c
+#define AR5K_PHY_ERR_FIL_RADAR         0x00000020      /* Radar signal */
+#define AR5K_PHY_ERR_FIL_OFDM          0x00020000      /* OFDM false detect (ANI) */
+#define AR5K_PHY_ERR_FIL_CCK           0x02000000      /* CCK false detect (ANI) */
+
+/*
+ * XR latency register
+ */
+#define AR5K_XRLAT_TX          0x8110
+
+/*
+ * ACK SIFS register
+ */
+#define AR5K_ACKSIFS           0x8114                  /* Register Address */
+#define AR5K_ACKSIFS_INC       0x00000000      /* ACK SIFS Increment (field) */
+
+/*
+ * MIC QoS control register (?)
+ */
+#define        AR5K_MIC_QOS_CTL                0x8118                  /* Register Address */
+#define        AR5K_MIC_QOS_CTL_OFF(_n)        (1 << (_n * 2))
+#define        AR5K_MIC_QOS_CTL_MQ_EN          0x00010000      /* Enable MIC QoS */
+
+/*
+ * MIC QoS select register (?)
+ */
+#define        AR5K_MIC_QOS_SEL                0x811c
+#define        AR5K_MIC_QOS_SEL_OFF(_n)        (1 << (_n * 4))
+
+/*
+ * Misc mode control register (?)
+ */
+#define        AR5K_MISC_MODE                  0x8120                  /* Register Address */
+#define        AR5K_MISC_MODE_FBSSID_MATCH     0x00000001      /* Force BSSID match */
+#define        AR5K_MISC_MODE_ACKSIFS_MEM      0x00000002      /* ACK SIFS memory (?) */
+#define        AR5K_MISC_MODE_COMBINED_MIC     0x00000004      /* use rx/tx MIC key */
+/* more bits */
+
+/*
+ * OFDM Filter counter
+ */
+#define        AR5K_OFDM_FIL_CNT               0x8124
+
+/*
+ * CCK Filter counter
+ */
+#define        AR5K_CCK_FIL_CNT                0x8128
+
+/*
+ * PHY Error Counters (?)
+ */
+#define        AR5K_PHYERR_CNT1                0x812c
+#define        AR5K_PHYERR_CNT1_MASK           0x8130
+
+#define        AR5K_PHYERR_CNT2                0x8134
+#define        AR5K_PHYERR_CNT2_MASK           0x8138
+
+/*
+ * TSF Threshold register (?)
+ */
+#define        AR5K_TSF_THRES                  0x813c
+
+/*
+ * TODO: Wake On Wireless registers
+ * Range: 0x8147 - 0x818c
+ */
+
+/*
+ * Rate -> ACK SIFS mapping table (32 entries)
+ */
+#define        AR5K_RATE_ACKSIFS_BASE          0x8680                  /* Register Address */
+#define        AR5K_RATE_ACKSIFS(_n)           (AR5K_RATE_ACKSIFS_BSE + ((_n) << 2))
+#define        AR5K_RATE_ACKSIFS_NORMAL        0x00000001      /* Normal SIFS (field) */
+#define        AR5K_RATE_ACKSIFS_TURBO         0x00000400      /* Turbo SIFS (field) */
+
+/*
+ * Rate -> duration mapping table (32 entries)
+ */
+#define AR5K_RATE_DUR_BASE             0x8700
+#define AR5K_RATE_DUR(_n)              (AR5K_RATE_DUR_BASE + ((_n) << 2))
+
+/*
+ * Rate -> db mapping table
+ * (8 entries, each one has 4 8bit fields)
+ */
+#define AR5K_RATE2DB_BASE              0x87c0
+#define AR5K_RATE2DB(_n)               (AR5K_RATE2DB_BASE + ((_n) << 2))
+
+/*
+ * db -> Rate mapping table
+ * (8 entries, each one has 4 8bit fields)
+ */
+#define AR5K_DB2RATE_BASE              0x87e0
+#define AR5K_DB2RATE(_n)               (AR5K_DB2RATE_BASE + ((_n) << 2))
+
+/*===5212 end===*/
+
+/*
+ * Key table (WEP) register
+ */
+#define AR5K_KEYTABLE_0_5210           0x9000
+#define AR5K_KEYTABLE_0_5211           0x8800
+#define AR5K_KEYTABLE_5210(_n)         (AR5K_KEYTABLE_0_5210 + ((_n) << 5))
+#define AR5K_KEYTABLE_5211(_n)         (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
+#define        AR5K_KEYTABLE(_n)               (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n))
+#define AR5K_KEYTABLE_OFF(_n, x)       (AR5K_KEYTABLE(_n) + (x << 2))
+#define AR5K_KEYTABLE_TYPE(_n)         AR5K_KEYTABLE_OFF(_n, 5)
+#define AR5K_KEYTABLE_TYPE_40          0x00000000
+#define AR5K_KEYTABLE_TYPE_104         0x00000001
+#define AR5K_KEYTABLE_TYPE_128         0x00000003
+#define AR5K_KEYTABLE_TYPE_TKIP                0x00000004      /* [5212+] */
+#define AR5K_KEYTABLE_TYPE_AES         0x00000005      /* [5211+] */
+#define AR5K_KEYTABLE_TYPE_CCM         0x00000006      /* [5212+] */
+#define AR5K_KEYTABLE_TYPE_NULL                0x00000007      /* [5211+] */
+#define AR5K_KEYTABLE_ANTENNA          0x00000008      /* [5212+] */
+#define AR5K_KEYTABLE_MAC0(_n)         AR5K_KEYTABLE_OFF(_n, 6)
+#define AR5K_KEYTABLE_MAC1(_n)         AR5K_KEYTABLE_OFF(_n, 7)
+#define AR5K_KEYTABLE_VALID            0x00008000
+
+/* If key type is TKIP and MIC is enabled
+ * MIC key goes in offset entry + 64 */
+#define        AR5K_KEYTABLE_MIC_OFFSET        64
+
+/* WEP 40-bit  = 40-bit  entered key + 24 bit IV = 64-bit
+ * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit
+ * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit
+ *
+ * Some vendors have introduced bigger WEP keys to address
+ * security vulnerabilities in WEP. This includes:
+ *
+ * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit
+ *
+ * We can expand this if we find ar5k Atheros cards with a larger
+ * key table size.
+ */
+#define AR5K_KEYTABLE_SIZE_5210                64
+#define AR5K_KEYTABLE_SIZE_5211                128
+#define        AR5K_KEYTABLE_SIZE              (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211)
+
+
+/*===PHY REGISTERS===*/
+
+/*
+ * PHY registers start
+ */
+#define        AR5K_PHY_BASE                   0x9800
+#define        AR5K_PHY(_n)                    (AR5K_PHY_BASE + ((_n) << 2))
+
+/*
+ * TST_2 (Misc config parameters)
+ */
+#define        AR5K_PHY_TST2                   0x9800                  /* Register Address */
+#define AR5K_PHY_TST2_TRIG_SEL         0x00000007      /* Trigger select (?)*/
+#define AR5K_PHY_TST2_TRIG             0x00000010      /* Trigger (?) */
+#define AR5K_PHY_TST2_CBUS_MODE                0x00000060      /* Cardbus mode (?) */
+#define AR5K_PHY_TST2_CLK32            0x00000400      /* CLK_OUT is CLK32 (32Khz external) */
+#define AR5K_PHY_TST2_CHANCOR_DUMP_EN  0x00000800      /* Enable Chancor dump (?) */
+#define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP        0x00001000      /* Even Chancor dump (?) */
+#define AR5K_PHY_TST2_RFSILENT_EN      0x00002000      /* Enable RFSILENT */
+#define AR5K_PHY_TST2_ALT_RFDATA       0x00004000      /* Alternate RFDATA (5-2GHz switch ?) */
+#define AR5K_PHY_TST2_MINI_OBS_EN      0x00008000      /* Enable mini OBS (?) */
+#define AR5K_PHY_TST2_RX2_IS_RX5_INV   0x00010000      /* 2GHz rx path is the 5GHz path inverted (?) */
+#define AR5K_PHY_TST2_SLOW_CLK160      0x00020000      /* Slow CLK160 (?) */
+#define AR5K_PHY_TST2_AGC_OBS_SEL_3    0x00040000      /* AGC OBS Select 3 (?) */
+#define AR5K_PHY_TST2_BBB_OBS_SEL      0x00080000      /* BB OBS Select (field ?) */
+#define AR5K_PHY_TST2_ADC_OBS_SEL      0x00800000      /* ADC OBS Select (field ?) */
+#define AR5K_PHY_TST2_RX_CLR_SEL       0x08000000      /* RX Clear Select (?) */
+#define AR5K_PHY_TST2_FORCE_AGC_CLR    0x10000000      /* Force AGC clear (?) */
+#define AR5K_PHY_SHIFT_2GHZ            0x00004007      /* Used to access 2GHz radios */
+#define AR5K_PHY_SHIFT_5GHZ            0x00000007      /* Used to access 5GHz radios (default) */
+
+/*
+ * PHY frame control register [5110] /turbo mode register [5111+]
+ *
+ * There is another frame control register for [5111+]
+ * at address 0x9944 (see below) but the 2 first flags
+ * are common here between 5110 frame control register
+ * and [5111+] turbo mode register, so this also works as
+ * a "turbo mode register" for 5110. We treat this one as
+ * a frame control register for 5110 below.
+ */
+#define        AR5K_PHY_TURBO                  0x9804                  /* Register Address */
+#define        AR5K_PHY_TURBO_MODE             0x00000001      /* Enable turbo mode */
+#define        AR5K_PHY_TURBO_SHORT            0x00000002      /* Set short symbols to turbo mode */
+#define        AR5K_PHY_TURBO_MIMO             0x00000004      /* Set turbo for mimo mimo */
+
+/*
+ * PHY agility command register
+ * (aka TST_1)
+ */
+#define        AR5K_PHY_AGC                    0x9808                  /* Register Address */
+#define        AR5K_PHY_TST1                   0x9808
+#define        AR5K_PHY_AGC_DISABLE            0x08000000      /* Disable AGC to A2 (?)*/
+#define        AR5K_PHY_TST1_TXHOLD            0x00003800      /* Set tx hold (?) */
+#define        AR5K_PHY_TST1_TXSRC_SRC         0x00000002      /* Used with bit 7 (?) */
+#define        AR5K_PHY_TST1_TXSRC_SRC_S       1
+#define        AR5K_PHY_TST1_TXSRC_ALT         0x00000080      /* Set input to tsdac (?) */
+#define        AR5K_PHY_TST1_TXSRC_ALT_S       7
+
+
+/*
+ * PHY timing register 3 [5112+]
+ */
+#define        AR5K_PHY_TIMING_3               0x9814
+#define        AR5K_PHY_TIMING_3_DSC_MAN       0xfffe0000
+#define        AR5K_PHY_TIMING_3_DSC_MAN_S     17
+#define        AR5K_PHY_TIMING_3_DSC_EXP       0x0001e000
+#define        AR5K_PHY_TIMING_3_DSC_EXP_S     13
+
+/*
+ * PHY chip revision register
+ */
+#define        AR5K_PHY_CHIP_ID                0x9818
+
+/*
+ * PHY activation register
+ */
+#define        AR5K_PHY_ACT                    0x981c                  /* Register Address */
+#define        AR5K_PHY_ACT_ENABLE             0x00000001      /* Activate PHY */
+#define        AR5K_PHY_ACT_DISABLE            0x00000002      /* Deactivate PHY */
+
+/*
+ * PHY RF control registers
+ */
+#define AR5K_PHY_RF_CTL2               0x9824                  /* Register Address */
+#define        AR5K_PHY_RF_CTL2_TXF2TXD_START  0x0000000f      /* TX frame to TX data start */
+#define        AR5K_PHY_RF_CTL2_TXF2TXD_START_S        0
+
+#define AR5K_PHY_RF_CTL3               0x9828                  /* Register Address */
+#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON   0x0000ff00      /* TX end to XLNA on */
+#define        AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S  8
+
+#define        AR5K_PHY_ADC_CTL                        0x982c
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF          0x00000003
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S        0
+#define        AR5K_PHY_ADC_CTL_PWD_DAC_OFF            0x00002000
+#define        AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF       0x00004000
+#define        AR5K_PHY_ADC_CTL_PWD_ADC_OFF            0x00008000
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON           0x00030000
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S         16
+
+#define AR5K_PHY_RF_CTL4               0x9834                  /* Register Address */
+#define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON  0x00000001      /* TX frame to XPA A on (field) */
+#define AR5K_PHY_RF_CTL4_TXF2XPA_B_ON  0x00000100      /* TX frame to XPA B on (field) */
+#define        AR5K_PHY_RF_CTL4_TXE2XPA_A_OFF  0x00010000      /* TX end to XPA A off (field) */
+#define AR5K_PHY_RF_CTL4_TXE2XPA_B_OFF 0x01000000      /* TX end to XPA B off (field) */
+
+/*
+ * Pre-Amplifier control register
+ * (XPA -> external pre-amplifier)
+ */
+#define        AR5K_PHY_PA_CTL                 0x9838                  /* Register Address */
+#define        AR5K_PHY_PA_CTL_XPA_A_HI        0x00000001      /* XPA A high (?) */
+#define        AR5K_PHY_PA_CTL_XPA_B_HI        0x00000002      /* XPA B high (?) */
+#define        AR5K_PHY_PA_CTL_XPA_A_EN        0x00000004      /* Enable XPA A */
+#define        AR5K_PHY_PA_CTL_XPA_B_EN        0x00000008      /* Enable XPA B */
+
+/*
+ * PHY settling register
+ */
+#define AR5K_PHY_SETTLING              0x9844                  /* Register Address */
+#define        AR5K_PHY_SETTLING_AGC           0x0000007f      /* AGC settling time */
+#define        AR5K_PHY_SETTLING_AGC_S         0
+#define        AR5K_PHY_SETTLING_SWITCH        0x00003f80      /* Switch settlig time */
+#define        AR5K_PHY_SETTLING_SWITCH_S      7
+
+/*
+ * PHY Gain registers
+ */
+#define AR5K_PHY_GAIN                  0x9848                  /* Register Address */
+#define        AR5K_PHY_GAIN_TXRX_ATTEN        0x0003f000      /* TX-RX Attenuation */
+#define        AR5K_PHY_GAIN_TXRX_ATTEN_S      12
+#define        AR5K_PHY_GAIN_TXRX_RF_MAX       0x007c0000
+#define        AR5K_PHY_GAIN_TXRX_RF_MAX_S     18
+
+#define        AR5K_PHY_GAIN_OFFSET            0x984c                  /* Register Address */
+#define        AR5K_PHY_GAIN_OFFSET_RXTX_FLAG  0x00020000      /* RX-TX flag (?) */
+
+/*
+ * Desired ADC/PGA size register
+ * (for more infos read ANI patent)
+ */
+#define AR5K_PHY_DESIRED_SIZE          0x9850                  /* Register Address */
+#define        AR5K_PHY_DESIRED_SIZE_ADC       0x000000ff      /* ADC desired size */
+#define        AR5K_PHY_DESIRED_SIZE_ADC_S     0
+#define        AR5K_PHY_DESIRED_SIZE_PGA       0x0000ff00      /* PGA desired size */
+#define        AR5K_PHY_DESIRED_SIZE_PGA_S     8
+#define        AR5K_PHY_DESIRED_SIZE_TOT       0x0ff00000      /* Total desired size */
+#define        AR5K_PHY_DESIRED_SIZE_TOT_S     20
+
+/*
+ * PHY signal register
+ * (for more infos read ANI patent)
+ */
+#define        AR5K_PHY_SIG                    0x9858                  /* Register Address */
+#define        AR5K_PHY_SIG_FIRSTEP            0x0003f000      /* FIRSTEP */
+#define        AR5K_PHY_SIG_FIRSTEP_S          12
+#define        AR5K_PHY_SIG_FIRPWR             0x03fc0000      /* FIPWR */
+#define        AR5K_PHY_SIG_FIRPWR_S           18
+
+/*
+ * PHY coarse agility control register
+ * (for more infos read ANI patent)
+ */
+#define        AR5K_PHY_AGCCOARSE              0x985c                  /* Register Address */
+#define        AR5K_PHY_AGCCOARSE_LO           0x00007f80      /* AGC Coarse low */
+#define        AR5K_PHY_AGCCOARSE_LO_S         7
+#define        AR5K_PHY_AGCCOARSE_HI           0x003f8000      /* AGC Coarse high */
+#define        AR5K_PHY_AGCCOARSE_HI_S         15
+
+/*
+ * PHY agility control register
+ */
+#define        AR5K_PHY_AGCCTL                 0x9860                  /* Register address */
+#define        AR5K_PHY_AGCCTL_CAL             0x00000001      /* Enable PHY calibration */
+#define        AR5K_PHY_AGCCTL_NF              0x00000002      /* Enable Noise Floor calibration */
+#define        AR5K_PHY_AGCCTL_NF_EN           0x00008000      /* Enable nf calibration to happen (?) */
+#define        AR5K_PHY_AGCCTL_NF_NOUPDATE     0x00020000      /* Don't update nf automaticaly */
+
+/*
+ * PHY noise floor status register
+ */
+#define AR5K_PHY_NF                    0x9864                  /* Register address */
+#define AR5K_PHY_NF_M                  0x000001ff      /* Noise floor mask */
+#define AR5K_PHY_NF_ACTIVE             0x00000100      /* Noise floor calibration still active */
+#define AR5K_PHY_NF_RVAL(_n)           (((_n) >> 19) & AR5K_PHY_NF_M)
+#define AR5K_PHY_NF_AVAL(_n)           (-((_n) ^ AR5K_PHY_NF_M) + 1)
+#define AR5K_PHY_NF_SVAL(_n)           (((_n) & AR5K_PHY_NF_M) | (1 << 9))
+#define        AR5K_PHY_NF_THRESH62            0x0007f000      /* Thresh62 -check ANI patent- (field) */
+#define        AR5K_PHY_NF_THRESH62_S          12
+#define        AR5K_PHY_NF_MINCCA_PWR          0x0ff80000      /* ??? */
+#define        AR5K_PHY_NF_MINCCA_PWR_S        19
+
+/*
+ * PHY ADC saturation register [5110]
+ */
+#define        AR5K_PHY_ADCSAT                 0x9868
+#define        AR5K_PHY_ADCSAT_ICNT            0x0001f800
+#define        AR5K_PHY_ADCSAT_ICNT_S          11
+#define        AR5K_PHY_ADCSAT_THR             0x000007e0
+#define        AR5K_PHY_ADCSAT_THR_S           5
+
+/*
+ * PHY Weak ofdm signal detection threshold registers (ANI) [5212+]
+ */
+
+/* High thresholds */
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR            0x9868
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT   0x0000001f
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT_S 0
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1         0x00fe0000
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1_S       17
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2         0x7f000000
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S       24
+
+/* Low thresholds */
+#define AR5K_PHY_WEAK_OFDM_LOW_THR             0x986c
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN  0x00000001
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT    0x00003f00
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S  8
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1          0x001fc000
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1_S                14
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2          0x0fe00000
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_S                21
+
+
+/*
+ * PHY sleep registers [5112+]
+ */
+#define AR5K_PHY_SCR                   0x9870
+
+#define AR5K_PHY_SLMT                  0x9874
+#define AR5K_PHY_SLMT_32MHZ            0x0000007f
+
+#define AR5K_PHY_SCAL                  0x9878
+#define AR5K_PHY_SCAL_32MHZ            0x0000000e
+#define        AR5K_PHY_SCAL_32MHZ_2417        0x0000000a
+#define        AR5K_PHY_SCAL_32MHZ_HB63        0x00000032
+
+/*
+ * PHY PLL (Phase Locked Loop) control register
+ */
+#define        AR5K_PHY_PLL                    0x987c
+#define        AR5K_PHY_PLL_20MHZ              0x00000013      /* For half rate (?) */
+/* 40MHz -> 5GHz band */
+#define        AR5K_PHY_PLL_40MHZ_5211         0x00000018
+#define        AR5K_PHY_PLL_40MHZ_5212         0x000000aa
+#define        AR5K_PHY_PLL_40MHZ_5413         0x00000004
+#define        AR5K_PHY_PLL_40MHZ              (ah->ah_version == AR5K_AR5211 ? \
+                                       AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212)
+/* 44MHz -> 2.4GHz band */
+#define        AR5K_PHY_PLL_44MHZ_5211         0x00000019
+#define        AR5K_PHY_PLL_44MHZ_5212         0x000000ab
+#define        AR5K_PHY_PLL_44MHZ              (ah->ah_version == AR5K_AR5211 ? \
+                                       AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212)
+
+#define AR5K_PHY_PLL_RF5111            0x00000000
+#define AR5K_PHY_PLL_RF5112            0x00000040
+#define        AR5K_PHY_PLL_HALF_RATE          0x00000100
+#define        AR5K_PHY_PLL_QUARTER_RATE       0x00000200
+
+/*
+ * RF Buffer register
+ *
+ * It's obvious from the code that 0x989c is the buffer register but
+ * for the other special registers that we write to after sending each
+ * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
+ * for now. It's interesting that they are also used for some other operations.
+ */
+
+#define AR5K_RF_BUFFER                 0x989c
+#define AR5K_RF_BUFFER_CONTROL_0       0x98c0  /* Channel on 5110 */
+#define AR5K_RF_BUFFER_CONTROL_1       0x98c4  /* Bank 7 on 5112 */
+#define AR5K_RF_BUFFER_CONTROL_2       0x98cc  /* Bank 7 on 5111 */
+
+#define AR5K_RF_BUFFER_CONTROL_3       0x98d0  /* Bank 2 on 5112 */
+                                               /* Channel set on 5111 */
+                                               /* Used to read radio revision*/
+
+#define AR5K_RF_BUFFER_CONTROL_4       0x98d4  /* RF Stage register on 5110 */
+                                               /* Bank 0,1,2,6 on 5111 */
+                                               /* Bank 1 on 5112 */
+                                               /* Used during activation on 5111 */
+
+#define AR5K_RF_BUFFER_CONTROL_5       0x98d8  /* Bank 3 on 5111 */
+                                               /* Used during activation on 5111 */
+                                               /* Channel on 5112 */
+                                               /* Bank 6 on 5112 */
+
+#define AR5K_RF_BUFFER_CONTROL_6       0x98dc  /* Bank 3 on 5112 */
+
+/*
+ * PHY RF stage register [5210]
+ */
+#define AR5K_PHY_RFSTG                 0x98d4
+#define AR5K_PHY_RFSTG_DISABLE         0x00000021
+
+/*
+ * BIN masks (?)
+ */
+#define        AR5K_PHY_BIN_MASK_1     0x9900
+#define        AR5K_PHY_BIN_MASK_2     0x9904
+#define        AR5K_PHY_BIN_MASK_3     0x9908
+
+#define        AR5K_PHY_BIN_MASK_CTL           0x990c
+#define        AR5K_PHY_BIN_MASK_CTL_MASK_4    0x00003fff
+#define        AR5K_PHY_BIN_MASK_CTL_MASK_4_S  0
+#define        AR5K_PHY_BIN_MASK_CTL_RATE      0xff000000
+#define        AR5K_PHY_BIN_MASK_CTL_RATE_S    24
+
+/*
+ * PHY Antenna control register
+ */
+#define AR5K_PHY_ANT_CTL               0x9910                  /* Register Address */
+#define        AR5K_PHY_ANT_CTL_TXRX_EN        0x00000001      /* Enable TX/RX (?) */
+#define        AR5K_PHY_ANT_CTL_SECTORED_ANT   0x00000004      /* Sectored Antenna */
+#define        AR5K_PHY_ANT_CTL_HITUNE5        0x00000008      /* Hitune5 (?) */
+#define        AR5K_PHY_ANT_CTL_SWTABLE_IDLE   0x000003f0      /* Switch table idle (?) */
+#define        AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4
+
+/*
+ * PHY receiver delay register [5111+]
+ */
+#define        AR5K_PHY_RX_DELAY               0x9914                  /* Register Address */
+#define        AR5K_PHY_RX_DELAY_M             0x00003fff      /* Mask for RX activate to receive delay (/100ns) */
+
+/*
+ * PHY max rx length register (?) [5111]
+ */
+#define        AR5K_PHY_MAX_RX_LEN             0x991c
+
+/*
+ * PHY timing register 4
+ * I(nphase)/Q(adrature) calibration register [5111+]
+ */
+#define        AR5K_PHY_IQ                     0x9920                  /* Register Address */
+#define        AR5K_PHY_IQ_CORR_Q_Q_COFF       0x0000001f      /* Mask for q correction info */
+#define        AR5K_PHY_IQ_CORR_Q_I_COFF       0x000007e0      /* Mask for i correction info */
+#define        AR5K_PHY_IQ_CORR_Q_I_COFF_S     5
+#define        AR5K_PHY_IQ_CORR_ENABLE         0x00000800      /* Enable i/q correction */
+#define        AR5K_PHY_IQ_CAL_NUM_LOG_MAX     0x0000f000      /* Mask for max number of samples in log scale */
+#define        AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S   12
+#define        AR5K_PHY_IQ_RUN                 0x00010000      /* Run i/q calibration */
+#define        AR5K_PHY_IQ_USE_PT_DF           0x00020000      /* Use pilot track df (?) */
+#define        AR5K_PHY_IQ_EARLY_TRIG_THR      0x00200000      /* Early trigger threshold (?) (field) */
+#define        AR5K_PHY_IQ_PILOT_MASK_EN       0x10000000      /* Enable pilot mask (?) */
+#define        AR5K_PHY_IQ_CHAN_MASK_EN        0x20000000      /* Enable channel mask (?) */
+#define        AR5K_PHY_IQ_SPUR_FILT_EN        0x40000000      /* Enable spur filter */
+#define        AR5K_PHY_IQ_SPUR_RSSI_EN        0x80000000      /* Enable spur rssi */
+
+/*
+ * PHY timing register 5
+ * OFDM Self-correlator Cyclic RSSI threshold params
+ * (Check out bb_cycpwr_thr1 on ANI patent)
+ */
+#define        AR5K_PHY_OFDM_SELFCORR                  0x9924                  /* Register Address */
+#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN    0x00000001      /* Enable cyclic RSSI thr 1 */
+#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1       0x000000fe      /* Mask for Cyclic RSSI threshold 1 */
+#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S     1
+#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3       0x00000100      /* Cyclic RSSI threshold 3 (field) (?) */
+#define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN    0x00008000      /* Enable 1A RSSI threshold (?) */
+#define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR       0x00010000      /* 1A RSSI threshold (field) (?) */
+#define        AR5K_PHY_OFDM_SELFCORR_LSCTHR_HIRSSI    0x00800000      /* Long sc threshold hi rssi (?) */
+
+/*
+ * PHY-only warm reset register
+ */
+#define        AR5K_PHY_WARM_RESET             0x9928
+
+/*
+ * PHY-only control register
+ */
+#define AR5K_PHY_CTL                   0x992c                  /* Register Address */
+#define        AR5K_PHY_CTL_RX_DRAIN_RATE      0x00000001      /* RX drain rate (?) */
+#define        AR5K_PHY_CTL_LATE_TX_SIG_SYM    0x00000002      /* Late tx signal symbol (?) */
+#define        AR5K_PHY_CTL_GEN_SCRAMBLER      0x00000004      /* Generate scrambler */
+#define        AR5K_PHY_CTL_TX_ANT_SEL         0x00000008      /* TX antenna select */
+#define        AR5K_PHY_CTL_TX_ANT_STATIC      0x00000010      /* Static TX antenna */
+#define        AR5K_PHY_CTL_RX_ANT_SEL         0x00000020      /* RX antenna select */
+#define        AR5K_PHY_CTL_RX_ANT_STATIC      0x00000040      /* Static RX antenna */
+#define        AR5K_PHY_CTL_LOW_FREQ_SLE_EN    0x00000080      /* Enable low freq sleep */
+
+/*
+ * PHY PAPD probe register [5111+]
+ */
+#define        AR5K_PHY_PAPD_PROBE             0x9930
+#define        AR5K_PHY_PAPD_PROBE_SH_HI_PAR   0x00000001
+#define        AR5K_PHY_PAPD_PROBE_PCDAC_BIAS  0x00000002
+#define        AR5K_PHY_PAPD_PROBE_COMP_GAIN   0x00000040
+#define        AR5K_PHY_PAPD_PROBE_TXPOWER     0x00007e00
+#define        AR5K_PHY_PAPD_PROBE_TXPOWER_S   9
+#define        AR5K_PHY_PAPD_PROBE_TX_NEXT     0x00008000
+#define        AR5K_PHY_PAPD_PROBE_PREDIST_EN  0x00010000
+#define        AR5K_PHY_PAPD_PROBE_TYPE        0x01800000      /* [5112+] */
+#define        AR5K_PHY_PAPD_PROBE_TYPE_S      23
+#define        AR5K_PHY_PAPD_PROBE_TYPE_OFDM   0
+#define        AR5K_PHY_PAPD_PROBE_TYPE_XR     1
+#define        AR5K_PHY_PAPD_PROBE_TYPE_CCK    2
+#define        AR5K_PHY_PAPD_PROBE_GAINF       0xfe000000
+#define        AR5K_PHY_PAPD_PROBE_GAINF_S     25
+#define        AR5K_PHY_PAPD_PROBE_INI_5111    0x00004883      /* [5212+] */
+#define        AR5K_PHY_PAPD_PROBE_INI_5112    0x00004882      /* [5212+] */
+
+/*
+ * PHY TX rate power registers [5112+]
+ */
+#define        AR5K_PHY_TXPOWER_RATE1                  0x9934
+#define        AR5K_PHY_TXPOWER_RATE2                  0x9938
+#define        AR5K_PHY_TXPOWER_RATE_MAX               0x993c
+#define        AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE    0x00000040
+#define        AR5K_PHY_TXPOWER_RATE3                  0xa234
+#define        AR5K_PHY_TXPOWER_RATE4                  0xa238
+
+/*
+ * PHY frame control register [5111+]
+ */
+#define        AR5K_PHY_FRAME_CTL_5210         0x9804
+#define        AR5K_PHY_FRAME_CTL_5211         0x9944
+#define        AR5K_PHY_FRAME_CTL              (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
+/*---[5111+]---*/
+#define        AR5K_PHY_FRAME_CTL_TX_CLIP      0x00000038      /* Mask for tx clip (?) */
+#define        AR5K_PHY_FRAME_CTL_TX_CLIP_S    3
+#define        AR5K_PHY_FRAME_CTL_PREP_CHINFO  0x00010000      /* Prepend chan info */
+#define        AR5K_PHY_FRAME_CTL_EMU          0x80000000
+#define        AR5K_PHY_FRAME_CTL_EMU_S        31
+/*---[5110/5111]---*/
+#define        AR5K_PHY_FRAME_CTL_TIMING_ERR   0x01000000      /* PHY timing error */
+#define        AR5K_PHY_FRAME_CTL_PARITY_ERR   0x02000000      /* Parity error */
+#define        AR5K_PHY_FRAME_CTL_ILLRATE_ERR  0x04000000      /* Illegal rate */
+#define        AR5K_PHY_FRAME_CTL_ILLLEN_ERR   0x08000000      /* Illegal length */
+#define        AR5K_PHY_FRAME_CTL_SERVICE_ERR  0x20000000
+#define        AR5K_PHY_FRAME_CTL_TXURN_ERR    0x40000000      /* TX underrun */
+#define AR5K_PHY_FRAME_CTL_INI         AR5K_PHY_FRAME_CTL_SERVICE_ERR | \
+                       AR5K_PHY_FRAME_CTL_TXURN_ERR | \
+                       AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \
+                       AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \
+                       AR5K_PHY_FRAME_CTL_PARITY_ERR | \
+                       AR5K_PHY_FRAME_CTL_TIMING_ERR
+
+/*
+ * PHY Tx Power adjustment register [5212A+]
+ */
+#define        AR5K_PHY_TX_PWR_ADJ                     0x994c
+#define        AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA      0x00000fc0
+#define        AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S    6
+#define        AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX     0x00fc0000
+#define        AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S   18
+
+/*
+ * PHY radar detection register [5111+]
+ */
+#define        AR5K_PHY_RADAR                  0x9954
+#define        AR5K_PHY_RADAR_ENABLE           0x00000001
+#define        AR5K_PHY_RADAR_DISABLE          0x00000000
+#define AR5K_PHY_RADAR_INBANDTHR       0x0000003e      /* Inband threshold
+                                                       5-bits, units unknown {0..31}
+                                                       (? MHz ?) */
+#define AR5K_PHY_RADAR_INBANDTHR_S     1
+
+#define AR5K_PHY_RADAR_PRSSI_THR       0x00000fc0      /* Pulse RSSI/SNR threshold
+                                                       6-bits, dBm range {0..63}
+                                                       in dBm units. */
+#define AR5K_PHY_RADAR_PRSSI_THR_S     6
+
+#define AR5K_PHY_RADAR_PHEIGHT_THR     0x0003f000      /* Pulse height threshold
+                                                       6-bits, dBm range {0..63}
+                                                       in dBm units. */
+#define AR5K_PHY_RADAR_PHEIGHT_THR_S   12
+
+#define AR5K_PHY_RADAR_RSSI_THR        0x00fc0000      /* Radar RSSI/SNR threshold.
+                                                       6-bits, dBm range {0..63}
+                                                       in dBm units. */
+#define AR5K_PHY_RADAR_RSSI_THR_S      18
+
+#define AR5K_PHY_RADAR_FIRPWR_THR      0x7f000000      /* Finite Impulse Response
+                                                       filter power out threshold.
+                                                       7-bits, standard power range
+                                                       {0..127} in 1/2 dBm units. */
+#define AR5K_PHY_RADAR_FIRPWR_THRS     24
+
+/*
+ * PHY antenna switch table registers
+ */
+#define AR5K_PHY_ANT_SWITCH_TABLE_0    0x9960
+#define AR5K_PHY_ANT_SWITCH_TABLE_1    0x9964
+
+/*
+ * PHY Noise floor threshold
+ */
+#define AR5K_PHY_NFTHRES               0x9968
+
+/*
+ * Sigma Delta register (?) [5213]
+ */
+#define AR5K_PHY_SIGMA_DELTA           0x996C
+#define AR5K_PHY_SIGMA_DELTA_ADC_SEL   0x00000003
+#define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0
+#define AR5K_PHY_SIGMA_DELTA_FILT2     0x000000f8
+#define AR5K_PHY_SIGMA_DELTA_FILT2_S   3
+#define AR5K_PHY_SIGMA_DELTA_FILT1     0x00001f00
+#define AR5K_PHY_SIGMA_DELTA_FILT1_S   8
+#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP  0x01ffe000
+#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S        13
+
+/*
+ * RF restart register [5112+] (?)
+ */
+#define AR5K_PHY_RESTART               0x9970          /* restart */
+#define AR5K_PHY_RESTART_DIV_GC                0x001c0000      /* Fast diversity gc_limit (?) */
+#define AR5K_PHY_RESTART_DIV_GC_S      18
+
+/*
+ * RF Bus access request register (for synth-oly channel switching)
+ */
+#define AR5K_PHY_RFBUS_REQ             0x997C
+#define AR5K_PHY_RFBUS_REQ_REQUEST     0x00000001
+
+/*
+ * Spur mitigation masks (?)
+ */
+#define AR5K_PHY_TIMING_7              0x9980
+#define AR5K_PHY_TIMING_8              0x9984
+#define AR5K_PHY_TIMING_8_PILOT_MASK_2         0x000fffff
+#define AR5K_PHY_TIMING_8_PILOT_MASK_2_S       0
+
+#define AR5K_PHY_BIN_MASK2_1           0x9988
+#define AR5K_PHY_BIN_MASK2_2           0x998c
+#define AR5K_PHY_BIN_MASK2_3           0x9990
+
+#define AR5K_PHY_BIN_MASK2_4           0x9994
+#define AR5K_PHY_BIN_MASK2_4_MASK_4    0x00003fff
+#define AR5K_PHY_BIN_MASK2_4_MASK_4_S  0
+
+#define AR5K_PHY_TIMING_9                      0x9998
+#define AR5K_PHY_TIMING_10                     0x999c
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2                0x000fffff
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2_S      0
+
+/*
+ * Spur mitigation control
+ */
+#define AR5K_PHY_TIMING_11                     0x99a0          /* Register address */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE    0x000fffff      /* Spur delta phase */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S  0
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD                0x3ff00000      /* Freq sigma delta */
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S      20
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC     0x40000000      /* Spur filter in AGC detector */
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000      /* Spur filter in OFDM self correlator */
+
+/*
+ * Gain tables
+ */
+#define        AR5K_BB_GAIN_BASE               0x9b00  /* BaseBand Amplifier Gain table base address */
+#define AR5K_BB_GAIN(_n)               (AR5K_BB_GAIN_BASE + ((_n) << 2))
+#define        AR5K_RF_GAIN_BASE               0x9a00  /* RF Amplrifier Gain table base address */
+#define AR5K_RF_GAIN(_n)               (AR5K_RF_GAIN_BASE + ((_n) << 2))
+
+/*
+ * PHY timing IQ calibration result register [5111+]
+ */
+#define        AR5K_PHY_IQRES_CAL_PWR_I        0x9c10  /* I (Inphase) power value */
+#define        AR5K_PHY_IQRES_CAL_PWR_Q        0x9c14  /* Q (Quadrature) power value */
+#define        AR5K_PHY_IQRES_CAL_CORR         0x9c18  /* I/Q Correlation */
+
+/*
+ * PHY current RSSI register [5111+]
+ */
+#define        AR5K_PHY_CURRENT_RSSI   0x9c1c
+
+/*
+ * PHY RF Bus grant register
+ */
+#define        AR5K_PHY_RFBUS_GRANT    0x9c20
+#define        AR5K_PHY_RFBUS_GRANT_OK 0x00000001
+
+/*
+ * PHY ADC test register
+ */
+#define        AR5K_PHY_ADC_TEST       0x9c24
+#define        AR5K_PHY_ADC_TEST_I     0x00000001
+#define        AR5K_PHY_ADC_TEST_Q     0x00000200
+
+/*
+ * PHY DAC test register
+ */
+#define        AR5K_PHY_DAC_TEST       0x9c28
+#define        AR5K_PHY_DAC_TEST_I     0x00000001
+#define        AR5K_PHY_DAC_TEST_Q     0x00000200
+
+/*
+ * PHY PTAT register (?)
+ */
+#define        AR5K_PHY_PTAT           0x9c2c
+
+/*
+ * PHY Illegal TX rate register [5112+]
+ */
+#define        AR5K_PHY_BAD_TX_RATE    0x9c30
+
+/*
+ * PHY SPUR Power register [5112+]
+ */
+#define        AR5K_PHY_SPUR_PWR       0x9c34                  /* Register Address */
+#define        AR5K_PHY_SPUR_PWR_I     0x00000001      /* SPUR Power estimate for I (field) */
+#define        AR5K_PHY_SPUR_PWR_Q     0x00000100      /* SPUR Power estimate for Q (field) */
+#define        AR5K_PHY_SPUR_PWR_FILT  0x00010000      /* Power with SPUR removed (field) */
+
+/*
+ * PHY Channel status register [5112+] (?)
+ */
+#define        AR5K_PHY_CHAN_STATUS            0x9c38
+#define        AR5K_PHY_CHAN_STATUS_BT_ACT     0x00000001
+#define        AR5K_PHY_CHAN_STATUS_RX_CLR_RAW 0x00000002
+#define        AR5K_PHY_CHAN_STATUS_RX_CLR_MAC 0x00000004
+#define        AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008
+
+/*
+ * Heavy clip enable register
+ */
+#define        AR5K_PHY_HEAVY_CLIP_ENABLE      0x99e0
+
+/*
+ * PHY clock sleep registers [5112+]
+ */
+#define AR5K_PHY_SCLOCK                        0x99f0
+#define AR5K_PHY_SCLOCK_32MHZ          0x0000000c
+#define AR5K_PHY_SDELAY                        0x99f4
+#define AR5K_PHY_SDELAY_32MHZ          0x000000ff
+#define AR5K_PHY_SPENDING              0x99f8
+
+
+/*
+ * PHY PAPD I (power?) table (?)
+ * (92! entries)
+ */
+#define        AR5K_PHY_PAPD_I_BASE    0xa000
+#define        AR5K_PHY_PAPD_I(_n)     (AR5K_PHY_PAPD_I_BASE + ((_n) << 2))
+
+/*
+ * PHY PCDAC TX power table
+ */
+#define        AR5K_PHY_PCDAC_TXPOWER_BASE     0xa180
+#define        AR5K_PHY_PCDAC_TXPOWER(_n)      (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
+
+/*
+ * PHY mode register [5111+]
+ */
+#define        AR5K_PHY_MODE                   0x0a200                 /* Register Address */
+#define        AR5K_PHY_MODE_MOD               0x00000001      /* PHY Modulation bit */
+#define AR5K_PHY_MODE_MOD_OFDM         0
+#define AR5K_PHY_MODE_MOD_CCK          1
+#define AR5K_PHY_MODE_FREQ             0x00000002      /* Freq mode bit */
+#define        AR5K_PHY_MODE_FREQ_5GHZ         0
+#define        AR5K_PHY_MODE_FREQ_2GHZ         2
+#define AR5K_PHY_MODE_MOD_DYN          0x00000004      /* Enable Dynamic OFDM/CCK mode [5112+] */
+#define AR5K_PHY_MODE_RAD              0x00000008      /* [5212+] */
+#define AR5K_PHY_MODE_RAD_RF5111       0
+#define AR5K_PHY_MODE_RAD_RF5112       8
+#define AR5K_PHY_MODE_XR               0x00000010      /* Enable XR mode [5112+] */
+#define        AR5K_PHY_MODE_HALF_RATE         0x00000020      /* Enable Half rate (test) */
+#define        AR5K_PHY_MODE_QUARTER_RATE      0x00000040      /* Enable Quarter rat (test) */
+
+/*
+ * PHY CCK transmit control register [5111+ (?)]
+ */
+#define AR5K_PHY_CCKTXCTL              0xa204
+#define AR5K_PHY_CCKTXCTL_WORLD                0x00000000
+#define AR5K_PHY_CCKTXCTL_JAPAN                0x00000010
+#define        AR5K_PHY_CCKTXCTL_SCRAMBLER_DIS 0x00000001
+#define        AR5K_PHY_CCKTXCTK_DAC_SCALE     0x00000004
+
+/*
+ * PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
+ */
+#define AR5K_PHY_CCK_CROSSCORR                 0xa208
+#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR    0x0000000f
+#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S  0
+
+/* Same address is used for antenna diversity activation */
+#define        AR5K_PHY_FAST_ANT_DIV           0xa208
+#define        AR5K_PHY_FAST_ANT_DIV_EN        0x00002000
+
+/*
+ * PHY 2GHz gain register [5111+]
+ */
+#define        AR5K_PHY_GAIN_2GHZ                      0xa20c
+#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX          0x00fc0000
+#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S        18
+#define        AR5K_PHY_GAIN_2GHZ_INI_5111             0x6480416c
+
+#define        AR5K_PHY_CCK_RX_CTL_4                   0xa21c
+#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT    0x01f80000
+#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S  19
+
+#define        AR5K_PHY_DAG_CCK_CTL                    0xa228
+#define        AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR        0x00000200
+#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR           0x0001fc00
+#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S         10
+
+#define        AR5K_PHY_FAST_ADC       0xa24c
+
+#define        AR5K_PHY_BLUETOOTH      0xa254
+
+/*
+ * Transmit Power Control register
+ * [2413+]
+ */
+#define        AR5K_PHY_TPC_RG1                0xa258
+#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN    0x0000c000
+#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S  14
+#define AR5K_PHY_TPC_RG1_PDGAIN_1      0x00030000
+#define AR5K_PHY_TPC_RG1_PDGAIN_1_S    16
+#define AR5K_PHY_TPC_RG1_PDGAIN_2      0x000c0000
+#define AR5K_PHY_TPC_RG1_PDGAIN_2_S    18
+#define AR5K_PHY_TPC_RG1_PDGAIN_3      0x00300000
+#define AR5K_PHY_TPC_RG1_PDGAIN_3_S    20
+
+#define        AR5K_PHY_TPC_RG5                        0xa26C
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP        0x0000000F
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S      0
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1     0x000003F0
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S   4
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2     0x0000FC00
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S   10
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3     0x003F0000
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S   16
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4     0x0FC00000
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S   22
+
+/*
+ * PHY PDADC Tx power table
+ */
+#define AR5K_PHY_PDADC_TXPOWER_BASE    0xa280
+#define        AR5K_PHY_PDADC_TXPOWER(_n)      (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
new file mode 100644 (file)
index 0000000..775fdf7
--- /dev/null
@@ -0,0 +1,1346 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
+ * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+#define _ATH5K_RESET
+
+/*****************************\
+  Reset functions and helpers
+\*****************************/
+
+#include <linux/pci.h>                 /* To determine if a card is pci-e */
+#include <linux/bitops.h>      /* For get_bitmask_order */
+#include "ath5k.h"
+#include "reg.h"
+#include "base.h"
+#include "debug.h"
+
+/**
+ * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
+ *
+ * @ah: the &struct ath5k_hw
+ * @channel: the currently set channel upon reset
+ *
+ * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
+ * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
+ *
+ * Since delta slope is floating point we split it on its exponent and
+ * mantissa and provide these values on hw.
+ *
+ * For more infos i think this patent is related
+ * http://www.freepatentsonline.com/7184495.html
+ */
+static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
+       struct ieee80211_channel *channel)
+{
+       /* Get exponent and mantissa and set it */
+       u32 coef_scaled, coef_exp, coef_man,
+               ds_coef_exp, ds_coef_man, clock;
+
+       BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
+               !(channel->hw_value & CHANNEL_OFDM));
+
+       /* Get coefficient
+        * ALGO: coef = (5 * clock * carrier_freq) / 2)
+        * we scale coef by shifting clock value by 24 for
+        * better precision since we use integers */
+       /* TODO: Half/quarter rate */
+       clock =  ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO);
+
+       coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
+
+       /* Get exponent
+        * ALGO: coef_exp = 14 - highest set bit position */
+       coef_exp = get_bitmask_order(coef_scaled);
+
+       /* Doesn't make sense if it's zero*/
+       if (!coef_exp)
+               return -EINVAL;
+
+       /* Note: we've shifted coef_scaled by 24 */
+       coef_exp = 14 - (coef_exp - 24);
+
+
+       /* Get mantissa (significant digits)
+        * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
+       coef_man = coef_scaled +
+               (1 << (24 - coef_exp - 1));
+
+       /* Calculate delta slope coefficient exponent
+        * and mantissa (remove scaling) and set them on hw */
+       ds_coef_man = coef_man >> (24 - coef_exp);
+       ds_coef_exp = coef_exp - 16;
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+               AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+               AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
+
+       return 0;
+}
+
+
+/*
+ * index into rates for control rates, we can set it up like this because
+ * this is only used for AR5212 and we know it supports G mode
+ */
+static const unsigned int control_rates[] =
+       { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
+
+/**
+ * ath5k_hw_write_rate_duration - fill rate code to duration table
+ *
+ * @ah: the &struct ath5k_hw
+ * @mode: one of enum ath5k_driver_mode
+ *
+ * Write the rate code to duration table upon hw reset. This is a helper for
+ * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
+ * the hardware, based on current mode, for each rate. The rates which are
+ * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
+ * different rate code so we write their value twice (one for long preample
+ * and one for short).
+ *
+ * Note: Band doesn't matter here, if we set the values for OFDM it works
+ * on both a and g modes. So all we have to do is set values for all g rates
+ * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
+ * quarter rate mode, we need to use another set of bitrates (that's why we
+ * need the mode parameter) but we don't handle these proprietary modes yet.
+ */
+static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
+       unsigned int mode)
+{
+       struct ath5k_softc *sc = ah->ah_sc;
+       struct ieee80211_rate *rate;
+       unsigned int i;
+
+       /* Write rate duration table */
+       for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
+               u32 reg;
+               u16 tx_time;
+
+               rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
+
+               /* Set ACK timeout */
+               reg = AR5K_RATE_DUR(rate->hw_value);
+
+               /* An ACK frame consists of 10 bytes. If you add the FCS,
+                * which ieee80211_generic_frame_duration() adds,
+                * its 14 bytes. Note we use the control rate and not the
+                * actual rate for this rate. See mac80211 tx.c
+                * ieee80211_duration() for a brief description of
+                * what rate we should choose to TX ACKs. */
+               tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
+                                                       sc->vif, 10, rate));
+
+               ath5k_hw_reg_write(ah, tx_time, reg);
+
+               if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
+                       continue;
+
+               /*
+                * We're not distinguishing short preamble here,
+                * This is true, all we'll get is a longer value here
+                * which is not necessarilly bad. We could use
+                * export ieee80211_frame_duration() but that needs to be
+                * fixed first to be properly used by mac802111 drivers:
+                *
+                *  - remove erp stuff and let the routine figure ofdm
+                *    erp rates
+                *  - remove passing argument ieee80211_local as
+                *    drivers don't have access to it
+                *  - move drivers using ieee80211_generic_frame_duration()
+                *    to this
+                */
+               ath5k_hw_reg_write(ah, tx_time,
+                       reg + (AR5K_SET_SHORT_PREAMBLE << 2));
+       }
+}
+
+/*
+ * Reset chipset
+ */
+static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
+{
+       int ret;
+       u32 mask = val ? val : ~0U;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Read-and-clear RX Descriptor Pointer*/
+       ath5k_hw_reg_read(ah, AR5K_RXDP);
+
+       /*
+        * Reset the device and wait until success
+        */
+       ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
+
+       /* Wait at least 128 PCI clocks */
+       udelay(15);
+
+       if (ah->ah_version == AR5K_AR5210) {
+               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+       } else {
+               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
+               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
+       }
+
+       ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
+
+       /*
+        * Reset configuration register (for hw byte-swap). Note that this
+        * is only set for big endian. We do the necessary magic in
+        * AR5K_INIT_CFG.
+        */
+       if ((val & AR5K_RESET_CTL_PCU) == 0)
+               ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
+
+       return ret;
+}
+
+/*
+ * Sleep control
+ */
+int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
+               bool set_chip, u16 sleep_duration)
+{
+       unsigned int i;
+       u32 staid, data;
+
+       ATH5K_TRACE(ah->ah_sc);
+       staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
+
+       switch (mode) {
+       case AR5K_PM_AUTO:
+               staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
+               /* fallthrough */
+       case AR5K_PM_NETWORK_SLEEP:
+               if (set_chip)
+                       ath5k_hw_reg_write(ah,
+                               AR5K_SLEEP_CTL_SLE_ALLOW |
+                               sleep_duration,
+                               AR5K_SLEEP_CTL);
+
+               staid |= AR5K_STA_ID1_PWR_SV;
+               break;
+
+       case AR5K_PM_FULL_SLEEP:
+               if (set_chip)
+                       ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
+                               AR5K_SLEEP_CTL);
+
+               staid |= AR5K_STA_ID1_PWR_SV;
+               break;
+
+       case AR5K_PM_AWAKE:
+
+               staid &= ~AR5K_STA_ID1_PWR_SV;
+
+               if (!set_chip)
+                       goto commit;
+
+               /* Preserve sleep duration */
+               data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
+               if (data & 0xffc00000)
+                       data = 0;
+               else
+                       data = data & 0xfffcffff;
+
+               ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+               udelay(15);
+
+               for (i = 50; i > 0; i--) {
+                       /* Check if the chip did wake up */
+                       if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
+                                       AR5K_PCICFG_SPWR_DN) == 0)
+                               break;
+
+                       /* Wait a bit and retry */
+                       udelay(200);
+                       ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+               }
+
+               /* Fail if the chip didn't wake up */
+               if (i <= 0)
+                       return -EIO;
+
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+commit:
+       ah->ah_power_mode = mode;
+       ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
+
+       return 0;
+}
+
+/*
+ * Bring up MAC + PHY Chips and program PLL
+ * TODO: Half/Quarter rate support
+ */
+int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
+{
+       struct pci_dev *pdev = ah->ah_sc->pdev;
+       u32 turbo, mode, clock, bus_flags;
+       int ret;
+
+       turbo = 0;
+       mode = 0;
+       clock = 0;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Wakeup the device */
+       ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+               return ret;
+       }
+
+       if (ah->ah_version != AR5K_AR5210) {
+               /*
+                * Get channel mode flags
+                */
+
+               if (ah->ah_radio >= AR5K_RF5112) {
+                       mode = AR5K_PHY_MODE_RAD_RF5112;
+                       clock = AR5K_PHY_PLL_RF5112;
+               } else {
+                       mode = AR5K_PHY_MODE_RAD_RF5111;        /*Zero*/
+                       clock = AR5K_PHY_PLL_RF5111;            /*Zero*/
+               }
+
+               if (flags & CHANNEL_2GHZ) {
+                       mode |= AR5K_PHY_MODE_FREQ_2GHZ;
+                       clock |= AR5K_PHY_PLL_44MHZ;
+
+                       if (flags & CHANNEL_CCK) {
+                               mode |= AR5K_PHY_MODE_MOD_CCK;
+                       } else if (flags & CHANNEL_OFDM) {
+                               /* XXX Dynamic OFDM/CCK is not supported by the
+                                * AR5211 so we set MOD_OFDM for plain g (no
+                                * CCK headers) operation. We need to test
+                                * this, 5211 might support ofdm-only g after
+                                * all, there are also initial register values
+                                * in the code for g mode (see initvals.c). */
+                               if (ah->ah_version == AR5K_AR5211)
+                                       mode |= AR5K_PHY_MODE_MOD_OFDM;
+                               else
+                                       mode |= AR5K_PHY_MODE_MOD_DYN;
+                       } else {
+                               ATH5K_ERR(ah->ah_sc,
+                                       "invalid radio modulation mode\n");
+                               return -EINVAL;
+                       }
+               } else if (flags & CHANNEL_5GHZ) {
+                       mode |= AR5K_PHY_MODE_FREQ_5GHZ;
+
+                       if (ah->ah_radio == AR5K_RF5413)
+                               clock = AR5K_PHY_PLL_40MHZ_5413;
+                       else
+                               clock |= AR5K_PHY_PLL_40MHZ;
+
+                       if (flags & CHANNEL_OFDM)
+                               mode |= AR5K_PHY_MODE_MOD_OFDM;
+                       else {
+                               ATH5K_ERR(ah->ah_sc,
+                                       "invalid radio modulation mode\n");
+                               return -EINVAL;
+                       }
+               } else {
+                       ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
+                       return -EINVAL;
+               }
+
+               if (flags & CHANNEL_TURBO)
+                       turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
+       } else { /* Reset the device */
+
+               /* ...enable Atheros turbo mode if requested */
+               if (flags & CHANNEL_TURBO)
+                       ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
+                                       AR5K_PHY_TURBO);
+       }
+
+       /* reseting PCI on PCI-E cards results card to hang
+        * and always return 0xffff... so we ingore that flag
+        * for PCI-E cards */
+       bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+
+       /* Reset chipset */
+       if (ah->ah_version == AR5K_AR5210) {
+               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+                       AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+                       AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+                       mdelay(2);
+       } else {
+               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+                       AR5K_RESET_CTL_BASEBAND | bus_flags);
+       }
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
+               return -EIO;
+       }
+
+       /* ...wakeup again!*/
+       ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
+               return ret;
+       }
+
+       /* ...final warm reset */
+       if (ath5k_hw_nic_reset(ah, 0)) {
+               ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
+               return -EIO;
+       }
+
+       if (ah->ah_version != AR5K_AR5210) {
+
+               /* ...update PLL if needed */
+               if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
+                       ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
+                       udelay(300);
+               }
+
+               /* ...set the PHY operating mode */
+               ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
+               ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
+       }
+
+       return 0;
+}
+
+/*
+ * If there is an external 32KHz crystal available, use it
+ * as ref. clock instead of 32/40MHz clock and baseband clocks
+ * to save power during sleep or restore normal 32/40MHz
+ * operation.
+ *
+ * XXX: When operating on 32KHz certain PHY registers (27 - 31,
+ *     123 - 127) require delay on access.
+ */
+static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 scal, spending, usec32;
+
+       /* Only set 32KHz settings if we have an external
+        * 32KHz crystal present */
+       if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
+       AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
+       enable) {
+
+               /* 1 usec/cycle */
+               AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
+               /* Set up tsf increment on each cycle */
+               AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
+
+               /* Set baseband sleep control registers
+                * and sleep control rate */
+               ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+
+               if ((ah->ah_radio == AR5K_RF5112) ||
+               (ah->ah_radio == AR5K_RF5413) ||
+               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+                       spending = 0x14;
+               else
+                       spending = 0x18;
+               ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+               if ((ah->ah_radio == AR5K_RF5112) ||
+               (ah->ah_radio == AR5K_RF5413) ||
+               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+                       ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
+                       ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
+                       ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
+                       ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
+                       AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
+               } else {
+                       ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
+                       ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
+                       ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
+                       ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
+                       AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
+               }
+
+               /* Enable sleep clock operation */
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+       } else {
+
+               /* Disable sleep clock operation and
+                * restore default parameters */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
+
+               ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+               ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
+
+               if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+                       scal = AR5K_PHY_SCAL_32MHZ_2417;
+               else if (ath5k_eeprom_is_hb63(ah))
+                       scal = AR5K_PHY_SCAL_32MHZ_HB63;
+               else
+                       scal = AR5K_PHY_SCAL_32MHZ;
+               ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+
+               ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
+               ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
+
+               if ((ah->ah_radio == AR5K_RF5112) ||
+               (ah->ah_radio == AR5K_RF5413) ||
+               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+                       spending = 0x14;
+               else
+                       spending = 0x18;
+               ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+               if ((ah->ah_radio == AR5K_RF5112) ||
+               (ah->ah_radio == AR5K_RF5413))
+                       usec32 = 39;
+               else
+                       usec32 = 31;
+               AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
+       }
+       return;
+}
+
+static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channel)
+{
+       u8 refclk_freq;
+
+       if ((ah->ah_radio == AR5K_RF5112) ||
+       (ah->ah_radio == AR5K_RF5413) ||
+       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+               refclk_freq = 40;
+       else
+               refclk_freq = 32;
+
+       if ((channel->center_freq % refclk_freq != 0) &&
+       ((channel->center_freq % refclk_freq < 10) ||
+       (channel->center_freq % refclk_freq > 22)))
+               return true;
+       else
+               return false;
+}
+
+/* TODO: Half/Quarter rate */
+static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channel)
+{
+       if (ah->ah_version == AR5K_AR5212 &&
+           ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+
+               /* Setup ADC control */
+               ath5k_hw_reg_write(ah,
+                               (AR5K_REG_SM(2,
+                               AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
+                               AR5K_REG_SM(2,
+                               AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
+                               AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
+                               AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
+                               AR5K_PHY_ADC_CTL);
+
+
+
+               /* Disable barker RSSI threshold */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+                               AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+                       AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
+
+               /* Set the mute mask */
+               ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
+       }
+
+       /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */
+       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
+
+       /* Enable DCU double buffering */
+       if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
+               AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+                               AR5K_TXCFG_DCU_DBL_BUF_DIS);
+
+       /* Set DAC/ADC delays */
+       if (ah->ah_version == AR5K_AR5212) {
+               u32 scal;
+               if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+                       scal = AR5K_PHY_SCAL_32MHZ_2417;
+               else if (ath5k_eeprom_is_hb63(ah))
+                       scal = AR5K_PHY_SCAL_32MHZ_HB63;
+               else
+                       scal = AR5K_PHY_SCAL_32MHZ;
+               ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+       }
+
+       /* Set fast ADC */
+       if ((ah->ah_radio == AR5K_RF5413) ||
+       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+               u32 fast_adc = true;
+
+               if (channel->center_freq == 2462 ||
+               channel->center_freq == 2467)
+                       fast_adc = 0;
+
+               /* Only update if needed */
+               if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
+                               ath5k_hw_reg_write(ah, fast_adc,
+                                               AR5K_PHY_FAST_ADC);
+       }
+
+       /* Fix for first revision of the RF5112 RF chipset */
+       if (ah->ah_radio == AR5K_RF5112 &&
+                       ah->ah_radio_5ghz_revision <
+                       AR5K_SREV_RAD_5112A) {
+               u32 data;
+               ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
+                               AR5K_PHY_CCKTXCTL);
+               if (channel->hw_value & CHANNEL_5GHZ)
+                       data = 0xffb81020;
+               else
+                       data = 0xffb80d20;
+               ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
+       }
+
+       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+               u32 usec_reg;
+               /* 5311 has different tx/rx latency masks
+                * from 5211, since we deal 5311 the same
+                * as 5211 when setting initvals, shift
+                * values here to their proper locations */
+               usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
+               ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
+                               AR5K_USEC_32 |
+                               AR5K_USEC_TX_LATENCY_5211 |
+                               AR5K_REG_SM(29,
+                               AR5K_USEC_RX_LATENCY_5210)),
+                               AR5K_USEC_5211);
+               /* Clear QCU/DCU clock gating register */
+               ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
+               /* Set DAC/ADC delays */
+               ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
+               /* Enable PCU FIFO corruption ECO */
+               AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
+                                       AR5K_DIAG_SW_ECO_ENABLE);
+       }
+}
+
+static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       s16 cck_ofdm_pwr_delta;
+
+       /* Adjust power delta for channel 14 */
+       if (channel->center_freq == 2484)
+               cck_ofdm_pwr_delta =
+                       ((ee->ee_cck_ofdm_power_delta -
+                       ee->ee_scaled_cck_delta) * 2) / 10;
+       else
+               cck_ofdm_pwr_delta =
+                       (ee->ee_cck_ofdm_power_delta * 2) / 10;
+
+       /* Set CCK to OFDM power delta on tx power
+        * adjustment register */
+       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+               if (channel->hw_value == CHANNEL_G)
+                       ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
+                               AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
+                       AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
+                               AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
+                               AR5K_PHY_TX_PWR_ADJ);
+               else
+                       ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
+       } else {
+               /* For older revs we scale power on sw during tx power
+                * setup */
+               ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
+               ah->ah_txpower.txp_cck_ofdm_gainf_delta =
+                                               ee->ee_cck_ofdm_gain_delta;
+       }
+
+       /* Set antenna idle switch table */
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
+                       AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
+                       (ah->ah_antenna[ee_mode][0] |
+                       AR5K_PHY_ANT_CTL_TXRX_EN));
+
+       /* Set antenna switch table */
+       ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
+               AR5K_PHY_ANT_SWITCH_TABLE_0);
+       ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
+               AR5K_PHY_ANT_SWITCH_TABLE_1);
+
+       /* Noise floor threshold */
+       ath5k_hw_reg_write(ah,
+               AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
+               AR5K_PHY_NFTHRES);
+
+       if ((channel->hw_value & CHANNEL_TURBO) &&
+       (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
+               /* Switch settling time (Turbo) */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+                               AR5K_PHY_SETTLING_SWITCH,
+                               ee->ee_switch_settling_turbo[ee_mode]);
+
+               /* Tx/Rx attenuation (Turbo) */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+                               AR5K_PHY_GAIN_TXRX_ATTEN,
+                               ee->ee_atn_tx_rx_turbo[ee_mode]);
+
+               /* ADC/PGA desired size (Turbo) */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+                               AR5K_PHY_DESIRED_SIZE_ADC,
+                               ee->ee_adc_desired_size_turbo[ee_mode]);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+                               AR5K_PHY_DESIRED_SIZE_PGA,
+                               ee->ee_pga_desired_size_turbo[ee_mode]);
+
+               /* Tx/Rx margin (Turbo) */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+                               AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+                               ee->ee_margin_tx_rx_turbo[ee_mode]);
+
+       } else {
+               /* Switch settling time */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+                               AR5K_PHY_SETTLING_SWITCH,
+                               ee->ee_switch_settling[ee_mode]);
+
+               /* Tx/Rx attenuation */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+                               AR5K_PHY_GAIN_TXRX_ATTEN,
+                               ee->ee_atn_tx_rx[ee_mode]);
+
+               /* ADC/PGA desired size */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+                               AR5K_PHY_DESIRED_SIZE_ADC,
+                               ee->ee_adc_desired_size[ee_mode]);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+                               AR5K_PHY_DESIRED_SIZE_PGA,
+                               ee->ee_pga_desired_size[ee_mode]);
+
+               /* Tx/Rx margin */
+               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+                       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+                               AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+                               ee->ee_margin_tx_rx[ee_mode]);
+       }
+
+       /* XPA delays */
+       ath5k_hw_reg_write(ah,
+               (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
+               (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
+               (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
+               (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
+
+       /* XLNA delay */
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
+                       AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
+                       ee->ee_tx_end2xlna_enable[ee_mode]);
+
+       /* Thresh64 (ANI) */
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
+                       AR5K_PHY_NF_THRESH62,
+                       ee->ee_thr_62[ee_mode]);
+
+
+       /* False detect backoff for channels
+        * that have spur noise. Write the new
+        * cyclic power RSSI threshold. */
+       if (ath5k_hw_chan_has_spur_noise(ah, channel))
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+                               AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+                               AR5K_INIT_CYCRSSI_THR1 +
+                               ee->ee_false_detect[ee_mode]);
+       else
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+                               AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+                               AR5K_INIT_CYCRSSI_THR1);
+
+       /* I/Q correction
+        * TODO: Per channel i/q infos ? */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+               AR5K_PHY_IQ_CORR_ENABLE |
+               (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
+               ee->ee_q_cal[ee_mode]);
+
+       /* Heavy clipping -disable for now */
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
+
+       return;
+}
+
+/*
+ * Main reset function
+ */
+int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
+       struct ieee80211_channel *channel, bool change_channel)
+{
+       u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
+       u32 phy_tst1;
+       u8 mode, freq, ee_mode, ant[2];
+       int i, ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       s_ant = 0;
+       ee_mode = 0;
+       staid1_flags = 0;
+       tsf_up = 0;
+       tsf_lo = 0;
+       freq = 0;
+       mode = 0;
+
+       /*
+        * Save some registers before a reset
+        */
+       /*DCU/Antenna selection not available on 5210*/
+       if (ah->ah_version != AR5K_AR5210) {
+
+               switch (channel->hw_value & CHANNEL_MODES) {
+               case CHANNEL_A:
+                       mode = AR5K_MODE_11A;
+                       freq = AR5K_INI_RFGAIN_5GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11A;
+                       break;
+               case CHANNEL_G:
+                       mode = AR5K_MODE_11G;
+                       freq = AR5K_INI_RFGAIN_2GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+                       break;
+               case CHANNEL_B:
+                       mode = AR5K_MODE_11B;
+                       freq = AR5K_INI_RFGAIN_2GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11B;
+                       break;
+               case CHANNEL_T:
+                       mode = AR5K_MODE_11A_TURBO;
+                       freq = AR5K_INI_RFGAIN_5GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11A;
+                       break;
+               case CHANNEL_TG:
+                       if (ah->ah_version == AR5K_AR5211) {
+                               ATH5K_ERR(ah->ah_sc,
+                                       "TurboG mode not available on 5211");
+                               return -EINVAL;
+                       }
+                       mode = AR5K_MODE_11G_TURBO;
+                       freq = AR5K_INI_RFGAIN_2GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+                       break;
+               case CHANNEL_XR:
+                       if (ah->ah_version == AR5K_AR5211) {
+                               ATH5K_ERR(ah->ah_sc,
+                                       "XR mode not available on 5211");
+                               return -EINVAL;
+                       }
+                       mode = AR5K_MODE_XR;
+                       freq = AR5K_INI_RFGAIN_5GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11A;
+                       break;
+               default:
+                       ATH5K_ERR(ah->ah_sc,
+                               "invalid channel: %d\n", channel->center_freq);
+                       return -EINVAL;
+               }
+
+               if (change_channel) {
+                       /*
+                        * Save frame sequence count
+                        * For revs. after Oahu, only save
+                        * seq num for DCU 0 (Global seq num)
+                        */
+                       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+
+                               for (i = 0; i < 10; i++)
+                                       s_seq[i] = ath5k_hw_reg_read(ah,
+                                               AR5K_QUEUE_DCU_SEQNUM(i));
+
+                       } else {
+                               s_seq[0] = ath5k_hw_reg_read(ah,
+                                               AR5K_QUEUE_DCU_SEQNUM(0));
+                       }
+
+                       /* TSF accelerates on AR5211 durring reset
+                        * As a workaround save it here and restore
+                        * it later so that it's back in time after
+                        * reset. This way it'll get re-synced on the
+                        * next beacon without breaking ad-hoc.
+                        *
+                        * On AR5212 TSF is almost preserved across a
+                        * reset so it stays back in time anyway and
+                        * we don't have to save/restore it.
+                        *
+                        * XXX: Since this breaks power saving we have
+                        * to disable power saving until we receive the
+                        * next beacon, so we can resync beacon timers */
+                       if (ah->ah_version == AR5K_AR5211) {
+                               tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+                               tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+                       }
+               }
+
+               /* Save default antenna */
+               s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
+
+               if (ah->ah_version == AR5K_AR5212) {
+                       /* Restore normal 32/40MHz clock operation
+                        * to avoid register access delay on certain
+                        * PHY registers */
+                       ath5k_hw_set_sleep_clock(ah, false);
+
+                       /* Since we are going to write rf buffer
+                        * check if we have any pending gain_F
+                        * optimization settings */
+                       if (change_channel && ah->ah_rf_banks != NULL)
+                               ath5k_hw_gainf_calibrate(ah);
+               }
+       }
+
+       /*GPIOs*/
+       s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
+                                       AR5K_PCICFG_LEDSTATE;
+       s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
+       s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
+
+       /* AR5K_STA_ID1 flags, only preserve antenna
+        * settings and ack/cts rate mode */
+       staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
+                       (AR5K_STA_ID1_DEFAULT_ANTENNA |
+                       AR5K_STA_ID1_DESC_ANTENNA |
+                       AR5K_STA_ID1_RTS_DEF_ANTENNA |
+                       AR5K_STA_ID1_ACKCTS_6MB |
+                       AR5K_STA_ID1_BASE_RATE_11B |
+                       AR5K_STA_ID1_SELFGEN_DEF_ANT);
+
+       /* Wakeup the device */
+       ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
+       if (ret)
+               return ret;
+
+       /*
+        * Initialize operating mode
+        */
+       ah->ah_op_mode = op_mode;
+
+       /* PHY access enable */
+       if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
+               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+       else
+               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
+                                                       AR5K_PHY(0));
+
+       /* Write initial settings */
+       ret = ath5k_hw_write_initvals(ah, mode, change_channel);
+       if (ret)
+               return ret;
+
+       /*
+        * 5211/5212 Specific
+        */
+       if (ah->ah_version != AR5K_AR5210) {
+
+               /*
+                * Write initial RF gain settings
+                * This should work for both 5111/5112
+                */
+               ret = ath5k_hw_rfgain_init(ah, freq);
+               if (ret)
+                       return ret;
+
+               mdelay(1);
+
+               /*
+                * Tweak initval settings for revised
+                * chipsets and add some more config
+                * bits
+                */
+               ath5k_hw_tweak_initval_settings(ah, channel);
+
+               /*
+                * Set TX power (FIXME)
+                */
+               ret = ath5k_hw_txpower(ah, channel, ee_mode,
+                                       AR5K_TUNE_DEFAULT_TXPOWER);
+               if (ret)
+                       return ret;
+
+               /* Write rate duration table only on AR5212 and if
+                * virtual interface has already been brought up
+                * XXX: rethink this after new mode changes to
+                * mac80211 are integrated */
+               if (ah->ah_version == AR5K_AR5212 &&
+                       ah->ah_sc->vif != NULL)
+                       ath5k_hw_write_rate_duration(ah, mode);
+
+               /*
+                * Write RF buffer
+                */
+               ret = ath5k_hw_rfregs_init(ah, channel, mode);
+               if (ret)
+                       return ret;
+
+
+               /* Write OFDM timings on 5212*/
+               if (ah->ah_version == AR5K_AR5212 &&
+                       channel->hw_value & CHANNEL_OFDM) {
+                       ret = ath5k_hw_write_ofdm_timings(ah, channel);
+                       if (ret)
+                               return ret;
+               }
+
+               /*Enable/disable 802.11b mode on 5111
+               (enable 2111 frequency converter + CCK)*/
+               if (ah->ah_radio == AR5K_RF5111) {
+                       if (mode == AR5K_MODE_11B)
+                               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
+                                   AR5K_TXCFG_B_MODE);
+                       else
+                               AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+                                   AR5K_TXCFG_B_MODE);
+               }
+
+               /*
+                * In case a fixed antenna was set as default
+                * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
+                * registers.
+                */
+               if (s_ant != 0) {
+                       if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
+                               ant[0] = ant[1] = AR5K_ANT_FIXED_A;
+                       else    /* 2 - Aux */
+                               ant[0] = ant[1] = AR5K_ANT_FIXED_B;
+               } else {
+                       ant[0] = AR5K_ANT_FIXED_A;
+                       ant[1] = AR5K_ANT_FIXED_B;
+               }
+
+               /* Commit values from EEPROM */
+               ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode);
+
+       } else {
+               /*
+                * For 5210 we do all initialization using
+                * initvals, so we don't have to modify
+                * any settings (5210 also only supports
+                * a/aturbo modes)
+                */
+               mdelay(1);
+               /* Disable phy and wait */
+               ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
+               mdelay(1);
+       }
+
+       /*
+        * Restore saved values
+        */
+
+       /*DCU/Antenna selection not available on 5210*/
+       if (ah->ah_version != AR5K_AR5210) {
+
+               if (change_channel) {
+                       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+                               for (i = 0; i < 10; i++)
+                                       ath5k_hw_reg_write(ah, s_seq[i],
+                                               AR5K_QUEUE_DCU_SEQNUM(i));
+                       } else {
+                               ath5k_hw_reg_write(ah, s_seq[0],
+                                       AR5K_QUEUE_DCU_SEQNUM(0));
+                       }
+
+
+                       if (ah->ah_version == AR5K_AR5211) {
+                               ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
+                               ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
+                       }
+               }
+
+               ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
+       }
+
+       /* Ledstate */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
+
+       /* Gpio settings */
+       ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
+       ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
+
+       /* Restore sta_id flags and preserve our mac address*/
+       ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
+                                               AR5K_STA_ID0);
+       ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
+                                               AR5K_STA_ID1);
+
+
+       /*
+        * Configure PCU
+        */
+
+       /* Restore bssid and bssid mask */
+       /* XXX: add ah->aid once mac80211 gives this to us */
+       ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+
+       /* Set PCU config */
+       ath5k_hw_set_opmode(ah);
+
+       /* Clear any pending interrupts
+        * PISR/SISR Not available on 5210 */
+       if (ah->ah_version != AR5K_AR5210)
+               ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
+
+       /* Set RSSI/BRSSI thresholds
+        *
+        * Note: If we decide to set this value
+        * dynamicaly, have in mind that when AR5K_RSSI_THR
+        * register is read it might return 0x40 if we haven't
+        * wrote anything to it plus BMISS RSSI threshold is zeroed.
+        * So doing a save/restore procedure here isn't the right
+        * choice. Instead store it on ath5k_hw */
+       ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
+                               AR5K_TUNE_BMISS_THRES <<
+                               AR5K_RSSI_THR_BMISS_S),
+                               AR5K_RSSI_THR);
+
+       /* MIC QoS support */
+       if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
+               ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
+               ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
+       }
+
+       /* QoS NOACK Policy */
+       if (ah->ah_version == AR5K_AR5212) {
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
+                       AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET)  |
+                       AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
+                       AR5K_QOS_NOACK);
+       }
+
+
+       /*
+        * Configure PHY
+        */
+
+       /* Set channel on PHY */
+       ret = ath5k_hw_channel(ah, channel);
+       if (ret)
+               return ret;
+
+       /*
+        * Enable the PHY and wait until completion
+        * This includes BaseBand and Synthesizer
+        * activation.
+        */
+       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
+
+       /*
+        * On 5211+ read activation -> rx delay
+        * and use it.
+        *
+        * TODO: Half/quarter rate support
+        */
+       if (ah->ah_version != AR5K_AR5210) {
+               u32 delay;
+               delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
+                       AR5K_PHY_RX_DELAY_M;
+               delay = (channel->hw_value & CHANNEL_CCK) ?
+                       ((delay << 2) / 22) : (delay / 10);
+
+               udelay(100 + (2 * delay));
+       } else {
+               mdelay(1);
+       }
+
+       /*
+        * Perform ADC test to see if baseband is ready
+        * Set tx hold and check adc test register
+        */
+       phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
+       ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
+       for (i = 0; i <= 20; i++) {
+               if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
+                       break;
+               udelay(200);
+       }
+       ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
+
+       /*
+        * Start automatic gain control calibration
+        *
+        * During AGC calibration RX path is re-routed to
+        * a power detector so we don't receive anything.
+        *
+        * This method is used to calibrate some static offsets
+        * used together with on-the fly I/Q calibration (the
+        * one performed via ath5k_hw_phy_calibrate), that doesn't
+        * interrupt rx path.
+        *
+        * While rx path is re-routed to the power detector we also
+        * start a noise floor calibration, to measure the
+        * card's noise floor (the noise we measure when we are not
+        * transmiting or receiving anything).
+        *
+        * If we are in a noisy environment AGC calibration may time
+        * out and/or noise floor calibration might timeout.
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+                               AR5K_PHY_AGCCTL_CAL);
+
+       /* At the same time start I/Q calibration for QAM constellation
+        * -no need for CCK- */
+       ah->ah_calibration = false;
+       if (!(mode == AR5K_MODE_11B)) {
+               ah->ah_calibration = true;
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
+                               AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+                               AR5K_PHY_IQ_RUN);
+       }
+
+       /* Wait for gain calibration to finish (we check for I/Q calibration
+        * during ath5k_phy_calibrate) */
+       if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
+                       AR5K_PHY_AGCCTL_CAL, 0, false)) {
+               ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
+                       channel->center_freq);
+       }
+
+       /*
+        * If we run NF calibration before AGC, it always times out.
+        * Binary HAL starts NF and AGC calibration at the same time
+        * and only waits for AGC to finish. Also if AGC or NF cal.
+        * times out, reset doesn't fail on binary HAL. I believe
+        * that's wrong because since rx path is routed to a detector,
+        * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
+        * enables noise floor calibration after offset calibration and if noise
+        * floor calibration fails, reset fails. I believe that's
+        * a better approach, we just need to find a polling interval
+        * that suits best, even if reset continues we need to make
+        * sure that rx path is ready.
+        */
+       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+
+
+       /*
+        * Configure QCUs/DCUs
+        */
+
+       /* TODO: HW Compression support for data queues */
+       /* TODO: Burst prefetch for data queues */
+
+       /*
+        * Reset queues and start beacon timers at the end of the reset routine
+        * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
+        * Note: If we want we can assign multiple qcus on one dcu.
+        */
+       for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
+               ret = ath5k_hw_reset_tx_queue(ah, i);
+               if (ret) {
+                       ATH5K_ERR(ah->ah_sc,
+                               "failed to reset TX queue #%d\n", i);
+                       return ret;
+               }
+       }
+
+
+       /*
+        * Configure DMA/Interrupts
+        */
+
+       /*
+        * Set Rx/Tx DMA Configuration
+        *
+        * Set standard DMA size (128). Note that
+        * a DMA size of 512 causes rx overruns and tx errors
+        * on pci-e cards (tested on 5424 but since rx overruns
+        * also occur on 5416/5418 with madwifi we set 128
+        * for all PCI-E cards to be safe).
+        *
+        * XXX: need to check 5210 for this
+        * TODO: Check out tx triger level, it's always 64 on dumps but I
+        * guess we can tweak it and see how it goes ;-)
+        */
+       if (ah->ah_version != AR5K_AR5210) {
+               AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+                       AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+               AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+                       AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+       }
+
+       /* Pre-enable interrupts on 5211/5212*/
+       if (ah->ah_version != AR5K_AR5210)
+               ath5k_hw_set_imr(ah, ah->ah_imr);
+
+       /*
+        * Setup RFKill interrupt if rfkill flag is set on eeprom.
+        * TODO: Use gpio pin and polarity infos from eeprom
+        * TODO: Handle this in ath5k_intr because it'll result
+        *       a nasty interrupt storm.
+        */
+#if 0
+       if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
+               ath5k_hw_set_gpio_input(ah, 0);
+               ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
+               if (ah->ah_gpio[0] == 0)
+                       ath5k_hw_set_gpio_intr(ah, 0, 1);
+               else
+                       ath5k_hw_set_gpio_intr(ah, 0, 0);
+       }
+#endif
+
+       /* Enable 32KHz clock function for AR5212+ chips
+        * Set clocks to 32KHz operation and use an
+        * external 32KHz crystal when sleeping if one
+        * exists */
+       if (ah->ah_version == AR5K_AR5212)
+                       ath5k_hw_set_sleep_clock(ah, true);
+
+       /*
+        * Disable beacons and reset the register
+        */
+       AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
+                       AR5K_BEACON_RESET_TSF);
+
+       return 0;
+}
+
+#undef _ATH5K_RESET
diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h
new file mode 100644 (file)
index 0000000..e50baff
--- /dev/null
@@ -0,0 +1,1181 @@
+/*
+ * RF Buffer handling functions
+ *
+ * Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+
+/*
+ * There are some special registers on the RF chip
+ * that control various operation settings related mostly to
+ * the analog parts (channel, gain adjustment etc).
+ *
+ * We don't write on those registers directly but
+ * we send a data packet on the chip, using a special register,
+ * that holds all the settings we need. After we 've sent the
+ * data packet, we write on another special register to notify hw
+ * to apply the settings. This is done so that control registers
+ * can be dynamicaly programmed during operation and the settings
+ * are applied faster on the hw.
+ *
+ * We call each data packet an "RF Bank" and all the data we write
+ * (all RF Banks) "RF Buffer". This file holds initial RF Buffer
+ * data for the different RF chips, and various info to match RF
+ * Buffer offsets with specific RF registers so that we can access
+ * them. We tweak these settings on rfregs_init function.
+ *
+ * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer
+ * registers and control registers):
+ *
+ * http://www.google.com/patents?id=qNURAAAAEBAJ
+ */
+
+
+/*
+ * Struct to hold default mode specific RF
+ * register values (RF Banks)
+ */
+struct ath5k_ini_rfbuffer {
+       u8      rfb_bank;               /* RF Bank number */
+       u16     rfb_ctrl_register;      /* RF Buffer control register */
+       u32     rfb_mode_data[5];       /* RF Buffer data for each mode */
+};
+
+/*
+ * Struct to hold RF Buffer field
+ * infos used to access certain RF
+ * analog registers
+ */
+struct ath5k_rfb_field {
+       u8      len;    /* Field length */
+       u16     pos;    /* Offset on the raw packet */
+       u8      col;    /* Column -used for shifting */
+};
+
+/*
+ * RF analog register definition
+ */
+struct ath5k_rf_reg {
+       u8                      bank;   /* RF Buffer Bank number */
+       u8                      index;  /* Register's index on rf_regs_idx */
+       struct ath5k_rfb_field  field;  /* RF Buffer field for this register */
+};
+
+/* Map RF registers to indexes
+ * We do this to handle common bits and make our
+ * life easier by using an index for each register
+ * instead of a full rfb_field */
+enum ath5k_rf_regs_idx {
+       /* BANK 6 */
+       AR5K_RF_OB_2GHZ = 0,
+       AR5K_RF_OB_5GHZ,
+       AR5K_RF_DB_2GHZ,
+       AR5K_RF_DB_5GHZ,
+       AR5K_RF_FIXED_BIAS_A,
+       AR5K_RF_FIXED_BIAS_B,
+       AR5K_RF_PWD_XPD,
+       AR5K_RF_XPD_SEL,
+       AR5K_RF_XPD_GAIN,
+       AR5K_RF_PD_GAIN_LO,
+       AR5K_RF_PD_GAIN_HI,
+       AR5K_RF_HIGH_VC_CP,
+       AR5K_RF_MID_VC_CP,
+       AR5K_RF_LOW_VC_CP,
+       AR5K_RF_PUSH_UP,
+       AR5K_RF_PAD2GND,
+       AR5K_RF_XB2_LVL,
+       AR5K_RF_XB5_LVL,
+       AR5K_RF_PWD_ICLOBUF_2G,
+       AR5K_RF_PWD_84,
+       AR5K_RF_PWD_90,
+       AR5K_RF_PWD_130,
+       AR5K_RF_PWD_131,
+       AR5K_RF_PWD_132,
+       AR5K_RF_PWD_136,
+       AR5K_RF_PWD_137,
+       AR5K_RF_PWD_138,
+       AR5K_RF_PWD_166,
+       AR5K_RF_PWD_167,
+       AR5K_RF_DERBY_CHAN_SEL_MODE,
+       /* BANK 7 */
+       AR5K_RF_GAIN_I,
+       AR5K_RF_PLO_SEL,
+       AR5K_RF_RFGAIN_SEL,
+       AR5K_RF_RFGAIN_STEP,
+       AR5K_RF_WAIT_S,
+       AR5K_RF_WAIT_I,
+       AR5K_RF_MAX_TIME,
+       AR5K_RF_MIXVGA_OVR,
+       AR5K_RF_MIXGAIN_OVR,
+       AR5K_RF_MIXGAIN_STEP,
+       AR5K_RF_PD_DELAY_A,
+       AR5K_RF_PD_DELAY_B,
+       AR5K_RF_PD_DELAY_XR,
+       AR5K_RF_PD_PERIOD_A,
+       AR5K_RF_PD_PERIOD_B,
+       AR5K_RF_PD_PERIOD_XR,
+};
+
+
+/*******************\
+* RF5111 (Sombrero) *
+\*******************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF5111_OB_2GHZ             { 3, 119, 0 }
+#define        AR5K_RF5111_DB_2GHZ             { 3, 122, 0 }
+
+#define        AR5K_RF5111_OB_5GHZ             { 3, 104, 0 }
+#define        AR5K_RF5111_DB_5GHZ             { 3, 107, 0 }
+
+#define        AR5K_RF5111_PWD_XPD             { 1, 95,  0 }
+#define        AR5K_RF5111_XPD_GAIN            { 4, 96,  0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5111_PWD(_n)            { 1, (135 - _n), 3 }
+
+/* BANK 7                              len  pos col */
+#define        AR5K_RF5111_GAIN_I              { 6, 29,  0 }
+#define        AR5K_RF5111_PLO_SEL             { 1, 4,   0 }
+#define        AR5K_RF5111_RFGAIN_SEL          { 1, 36,  0 }
+#define AR5K_RF5111_RFGAIN_STEP                { 6, 37,  0 }
+/* Only on AR5212 BaseBand and up */
+#define        AR5K_RF5111_WAIT_S              { 5, 19,  0 }
+#define        AR5K_RF5111_WAIT_I              { 5, 24,  0 }
+#define        AR5K_RF5111_MAX_TIME            { 2, 49,  0 }
+
+static const struct ath5k_rf_reg rf_regs_5111[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5111_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5111_DB_2GHZ},
+       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5111_OB_5GHZ},
+       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5111_DB_5GHZ},
+       {6, AR5K_RF_PWD_XPD,            AR5K_RF5111_PWD_XPD},
+       {6, AR5K_RF_XPD_GAIN,           AR5K_RF5111_XPD_GAIN},
+       {6, AR5K_RF_PWD_84,             AR5K_RF5111_PWD(84)},
+       {6, AR5K_RF_PWD_90,             AR5K_RF5111_PWD(90)},
+       {7, AR5K_RF_GAIN_I,             AR5K_RF5111_GAIN_I},
+       {7, AR5K_RF_PLO_SEL,            AR5K_RF5111_PLO_SEL},
+       {7, AR5K_RF_RFGAIN_SEL,         AR5K_RF5111_RFGAIN_SEL},
+       {7, AR5K_RF_RFGAIN_STEP,        AR5K_RF5111_RFGAIN_STEP},
+       {7, AR5K_RF_WAIT_S,             AR5K_RF5111_WAIT_S},
+       {7, AR5K_RF_WAIT_I,             AR5K_RF5111_WAIT_I},
+       {7, AR5K_RF_MAX_TIME,           AR5K_RF5111_MAX_TIME}
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5111[] = {
+       { 0, 0x989c,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
+       { 0, 0x989c,
+           { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
+       { 0, 0x98d4,
+           { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
+       { 1, 0x98d4,
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d4,
+           { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
+       { 3, 0x98d8,
+           { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+       { 6, 0x989c,
+           { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
+       { 6, 0x989c,
+           { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
+       { 6, 0x989c,
+           { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
+       { 6, 0x989c,
+           { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
+       { 6, 0x989c,
+           { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
+       { 6, 0x98d4,
+           { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
+       { 7, 0x989c,
+           { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
+       { 7, 0x989c,
+           { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
+       { 7, 0x989c,
+           { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+       { 7, 0x989c,
+           { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
+       { 7, 0x989c,
+           { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
+       { 7, 0x989c,
+           { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
+       { 7, 0x989c,
+           { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***********************\
+* RF5112/RF2112 (Derby) *
+\***********************/
+
+/* BANK 7 (Common)                     len  pos col */
+#define        AR5K_RF5112X_GAIN_I             { 6, 14,  0 }
+#define        AR5K_RF5112X_MIXVGA_OVR         { 1, 36,  0 }
+#define        AR5K_RF5112X_MIXGAIN_OVR        { 2, 37,  0 }
+#define AR5K_RF5112X_MIXGAIN_STEP      { 4, 32,  0 }
+#define        AR5K_RF5112X_PD_DELAY_A         { 4, 58,  0 }
+#define        AR5K_RF5112X_PD_DELAY_B         { 4, 62,  0 }
+#define        AR5K_RF5112X_PD_DELAY_XR        { 4, 66,  0 }
+#define        AR5K_RF5112X_PD_PERIOD_A        { 4, 70,  0 }
+#define        AR5K_RF5112X_PD_PERIOD_B        { 4, 74,  0 }
+#define        AR5K_RF5112X_PD_PERIOD_XR       { 4, 78,  0 }
+
+/* RFX112 (Derby 1) */
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF5112_OB_2GHZ             { 3, 269, 0 }
+#define        AR5K_RF5112_DB_2GHZ             { 3, 272, 0 }
+
+#define        AR5K_RF5112_OB_5GHZ             { 3, 261, 0 }
+#define        AR5K_RF5112_DB_5GHZ             { 3, 264, 0 }
+
+#define        AR5K_RF5112_FIXED_BIAS_A        { 1, 260, 0 }
+#define        AR5K_RF5112_FIXED_BIAS_B        { 1, 259, 0 }
+
+#define        AR5K_RF5112_XPD_SEL             { 1, 284, 0 }
+#define        AR5K_RF5112_XPD_GAIN            { 2, 252, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112_PWD(_n)            { 1, (302 - _n), 3 }
+
+static const struct ath5k_rf_reg rf_regs_5112[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5112_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5112_DB_2GHZ},
+       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5112_OB_5GHZ},
+       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5112_DB_5GHZ},
+       {6, AR5K_RF_FIXED_BIAS_A,       AR5K_RF5112_FIXED_BIAS_A},
+       {6, AR5K_RF_FIXED_BIAS_B,       AR5K_RF5112_FIXED_BIAS_B},
+       {6, AR5K_RF_XPD_SEL,            AR5K_RF5112_XPD_SEL},
+       {6, AR5K_RF_XPD_GAIN,           AR5K_RF5112_XPD_GAIN},
+       {6, AR5K_RF_PWD_130,            AR5K_RF5112_PWD(130)},
+       {6, AR5K_RF_PWD_131,            AR5K_RF5112_PWD(131)},
+       {6, AR5K_RF_PWD_132,            AR5K_RF5112_PWD(132)},
+       {6, AR5K_RF_PWD_136,            AR5K_RF5112_PWD(136)},
+       {6, AR5K_RF_PWD_137,            AR5K_RF5112_PWD(137)},
+       {6, AR5K_RF_PWD_138,            AR5K_RF5112_PWD(138)},
+       {7, AR5K_RF_GAIN_I,             AR5K_RF5112X_GAIN_I},
+       {7, AR5K_RF_MIXVGA_OVR,         AR5K_RF5112X_MIXVGA_OVR},
+       {7, AR5K_RF_MIXGAIN_OVR,        AR5K_RF5112X_MIXGAIN_OVR},
+       {7, AR5K_RF_MIXGAIN_STEP,       AR5K_RF5112X_MIXGAIN_STEP},
+       {7, AR5K_RF_PD_DELAY_A,         AR5K_RF5112X_PD_DELAY_A},
+       {7, AR5K_RF_PD_DELAY_B,         AR5K_RF5112X_PD_DELAY_B},
+       {7, AR5K_RF_PD_DELAY_XR,        AR5K_RF5112X_PD_DELAY_XR},
+       {7, AR5K_RF_PD_PERIOD_A,        AR5K_RF5112X_PD_PERIOD_A},
+       {7, AR5K_RF_PD_PERIOD_B,        AR5K_RF5112X_PD_PERIOD_B},
+       {7, AR5K_RF_PD_PERIOD_XR,       AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+       { 3, 0x98dc,
+           { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
+       { 6, 0x989c,
+           { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
+       { 6, 0x989c,
+           { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
+       { 6, 0x989c,
+           { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
+       { 6, 0x989c,
+           { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
+       { 6, 0x989c,
+           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+       { 6, 0x989c,
+           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+       { 6, 0x989c,
+           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
+       { 6, 0x989c,
+           { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
+       { 6, 0x989c,
+           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+       { 6, 0x989c,
+           { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+       { 6, 0x989c,
+           { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
+       { 6, 0x989c,
+           { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
+       { 6, 0x989c,
+           { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+       { 6, 0x989c,
+           { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
+       { 6, 0x989c,
+           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+       { 6, 0x989c,
+           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+       { 6, 0x989c,
+           { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
+       { 6, 0x989c,
+           { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
+       { 6, 0x989c,
+           { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+       { 6, 0x989c,
+           { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
+       { 6, 0x989c,
+           { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
+       { 6, 0x989c,
+           { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
+       { 6, 0x989c,
+           { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
+       { 6, 0x989c,
+           { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
+       { 6, 0x989c,
+           { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
+       { 6, 0x989c,
+           { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
+       { 6, 0x989c,
+           { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
+       { 6, 0x989c,
+           { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
+       { 6, 0x989c,
+           { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
+       { 6, 0x98d0,
+           { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
+       { 7, 0x989c,
+           { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+       { 7, 0x989c,
+           { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+       { 7, 0x989c,
+           { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
+       { 7, 0x989c,
+           { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+       { 7, 0x989c,
+           { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
+       { 7, 0x989c,
+           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+       { 7, 0x989c,
+           { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+       { 7, 0x989c,
+           { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
+       { 7, 0x989c,
+           { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
+       { 7, 0x989c,
+           { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+       { 7, 0x989c,
+           { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+       { 7, 0x989c,
+           { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+       { 7, 0x98c4,
+           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+/* RFX112A (Derby 2) */
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF5112A_OB_2GHZ            { 3, 287, 0 }
+#define        AR5K_RF5112A_DB_2GHZ            { 3, 290, 0 }
+
+#define        AR5K_RF5112A_OB_5GHZ            { 3, 279, 0 }
+#define        AR5K_RF5112A_DB_5GHZ            { 3, 282, 0 }
+
+#define        AR5K_RF5112A_FIXED_BIAS_A       { 1, 278, 0 }
+#define        AR5K_RF5112A_FIXED_BIAS_B       { 1, 277, 0 }
+
+#define        AR5K_RF5112A_XPD_SEL            { 1, 302, 0 }
+#define        AR5K_RF5112A_PDGAINLO           { 2, 270, 0 }
+#define        AR5K_RF5112A_PDGAINHI           { 2, 257, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112A_PWD(_n)           { 1, (306 - _n), 3 }
+
+/* Voltage regulators */
+#define        AR5K_RF5112A_HIGH_VC_CP         { 2, 90,  2 }
+#define        AR5K_RF5112A_MID_VC_CP          { 2, 92,  2 }
+#define        AR5K_RF5112A_LOW_VC_CP          { 2, 94,  2 }
+#define        AR5K_RF5112A_PUSH_UP            { 1, 254,  2 }
+
+/* Power consumption */
+#define        AR5K_RF5112A_PAD2GND            { 1, 281, 1 }
+#define        AR5K_RF5112A_XB2_LVL            { 2, 1,   3 }
+#define        AR5K_RF5112A_XB5_LVL            { 2, 3,   3 }
+
+static const struct ath5k_rf_reg rf_regs_5112a[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5112A_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5112A_DB_2GHZ},
+       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5112A_OB_5GHZ},
+       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5112A_DB_5GHZ},
+       {6, AR5K_RF_FIXED_BIAS_A,       AR5K_RF5112A_FIXED_BIAS_A},
+       {6, AR5K_RF_FIXED_BIAS_B,       AR5K_RF5112A_FIXED_BIAS_B},
+       {6, AR5K_RF_XPD_SEL,            AR5K_RF5112A_XPD_SEL},
+       {6, AR5K_RF_PD_GAIN_LO,         AR5K_RF5112A_PDGAINLO},
+       {6, AR5K_RF_PD_GAIN_HI,         AR5K_RF5112A_PDGAINHI},
+       {6, AR5K_RF_PWD_130,            AR5K_RF5112A_PWD(130)},
+       {6, AR5K_RF_PWD_131,            AR5K_RF5112A_PWD(131)},
+       {6, AR5K_RF_PWD_132,            AR5K_RF5112A_PWD(132)},
+       {6, AR5K_RF_PWD_136,            AR5K_RF5112A_PWD(136)},
+       {6, AR5K_RF_PWD_137,            AR5K_RF5112A_PWD(137)},
+       {6, AR5K_RF_PWD_138,            AR5K_RF5112A_PWD(138)},
+       {6, AR5K_RF_PWD_166,            AR5K_RF5112A_PWD(166)},
+       {6, AR5K_RF_PWD_167,            AR5K_RF5112A_PWD(167)},
+       {6, AR5K_RF_HIGH_VC_CP,         AR5K_RF5112A_HIGH_VC_CP},
+       {6, AR5K_RF_MID_VC_CP,          AR5K_RF5112A_MID_VC_CP},
+       {6, AR5K_RF_LOW_VC_CP,          AR5K_RF5112A_LOW_VC_CP},
+       {6, AR5K_RF_PUSH_UP,            AR5K_RF5112A_PUSH_UP},
+       {6, AR5K_RF_PAD2GND,            AR5K_RF5112A_PAD2GND},
+       {6, AR5K_RF_XB2_LVL,            AR5K_RF5112A_XB2_LVL},
+       {6, AR5K_RF_XB5_LVL,            AR5K_RF5112A_XB5_LVL},
+       {7, AR5K_RF_GAIN_I,             AR5K_RF5112X_GAIN_I},
+       {7, AR5K_RF_MIXVGA_OVR,         AR5K_RF5112X_MIXVGA_OVR},
+       {7, AR5K_RF_MIXGAIN_OVR,        AR5K_RF5112X_MIXGAIN_OVR},
+       {7, AR5K_RF_MIXGAIN_STEP,       AR5K_RF5112X_MIXGAIN_STEP},
+       {7, AR5K_RF_PD_DELAY_A,         AR5K_RF5112X_PD_DELAY_A},
+       {7, AR5K_RF_PD_DELAY_B,         AR5K_RF5112X_PD_DELAY_B},
+       {7, AR5K_RF_PD_DELAY_XR,        AR5K_RF5112X_PD_DELAY_XR},
+       {7, AR5K_RF_PD_PERIOD_A,        AR5K_RF5112X_PD_PERIOD_A},
+       {7, AR5K_RF_PD_PERIOD_B,        AR5K_RF5112X_PD_PERIOD_B},
+       {7, AR5K_RF_PD_PERIOD_XR,       AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
+       { 6, 0x989c,
+           { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
+       { 6, 0x989c,
+           { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
+       { 6, 0x989c,
+           { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
+       { 6, 0x989c,
+           { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
+       { 6, 0x989c,
+           { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
+       { 6, 0x989c,
+           { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
+       { 6, 0x989c,
+           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+       { 6, 0x989c,
+           { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
+       { 6, 0x989c,
+           { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+       { 6, 0x989c,
+           { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
+       { 6, 0x989c,
+           { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
+       { 6, 0x989c,
+           { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+       { 6, 0x989c,
+           { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
+       { 6, 0x989c,
+           { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
+       { 6, 0x989c,
+           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+       { 6, 0x989c,
+           { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
+       { 6, 0x989c,
+           { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
+       { 6, 0x989c,
+           { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
+       { 6, 0x989c,
+           { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
+       { 6, 0x989c,
+           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
+       { 6, 0x989c,
+           { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
+       { 6, 0x989c,
+           { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
+       { 6, 0x989c,
+           { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
+       { 6, 0x989c,
+           { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
+       { 6, 0x98d8,
+           { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
+       { 7, 0x989c,
+           { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+       { 7, 0x989c,
+           { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+       { 7, 0x989c,
+           { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
+       { 7, 0x989c,
+           { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+       { 7, 0x989c,
+           { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
+       { 7, 0x989c,
+           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+       { 7, 0x989c,
+           { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+       { 7, 0x989c,
+           { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
+       { 7, 0x989c,
+           { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
+       { 7, 0x989c,
+           { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+       { 7, 0x989c,
+           { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+       { 7, 0x989c,
+           { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+       { 7, 0x98c4,
+           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+
+
+/******************\
+* RF2413 (Griffin) *
+\******************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF2413_OB_2GHZ             { 3, 168, 0 }
+#define        AR5K_RF2413_DB_2GHZ             { 3, 165, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2413[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2413_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2413_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ???
+ */
+static const struct ath5k_ini_rfbuffer rfb_2413[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
+       { 6, 0x989c,
+           { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
+       { 6, 0x989c,
+           { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
+       { 6, 0x989c,
+           { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
+       { 6, 0x989c,
+           { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
+       { 6, 0x989c,
+           { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
+       { 6, 0x989c,
+           { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
+       { 6, 0x989c,
+           { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
+       { 6, 0x989c,
+           { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
+       { 6, 0x989c,
+           { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
+       { 6, 0x989c,
+           { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
+       { 6, 0x989c,
+           { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
+       { 6, 0x989c,
+           { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
+       { 6, 0x98d8,
+           { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2315/RF2316 (Cobra SoC) *
+\***************************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF2316_OB_2GHZ             { 3, 178, 0 }
+#define        AR5K_RF2316_DB_2GHZ             { 3, 175, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2316[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2316_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2316_DB_2GHZ},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_2316[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
+       { 6, 0x989c,
+           { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+       { 6, 0x989c,
+           { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
+       { 6, 0x989c,
+           { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
+       { 6, 0x989c,
+           { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
+       { 6, 0x989c,
+           { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
+       { 6, 0x989c,
+           { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
+       { 6, 0x989c,
+           { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+       { 6, 0x989c,
+           { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
+       { 6, 0x989c,
+           { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
+       { 6, 0x989c,
+           { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
+       { 6, 0x989c,
+           { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
+       { 6, 0x989c,
+           { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
+       { 6, 0x989c,
+           { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
+       { 6, 0x989c,
+           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+       { 6, 0x989c,
+           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+       { 6, 0x989c,
+           { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
+       { 6, 0x989c,
+           { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
+       { 6, 0x98c0,
+           { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/******************************\
+* RF5413/RF5424 (Eagle/Condor) *
+\******************************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF5413_OB_2GHZ             { 3, 241, 0 }
+#define        AR5K_RF5413_DB_2GHZ             { 3, 238, 0 }
+
+#define        AR5K_RF5413_OB_5GHZ             { 3, 247, 0 }
+#define        AR5K_RF5413_DB_5GHZ             { 3, 244, 0 }
+
+#define        AR5K_RF5413_PWD_ICLOBUF2G       { 3, 131, 3 }
+#define        AR5K_RF5413_DERBY_CHAN_SEL_MODE { 1, 291, 2 }
+
+static const struct ath5k_rf_reg rf_regs_5413[] = {
+       {6, AR5K_RF_OB_2GHZ,             AR5K_RF5413_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,             AR5K_RF5413_DB_2GHZ},
+       {6, AR5K_RF_OB_5GHZ,             AR5K_RF5413_OB_5GHZ},
+       {6, AR5K_RF_DB_5GHZ,             AR5K_RF5413_DB_5GHZ},
+       {6, AR5K_RF_PWD_ICLOBUF_2G,      AR5K_RF5413_PWD_ICLOBUF2G},
+       {6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5413[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+       { 3, 0x98dc,
+           { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
+       { 6, 0x989c,
+           { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
+       { 6, 0x989c,
+           { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
+       { 6, 0x989c,
+           { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
+       { 6, 0x989c,
+           { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+       { 6, 0x989c,
+           { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+       { 6, 0x989c,
+           { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
+       { 6, 0x989c,
+           { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
+       { 6, 0x989c,
+           { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
+       { 6, 0x989c,
+           { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
+       { 6, 0x989c,
+           { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
+       { 6, 0x989c,
+           { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
+       { 6, 0x989c,
+           { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+       { 6, 0x989c,
+           { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
+       { 6, 0x989c,
+           { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+       { 6, 0x989c,
+           { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
+       { 6, 0x989c,
+           { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
+       { 6, 0x989c,
+           { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
+       { 6, 0x989c,
+           { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
+       { 6, 0x989c,
+           { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
+       { 6, 0x989c,
+           { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
+       { 6, 0x989c,
+           { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
+       { 6, 0x98c8,
+           { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2425/RF2417 (Swan/Nala) *
+* AR2317 (Spider SoC)       *
+\***************************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF2425_OB_2GHZ             { 3, 193, 0 }
+#define        AR5K_RF2425_DB_2GHZ             { 3, 190, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2425[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2425_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2425_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2425[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+       { 6, 0x989c,
+           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+       { 6, 0x989c,
+           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+       { 6, 0x989c,
+           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+       { 6, 0x989c,
+           { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+       { 6, 0x989c,
+           { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+       { 6, 0x989c,
+           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+       { 6, 0x989c,
+           { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+       { 6, 0x989c,
+           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+       { 6, 0x989c,
+           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+       { 6, 0x989c,
+           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+       { 6, 0x989c,
+           { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+       { 6, 0x98c4,
+           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ */
+static const struct ath5k_ini_rfbuffer rfb_2317[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+       { 6, 0x989c,
+           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+       { 6, 0x989c,
+           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+       { 6, 0x989c,
+           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+       { 6, 0x989c,
+           { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+       { 6, 0x989c,
+           { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
+       { 6, 0x989c,
+           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+       { 6, 0x989c,
+           { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+       { 6, 0x989c,
+           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+       { 6, 0x989c,
+           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+       { 6, 0x989c,
+           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+       { 6, 0x989c,
+           { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
+       { 6, 0x98c4,
+           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2417[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+       { 6, 0x989c,
+           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+       { 6, 0x989c,
+           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+       { 6, 0x989c,
+           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+       { 6, 0x989c,
+           { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
+       { 6, 0x989c,
+           { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+       { 6, 0x989c,
+           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+       { 6, 0x989c,
+           { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
+       { 6, 0x989c,
+           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+       { 6, 0x989c,
+           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+       { 6, 0x989c,
+           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+       { 6, 0x989c,
+           { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+       { 6, 0x98c4,
+           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
diff --git a/drivers/net/wireless/ath/ath5k/rfgain.h b/drivers/net/wireless/ath/ath5k/rfgain.h
new file mode 100644 (file)
index 0000000..1354d8c
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+ * RF Gain optimization
+ *
+ * Copyright (c) 2004-2009 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*
+ * Mode-specific RF Gain table (64bytes) for RF5111/5112
+ * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
+ * RF Gain values are included in AR5K_AR5210_INI)
+ */
+struct ath5k_ini_rfgain {
+       u16     rfg_register;   /* RF Gain register address */
+       u32     rfg_value[2];   /* [freq (see below)] */
+};
+
+/* Initial RF Gain settings for RF5111 */
+static const struct ath5k_ini_rfgain rfgain_5111[] = {
+       /*                            5Ghz      2Ghz    */
+       { AR5K_RF_GAIN(0),      { 0x000001a9, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x000001e9, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000029, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x00000069, 0x00000150 } },
+       { AR5K_RF_GAIN(4),      { 0x00000199, 0x00000190 } },
+       { AR5K_RF_GAIN(5),      { 0x000001d9, 0x000001d0 } },
+       { AR5K_RF_GAIN(6),      { 0x00000019, 0x00000010 } },
+       { AR5K_RF_GAIN(7),      { 0x00000059, 0x00000044 } },
+       { AR5K_RF_GAIN(8),      { 0x00000099, 0x00000084 } },
+       { AR5K_RF_GAIN(9),      { 0x000001a5, 0x00000148 } },
+       { AR5K_RF_GAIN(10),     { 0x000001e5, 0x00000188 } },
+       { AR5K_RF_GAIN(11),     { 0x00000025, 0x000001c8 } },
+       { AR5K_RF_GAIN(12),     { 0x000001c8, 0x00000014 } },
+       { AR5K_RF_GAIN(13),     { 0x00000008, 0x00000042 } },
+       { AR5K_RF_GAIN(14),     { 0x00000048, 0x00000082 } },
+       { AR5K_RF_GAIN(15),     { 0x00000088, 0x00000178 } },
+       { AR5K_RF_GAIN(16),     { 0x00000198, 0x000001b8 } },
+       { AR5K_RF_GAIN(17),     { 0x000001d8, 0x000001f8 } },
+       { AR5K_RF_GAIN(18),     { 0x00000018, 0x00000012 } },
+       { AR5K_RF_GAIN(19),     { 0x00000058, 0x00000052 } },
+       { AR5K_RF_GAIN(20),     { 0x00000098, 0x00000092 } },
+       { AR5K_RF_GAIN(21),     { 0x000001a4, 0x0000017c } },
+       { AR5K_RF_GAIN(22),     { 0x000001e4, 0x000001bc } },
+       { AR5K_RF_GAIN(23),     { 0x00000024, 0x000001fc } },
+       { AR5K_RF_GAIN(24),     { 0x00000064, 0x0000000a } },
+       { AR5K_RF_GAIN(25),     { 0x000000a4, 0x0000004a } },
+       { AR5K_RF_GAIN(26),     { 0x000000e4, 0x0000008a } },
+       { AR5K_RF_GAIN(27),     { 0x0000010a, 0x0000015a } },
+       { AR5K_RF_GAIN(28),     { 0x0000014a, 0x0000019a } },
+       { AR5K_RF_GAIN(29),     { 0x0000018a, 0x000001da } },
+       { AR5K_RF_GAIN(30),     { 0x000001ca, 0x0000000e } },
+       { AR5K_RF_GAIN(31),     { 0x0000000a, 0x0000004e } },
+       { AR5K_RF_GAIN(32),     { 0x0000004a, 0x0000008e } },
+       { AR5K_RF_GAIN(33),     { 0x0000008a, 0x0000015e } },
+       { AR5K_RF_GAIN(34),     { 0x000001ba, 0x0000019e } },
+       { AR5K_RF_GAIN(35),     { 0x000001fa, 0x000001de } },
+       { AR5K_RF_GAIN(36),     { 0x0000003a, 0x00000009 } },
+       { AR5K_RF_GAIN(37),     { 0x0000007a, 0x00000049 } },
+       { AR5K_RF_GAIN(38),     { 0x00000186, 0x00000089 } },
+       { AR5K_RF_GAIN(39),     { 0x000001c6, 0x00000179 } },
+       { AR5K_RF_GAIN(40),     { 0x00000006, 0x000001b9 } },
+       { AR5K_RF_GAIN(41),     { 0x00000046, 0x000001f9 } },
+       { AR5K_RF_GAIN(42),     { 0x00000086, 0x00000039 } },
+       { AR5K_RF_GAIN(43),     { 0x000000c6, 0x00000079 } },
+       { AR5K_RF_GAIN(44),     { 0x000000c6, 0x000000b9 } },
+       { AR5K_RF_GAIN(45),     { 0x000000c6, 0x000001bd } },
+       { AR5K_RF_GAIN(46),     { 0x000000c6, 0x000001fd } },
+       { AR5K_RF_GAIN(47),     { 0x000000c6, 0x0000003d } },
+       { AR5K_RF_GAIN(48),     { 0x000000c6, 0x0000007d } },
+       { AR5K_RF_GAIN(49),     { 0x000000c6, 0x000000bd } },
+       { AR5K_RF_GAIN(50),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(51),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(52),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(53),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(54),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(55),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(56),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(57),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(58),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(59),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(60),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(61),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(62),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(63),     { 0x000000c6, 0x000000fd } },
+};
+
+/* Initial RF Gain settings for RF5112 */
+static const struct ath5k_ini_rfgain rfgain_5112[] = {
+       /*                            5Ghz      2Ghz    */
+       { AR5K_RF_GAIN(0),      { 0x00000007, 0x00000007 } },
+       { AR5K_RF_GAIN(1),      { 0x00000047, 0x00000047 } },
+       { AR5K_RF_GAIN(2),      { 0x00000087, 0x00000087 } },
+       { AR5K_RF_GAIN(3),      { 0x000001a0, 0x000001a0 } },
+       { AR5K_RF_GAIN(4),      { 0x000001e0, 0x000001e0 } },
+       { AR5K_RF_GAIN(5),      { 0x00000020, 0x00000020 } },
+       { AR5K_RF_GAIN(6),      { 0x00000060, 0x00000060 } },
+       { AR5K_RF_GAIN(7),      { 0x000001a1, 0x000001a1 } },
+       { AR5K_RF_GAIN(8),      { 0x000001e1, 0x000001e1 } },
+       { AR5K_RF_GAIN(9),      { 0x00000021, 0x00000021 } },
+       { AR5K_RF_GAIN(10),     { 0x00000061, 0x00000061 } },
+       { AR5K_RF_GAIN(11),     { 0x00000162, 0x00000162 } },
+       { AR5K_RF_GAIN(12),     { 0x000001a2, 0x000001a2 } },
+       { AR5K_RF_GAIN(13),     { 0x000001e2, 0x000001e2 } },
+       { AR5K_RF_GAIN(14),     { 0x00000022, 0x00000022 } },
+       { AR5K_RF_GAIN(15),     { 0x00000062, 0x00000062 } },
+       { AR5K_RF_GAIN(16),     { 0x00000163, 0x00000163 } },
+       { AR5K_RF_GAIN(17),     { 0x000001a3, 0x000001a3 } },
+       { AR5K_RF_GAIN(18),     { 0x000001e3, 0x000001e3 } },
+       { AR5K_RF_GAIN(19),     { 0x00000023, 0x00000023 } },
+       { AR5K_RF_GAIN(20),     { 0x00000063, 0x00000063 } },
+       { AR5K_RF_GAIN(21),     { 0x00000184, 0x00000184 } },
+       { AR5K_RF_GAIN(22),     { 0x000001c4, 0x000001c4 } },
+       { AR5K_RF_GAIN(23),     { 0x00000004, 0x00000004 } },
+       { AR5K_RF_GAIN(24),     { 0x000001ea, 0x0000000b } },
+       { AR5K_RF_GAIN(25),     { 0x0000002a, 0x0000004b } },
+       { AR5K_RF_GAIN(26),     { 0x0000006a, 0x0000008b } },
+       { AR5K_RF_GAIN(27),     { 0x000000aa, 0x000001ac } },
+       { AR5K_RF_GAIN(28),     { 0x000001ab, 0x000001ec } },
+       { AR5K_RF_GAIN(29),     { 0x000001eb, 0x0000002c } },
+       { AR5K_RF_GAIN(30),     { 0x0000002b, 0x00000012 } },
+       { AR5K_RF_GAIN(31),     { 0x0000006b, 0x00000052 } },
+       { AR5K_RF_GAIN(32),     { 0x000000ab, 0x00000092 } },
+       { AR5K_RF_GAIN(33),     { 0x000001ac, 0x00000193 } },
+       { AR5K_RF_GAIN(34),     { 0x000001ec, 0x000001d3 } },
+       { AR5K_RF_GAIN(35),     { 0x0000002c, 0x00000013 } },
+       { AR5K_RF_GAIN(36),     { 0x0000003a, 0x00000053 } },
+       { AR5K_RF_GAIN(37),     { 0x0000007a, 0x00000093 } },
+       { AR5K_RF_GAIN(38),     { 0x000000ba, 0x00000194 } },
+       { AR5K_RF_GAIN(39),     { 0x000001bb, 0x000001d4 } },
+       { AR5K_RF_GAIN(40),     { 0x000001fb, 0x00000014 } },
+       { AR5K_RF_GAIN(41),     { 0x0000003b, 0x0000003a } },
+       { AR5K_RF_GAIN(42),     { 0x0000007b, 0x0000007a } },
+       { AR5K_RF_GAIN(43),     { 0x000000bb, 0x000000ba } },
+       { AR5K_RF_GAIN(44),     { 0x000001bc, 0x000001bb } },
+       { AR5K_RF_GAIN(45),     { 0x000001fc, 0x000001fb } },
+       { AR5K_RF_GAIN(46),     { 0x0000003c, 0x0000003b } },
+       { AR5K_RF_GAIN(47),     { 0x0000007c, 0x0000007b } },
+       { AR5K_RF_GAIN(48),     { 0x000000bc, 0x000000bb } },
+       { AR5K_RF_GAIN(49),     { 0x000000fc, 0x000001bc } },
+       { AR5K_RF_GAIN(50),     { 0x000000fc, 0x000001fc } },
+       { AR5K_RF_GAIN(51),     { 0x000000fc, 0x0000003c } },
+       { AR5K_RF_GAIN(52),     { 0x000000fc, 0x0000007c } },
+       { AR5K_RF_GAIN(53),     { 0x000000fc, 0x000000bc } },
+       { AR5K_RF_GAIN(54),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(55),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(56),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(57),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(58),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(59),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(60),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(61),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(62),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(63),     { 0x000000fc, 0x000000fc } },
+};
+
+/* Initial RF Gain settings for RF2413 */
+static const struct ath5k_ini_rfgain rfgain_2413[] = {
+       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x00000000, 0x00000181 } },
+       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000001c1 } },
+       { AR5K_RF_GAIN(5),      { 0x00000000, 0x00000001 } },
+       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000041 } },
+       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000081 } },
+       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000168 } },
+       { AR5K_RF_GAIN(9),      { 0x00000000, 0x000001a8 } },
+       { AR5K_RF_GAIN(10),     { 0x00000000, 0x000001e8 } },
+       { AR5K_RF_GAIN(11),     { 0x00000000, 0x00000028 } },
+       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000068 } },
+       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000189 } },
+       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000001c9 } },
+       { AR5K_RF_GAIN(15),     { 0x00000000, 0x00000009 } },
+       { AR5K_RF_GAIN(16),     { 0x00000000, 0x00000049 } },
+       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000089 } },
+       { AR5K_RF_GAIN(18),     { 0x00000000, 0x00000190 } },
+       { AR5K_RF_GAIN(19),     { 0x00000000, 0x000001d0 } },
+       { AR5K_RF_GAIN(20),     { 0x00000000, 0x00000010 } },
+       { AR5K_RF_GAIN(21),     { 0x00000000, 0x00000050 } },
+       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000090 } },
+       { AR5K_RF_GAIN(23),     { 0x00000000, 0x00000191 } },
+       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000001d1 } },
+       { AR5K_RF_GAIN(25),     { 0x00000000, 0x00000011 } },
+       { AR5K_RF_GAIN(26),     { 0x00000000, 0x00000051 } },
+       { AR5K_RF_GAIN(27),     { 0x00000000, 0x00000091 } },
+       { AR5K_RF_GAIN(28),     { 0x00000000, 0x00000178 } },
+       { AR5K_RF_GAIN(29),     { 0x00000000, 0x000001b8 } },
+       { AR5K_RF_GAIN(30),     { 0x00000000, 0x000001f8 } },
+       { AR5K_RF_GAIN(31),     { 0x00000000, 0x00000038 } },
+       { AR5K_RF_GAIN(32),     { 0x00000000, 0x00000078 } },
+       { AR5K_RF_GAIN(33),     { 0x00000000, 0x00000199 } },
+       { AR5K_RF_GAIN(34),     { 0x00000000, 0x000001d9 } },
+       { AR5K_RF_GAIN(35),     { 0x00000000, 0x00000019 } },
+       { AR5K_RF_GAIN(36),     { 0x00000000, 0x00000059 } },
+       { AR5K_RF_GAIN(37),     { 0x00000000, 0x00000099 } },
+       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000d9 } },
+       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f9 } },
+};
+
+/* Initial RF Gain settings for AR2316 */
+static const struct ath5k_ini_rfgain rfgain_2316[] = {
+       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x00000000, 0x000000c0 } },
+       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000000e0 } },
+       { AR5K_RF_GAIN(5),      { 0x00000000, 0x000000e0 } },
+       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000128 } },
+       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000128 } },
+       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000128 } },
+       { AR5K_RF_GAIN(9),      { 0x00000000, 0x00000168 } },
+       { AR5K_RF_GAIN(10),     { 0x00000000, 0x000001a8 } },
+       { AR5K_RF_GAIN(11),     { 0x00000000, 0x000001e8 } },
+       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000028 } },
+       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000068 } },
+       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000000a8 } },
+       { AR5K_RF_GAIN(15),     { 0x00000000, 0x000000e8 } },
+       { AR5K_RF_GAIN(16),     { 0x00000000, 0x000000e8 } },
+       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000130 } },
+       { AR5K_RF_GAIN(18),     { 0x00000000, 0x00000130 } },
+       { AR5K_RF_GAIN(19),     { 0x00000000, 0x00000170 } },
+       { AR5K_RF_GAIN(20),     { 0x00000000, 0x000001b0 } },
+       { AR5K_RF_GAIN(21),     { 0x00000000, 0x000001f0 } },
+       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000030 } },
+       { AR5K_RF_GAIN(23),     { 0x00000000, 0x00000070 } },
+       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000000b0 } },
+       { AR5K_RF_GAIN(25),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(26),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(27),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(28),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(29),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(30),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(31),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(32),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(33),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(34),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(35),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(36),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(37),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f0 } },
+};
+
+
+/* Initial RF Gain settings for RF5413 */
+static const struct ath5k_ini_rfgain rfgain_5413[] = {
+       /*                            5Ghz      2Ghz    */
+       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x00000040, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000080, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x000001a1, 0x00000161 } },
+       { AR5K_RF_GAIN(4),      { 0x000001e1, 0x000001a1 } },
+       { AR5K_RF_GAIN(5),      { 0x00000021, 0x000001e1 } },
+       { AR5K_RF_GAIN(6),      { 0x00000061, 0x00000021 } },
+       { AR5K_RF_GAIN(7),      { 0x00000188, 0x00000061 } },
+       { AR5K_RF_GAIN(8),      { 0x000001c8, 0x00000188 } },
+       { AR5K_RF_GAIN(9),      { 0x00000008, 0x000001c8 } },
+       { AR5K_RF_GAIN(10),     { 0x00000048, 0x00000008 } },
+       { AR5K_RF_GAIN(11),     { 0x00000088, 0x00000048 } },
+       { AR5K_RF_GAIN(12),     { 0x000001a9, 0x00000088 } },
+       { AR5K_RF_GAIN(13),     { 0x000001e9, 0x00000169 } },
+       { AR5K_RF_GAIN(14),     { 0x00000029, 0x000001a9 } },
+       { AR5K_RF_GAIN(15),     { 0x00000069, 0x000001e9 } },
+       { AR5K_RF_GAIN(16),     { 0x000001d0, 0x00000029 } },
+       { AR5K_RF_GAIN(17),     { 0x00000010, 0x00000069 } },
+       { AR5K_RF_GAIN(18),     { 0x00000050, 0x00000190 } },
+       { AR5K_RF_GAIN(19),     { 0x00000090, 0x000001d0 } },
+       { AR5K_RF_GAIN(20),     { 0x000001b1, 0x00000010 } },
+       { AR5K_RF_GAIN(21),     { 0x000001f1, 0x00000050 } },
+       { AR5K_RF_GAIN(22),     { 0x00000031, 0x00000090 } },
+       { AR5K_RF_GAIN(23),     { 0x00000071, 0x00000171 } },
+       { AR5K_RF_GAIN(24),     { 0x000001b8, 0x000001b1 } },
+       { AR5K_RF_GAIN(25),     { 0x000001f8, 0x000001f1 } },
+       { AR5K_RF_GAIN(26),     { 0x00000038, 0x00000031 } },
+       { AR5K_RF_GAIN(27),     { 0x00000078, 0x00000071 } },
+       { AR5K_RF_GAIN(28),     { 0x00000199, 0x00000198 } },
+       { AR5K_RF_GAIN(29),     { 0x000001d9, 0x000001d8 } },
+       { AR5K_RF_GAIN(30),     { 0x00000019, 0x00000018 } },
+       { AR5K_RF_GAIN(31),     { 0x00000059, 0x00000058 } },
+       { AR5K_RF_GAIN(32),     { 0x00000099, 0x00000098 } },
+       { AR5K_RF_GAIN(33),     { 0x000000d9, 0x00000179 } },
+       { AR5K_RF_GAIN(34),     { 0x000000f9, 0x000001b9 } },
+       { AR5K_RF_GAIN(35),     { 0x000000f9, 0x000001f9 } },
+       { AR5K_RF_GAIN(36),     { 0x000000f9, 0x00000039 } },
+       { AR5K_RF_GAIN(37),     { 0x000000f9, 0x00000079 } },
+       { AR5K_RF_GAIN(38),     { 0x000000f9, 0x000000b9 } },
+       { AR5K_RF_GAIN(39),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(40),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(41),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(42),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(43),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(44),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(45),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(46),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(47),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(48),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(49),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(50),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(51),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(52),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(53),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(54),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(55),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(56),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(57),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(58),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(59),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(60),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(61),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(62),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(63),     { 0x000000f9, 0x000000f9 } },
+};
+
+
+/* Initial RF Gain settings for RF2425 */
+static const struct ath5k_ini_rfgain rfgain_2425[] = {
+       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x00000000, 0x00000181 } },
+       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000001c1 } },
+       { AR5K_RF_GAIN(5),      { 0x00000000, 0x00000001 } },
+       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000041 } },
+       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000081 } },
+       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000188 } },
+       { AR5K_RF_GAIN(9),      { 0x00000000, 0x000001c8 } },
+       { AR5K_RF_GAIN(10),     { 0x00000000, 0x00000008 } },
+       { AR5K_RF_GAIN(11),     { 0x00000000, 0x00000048 } },
+       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000088 } },
+       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000189 } },
+       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000001c9 } },
+       { AR5K_RF_GAIN(15),     { 0x00000000, 0x00000009 } },
+       { AR5K_RF_GAIN(16),     { 0x00000000, 0x00000049 } },
+       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000089 } },
+       { AR5K_RF_GAIN(18),     { 0x00000000, 0x000001b0 } },
+       { AR5K_RF_GAIN(19),     { 0x00000000, 0x000001f0 } },
+       { AR5K_RF_GAIN(20),     { 0x00000000, 0x00000030 } },
+       { AR5K_RF_GAIN(21),     { 0x00000000, 0x00000070 } },
+       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000171 } },
+       { AR5K_RF_GAIN(23),     { 0x00000000, 0x000001b1 } },
+       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000001f1 } },
+       { AR5K_RF_GAIN(25),     { 0x00000000, 0x00000031 } },
+       { AR5K_RF_GAIN(26),     { 0x00000000, 0x00000071 } },
+       { AR5K_RF_GAIN(27),     { 0x00000000, 0x000001b8 } },
+       { AR5K_RF_GAIN(28),     { 0x00000000, 0x000001f8 } },
+       { AR5K_RF_GAIN(29),     { 0x00000000, 0x00000038 } },
+       { AR5K_RF_GAIN(30),     { 0x00000000, 0x00000078 } },
+       { AR5K_RF_GAIN(31),     { 0x00000000, 0x000000b8 } },
+       { AR5K_RF_GAIN(32),     { 0x00000000, 0x000001b9 } },
+       { AR5K_RF_GAIN(33),     { 0x00000000, 0x000001f9 } },
+       { AR5K_RF_GAIN(34),     { 0x00000000, 0x00000039 } },
+       { AR5K_RF_GAIN(35),     { 0x00000000, 0x00000079 } },
+       { AR5K_RF_GAIN(36),     { 0x00000000, 0x000000b9 } },
+       { AR5K_RF_GAIN(37),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f9 } },
+};
+
+#define AR5K_GAIN_CRN_FIX_BITS_5111            4
+#define AR5K_GAIN_CRN_FIX_BITS_5112            7
+#define AR5K_GAIN_CRN_MAX_FIX_BITS             AR5K_GAIN_CRN_FIX_BITS_5112
+#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN         15
+#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN         20
+#define AR5K_GAIN_CCK_PROBE_CORR               5
+#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA          15
+#define AR5K_GAIN_STEP_COUNT                   10
+
+/* Check if our current measurement is inside our
+ * current variable attenuation window */
+#define AR5K_GAIN_CHECK_ADJUST(_g)             \
+       ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
+
+struct ath5k_gain_opt_step {
+       s8                              gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
+       s8                              gos_gain;
+};
+
+struct ath5k_gain_opt {
+       u8                              go_default;
+       u8                              go_steps_count;
+       const struct ath5k_gain_opt_step        go_step[AR5K_GAIN_STEP_COUNT];
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Tx clip PHY register
+ * 2) PWD 90 RF register
+ * 3) PWD 84 RF register
+ * 4) RFGainSel RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5111 = {
+       4,
+       9,
+       {
+               { { 4, 1, 1, 1 }, 6 },
+               { { 4, 0, 1, 1 }, 4 },
+               { { 3, 1, 1, 1 }, 3 },
+               { { 4, 0, 0, 1 }, 1 },
+               { { 4, 1, 1, 0 }, 0 },
+               { { 4, 0, 1, 0 }, -2 },
+               { { 3, 1, 1, 0 }, -3 },
+               { { 4, 0, 0, 0 }, -4 },
+               { { 2, 1, 1, 0 }, -6 }
+       }
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Mixgain ovr RF register
+ * 2) PWD 138 RF register
+ * 3) PWD 137 RF register
+ * 4) PWD 136 RF register
+ * 5) PWD 132 RF register
+ * 6) PWD 131 RF register
+ * 7) PWD 130 RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5112 = {
+       1,
+       8,
+       {
+               { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
+               { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
+               { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
+               { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
+               { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
+               { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
+               { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
+               { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
+       }
+};
+
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
new file mode 100644 (file)
index 0000000..0ed1ac3
--- /dev/null
@@ -0,0 +1,24 @@
+config ATH9K
+       tristate "Atheros 802.11n wireless cards support"
+       depends on PCI && MAC80211 && WLAN_80211
+       depends on RFKILL || RFKILL=n
+       select ATH_COMMON
+       select MAC80211_LEDS
+       select LEDS_CLASS
+       select NEW_LEDS
+       ---help---
+         This module adds support for wireless adapters based on
+         Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
+
+         If you choose to build a module, it'll be called ath9k.
+
+config ATH9K_DEBUG
+       bool "Atheros ath9k debugging"
+       depends on ATH9K
+       ---help---
+         Say Y, if you need ath9k to display debug messages.
+         Pass the debug mask as a module parameter:
+
+         modprobe ath9k debug=0x00002000
+
+         Look in ath9k/core.h for possible debug masks
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
new file mode 100644 (file)
index 0000000..783bc39
--- /dev/null
@@ -0,0 +1,18 @@
+ath9k-y +=     hw.o \
+               eeprom.o \
+               mac.o \
+               calib.o \
+               ani.o \
+               phy.o \
+               beacon.o \
+               main.o \
+               recv.o \
+               xmit.o \
+               virtual.o \
+               rc.o
+
+ath9k-$(CONFIG_PCI) += pci.o
+ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
+ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
+
+obj-$(CONFIG_ATH9K) += ath9k.o
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
new file mode 100644 (file)
index 0000000..0e65c51
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * 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 <linux/nl80211.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+#include "ath9k.h"
+
+/* return bus cachesize in 4B word units */
+static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz)
+{
+       *csz = L1_CACHE_BYTES >> 2;
+}
+
+static void ath_ahb_cleanup(struct ath_softc *sc)
+{
+       iounmap(sc->mem);
+}
+
+static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+       struct ath_softc *sc = ah->ah_sc;
+       struct platform_device *pdev = to_platform_device(sc->dev);
+       struct ath9k_platform_data *pdata;
+
+       pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
+       if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "%s: flash read failed, offset %08x is out of range\n",
+                               __func__, off);
+               return false;
+       }
+
+       *data = pdata->eeprom_data[off];
+       return true;
+}
+
+static struct ath_bus_ops ath_ahb_bus_ops  = {
+       .read_cachesize = ath_ahb_read_cachesize,
+       .cleanup = ath_ahb_cleanup,
+
+       .eeprom_read = ath_ahb_eeprom_read,
+};
+
+static int ath_ahb_probe(struct platform_device *pdev)
+{
+       void __iomem *mem;
+       struct ath_wiphy *aphy;
+       struct ath_softc *sc;
+       struct ieee80211_hw *hw;
+       struct resource *res;
+       int irq;
+       int ret = 0;
+       struct ath_hw *ah;
+
+       if (!pdev->dev.platform_data) {
+               dev_err(&pdev->dev, "no platform data specified\n");
+               ret = -EINVAL;
+               goto err_out;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "no memory resource found\n");
+               ret = -ENXIO;
+               goto err_out;
+       }
+
+       mem = ioremap_nocache(res->start, res->end - res->start + 1);
+       if (mem == NULL) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -ENOMEM;
+               goto err_out;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "no IRQ resource found\n");
+               ret = -ENXIO;
+               goto err_iounmap;
+       }
+
+       irq = res->start;
+
+       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+                               sizeof(struct ath_softc), &ath9k_ops);
+       if (hw == NULL) {
+               dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+               ret = -ENOMEM;
+               goto err_iounmap;
+       }
+
+       SET_IEEE80211_DEV(hw, &pdev->dev);
+       platform_set_drvdata(pdev, hw);
+
+       aphy = hw->priv;
+       sc = (struct ath_softc *) (aphy + 1);
+       aphy->sc = sc;
+       aphy->hw = hw;
+       sc->pri_wiphy = aphy;
+       sc->hw = hw;
+       sc->dev = &pdev->dev;
+       sc->mem = mem;
+       sc->bus_ops = &ath_ahb_bus_ops;
+       sc->irq = irq;
+
+       ret = ath_attach(AR5416_AR9100_DEVID, sc);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
+               ret = -ENODEV;
+               goto err_free_hw;
+       }
+
+       ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
+       if (ret) {
+               dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret);
+               ret = -EIO;
+               goto err_detach;
+       }
+
+       ah = sc->sc_ah;
+       printk(KERN_INFO
+              "%s: Atheros AR%s MAC/BB Rev:%x, "
+              "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
+              wiphy_name(hw->wiphy),
+              ath_mac_bb_name(ah->hw_version.macVersion),
+              ah->hw_version.macRev,
+              ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+              ah->hw_version.phyRev,
+              (unsigned long)mem, irq);
+
+       return 0;
+
+ err_detach:
+       ath_detach(sc);
+ err_free_hw:
+       ieee80211_free_hw(hw);
+       platform_set_drvdata(pdev, NULL);
+ err_iounmap:
+       iounmap(mem);
+ err_out:
+       return ret;
+}
+
+static int ath_ahb_remove(struct platform_device *pdev)
+{
+       struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+
+       if (hw) {
+               struct ath_wiphy *aphy = hw->priv;
+               struct ath_softc *sc = aphy->sc;
+
+               ath_cleanup(sc);
+               platform_set_drvdata(pdev, NULL);
+       }
+
+       return 0;
+}
+
+static struct platform_driver ath_ahb_driver = {
+       .probe      = ath_ahb_probe,
+       .remove     = ath_ahb_remove,
+       .driver         = {
+               .name   = "ath9k",
+               .owner  = THIS_MODULE,
+       },
+};
+
+int ath_ahb_init(void)
+{
+       return platform_driver_register(&ath_ahb_driver);
+}
+
+void ath_ahb_exit(void)
+{
+       platform_driver_unregister(&ath_ahb_driver);
+}
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
new file mode 100644 (file)
index 0000000..1aeafb5
--- /dev/null
@@ -0,0 +1,822 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
+                                       struct ath9k_channel *chan)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+               if (ah->ani[i].c &&
+                   ah->ani[i].c->channel == chan->channel)
+                       return i;
+               if (ah->ani[i].c == NULL) {
+                       ah->ani[i].c = chan;
+                       return i;
+               }
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "No more channel states left. Using channel 0\n");
+
+       return 0;
+}
+
+static bool ath9k_hw_ani_control(struct ath_hw *ah,
+                                enum ath9k_ani_cmd cmd, int param)
+{
+       struct ar5416AniState *aniState = ah->curani;
+
+       switch (cmd & ah->ani_function) {
+       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "level out of range (%u > %u)\n",
+                               level,
+                               (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
+                       return false;
+               }
+
+               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+                             AR_PHY_DESIRED_SZ_TOT_DES,
+                             ah->totalSizeDesired[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+                             AR_PHY_AGC_CTL1_COARSE_LOW,
+                             ah->coarse_low[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+                             AR_PHY_AGC_CTL1_COARSE_HIGH,
+                             ah->coarse_high[level]);
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRPWR,
+                             ah->firpwr[level]);
+
+               if (level > aniState->noiseImmunityLevel)
+                       ah->stats.ast_ani_niup++;
+               else if (level < aniState->noiseImmunityLevel)
+                       ah->stats.ast_ani_nidown++;
+               aniState->noiseImmunityLevel = level;
+               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 };
+               u32 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)
+                               ah->stats.ast_ani_ofdmon++;
+                       else
+                               ah->stats.ast_ani_ofdmoff++;
+                       aniState->ofdmWeakSigDetectOff = !on;
+               }
+               break;
+       }
+       case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
+               const int weakSigThrCck[] = { 8, 6 };
+               u32 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)
+                               ah->stats.ast_ani_cckhigh++;
+                       else
+                               ah->stats.ast_ani_ccklow++;
+                       aniState->cckWeakSigThreshold = high;
+               }
+               break;
+       }
+       case ATH9K_ANI_FIRSTEP_LEVEL:{
+               const int firstep[] = { 0, 4, 8 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(firstep)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "level out of range (%u > %u)\n",
+                               level,
+                               (unsigned) ARRAY_SIZE(firstep));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRSTEP,
+                             firstep[level]);
+               if (level > aniState->firstepLevel)
+                       ah->stats.ast_ani_stepup++;
+               else if (level < aniState->firstepLevel)
+                       ah->stats.ast_ani_stepdown++;
+               aniState->firstepLevel = level;
+               break;
+       }
+       case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
+               const int cycpwrThr1[] =
+                       { 2, 4, 6, 8, 10, 12, 14, 16 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(cycpwrThr1)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "level out of range (%u > %u)\n",
+                               level,
+                               (unsigned)
+                               ARRAY_SIZE(cycpwrThr1));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+                             AR_PHY_TIMING5_CYCPWR_THR1,
+                             cycpwrThr1[level]);
+               if (level > aniState->spurImmunityLevel)
+                       ah->stats.ast_ani_spurup++;
+               else if (level < aniState->spurImmunityLevel)
+                       ah->stats.ast_ani_spurdown++;
+               aniState->spurImmunityLevel = level;
+               break;
+       }
+       case ATH9K_ANI_PRESENT:
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "invalid cmd %u\n", cmd);
+               return false;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "ANI parameters:\n");
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
+               "ofdmWeakSigDetectOff=%d\n",
+               aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
+               !aniState->ofdmWeakSigDetectOff);
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "cckWeakSigThreshold=%d, "
+               "firstepLevel=%d, listenTime=%d\n",
+               aniState->cckWeakSigThreshold, aniState->firstepLevel,
+               aniState->listenTime);
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
+               aniState->cycleCount, aniState->ofdmPhyErrCount,
+               aniState->cckPhyErrCount);
+
+       return true;
+}
+
+static void ath9k_hw_update_mibstats(struct ath_hw *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_hw *ah)
+{
+       struct ar5416AniState *aniState;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = ah->curani;
+
+       aniState->listenTime = 0;
+       if (ah->has_hw_phycounters) {
+               if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
+                       aniState->ofdmPhyErrBase = 0;
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "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;
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "CCK Trigger is too high for hw counters\n");
+               } else {
+                       aniState->cckPhyErrBase =
+                               AR_PHY_COUNTMAX - aniState->cckTrigHigh;
+               }
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Writing ofdmbase=%u   cckbase=%u\n",
+                       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, &ah->ah_mibStats);
+       }
+       aniState->ofdmPhyErrCount = 0;
+       aniState->cckPhyErrCount = 0;
+}
+
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = 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->opmode == NL80211_IFTYPE_AP) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               }
+               return;
+       }
+       rssi = BEACON_RSSI(ah);
+       if (rssi > aniState->rssiThrHigh) {
+               if (!aniState->ofdmWeakSigDetectOff) {
+                       if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                        false)) {
+                               ath9k_hw_ani_control(ah,
+                                       ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
+                               return;
+                       }
+               }
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+                       return;
+               }
+       } else if (rssi > aniState->rssiThrLow) {
+               if (aniState->ofdmWeakSigDetectOff)
+                       ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    true);
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               return;
+       } else {
+               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+                       if (!aniState->ofdmWeakSigDetectOff)
+                               ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    false);
+                       if (aniState->firstepLevel > 0)
+                               ath9k_hw_ani_control(ah,
+                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
+                       return;
+               }
+       }
+}
+
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = 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->opmode == NL80211_IFTYPE_AP) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               }
+               return;
+       }
+       rssi = BEACON_RSSI(ah);
+       if (rssi > aniState->rssiThrLow) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+       } else {
+               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+                       if (aniState->firstepLevel > 0)
+                               ath9k_hw_ani_control(ah,
+                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
+               }
+       }
+}
+
+static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       aniState = ah->curani;
+
+       if (ah->opmode == NL80211_IFTYPE_AP) {
+               if (aniState->firstepLevel > 0) {
+                       if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                                aniState->firstepLevel - 1))
+                               return;
+               }
+       } else {
+               rssi = BEACON_RSSI(ah);
+               if (rssi > aniState->rssiThrHigh) {
+                       /* XXX: Handle me */
+               } else if (rssi > aniState->rssiThrLow) {
+                       if (aniState->ofdmWeakSigDetectOff) {
+                               if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                        true) == true)
+                                       return;
+                       }
+                       if (aniState->firstepLevel > 0) {
+                               if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_FIRSTEP_LEVEL,
+                                        aniState->firstepLevel - 1) == true)
+                                       return;
+                       }
+               } else {
+                       if (aniState->firstepLevel > 0) {
+                               if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_FIRSTEP_LEVEL,
+                                        aniState->firstepLevel - 1) == 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) {
+               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_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       u32 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 = ah->curani;
+       if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
+
+               listenTime = 0;
+               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_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       struct ath9k_channel *chan = ah->curchan;
+       int index;
+
+       if (!DO_ANI(ah))
+               return;
+
+       index = ath9k_hw_get_ani_channel_idx(ah, chan);
+       aniState = &ah->ani[index];
+       ah->curani = aniState;
+
+       if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
+           && ah->opmode != NL80211_IFTYPE_ADHOC) {
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Reset ANI state opmode %u\n", ah->opmode);
+               ah->stats.ast_ani_reset++;
+
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    !ATH9K_ANI_USE_OFDM_WEAK_SIG);
+               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->opmode == NL80211_IFTYPE_AP) {
+                       ah->curani->ofdmTrigHigh =
+                               ah->config.ofdm_trig_high;
+                       ah->curani->ofdmTrigLow =
+                               ah->config.ofdm_trig_low;
+                       ah->curani->cckTrigHigh =
+                               ah->config.cck_trig_high;
+                       ah->curani->cckTrigLow =
+                               ah->config.cck_trig_low;
+               }
+               ath9k_ani_restart(ah);
+               return;
+       }
+
+       if (aniState->noiseImmunityLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                    aniState->noiseImmunityLevel);
+       if (aniState->spurImmunityLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                    aniState->spurImmunityLevel);
+       if (aniState->ofdmWeakSigDetectOff)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    !aniState->ofdmWeakSigDetectOff);
+       if (aniState->cckWeakSigThreshold)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
+                                    aniState->cckWeakSigThreshold);
+       if (aniState->firstepLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                    aniState->firstepLevel);
+       if (ah->has_hw_phycounters) {
+               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);
+       }
+}
+
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
+                         const struct ath9k_node_stats *stats,
+                         struct ath9k_channel *chan)
+{
+       struct ar5416AniState *aniState;
+       int32_t listenTime;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = ah->curani;
+       ah->stats.ast_nodestats = *stats;
+
+       listenTime = ath9k_hw_ani_get_listen_time(ah);
+       if (listenTime < 0) {
+               ah->stats.ast_ani_lneg++;
+               ath9k_ani_restart(ah);
+               return;
+       }
+
+       aniState->listenTime += listenTime;
+
+       if (ah->has_hw_phycounters) {
+               u32 phyCnt1, phyCnt2;
+               u32 ofdmPhyErrCnt, cckPhyErrCnt;
+
+               ath9k_hw_update_mibstats(ah, &ah->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) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                                       "phyCnt1 0x%x, resetting "
+                                       "counter value to 0x%x\n",
+                                       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) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                                       "phyCnt2 0x%x, resetting "
+                                       "counter value to 0x%x\n",
+                                       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;
+               ah->stats.ast_ani_ofdmerrs +=
+                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
+               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+
+               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+               ah->stats.ast_ani_cckerrs +=
+                       cckPhyErrCnt - aniState->cckPhyErrCount;
+               aniState->cckPhyErrCount = cckPhyErrCnt;
+       }
+
+       if (aniState->listenTime > 5 * 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 > 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);
+               }
+       }
+}
+
+bool ath9k_hw_phycounters(struct ath_hw *ah)
+{
+       return ah->has_hw_phycounters ? true : false;
+}
+
+void ath9k_enable_mib_counters(struct ath_hw *ah)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
+
+       ath9k_hw_update_mibstats(ah, &ah->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);
+}
+
+/* Freeze the MIB counters, get the stats and then clear them */
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
+       REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
+       ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+       REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
+       REG_WRITE(ah, AR_FILT_OFDM, 0);
+       REG_WRITE(ah, AR_FILT_CCK, 0);
+}
+
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
+                                 u32 *rxc_pcnt,
+                                 u32 *rxf_pcnt,
+                                 u32 *txf_pcnt)
+{
+       static u32 cycles, rx_clear, rx_frame, tx_frame;
+       u32 good = 1;
+
+       u32 rc = REG_READ(ah, AR_RCCNT);
+       u32 rf = REG_READ(ah, AR_RFCNT);
+       u32 tf = REG_READ(ah, AR_TFCNT);
+       u32 cc = REG_READ(ah, AR_CCCNT);
+
+       if (cycles == 0 || cycles > cc) {
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "cycle counter wrap. ExtBusy = 0\n");
+               good = 0;
+       } else {
+               u32 cc_d = cc - cycles;
+               u32 rc_d = rc - rx_clear;
+               u32 rf_d = rf - rx_frame;
+               u32 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_hw *ah,
+                          const struct ath9k_node_stats *stats)
+{
+       u32 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, &ah->ah_mibStats);
+       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 = ah->curani;
+               u32 ofdmPhyErrCnt, cckPhyErrCnt;
+
+               /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
+               ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
+               ah->stats.ast_ani_ofdmerrs +=
+                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
+               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+
+               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+               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_hw *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++) {
+               ah->totalSizeDesired[i] = totalSizeDesired[i];
+               ah->coarse_high[i] = coarseHigh[i];
+               ah->coarse_low[i] = coarseLow[i];
+               ah->firpwr[i] = firpwr[i];
+       }
+}
+
+void ath9k_hw_ani_attach(struct ath_hw *ah)
+{
+       int i;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
+
+       ah->has_hw_phycounters = 1;
+
+       memset(ah->ani, 0, sizeof(ah->ani));
+       for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+               ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
+               ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
+               ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
+               ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
+               ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
+               ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
+               ah->ani[i].ofdmWeakSigDetectOff =
+                       !ATH9K_ANI_USE_OFDM_WEAK_SIG;
+               ah->ani[i].cckWeakSigThreshold =
+                       ATH9K_ANI_CCK_WEAK_SIG_THR;
+               ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+               ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+               if (ah->has_hw_phycounters) {
+                       ah->ani[i].ofdmPhyErrBase =
+                               AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
+                       ah->ani[i].cckPhyErrBase =
+                               AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
+               }
+       }
+       if (ah->has_hw_phycounters) {
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Setting OfdmErrBase = 0x%08x\n",
+                       ah->ani[0].ofdmPhyErrBase);
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
+                       ah->ani[0].cckPhyErrBase);
+
+               REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
+               REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
+               ath9k_enable_mib_counters(ah);
+       }
+       ah->aniperiod = ATH9K_ANI_PERIOD;
+       if (ah->config.enable_ani)
+               ah->proc_phyerr |= HAL_PROCESS_ANI;
+}
+
+void ath9k_hw_ani_detach(struct ath_hw *ah)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
+
+       if (ah->has_hw_phycounters) {
+               ath9k_hw_disable_mib_counters(ah);
+               REG_WRITE(ah, AR_PHY_ERR_1, 0);
+               REG_WRITE(ah, AR_PHY_ERR_2, 0);
+       }
+}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
new file mode 100644 (file)
index 0000000..08b4e7e
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2008-2009 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 ANI_H
+#define ANI_H
+
+#define HAL_PROCESS_ANI           0x00000001
+#define ATH9K_RSSI_EP_MULTIPLIER  (1<<7)
+
+#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
+
+#define HAL_EP_RND(x, mul)                                             \
+       ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+#define BEACON_RSSI(ahp)                                       \
+       HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi,        \
+                  ATH9K_RSSI_EP_MULTIPLIER)
+
+#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       true
+#define ATH9K_ANI_CCK_WEAK_SIG_THR        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 HAL_NOISE_IMMUNE_MAX              4
+#define HAL_SPUR_IMMUNE_MAX               7
+#define HAL_FIRST_STEP_MAX                2
+
+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
+};
+
+struct ath9k_mib_stats {
+       u32 ackrcv_bad;
+       u32 rts_bad;
+       u32 rts_good;
+       u32 fcs_bad;
+       u32 beacons;
+};
+
+struct ath9k_node_stats {
+       u32 ns_avgbrssi;
+       u32 ns_avgrssi;
+       u32 ns_avgtxrssi;
+       u32 ns_avgtxrate;
+};
+
+struct ar5416AniState {
+       struct ath9k_channel *c;
+       u8 noiseImmunityLevel;
+       u8 spurImmunityLevel;
+       u8 firstepLevel;
+       u8 ofdmWeakSigDetectOff;
+       u8 cckWeakSigThreshold;
+       u32 listenTime;
+       u32 ofdmTrigHigh;
+       u32 ofdmTrigLow;
+       int32_t cckTrigHigh;
+       int32_t cckTrigLow;
+       int32_t rssiThrLow;
+       int32_t rssiThrHigh;
+       u32 noiseFloor;
+       u32 txFrameCount;
+       u32 rxFrameCount;
+       u32 cycleCount;
+       u32 ofdmPhyErrCount;
+       u32 cckPhyErrCount;
+       u32 ofdmPhyErrBase;
+       u32 cckPhyErrBase;
+       int16_t pktRssi[2];
+       int16_t ofdmErrRssi[2];
+       int16_t cckErrRssi[2];
+};
+
+struct ar5416Stats {
+       u32 ast_ani_niup;
+       u32 ast_ani_nidown;
+       u32 ast_ani_spurup;
+       u32 ast_ani_spurdown;
+       u32 ast_ani_ofdmon;
+       u32 ast_ani_ofdmoff;
+       u32 ast_ani_cckhigh;
+       u32 ast_ani_ccklow;
+       u32 ast_ani_stepup;
+       u32 ast_ani_stepdown;
+       u32 ast_ani_ofdmerrs;
+       u32 ast_ani_cckerrs;
+       u32 ast_ani_reset;
+       u32 ast_ani_lzero;
+       u32 ast_ani_lneg;
+       struct ath9k_mib_stats ast_mibstats;
+       struct ath9k_node_stats ast_nodestats;
+};
+#define ah_mibStats stats.ast_mibstats
+
+void ath9k_ani_reset(struct ath_hw *ah);
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
+                         const struct ath9k_node_stats *stats,
+                         struct ath9k_channel *chan);
+bool ath9k_hw_phycounters(struct ath_hw *ah);
+void ath9k_enable_mib_counters(struct ath_hw *ah);
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
+                                 u32 *rxf_pcnt, u32 *txf_pcnt);
+void ath9k_hw_procmibevent(struct ath_hw *ah,
+                          const struct ath9k_node_stats *stats);
+void ath9k_hw_ani_setup(struct ath_hw *ah);
+void ath9k_hw_ani_attach(struct ath_hw *ah);
+void ath9k_hw_ani_detach(struct ath_hw *ah);
+
+#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
new file mode 100644 (file)
index 0000000..c92d46f
--- /dev/null
@@ -0,0 +1,730 @@
+/*
+ * Copyright (c) 2008-2009 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 ATH9K_H
+#define ATH9K_H
+
+#include <linux/etherdevice.h>
+#include <linux/device.h>
+#include <net/mac80211.h>
+#include <linux/leds.h>
+#include <linux/rfkill.h>
+
+#include "hw.h"
+#include "rc.h"
+#include "debug.h"
+
+struct ath_node;
+
+/* 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 ASSERT(exp) BUG_ON(!(exp))
+
+#define TSF_TO_TU(_h,_l) \
+       ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
+
+#define        ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
+
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+struct ath_config {
+       u32 ath_aggr_prot;
+       u16 txpowlimit;
+       u8 cabqReadytime;
+};
+
+/*************************/
+/* Descriptor Management */
+/*************************/
+
+#define ATH_TXBUF_RESET(_bf) do {                              \
+               (_bf)->bf_stale = false;                        \
+               (_bf)->bf_lastbf = NULL;                        \
+               (_bf)->bf_next = NULL;                          \
+               memset(&((_bf)->bf_state), 0,                   \
+                      sizeof(struct ath_buf_state));           \
+       } while (0)
+
+#define ATH_RXBUF_RESET(_bf) do {              \
+               (_bf)->bf_stale = false;        \
+       } while (0)
+
+/**
+ * enum buffer_type - Buffer type flags
+ *
+ * @BUF_HT: Send this buffer using HT capabilities
+ * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
+ * @BUF_AGGR: Indicates whether the buffer can be aggregated
+ *     (used in aggregation scheduling)
+ * @BUF_RETRY: Indicates whether the buffer is retried
+ * @BUF_XRETRY: To denote excessive retries of the buffer
+ */
+enum buffer_type {
+       BUF_HT                  = BIT(1),
+       BUF_AMPDU               = BIT(2),
+       BUF_AGGR                = BIT(3),
+       BUF_RETRY               = BIT(4),
+       BUF_XRETRY              = BIT(5),
+};
+
+struct ath_buf_state {
+       int bfs_nframes;
+       u16 bfs_al;
+       u16 bfs_frmlen;
+       int bfs_seqno;
+       int bfs_tidno;
+       int bfs_retries;
+       u8 bf_type;
+       u32 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_keyix                bf_state.bfs_keyix
+#define bf_keytype             bf_state.bfs_keytype
+#define bf_isht(bf)            (bf->bf_state.bf_type & BUF_HT)
+#define bf_isampdu(bf)         (bf->bf_state.bf_type & BUF_AMPDU)
+#define bf_isaggr(bf)          (bf->bf_state.bf_type & BUF_AGGR)
+#define bf_isretried(bf)       (bf->bf_state.bf_type & BUF_RETRY)
+#define bf_isxretried(bf)      (bf->bf_state.bf_type & BUF_XRETRY)
+
+struct ath_buf {
+       struct list_head list;
+       struct ath_buf *bf_lastbf;      /* last buf of this unit (a frame or
+                                          an aggregate) */
+       struct ath_buf *bf_next;        /* next subframe in the aggregate */
+       struct sk_buff *bf_mpdu;        /* enclosing frame structure */
+       struct ath_desc *bf_desc;       /* virtual addr of desc */
+       dma_addr_t bf_daddr;            /* physical addr of desc */
+       dma_addr_t bf_buf_addr;         /* physical addr of data buffer */
+       bool bf_stale;
+       u16 bf_flags;
+       struct ath_buf_state bf_state;
+       dma_addr_t bf_dmacontext;
+};
+
+struct ath_descdma {
+       struct ath_desc *dd_desc;
+       dma_addr_t dd_desc_paddr;
+       u32 dd_desc_len;
+       struct ath_buf *dd_bufptr;
+};
+
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+                     struct list_head *head, const char *name,
+                     int nbuf, int ndesc);
+void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
+                        struct list_head *head);
+
+/***********/
+/* RX / TX */
+/***********/
+
+#define ATH_MAX_ANTENNA         3
+#define ATH_RXBUF               512
+#define WME_NUM_TID             16
+#define ATH_TXBUF               512
+#define ATH_TXMAXTRY            13
+#define ATH_11N_TXMAXTRY        10
+#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)
+
+#define WME_AC_BE   0
+#define WME_AC_BK   1
+#define WME_AC_VI   2
+#define WME_AC_VO   3
+#define WME_NUM_AC  4
+
+#define ADDBA_EXCHANGE_ATTEMPTS    10
+#define ATH_AGGR_DELIM_SZ          4
+#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 ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
+#define ATH_AMPDU_LIMIT_DEFAULT    ATH_AMPDU_LIMIT_MAX
+
+#define IEEE80211_SEQ_SEQ_SHIFT    4
+#define IEEE80211_SEQ_MAX          4096
+#define IEEE80211_MIN_AMPDU_BUF    0x8
+#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
+#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))
+
+/* 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)->tid[(_tidno)])
+
+enum ATH_AGGR_STATUS {
+       ATH_AGGR_DONE,
+       ATH_AGGR_BAW_CLOSED,
+       ATH_AGGR_LIMITED,
+};
+
+struct ath_txq {
+       u32 axq_qnum;
+       u32 *axq_link;
+       struct list_head axq_q;
+       spinlock_t axq_lock;
+       u32 axq_depth;
+       u8 axq_aggr_depth;
+       u32 axq_totalqueued;
+       bool stopped;
+       struct ath_buf *axq_linkbuf;
+
+       /* first desc of the last descriptor that contains CTS */
+       struct ath_desc *axq_lastdsWithCTS;
+
+       /* final desc of the gating desc that determines whether
+          lastdsWithCTS has been DMA'ed or not */
+       struct ath_desc *axq_gatingds;
+
+       struct list_head axq_acq;
+};
+
+#define AGGR_CLEANUP         BIT(1)
+#define AGGR_ADDBA_COMPLETE  BIT(2)
+#define AGGR_ADDBA_PROGRESS  BIT(3)
+
+struct ath_atx_tid {
+       struct list_head list;
+       struct list_head buf_q;
+       struct ath_node *an;
+       struct ath_atx_ac *ac;
+       struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
+       u16 seq_start;
+       u16 seq_next;
+       u16 baw_size;
+       int tidno;
+       int baw_head;   /* first un-acked tx buffer */
+       int baw_tail;   /* next unused tx buffer slot */
+       int sched;
+       int paused;
+       u8 state;
+       int addba_exchangeattempts;
+};
+
+struct ath_atx_ac {
+       int sched;
+       int qnum;
+       struct list_head list;
+       struct list_head tid_q;
+};
+
+struct ath_tx_control {
+       struct ath_txq *txq;
+       int if_id;
+       enum ath9k_internal_frame_type frame_type;
+};
+
+#define ATH_TX_ERROR        0x01
+#define ATH_TX_XRETRY       0x02
+#define ATH_TX_BAR          0x04
+
+struct ath_node {
+       struct ath_softc *an_sc;
+       struct ath_atx_tid tid[WME_NUM_TID];
+       struct ath_atx_ac ac[WME_NUM_AC];
+       u16 maxampdu;
+       u8 mpdudensity;
+};
+
+struct ath_tx {
+       u16 seq_no;
+       u32 txqsetup;
+       int hwq_map[ATH9K_WME_AC_VO+1];
+       spinlock_t txbuflock;
+       struct list_head txbuf;
+       struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
+       struct ath_descdma txdma;
+};
+
+struct ath_rx {
+       u8 defant;
+       u8 rxotherant;
+       u32 *rxlink;
+       int bufsize;
+       unsigned int rxfilter;
+       spinlock_t rxflushlock;
+       spinlock_t rxbuflock;
+       struct list_head rxbuf;
+       struct ath_descdma rxdma;
+};
+
+int ath_startrecv(struct ath_softc *sc);
+bool ath_stoprecv(struct ath_softc *sc);
+void ath_flushrecv(struct ath_softc *sc);
+u32 ath_calcrxfilter(struct ath_softc *sc);
+int ath_rx_init(struct ath_softc *sc, int nbufs);
+void ath_rx_cleanup(struct ath_softc *sc);
+int ath_rx_tasklet(struct ath_softc *sc, int flush);
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_setup(struct ath_softc *sc, int haltype);
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+void ath_draintxq(struct ath_softc *sc,
+                    struct ath_txq *txq, bool retry_tx);
+void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
+void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_init(struct ath_softc *sc, int nbufs);
+void ath_tx_cleanup(struct ath_softc *sc);
+struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
+int ath_txq_update(struct ath_softc *sc, int qnum,
+                  struct ath9k_tx_queue_info *q);
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+                struct ath_tx_control *txctl);
+void ath_tx_tasklet(struct ath_softc *sc);
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+                     u16 tid, u16 *ssn);
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+
+/********/
+/* VIFs */
+/********/
+
+struct ath_vif {
+       int av_bslot;
+       __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
+       enum nl80211_iftype av_opmode;
+       struct ath_buf *av_bcbuf;
+       struct ath_tx_control av_btxctl;
+       u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
+};
+
+/*******************/
+/* 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
+#define ATH_DEFAULT_BINTVAL            100 /* TU */
+#define ATH_DEFAULT_BMISS_LIMIT        10
+#define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
+
+struct ath_beacon_config {
+       u16 beacon_interval;
+       u16 listen_interval;
+       u16 dtim_period;
+       u16 bmiss_timeout;
+       u8 dtim_count;
+};
+
+struct ath_beacon {
+       enum {
+               OK,             /* no change needed */
+               UPDATE,         /* update pending */
+               COMMIT          /* beacon sent, commit change */
+       } updateslot;           /* slot time update fsm */
+
+       u32 beaconq;
+       u32 bmisscnt;
+       u32 ast_be_xmit;
+       u64 bc_tstamp;
+       struct ieee80211_vif *bslot[ATH_BCBUF];
+       struct ath_wiphy *bslot_aphy[ATH_BCBUF];
+       int slottime;
+       int slotupdate;
+       struct ath9k_tx_queue_info beacon_qi;
+       struct ath_descdma bdma;
+       struct ath_txq *cabq;
+       struct list_head bbuf;
+};
+
+void ath_beacon_tasklet(unsigned long data);
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
+int ath_beaconq_setup(struct ath_hw *ah);
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
+
+/*******/
+/* ANI */
+/*******/
+
+#define ATH_STA_SHORT_CALINTERVAL 1000    /* 1 second */
+#define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
+#define ATH_ANI_POLLINTERVAL      100     /* 100 ms */
+#define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
+#define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
+
+struct ath_ani {
+       bool caldone;
+       int16_t noise_floor;
+       unsigned int longcal_timer;
+       unsigned int shortcal_timer;
+       unsigned int resetcal_timer;
+       unsigned int checkani_timer;
+       struct timer_list timer;
+};
+
+/********************/
+/*   LED Control    */
+/********************/
+
+#define ATH_LED_PIN    1
+#define ATH_LED_ON_DURATION_IDLE       350     /* in msecs */
+#define ATH_LED_OFF_DURATION_IDLE      250     /* in msecs */
+
+enum ath_led_type {
+       ATH_LED_RADIO,
+       ATH_LED_ASSOC,
+       ATH_LED_TX,
+       ATH_LED_RX
+};
+
+struct ath_led {
+       struct ath_softc *sc;
+       struct led_classdev led_cdev;
+       enum ath_led_type led_type;
+       char name[32];
+       bool registered;
+};
+
+/* Rfkill */
+#define ATH_RFKILL_POLL_INTERVAL       2000 /* msecs */
+
+struct ath_rfkill {
+       struct rfkill *rfkill;
+       struct delayed_work rfkill_poll;
+       char rfkill_name[32];
+};
+
+/********************/
+/* 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 */
+
+/*
+ * 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_TXPOWER_MAX         100     /* .5 dBm units */
+#define ATH_RSSI_DUMMY_MARKER   0x127
+#define ATH_RATE_DUMMY_MARKER   0
+
+#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_FULL_RESET        BIT(4)
+#define SC_OP_PREAMBLE_SHORT    BIT(5)
+#define SC_OP_PROTECT_ENABLE    BIT(6)
+#define SC_OP_RXFLUSH           BIT(7)
+#define SC_OP_LED_ASSOCIATED    BIT(8)
+#define SC_OP_RFKILL_REGISTERED BIT(9)
+#define SC_OP_RFKILL_SW_BLOCKED BIT(10)
+#define SC_OP_RFKILL_HW_BLOCKED BIT(11)
+#define SC_OP_WAIT_FOR_BEACON   BIT(12)
+#define SC_OP_LED_ON            BIT(13)
+#define SC_OP_SCANNING          BIT(14)
+#define SC_OP_TSF_RESET         BIT(15)
+
+struct ath_bus_ops {
+       void            (*read_cachesize)(struct ath_softc *sc, int *csz);
+       void            (*cleanup)(struct ath_softc *sc);
+       bool            (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
+};
+
+struct ath_wiphy;
+
+struct ath_softc {
+       struct ieee80211_hw *hw;
+       struct device *dev;
+
+       spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
+       struct ath_wiphy *pri_wiphy;
+       struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
+                                      * have NULL entries */
+       int num_sec_wiphy; /* number of sec_wiphy pointers in the array */
+       int chan_idx;
+       int chan_is_ht;
+       struct ath_wiphy *next_wiphy;
+       struct work_struct chan_work;
+       int wiphy_select_failures;
+       unsigned long wiphy_select_first_fail;
+       struct delayed_work wiphy_work;
+       unsigned long wiphy_scheduler_int;
+       int wiphy_scheduler_index;
+
+       struct tasklet_struct intr_tq;
+       struct tasklet_struct bcon_tasklet;
+       struct ath_hw *sc_ah;
+       void __iomem *mem;
+       int irq;
+       spinlock_t sc_resetlock;
+       spinlock_t sc_serial_rw;
+       struct mutex mutex;
+
+       u8 curbssid[ETH_ALEN];
+       u8 bssidmask[ETH_ALEN];
+       u32 intrstatus;
+       u32 sc_flags; /* SC_OP_* */
+       u16 curtxpow;
+       u16 curaid;
+       u16 cachelsz;
+       u8 nbcnvifs;
+       u16 nvifs;
+       u8 tx_chainmask;
+       u8 rx_chainmask;
+       u32 keymax;
+       DECLARE_BITMAP(keymap, ATH_KEYMAX);
+       u8 splitmic;
+       atomic_t ps_usecount;
+       enum ath9k_int imask;
+       enum ath9k_ht_extprotspacing ht_extprotspacing;
+       enum ath9k_ht_macmode tx_chan_width;
+
+       struct ath_config config;
+       struct ath_rx rx;
+       struct ath_tx tx;
+       struct ath_beacon beacon;
+       struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
+       struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
+       struct ath_rate_table *cur_rate_table;
+       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+
+       struct ath_led radio_led;
+       struct ath_led assoc_led;
+       struct ath_led tx_led;
+       struct ath_led rx_led;
+       struct delayed_work ath_led_blink_work;
+       int led_on_duration;
+       int led_off_duration;
+       int led_on_cnt;
+       int led_off_cnt;
+
+       struct ath_rfkill rf_kill;
+       struct ath_ani ani;
+       struct ath9k_node_stats nodestats;
+#ifdef CONFIG_ATH9K_DEBUG
+       struct ath9k_debug debug;
+#endif
+       struct ath_bus_ops *bus_ops;
+};
+
+struct ath_wiphy {
+       struct ath_softc *sc; /* shared for all virtual wiphys */
+       struct ieee80211_hw *hw;
+       enum ath_wiphy_state {
+               ATH_WIPHY_INACTIVE,
+               ATH_WIPHY_ACTIVE,
+               ATH_WIPHY_PAUSING,
+               ATH_WIPHY_PAUSED,
+               ATH_WIPHY_SCAN,
+       } state;
+       int chan_idx;
+       int chan_is_ht;
+};
+
+int ath_reset(struct ath_softc *sc, bool retry_tx);
+int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
+int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
+int ath_cabq_update(struct ath_softc *);
+
+static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
+{
+       sc->bus_ops->read_cachesize(sc, csz);
+}
+
+static inline void ath_bus_cleanup(struct ath_softc *sc)
+{
+       sc->bus_ops->cleanup(sc);
+}
+
+extern struct ieee80211_ops ath9k_ops;
+
+irqreturn_t ath_isr(int irq, void *dev);
+void ath_cleanup(struct ath_softc *sc);
+int ath_attach(u16 devid, struct ath_softc *sc);
+void ath_detach(struct ath_softc *sc);
+const char *ath_mac_bb_name(u32 mac_bb_version);
+const char *ath_rf_name(u16 rf_version);
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                          struct ath9k_channel *ichan);
+void ath_update_chainmask(struct ath_softc *sc, int is_ht);
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                   struct ath9k_channel *hchan);
+void ath_radio_enable(struct ath_softc *sc);
+void ath_radio_disable(struct ath_softc *sc);
+
+#ifdef CONFIG_PCI
+int ath_pci_init(void);
+void ath_pci_exit(void);
+#else
+static inline int ath_pci_init(void) { return 0; };
+static inline void ath_pci_exit(void) {};
+#endif
+
+#ifdef CONFIG_ATHEROS_AR71XX
+int ath_ahb_init(void);
+void ath_ahb_exit(void);
+#else
+static inline int ath_ahb_init(void) { return 0; };
+static inline void ath_ahb_exit(void) {};
+#endif
+
+static inline void ath9k_ps_wakeup(struct ath_softc *sc)
+{
+       if (atomic_inc_return(&sc->ps_usecount) == 1)
+               if (sc->sc_ah->power_mode !=  ATH9K_PM_AWAKE) {
+                       sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
+                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+               }
+}
+
+static inline void ath9k_ps_restore(struct ath_softc *sc)
+{
+       if (atomic_dec_and_test(&sc->ps_usecount))
+               if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
+                   !(sc->sc_flags & SC_OP_WAIT_FOR_BEACON))
+                       ath9k_hw_setpower(sc->sc_ah,
+                                         sc->sc_ah->restore_mode);
+}
+
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
+int ath9k_wiphy_add(struct ath_softc *sc);
+int ath9k_wiphy_del(struct ath_wiphy *aphy);
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ath9k_wiphy_pause(struct ath_wiphy *aphy);
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+int ath9k_wiphy_select(struct ath_wiphy *aphy);
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int);
+void ath9k_wiphy_chan_work(struct work_struct *work);
+bool ath9k_wiphy_started(struct ath_softc *sc);
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+                                 struct ath_wiphy *selected);
+bool ath9k_wiphy_scanning(struct ath_softc *sc);
+void ath9k_wiphy_work(struct work_struct *work);
+
+/*
+ * 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.
+ */
+
+static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
+{
+       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+               unsigned long flags;
+               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+               iowrite32(val, ah->ah_sc->mem + reg_offset);
+               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+       } else
+               iowrite32(val, ah->ah_sc->mem + reg_offset);
+}
+
+static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
+{
+       u32 val;
+       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+               unsigned long flags;
+               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+               val = ioread32(ah->ah_sc->mem + reg_offset);
+               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+       } else
+               val = ioread32(ah->ah_sc->mem + reg_offset);
+       return val;
+}
+
+#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
new file mode 100644 (file)
index 0000000..eb4759f
--- /dev/null
@@ -0,0 +1,743 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+#define FUDGE 2
+
+/*
+ *  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 ath_beaconq_config(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_tx_queue_info qi;
+
+       ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
+       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
+               /* 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->beacon.beacon_qi.tqi_aifs;
+               qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
+               qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
+       }
+
+       if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to update h/w beacon queue parameters\n");
+               return 0;
+       } else {
+               ath9k_hw_resettxqueue(ah, sc->beacon.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 ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
+                            struct ath_buf *bf)
+{
+       struct sk_buff *skb = bf->bf_mpdu;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_desc *ds;
+       struct ath9k_11n_rate_series series[4];
+       struct ath_rate_table *rt;
+       int flags, antenna, ctsrate = 0, ctsduration = 0;
+       u8 rate;
+
+       ds = bf->bf_desc;
+       flags = ATH9K_TXDESC_NOACK;
+
+       if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+            (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
+           (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 beacon.
+                * Should only switch every beacon period, not for every SWBA
+                * XXX assumes two antennae
+                */
+               antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
+       }
+
+       ds->ds_data = bf->bf_buf_addr;
+
+       rt = sc->cur_rate_table;
+       rate = rt->info[0].ratecode;
+       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+               rate |= rt->info[0].short_preamble;
+
+       ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
+                              ATH9K_PKT_TYPE_BEACON,
+                              MAX_RATE_POWER,
+                              ATH9K_TXKEYIX_INVALID,
+                              ATH9K_KEY_TYPE_CLEAR,
+                              flags);
+
+       /* NB: beacon's BufLen must be a multiple of 4 bytes */
+       ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
+                           true, true, ds);
+
+       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
+       series[0].Tries = 1;
+       series[0].Rate = rate;
+       series[0].ChSel = 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);
+}
+
+static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
+                                          struct ieee80211_vif *vif)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_buf *bf;
+       struct ath_vif *avp;
+       struct sk_buff *skb;
+       struct ath_txq *cabq;
+       struct ieee80211_tx_info *info;
+       int cabq_depth;
+
+       if (aphy->state != ATH_WIPHY_ACTIVE)
+               return NULL;
+
+       avp = (void *)vif->drv_priv;
+       cabq = sc->beacon.cabq;
+
+       if (avp->av_bcbuf == NULL)
+               return NULL;
+
+       /* Release the old beacon first */
+
+       bf = avp->av_bcbuf;
+       skb = bf->bf_mpdu;
+       if (skb) {
+               dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                                skb->len, DMA_TO_DEVICE);
+               dev_kfree_skb_any(skb);
+       }
+
+       /* Get a new beacon from mac80211 */
+
+       skb = ieee80211_beacon_get(hw, vif);
+       bf->bf_mpdu = skb;
+       if (skb == NULL)
+               return NULL;
+       ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
+               avp->tsf_adjust;
+
+       info = IEEE80211_SKB_CB(skb);
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               /*
+                * TODO: make sure the seq# gets assigned properly (vs. other
+                * TX frames)
+                */
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+               sc->tx.seq_no += 0x10;
+               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+       }
+
+       bf->bf_buf_addr = bf->bf_dmacontext =
+               dma_map_single(sc->dev, skb->data,
+                              skb->len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
+               dev_kfree_skb_any(skb);
+               bf->bf_mpdu = NULL;
+               DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n");
+               return NULL;
+       }
+
+       skb = ieee80211_get_buffered_bc(hw, vif);
+
+       /*
+        * if the CABQ traffic from previous DTIM is pending and the current
+        *  beacon is also a DTIM.
+        *  1) if there is only one vif let the cab traffic continue.
+        *  2) if there are more than one vif and we are using staggered
+        *     beacons, then drain the cabq by dropping all the frames in
+        *     the cabq so that the current vifs cab traffic can be scheduled.
+        */
+       spin_lock_bh(&cabq->axq_lock);
+       cabq_depth = cabq->axq_depth;
+       spin_unlock_bh(&cabq->axq_lock);
+
+       if (skb && cabq_depth) {
+               if (sc->nvifs > 1) {
+                       DPRINTF(sc, ATH_DBG_BEACON,
+                               "Flushing previous cabq traffic\n");
+                       ath_draintxq(sc, cabq, false);
+               }
+       }
+
+       ath_beacon_setup(sc, avp, bf);
+
+       while (skb) {
+               ath_tx_cabq(hw, skb);
+               skb = ieee80211_get_buffered_bc(hw, vif);
+       }
+
+       return bf;
+}
+
+/*
+ * Startup beacon transmission for adhoc mode when they are sent entirely
+ * by the hardware using the self-linked descriptor + veol trick.
+*/
+static void ath_beacon_start_adhoc(struct ath_softc *sc,
+                                  struct ieee80211_vif *vif)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf;
+       struct ath_vif *avp;
+       struct sk_buff *skb;
+
+       avp = (void *)vif->drv_priv;
+
+       if (avp->av_bcbuf == NULL)
+               return;
+
+       bf = avp->av_bcbuf;
+       skb = bf->bf_mpdu;
+
+       ath_beacon_setup(sc, avp, bf);
+
+       /* NB: caller is known to have already stopped tx dma */
+       ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
+       ath9k_hw_txstart(ah, sc->beacon.beaconq);
+       DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
+               sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
+}
+
+int ath_beaconq_setup(struct ath_hw *ah)
+{
+       struct ath9k_tx_queue_info qi;
+
+       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 ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
+{
+       struct ath_softc *sc = aphy->sc;
+       struct ath_vif *avp;
+       struct ath_buf *bf;
+       struct sk_buff *skb;
+       __le64 tstamp;
+
+       avp = (void *)vif->drv_priv;
+
+       /* Allocate a beacon descriptor if we haven't done so. */
+       if (!avp->av_bcbuf) {
+               /* Allocate beacon state for hostap/ibss.  We know
+                * a buffer is available. */
+               avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
+                                                struct ath_buf, list);
+               list_del(&avp->av_bcbuf->list);
+
+               if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
+                   !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+                       int slot;
+                       /*
+                        * Assign the vif to a beacon xmit slot. As
+                        * above, this cannot fail to find one.
+                        */
+                       avp->av_bslot = 0;
+                       for (slot = 0; slot < ATH_BCBUF; slot++)
+                               if (sc->beacon.bslot[slot] == NULL) {
+                                       /*
+                                        * XXX hack, space out slots to better
+                                        * deal with misses
+                                        */
+                                       if (slot+1 < ATH_BCBUF &&
+                                           sc->beacon.bslot[slot+1] == NULL) {
+                                               avp->av_bslot = slot+1;
+                                               break;
+                                       }
+                                       avp->av_bslot = slot;
+                                       /* NB: keep looking for a double slot */
+                               }
+                       BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
+                       sc->beacon.bslot[avp->av_bslot] = vif;
+                       sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
+                       sc->nbcnvifs++;
+               }
+       }
+
+       /* release the previous beacon frame, if it already exists. */
+       bf = avp->av_bcbuf;
+       if (bf->bf_mpdu != NULL) {
+               skb = bf->bf_mpdu;
+               dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                                skb->len, DMA_TO_DEVICE);
+               dev_kfree_skb_any(skb);
+               bf->bf_mpdu = NULL;
+       }
+
+       /* NB: the beacon data buffer must be 32-bit aligned. */
+       skb = ieee80211_beacon_get(sc->hw, vif);
+       if (skb == NULL) {
+               DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
+               return -ENOMEM;
+       }
+
+       tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+       sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
+       /* Calculate a TSF adjustment factor required for staggered beacons. */
+       if (avp->av_bslot > 0) {
+               u64 tsfadjust;
+               int intval;
+
+               intval = sc->hw->conf.beacon_int ?
+                       sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+
+               /*
+                * Calculate the TSF offset for this beacon slot, i.e., the
+                * number of usecs that need to be added to the timestamp field
+                * in Beacon and Probe Response frames. Beacon slot 0 is
+                * processed at the correct offset, so it does not require TSF
+                * adjustment. Other slots are adjusted to get the timestamp
+                * close to the TBTT for the BSS.
+                */
+               tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
+               avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
+
+               DPRINTF(sc, ATH_DBG_BEACON,
+                       "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
+                       avp->av_bslot, intval, (unsigned long long)tsfadjust);
+
+               ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
+                       avp->tsf_adjust;
+       } else
+               avp->tsf_adjust = cpu_to_le64(0);
+
+       bf->bf_mpdu = skb;
+       bf->bf_buf_addr = bf->bf_dmacontext =
+               dma_map_single(sc->dev, skb->data,
+                              skb->len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
+               dev_kfree_skb_any(skb);
+               bf->bf_mpdu = NULL;
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "dma_mapping_error on beacon alloc\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
+{
+       if (avp->av_bcbuf != NULL) {
+               struct ath_buf *bf;
+
+               if (avp->av_bslot != -1) {
+                       sc->beacon.bslot[avp->av_bslot] = NULL;
+                       sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
+                       sc->nbcnvifs--;
+               }
+
+               bf = avp->av_bcbuf;
+               if (bf->bf_mpdu != NULL) {
+                       struct sk_buff *skb = bf->bf_mpdu;
+                       dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                                        skb->len, DMA_TO_DEVICE);
+                       dev_kfree_skb_any(skb);
+                       bf->bf_mpdu = NULL;
+               }
+               list_add_tail(&bf->list, &sc->beacon.bbuf);
+
+               avp->av_bcbuf = NULL;
+       }
+}
+
+void ath_beacon_tasklet(unsigned long data)
+{
+       struct ath_softc *sc = (struct ath_softc *)data;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf = NULL;
+       struct ieee80211_vif *vif;
+       struct ath_wiphy *aphy;
+       int slot;
+       u32 bfaddr, bc = 0, tsftu;
+       u64 tsf;
+       u16 intval;
+
+       /*
+        * Check if the previous beacon has gone out.  If
+        * not don't try to post another, skip this period
+        * and wait for the next.  Missed beacons indicate
+        * a problem and should not occur.  If we miss too
+        * many consecutive beacons reset the device.
+        */
+       if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
+               sc->beacon.bmisscnt++;
+
+               if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
+                       DPRINTF(sc, ATH_DBG_BEACON,
+                               "missed %u consecutive beacons\n",
+                               sc->beacon.bmisscnt);
+               } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
+                       DPRINTF(sc, ATH_DBG_BEACON,
+                               "beacon is officially stuck\n");
+                       ath_reset(sc, false);
+               }
+
+               return;
+       }
+
+       if (sc->beacon.bmisscnt != 0) {
+               DPRINTF(sc, ATH_DBG_BEACON,
+                       "resume beacon xmit after %u misses\n",
+                       sc->beacon.bmisscnt);
+               sc->beacon.bmisscnt = 0;
+       }
+
+       /*
+        * Generate beacon frames. we are sending frames
+        * staggered so calculate the slot for this frame based
+        * on the tsf to safeguard against missing an swba.
+        */
+
+       intval = sc->hw->conf.beacon_int ?
+               sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+
+       tsf = ath9k_hw_gettsf64(ah);
+       tsftu = TSF_TO_TU(tsf>>32, tsf);
+       slot = ((tsftu % intval) * ATH_BCBUF) / intval;
+       /*
+        * Reverse the slot order to get slot 0 on the TBTT offset that does
+        * not require TSF adjustment and other slots adding
+        * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
+        * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
+        * and slot 0 is at correct offset to TBTT.
+        */
+       slot = ATH_BCBUF - slot - 1;
+       vif = sc->beacon.bslot[slot];
+       aphy = sc->beacon.bslot_aphy[slot];
+
+       DPRINTF(sc, ATH_DBG_BEACON,
+               "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
+               slot, tsf, tsftu, intval, vif);
+
+       bfaddr = 0;
+       if (vif) {
+               bf = ath_beacon_generate(aphy->hw, vif);
+               if (bf != NULL) {
+                       bfaddr = bf->bf_daddr;
+                       bc = 1;
+               }
+       }
+
+       /*
+        * Handle slot time change when a non-ERP station joins/leaves
+        * an 11g network.  The 802.11 layer notifies us via callback,
+        * we mark updateslot, then wait one beacon before effecting
+        * the change.  This gives associated stations at least one
+        * beacon interval to note the state change.
+        *
+        * NB: The slot time change state machine is clocked according
+        *     to whether we are bursting or staggering beacons.  We
+        *     recognize the request to update and record the current
+        *     slot then don't transition until that slot is reached
+        *     again.  If we miss a beacon for that slot then we'll be
+        *     slow to transition but we'll be sure at least one beacon
+        *     interval has passed.  When bursting slot is always left
+        *     set to ATH_BCBUF so this check is a noop.
+        */
+       if (sc->beacon.updateslot == UPDATE) {
+               sc->beacon.updateslot = COMMIT; /* commit next beacon */
+               sc->beacon.slotupdate = slot;
+       } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
+               ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
+               sc->beacon.updateslot = OK;
+       }
+       if (bfaddr != 0) {
+               /*
+                * Stop any current dma and put the new frame(s) 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->beacon.beaconq)) {
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "beacon queue %u did not stop?\n", sc->beacon.beaconq);
+               }
+
+               /* NB: cabq traffic should already be queued and primed */
+               ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
+               ath9k_hw_txstart(ah, sc->beacon.beaconq);
+
+               sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
+       }
+}
+
+/*
+ * 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.
+ */
+static void ath_beacon_config_ap(struct ath_softc *sc,
+                                struct ath_beacon_config *conf,
+                                struct ath_vif *avp)
+{
+       u32 nexttbtt, intval;
+
+       /* Configure the timers only when the TSF has to be reset */
+
+       if (!(sc->sc_flags & SC_OP_TSF_RESET))
+               return;
+
+       /* NB: the beacon interval is kept internally in TU's */
+       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+       intval /= ATH_BCBUF;    /* for staggered beacons */
+       nexttbtt = intval;
+       intval |= ATH9K_BEACON_RESET_TSF;
+
+       /*
+        * In AP mode we enable the beacon timers and SWBA interrupts to
+        * prepare beacon frames.
+        */
+       intval |= ATH9K_BEACON_ENA;
+       sc->imask |= ATH9K_INT_SWBA;
+       ath_beaconq_config(sc);
+
+       /* Set the computed AP beacon timers */
+
+       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+       ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+       sc->beacon.bmisscnt = 0;
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+       /* Clear the reset TSF flag, so that subsequent beacon updation
+          will not reset the HW TSF. */
+
+       sc->sc_flags &= ~SC_OP_TSF_RESET;
+}
+
+/*
+ * This sets up the beacon timers according to the timestamp of the last
+ * received beacon and the current TSF, configures PCF and DTIM
+ * handling, programs the sleep registers so the hardware will wakeup in
+ * time to receive beacons, and configures the beacon miss handling so
+ * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
+ * we've associated with.
+ */
+static void ath_beacon_config_sta(struct ath_softc *sc,
+                                 struct ath_beacon_config *conf,
+                                 struct ath_vif *avp)
+{
+       struct ath9k_beacon_state bs;
+       int dtimperiod, dtimcount, sleepduration;
+       int cfpperiod, cfpcount;
+       u32 nexttbtt = 0, intval, tsftu;
+       u64 tsf;
+
+       memset(&bs, 0, sizeof(bs));
+       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+
+       /*
+        * 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;
+
+       /*
+        * Pull nexttbtt forward to reflect the current
+        * TSF and calculate dtim+cfp state for the result.
+        */
+       tsf = ath9k_hw_gettsf64(sc->sc_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);
+
+       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;
+               else if (bs.bs_bmissthreshold <= 0)
+                       bs.bs_bmissthreshold = 1;
+       }
+
+       /*
+        * Calculate sleep duration. The configuration is given in ms.
+        * We ensure 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;
+
+       /* TSF out of range threshold fixed at 1 second */
+       bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
+
+       DPRINTF(sc, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
+       DPRINTF(sc, ATH_DBG_BEACON,
+               "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
+               bs.bs_bmissthreshold, bs.bs_sleepduration,
+               bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
+
+       /* Set the computed STA beacon timers */
+
+       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+       ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs);
+       sc->imask |= ATH9K_INT_BMISS;
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+}
+
+static void ath_beacon_config_adhoc(struct ath_softc *sc,
+                                   struct ath_beacon_config *conf,
+                                   struct ath_vif *avp,
+                                   struct ieee80211_vif *vif)
+{
+       u64 tsf;
+       u32 tsftu, intval, nexttbtt;
+
+       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+
+       /* Pull nexttbtt forward to reflect the current TSF */
+
+       nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+       if (nexttbtt == 0)
+                nexttbtt = intval;
+        else if (intval)
+                nexttbtt = roundup(nexttbtt, intval);
+
+       tsf = ath9k_hw_gettsf64(sc->sc_ah);
+       tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
+       do {
+               nexttbtt += intval;
+       } while (nexttbtt < tsftu);
+
+       DPRINTF(sc, ATH_DBG_BEACON,
+               "IBSS nexttbtt %u intval %u (%u)\n",
+               nexttbtt, intval, 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 (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
+               sc->imask |= ATH9K_INT_SWBA;
+
+       ath_beaconq_config(sc);
+
+       /* Set the computed ADHOC beacon timers */
+
+       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+       ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+       sc->beacon.bmisscnt = 0;
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
+               ath_beacon_start_adhoc(sc, vif);
+}
+
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
+{
+       struct ath_beacon_config conf;
+
+       /* Setup the beacon configuration parameters */
+
+       memset(&conf, 0, sizeof(struct ath_beacon_config));
+       conf.beacon_interval = sc->hw->conf.beacon_int ?
+               sc->hw->conf.beacon_int : 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;
+
+       if (vif) {
+               struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
+
+               switch(avp->av_opmode) {
+               case NL80211_IFTYPE_AP:
+                       ath_beacon_config_ap(sc, &conf, avp);
+                       break;
+               case NL80211_IFTYPE_ADHOC:
+               case NL80211_IFTYPE_MESH_POINT:
+                       ath_beacon_config_adhoc(sc, &conf, avp, vif);
+                       break;
+               case NL80211_IFTYPE_STATION:
+                       ath_beacon_config_sta(sc, &conf, avp);
+                       break;
+               default:
+                       DPRINTF(sc, ATH_DBG_CONFIG,
+                               "Unsupported beaconing mode\n");
+                       return;
+               }
+
+               sc->sc_flags |= SC_OP_BEACONS;
+       }
+}
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
new file mode 100644 (file)
index 0000000..e2d62e9
--- /dev/null
@@ -0,0 +1,1060 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+/* 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 */
+
+static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
+{
+       if (nf > ATH9K_NF_TOO_LOW) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "noise floor value detected (%d) is "
+                       "lower than what we think is a "
+                       "reasonable value (%d)\n",
+                       nf, ATH9K_NF_TOO_LOW);
+               return false;
+       }
+       return 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);
+               }
+       }
+       return;
+}
+
+static void ath9k_hw_do_getnf(struct ath_hw *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);
+       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+               "NF calibrated [ctl] [chain 0] is %d\n", nf);
+       nfarray[0] = nf;
+
+       if (!AR_SREV_9285(ah)) {
+               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);
+               DPRINTF(ah->ah_sc, ATH_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);
+                       DPRINTF(ah->ah_sc, ATH_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);
+       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+               "NF calibrated [ext] [chain 0] is %d\n", nf);
+       nfarray[3] = nf;
+
+       if (!AR_SREV_9285(ah)) {
+               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);
+               DPRINTF(ah->ah_sc, ATH_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);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "NF calibrated [ext] [chain 2] is %d\n", nf);
+                       nfarray[5] = nf;
+               }
+       }
+}
+
+static bool getNoiseFloorThresh(struct ath_hw *ah,
+                               enum ieee80211_band band,
+                               int16_t *nft)
+{
+       switch (band) {
+       case IEEE80211_BAND_5GHZ:
+               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
+               break;
+       case IEEE80211_BAND_2GHZ:
+               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
+               break;
+       default:
+               BUG_ON(1);
+               return false;
+       }
+
+       return true;
+}
+
+static void ath9k_hw_setup_calibration(struct ath_hw *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);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "starting IQ Mismatch Calibration\n");
+               break;
+       case ADC_GAIN_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "starting ADC Gain Calibration\n");
+               break;
+       case ADC_DC_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "starting ADC DC Calibration\n");
+               break;
+       case ADC_DC_INIT_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "starting Init ADC DC Calibration\n");
+               break;
+       }
+
+       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+                   AR_PHY_TIMING_CTRL4_DO_CAL);
+}
+
+static void ath9k_hw_reset_calibration(struct ath_hw *ah,
+                                      struct hal_cal_list *currCal)
+{
+       int i;
+
+       ath9k_hw_setup_calibration(ah, currCal);
+
+       currCal->calState = CAL_RUNNING;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->meas0.sign[i] = 0;
+               ah->meas1.sign[i] = 0;
+               ah->meas2.sign[i] = 0;
+               ah->meas3.sign[i] = 0;
+       }
+
+       ah->cal_samples = 0;
+}
+
+static void ath9k_hw_per_calibration(struct ath_hw *ah,
+                                    struct ath9k_channel *ichan,
+                                    u8 rxchainmask,
+                                    struct hal_cal_list *currCal,
+                                    bool *isCalDone)
+{
+       *isCalDone = 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);
+                       ah->cal_samples++;
+
+                       if (ah->cal_samples >= 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 = true;
+                       } else {
+                               ath9k_hw_setup_calibration(ah, currCal);
+                       }
+               }
+       } else if (!(ichan->CalValid & currCal->calData->calType)) {
+               ath9k_hw_reset_calibration(ah, currCal);
+       }
+}
+
+/* Assumes you are talking about the currently configured channel */
+static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
+                                    enum hal_cal_types calType)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       switch (calType & ah->supp_cals) {
+       case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
+               return true;
+       case ADC_GAIN_CAL:
+       case ADC_DC_CAL:
+               if (conf->channel->band == IEEE80211_BAND_5GHZ &&
+                 conf_is_ht20(conf))
+                       return true;
+               break;
+       }
+       return false;
+}
+
+static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalPowerMeasI[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalPowerMeasQ[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalIqCorrMeas[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+                       ah->cal_samples, i, ah->totalPowerMeasI[i],
+                       ah->totalPowerMeasQ[i],
+                       ah->totalIqCorrMeas[i]);
+       }
+}
+
+static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalAdcIOddPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalAdcIEvenPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalAdcQOddPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ah->totalAdcQEvenPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+                       "oddq=0x%08x; evenq=0x%08x;\n",
+                       ah->cal_samples, i,
+                       ah->totalAdcIOddPhase[i],
+                       ah->totalAdcIEvenPhase[i],
+                       ah->totalAdcQOddPhase[i],
+                       ah->totalAdcQEvenPhase[i]);
+       }
+}
+
+static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalAdcDcOffsetIOddPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalAdcDcOffsetIEvenPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalAdcDcOffsetQOddPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ah->totalAdcDcOffsetQEvenPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+                       "oddq=0x%08x; evenq=0x%08x;\n",
+                       ah->cal_samples, i,
+                       ah->totalAdcDcOffsetIOddPhase[i],
+                       ah->totalAdcDcOffsetIEvenPhase[i],
+                       ah->totalAdcDcOffsetQOddPhase[i],
+                       ah->totalAdcDcOffsetQEvenPhase[i]);
+       }
+}
+
+static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
+{
+       u32 powerMeasQ, powerMeasI, iqCorrMeas;
+       u32 qCoffDenom, iCoffDenom;
+       int32_t qCoff, iCoff;
+       int iqCorrNeg, i;
+
+       for (i = 0; i < numChains; i++) {
+               powerMeasI = ah->totalPowerMeasI[i];
+               powerMeasQ = ah->totalPowerMeasQ[i];
+               iqCorrMeas = ah->totalIqCorrMeas[i];
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Starting IQ Cal and Correction for Chain %d\n",
+                       i);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+                       i, ah->totalIqCorrMeas[i]);
+
+               iqCorrNeg = 0;
+
+               if (iqCorrMeas > 0x80000000) {
+                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+                       iqCorrNeg = 1;
+               }
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+               DPRINTF(ah->ah_sc, ATH_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;
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d qCoff = 0x%08x\n", i, qCoff);
+
+                       iCoff = iCoff & 0x3f;
+                       DPRINTF(ah->ah_sc, ATH_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;
+
+                       DPRINTF(ah->ah_sc, ATH_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);
+                       DPRINTF(ah->ah_sc, ATH_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_hw *ah, u8 numChains)
+{
+       u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
+       u32 qGainMismatch, iGainMismatch, val, i;
+
+       for (i = 0; i < numChains; i++) {
+               iOddMeasOffset = ah->totalAdcIOddPhase[i];
+               iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
+               qOddMeasOffset = ah->totalAdcQOddPhase[i];
+               qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Starting ADC Gain Cal for Chain %d\n", i);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+                       iOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+                       iEvenMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+                       qOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_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;
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d gain_mismatch_i = 0x%08x\n", i,
+                               iGainMismatch);
+                       DPRINTF(ah->ah_sc, ATH_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);
+
+                       DPRINTF(ah->ah_sc, ATH_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_hw *ah, u8 numChains)
+{
+       u32 iOddMeasOffset, iEvenMeasOffset, val, i;
+       int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
+       const struct hal_percal_data *calData =
+               ah->cal_list_curr->calData;
+       u32 numSamples =
+               (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
+
+       for (i = 0; i < numChains; i++) {
+               iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
+               iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
+               qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
+               qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Starting ADC DC Offset Cal for Chain %d\n", i);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_i = %d\n", i,
+                       iOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_i = %d\n", i,
+                       iEvenMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_q = %d\n", i,
+                       qOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_q = %d\n", i,
+                       qEvenMeasOffset);
+
+               iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+               qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+                       iDcMismatch);
+               DPRINTF(ah->ah_sc, ATH_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);
+
+               DPRINTF(ah->ah_sc, ATH_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);
+}
+
+/* This is done for the currently configured channel */
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+       struct hal_cal_list *currCal = ah->cal_list_curr;
+
+       if (!ah->curchan)
+               return true;
+
+       if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
+               return true;
+
+       if (currCal == NULL)
+               return true;
+
+       if (currCal->calState != CAL_DONE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Calibration state incorrect, %d\n",
+                       currCal->calState);
+               return true;
+       }
+
+       if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
+               return true;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+               "Resetting Cal %d state for channel %u\n",
+               currCal->calData->calType, conf->channel->center_freq);
+
+       ah->curchan->CalValid &= ~currCal->calData->calType;
+       currCal->calState = CAL_WAITING;
+
+       return false;
+}
+
+void ath9k_hw_start_nfcal(struct ath_hw *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);
+}
+
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath9k_nfcal_hist *h;
+       int i, j;
+       int32_t val;
+       const u32 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
+       };
+       u8 chainmask;
+
+       if (AR_SREV_9285(ah))
+               chainmask = 0x9;
+       else if (AR_SREV_9280(ah))
+               chainmask = 0x1B;
+       else
+               chainmask = 0x3F;
+
+       h = ah->nfCalHist;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar5416_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (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;
+               udelay(10);
+       }
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar5416_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (-50) << 1) & 0x1ff);
+                       REG_WRITE(ah, ar5416_cca_regs[i], val);
+               }
+       }
+}
+
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
+                      struct ath9k_channel *chan)
+{
+       int16_t nf, nfThresh;
+       int16_t nfarray[NUM_NF_READINGS] = { 0 };
+       struct ath9k_nfcal_hist *h;
+       struct ieee80211_channel *c = chan->chan;
+
+       chan->channelFlags &= (~CHANNEL_CW_INT);
+       if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "NF did not complete in calibration window\n");
+               nf = 0;
+               chan->rawNoiseFloor = nf;
+               return chan->rawNoiseFloor;
+       } else {
+               ath9k_hw_do_getnf(ah, nfarray);
+               nf = nfarray[0];
+               if (getNoiseFloorThresh(ah, c->band, &nfThresh)
+                   && nf > nfThresh) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "noise floor failed detected; "
+                               "detected %d, threshold %d\n",
+                               nf, nfThresh);
+                       chan->channelFlags |= CHANNEL_CW_INT;
+               }
+       }
+
+       h = ah->nfCalHist;
+
+       ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
+       chan->rawNoiseFloor = h[0].privNF;
+
+       return chan->rawNoiseFloor;
+}
+
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *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;
+               }
+       }
+}
+
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       s16 nf;
+
+       if (chan->rawNoiseFloor == 0)
+               nf = -96;
+       else
+               nf = chan->rawNoiseFloor;
+
+       if (!ath9k_hw_nf_in_range(ah, nf))
+               nf = ATH_DEFAULT_NOISE_FLOOR;
+
+       return nf;
+}
+
+static void ath9k_olc_temp_compensation(struct ath_hw *ah)
+{
+       u32 rddata, i;
+       int delta, currPDADC, regval;
+
+       rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
+
+       currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+               delta = (currPDADC - ah->initPDADC + 4) / 8;
+       else
+               delta = (currPDADC - ah->initPDADC + 5) / 10;
+
+       if (delta != ah->PDADCdelta) {
+               ah->PDADCdelta = delta;
+               for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+                       regval = ah->originalGain[i] - delta;
+                       if (regval < 0)
+                               regval = 0;
+
+                       REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
+                                       AR_PHY_TX_GAIN, regval);
+               }
+       }
+}
+
+static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
+{
+
+       u32 regVal;
+       int i, offset, offs_6_1, offs_0;
+       u32 ccomp_org, reg_field;
+       u32 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));
+               udelay(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);
+       udelay(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);
+               udelay(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);
+       udelay(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);
+
+}
+
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+                       u8 rxchainmask, bool longcal,
+                       bool *isCalDone)
+{
+       struct hal_cal_list *currCal = ah->cal_list_curr;
+
+       *isCalDone = true;
+
+       if (currCal &&
+           (currCal->calState == CAL_RUNNING ||
+            currCal->calState == CAL_WAITING)) {
+               ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
+                                        isCalDone);
+               if (*isCalDone) {
+                       ah->cal_list_curr = currCal = currCal->calNext;
+
+                       if (currCal->calState == CAL_WAITING) {
+                               *isCalDone = false;
+                               ath9k_hw_reset_calibration(ah, currCal);
+                       }
+               }
+       }
+
+       if (longcal) {
+               if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+                       ath9k_hw_9285_pa_cal(ah);
+
+               if (OLC_FOR_AR9280_20_LATER)
+                       ath9k_olc_temp_compensation(ah);
+               ath9k_hw_getnf(ah, chan);
+               ath9k_hw_loadnf(ah, ah->curchan);
+               ath9k_hw_start_nfcal(ah);
+
+               if (chan->channelFlags & CHANNEL_CW_INT)
+                       chan->channelFlags &= ~CHANNEL_CW_INT;
+       }
+
+       return true;
+}
+
+static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       if (chan->channelFlags & CHANNEL_HT20) {
+               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+               REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                           AR_PHY_AGC_CONTROL_FLTR_CAL);
+               REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+               REG_SET_BIT(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, AH_WAIT_TIMEOUT)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset "
+                               "calibration failed to complete in "
+                               "1ms; noisy ??\n");
+                       return false;
+               }
+               REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       }
+       REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+       REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+       REG_SET_BIT(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, AH_WAIT_TIMEOUT)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration "
+                               "failed to complete in 1ms; noisy ??\n");
+               return false;
+       }
+
+       REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+       REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+       return true;
+}
+
+bool ath9k_hw_init_cal(struct ath_hw *ah,
+                      struct ath9k_channel *chan)
+{
+       if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
+               if (!ar9285_clc(ah, chan))
+                       return false;
+       } else if (AR_SREV_9280_10_OR_LATER(ah)) {
+               REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+
+               /* Kick off the cal */
+               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,
+                                       AH_WAIT_TIMEOUT)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "offset calibration failed to complete in 1ms; "
+                               "noisy environment?\n");
+                       return false;
+               }
+
+               REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       }
+
+       /* Calibrate the AGC */
+       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, AH_WAIT_TIMEOUT)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "offset calibration failed to complete in 1ms; "
+                       "noisy environment?\n");
+               return false;
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+       }
+
+       /* Do PA Calibration */
+       if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+               ath9k_hw_9285_pa_cal(ah);
+
+       /* Do NF Calibration */
+       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                       REG_READ(ah, AR_PHY_AGC_CONTROL) |
+                       AR_PHY_AGC_CONTROL_NF);
+
+       ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+
+       if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
+               if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
+                       INIT_CAL(&ah->adcgain_caldata);
+                       INSERT_CAL(ah, &ah->adcgain_caldata);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                                       "enabling ADC Gain Calibration.\n");
+               }
+               if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
+                       INIT_CAL(&ah->adcdc_caldata);
+                       INSERT_CAL(ah, &ah->adcdc_caldata);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                                       "enabling ADC DC Calibration.\n");
+               }
+               if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+                       INIT_CAL(&ah->iq_caldata);
+                       INSERT_CAL(ah, &ah->iq_caldata);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                                       "enabling IQ Calibration.\n");
+               }
+
+               ah->cal_list_curr = ah->cal_list;
+
+               if (ah->cal_list_curr)
+                       ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
+       }
+
+       chan->CalValid = 0;
+
+       return 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
+};
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
new file mode 100644 (file)
index 0000000..1c74bd5
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2008-2009 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 CALIB_H
+#define CALIB_H
+
+extern const struct hal_percal_data iq_cal_multi_sample;
+extern const struct hal_percal_data iq_cal_single_sample;
+extern const struct hal_percal_data adc_gain_cal_multi_sample;
+extern const struct hal_percal_data adc_gain_cal_single_sample;
+extern const struct hal_percal_data adc_dc_cal_multi_sample;
+extern const struct hal_percal_data adc_dc_cal_single_sample;
+extern const struct hal_percal_data adc_init_dc_cal;
+
+#define AR_PHY_CCA_MAX_GOOD_VALUE                      -85
+#define AR_PHY_CCA_MAX_HIGH_VALUE                      -62
+#define AR_PHY_CCA_MIN_BAD_VALUE                       -140
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
+
+#define NUM_NF_READINGS       6
+#define ATH9K_NF_CAL_HIST_MAX 5
+
+struct ar5416IniArray {
+       u32 *ia_array;
+       u32 ia_rows;
+       u32 ia_columns;
+};
+
+#define INIT_INI_ARRAY(iniarray, array, rows, columns) do {    \
+               (iniarray)->ia_array = (u32 *)(array);          \
+               (iniarray)->ia_rows = (rows);                   \
+               (iniarray)->ia_columns = (columns);             \
+       } 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)->cal_list_last == NULL) {                    \
+                       (_ahp)->cal_list =                              \
+                               (_ahp)->cal_list_last = (_perCal);      \
+                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
+               } else {                                                \
+                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
+                       (_ahp)->cal_list_last = (_perCal);              \
+                       (_perCal)->calNext = (_ahp)->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;
+       u32 calNumSamples;
+       u32 calCountMax;
+       void (*calCollect) (struct ath_hw *);
+       void (*calPostProc) (struct ath_hw *, u8);
+};
+
+struct hal_cal_list {
+       const struct hal_percal_data *calData;
+       enum hal_cal_state calState;
+       struct hal_cal_list *calNext;
+};
+
+struct ath9k_nfcal_hist {
+       int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
+       u8 currIndex;
+       int16_t privNF;
+       u8 invalidNFcount;
+};
+
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
+void ath9k_hw_start_nfcal(struct ath_hw *ah);
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
+                      struct ath9k_channel *chan);
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+                       u8 rxchainmask, bool longcal,
+                       bool *isCalDone);
+bool ath9k_hw_init_cal(struct ath_hw *ah,
+                      struct ath9k_channel *chan);
+
+#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
new file mode 100644 (file)
index 0000000..97df20c
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * Copyright (c) 2008-2009 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 <asm/unaligned.h>
+
+#include "ath9k.h"
+
+static unsigned int ath9k_debug = DBG_DEFAULT;
+module_param_named(debug, ath9k_debug, uint, 0);
+
+static struct dentry *ath9k_debugfs_root;
+
+void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
+{
+       if (!sc)
+               return;
+
+       if (sc->debug.debug_mask & dbg_mask) {
+               va_list args;
+
+               va_start(args, fmt);
+               printk(KERN_DEBUG "ath9k: ");
+               vprintk(fmt, args);
+               va_end(args);
+       }
+}
+
+static int ath9k_debugfs_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t read_file_dma(struct file *file, char __user *user_buf,
+                            size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       struct ath_hw *ah = sc->sc_ah;
+       char buf[1024];
+       unsigned int len = 0;
+       u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
+       int i, qcuOffset = 0, dcuOffset = 0;
+       u32 *qcuBase = &val[0], *dcuBase = &val[4];
+
+       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)));
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "Raw DMA Debug values:\n");
+
+       for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
+               if (i % 4 == 0)
+                       len += snprintf(buf + len, sizeof(buf) - len, "\n");
+
+               val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
+               len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ",
+                               i, val[i]);
+       }
+
+       len += snprintf(buf + len, sizeof(buf) - len, "\n\n");
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "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++;
+               }
+
+               len += snprintf(buf + len, sizeof(buf) - len,
+                       "%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);
+       }
+
+       len += snprintf(buf + len, sizeof(buf) - len, "\n");
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
+               (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "qcu_complete state: %2x    dcu_complete state:     %2x\n",
+               (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "dcu_arb state:      %2x    dcu_fp state:           %2x\n",
+               (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
+               (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
+               (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
+               (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
+
+       len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n",
+                       REG_READ(ah, AR_OBS_BUS_1));
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "AR_CR: 0x%x \n", REG_READ(ah, AR_CR));
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_dma = {
+       .read = read_file_dma,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+
+void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
+{
+       if (status)
+               sc->debug.stats.istats.total++;
+       if (status & ATH9K_INT_RX)
+               sc->debug.stats.istats.rxok++;
+       if (status & ATH9K_INT_RXEOL)
+               sc->debug.stats.istats.rxeol++;
+       if (status & ATH9K_INT_RXORN)
+               sc->debug.stats.istats.rxorn++;
+       if (status & ATH9K_INT_TX)
+               sc->debug.stats.istats.txok++;
+       if (status & ATH9K_INT_TXURN)
+               sc->debug.stats.istats.txurn++;
+       if (status & ATH9K_INT_MIB)
+               sc->debug.stats.istats.mib++;
+       if (status & ATH9K_INT_RXPHY)
+               sc->debug.stats.istats.rxphyerr++;
+       if (status & ATH9K_INT_RXKCM)
+               sc->debug.stats.istats.rx_keycache_miss++;
+       if (status & ATH9K_INT_SWBA)
+               sc->debug.stats.istats.swba++;
+       if (status & ATH9K_INT_BMISS)
+               sc->debug.stats.istats.bmiss++;
+       if (status & ATH9K_INT_BNR)
+               sc->debug.stats.istats.bnr++;
+       if (status & ATH9K_INT_CST)
+               sc->debug.stats.istats.cst++;
+       if (status & ATH9K_INT_GTT)
+               sc->debug.stats.istats.gtt++;
+       if (status & ATH9K_INT_TIM)
+               sc->debug.stats.istats.tim++;
+       if (status & ATH9K_INT_CABEND)
+               sc->debug.stats.istats.cabend++;
+       if (status & ATH9K_INT_DTIMSYNC)
+               sc->debug.stats.istats.dtimsync++;
+       if (status & ATH9K_INT_DTIM)
+               sc->debug.stats.istats.dtim++;
+}
+
+static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
+                                  size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[512];
+       unsigned int len = 0;
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_interrupt = {
+       .read = read_file_interrupt,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+       struct ath_tx_info_priv *tx_info_priv = NULL;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_tx_rate *rates = tx_info->status.rates;
+       int final_ts_idx, idx;
+
+       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       final_ts_idx = tx_info_priv->tx.ts_rateindex;
+       idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
+
+       sc->debug.stats.n_rcstats[idx].success++;
+}
+
+static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+       struct ath_tx_info_priv *tx_info_priv = NULL;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_tx_rate *rates = tx_info->status.rates;
+       int final_ts_idx, idx;
+
+       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       final_ts_idx = tx_info_priv->tx.ts_rateindex;
+       idx = rates[final_ts_idx].idx;
+
+       sc->debug.stats.legacy_rcstats[idx].success++;
+}
+
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+       if (conf_is_ht(&sc->hw->conf))
+               ath_debug_stat_11n_rc(sc, skb);
+       else
+               ath_debug_stat_legacy_rc(sc, skb);
+}
+
+/* FIXME: legacy rates, later on .. */
+void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+                           int xretries, int retries, u8 per)
+{
+       if (conf_is_ht(&sc->hw->conf)) {
+               int idx = sc->cur_rate_table->info[rix].dot11rate;
+
+               sc->debug.stats.n_rcstats[idx].xretries += xretries;
+               sc->debug.stats.n_rcstats[idx].retries += retries;
+               sc->debug.stats.n_rcstats[idx].per = per;
+       }
+}
+
+static ssize_t ath_read_file_stat_11n_rc(struct file *file,
+                                        char __user *user_buf,
+                                        size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[1024];
+       unsigned int len = 0;
+       int i = 0;
+
+       len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success",
+                      "Retries", "XRetries", "PER");
+
+       for (i = 0; i <= 15; i++) {
+               len += snprintf(buf + len, sizeof(buf) - len,
+                               "%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
+                               sc->debug.stats.n_rcstats[i].success,
+                               sc->debug.stats.n_rcstats[i].retries,
+                               sc->debug.stats.n_rcstats[i].xretries,
+                               sc->debug.stats.n_rcstats[i].per);
+       }
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath_read_file_stat_legacy_rc(struct file *file,
+                                           char __user *user_buf,
+                                           size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[512];
+       unsigned int len = 0;
+       int i = 0;
+
+       len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success");
+
+       for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
+               len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n",
+                               sc->cur_rate_table->info[i].ratekbps / 1000,
+                               sc->debug.stats.legacy_rcstats[i].success);
+       }
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+
+       if (sc->cur_rate_table == NULL)
+               return 0;
+
+       if (conf_is_ht(&sc->hw->conf))
+               return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
+       else
+               return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
+}
+
+static const struct file_operations fops_rcstat = {
+       .read = read_file_rcstat,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
+{
+       switch (state) {
+       case ATH_WIPHY_INACTIVE:
+               return "INACTIVE";
+       case ATH_WIPHY_ACTIVE:
+               return "ACTIVE";
+       case ATH_WIPHY_PAUSING:
+               return "PAUSING";
+       case ATH_WIPHY_PAUSED:
+               return "PAUSED";
+       case ATH_WIPHY_SCAN:
+               return "SCAN";
+       }
+       return "?";
+}
+
+static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
+                              size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[512];
+       unsigned int len = 0;
+       int i;
+       u8 addr[ETH_ALEN];
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "primary: %s (%s chan=%d ht=%d)\n",
+                       wiphy_name(sc->pri_wiphy->hw->wiphy),
+                       ath_wiphy_state_str(sc->pri_wiphy->state),
+                       sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               struct ath_wiphy *aphy = sc->sec_wiphy[i];
+               if (aphy == NULL)
+                       continue;
+               len += snprintf(buf + len, sizeof(buf) - len,
+                               "secondary: %s (%s chan=%d ht=%d)\n",
+                               wiphy_name(aphy->hw->wiphy),
+                               ath_wiphy_state_str(aphy->state),
+                               aphy->chan_idx, aphy->chan_is_ht);
+       }
+
+       put_unaligned_le32(REG_READ(sc->sc_ah, AR_STA_ID0), addr);
+       put_unaligned_le16(REG_READ(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "addr: %pM\n", addr);
+       put_unaligned_le32(REG_READ(sc->sc_ah, AR_BSSMSKL), addr);
+       put_unaligned_le16(REG_READ(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "addrmask: %pM\n", addr);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name)
+{
+       int i;
+       if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0)
+               return sc->pri_wiphy;
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               struct ath_wiphy *aphy = sc->sec_wiphy[i];
+               if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0)
+                       return aphy;
+       }
+       return NULL;
+}
+
+static int del_wiphy(struct ath_softc *sc, const char *name)
+{
+       struct ath_wiphy *aphy = get_wiphy(sc, name);
+       if (!aphy)
+               return -ENOENT;
+       return ath9k_wiphy_del(aphy);
+}
+
+static int pause_wiphy(struct ath_softc *sc, const char *name)
+{
+       struct ath_wiphy *aphy = get_wiphy(sc, name);
+       if (!aphy)
+               return -ENOENT;
+       return ath9k_wiphy_pause(aphy);
+}
+
+static int unpause_wiphy(struct ath_softc *sc, const char *name)
+{
+       struct ath_wiphy *aphy = get_wiphy(sc, name);
+       if (!aphy)
+               return -ENOENT;
+       return ath9k_wiphy_unpause(aphy);
+}
+
+static int select_wiphy(struct ath_softc *sc, const char *name)
+{
+       struct ath_wiphy *aphy = get_wiphy(sc, name);
+       if (!aphy)
+               return -ENOENT;
+       return ath9k_wiphy_select(aphy);
+}
+
+static int schedule_wiphy(struct ath_softc *sc, const char *msec)
+{
+       ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0));
+       return 0;
+}
+
+static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[50];
+       size_t len;
+
+       len = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, len))
+               return -EFAULT;
+       buf[len] = '\0';
+       if (len > 0 && buf[len - 1] == '\n')
+               buf[len - 1] = '\0';
+
+       if (strncmp(buf, "add", 3) == 0) {
+               int res = ath9k_wiphy_add(sc);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "del=", 4) == 0) {
+               int res = del_wiphy(sc, buf + 4);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "pause=", 6) == 0) {
+               int res = pause_wiphy(sc, buf + 6);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "unpause=", 8) == 0) {
+               int res = unpause_wiphy(sc, buf + 8);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "select=", 7) == 0) {
+               int res = select_wiphy(sc, buf + 7);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "schedule=", 9) == 0) {
+               int res = schedule_wiphy(sc, buf + 9);
+               if (res < 0)
+                       return res;
+       } else
+               return -EOPNOTSUPP;
+
+       return count;
+}
+
+static const struct file_operations fops_wiphy = {
+       .read = read_file_wiphy,
+       .write = write_file_wiphy,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+
+int ath9k_init_debug(struct ath_softc *sc)
+{
+       sc->debug.debug_mask = ath9k_debug;
+
+       if (!ath9k_debugfs_root)
+               return -ENOENT;
+
+       sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
+                                                     ath9k_debugfs_root);
+       if (!sc->debug.debugfs_phy)
+               goto err;
+
+       sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
+                                      sc->debug.debugfs_phy, sc, &fops_dma);
+       if (!sc->debug.debugfs_dma)
+               goto err;
+
+       sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
+                                                    S_IRUGO,
+                                                    sc->debug.debugfs_phy,
+                                                    sc, &fops_interrupt);
+       if (!sc->debug.debugfs_interrupt)
+               goto err;
+
+       sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
+                                                 S_IRUGO,
+                                                 sc->debug.debugfs_phy,
+                                                 sc, &fops_rcstat);
+       if (!sc->debug.debugfs_rcstat)
+               goto err;
+
+       sc->debug.debugfs_wiphy = debugfs_create_file(
+               "wiphy", S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc,
+               &fops_wiphy);
+       if (!sc->debug.debugfs_wiphy)
+               goto err;
+
+       return 0;
+err:
+       ath9k_exit_debug(sc);
+       return -ENOMEM;
+}
+
+void ath9k_exit_debug(struct ath_softc *sc)
+{
+       debugfs_remove(sc->debug.debugfs_wiphy);
+       debugfs_remove(sc->debug.debugfs_rcstat);
+       debugfs_remove(sc->debug.debugfs_interrupt);
+       debugfs_remove(sc->debug.debugfs_dma);
+       debugfs_remove(sc->debug.debugfs_phy);
+}
+
+int ath9k_debug_create_root(void)
+{
+       ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
+       if (!ath9k_debugfs_root)
+               return -ENOENT;
+
+       return 0;
+}
+
+void ath9k_debug_remove_root(void)
+{
+       debugfs_remove(ath9k_debugfs_root);
+       ath9k_debugfs_root = NULL;
+}
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
new file mode 100644 (file)
index 0000000..23298b9
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2008-2009 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 DEBUG_H
+#define DEBUG_H
+
+enum ATH_DEBUG {
+       ATH_DBG_RESET           = 0x00000001,
+       ATH_DBG_QUEUE           = 0x00000002,
+       ATH_DBG_EEPROM          = 0x00000004,
+       ATH_DBG_CALIBRATE       = 0x00000008,
+       ATH_DBG_INTERRUPT       = 0x00000010,
+       ATH_DBG_REGULATORY      = 0x00000020,
+       ATH_DBG_ANI             = 0x00000040,
+       ATH_DBG_XMIT            = 0x00000080,
+       ATH_DBG_BEACON          = 0x00000100,
+       ATH_DBG_CONFIG          = 0x00000200,
+       ATH_DBG_FATAL           = 0x00000400,
+       ATH_DBG_ANY             = 0xffffffff
+};
+
+#define DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH9K_DEBUG
+
+/**
+ * struct ath_interrupt_stats - Contains statistics about interrupts
+ * @total: Total no. of interrupts generated so far
+ * @rxok: RX with no errors
+ * @rxeol: RX with no more RXDESC available
+ * @rxorn: RX FIFO overrun
+ * @txok: TX completed at the requested rate
+ * @txurn: TX FIFO underrun
+ * @mib: MIB regs reaching its threshold
+ * @rxphyerr: RX with phy errors
+ * @rx_keycache_miss: RX with key cache misses
+ * @swba: Software Beacon Alert
+ * @bmiss: Beacon Miss
+ * @bnr: Beacon Not Ready
+ * @cst: Carrier Sense TImeout
+ * @gtt: Global TX Timeout
+ * @tim: RX beacon TIM occurrence
+ * @cabend: RX End of CAB traffic
+ * @dtimsync: DTIM sync lossage
+ * @dtim: RX Beacon with DTIM
+ */
+struct ath_interrupt_stats {
+       u32 total;
+       u32 rxok;
+       u32 rxeol;
+       u32 rxorn;
+       u32 txok;
+       u32 txeol;
+       u32 txurn;
+       u32 mib;
+       u32 rxphyerr;
+       u32 rx_keycache_miss;
+       u32 swba;
+       u32 bmiss;
+       u32 bnr;
+       u32 cst;
+       u32 gtt;
+       u32 tim;
+       u32 cabend;
+       u32 dtimsync;
+       u32 dtim;
+};
+
+struct ath_legacy_rc_stats {
+       u32 success;
+};
+
+struct ath_11n_rc_stats {
+       u32 success;
+       u32 retries;
+       u32 xretries;
+       u8 per;
+};
+
+struct ath_stats {
+       struct ath_interrupt_stats istats;
+       struct ath_legacy_rc_stats legacy_rcstats[12];  /* max(11a,11b,11g) */
+       struct ath_11n_rc_stats n_rcstats[16];          /* 0..15 MCS rates */
+};
+
+struct ath9k_debug {
+       int debug_mask;
+       struct dentry *debugfs_phy;
+       struct dentry *debugfs_dma;
+       struct dentry *debugfs_interrupt;
+       struct dentry *debugfs_rcstat;
+       struct dentry *debugfs_wiphy;
+       struct ath_stats stats;
+};
+
+void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
+int ath9k_init_debug(struct ath_softc *sc);
+void ath9k_exit_debug(struct ath_softc *sc);
+int ath9k_debug_create_root(void);
+void ath9k_debug_remove_root(void);
+void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
+void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+                           int xretries, int retries, u8 per);
+
+#else
+
+static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
+                          const char *fmt, ...)
+{
+}
+
+static inline int ath9k_init_debug(struct ath_softc *sc)
+{
+       return 0;
+}
+
+static inline void ath9k_exit_debug(struct ath_softc *sc)
+{
+}
+
+static inline int ath9k_debug_create_root(void)
+{
+       return 0;
+}
+
+static inline void ath9k_debug_remove_root(void)
+{
+}
+
+static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
+                                           enum ath9k_int status)
+{
+}
+
+static inline void ath_debug_stat_rc(struct ath_softc *sc,
+                                    struct sk_buff *skb)
+{
+}
+
+static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+                                         int xretries, int retries, u8 per)
+{
+}
+
+#endif /* CONFIG_ATH9K_DEBUG */
+
+#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
new file mode 100644 (file)
index 0000000..44fee5a
--- /dev/null
@@ -0,0 +1,2813 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
+                                     u32 reg, u32 mask,
+                                     u32 shift, u32 val)
+{
+       u32 regVal;
+
+       regVal = REG_READ(ah, reg) & ~mask;
+       regVal |= (val << shift) & mask;
+
+       REG_WRITE(ah, reg, regVal);
+
+       if (ah->config.analog_shiftreg)
+               udelay(100);
+
+       return;
+}
+
+static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
+{
+
+       if (fbin == AR5416_BCHAN_UNUSED)
+               return fbin;
+
+       return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
+}
+
+static inline int16_t ath9k_hw_interpolate(u16 target,
+                                          u16 srcLeft, u16 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 bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
+                                                 u16 listSize, u16 *indexL,
+                                                 u16 *indexR)
+{
+       u16 i;
+
+       if (target <= pList[0]) {
+               *indexL = *indexR = 0;
+               return true;
+       }
+       if (target >= pList[listSize - 1]) {
+               *indexL = *indexR = (u16) (listSize - 1);
+               return true;
+       }
+
+       for (i = 0; i < listSize - 1; i++) {
+               if (pList[i] == target) {
+                       *indexL = *indexR = i;
+                       return true;
+               }
+               if (target < pList[i + 1]) {
+                       *indexL = i;
+                       *indexR = (u16) (i + 1);
+                       return false;
+               }
+       }
+       return false;
+}
+
+static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+       struct ath_softc *sc = ah->ah_sc;
+
+       return sc->bus_ops->eeprom_read(ah, off, data);
+}
+
+static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+                                          u8 *pVpdList, u16 numIntercepts,
+                                          u8 *pRetVpdList)
+{
+       u16 i, k;
+       u8 currPwr = pwrMin;
+       u16 idxL = 0, idxR = 0;
+
+       for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
+               ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
+                                              numIntercepts, &(idxL),
+                                              &(idxR));
+               if (idxR < 1)
+                       idxR = 1;
+               if (idxL == numIntercepts - 1)
+                       idxL = (u16) (numIntercepts - 2);
+               if (pPwrList[idxL] == pPwrList[idxR])
+                       k = pVpdList[idxL];
+               else
+                       k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
+                                  (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
+                                 (pPwrList[idxR] - pPwrList[idxL]));
+               pRetVpdList[i] = (u8) k;
+               currPwr += 2;
+       }
+
+       return true;
+}
+
+static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
+                                     struct ath9k_channel *chan,
+                                     struct cal_target_power_leg *powInfo,
+                                     u16 numChannels,
+                                     struct cal_target_power_leg *pNewPower,
+                                     u16 numRates, bool isExtTarget)
+{
+       struct chan_centers centers;
+       u16 clo, chi;
+       int i;
+       int matchIndex = -1, lowIndex = -1;
+       u16 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] =
+                               (u8)ath9k_hw_interpolate(freq, clo, chi,
+                                               powInfo[lowIndex].tPow2x[i],
+                                               powInfo[lowIndex + 1].tPow2x[i]);
+               }
+       }
+}
+
+static void ath9k_get_txgain_index(struct ath_hw *ah,
+               struct ath9k_channel *chan,
+               struct calDataPerFreqOpLoop *rawDatasetOpLoop,
+               u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
+{
+       u8 pcdac, i = 0;
+       u16 idxL = 0, idxR = 0, numPiers;
+       bool match;
+       struct chan_centers centers;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       for (numPiers = 0; numPiers < availPiers; numPiers++)
+               if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
+                       break;
+
+       match = ath9k_hw_get_lower_upper_index(
+                       (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+                       calChans, numPiers, &idxL, &idxR);
+       if (match) {
+               pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
+               *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
+       } else {
+               pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
+               *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
+                               rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+       }
+
+       while (pcdac > ah->originalGain[i] &&
+                       i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
+               i++;
+
+       *pcdacIdx = i;
+       return;
+}
+
+static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
+                               u32 initTxGain,
+                               int txPower,
+                               u8 *pPDADCValues)
+{
+       u32 i;
+       u32 offset;
+
+       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
+                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
+                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+
+       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
+                       AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
+
+       offset = txPower;
+       for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
+               if (i < offset)
+                       pPDADCValues[i] = 0x0;
+               else
+                       pPDADCValues[i] = 0xFF;
+}
+
+
+
+
+static void ath9k_hw_get_target_powers(struct ath_hw *ah,
+                                      struct ath9k_channel *chan,
+                                      struct cal_target_power_ht *powInfo,
+                                      u16 numChannels,
+                                      struct cal_target_power_ht *pNewPower,
+                                      u16 numRates, bool isHt40Target)
+{
+       struct chan_centers centers;
+       u16 clo, chi;
+       int i;
+       int matchIndex = -1, lowIndex = -1;
+       u16 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] = (u8)ath9k_hw_interpolate(freq,
+                                               clo, chi,
+                                               powInfo[lowIndex].tPow2x[i],
+                                               powInfo[lowIndex + 1].tPow2x[i]);
+               }
+       }
+}
+
+static u16 ath9k_hw_get_max_edge_power(u16 freq,
+                                      struct cal_ctl_edges *pRdEdgesPower,
+                                      bool is2GHz, int num_band_edges)
+{
+       u16 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;
+}
+
+/****************************************/
+/* EEPROM Operations for 4K sized cards */
+/****************************************/
+
+static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
+{
+       return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
+}
+
+static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
+{
+       return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
+}
+
+static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+       u16 *eep_data = (u16 *)&ah->eeprom.map4k;
+       int addr, eep_start_loc = 0;
+
+       eep_start_loc = 64;
+
+       if (!ath9k_hw_use_flash(ah)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Reading from EEPROM, not flash\n");
+       }
+
+       for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+               if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                              "Unable to read eeprom region \n");
+                       return false;
+               }
+               eep_data++;
+       }
+
+       return true;
+#undef SIZE_EEPROM_4K
+}
+
+static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
+{
+#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+       struct ar5416_eeprom_4k *eep =
+               (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
+       u16 *eepdata, temp, magic, magic2;
+       u32 sum = 0, el;
+       bool need_swap = false;
+       int i, addr;
+
+
+       if (!ath9k_hw_use_flash(ah)) {
+               if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+                                        &magic)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Reading Magic # failed\n");
+                       return false;
+               }
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Read Magic = 0x%04X\n", magic);
+
+               if (magic != AR5416_EEPROM_MAGIC) {
+                       magic2 = swab16(magic);
+
+                       if (magic2 == AR5416_EEPROM_MAGIC) {
+                               need_swap = true;
+                               eepdata = (u16 *) (&ah->eeprom);
+
+                               for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
+                                       temp = swab16(*eepdata);
+                                       *eepdata = temp;
+                                       eepdata++;
+                               }
+                       } else {
+                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                                       "Invalid EEPROM Magic. "
+                                       "endianness mismatch.\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+               need_swap ? "True" : "False");
+
+       if (need_swap)
+               el = swab16(ah->eeprom.map4k.baseEepHeader.length);
+       else
+               el = ah->eeprom.map4k.baseEepHeader.length;
+
+       if (el > sizeof(struct ar5416_eeprom_4k))
+               el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
+       else
+               el = el / sizeof(u16);
+
+       eepdata = (u16 *)(&ah->eeprom);
+
+       for (i = 0; i < el; i++)
+               sum ^= *eepdata++;
+
+       if (need_swap) {
+               u32 integer;
+               u16 word;
+
+               DPRINTF(ah->ah_sc, ATH_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 || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+                       sum, ah->eep_ops->get_eeprom_ver(ah));
+               return -EINVAL;
+       }
+
+       return 0;
+#undef EEPROM_4K_SIZE
+}
+
+static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
+                                 enum eeprom_param param)
+{
+       struct ar5416_eeprom_4k *eep = &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->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;
+       case EEP_FRAC_N_5G:
+               return 0;
+       default:
+               return 0;
+       }
+}
+
+static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               struct cal_data_per_freq_4k *pRawDataSet,
+                               u8 *bChans, u16 availPiers,
+                               u16 tPdGainOverlap, int16_t *pMinCalPower,
+                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
+                               u16 numXpdGains)
+{
+#define TMP_VAL_VPD_TABLE \
+       ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
+       int i, j, k;
+       int16_t ss;
+       u16 idxL = 0, idxR = 0, numPiers;
+       static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+       u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+       u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+       int16_t vpdStep;
+       int16_t tmpVal;
+       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+       bool 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(
+                                       (u8)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];
+                       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]);
+
+
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrL, pVpdL,
+                                               AR5416_EEP4K_PD_GAIN_ICEPTS,
+                                               vpdTableL[i]);
+                       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] =
+                                       (u8)(ath9k_hw_interpolate((u16)
+                                            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] =
+                               (u16)(maxPwrT4[i] / 2);
+               else
+                       pPdGainBoundaries[i] =
+                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+               pPdGainBoundaries[i] =
+                       min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+               if ((i == 0) && !AR_SREV_5416_20_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++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+                       ss++;
+               }
+
+               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+               tgtIndex = (u8)(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++] = (u8)((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 bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 int16_t *pTxPowerIndexOffset)
+{
+       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+       struct cal_data_per_freq_4k *pRawDataset;
+       u8 *pCalBChans = NULL;
+       u16 pdGainOverlap_t2;
+       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+       u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
+       u16 numPiers, i, j;
+       int16_t tMinCalPower;
+       u16 numXpdGain, xpdMask;
+       u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
+       u32 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 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+       }
+
+       pCalBChans = pEepData->calFreqPier2G;
+       numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
+
+       numXpdGain = 0;
+
+       for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
+               if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
+                       if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
+                               break;
+                       xpdGainValues[numXpdGain] =
+                               (u16)(AR5416_EEP4K_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, 0);
+
+       for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+               if (AR_SREV_5416_20_OR_LATER(ah) &&
+                   (ah->rxchainmask == 5 || 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_20_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);
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
+                                       i, regChainOffset, regOffset,
+                                       reg32);
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "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 true;
+}
+
+static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
+                                                struct ath9k_channel *chan,
+                                                int16_t *ratesArray,
+                                                u16 cfgCtl,
+                                                u16 AntennaReduction,
+                                                u16 twiceMaxRegulatoryPower,
+                                                u16 powerLimit)
+{
+       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+       static const u16 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}
+       };
+       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+       u16 ctlModesFor11g[] =
+               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+                 CTL_2GHT40
+               };
+       u16 numCtlModes, *pCtlMode, ctlMode, freq;
+       struct chan_centers centers;
+       int tx_chainmask;
+       u16 twiceMinEdgePower;
+
+       tx_chainmask = 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->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
+               maxRegAllowedPower -=
+                       (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
+       }
+
+       scaledPower = min(powerLimit, maxRegAllowedPower);
+       scaledPower = max((u16)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, false);
+       ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower2G,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, false);
+       ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower2GHT20,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, 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, true);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPowerCck,
+                               AR5416_NUM_2G_CCK_TARGET_POWERS,
+                               &targetPowerCckExt, 4, true);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower2G,
+                               AR5416_NUM_2G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, true);
+       }
+
+       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+               bool 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 (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
+                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "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++) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "  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);
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "    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 = (u8)min(twiceMaxEdgePower, scaledPower);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "    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((u16)targetPowerCck.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11G:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
+                                       i++) {
+                               targetPowerOfdm.tPow2x[i] =
+                                       min((u16)targetPowerOfdm.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_2GHT20:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
+                                       i++) {
+                               targetPowerHt20.tPow2x[i] =
+                                       min((u16)targetPowerHt20.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11B_EXT:
+                       targetPowerCckExt.tPow2x[0] = min((u16)
+                                       targetPowerCckExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_11G_EXT:
+                       targetPowerOfdmExt.tPow2x[0] = min((u16)
+                                       targetPowerOfdmExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_2GHT40:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
+                                       i++) {
+                               targetPowerHt40.tPow2x[i] =
+                                       min((u16)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 true;
+}
+
+static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
+                                  struct ath9k_channel *chan,
+                                  u16 cfgCtl,
+                                  u8 twiceAntennaReduction,
+                                  u8 twiceMaxRegulatoryPower,
+                                  u8 powerLimit)
+{
+       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+       struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
+       int16_t ratesArray[Ar5416RateSize];
+       int16_t txPowerIndexOffset = 0;
+       u8 ht40PowerIncForPdadc = 2;
+       int i;
+
+       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)) {
+               DPRINTF(ah->ah_sc, ATH_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)) {
+               DPRINTF(ah->ah_sc, ATH_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->regulatory.max_power_level =
+                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+       else
+               ah->regulatory.max_power_level = ratesArray[i];
+
+       return 0;
+}
+
+static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
+                                 struct ath9k_channel *chan)
+{
+       struct modal_eep_4k_header *pModal;
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       u8 biaslevel;
+
+       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+               return;
+
+       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+               return;
+
+       pModal = &eep->modalHeader;
+
+       if (pModal->xpaBiasLvl != 0xff) {
+               biaslevel = pModal->xpaBiasLvl;
+               INI_RA(&ah->iniAddac, 7, 1) =
+                 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
+       }
+}
+
+static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
+                                struct modal_eep_4k_header *pModal,
+                                struct ar5416_eeprom_4k *eep,
+                                u8 txRxAttenLocal, int regChainOffset)
+{
+       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));
+}
+
+static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       struct modal_eep_4k_header *pModal;
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       u8 txRxAttenLocal;
+       u8 ob[5], db1[5], db2[5];
+       u8 ant_div_control1, ant_div_control2;
+       u32 regVal;
+
+       pModal = &eep->modalHeader;
+       txRxAttenLocal = 23;
+
+       REG_WRITE(ah, AR_PHY_SWITCH_COM,
+                 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+       /* Single chain for 4K EEPROM*/
+       ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
+
+       /* 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) {
+               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);
+       }
+}
+
+static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
+                                             struct ath9k_channel *chan)
+{
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       struct modal_eep_4k_header *pModal = &eep->modalHeader;
+
+       return pModal->antCtrlCommon & 0xFFFF;
+}
+
+static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
+                                        enum ieee80211_band freq_band)
+{
+       return 1;
+}
+
+static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
+{
+#define EEP_MAP4K_SPURCHAN \
+       (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
+
+       u16 spur_val = AR_NO_SPUR;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "Getting spur idx %d is2Ghz. %d val %x\n",
+               i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+       switch (ah->config.spurmode) {
+       case SPUR_DISABLE:
+               break;
+       case SPUR_ENABLE_IOCTL:
+               spur_val = ah->config.spurchans[i][is2GHz];
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Getting spur val from new loc. %d\n", spur_val);
+               break;
+       case SPUR_ENABLE_EEPROM:
+               spur_val = EEP_MAP4K_SPURCHAN;
+               break;
+       }
+
+       return spur_val;
+
+#undef EEP_MAP4K_SPURCHAN
+}
+
+static struct eeprom_ops eep_4k_ops = {
+       .check_eeprom           = ath9k_hw_4k_check_eeprom,
+       .get_eeprom             = ath9k_hw_4k_get_eeprom,
+       .fill_eeprom            = ath9k_hw_4k_fill_eeprom,
+       .get_eeprom_ver         = ath9k_hw_4k_get_eeprom_ver,
+       .get_eeprom_rev         = ath9k_hw_4k_get_eeprom_rev,
+       .get_num_ant_config     = ath9k_hw_4k_get_num_ant_config,
+       .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
+       .set_board_values       = ath9k_hw_4k_set_board_values,
+       .set_addac              = ath9k_hw_4k_set_addac,
+       .set_txpower            = ath9k_hw_4k_set_txpower,
+       .get_spur_channel       = ath9k_hw_4k_get_spur_channel
+};
+
+/************************************************/
+/* EEPROM Operations for non-4K (Default) cards */
+/************************************************/
+
+static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
+{
+       return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
+}
+
+static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
+{
+       return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
+}
+
+static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
+       u16 *eep_data = (u16 *)&ah->eeprom.def;
+       int addr, ar5416_eep_start_loc = 0x100;
+
+       for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
+               if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
+                                        eep_data)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Unable to read eeprom region\n");
+                       return false;
+               }
+               eep_data++;
+       }
+       return true;
+#undef SIZE_EEPROM_DEF
+}
+
+static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
+{
+       struct ar5416_eeprom_def *eep =
+               (struct ar5416_eeprom_def *) &ah->eeprom.def;
+       u16 *eepdata, temp, magic, magic2;
+       u32 sum = 0, el;
+       bool need_swap = false;
+       int i, addr, size;
+
+       if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
+               return false;
+       }
+
+       if (!ath9k_hw_use_flash(ah)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Read Magic = 0x%04X\n", magic);
+
+               if (magic != AR5416_EEPROM_MAGIC) {
+                       magic2 = swab16(magic);
+
+                       if (magic2 == AR5416_EEPROM_MAGIC) {
+                               size = sizeof(struct ar5416_eeprom_def);
+                               need_swap = true;
+                               eepdata = (u16 *) (&ah->eeprom);
+
+                               for (addr = 0; addr < size / sizeof(u16); addr++) {
+                                       temp = swab16(*eepdata);
+                                       *eepdata = temp;
+                                       eepdata++;
+                               }
+                       } else {
+                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                                       "Invalid EEPROM Magic. "
+                                       "Endianness mismatch.\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+               need_swap ? "True" : "False");
+
+       if (need_swap)
+               el = swab16(ah->eeprom.def.baseEepHeader.length);
+       else
+               el = ah->eeprom.def.baseEepHeader.length;
+
+       if (el > sizeof(struct ar5416_eeprom_def))
+               el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
+       else
+               el = el / sizeof(u16);
+
+       eepdata = (u16 *)(&ah->eeprom);
+
+       for (i = 0; i < el; i++)
+               sum ^= *eepdata++;
+
+       if (need_swap) {
+               u32 integer, j;
+               u16 word;
+
+               DPRINTF(ah->ah_sc, ATH_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 || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+                       sum, ah->eep_ops->get_eeprom_ver(ah));
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
+                                  enum eeprom_param param)
+{
+       struct ar5416_eeprom_def *eep = &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 AR5416_VER_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;
+       case EEP_OL_PWRCTRL:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+                       return pBase->openLoopPwrCntl ? true : false;
+               else
+                       return false;
+       case EEP_RC_CHAIN_MASK:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+                       return pBase->rcChainMask;
+               else
+                       return 0;
+       case EEP_DAC_HPWR_5G:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
+                       return pBase->dacHiPwrMode_5G;
+               else
+                       return 0;
+       case EEP_FRAC_N_5G:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
+                       return pBase->frac_n_5g;
+               else
+                       return 0;
+       default:
+               return 0;
+       }
+}
+
+static void ath9k_hw_def_set_gain(struct ath_hw *ah,
+                                 struct modal_eep_header *pModal,
+                                 struct ar5416_eeprom_def *eep,
+                                 u8 txRxAttenLocal, int regChainOffset, int i)
+{
+       if (AR5416_VER_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));
+       }
+}
+
+static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
+                                         struct ath9k_channel *chan)
+{
+       struct modal_eep_header *pModal;
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       int i, regChainOffset;
+       u8 txRxAttenLocal;
+
+       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+       txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
+
+       REG_WRITE(ah, AR_PHY_SWITCH_COM,
+                 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               if (AR_SREV_9280(ah)) {
+                       if (i >= 2)
+                               break;
+               }
+
+               if (AR_SREV_5416_20_OR_LATER(ah) &&
+                   (ah->rxchainmask == 5 || 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_20_OR_LATER(ah))
+                       ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
+                                             regChainOffset, i);
+       }
+
+       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);
+               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 (AR5416_VER_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 (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+               if (IS_CHAN_HT40(chan))
+                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+                                     AR_PHY_SETTLING_SWITCH,
+                                     pModal->swSettleHt40);
+       }
+
+       if (AR_SREV_9280_20_OR_LATER(ah) &&
+           AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+               REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
+                             AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
+                             pModal->miscBits);
+
+
+       if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
+               if (IS_CHAN_2GHZ(chan))
+                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+                                       eep->baseEepHeader.dacLpMode);
+               else if (eep->baseEepHeader.dacHiPwrMode_5G)
+                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
+               else
+                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+                                     eep->baseEepHeader.dacLpMode);
+
+               REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
+                             pModal->miscBits >> 2);
+
+               REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
+                             AR_PHY_TX_DESIRED_SCALE_CCK,
+                             eep->baseEepHeader.desiredScaleCCK);
+       }
+}
+
+static void ath9k_hw_def_set_addac(struct ath_hw *ah,
+                                  struct ath9k_channel *chan)
+{
+#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
+       struct modal_eep_header *pModal;
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       u8 biaslevel;
+
+       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+               return;
+
+       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+               return;
+
+       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+       if (pModal->xpaBiasLvl != 0xff) {
+               biaslevel = pModal->xpaBiasLvl;
+       } else {
+               u16 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(0) & 0xff;
+               biaslevel = (u8) (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 = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
+                       else
+                               break;
+                       freqCount++;
+               }
+       }
+
+       if (IS_CHAN_2GHZ(chan)) {
+               INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
+                                       7, 1) & (~0x18)) | biaslevel << 3;
+       } else {
+               INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
+                                       6, 1) & (~0xc0)) | biaslevel << 6;
+       }
+#undef XPA_LVL_FREQ
+}
+
+static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               struct cal_data_per_freq *pRawDataSet,
+                               u8 *bChans, u16 availPiers,
+                               u16 tPdGainOverlap, int16_t *pMinCalPower,
+                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
+                               u16 numXpdGains)
+{
+       int i, j, k;
+       int16_t ss;
+       u16 idxL = 0, idxR = 0, numPiers;
+       static u8 vpdTableL[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableR[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableI[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+       u8 minPwrT4[AR5416_NUM_PD_GAINS];
+       u8 maxPwrT4[AR5416_NUM_PD_GAINS];
+       int16_t vpdStep;
+       int16_t tmpVal;
+       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+       bool 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((u8)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];
+                       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]);
+
+
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrL, pVpdL,
+                                               AR5416_PD_GAIN_ICEPTS,
+                                               vpdTableL[i]);
+                       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] =
+                                       (u8)(ath9k_hw_interpolate((u16)
+                                            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] =
+                               (u16)(maxPwrT4[i] / 2);
+               else
+                       pPdGainBoundaries[i] =
+                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+               pPdGainBoundaries[i] =
+                       min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+               if ((i == 0) && !AR_SREV_5416_20_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++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+                       ss++;
+               }
+
+               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+               tgtIndex = (u8)(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++] = (u8)((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++;
+       }
+
+       return;
+}
+
+static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 int16_t *pTxPowerIndexOffset)
+{
+#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
+#define SM_PDGAIN_B(x, y) \
+               SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
+
+       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       struct cal_data_per_freq *pRawDataset;
+       u8 *pCalBChans = NULL;
+       u16 pdGainOverlap_t2;
+       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+       u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+       u16 numPiers, i, j;
+       int16_t tMinCalPower;
+       u16 numXpdGain, xpdMask;
+       u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+       u32 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 = (u16)(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;
+       }
+
+       if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
+               pRawDataset = pEepData->calPierData2G[0];
+               ah->initPDADC = ((struct calDataPerFreqOpLoop *)
+                                pRawDataset)->vpdPdg[0][0];
+       }
+
+       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] =
+                               (u16)(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_20_OR_LATER(ah) &&
+                   (ah->rxchainmask == 5 || 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];
+
+
+                       if (OLC_FOR_AR9280_20_LATER) {
+                               u8 pcdacIdx;
+                               u8 txPower;
+
+                               ath9k_get_txgain_index(ah, chan,
+                               (struct calDataPerFreqOpLoop *)pRawDataset,
+                               pCalBChans, numPiers, &txPower, &pcdacIdx);
+                               ath9k_olc_get_pdadcs(ah, pcdacIdx,
+                                                    txPower/2, pdadcValues);
+                       } else {
+                               ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
+                                                       chan, pRawDataset,
+                                                       pCalBChans, numPiers,
+                                                       pdGainOverlap_t2,
+                                                       &tMinCalPower,
+                                                       gainBoundaries,
+                                                       pdadcValues,
+                                                       numXpdGain);
+                       }
+
+                       if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+                               if (OLC_FOR_AR9280_20_LATER) {
+                                       REG_WRITE(ah,
+                                               AR_PHY_TPCRG5 + regChainOffset,
+                                               SM(0x6,
+                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+                                               SM_PD_GAIN(1) | SM_PD_GAIN(2) |
+                                               SM_PD_GAIN(3) | SM_PD_GAIN(4));
+                               } else {
+                                       REG_WRITE(ah,
+                                               AR_PHY_TPCRG5 + regChainOffset,
+                                               SM(pdGainOverlap_t2,
+                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
+                                               SM_PDGAIN_B(0, 1) |
+                                               SM_PDGAIN_B(1, 2) |
+                                               SM_PDGAIN_B(2, 3) |
+                                               SM_PDGAIN_B(3, 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);
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
+                                       i, regChainOffset, regOffset,
+                                       reg32);
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "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 true;
+#undef SM_PD_GAIN
+#undef SM_PDGAIN_B
+}
+
+static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
+                                                 struct ath9k_channel *chan,
+                                                 int16_t *ratesArray,
+                                                 u16 cfgCtl,
+                                                 u16 AntennaReduction,
+                                                 u16 twiceMaxRegulatoryPower,
+                                                 u16 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 ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+       static const u16 tpScaleReductionTable[5] =
+               { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+       int i;
+       int16_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}
+       };
+       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+       u16 ctlModesFor11a[] =
+               { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
+       u16 ctlModesFor11g[] =
+               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+                 CTL_2GHT40
+               };
+       u16 numCtlModes, *pCtlMode, ctlMode, freq;
+       struct chan_centers centers;
+       int tx_chainmask;
+       u16 twiceMinEdgePower;
+
+       tx_chainmask = 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((u8)twiceLargestAntenna,
+                                 pEepData->modalHeader
+                                 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+
+       twiceLargestAntenna = (int16_t)min(AntennaReduction -
+                                          twiceLargestAntenna, 0);
+
+       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+       if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
+               maxRegAllowedPower -=
+                       (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 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((u16)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, false);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower2G,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, false);
+               ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower2GHT20,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, 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, true);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPowerCck,
+                               AR5416_NUM_2G_CCK_TARGET_POWERS,
+                               &targetPowerCckExt, 4, true);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower2G,
+                               AR5416_NUM_2G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, 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, false);
+               ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower5GHT20,
+                       AR5416_NUM_5G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, 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, true);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower5G,
+                               AR5416_NUM_5G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, true);
+               }
+       }
+
+       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+               bool 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 (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
+                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "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++) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "  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);
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "    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);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "    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((u16)targetPowerCck.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11A:
+               case CTL_11G:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+                               targetPowerOfdm.tPow2x[i] =
+                                       min((u16)targetPowerOfdm.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_5GHT20:
+               case CTL_2GHT20:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+                               targetPowerHt20.tPow2x[i] =
+                                       min((u16)targetPowerHt20.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11B_EXT:
+                       targetPowerCckExt.tPow2x[0] = min((u16)
+                                       targetPowerCckExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_11A_EXT:
+               case CTL_11G_EXT:
+                       targetPowerOfdmExt.tPow2x[0] = min((u16)
+                                       targetPowerOfdmExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_5GHT40:
+               case CTL_2GHT40:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                               targetPowerHt40.tPow2x[i] =
+                                       min((u16)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 true;
+}
+
+static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
+                                   struct ath9k_channel *chan,
+                                   u16 cfgCtl,
+                                   u8 twiceAntennaReduction,
+                                   u8 twiceMaxRegulatoryPower,
+                                   u8 powerLimit)
+{
+#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
+       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       struct modal_eep_header *pModal =
+               &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+       int16_t ratesArray[Ar5416RateSize];
+       int16_t txPowerIndexOffset = 0;
+       u8 ht40PowerIncForPdadc = 2;
+       int i, cck_ofdm_delta = 0;
+
+       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)) {
+               DPRINTF(ah->ah_sc, ATH_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)) {
+               DPRINTF(ah->ah_sc, ATH_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)) {
+               if (OLC_FOR_AR9280_20_LATER) {
+                       cck_ofdm_delta = 2;
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+                               ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
+                               | ATH9K_POW_SM(ratesArray[rateXr], 8)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+                               ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
+               } else {
+                       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));
+               if (OLC_FOR_AR9280_20_LATER) {
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+                               ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
+                               | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
+               } else {
+                       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->regulatory.max_power_level =
+                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+       else
+               ah->regulatory.max_power_level = ratesArray[i];
+
+       switch(ar5416_get_ntxchains(ah->txchainmask)) {
+       case 1:
+               break;
+       case 2:
+               ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+               break;
+       case 3:
+               ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Invalid chainmask configuration\n");
+               break;
+       }
+
+       return 0;
+}
+
+static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
+                                         enum ieee80211_band freq_band)
+{
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       struct modal_eep_header *pModal =
+               &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
+       struct base_eep_header *pBase = &eep->baseEepHeader;
+       u8 num_ant_config;
+
+       num_ant_config = 1;
+
+       if (pBase->version >= 0x0E0D)
+               if (pModal->useAnt1)
+                       num_ant_config += 1;
+
+       return num_ant_config;
+}
+
+static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
+                                              struct ath9k_channel *chan)
+{
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       struct modal_eep_header *pModal =
+               &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+       return pModal->antCtrlCommon & 0xFFFF;
+}
+
+static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
+{
+#define EEP_DEF_SPURCHAN \
+       (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
+
+       u16 spur_val = AR_NO_SPUR;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "Getting spur idx %d is2Ghz. %d val %x\n",
+               i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+       switch (ah->config.spurmode) {
+       case SPUR_DISABLE:
+               break;
+       case SPUR_ENABLE_IOCTL:
+               spur_val = ah->config.spurchans[i][is2GHz];
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Getting spur val from new loc. %d\n", spur_val);
+               break;
+       case SPUR_ENABLE_EEPROM:
+               spur_val = EEP_DEF_SPURCHAN;
+               break;
+       }
+
+       return spur_val;
+
+#undef EEP_DEF_SPURCHAN
+}
+
+static struct eeprom_ops eep_def_ops = {
+       .check_eeprom           = ath9k_hw_def_check_eeprom,
+       .get_eeprom             = ath9k_hw_def_get_eeprom,
+       .fill_eeprom            = ath9k_hw_def_fill_eeprom,
+       .get_eeprom_ver         = ath9k_hw_def_get_eeprom_ver,
+       .get_eeprom_rev         = ath9k_hw_def_get_eeprom_rev,
+       .get_num_ant_config     = ath9k_hw_def_get_num_ant_config,
+       .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
+       .set_board_values       = ath9k_hw_def_set_board_values,
+       .set_addac              = ath9k_hw_def_set_addac,
+       .set_txpower            = ath9k_hw_def_set_txpower,
+       .get_spur_channel       = ath9k_hw_def_get_spur_channel
+};
+
+int ath9k_hw_eeprom_attach(struct ath_hw *ah)
+{
+       int status;
+
+       if (AR_SREV_9285(ah)) {
+               ah->eep_map = EEP_MAP_4KBITS;
+               ah->eep_ops = &eep_4k_ops;
+       } else {
+               ah->eep_map = EEP_MAP_DEFAULT;
+               ah->eep_ops = &eep_def_ops;
+       }
+
+       if (!ah->eep_ops->fill_eeprom(ah))
+               return -EIO;
+
+       status = ah->eep_ops->check_eeprom(ah);
+
+       return status;
+}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
new file mode 100644 (file)
index 0000000..9a7715d
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2008-2009 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 EEPROM_H
+#define EEPROM_H
+
+#include <net/wireless.h>
+
+#define AH_USE_EEPROM   0x1
+
+#ifdef __BIG_ENDIAN
+#define AR5416_EEPROM_MAGIC 0x5aa5
+#else
+#define AR5416_EEPROM_MAGIC 0xa55a
+#endif
+
+#define CTRY_DEBUG   0x1ff
+#define        CTRY_DEFAULT 0
+
+#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 AR5416_EEPROM_MAGIC_OFFSET  0x0
+#define AR5416_EEPROM_S             2
+#define AR5416_EEPROM_OFFSET        0x2000
+#define AR5416_EEPROM_MAX           0xae0
+
+#define AR5416_EEPROM_START_ADDR \
+       (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
+
+#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 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 INCREASE_MAXPOW_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+#define INCREASE_MAXPOW_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
+
+/*
+ * For AR9285 and later chipsets, the following bits are not being programmed
+ * in EEPROM and so need to be enabled always.
+ *
+ * Bit 0: en_fcc_mid
+ * Bit 1: en_jap_mid
+ * Bit 2: en_fcc_dfs_ht40
+ * Bit 3: en_jap_ht40
+ * Bit 4: en_jap_dfs_ht40
+ */
+#define AR9285_RDEXT_DEFAULT    0x1F
+
+#define AR_EEPROM_MAC(i)       (0x1d+(i))
+#define ATH9K_POW_SM(_r, _s)   (((_r) & 0x3f) << (_s))
+#define FREQ2FBIN(x, y)                ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
+#define ath9k_hw_use_flash(_ah)        (!(_ah->ah_flags & AH_USE_EEPROM))
+
+#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
+#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
+                                ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+
+#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 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_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 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_EEP_MINOR_VER_20      0x14
+#define AR5416_EEP_MINOR_VER_22      0x16
+
+#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
+
+#define AR9280_TX_GAIN_TABLE_SIZE 22
+
+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,
+       EEP_OL_PWRCTRL,
+       EEP_RC_CHAIN_MASK,
+       EEP_DAC_HPWR_5G,
+       EEP_FRAC_N_5G
+};
+
+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
+};
+
+struct base_eep_header {
+       u16 length;
+       u16 checksum;
+       u16 version;
+       u8 opCapFlags;
+       u8 eepMisc;
+       u16 regDmn[2];
+       u8 macAddr[6];
+       u8 rxMask;
+       u8 txMask;
+       u16 rfSilent;
+       u16 blueToothOptions;
+       u16 deviceCap;
+       u32 binBuildNumber;
+       u8 deviceType;
+       u8 pwdclkind;
+       u8 futureBase_1[2];
+       u8 rxGainType;
+       u8 dacHiPwrMode_5G;
+       u8 openLoopPwrCntl;
+       u8 dacLpMode;
+       u8 txGainType;
+       u8 rcChainMask;
+       u8 desiredScaleCCK;
+       u8 power_table_offset;
+       u8 frac_n_5g;
+       u8 futureBase_3[21];
+} __packed;
+
+struct base_eep_header_4k {
+       u16 length;
+       u16 checksum;
+       u16 version;
+       u8 opCapFlags;
+       u8 eepMisc;
+       u16 regDmn[2];
+       u8 macAddr[6];
+       u8 rxMask;
+       u8 txMask;
+       u16 rfSilent;
+       u16 blueToothOptions;
+       u16 deviceCap;
+       u32 binBuildNumber;
+       u8 deviceType;
+       u8 txGainType;
+} __packed;
+
+
+struct spur_chan {
+       u16 spurChan;
+       u8 spurRangeLow;
+       u8 spurRangeHigh;
+} __packed;
+
+struct modal_eep_header {
+       u32 antCtrlChain[AR5416_MAX_CHAINS];
+       u32 antCtrlCommon;
+       u8 antennaGainCh[AR5416_MAX_CHAINS];
+       u8 switchSettling;
+       u8 txRxAttenCh[AR5416_MAX_CHAINS];
+       u8 rxTxMarginCh[AR5416_MAX_CHAINS];
+       u8 adcDesiredSize;
+       u8 pgaDesiredSize;
+       u8 xlnaGainCh[AR5416_MAX_CHAINS];
+       u8 txEndToXpaOff;
+       u8 txEndToRxOn;
+       u8 txFrameToXpaOn;
+       u8 thresh62;
+       u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
+       u8 xpdGain;
+       u8 xpd;
+       u8 iqCalICh[AR5416_MAX_CHAINS];
+       u8 iqCalQCh[AR5416_MAX_CHAINS];
+       u8 pdGainOverlap;
+       u8 ob;
+       u8 db;
+       u8 xpaBiasLvl;
+       u8 pwrDecreaseFor2Chain;
+       u8 pwrDecreaseFor3Chain;
+       u8 txFrameToDataStart;
+       u8 txFrameToPaOn;
+       u8 ht40PowerIncForPdadc;
+       u8 bswAtten[AR5416_MAX_CHAINS];
+       u8 bswMargin[AR5416_MAX_CHAINS];
+       u8 swSettleHt40;
+       u8 xatten2Db[AR5416_MAX_CHAINS];
+       u8 xatten2Margin[AR5416_MAX_CHAINS];
+       u8 ob_ch1;
+       u8 db_ch1;
+       u8 useAnt1:1,
+           force_xpaon:1,
+           local_bias:1,
+           femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+       u8 miscBits;
+       u16 xpaBiasLvlFreq[3];
+       u8 futureModal[6];
+
+       struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+struct calDataPerFreqOpLoop {
+       u8 pwrPdg[2][5];
+       u8 vpdPdg[2][5];
+       u8 pcdac[2][5];
+       u8 empty[2][5];
+} __packed;
+
+struct modal_eep_4k_header {
+       u32  antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+       u32  antCtrlCommon;
+       u8   antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   switchSettling;
+       u8   txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   adcDesiredSize;
+       u8   pgaDesiredSize;
+       u8   xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   txEndToXpaOff;
+       u8   txEndToRxOn;
+       u8   txFrameToXpaOn;
+       u8   thresh62;
+       u8   noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   xpdGain;
+       u8   xpd;
+       u8   iqCalICh[AR5416_EEP4K_MAX_CHAINS];
+       u8   iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   pdGainOverlap;
+       u8   ob_01;
+       u8   db1_01;
+       u8   xpaBiasLvl;
+       u8   txFrameToDataStart;
+       u8   txFrameToPaOn;
+       u8   ht40PowerIncForPdadc;
+       u8   bswAtten[AR5416_EEP4K_MAX_CHAINS];
+       u8   bswMargin[AR5416_EEP4K_MAX_CHAINS];
+       u8   swSettleHt40;
+       u8   xatten2Db[AR5416_EEP4K_MAX_CHAINS];
+       u8   xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
+       u8   db2_01;
+       u8   version;
+       u16  ob_234;
+       u16  db1_234;
+       u16  db2_234;
+       u8   futureModal[4];
+
+       struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+
+struct cal_data_per_freq {
+       u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+       u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_data_per_freq_4k {
+       u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+       u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_target_power_leg {
+       u8 bChannel;
+       u8 tPow2x[4];
+} __packed;
+
+struct cal_target_power_ht {
+       u8 bChannel;
+       u8 tPow2x[8];
+} __packed;
+
+
+#ifdef __BIG_ENDIAN_BITFIELD
+struct cal_ctl_edges {
+       u8 bChannel;
+       u8 flag:2, tPower:6;
+} __packed;
+#else
+struct cal_ctl_edges {
+       u8 bChannel;
+       u8 tPower:6, flag:2;
+} __packed;
+#endif
+
+struct cal_ctl_data {
+       struct cal_ctl_edges
+       ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+struct cal_ctl_data_4k {
+       struct cal_ctl_edges
+       ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
+} __packed;
+
+struct ar5416_eeprom_def {
+       struct base_eep_header baseEepHeader;
+       u8 custData[64];
+       struct modal_eep_header modalHeader[2];
+       u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
+       u8 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];
+       u8 ctlIndex[AR5416_NUM_CTLS];
+       struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
+       u8 padding;
+} __packed;
+
+struct ar5416_eeprom_4k {
+       struct base_eep_header_4k baseEepHeader;
+       u8 custData[20];
+       struct modal_eep_4k_header modalHeader;
+       u8 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];
+       u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
+       struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
+       u8 padding;
+} __packed;
+
+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 {
+       u16 countryCode;
+       u16 regDmnEnum;
+       u16 regDmn5G;
+       u16 regDmn2G;
+       u8 isMultidomain;
+       u8 iso[3];
+};
+
+enum ath9k_eep_map {
+       EEP_MAP_DEFAULT = 0x0,
+       EEP_MAP_4KBITS,
+       EEP_MAP_MAX
+};
+
+struct eeprom_ops {
+       int (*check_eeprom)(struct ath_hw *hw);
+       u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
+       bool (*fill_eeprom)(struct ath_hw *hw);
+       int (*get_eeprom_ver)(struct ath_hw *hw);
+       int (*get_eeprom_rev)(struct ath_hw *hw);
+       u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
+       u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
+                                     struct ath9k_channel *chan);
+       void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
+       void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
+       int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
+                          u16 cfgCtl, u8 twiceAntennaReduction,
+                          u8 twiceMaxRegulatoryPower, u8 powerLimit);
+       u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
+};
+
+#define ar5416_get_ntxchains(_txchainmask)                     \
+       (((_txchainmask >> 2) & 1) +                            \
+        ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
+
+int ath9k_hw_eeprom_attach(struct ath_hw *ah);
+
+#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
new file mode 100644 (file)
index 0000000..24299e6
--- /dev/null
@@ -0,0 +1,3861 @@
+/*
+ * Copyright (c) 2008-2009 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 <linux/io.h>
+#include <asm/unaligned.h>
+
+#include "ath9k.h"
+#include "initvals.h"
+
+static int btcoex_enable;
+module_param(btcoex_enable, bool, 0);
+MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
+
+#define ATH9K_CLOCK_RATE_CCK           22
+#define ATH9K_CLOCK_RATE_5GHZ_OFDM     40
+#define ATH9K_CLOCK_RATE_2GHZ_OFDM     44
+
+static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
+                             enum ath9k_ht_macmode macmode);
+static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
+                             struct ar5416_eeprom_def *pEepData,
+                             u32 reg, u32 value);
+static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+
+/********************/
+/* Helper Functions */
+/********************/
+
+static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       if (!ah->curchan) /* should really check for CCK instead */
+               return clks / ATH9K_CLOCK_RATE_CCK;
+       if (conf->channel->band == IEEE80211_BAND_2GHZ)
+               return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
+
+       return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
+}
+
+static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       if (conf_is_ht40(conf))
+               return ath9k_hw_mac_usec(ah, clks) / 2;
+       else
+               return ath9k_hw_mac_usec(ah, clks);
+}
+
+static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       if (!ah->curchan) /* should really check for CCK instead */
+               return usecs *ATH9K_CLOCK_RATE_CCK;
+       if (conf->channel->band == IEEE80211_BAND_2GHZ)
+               return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
+       return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
+}
+
+static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       if (conf_is_ht40(conf))
+               return ath9k_hw_mac_clks(ah, usecs) * 2;
+       else
+               return ath9k_hw_mac_clks(ah, usecs);
+}
+
+bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
+{
+       int i;
+
+       BUG_ON(timeout < AH_TIME_QUANTUM);
+
+       for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
+               if ((REG_READ(ah, reg) & mask) == val)
+                       return true;
+
+               udelay(AH_TIME_QUANTUM);
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+               "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+               timeout, reg, REG_READ(ah, reg), mask, val);
+
+       return false;
+}
+
+u32 ath9k_hw_reverse_bits(u32 val, u32 n)
+{
+       u32 retval;
+       int i;
+
+       for (i = 0, retval = 0; i < n; i++) {
+               retval = (retval << 1) | (val & 1);
+               val >>= 1;
+       }
+       return retval;
+}
+
+bool ath9k_get_channel_edges(struct ath_hw *ah,
+                            u16 flags, u16 *low,
+                            u16 *high)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+       if (flags & CHANNEL_5GHZ) {
+               *low = pCap->low_5ghz_chan;
+               *high = pCap->high_5ghz_chan;
+               return true;
+       }
+       if ((flags & CHANNEL_2GHZ)) {
+               *low = pCap->low_2ghz_chan;
+               *high = pCap->high_2ghz_chan;
+               return true;
+       }
+       return false;
+}
+
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
+                          struct ath_rate_table *rates,
+                          u32 frameLen, u16 rateix,
+                          bool shortPreamble)
+{
+       u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
+       u32 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->curchan && IS_CHAN_QUARTER_RATE(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->curchan &&
+                          IS_CHAN_HALF_RATE(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:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Unknown phy %u (rate ix %u)\n",
+                       rates->info[rateix].phy, rateix);
+               txTime = 0;
+               break;
+       }
+
+       return txTime;
+}
+
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 struct chan_centers *centers)
+{
+       int8_t extoff;
+
+       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 *
+                        ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
+                         HT40_CHANNEL_CENTER_SHIFT : 15));
+}
+
+/******************/
+/* Chip Revisions */
+/******************/
+
+static void ath9k_hw_read_revisions(struct ath_hw *ah)
+{
+       u32 val;
+
+       val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
+
+       if (val == 0xFF) {
+               val = REG_READ(ah, AR_SREV);
+               ah->hw_version.macVersion =
+                       (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
+               ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+               ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
+       } else {
+               if (!AR_SREV_9100(ah))
+                       ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
+
+               ah->hw_version.macRev = val & AR_SREV_REVISION;
+
+               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
+                       ah->is_pciexpress = true;
+       }
+}
+
+static int ath9k_hw_get_radiorev(struct ath_hw *ah)
+{
+       u32 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_hw *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 bool ath9k_hw_chip_test(struct ath_hw *ah)
+{
+       u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
+       u32 regHold[2];
+       u32 patternData[4] = { 0x55555555,
+                              0xaaaaaaaa,
+                              0x66666666,
+                              0x99999999 };
+       int i, j;
+
+       for (i = 0; i < 2; i++) {
+               u32 addr = regAddr[i];
+               u32 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) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                                       "address test failed "
+                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+                                       addr, wrData, rdData);
+                               return false;
+                       }
+               }
+               for (j = 0; j < 4; j++) {
+                       wrData = patternData[j];
+                       REG_WRITE(ah, addr, wrData);
+                       rdData = REG_READ(ah, addr);
+                       if (wrData != rdData) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                                       "address test failed "
+                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+                                       addr, wrData, rdData);
+                               return false;
+                       }
+               }
+               REG_WRITE(ah, regAddr[i], regHold[i]);
+       }
+       udelay(100);
+
+       return true;
+}
+
+static const char *ath9k_hw_devname(u16 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 AR5416_AR9100_DEVID:
+               return "Atheros 9100";
+       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_hw *ah)
+{
+       int i;
+
+       ah->config.dma_beacon_response_time = 2;
+       ah->config.sw_beacon_response_time = 10;
+       ah->config.additional_swba_backoff = 0;
+       ah->config.ack_6mb = 0x0;
+       ah->config.cwm_ignore_extcca = 0;
+       ah->config.pcie_powersave_enable = 0;
+       ah->config.pcie_clock_req = 0;
+       ah->config.pcie_waen = 0;
+       ah->config.analog_shiftreg = 1;
+       ah->config.ht_enable = 1;
+       ah->config.ofdm_trig_low = 200;
+       ah->config.ofdm_trig_high = 500;
+       ah->config.cck_trig_high = 200;
+       ah->config.cck_trig_low = 100;
+       ah->config.enable_ani = 1;
+       ah->config.diversity_control = 0;
+       ah->config.antenna_switch_swap = 0;
+
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               ah->config.spurchans[i][0] = AR_NO_SPUR;
+               ah->config.spurchans[i][1] = AR_NO_SPUR;
+       }
+
+       ah->config.intr_mitigation = true;
+
+       /*
+        * 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).
+        */
+       if (num_possible_cpus() > 1)
+               ah->config.serialize_regmode = SER_REG_MODE_AUTO;
+}
+
+static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
+                                       int *status)
+{
+       struct ath_hw *ah;
+
+       ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
+       if (ah == NULL) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Cannot allocate memory for state block\n");
+               *status = -ENOMEM;
+               return NULL;
+       }
+
+       ah->ah_sc = sc;
+       ah->hw_version.magic = AR5416_MAGIC;
+       ah->regulatory.country_code = CTRY_DEFAULT;
+       ah->hw_version.devid = devid;
+       ah->hw_version.subvendorid = 0;
+
+       ah->ah_flags = 0;
+       if ((devid == AR5416_AR9100_DEVID))
+               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
+       if (!AR_SREV_9100(ah))
+               ah->ah_flags = AH_USE_EEPROM;
+
+       ah->regulatory.power_limit = MAX_RATE_POWER;
+       ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
+       ah->atim_window = 0;
+       ah->diversity_control = ah->config.diversity_control;
+       ah->antenna_switch_swap =
+               ah->config.antenna_switch_swap;
+       ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
+       ah->beacon_interval = 100;
+       ah->enable_32kHz_clock = DONT_USE_32KHZ;
+       ah->slottime = (u32) -1;
+       ah->acktimeout = (u32) -1;
+       ah->ctstimeout = (u32) -1;
+       ah->globaltxtimeout = (u32) -1;
+
+       ah->gbeacon_rate = 0;
+
+       return ah;
+}
+
+static int ath9k_hw_rfattach(struct ath_hw *ah)
+{
+       bool rfStatus = false;
+       int ecode = 0;
+
+       rfStatus = ath9k_hw_init_rf(ah, &ecode);
+       if (!rfStatus) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "RF setup failed, status: %u\n", ecode);
+               return ecode;
+       }
+
+       return 0;
+}
+
+static int ath9k_hw_rf_claim(struct ath_hw *ah)
+{
+       u32 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:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Radio Chip Rev 0x%02X not supported\n",
+                       val & AR_RADIO_SREV_MAJOR);
+               return -EOPNOTSUPP;
+       }
+
+       ah->hw_version.analog5GhzRev = val;
+
+       return 0;
+}
+
+static int ath9k_hw_init_macaddr(struct ath_hw *ah)
+{
+       u32 sum;
+       int i;
+       u16 eeval;
+
+       sum = 0;
+       for (i = 0; i < 3; i++) {
+               eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
+               sum += eeval;
+               ah->macaddr[2 * i] = eeval >> 8;
+               ah->macaddr[2 * i + 1] = eeval & 0xff;
+       }
+       if (sum == 0 || sum == 0xffff * 3)
+               return -EADDRNOTAVAIL;
+
+       return 0;
+}
+
+static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
+{
+       u32 rxgain_type;
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
+               rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
+
+               if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
+                       INIT_INI_ARRAY(&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(&ah->iniModesRxGain,
+                       ar9280Modes_backoff_23db_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_original_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+       } else {
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_original_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+       }
+}
+
+static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
+{
+       u32 txgain_type;
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
+               txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9280Modes_high_power_tx_gain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9280Modes_original_tx_gain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+       } else {
+               INIT_INI_ARRAY(&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_hw *ah)
+{
+       int ecode;
+
+       if (!ath9k_hw_chip_test(ah))
+               return -ENODEV;
+
+       ecode = ath9k_hw_rf_claim(ah);
+       if (ecode != 0)
+               return ecode;
+
+       ecode = ath9k_hw_eeprom_attach(ah);
+       if (ecode != 0)
+               return ecode;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_CONFIG, "Eeprom VER: %d, REV: %d\n",
+               ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah));
+
+       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_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
+                                        int *status)
+{
+       struct ath_hw *ah;
+       int ecode;
+       u32 i, j;
+
+       ah = ath9k_hw_newstate(devid, sc, status);
+       if (ah == NULL)
+               return NULL;
+
+       ath9k_hw_set_defaults(ah);
+
+       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n");
+               ecode = -EIO;
+               goto bad;
+       }
+
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
+               ecode = -EIO;
+               goto bad;
+       }
+
+       if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
+                   (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
+                       ah->config.serialize_regmode =
+                               SER_REG_MODE_ON;
+               } else {
+                       ah->config.serialize_regmode =
+                               SER_REG_MODE_OFF;
+               }
+       }
+
+       DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
+               ah->config.serialize_regmode);
+
+       if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
+           (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
+           (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
+           (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Mac Chip Rev 0x%02x.%x is not supported by "
+                       "this driver\n", ah->hw_version.macVersion,
+                       ah->hw_version.macRev);
+               ecode = -EOPNOTSUPP;
+               goto bad;
+       }
+
+       if (AR_SREV_9100(ah)) {
+               ah->iq_caldata.calData = &iq_cal_multi_sample;
+               ah->supp_cals = IQ_MISMATCH_CAL;
+               ah->is_pciexpress = false;
+       }
+       ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
+
+       if (AR_SREV_9160_10_OR_LATER(ah)) {
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       ah->iq_caldata.calData = &iq_cal_single_sample;
+                       ah->adcgain_caldata.calData =
+                               &adc_gain_cal_single_sample;
+                       ah->adcdc_caldata.calData =
+                               &adc_dc_cal_single_sample;
+                       ah->adcdc_calinitdata.calData =
+                               &adc_init_dc_cal;
+               } else {
+                       ah->iq_caldata.calData = &iq_cal_multi_sample;
+                       ah->adcgain_caldata.calData =
+                               &adc_gain_cal_multi_sample;
+                       ah->adcdc_caldata.calData =
+                               &adc_dc_cal_multi_sample;
+                       ah->adcdc_calinitdata.calData =
+                               &adc_init_dc_cal;
+               }
+               ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+       }
+
+       ah->ani_function = ATH9K_ANI_ALL;
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
+
+       if (AR_SREV_9285_12_OR_LATER(ah)) {
+
+               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
+                              ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
+                              ARRAY_SIZE(ar9285Common_9285_1_2), 2);
+
+               if (ah->config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_off_L1_9285_1_2,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
+               } else {
+                       INIT_INI_ARRAY(&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(&ah->iniModes, ar9285Modes_9285,
+                              ARRAY_SIZE(ar9285Modes_9285), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
+                              ARRAY_SIZE(ar9285Common_9285), 2);
+
+               if (ah->config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_off_L1_9285,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
+               } else {
+                       INIT_INI_ARRAY(&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(&ah->iniModes, ar9280Modes_9280_2,
+                              ARRAY_SIZE(ar9280Modes_9280_2), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
+                              ARRAY_SIZE(ar9280Common_9280_2), 2);
+
+               if (ah->config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                              ar9280PciePhy_clkreq_off_L1_9280,
+                              ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                              ar9280PciePhy_clkreq_always_on_L1_9280,
+                              ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
+               }
+               INIT_INI_ARRAY(&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(&ah->iniModes, ar9280Modes_9280,
+                              ARRAY_SIZE(ar9280Modes_9280), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
+                              ARRAY_SIZE(ar9280Common_9280), 2);
+       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
+                              ARRAY_SIZE(ar5416Modes_9160), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
+                              ARRAY_SIZE(ar5416Common_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
+                              ARRAY_SIZE(ar5416Bank0_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
+                              ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
+                              ARRAY_SIZE(ar5416Bank1_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
+                              ARRAY_SIZE(ar5416Bank2_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
+                              ARRAY_SIZE(ar5416Bank3_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
+                              ARRAY_SIZE(ar5416Bank6_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
+                              ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
+                              ARRAY_SIZE(ar5416Bank7_9160), 2);
+               if (AR_SREV_9160_11(ah)) {
+                       INIT_INI_ARRAY(&ah->iniAddac,
+                                      ar5416Addac_91601_1,
+                                      ARRAY_SIZE(ar5416Addac_91601_1), 2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
+                                      ARRAY_SIZE(ar5416Addac_9160), 2);
+               }
+       } else if (AR_SREV_9100_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
+                              ARRAY_SIZE(ar5416Modes_9100), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
+                              ARRAY_SIZE(ar5416Common_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
+                              ARRAY_SIZE(ar5416Bank0_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
+                              ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
+                              ARRAY_SIZE(ar5416Bank1_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
+                              ARRAY_SIZE(ar5416Bank2_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
+                              ARRAY_SIZE(ar5416Bank3_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
+                              ARRAY_SIZE(ar5416Bank6_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
+                              ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
+                              ARRAY_SIZE(ar5416Bank7_9100), 2);
+               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
+                              ARRAY_SIZE(ar5416Addac_9100), 2);
+       } else {
+               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
+                              ARRAY_SIZE(ar5416Modes), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
+                              ARRAY_SIZE(ar5416Common), 2);
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
+                              ARRAY_SIZE(ar5416Bank0), 2);
+               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
+                              ARRAY_SIZE(ar5416BB_RfGain), 3);
+               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
+                              ARRAY_SIZE(ar5416Bank1), 2);
+               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
+                              ARRAY_SIZE(ar5416Bank2), 2);
+               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
+                              ARRAY_SIZE(ar5416Bank3), 3);
+               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
+                              ARRAY_SIZE(ar5416Bank6), 3);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
+                              ARRAY_SIZE(ar5416Bank6TPC), 3);
+               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
+                              ARRAY_SIZE(ar5416Bank7), 2);
+               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
+                              ARRAY_SIZE(ar5416Addac), 2);
+       }
+
+       if (ah->is_pciexpress)
+               ath9k_hw_configpcipowersave(ah, 0);
+       else
+               ath9k_hw_disablepcie(ah);
+
+       ecode = ath9k_hw_post_attach(ah);
+       if (ecode != 0)
+               goto bad;
+
+       if (AR_SREV_9285_12_OR_LATER(ah)) {
+               u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+               /* txgain table */
+               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9285Modes_high_power_tx_gain_9285_1_2,
+                       ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9285Modes_original_tx_gain_9285_1_2,
+                       ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
+               }
+
+       }
+
+       /* 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);
+
+       ath9k_hw_fill_cap_info(ah);
+
+       if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
+           test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
+
+               /* EEPROM Fixup */
+               for (i = 0; i < ah->iniModes.ia_rows; i++) {
+                       u32 reg = INI_RA(&ah->iniModes, i, 0);
+
+                       for (j = 1; j < ah->iniModes.ia_columns; j++) {
+                               u32 val = INI_RA(&ah->iniModes, i, j);
+
+                               INI_RA(&ah->iniModes, i, j) =
+                                       ath9k_hw_ini_fixup(ah,
+                                                          &ah->eeprom.def,
+                                                          reg, val);
+                       }
+               }
+       }
+
+       ecode = ath9k_hw_init_macaddr(ah);
+       if (ecode != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Failed to initialize MAC address\n");
+               goto bad;
+       }
+
+       if (AR_SREV_9285(ah))
+               ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
+       else
+               ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
+
+       ath9k_init_nfcal_hist_buffer(ah);
+
+       return ah;
+bad:
+       if (ah)
+               ath9k_hw_detach(ah);
+       if (status)
+               *status = ecode;
+
+       return NULL;
+}
+
+static void ath9k_hw_init_bb(struct ath_hw *ah,
+                            struct ath9k_channel *chan)
+{
+       u32 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);
+
+       udelay(synthDelay + BASE_ACTIVATE_DELAY);
+}
+
+static void ath9k_hw_init_qos(struct ath_hw *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_hw *ah,
+                             struct ath9k_channel *chan)
+{
+       u32 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, AR_RTC_PLL_CONTROL, pll);
+
+       udelay(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_hw *ah)
+{
+       int rx_chainmask, tx_chainmask;
+
+       rx_chainmask = ah->rxchainmask;
+       tx_chainmask = ah->txchainmask;
+
+       switch (rx_chainmask) {
+       case 0x5:
+               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+                           AR_PHY_SWAP_ALT_CHAIN);
+       case 0x3:
+               if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
+                       REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
+                       REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
+                       break;
+               }
+       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_hw *ah,
+                                         enum nl80211_iftype opmode)
+{
+       ah->mask_reg = AR_IMR_TXERR |
+               AR_IMR_TXURN |
+               AR_IMR_RXERR |
+               AR_IMR_RXORN |
+               AR_IMR_BCNMISC;
+
+       if (ah->config.intr_mitigation)
+               ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+       else
+               ah->mask_reg |= AR_IMR_RXOK;
+
+       ah->mask_reg |= AR_IMR_TXOK;
+
+       if (opmode == NL80211_IFTYPE_AP)
+               ah->mask_reg |= AR_IMR_MIB;
+
+       REG_WRITE(ah, AR_IMR, ah->mask_reg);
+       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 bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
+{
+       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us);
+               ah->acktimeout = (u32) -1;
+               return false;
+       } else {
+               REG_RMW_FIELD(ah, AR_TIME_OUT,
+                             AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
+               ah->acktimeout = us;
+               return true;
+       }
+}
+
+static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+{
+       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us);
+               ah->ctstimeout = (u32) -1;
+               return false;
+       } else {
+               REG_RMW_FIELD(ah, AR_TIME_OUT,
+                             AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
+               ah->ctstimeout = us;
+               return true;
+       }
+}
+
+static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
+{
+       if (tu > 0xFFFF) {
+               DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
+                       "bad global tx timeout %u\n", tu);
+               ah->globaltxtimeout = (u32) -1;
+               return false;
+       } else {
+               REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
+               ah->globaltxtimeout = tu;
+               return true;
+       }
+}
+
+static void ath9k_hw_init_user_settings(struct ath_hw *ah)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
+               ah->misc_mode);
+
+       if (ah->misc_mode != 0)
+               REG_WRITE(ah, AR_PCU_MISC,
+                         REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
+       if (ah->slottime != (u32) -1)
+               ath9k_hw_setslottime(ah, ah->slottime);
+       if (ah->acktimeout != (u32) -1)
+               ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
+       if (ah->ctstimeout != (u32) -1)
+               ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
+       if (ah->globaltxtimeout != (u32) -1)
+               ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
+}
+
+const char *ath9k_hw_probe(u16 vendorid, u16 devid)
+{
+       return vendorid == ATHEROS_VENDOR_ID ?
+               ath9k_hw_devname(devid) : NULL;
+}
+
+void ath9k_hw_detach(struct ath_hw *ah)
+{
+       if (!AR_SREV_9100(ah))
+               ath9k_hw_ani_detach(ah);
+
+       ath9k_hw_rfdetach(ah);
+       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+       kfree(ah);
+}
+
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
+{
+       struct ath_hw *ah = NULL;
+
+       switch (devid) {
+       case AR5416_DEVID_PCI:
+       case AR5416_DEVID_PCIE:
+       case AR5416_AR9100_DEVID:
+       case AR9160_DEVID_PCI:
+       case AR9280_DEVID_PCI:
+       case AR9280_DEVID_PCIE:
+       case AR9285_DEVID_PCIE:
+               ah = ath9k_hw_do_attach(devid, sc, error);
+               break;
+       default:
+               *error = -ENXIO;
+               break;
+       }
+
+       return ah;
+}
+
+/*******/
+/* INI */
+/*******/
+
+static void ath9k_hw_override_ini(struct ath_hw *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_20_OR_LATER(ah) ||
+           AR_SREV_9280_10_OR_LATER(ah))
+               return;
+
+       REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
+}
+
+static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
+                             struct ar5416_eeprom_def *pEepData,
+                             u32 reg, u32 value)
+{
+       struct base_eep_header *pBase = &(pEepData->baseEepHeader);
+
+       switch (ah->hw_version.devid) {
+       case AR9280_DEVID_PCI:
+               if (reg == 0x7894) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "ini VAL: %x  EEPROM: %x\n", value,
+                               (pBase->version & 0xff));
+
+                       if ((pBase->version & 0xff) > 0x0a) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PWDCLKIND: %d\n",
+                                       pBase->pwdclkind);
+                               value &= ~AR_AN_TOP2_PWDCLKIND;
+                               value |= AR_AN_TOP2_PWDCLKIND &
+                                       (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
+                       } else {
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PWDCLKIND Earlier Rev\n");
+                       }
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "final ini VAL: %x\n", value);
+               }
+               break;
+       }
+
+       return value;
+}
+
+static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
+                             struct ar5416_eeprom_def *pEepData,
+                             u32 reg, u32 value)
+{
+       if (ah->eep_map == EEP_MAP_4KBITS)
+               return value;
+       else
+               return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
+}
+
+static void ath9k_olc_init(struct ath_hw *ah)
+{
+       u32 i;
+
+       for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
+               ah->originalGain[i] =
+                       MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
+                                       AR_PHY_TX_GAIN);
+       ah->PDADCdelta = 0;
+}
+
+static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
+                             struct ath9k_channel *chan)
+{
+       u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
+
+       if (IS_CHAN_B(chan))
+               ctl |= CTL_11B;
+       else if (IS_CHAN_G(chan))
+               ctl |= CTL_11G;
+       else
+               ctl |= CTL_11A;
+
+       return ctl;
+}
+
+static int ath9k_hw_process_ini(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               enum ath9k_ht_macmode macmode)
+{
+       int i, regWrites = 0;
+       struct ieee80211_channel *channel = chan->chan;
+       u32 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:
+               return -EINVAL;
+       }
+
+       REG_WRITE(ah, AR_PHY(0), 0x00000007);
+       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+       ah->eep_ops->set_addac(ah, chan);
+
+       if (AR_SREV_5416_22_OR_LATER(ah)) {
+               REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
+       } else {
+               struct ar5416IniArray temp;
+               u32 addacSize =
+                       sizeof(u32) * ah->iniAddac.ia_rows *
+                       ah->iniAddac.ia_columns;
+
+               memcpy(ah->addac5416_21,
+                      ah->iniAddac.ia_array, addacSize);
+
+               (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
+
+               temp.ia_array = ah->addac5416_21;
+               temp.ia_columns = ah->iniAddac.ia_columns;
+               temp.ia_rows = ah->iniAddac.ia_rows;
+               REG_WRITE_ARRAY(&temp, 1, regWrites);
+       }
+
+       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
+
+       for (i = 0; i < ah->iniModes.ia_rows; i++) {
+               u32 reg = INI_RA(&ah->iniModes, i, 0);
+               u32 val = INI_RA(&ah->iniModes, i, modesIndex);
+
+               REG_WRITE(ah, reg, val);
+
+               if (reg >= 0x7800 && reg < 0x78a0
+                   && ah->config.analog_shiftreg) {
+                       udelay(100);
+               }
+
+               DO_DELAY(regWrites);
+       }
+
+       if (AR_SREV_9280(ah))
+               REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
+
+       if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
+           AR_SREV_9285_12_OR_LATER(ah)))
+               REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
+
+       for (i = 0; i < ah->iniCommon.ia_rows; i++) {
+               u32 reg = INI_RA(&ah->iniCommon, i, 0);
+               u32 val = INI_RA(&ah->iniCommon, i, 1);
+
+               REG_WRITE(ah, reg, val);
+
+               if (reg >= 0x7800 && reg < 0x78a0
+                   && ah->config.analog_shiftreg) {
+                       udelay(100);
+               }
+
+               DO_DELAY(regWrites);
+       }
+
+       ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
+
+       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
+               REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
+                               regWrites);
+       }
+
+       ath9k_hw_override_ini(ah, chan);
+       ath9k_hw_set_regs(ah, chan, macmode);
+       ath9k_hw_init_chain_masks(ah);
+
+       if (OLC_FOR_AR9280_20_LATER)
+               ath9k_olc_init(ah);
+
+       status = ah->eep_ops->set_txpower(ah, chan,
+                                 ath9k_regd_get_ctl(&ah->regulatory, chan),
+                                 channel->max_antenna_gain * 2,
+                                 channel->max_power * 2,
+                                 min((u32) MAX_RATE_POWER,
+                                     (u32) ah->regulatory.power_limit));
+       if (status != 0) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Error initializing transmit power\n");
+               return -EIO;
+       }
+
+       if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "ar5416SetRfRegs failed\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+/****************************************/
+/* Reset and Channel Switching Routines */
+/****************************************/
+
+static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       u32 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_hw *ah)
+{
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+}
+
+static inline void ath9k_hw_set_dma(struct ath_hw *ah)
+{
+       u32 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->tx_trig_level);
+
+       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_hw *ah, int opmode)
+{
+       u32 val;
+
+       val = REG_READ(ah, AR_STA_ID1);
+       val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
+       switch (opmode) {
+       case NL80211_IFTYPE_AP:
+               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 NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
+               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 NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_MONITOR:
+               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
+               break;
+       }
+}
+
+static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
+                                                u32 coef_scaled,
+                                                u32 *coef_mantissa,
+                                                u32 *coef_exponent)
+{
+       u32 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_hw *ah,
+                                    struct ath9k_channel *chan)
+{
+       u32 coef_scaled, ds_coef_exp, ds_coef_man;
+       u32 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 bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
+{
+       u32 rst_flags;
+       u32 tmpReg;
+
+       if (AR_SREV_9100(ah)) {
+               u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
+               val &= ~AR_RTC_DERIVED_CLK_PERIOD;
+               val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
+               REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
+               (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
+       }
+
+       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, AR_RTC_RC, rst_flags);
+       udelay(50);
+
+       REG_WRITE(ah, AR_RTC_RC, 0);
+       if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                       "RTC stuck in MAC reset\n");
+               return false;
+       }
+
+       if (!AR_SREV_9100(ah))
+               REG_WRITE(ah, AR_RC, 0);
+
+       ath9k_hw_init_pll(ah, NULL);
+
+       if (AR_SREV_9100(ah))
+               udelay(50);
+
+       return true;
+}
+
+static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
+                 AR_RTC_FORCE_WAKE_ON_INT);
+
+       REG_WRITE(ah, AR_RTC_RESET, 0);
+       udelay(2);
+       REG_WRITE(ah, AR_RTC_RESET, 1);
+
+       if (!ath9k_hw_wait(ah,
+                          AR_RTC_STATUS,
+                          AR_RTC_STATUS_M,
+                          AR_RTC_STATUS_ON,
+                          AH_WAIT_TIMEOUT)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n");
+               return false;
+       }
+
+       ath9k_hw_read_revisions(ah);
+
+       return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
+}
+
+static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 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);
+               break;
+       case ATH9K_RESET_WARM:
+       case ATH9K_RESET_COLD:
+               return ath9k_hw_set_reset(ah, type);
+               break;
+       default:
+               return false;
+       }
+}
+
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
+                             enum ath9k_ht_macmode macmode)
+{
+       u32 phymode;
+       u32 enableDacFifo = 0;
+
+       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 (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 bool ath9k_hw_chip_reset(struct ath_hw *ah,
+                               struct ath9k_channel *chan)
+{
+       if (OLC_FOR_AR9280_20_LATER) {
+               if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
+                       return false;
+       } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+               return false;
+
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return false;
+
+       ah->chip_fullsleep = false;
+       ath9k_hw_init_pll(ah, chan);
+       ath9k_hw_set_rfmode(ah, chan);
+
+       return true;
+}
+
+static bool ath9k_hw_channel_change(struct ath_hw *ah,
+                                   struct ath9k_channel *chan,
+                                   enum ath9k_ht_macmode macmode)
+{
+       struct ieee80211_channel *channel = chan->chan;
+       u32 synthDelay, qnum;
+
+       for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
+               if (ath9k_hw_numtxpending(ah, qnum)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                               "Transmit frames pending on queue %d\n", qnum);
+                       return 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, AH_WAIT_TIMEOUT)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Could not kill baseband RX\n");
+               return false;
+       }
+
+       ath9k_hw_set_regs(ah, chan, macmode);
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Failed to set channel\n");
+                       return false;
+               }
+       } else {
+               if (!(ath9k_hw_set_channel(ah, chan))) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Failed to set channel\n");
+                       return false;
+               }
+       }
+
+       if (ah->eep_ops->set_txpower(ah, chan,
+                            ath9k_regd_get_ctl(&ah->regulatory, chan),
+                            channel->max_antenna_gain * 2,
+                            channel->max_power * 2,
+                            min((u32) MAX_RATE_POWER,
+                                (u32) ah->regulatory.power_limit)) != 0) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Error initializing transmit power\n");
+               return 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;
+
+       udelay(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 = true;
+
+       return true;
+}
+
+static void ath9k_hw_9280_spur_mitigate(struct ath_hw *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;
+       bool is2GHz = IS_CHAN_2GHZ(chan);
+
+       memset(&mask_m, 0, sizeof(int8_t) * 123);
+       memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       ah->config.spurmode = SPUR_ENABLE_EEPROM;
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               cur_bb_spur = ah->eep_ops->get_spur_channel(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_v = abs(cur_vit_mask - bin);
+
+                       if (tmp_v < 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_hw *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;
+       bool is2GHz = IS_CHAN_2GHZ(chan);
+
+       memset(&mask_m, 0, sizeof(int8_t) * 123);
+       memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               cur_bb_spur = ah->eep_ops->get_spur_channel(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_v = abs(cur_vit_mask - bin);
+
+                       if (tmp_v < 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);
+}
+
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                   bool bChannelChange)
+{
+       u32 saveLedState;
+       struct ath_softc *sc = ah->ah_sc;
+       struct ath9k_channel *curchan = ah->curchan;
+       u32 saveDefAntenna;
+       u32 macStaId1;
+       int i, rx_chainmask, r;
+
+       ah->extprotspacing = sc->ht_extprotspacing;
+       ah->txchainmask = sc->tx_chainmask;
+       ah->rxchainmask = sc->rx_chainmask;
+
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return -EIO;
+
+       if (curchan)
+               ath9k_hw_getnf(ah, curchan);
+
+       if (bChannelChange &&
+           (ah->chip_fullsleep != true) &&
+           (ah->curchan != NULL) &&
+           (chan->channel != ah->curchan->channel) &&
+           ((chan->channelFlags & CHANNEL_ALL) ==
+            (ah->curchan->channelFlags & CHANNEL_ALL)) &&
+           (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
+                                  !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) {
+
+               if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
+                       ath9k_hw_loadnf(ah, ah->curchan);
+                       ath9k_hw_start_nfcal(ah);
+                       return 0;
+               }
+       }
+
+       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)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n");
+               return -EINVAL;
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
+
+       r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
+       if (r)
+               return r;
+
+       /* Setup MFP options for CCMP */
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
+                * frames when constructing CCMP AAD. */
+               REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
+                             0xc7ff);
+               ah->sw_mgmt_crypto = false;
+       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+               /* Disable hardware crypto for management frames */
+               REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
+                           AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+               REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+                           AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+               ah->sw_mgmt_crypto = true;
+       } else
+               ah->sw_mgmt_crypto = true;
+
+       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);
+
+       ah->eep_ops->set_board_values(ah, chan);
+
+       ath9k_hw_decrease_chain_power(ah, chan);
+
+       REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr));
+       REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4)
+                 | macStaId1
+                 | AR_STA_ID1_RTS_USE_DEF
+                 | (ah->config.
+                    ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
+                 | ah->sta_id1_defaults);
+       ath9k_hw_set_operating_mode(ah, ah->opmode);
+
+       REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
+       REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
+
+       REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
+
+       REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
+       REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
+                 ((sc->curaid & 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)))
+                       return -EIO;
+       } else {
+               if (!(ath9k_hw_set_channel(ah, chan)))
+                       return -EIO;
+       }
+
+       for (i = 0; i < AR_NUM_DCU; i++)
+               REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
+
+       ah->intr_txqs = 0;
+       for (i = 0; i < ah->caps.total_queues; i++)
+               ath9k_hw_resettxqueue(ah, i);
+
+       ath9k_hw_init_interrupt_masks(ah, ah->opmode);
+       ath9k_hw_init_qos(ah);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       if (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 (ah->config.intr_mitigation) {
+               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))
+               return -EIO;;
+
+       rx_chainmask = 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)) {
+               u32 mask;
+               mask = REG_READ(ah, AR_CFG);
+               if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                               "CFG Byte Swap Set 0x%x\n", mask);
+               } else {
+                       mask =
+                               INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
+                       REG_WRITE(ah, AR_CFG, mask);
+                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                               "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
+               }
+       } else {
+#ifdef __BIG_ENDIAN
+               REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
+#endif
+       }
+
+       return 0;
+}
+
+/************************/
+/* Key Cache Management */
+/************************/
+
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
+{
+       u32 keyType;
+
+       if (entry >= ah->caps.keycache_size) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "keychache entry %u out of range\n", entry);
+               return 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)) {
+               u16 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->curchan == NULL)
+               return true;
+
+       return true;
+}
+
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
+{
+       u32 macHi, macLo;
+
+       if (entry >= ah->caps.keycache_size) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "keychache entry %u out of range\n", entry);
+               return 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 true;
+}
+
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
+                                const struct ath9k_keyval *k,
+                                const u8 *mac)
+{
+       const struct ath9k_hw_capabilities *pCap = &ah->caps;
+       u32 key0, key1, key2, key3, key4;
+       u32 keyType;
+
+       if (entry >= pCap->keycache_size) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "keycache entry %u out of range\n", entry);
+               return 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)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                               "AES-CCM not supported by mac rev 0x%x\n",
+                               ah->hw_version.macRev);
+                       return 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) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                               "entry %u inappropriate for TKIP\n", entry);
+                       return false;
+               }
+               break;
+       case ATH9K_CIPHER_WEP:
+               if (k->kv_len < LEN_WEP40) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                               "WEP key length %u too small\n", k->kv_len);
+                       return false;
+               }
+               if (k->kv_len <= LEN_WEP40)
+                       keyType = AR_KEYTABLE_TYPE_40;
+               else if (k->kv_len <= 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:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "cipher %u not supported\n", k->kv_type);
+               return false;
+       }
+
+       key0 = get_unaligned_le32(k->kv_val + 0);
+       key1 = get_unaligned_le16(k->kv_val + 4);
+       key2 = get_unaligned_le32(k->kv_val + 6);
+       key3 = get_unaligned_le16(k->kv_val + 10);
+       key4 = get_unaligned_le32(k->kv_val + 12);
+       if (k->kv_len <= LEN_WEP104)
+               key4 &= 0xff;
+
+       /*
+        * Note: Key cache registers access special memory area that requires
+        * two 32-bit writes to actually update the values in the internal
+        * memory. Consequently, the exact order and pairs used here must be
+        * maintained.
+        */
+
+       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
+               u16 micentry = entry + 64;
+
+               /*
+                * Write inverted key[47:0] first to avoid Michael MIC errors
+                * on frames that could be sent or received at the same time.
+                * The correct key will be written in the end once everything
+                * else is ready.
+                */
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
+
+               /* Write key[95:48] */
+               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+               /* Write key[127:96] and key type */
+               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+               /* Write MAC address for the entry */
+               (void) ath9k_hw_keysetmac(ah, entry, mac);
+
+               if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
+                       /*
+                        * TKIP uses two key cache entries:
+                        * Michael MIC TX/RX keys in the same key cache entry
+                        * (idx = main index + 64):
+                        * key0 [31:0] = RX key [31:0]
+                        * key1 [15:0] = TX key [31:16]
+                        * key1 [31:16] = reserved
+                        * key2 [31:0] = RX key [63:32]
+                        * key3 [15:0] = TX key [15:0]
+                        * key3 [31:16] = reserved
+                        * key4 [31:0] = TX key [63:32]
+                        */
+                       u32 mic0, mic1, mic2, mic3, mic4;
+
+                       mic0 = get_unaligned_le32(k->kv_mic + 0);
+                       mic2 = get_unaligned_le32(k->kv_mic + 4);
+                       mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
+                       mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
+                       mic4 = get_unaligned_le32(k->kv_txmic + 4);
+
+                       /* Write RX[31:0] and TX[31:16] */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
+
+                       /* Write RX[63:32] and TX[15:0] */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
+
+                       /* Write TX[63:32] and keyType(reserved) */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
+                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+                                 AR_KEYTABLE_TYPE_CLR);
+
+               } else {
+                       /*
+                        * TKIP uses four key cache entries (two for group
+                        * keys):
+                        * Michael MIC TX/RX keys are in different key cache
+                        * entries (idx = main index + 64 for TX and
+                        * main index + 32 + 96 for RX):
+                        * key0 [31:0] = TX/RX MIC key [31:0]
+                        * key1 [31:0] = reserved
+                        * key2 [31:0] = TX/RX MIC key [63:32]
+                        * key3 [31:0] = reserved
+                        * key4 [31:0] = reserved
+                        *
+                        * Upper layer code will call this function separately
+                        * for TX and RX keys when these registers offsets are
+                        * used.
+                        */
+                       u32 mic0, mic2;
+
+                       mic0 = get_unaligned_le32(k->kv_mic + 0);
+                       mic2 = get_unaligned_le32(k->kv_mic + 4);
+
+                       /* Write MIC key[31:0] */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+
+                       /* Write MIC key[63:32] */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+
+                       /* Write TX[63:32] and keyType(reserved) */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
+                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+                                 AR_KEYTABLE_TYPE_CLR);
+               }
+
+               /* MAC address registers are reserved for the MIC entry */
+               REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
+
+               /*
+                * Write the correct (un-inverted) key[47:0] last to enable
+                * TKIP now that all other registers are set with correct
+                * values.
+                */
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+       } else {
+               /* Write key[47:0] */
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+
+               /* Write key[95:48] */
+               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+               /* Write key[127:96] and key type */
+               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+               /* Write MAC address for the entry */
+               (void) ath9k_hw_keysetmac(ah, entry, mac);
+       }
+
+       return true;
+}
+
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
+{
+       if (entry < ah->caps.keycache_size) {
+               u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
+               if (val & AR_KEYTABLE_VALID)
+                       return true;
+       }
+       return false;
+}
+
+/******************************/
+/* Power Management (Chipset) */
+/******************************/
+
+static void ath9k_set_power_sleep(struct ath_hw *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, (AR_RTC_RESET),
+                           AR_RTC_RESET_EN);
+       }
+}
+
+static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
+{
+       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+       if (setChip) {
+               struct ath9k_hw_capabilities *pCap = &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 bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
+{
+       u32 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) != true) {
+                               return 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);
+               udelay(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;
+                       udelay(50);
+                       REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+                                   AR_RTC_FORCE_WAKE_EN);
+               }
+               if (i == 0) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Failed to wakeup in %uus\n", POWER_UP_TIME / 20);
+                       return false;
+               }
+       }
+
+       REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+
+       return true;
+}
+
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
+{
+       int status = true, setChip = true;
+       static const char *modes[] = {
+               "AWAKE",
+               "FULL-SLEEP",
+               "NETWORK SLEEP",
+               "UNDEFINED"
+       };
+
+       DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n",
+               modes[ah->power_mode], modes[mode]);
+
+       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);
+               ah->chip_fullsleep = true;
+               break;
+       case ATH9K_PM_NETWORK_SLEEP:
+               ath9k_set_power_network_sleep(ah, setChip);
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Unknown power mode %u\n", mode);
+               return false;
+       }
+       ah->power_mode = mode;
+
+       return status;
+}
+
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers.  Hence the 9 writes.
+ */
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
+{
+       u8 i;
+
+       if (ah->is_pciexpress != true)
+               return;
+
+       /* Do not touch SerDes registers */
+       if (ah->config.pcie_powersave_enable == 2)
+               return;
+
+       /* Nothing to do on restore for 11N */
+       if (restore)
+               return;
+
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               /*
+                * AR9280 2.0 or later chips use SerDes values from the
+                * initvals.h initialized depending on chipset during
+                * ath9k_hw_do_attach()
+                */
+               for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
+                       REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
+                                 INI_RA(&ah->iniPcieSerdes, i, 1));
+               }
+       } else if (AR_SREV_9280(ah) &&
+                  (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+               /* RX shut off when elecidle is asserted */
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
+
+               /* Shut off CLKREQ active in L1 */
+               if (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);
+
+               /* Load the new settings */
+               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+
+       } else {
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+               /* RX shut off when elecidle is asserted */
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
+
+               /*
+                * Ignore ah->ah_config.pcie_clock_req setting for
+                * pre-AR9280 11n
+                */
+               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);
+
+               /* Load the new settings */
+               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+       }
+
+       udelay(1000);
+
+       /* set bit 19 to allow forcing of pcie core into L1 state */
+       REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+       /* Several PCIe massages to ensure proper behaviour */
+       if (ah->config.pcie_waen) {
+               REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
+       } else {
+               if (AR_SREV_9285(ah))
+                       REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
+               /*
+                * On AR9280 chips bit 22 of 0x4004 needs to be set to
+                * otherwise card may disappear.
+                */
+               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 */
+/**********************/
+
+bool ath9k_hw_intrpend(struct ath_hw *ah)
+{
+       u32 host_isr;
+
+       if (AR_SREV_9100(ah))
+               return true;
+
+       host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
+       if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
+               return true;
+
+       host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+       if ((host_isr & AR_INTR_SYNC_DEFAULT)
+           && (host_isr != AR_INTR_SPURIOUS))
+               return true;
+
+       return false;
+}
+
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+       u32 isr = 0;
+       u32 mask2 = 0;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       u32 sync_cause = 0;
+       bool fatal_int = false;
+
+       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 false;
+       } else {
+               *masked = 0;
+               isr = REG_READ(ah, AR_ISR);
+       }
+
+       if (isr) {
+               if (isr & AR_ISR_BCNMISC) {
+                       u32 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;
+                       if (isr2 & AR_ISR_S2_TSFOOR)
+                               mask2 |= ATH9K_INT_TSFOOR;
+               }
+
+               isr = REG_READ(ah, AR_ISR_RAC);
+               if (isr == 0xffffffff) {
+                       *masked = 0;
+                       return false;
+               }
+
+               *masked = isr & ATH9K_INT_COMMON;
+
+               if (ah->config.intr_mitigation) {
+                       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)) {
+                       u32 s0_s, s1_s;
+
+                       *masked |= ATH9K_INT_TX;
+
+                       s0_s = REG_READ(ah, AR_ISR_S0_S);
+                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
+                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
+
+                       s1_s = REG_READ(ah, AR_ISR_S1_S);
+                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
+                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
+               }
+
+               if (isr & AR_ISR_RXORN) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
+                               "receive FIFO overrun interrupt\n");
+               }
+
+               if (!AR_SREV_9100(ah)) {
+                       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+                               u32 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 true;
+
+       if (sync_cause) {
+               fatal_int =
+                       (sync_cause &
+                        (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
+                       ? true : false;
+
+               if (fatal_int) {
+                       if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                                       "received PCI FATAL interrupt\n");
+                       }
+                       if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                                       "received PCI PERR interrupt\n");
+                       }
+               }
+               if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
+                               "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
+                       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) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
+                               "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+               }
+
+               REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+               (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
+       }
+
+       return true;
+}
+
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
+{
+       return ah->mask_reg;
+}
+
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
+{
+       u32 omask = ah->mask_reg;
+       u32 mask, mask2;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
+
+       if (omask & ATH9K_INT_GLOBAL) {
+               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "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 (ah->txok_interrupt_mask)
+                       mask |= AR_IMR_TXOK;
+               if (ah->txdesc_interrupt_mask)
+                       mask |= AR_IMR_TXDESC;
+               if (ah->txerr_interrupt_mask)
+                       mask |= AR_IMR_TXERR;
+               if (ah->txeol_interrupt_mask)
+                       mask |= AR_IMR_TXEOL;
+       }
+       if (ints & ATH9K_INT_RX) {
+               mask |= AR_IMR_RXERR;
+               if (ah->config.intr_mitigation)
+                       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_TSFOOR)
+                       mask2 |= AR_IMR_S2_TSFOOR;
+       }
+
+       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;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
+       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);
+       ah->mask_reg = 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) {
+               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "enable IER\n");
+               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);
+               }
+               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+                        REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+       }
+
+       return omask;
+}
+
+/*******************/
+/* Beacon Handling */
+/*******************/
+
+void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
+{
+       int flags = 0;
+
+       ah->beacon_interval = beacon_period;
+
+       switch (ah->opmode) {
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_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 NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
+               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 +
+                                    (ah->atim_window ? ah->
+                                     atim_window : 1)));
+               flags |= AR_NDP_TIMER_EN;
+       case NL80211_IFTYPE_AP:
+               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->config.
+                                    dma_beacon_response_time));
+               REG_WRITE(ah, AR_NEXT_SWBA,
+                         TU_TO_USEC(next_beacon -
+                                    ah->config.
+                                    sw_beacon_response_time));
+               flags |=
+                       AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_BEACON,
+                       "%s: unsupported opmode: %d\n",
+                       __func__, ah->opmode);
+               return;
+               break;
+       }
+
+       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_hw *ah,
+                                   const struct ath9k_beacon_state *bs)
+{
+       u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
+       struct ath9k_hw_capabilities *pCap = &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;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
+       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
+       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
+       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "DTIM period %d\n", 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);
+
+       /* TSF Out of Range Threshold */
+       REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
+}
+
+/*******************/
+/* HW Capabilities */
+/*******************/
+
+void ath9k_hw_fill_cap_info(struct ath_hw *ah)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       u16 capField = 0, eeval;
+
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
+       ah->regulatory.current_rd = eeval;
+
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
+       if (AR_SREV_9285_10_OR_LATER(ah))
+               eeval |= AR9285_RDEXT_DEFAULT;
+       ah->regulatory.current_rd_ext = eeval;
+
+       capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
+
+       if (ah->opmode != NL80211_IFTYPE_AP &&
+           ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
+               if (ah->regulatory.current_rd == 0x64 ||
+                   ah->regulatory.current_rd == 0x65)
+                       ah->regulatory.current_rd += 5;
+               else if (ah->regulatory.current_rd == 0x41)
+                       ah->regulatory.current_rd = 0x43;
+               DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+                       "regdomain mapped to 0x%x\n", ah->regulatory.current_rd);
+       }
+
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
+       bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
+
+       if (eeval & AR5416_OPFLAGS_11A) {
+               set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
+               if (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->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 = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
+       if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
+           !(eeval & AR5416_OPFLAGS_11A))
+               pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
+       else
+               pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
+
+       if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
+               ah->misc_mode |= 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;
+
+       if (ah->config.ht_enable)
+               pCap->hw_caps |= ATH9K_HW_CAP_HT;
+       else
+               pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
+
+       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->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
+
+       if (AR_SREV_9285_10_OR_LATER(ah))
+               pCap->num_gpio_pins = AR9285_NUM_GPIO;
+       else 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_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->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
+       if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
+               ah->rfkill_gpio =
+                       MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
+               ah->rfkill_polarity =
+                       MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
+
+               pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
+       }
+#endif
+
+       if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) ||
+           (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
+           (ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
+           (ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
+           (ah->hw_version.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->regulatory.current_rd_ext & (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;
+
+       pCap->num_antcfg_5ghz =
+               ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
+       pCap->num_antcfg_2ghz =
+               ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
+
+       if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
+               pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
+               ah->btactive_gpio = 6;
+               ah->wlanactive_gpio = 5;
+       }
+}
+
+bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 *result)
+{
+       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 true;
+               default:
+                       return false;
+               }
+       case ATH9K_CAP_TKIP_MIC:
+               switch (capability) {
+               case 0:
+                       return true;
+               case 1:
+                       return (ah->sta_id1_defaults &
+                               AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
+                       false;
+               }
+       case ATH9K_CAP_TKIP_SPLIT:
+               return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
+                       false : true;
+       case ATH9K_CAP_DIVERSITY:
+               return (REG_READ(ah, AR_PHY_CCK_DETECT) &
+                       AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
+                       true : false;
+       case ATH9K_CAP_MCAST_KEYSRCH:
+               switch (capability) {
+               case 0:
+                       return true;
+               case 1:
+                       if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
+                               return false;
+                       } else {
+                               return (ah->sta_id1_defaults &
+                                       AR_STA_ID1_MCAST_KSRCH) ? true :
+                                       false;
+                       }
+               }
+               return false;
+       case ATH9K_CAP_TXPOW:
+               switch (capability) {
+               case 0:
+                       return 0;
+               case 1:
+                       *result = ah->regulatory.power_limit;
+                       return 0;
+               case 2:
+                       *result = ah->regulatory.max_power_level;
+                       return 0;
+               case 3:
+                       *result = ah->regulatory.tp_scale;
+                       return 0;
+               }
+               return false;
+       case ATH9K_CAP_DS:
+               return (AR_SREV_9280_20_OR_LATER(ah) &&
+                       (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1))
+                       ? false : true;
+       default:
+               return false;
+       }
+}
+
+bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 setting, int *status)
+{
+       u32 v;
+
+       switch (type) {
+       case ATH9K_CAP_TKIP_MIC:
+               if (setting)
+                       ah->sta_id1_defaults |=
+                               AR_STA_ID1_CRPT_MIC_ENABLE;
+               else
+                       ah->sta_id1_defaults &=
+                               ~AR_STA_ID1_CRPT_MIC_ENABLE;
+               return 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 true;
+       case ATH9K_CAP_MCAST_KEYSRCH:
+               if (setting)
+                       ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
+               else
+                       ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
+               return true;
+       default:
+               return false;
+       }
+}
+
+/****************************/
+/* GPIO / RFKILL / Antennae */
+/****************************/
+
+static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
+                                        u32 gpio, u32 type)
+{
+       int addr;
+       u32 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_hw *ah, u32 gpio)
+{
+       u32 gpio_shift;
+
+       ASSERT(gpio < 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));
+}
+
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
+{
+#define MS_REG_READ(x, y) \
+       (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
+
+       if (gpio >= ah->caps.num_gpio_pins)
+               return 0xffffffff;
+
+       if (AR_SREV_9285_10_OR_LATER(ah))
+               return MS_REG_READ(AR9285, gpio) != 0;
+       else if (AR_SREV_9280_10_OR_LATER(ah))
+               return MS_REG_READ(AR928X, gpio) != 0;
+       else
+               return MS_REG_READ(AR, gpio) != 0;
+}
+
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
+                        u32 ah_signal_type)
+{
+       u32 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_hw *ah, u32 gpio, u32 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_hw *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->rfkill_gpio);
+       REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
+}
+#endif
+
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
+{
+       return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
+}
+
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
+{
+       REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
+}
+
+bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
+                              enum ath9k_ant_setting settings,
+                              struct ath9k_channel *chan,
+                              u8 *tx_chainmask,
+                              u8 *rx_chainmask,
+                              u8 *antenna_cfgd)
+{
+       static u8 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 = true;
+                       break;
+               case ATH9K_ANT_FIXED_B:
+                       if (ah->caps.tx_chainmask >
+                           ATH9K_ANTENNA1_CHAINMASK) {
+                               *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
+                       }
+                       *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
+                       *antenna_cfgd = true;
+                       break;
+               case ATH9K_ANT_VARIABLE:
+                       *tx_chainmask = tx_chainmask_cfg;
+                       *rx_chainmask = rx_chainmask_cfg;
+                       *antenna_cfgd = true;
+                       break;
+               default:
+                       break;
+               }
+       } else {
+               ah->diversity_control = settings;
+       }
+
+       return true;
+}
+
+/*********************/
+/* General Operation */
+/*********************/
+
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
+{
+       u32 bits = REG_READ(ah, AR_RX_FILTER);
+       u32 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_hw *ah, u32 bits)
+{
+       u32 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);
+}
+
+bool ath9k_hw_phy_disable(struct ath_hw *ah)
+{
+       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
+}
+
+bool ath9k_hw_disable(struct ath_hw *ah)
+{
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return false;
+
+       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
+}
+
+bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
+{
+       struct ath9k_channel *chan = ah->curchan;
+       struct ieee80211_channel *channel = chan->chan;
+
+       ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
+
+       if (ah->eep_ops->set_txpower(ah, chan,
+                            ath9k_regd_get_ctl(&ah->regulatory, chan),
+                            channel->max_antenna_gain * 2,
+                            channel->max_power * 2,
+                            min((u32) MAX_RATE_POWER,
+                                (u32) ah->regulatory.power_limit)) != 0)
+               return false;
+
+       return true;
+}
+
+void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
+{
+       memcpy(ah->macaddr, mac, ETH_ALEN);
+}
+
+void ath9k_hw_setopmode(struct ath_hw *ah)
+{
+       ath9k_hw_set_operating_mode(ah, ah->opmode);
+}
+
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
+{
+       REG_WRITE(ah, AR_MCAST_FIL0, filter0);
+       REG_WRITE(ah, AR_MCAST_FIL1, filter1);
+}
+
+void ath9k_hw_setbssidmask(struct ath_softc *sc)
+{
+       REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
+       REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
+}
+
+void ath9k_hw_write_associd(struct ath_softc *sc)
+{
+       REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
+       REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
+                 ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
+}
+
+u64 ath9k_hw_gettsf64(struct ath_hw *ah)
+{
+       u64 tsf;
+
+       tsf = REG_READ(ah, AR_TSF_U32);
+       tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
+
+       return tsf;
+}
+
+void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
+{
+       REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
+       REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
+}
+
+void ath9k_hw_reset_tsf(struct ath_hw *ah)
+{
+       int count;
+
+       count = 0;
+       while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
+               count++;
+               if (count > 10) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                               "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
+                       break;
+               }
+               udelay(10);
+       }
+       REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
+}
+
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
+{
+       if (setting)
+               ah->misc_mode |= AR_PCU_TX_ADD_TSF;
+       else
+               ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
+
+       return true;
+}
+
+bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
+{
+       if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us);
+               ah->slottime = (u32) -1;
+               return false;
+       } else {
+               REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
+               ah->slottime = us;
+               return true;
+       }
+}
+
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
+{
+       u32 macmode;
+
+       if (mode == ATH9K_HT_MACMODE_2040 &&
+           !ah->config.cwm_ignore_extcca)
+               macmode = AR_2040_JOINED_RX_CLEAR;
+       else
+               macmode = 0;
+
+       REG_WRITE(ah, AR_2040_MODE, macmode);
+}
+
+/***************************/
+/*  Bluetooth Coexistence  */
+/***************************/
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+{
+       /* connect bt_active to baseband */
+       REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+                       (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
+                        AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
+
+       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+                       AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+
+       /* Set input mux for bt_active to gpio pin */
+       REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+                       AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+                       ah->btactive_gpio);
+
+       /* Configure the desired gpio port for input */
+       ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
+
+       /* Configure the desired GPIO port for TX_FRAME output */
+       ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
+                           AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
new file mode 100644 (file)
index 0000000..5c4127e
--- /dev/null
@@ -0,0 +1,631 @@
+/*
+ * Copyright (c) 2008-2009 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 HW_H
+#define HW_H
+
+#include <linux/if_ether.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "mac.h"
+#include "ani.h"
+#include "eeprom.h"
+#include "calib.h"
+#include "reg.h"
+#include "phy.h"
+
+#include "../regd.h"
+
+#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 AR5416_MAGIC           0x19641014
+
+/* Register read/write primitives */
+#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
+#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_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 DO_DELAY(x) do {                       \
+               if ((++(x) % 64) == 0)          \
+                       udelay(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 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_TX_FRAME           3
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    5
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      6
+
+#define AR_GPIOD_MASK               0x00001FFF
+#define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
+
+#define BASE_ACTIVATE_DELAY         100
+#define RTC_PLL_SETTLE_DELAY        1000
+#define COEF_SCALE_S                24
+#define HT40_CHANNEL_CENTER_SHIFT   10
+
+#define ATH9K_ANTENNA0_CHAINMASK    0x1
+#define ATH9K_ANTENNA1_CHAINMASK    0x2
+
+#define ATH9K_NUM_DMA_DEBUG_REGS    8
+#define ATH9K_NUM_QUEUES            10
+
+#define MAX_RATE_POWER              63
+#define AH_WAIT_TIMEOUT             100000 /* (us) */
+#define AH_TIME_QUANTUM             10
+#define AR_KEYTABLE_SIZE            128
+#define POWER_UP_TIME               200000
+#define SPUR_RSSI_THRESH            40
+
+#define CAB_TIMEOUT_VAL             10
+#define BEACON_TIMEOUT_VAL          10
+#define MIN_BEACON_TIMEOUT_VAL      1
+#define SLEEP_SLOP                  3
+
+#define INIT_CONFIG_STATUS          0x00000000
+#define INIT_RSSI_THR               0x00000700
+#define INIT_BCON_CNTRL_REG         0x00000000
+
+#define TU_TO_USEC(_tu)             ((_tu) << 10)
+
+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_MIC_AESCCM                 = BIT(0),
+       ATH9K_HW_CAP_MIC_CKIP                   = BIT(1),
+       ATH9K_HW_CAP_MIC_TKIP                   = BIT(2),
+       ATH9K_HW_CAP_CIPHER_AESCCM              = BIT(3),
+       ATH9K_HW_CAP_CIPHER_CKIP                = BIT(4),
+       ATH9K_HW_CAP_CIPHER_TKIP                = BIT(5),
+       ATH9K_HW_CAP_VEOL                       = BIT(6),
+       ATH9K_HW_CAP_BSSIDMASK                  = BIT(7),
+       ATH9K_HW_CAP_MCAST_KEYSEARCH            = BIT(8),
+       ATH9K_HW_CAP_HT                         = BIT(9),
+       ATH9K_HW_CAP_GTT                        = BIT(10),
+       ATH9K_HW_CAP_FASTCC                     = BIT(11),
+       ATH9K_HW_CAP_RFSILENT                   = BIT(12),
+       ATH9K_HW_CAP_CST                        = BIT(13),
+       ATH9K_HW_CAP_ENHANCEDPM                 = BIT(14),
+       ATH9K_HW_CAP_AUTOSLEEP                  = BIT(15),
+       ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(16),
+       ATH9K_HW_CAP_BT_COEX                    = BIT(17)
+};
+
+enum ath9k_capability_type {
+       ATH9K_CAP_CIPHER = 0,
+       ATH9K_CAP_TKIP_MIC,
+       ATH9K_CAP_TKIP_SPLIT,
+       ATH9K_CAP_DIVERSITY,
+       ATH9K_CAP_TXPOW,
+       ATH9K_CAP_MCAST_KEYSRCH,
+       ATH9K_CAP_DS
+};
+
+struct ath9k_hw_capabilities {
+       u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
+       DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
+       u16 total_queues;
+       u16 keycache_size;
+       u16 low_5ghz_chan, high_5ghz_chan;
+       u16 low_2ghz_chan, high_2ghz_chan;
+       u16 rts_aggr_limit;
+       u8 tx_chainmask;
+       u8 rx_chainmask;
+       u16 tx_triglevel_max;
+       u16 reg_cap;
+       u8 num_gpio_pins;
+       u8 num_antcfg_2ghz;
+       u8 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;
+       u8 pcie_powersave_enable;
+       u8 pcie_clock_req;
+       u32 pcie_waen;
+       u8 analog_shiftreg;
+       u8 ht_enable;
+       u32 ofdm_trig_low;
+       u32 ofdm_trig_high;
+       u32 cck_trig_high;
+       u32 cck_trig_low;
+       u32 enable_ani;
+       u16 diversity_control;
+       u16 antenna_switch_swap;
+       int serialize_regmode;
+       bool 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;
+       u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
+};
+
+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_TSFOOR = 0x04000000,
+       ATH9K_INT_CST = 0x10000000,
+       ATH9K_INT_GTT = 0x20000000,
+       ATH9K_INT_FATAL = 0x40000000,
+       ATH9K_INT_GLOBAL = 0x80000000,
+       ATH9K_INT_BMISC = ATH9K_INT_TIM |
+               ATH9K_INT_DTIM |
+               ATH9K_INT_DTIMSYNC |
+               ATH9K_INT_TSFOOR |
+               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 = 0xffffffff
+};
+
+#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 {
+       struct ieee80211_channel *chan;
+       u16 channel;
+       u32 channelFlags;
+       u32 chanmode;
+       int32_t CalValid;
+       bool oneTimeCalsDone;
+       int8_t iCoff;
+       int8_t qCoff;
+       int16_t rawNoiseFloor;
+};
+
+#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)
+#define IS_CHAN_A_5MHZ_SPACED(_c)                      \
+       ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) &&  \
+        (((_c)->channel % 20) != 0) &&                 \
+        (((_c)->channel % 10) != 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)))
+
+enum ath9k_power_mode {
+       ATH9K_PM_AWAKE = 0,
+       ATH9K_PM_FULL_SLEEP,
+       ATH9K_PM_NETWORK_SLEEP,
+       ATH9K_PM_UNDEFINED
+};
+
+enum ath9k_ant_setting {
+       ATH9K_ANT_VARIABLE = 0,
+       ATH9K_ANT_FIXED_A,
+       ATH9K_ANT_FIXED_B
+};
+
+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,
+};
+
+struct ath9k_beacon_state {
+       u32 bs_nexttbtt;
+       u32 bs_nextdtim;
+       u32 bs_intval;
+#define ATH9K_BEACON_PERIOD       0x0000ffff
+#define ATH9K_BEACON_ENA          0x00800000
+#define ATH9K_BEACON_RESET_TSF    0x01000000
+#define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */
+       u32 bs_dtimperiod;
+       u16 bs_cfpperiod;
+       u16 bs_cfpmaxduration;
+       u32 bs_cfpnext;
+       u16 bs_timoffset;
+       u16 bs_bmissthreshold;
+       u32 bs_sleepduration;
+       u32 bs_tsfoor_threshold;
+};
+
+struct chan_centers {
+       u16 synth_center;
+       u16 ctl_center;
+       u16 ext_center;
+};
+
+enum {
+       ATH9K_RESET_POWER_ON,
+       ATH9K_RESET_WARM,
+       ATH9K_RESET_COLD,
+};
+
+struct ath9k_hw_version {
+       u32 magic;
+       u16 devid;
+       u16 subvendorid;
+       u32 macVersion;
+       u16 macRev;
+       u16 phyRev;
+       u16 analog5GhzRev;
+       u16 analog2GhzRev;
+};
+
+struct ath_hw {
+       struct ath_softc *ah_sc;
+       struct ath9k_hw_version hw_version;
+       struct ath9k_ops_config config;
+       struct ath9k_hw_capabilities caps;
+       struct ath_regulatory regulatory;
+       struct ath9k_channel channels[38];
+       struct ath9k_channel *curchan;
+
+       union {
+               struct ar5416_eeprom_def def;
+               struct ar5416_eeprom_4k map4k;
+       } eeprom;
+       const struct eeprom_ops *eep_ops;
+       enum ath9k_eep_map eep_map;
+
+       bool sw_mgmt_crypto;
+       bool is_pciexpress;
+       u8 macaddr[ETH_ALEN];
+       u16 tx_trig_level;
+       u16 rfsilent;
+       u32 rfkill_gpio;
+       u32 rfkill_polarity;
+       u32 btactive_gpio;
+       u32 wlanactive_gpio;
+       u32 ah_flags;
+
+       enum nl80211_iftype opmode;
+       enum ath9k_power_mode power_mode;
+       enum ath9k_power_mode restore_mode;
+
+       struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+       struct ar5416Stats stats;
+       struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
+
+       int16_t curchan_rad_index;
+       u32 mask_reg;
+       u32 txok_interrupt_mask;
+       u32 txerr_interrupt_mask;
+       u32 txdesc_interrupt_mask;
+       u32 txeol_interrupt_mask;
+       u32 txurn_interrupt_mask;
+       bool chip_fullsleep;
+       u32 atim_window;
+       u16 antenna_switch_swap;
+       enum ath9k_ant_setting diversity_control;
+
+       /* Calibration */
+       enum hal_cal_types supp_cals;
+       struct hal_cal_list iq_caldata;
+       struct hal_cal_list adcgain_caldata;
+       struct hal_cal_list adcdc_calinitdata;
+       struct hal_cal_list adcdc_caldata;
+       struct hal_cal_list *cal_list;
+       struct hal_cal_list *cal_list_last;
+       struct hal_cal_list *cal_list_curr;
+#define totalPowerMeasI meas0.unsign
+#define totalPowerMeasQ meas1.unsign
+#define totalIqCorrMeas meas2.sign
+#define totalAdcIOddPhase  meas0.unsign
+#define totalAdcIEvenPhase meas1.unsign
+#define totalAdcQOddPhase  meas2.unsign
+#define totalAdcQEvenPhase meas3.unsign
+#define totalAdcDcOffsetIOddPhase  meas0.sign
+#define totalAdcDcOffsetIEvenPhase meas1.sign
+#define totalAdcDcOffsetQOddPhase  meas2.sign
+#define totalAdcDcOffsetQEvenPhase meas3.sign
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas0;
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas1;
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas2;
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas3;
+       u16 cal_samples;
+
+       u32 sta_id1_defaults;
+       u32 misc_mode;
+       enum {
+               AUTO_32KHZ,
+               USE_32KHZ,
+               DONT_USE_32KHZ,
+       } enable_32kHz_clock;
+
+       /* RF */
+       u32 *analogBank0Data;
+       u32 *analogBank1Data;
+       u32 *analogBank2Data;
+       u32 *analogBank3Data;
+       u32 *analogBank6Data;
+       u32 *analogBank6TPCData;
+       u32 *analogBank7Data;
+       u32 *addac5416_21;
+       u32 *bank6Temp;
+
+       int16_t txpower_indexoffset;
+       u32 beacon_interval;
+       u32 slottime;
+       u32 acktimeout;
+       u32 ctstimeout;
+       u32 globaltxtimeout;
+       u8 gbeacon_rate;
+
+       /* ANI */
+       u32 proc_phyerr;
+       bool has_hw_phycounters;
+       u32 aniperiod;
+       struct ar5416AniState *curani;
+       struct ar5416AniState ani[255];
+       int totalSizeDesired[5];
+       int coarse_high[5];
+       int coarse_low[5];
+       int firpwr[5];
+       enum ath9k_ani_cmd ani_function;
+
+       u32 intr_txqs;
+       enum ath9k_ht_extprotspacing extprotspacing;
+       u8 txchainmask;
+       u8 rxchainmask;
+
+       u32 originalGain[22];
+       int initPDADC;
+       int PDADCdelta;
+
+       struct ar5416IniArray iniModes;
+       struct ar5416IniArray iniCommon;
+       struct ar5416IniArray iniBank0;
+       struct ar5416IniArray iniBB_RfGain;
+       struct ar5416IniArray iniBank1;
+       struct ar5416IniArray iniBank2;
+       struct ar5416IniArray iniBank3;
+       struct ar5416IniArray iniBank6;
+       struct ar5416IniArray iniBank6TPC;
+       struct ar5416IniArray iniBank7;
+       struct ar5416IniArray iniAddac;
+       struct ar5416IniArray iniPcieSerdes;
+       struct ar5416IniArray iniModesAdditional;
+       struct ar5416IniArray iniModesRxGain;
+       struct ar5416IniArray iniModesTxGain;
+};
+
+/* Attach, Detach, Reset */
+const char *ath9k_hw_probe(u16 vendorid, u16 devid);
+void ath9k_hw_detach(struct ath_hw *ah);
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
+void ath9k_hw_rfdetach(struct ath_hw *ah);
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                  bool bChannelChange);
+void ath9k_hw_fill_cap_info(struct ath_hw *ah);
+bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 *result);
+bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 setting, int *status);
+
+/* Key Cache Management */
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac);
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
+                                const struct ath9k_keyval *k,
+                                const u8 *mac);
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry);
+
+/* GPIO / RFKILL / Antennae */
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
+                        u32 ah_signal_type);
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+void ath9k_enable_rfkill(struct ath_hw *ah);
+#endif
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
+bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
+                              enum ath9k_ant_setting settings,
+                              struct ath9k_channel *chan,
+                              u8 *tx_chainmask, u8 *rx_chainmask,
+                              u8 *antenna_cfgd);
+
+/* General Operation */
+bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
+u32 ath9k_hw_reverse_bits(u32 val, u32 n);
+bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
+u16 ath9k_hw_computetxtime(struct ath_hw *ah, struct ath_rate_table *rates,
+                          u32 frameLen, u16 rateix, bool shortPreamble);
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 struct chan_centers *centers);
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
+bool ath9k_hw_phy_disable(struct ath_hw *ah);
+bool ath9k_hw_disable(struct ath_hw *ah);
+bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
+void ath9k_hw_setopmode(struct ath_hw *ah);
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
+void ath9k_hw_setbssidmask(struct ath_softc *sc);
+void ath9k_hw_write_associd(struct ath_softc *sc);
+u64 ath9k_hw_gettsf64(struct ath_hw *ah);
+void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
+void ath9k_hw_reset_tsf(struct ath_hw *ah);
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
+bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
+void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
+void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
+                                   const struct ath9k_beacon_state *bs);
+bool ath9k_hw_setpower(struct ath_hw *ah,
+                      enum ath9k_power_mode mode);
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
+
+/* Interrupt Handling */
+bool ath9k_hw_intrpend(struct ath_hw *ah);
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah);
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
new file mode 100644 (file)
index 0000000..e2f0a34
--- /dev/null
@@ -0,0 +1,4848 @@
+/*
+ * Copyright (c) 2008-2009 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.
+ */
+
+static const u32 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, 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 u32 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 },
+    { 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 u32 ar5416Bank0[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 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 u32 ar5416Bank1[][2] = {
+    { 0x000098b0, 0x02108421 },
+    { 0x000098ec, 0x00000008 },
+};
+
+static const u32 ar5416Bank2[][2] = {
+    { 0x000098b0, 0x0e73ff17 },
+    { 0x000098e0, 0x00000420 },
+};
+
+static const u32 ar5416Bank3[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 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, 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 u32 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, 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 u32 ar5416Bank7[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static const u32 ar5416Addac[][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 },
+    {0x000098cc,  0x00000000 },
+};
+
+static const u32 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, 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 u32 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 },
+    { 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 u32 ar5416Bank0_9100[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 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 u32 ar5416Bank1_9100[][2] = {
+    { 0x000098b0, 0x02108421},
+    { 0x000098ec, 0x00000008},
+};
+
+static const u32 ar5416Bank2_9100[][2] = {
+    { 0x000098b0, 0x0e73ff17},
+    { 0x000098e0, 0x00000420},
+};
+
+static const u32 ar5416Bank3_9100[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 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, 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 u32 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, 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 u32 ar5416Bank7_9100[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static const u32 ar5416Addac_9100[][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 },
+};
+
+static const u32 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 u32 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 u32 ar5416Bank0_9160[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 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 u32 ar5416Bank1_9160[][2] = {
+    { 0x000098b0, 0x02108421 },
+    { 0x000098ec, 0x00000008 },
+};
+
+static const u32 ar5416Bank2_9160[][2] = {
+    { 0x000098b0, 0x0e73ff17 },
+    { 0x000098e0, 0x00000420 },
+};
+
+static const u32 ar5416Bank3_9160[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 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 u32 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 u32 ar5416Bank7_9160[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static u32 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 u32 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 u32 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 u32 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 u32 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 },
+    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
+    { 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 },
+    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+    { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
+};
+
+static const u32 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 },
+    { 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 },
+    { 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 },
+    { 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 },
+    { 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 },
+    { 0x00007824, 0x00040000 },
+    { 0x00007828, 0xdb005012 },
+    { 0x0000782c, 0x04924914 },
+    { 0x00007830, 0x21084210 },
+    { 0x00007834, 0x6d801300 },
+    { 0x0000783c, 0x07e40000 },
+    { 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 u32 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 },
+};
+
+static const u32 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 u32 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 u32 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 u32 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, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 },
+    { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 },
+    { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 },
+    { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 },
+    { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
+    { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 },
+    { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
+    { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
+    { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 },
+    { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
+    { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
+    { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
+    { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 },
+    { 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
+    { 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
+    { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
+    { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
+    { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
+    { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
+    { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
+    { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce },
+};
+
+static const u32 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 },
+    { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
+    { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
+    { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
+    { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
+    { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
+    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
+};
+
+static const u32 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 u32 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 u_int32_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 u_int32_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 u_int32_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 u_int32_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 },
+};
+
+/* AR9285 v1_2 PCI Register Writes.  Created: 03/04/09 */
+static const u_int32_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, 0x03721620, 0x03721620, 0x037216a0 },
+    { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
+    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
+    { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
+    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 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, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
+    { 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, 0x00058084, 0x00058084, 0x00000000 },
+    { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+    { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+    { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+    { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+    { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+    { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+    { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+    { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+    { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+    { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+    { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+    { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+    { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+    { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+    { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+    { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+    { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+    { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+    { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+    { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+    { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+    { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+    { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+    { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+    { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+    { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+    { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 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, 0x00078b04, 0x00078b04, 0x00000000 },
+    { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+    { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+    { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+    { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+    { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+    { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+    { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+    { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+    { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+    { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+    { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+    { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+    { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+    { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+    { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+    { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+    { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+    { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+    { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+    { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+    { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+    { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+    { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+    { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+    { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+    { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+    { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+    { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+    { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+    { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+    { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+    { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+    { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+    { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+    { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+    { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+    { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+    { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+    { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+    { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+    { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+    { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+    { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+    { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+    { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+    { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+    { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+    { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+    { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+    { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+    { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+    { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+    { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+    { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+    { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+    { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+    { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+    { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+    { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+    { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+    { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+    { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+    { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+    { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+    { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+    { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+    { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+    { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+    { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+    { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+    { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+    { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+    { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+    { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+    { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
+    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+    { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+    { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+    { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+    { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+    { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+    { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+    { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+    { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+    { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+    { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+    { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+    { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+    { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+    { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+    { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+    { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+    { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+    { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+    { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+    { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+    { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+    { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+    { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+    { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+    { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+    { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+    { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+    { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+    { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+    { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+    { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+    { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+    { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+    { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+    { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+    { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+    { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+    { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+    { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+    { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+    { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+    { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+    { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
+    { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
+    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+};
+
+static const u_int32_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, 0x08f04810 },
+    { 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, 0x0000320a },
+    { 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, 0x2def0400 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099b4, 0x00000820 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000000 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099f0, 0x00000000 },
+    { 0x0000a208, 0x803e68c8 },
+    { 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 },
+    { 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 },
+    { 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 },
+    { 0x0000a3e4, 0x00000000 },
+    { 0x0000a3e8, 0x18c43433 },
+    { 0x0000a3ec, 0x00f70081 },
+    { 0x00007800, 0x00140000 },
+    { 0x00007804, 0x0e4548d8 },
+    { 0x00007808, 0x54214514 },
+    { 0x0000780c, 0x02025820 },
+    { 0x00007810, 0x71c0d388 },
+    { 0x00007814, 0x924934a8 },
+    { 0x0000781c, 0x00000000 },
+    { 0x00007824, 0x00d86fff },
+    { 0x00007828, 0x26d2491b },
+    { 0x0000782c, 0x6e36d97b },
+    { 0x00007830, 0xedb6d96e },
+    { 0x00007834, 0x71400087 },
+    { 0x0000783c, 0x0001fffe },
+    { 0x00007840, 0xffeb1a20 },
+    { 0x00007844, 0x000c0db6 },
+    { 0x00007848, 0x6db61b6f },
+    { 0x0000784c, 0x6d9b66db },
+    { 0x00007850, 0x6d8c6dba },
+    { 0x00007854, 0x00040000 },
+    { 0x00007858, 0xdb003012 },
+    { 0x0000785c, 0x04924914 },
+    { 0x00007860, 0x21084210 },
+    { 0x00007864, 0xf7d7ffde },
+    { 0x00007868, 0xc2034080 },
+    { 0x00007870, 0x10142c00 },
+};
+
+static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
+    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
+    { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
+    { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+    { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
+    { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+    { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+};
+
+static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
+    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
+    { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
+    { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
+    { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+    { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+    { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
+    { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+    { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+    { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+    { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+};
+
+static const u_int32_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 u_int32_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 },
+};
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
new file mode 100644 (file)
index 0000000..8ae4ec2
--- /dev/null
@@ -0,0 +1,976 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
+                                       struct ath9k_tx_queue_info *qi)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
+               "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
+               ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
+               ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
+               ah->txurn_interrupt_mask);
+
+       REG_WRITE(ah, AR_IMR_S0,
+                 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
+                 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
+       REG_WRITE(ah, AR_IMR_S1,
+                 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
+                 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
+       REG_RMW_FIELD(ah, AR_IMR_S2,
+                     AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask);
+}
+
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
+{
+       return REG_READ(ah, AR_QTXDP(q));
+}
+
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
+{
+       REG_WRITE(ah, AR_QTXDP(q), txdp);
+
+       return true;
+}
+
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q);
+
+       REG_WRITE(ah, AR_Q_TXE, 1 << q);
+
+       return true;
+}
+
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
+{
+       u32 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;
+}
+
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
+{
+       u32 txcfg, curLevel, newLevel;
+       enum ath9k_int omask;
+
+       if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
+               return false;
+
+       omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~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));
+
+       ath9k_hw_set_interrupts(ah, omask);
+
+       ah->tx_trig_level = newLevel;
+
+       return newLevel != curLevel;
+}
+
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
+{
+#define ATH9K_TX_STOP_DMA_TIMEOUT      4000    /* usec */
+#define ATH9K_TIME_QUANTUM             100     /* usec */
+
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_tx_queue_info *qi;
+       u32 tsfLow, j, wait;
+       u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
+                       "inactive queue: %u\n", q);
+               return false;
+       }
+
+       REG_WRITE(ah, AR_Q_TXD, 1 << q);
+
+       for (wait = wait_time; wait != 0; wait--) {
+               if (ath9k_hw_numtxpending(ah, q) == 0)
+                       break;
+               udelay(ATH9K_TIME_QUANTUM);
+       }
+
+       if (ath9k_hw_numtxpending(ah, q)) {
+               DPRINTF(ah->ah_sc, ATH_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;
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                               "TSF has moved while trying to set "
+                               "quiet time TSF: 0x%08x\n", tsfLow);
+               }
+
+               REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+
+               udelay(200);
+               REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+
+               wait = wait_time;
+               while (ath9k_hw_numtxpending(ah, q)) {
+                       if ((--wait) == 0) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                                       "Failed to stop TX DMA in 100 "
+                                       "msec after killing last frame\n");
+                               break;
+                       }
+                       udelay(ATH9K_TIME_QUANTUM);
+               }
+
+               REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+       }
+
+       REG_WRITE(ah, AR_Q_TXD, 0);
+       return wait != 0;
+
+#undef ATH9K_TX_STOP_DMA_TIMEOUT
+#undef ATH9K_TIME_QUANTUM
+}
+
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                        u32 segLen, bool firstSeg,
+                        bool 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 true;
+}
+
+void ath9k_hw_cleartxdesc(struct ath_hw *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_hw *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)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
+       if (ads->ds_txstatus1 & AR_Filtered)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
+       if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus9 & AR_TxOpExceeded)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
+       if (ads->ds_txstatus1 & AR_TxTimerExpired)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+
+       if (ads->ds_txstatus1 & AR_DescCfgErr)
+               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;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
+               ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, 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 = 0;
+
+       return 0;
+}
+
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
+                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
+                           u32 keyIx, enum ath9k_key_type keyType, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       txPower += ah->txpower_indexoffset;
+       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;
+       }
+}
+
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
+                                 struct ath_desc *lastds,
+                                 u32 durUpdateEn, u32 rtsctsRate,
+                                 u32 rtsctsDuration,
+                                 struct ath9k_11n_rate_series series[],
+                                 u32 nseries, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       struct ar5416_desc *last_ads = AR5416DESC(lastds);
+       u32 ds_ctl0;
+
+       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;
+}
+
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
+                               u32 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);
+}
+
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
+                                u32 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;
+}
+
+void ath9k_hw_set11n_aggr_last(struct ath_hw *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;
+}
+
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
+}
+
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
+                                  u32 burstDuration)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl2 &= ~AR_BurstDur;
+       ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
+}
+
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
+                                    u32 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_hw *ah, u32 *txqs)
+{
+       *txqs &= ah->intr_txqs;
+       ah->intr_txqs &= ~(*txqs);
+}
+
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+                           const struct ath9k_tx_queue_info *qinfo)
+{
+       u32 cw;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_tx_queue_info *qi;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
+                       "inactive queue: %u\n", q);
+               return false;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
+
+       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((u32) qinfo->tqi_shretry, 15U);
+       else
+               qi->tqi_shretry = INIT_SH_RETRY;
+       if (qinfo->tqi_lgretry != 0)
+               qi->tqi_lgretry = min((u32) 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 true;
+}
+
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
+                           struct ath9k_tx_queue_info *qinfo)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_tx_queue_info *qi;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
+                       "inactive queue: %u\n", q);
+               return 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 true;
+}
+
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
+                         const struct ath9k_tx_queue_info *qinfo)
+{
+       struct ath9k_tx_queue_info *qi;
+       struct ath9k_hw_capabilities *pCap = &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 (ah->txq[q].tqi_type ==
+                           ATH9K_TX_QUEUE_INACTIVE)
+                               break;
+               if (q == pCap->total_queues) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "No available TX queue\n");
+                       return -1;
+               }
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid TX queue type: %u\n",
+                       type);
+               return -1;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "TX queue: %u already active\n", q);
+               return -1;
+       }
+       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;
+}
+
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_tx_queue_info *qi;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
+                       "inactive queue: %u\n", q);
+               return false;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
+
+       qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
+       ah->txok_interrupt_mask &= ~(1 << q);
+       ah->txerr_interrupt_mask &= ~(1 << q);
+       ah->txdesc_interrupt_mask &= ~(1 << q);
+       ah->txeol_interrupt_mask &= ~(1 << q);
+       ah->txurn_interrupt_mask &= ~(1 << q);
+       ath9k_hw_set_txq_interrupts(ah, qi);
+
+       return true;
+}
+
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_channel *chan = ah->curchan;
+       struct ath9k_tx_queue_info *qi;
+       u32 cwMin, chanCwMin, value;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
+                       "inactive queue: %u\n", q);
+               return true;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TX queue: %u\n", 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);
+       } 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->config.sw_beacon_response_time -
+                         ah->config.dma_beacon_response_time) -
+                        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)
+               ah->txok_interrupt_mask |= 1 << q;
+       else
+               ah->txok_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
+               ah->txerr_interrupt_mask |= 1 << q;
+       else
+               ah->txerr_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
+               ah->txdesc_interrupt_mask |= 1 << q;
+       else
+               ah->txdesc_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
+               ah->txeol_interrupt_mask |= 1 << q;
+       else
+               ah->txeol_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
+               ah->txurn_interrupt_mask |= 1 << q;
+       else
+               ah->txurn_interrupt_mask &= ~(1 << q);
+       ath9k_hw_set_txq_interrupts(ah, qi);
+
+       return true;
+}
+
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
+                       u32 pa, struct ath_desc *nds, u64 tsf)
+{
+       struct ar5416_desc ads;
+       struct ar5416_desc *adsp = AR5416DESC(ds);
+       u32 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 = phyerr;
+               } 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;
+}
+
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                         u32 size, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       struct ath9k_hw_capabilities *pCap = &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))
+               memset(&(ads->u), 0, sizeof(ads->u));
+
+       return true;
+}
+
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
+{
+       u32 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, AH_WAIT_TIMEOUT)) {
+                       REG_CLR_BIT(ah, AR_DIAG_SW,
+                                   (AR_DIAG_RX_DIS |
+                                    AR_DIAG_RX_ABORT));
+
+                       reg = REG_READ(ah, AR_OBS_BUS_1);
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "RX failed to go idle in 10 ms RXSM=0x%x\n", reg);
+
+                       return false;
+               }
+       } else {
+               REG_CLR_BIT(ah, AR_DIAG_SW,
+                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+       }
+
+       return true;
+}
+
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
+{
+       REG_WRITE(ah, AR_RXDP, rxdp);
+}
+
+void ath9k_hw_rxena(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_CR, AR_CR_RXE);
+}
+
+void ath9k_hw_startpcureceive(struct ath_hw *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_hw *ah)
+{
+       REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
+
+       ath9k_hw_disable_mib_counters(ah);
+}
+
+bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
+{
+#define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
+#define AH_RX_TIME_QUANTUM     100     /* usec */
+
+       int i;
+
+       REG_WRITE(ah, AR_CR, AR_CR_RXD);
+
+       /* Wait for rx enable bit to go low */
+       for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
+               if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
+                       break;
+               udelay(AH_TIME_QUANTUM);
+       }
+
+       if (i == 0) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "DMA failed to stop in %d ms "
+                       "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
+                       AH_RX_STOP_DMA_TIMEOUT / 1000,
+                       REG_READ(ah, AR_CR),
+                       REG_READ(ah, AR_DIAG_SW));
+               return false;
+       } else {
+               return true;
+       }
+
+#undef AH_RX_TIME_QUANTUM
+#undef AH_RX_STOP_DMA_TIMEOUT
+}
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
new file mode 100644 (file)
index 0000000..1176bce
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ * Copyright (c) 2008-2009 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 MAC_H
+#define MAC_H
+
+#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_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 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
+
+#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 ATH9K_SLOT_TIME_6 6
+#define ATH9K_SLOT_TIME_9 9
+#define ATH9K_SLOT_TIME_20 20
+
+#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
+
+#define MIN_TX_FIFO_THRESHOLD   0x1
+#define MAX_TX_FIFO_THRESHOLD   ((4096 / 64) - 1)
+#define INIT_TX_FIFO_THRESHOLD  MIN_TX_FIFO_THRESHOLD
+
+struct ath_tx_status {
+       u32 ts_tstamp;
+       u16 ts_seqnum;
+       u8 ts_status;
+       u8 ts_ratecode;
+       u8 ts_rateindex;
+       int8_t ts_rssi;
+       u8 ts_shortretry;
+       u8 ts_longretry;
+       u8 ts_virtcol;
+       u8 ts_antenna;
+       u8 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;
+       u8 pad[3];
+       u32 ba_low;
+       u32 ba_high;
+       u32 evm0;
+       u32 evm1;
+       u32 evm2;
+};
+
+struct ath_rx_status {
+       u32 rs_tstamp;
+       u16 rs_datalen;
+       u8 rs_status;
+       u8 rs_phyerr;
+       int8_t rs_rssi;
+       u8 rs_keyix;
+       u8 rs_rate;
+       u8 rs_antenna;
+       u8 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;
+       u8 rs_isaggr;
+       u8 rs_moreaggr;
+       u8 rs_num_delims;
+       u8 rs_flags;
+       u32 evm0;
+       u32 evm1;
+       u32 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  ((u8)-1)
+#define ATH9K_TXKEYIX_INVALID  ((u32)-1)
+
+struct ath_desc {
+       u32 ds_link;
+       u32 ds_data;
+       u32 ds_ctl0;
+       u32 ds_ctl1;
+       u32 ds_hw[20];
+       union {
+               struct ath_tx_status tx;
+               struct ath_rx_status rx;
+               void *stats;
+       } ds_us;
+       void *ds_vdata;
+} __packed;
+
+#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
+
+struct ar5416_desc {
+       u32 ds_link;
+       u32 ds_data;
+       u32 ds_ctl0;
+       u32 ds_ctl1;
+       union {
+               struct {
+                       u32 ctl2;
+                       u32 ctl3;
+                       u32 ctl4;
+                       u32 ctl5;
+                       u32 ctl6;
+                       u32 ctl7;
+                       u32 ctl8;
+                       u32 ctl9;
+                       u32 ctl10;
+                       u32 ctl11;
+                       u32 status0;
+                       u32 status1;
+                       u32 status2;
+                       u32 status3;
+                       u32 status4;
+                       u32 status5;
+                       u32 status6;
+                       u32 status7;
+                       u32 status8;
+                       u32 status9;
+               } tx;
+               struct {
+                       u32 status0;
+                       u32 status1;
+                       u32 status2;
+                       u32 status3;
+                       u32 status4;
+                       u32 status5;
+                       u32 status6;
+                       u32 status7;
+                       u32 status8;
+               } rx;
+       } u;
+} __packed;
+
+#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
+
+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 ((u32) -1)
+#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
+
+#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 {
+       u32 tqi_ver;
+       enum ath9k_tx_queue tqi_type;
+       enum ath9k_tx_queue_subtype tqi_subtype;
+       enum ath9k_tx_queue_flags tqi_qflags;
+       u32 tqi_priority;
+       u32 tqi_aifs;
+       u32 tqi_cwmin;
+       u32 tqi_cwmax;
+       u16 tqi_shretry;
+       u16 tqi_lgretry;
+       u32 tqi_cbrPeriod;
+       u32 tqi_cbrOverflowLimit;
+       u32 tqi_burstTime;
+       u32 tqi_readyTime;
+       u32 tqi_physCompBuf;
+       u32 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_PHYERR = 0x00000100,
+       ATH9K_RX_FILTER_MYBEACON = 0x00000200,
+       ATH9K_RX_FILTER_PSPOLL = 0x00004000,
+       ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
+       ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
+};
+
+#define ATH9K_RATESERIES_RTS_CTS  0x0001
+#define ATH9K_RATESERIES_2040     0x0002
+#define ATH9K_RATESERIES_HALFGI   0x0004
+
+struct ath9k_11n_rate_series {
+       u32 Tries;
+       u32 Rate;
+       u32 PktDuration;
+       u32 ChSel;
+       u32 RateFlags;
+};
+
+struct ath9k_keyval {
+       u8 kv_type;
+       u8 kv_pad;
+       u16 kv_len;
+       u8 kv_val[16]; /* TK */
+       u8 kv_mic[8]; /* Michael MIC key */
+       u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
+                        * supports both MIC keys in the same key cache entry;
+                        * in that case, kv_mic is the RX key) */
+};
+
+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
+};
+
+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 ath_hw;
+struct ath9k_channel;
+struct ath_rate_table;
+
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q);
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                        u32 segLen, bool firstSeg,
+                        bool lastSeg, const struct ath_desc *ds0);
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
+int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
+                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
+                           u32 keyIx, enum ath9k_key_type keyType, u32 flags);
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
+                                 struct ath_desc *lastds,
+                                 u32 durUpdateEn, u32 rtsctsRate,
+                                 u32 rtsctsDuration,
+                                 struct ath9k_11n_rate_series series[],
+                                 u32 nseries, u32 flags);
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
+                               u32 aggrLen);
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
+                                u32 numDelims);
+void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
+                                  u32 burstDuration);
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
+                                    u32 vmf);
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+                           const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
+                           struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
+                         const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
+                       u32 pa, struct ath_desc *nds, u64 tsf);
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                         u32 size, u32 flags);
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
+void ath9k_hw_rxena(struct ath_hw *ah);
+void ath9k_hw_startpcureceive(struct ath_hw *ah);
+void ath9k_hw_stoppcurecv(struct ath_hw *ah);
+bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
+
+#endif /* MAC_H */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
new file mode 100644 (file)
index 0000000..8b6a7ea
--- /dev/null
@@ -0,0 +1,2890 @@
+/*
+ * Copyright (c) 2008-2009 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 <linux/nl80211.h>
+#include "ath9k.h"
+
+#define ATH_PCI_VERSION "0.1"
+
+static char *dev_info = "ath9k";
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
+MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
+
+/* We use the hw_value as an index into our private channel structure */
+
+#define CHAN2G(_freq, _idx)  { \
+       .center_freq = (_freq), \
+       .hw_value = (_idx), \
+       .max_power = 30, \
+}
+
+#define CHAN5G(_freq, _idx) { \
+       .band = IEEE80211_BAND_5GHZ, \
+       .center_freq = (_freq), \
+       .hw_value = (_idx), \
+       .max_power = 30, \
+}
+
+/* Some 2 GHz radios are actually tunable on 2312-2732
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_2ghz_chantable[] = {
+       CHAN2G(2412, 0), /* Channel 1 */
+       CHAN2G(2417, 1), /* Channel 2 */
+       CHAN2G(2422, 2), /* Channel 3 */
+       CHAN2G(2427, 3), /* Channel 4 */
+       CHAN2G(2432, 4), /* Channel 5 */
+       CHAN2G(2437, 5), /* Channel 6 */
+       CHAN2G(2442, 6), /* Channel 7 */
+       CHAN2G(2447, 7), /* Channel 8 */
+       CHAN2G(2452, 8), /* Channel 9 */
+       CHAN2G(2457, 9), /* Channel 10 */
+       CHAN2G(2462, 10), /* Channel 11 */
+       CHAN2G(2467, 11), /* Channel 12 */
+       CHAN2G(2472, 12), /* Channel 13 */
+       CHAN2G(2484, 13), /* Channel 14 */
+};
+
+/* Some 5 GHz radios are actually tunable on XXXX-YYYY
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_5ghz_chantable[] = {
+       /* _We_ call this UNII 1 */
+       CHAN5G(5180, 14), /* Channel 36 */
+       CHAN5G(5200, 15), /* Channel 40 */
+       CHAN5G(5220, 16), /* Channel 44 */
+       CHAN5G(5240, 17), /* Channel 48 */
+       /* _We_ call this UNII 2 */
+       CHAN5G(5260, 18), /* Channel 52 */
+       CHAN5G(5280, 19), /* Channel 56 */
+       CHAN5G(5300, 20), /* Channel 60 */
+       CHAN5G(5320, 21), /* Channel 64 */
+       /* _We_ call this "Middle band" */
+       CHAN5G(5500, 22), /* Channel 100 */
+       CHAN5G(5520, 23), /* Channel 104 */
+       CHAN5G(5540, 24), /* Channel 108 */
+       CHAN5G(5560, 25), /* Channel 112 */
+       CHAN5G(5580, 26), /* Channel 116 */
+       CHAN5G(5600, 27), /* Channel 120 */
+       CHAN5G(5620, 28), /* Channel 124 */
+       CHAN5G(5640, 29), /* Channel 128 */
+       CHAN5G(5660, 30), /* Channel 132 */
+       CHAN5G(5680, 31), /* Channel 136 */
+       CHAN5G(5700, 32), /* Channel 140 */
+       /* _We_ call this UNII 3 */
+       CHAN5G(5745, 33), /* Channel 149 */
+       CHAN5G(5765, 34), /* Channel 153 */
+       CHAN5G(5785, 35), /* Channel 157 */
+       CHAN5G(5805, 36), /* Channel 161 */
+       CHAN5G(5825, 37), /* Channel 165 */
+};
+
+static void ath_cache_conf_rate(struct ath_softc *sc,
+                               struct ieee80211_conf *conf)
+{
+       switch (conf->channel->band) {
+       case IEEE80211_BAND_2GHZ:
+               if (conf_is_ht20(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
+               else if (conf_is_ht40_minus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
+               else if (conf_is_ht40_plus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
+               else
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11G];
+               break;
+       case IEEE80211_BAND_5GHZ:
+               if (conf_is_ht20(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
+               else if (conf_is_ht40_minus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
+               else if (conf_is_ht40_plus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
+               else
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11A];
+               break;
+       default:
+               BUG_ON(1);
+               break;
+       }
+}
+
+static void ath_update_txpow(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       u32 txpow;
+
+       if (sc->curtxpow != sc->config.txpowlimit) {
+               ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
+               /* read back in case value is clamped */
+               ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
+               sc->curtxpow = txpow;
+       }
+}
+
+static u8 parse_mpdudensity(u8 mpdudensity)
+{
+       /*
+        * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
+        *   0 for no restriction
+        *   1 for 1/4 us
+        *   2 for 1/2 us
+        *   3 for 1 us
+        *   4 for 2 us
+        *   5 for 4 us
+        *   6 for 8 us
+        *   7 for 16 us
+        */
+       switch (mpdudensity) {
+       case 0:
+               return 0;
+       case 1:
+       case 2:
+       case 3:
+               /* Our lower layer calculations limit our precision to
+                  1 microsecond */
+               return 1;
+       case 4:
+               return 2;
+       case 5:
+               return 4;
+       case 6:
+               return 8;
+       case 7:
+               return 16;
+       default:
+               return 0;
+       }
+}
+
+static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
+{
+       struct ath_rate_table *rate_table = NULL;
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_rate *rate;
+       int i, maxrates;
+
+       switch (band) {
+       case IEEE80211_BAND_2GHZ:
+               rate_table = sc->hw_rate_table[ATH9K_MODE_11G];
+               break;
+       case IEEE80211_BAND_5GHZ:
+               rate_table = sc->hw_rate_table[ATH9K_MODE_11A];
+               break;
+       default:
+               break;
+       }
+
+       if (rate_table == NULL)
+               return;
+
+       sband = &sc->sbands[band];
+       rate = sc->rates[band];
+
+       if (rate_table->rate_cnt > ATH_RATE_MAX)
+               maxrates = ATH_RATE_MAX;
+       else
+               maxrates = rate_table->rate_cnt;
+
+       for (i = 0; i < maxrates; i++) {
+               rate[i].bitrate = rate_table->info[i].ratekbps / 100;
+               rate[i].hw_value = rate_table->info[i].ratecode;
+               if (rate_table->info[i].short_preamble) {
+                       rate[i].hw_value_short = rate_table->info[i].ratecode |
+                               rate_table->info[i].short_preamble;
+                       rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE;
+               }
+               sband->n_bitrates++;
+
+               DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n",
+                       rate[i].bitrate / 10, rate[i].hw_value);
+       }
+}
+
+/*
+ * 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.
+*/
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                   struct ath9k_channel *hchan)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       bool fastcc = true, stopped;
+       struct ieee80211_channel *channel = hw->conf.channel;
+       int r;
+
+       if (sc->sc_flags & SC_OP_INVALID)
+               return -EIO;
+
+       ath9k_ps_wakeup(sc);
+
+       /*
+        * 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.
+        */
+       ath9k_hw_set_interrupts(ah, 0);
+       ath_drain_all_txq(sc, false);
+       stopped = ath_stoprecv(sc);
+
+       /* 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 = false;
+
+       DPRINTF(sc, ATH_DBG_CONFIG,
+               "(%u MHz) -> (%u MHz), chanwidth: %d\n",
+               sc->sc_ah->curchan->channel,
+               channel->center_freq, sc->tx_chan_width);
+
+       spin_lock_bh(&sc->sc_resetlock);
+
+       r = ath9k_hw_reset(ah, hchan, fastcc);
+       if (r) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset channel (%u Mhz) "
+                       "reset status %u\n",
+                       channel->center_freq, r);
+               spin_unlock_bh(&sc->sc_resetlock);
+               return r;
+       }
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       sc->sc_flags &= ~SC_OP_FULL_RESET;
+
+       if (ath_startrecv(sc) != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to restart recv logic\n");
+               return -EIO;
+       }
+
+       ath_cache_conf_rate(sc, &hw->conf);
+       ath_update_txpow(sc);
+       ath9k_hw_set_interrupts(ah, sc->imask);
+       ath9k_ps_restore(sc);
+       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 ath_ani_calibrate(unsigned long data)
+{
+       struct ath_softc *sc = (struct ath_softc *)data;
+       struct ath_hw *ah = sc->sc_ah;
+       bool longcal = false;
+       bool shortcal = false;
+       bool aniflag = false;
+       unsigned int timestamp = jiffies_to_msecs(jiffies);
+       u32 cal_interval, short_cal_interval;
+
+       short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
+               ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
+
+       /*
+       * don't calibrate when we're scanning.
+       * we are most likely not on our home channel.
+       */
+       if (sc->sc_flags & SC_OP_SCANNING)
+               goto set_timer;
+
+       /* Long calibration runs independently of short calibration. */
+       if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
+               longcal = true;
+               DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
+               sc->ani.longcal_timer = timestamp;
+       }
+
+       /* Short calibration applies only while caldone is false */
+       if (!sc->ani.caldone) {
+               if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) {
+                       shortcal = true;
+                       DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies);
+                       sc->ani.shortcal_timer = timestamp;
+                       sc->ani.resetcal_timer = timestamp;
+               }
+       } else {
+               if ((timestamp - sc->ani.resetcal_timer) >=
+                   ATH_RESTART_CALINTERVAL) {
+                       sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
+                       if (sc->ani.caldone)
+                               sc->ani.resetcal_timer = timestamp;
+               }
+       }
+
+       /* Verify whether we must check ANI */
+       if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
+               aniflag = true;
+               sc->ani.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->nodestats, ah->curchan);
+
+               /* Perform calibration if necessary */
+               if (longcal || shortcal) {
+                       bool iscaldone = false;
+
+                       if (ath9k_hw_calibrate(ah, ah->curchan,
+                                              sc->rx_chainmask, longcal,
+                                              &iscaldone)) {
+                               if (longcal)
+                                       sc->ani.noise_floor =
+                                               ath9k_hw_getchan_noise(ah,
+                                                              ah->curchan);
+
+                               DPRINTF(sc, ATH_DBG_ANI,
+                                       "calibrate chan %u/%x nf: %d\n",
+                                       ah->curchan->channel,
+                                       ah->curchan->channelFlags,
+                                       sc->ani.noise_floor);
+                       } else {
+                               DPRINTF(sc, ATH_DBG_ANY,
+                                       "calibrate chan %u/%x failed\n",
+                                       ah->curchan->channel,
+                                       ah->curchan->channelFlags);
+                       }
+                       sc->ani.caldone = iscaldone;
+               }
+       }
+
+set_timer:
+       /*
+       * 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->config.enable_ani)
+               cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
+       if (!sc->ani.caldone)
+               cal_interval = min(cal_interval, (u32)short_cal_interval);
+
+       mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+}
+
+/*
+ * Update tx/rx chainmask. For legacy association,
+ * hard code chainmask to 1x1, for 11n association, use
+ * the chainmask configuration, for bt coexistence, use
+ * the chainmask configuration even in legacy mode.
+ */
+void ath_update_chainmask(struct ath_softc *sc, int is_ht)
+{
+       if (is_ht ||
+           (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
+               sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
+               sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
+       } else {
+               sc->tx_chainmask = 1;
+               sc->rx_chainmask = 1;
+       }
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
+               sc->tx_chainmask, sc->rx_chainmask);
+}
+
+static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
+{
+       struct ath_node *an;
+
+       an = (struct ath_node *)sta->drv_priv;
+
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               ath_tx_node_init(sc, an);
+               an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
+                                    sta->ht_cap.ampdu_factor);
+               an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
+       }
+}
+
+static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
+{
+       struct ath_node *an = (struct ath_node *)sta->drv_priv;
+
+       if (sc->sc_flags & SC_OP_TXAGGR)
+               ath_tx_node_cleanup(sc, an);
+}
+
+static void ath9k_tasklet(unsigned long data)
+{
+       struct ath_softc *sc = (struct ath_softc *)data;
+       u32 status = sc->intrstatus;
+
+       if (status & ATH9K_INT_FATAL) {
+               ath_reset(sc, false);
+               return;
+       }
+
+       if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
+               spin_lock_bh(&sc->rx.rxflushlock);
+               ath_rx_tasklet(sc, 0);
+               spin_unlock_bh(&sc->rx.rxflushlock);
+       }
+
+       if (status & ATH9K_INT_TX)
+               ath_tx_tasklet(sc);
+
+       /* re-enable hardware interrupt */
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+}
+
+irqreturn_t ath_isr(int irq, void *dev)
+{
+#define SCHED_INTR (                           \
+               ATH9K_INT_FATAL |               \
+               ATH9K_INT_RXORN |               \
+               ATH9K_INT_RXEOL |               \
+               ATH9K_INT_RX |                  \
+               ATH9K_INT_TX |                  \
+               ATH9K_INT_BMISS |               \
+               ATH9K_INT_CST |                 \
+               ATH9K_INT_TSFOOR)
+
+       struct ath_softc *sc = dev;
+       struct ath_hw *ah = sc->sc_ah;
+       enum ath9k_int status;
+       bool sched = false;
+
+       /*
+        * The hardware is not ready/present, don't
+        * touch anything. Note this can happen early
+        * on if the IRQ is shared.
+        */
+       if (sc->sc_flags & SC_OP_INVALID)
+               return IRQ_NONE;
+
+       ath9k_ps_wakeup(sc);
+
+       /* shared irq, not for us */
+
+       if (!ath9k_hw_intrpend(ah)) {
+               ath9k_ps_restore(sc);
+               return IRQ_NONE;
+       }
+
+       /*
+        * 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.
+        */
+       ath9k_hw_getisr(ah, &status);   /* NB: clears ISR too */
+       status &= 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) {
+               ath9k_ps_restore(sc);
+               return IRQ_NONE;
+       }
+
+       /* Cache the status */
+       sc->intrstatus = status;
+
+       if (status & SCHED_INTR)
+               sched = true;
+
+       /*
+        * If a FATAL or RXORN interrupt is received, we have to reset the
+        * chip immediately.
+        */
+       if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN))
+               goto chip_reset;
+
+       if (status & ATH9K_INT_SWBA)
+               tasklet_schedule(&sc->bcon_tasklet);
+
+       if (status & ATH9K_INT_TXURN)
+               ath9k_hw_updatetxtriglevel(ah, true);
+
+       if (status & ATH9K_INT_MIB) {
+               /*
+                * Disable interrupts until we service the MIB
+                * interrupt; otherwise it will continue to
+                * fire.
+                */
+               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->nodestats);
+               ath9k_hw_set_interrupts(ah, sc->imask);
+       }
+
+       if (status & ATH9K_INT_TIM_TIMER) {
+               if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+                       /* Clear RxAbort bit so that we can
+                        * receive frames */
+                       ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
+                       ath9k_hw_setrxabort(ah, 0);
+                       sched = true;
+                       sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
+               }
+       }
+
+chip_reset:
+
+       ath9k_ps_restore(sc);
+       ath_debug_stat_interrupt(sc, status);
+
+       if (sched) {
+               /* turn off every interrupt except SWBA */
+               ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA));
+               tasklet_schedule(&sc->intr_tq);
+       }
+
+       return IRQ_HANDLED;
+
+#undef SCHED_INTR
+}
+
+static u32 ath_get_extchanmode(struct ath_softc *sc,
+                              struct ieee80211_channel *chan,
+                              enum nl80211_channel_type channel_type)
+{
+       u32 chanmode = 0;
+
+       switch (chan->band) {
+       case IEEE80211_BAND_2GHZ:
+               switch(channel_type) {
+               case NL80211_CHAN_NO_HT:
+               case NL80211_CHAN_HT20:
+                       chanmode = CHANNEL_G_HT20;
+                       break;
+               case NL80211_CHAN_HT40PLUS:
+                       chanmode = CHANNEL_G_HT40PLUS;
+                       break;
+               case NL80211_CHAN_HT40MINUS:
+                       chanmode = CHANNEL_G_HT40MINUS;
+                       break;
+               }
+               break;
+       case IEEE80211_BAND_5GHZ:
+               switch(channel_type) {
+               case NL80211_CHAN_NO_HT:
+               case NL80211_CHAN_HT20:
+                       chanmode = CHANNEL_A_HT20;
+                       break;
+               case NL80211_CHAN_HT40PLUS:
+                       chanmode = CHANNEL_A_HT40PLUS;
+                       break;
+               case NL80211_CHAN_HT40MINUS:
+                       chanmode = CHANNEL_A_HT40MINUS;
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return chanmode;
+}
+
+static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
+                          struct ath9k_keyval *hk, const u8 *addr,
+                          bool authenticator)
+{
+       const u8 *key_rxmic;
+       const u8 *key_txmic;
+
+       key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
+       key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
+
+       if (addr == NULL) {
+               /*
+                * Group key installation - only two key cache entries are used
+                * regardless of splitmic capability since group key is only
+                * used either for TX or RX.
+                */
+               if (authenticator) {
+                       memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+                       memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
+               } else {
+                       memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+                       memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
+               }
+               return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
+       }
+       if (!sc->splitmic) {
+               /* TX and RX keys share the same key cache entry. */
+               memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+               memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
+               return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
+       }
+
+       /* Separate key cache entries for TX and RX */
+
+       /* TX key goes at first index, RX key at +32. */
+       memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+       if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
+               /* TX MIC entry failed. No need to proceed further */
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Setting TX MIC Key Failed\n");
+               return 0;
+       }
+
+       memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+       /* XXX delete tx key on failure? */
+       return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr);
+}
+
+static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
+{
+       int i;
+
+       for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+               if (test_bit(i, sc->keymap) ||
+                   test_bit(i + 64, sc->keymap))
+                       continue; /* At least one part of TKIP key allocated */
+               if (sc->splitmic &&
+                   (test_bit(i + 32, sc->keymap) ||
+                    test_bit(i + 64 + 32, sc->keymap)))
+                       continue; /* At least one part of TKIP key allocated */
+
+               /* Found a free slot for a TKIP key */
+               return i;
+       }
+       return -1;
+}
+
+static int ath_reserve_key_cache_slot(struct ath_softc *sc)
+{
+       int i;
+
+       /* First, try to find slots that would not be available for TKIP. */
+       if (sc->splitmic) {
+               for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) {
+                       if (!test_bit(i, sc->keymap) &&
+                           (test_bit(i + 32, sc->keymap) ||
+                            test_bit(i + 64, sc->keymap) ||
+                            test_bit(i + 64 + 32, sc->keymap)))
+                               return i;
+                       if (!test_bit(i + 32, sc->keymap) &&
+                           (test_bit(i, sc->keymap) ||
+                            test_bit(i + 64, sc->keymap) ||
+                            test_bit(i + 64 + 32, sc->keymap)))
+                               return i + 32;
+                       if (!test_bit(i + 64, sc->keymap) &&
+                           (test_bit(i , sc->keymap) ||
+                            test_bit(i + 32, sc->keymap) ||
+                            test_bit(i + 64 + 32, sc->keymap)))
+                               return i + 64;
+                       if (!test_bit(i + 64 + 32, sc->keymap) &&
+                           (test_bit(i, sc->keymap) ||
+                            test_bit(i + 32, sc->keymap) ||
+                            test_bit(i + 64, sc->keymap)))
+                               return i + 64 + 32;
+               }
+       } else {
+               for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+                       if (!test_bit(i, sc->keymap) &&
+                           test_bit(i + 64, sc->keymap))
+                               return i;
+                       if (test_bit(i, sc->keymap) &&
+                           !test_bit(i + 64, sc->keymap))
+                               return i + 64;
+               }
+       }
+
+       /* No partially used TKIP slots, pick any available slot */
+       for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) {
+               /* Do not allow slots that could be needed for TKIP group keys
+                * to be used. This limitation could be removed if we know that
+                * TKIP will not be used. */
+               if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
+                       continue;
+               if (sc->splitmic) {
+                       if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
+                               continue;
+                       if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
+                               continue;
+               }
+
+               if (!test_bit(i, sc->keymap))
+                       return i; /* Found a free slot for a key */
+       }
+
+       /* No free slot found */
+       return -1;
+}
+
+static int ath_key_config(struct ath_softc *sc,
+                         struct ieee80211_vif *vif,
+                         struct ieee80211_sta *sta,
+                         struct ieee80211_key_conf *key)
+{
+       struct ath9k_keyval hk;
+       const u8 *mac = NULL;
+       int ret = 0;
+       int idx;
+
+       memset(&hk, 0, sizeof(hk));
+
+       switch (key->alg) {
+       case ALG_WEP:
+               hk.kv_type = ATH9K_CIPHER_WEP;
+               break;
+       case ALG_TKIP:
+               hk.kv_type = ATH9K_CIPHER_TKIP;
+               break;
+       case ALG_CCMP:
+               hk.kv_type = ATH9K_CIPHER_AES_CCM;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       hk.kv_len = key->keylen;
+       memcpy(hk.kv_val, key->key, key->keylen);
+
+       if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+               /* For now, use the default keys for broadcast keys. This may
+                * need to change with virtual interfaces. */
+               idx = key->keyidx;
+       } else if (key->keyidx) {
+               if (WARN_ON(!sta))
+                       return -EOPNOTSUPP;
+               mac = sta->addr;
+
+               if (vif->type != NL80211_IFTYPE_AP) {
+                       /* Only keyidx 0 should be used with unicast key, but
+                        * allow this for client mode for now. */
+                       idx = key->keyidx;
+               } else
+                       return -EIO;
+       } else {
+               if (WARN_ON(!sta))
+                       return -EOPNOTSUPP;
+               mac = sta->addr;
+
+               if (key->alg == ALG_TKIP)
+                       idx = ath_reserve_key_cache_slot_tkip(sc);
+               else
+                       idx = ath_reserve_key_cache_slot(sc);
+               if (idx < 0)
+                       return -ENOSPC; /* no free key cache entries */
+       }
+
+       if (key->alg == ALG_TKIP)
+               ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac,
+                                     vif->type == NL80211_IFTYPE_AP);
+       else
+               ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac);
+
+       if (!ret)
+               return -EIO;
+
+       set_bit(idx, sc->keymap);
+       if (key->alg == ALG_TKIP) {
+               set_bit(idx + 64, sc->keymap);
+               if (sc->splitmic) {
+                       set_bit(idx + 32, sc->keymap);
+                       set_bit(idx + 64 + 32, sc->keymap);
+               }
+       }
+
+       return idx;
+}
+
+static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
+{
+       ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx);
+       if (key->hw_key_idx < IEEE80211_WEP_NKID)
+               return;
+
+       clear_bit(key->hw_key_idx, sc->keymap);
+       if (key->alg != ALG_TKIP)
+               return;
+
+       clear_bit(key->hw_key_idx + 64, sc->keymap);
+       if (sc->splitmic) {
+               clear_bit(key->hw_key_idx + 32, sc->keymap);
+               clear_bit(key->hw_key_idx + 64 + 32, sc->keymap);
+       }
+}
+
+static void setup_ht_cap(struct ath_softc *sc,
+                        struct ieee80211_sta_ht_cap *ht_info)
+{
+#define        ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3       /* 2 ^ 16 */
+#define        ATH9K_HT_CAP_MPDUDENSITY_8 0x6          /* 8 usec */
+
+       ht_info->ht_supported = true;
+       ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+                      IEEE80211_HT_CAP_SM_PS |
+                      IEEE80211_HT_CAP_SGI_40 |
+                      IEEE80211_HT_CAP_DSSSCCK40;
+
+       ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
+       ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
+
+       /* set up supported mcs set */
+       memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
+
+       switch(sc->rx_chainmask) {
+       case 1:
+               ht_info->mcs.rx_mask[0] = 0xff;
+               break;
+       case 3:
+       case 5:
+       case 7:
+       default:
+               ht_info->mcs.rx_mask[0] = 0xff;
+               ht_info->mcs.rx_mask[1] = 0xff;
+               break;
+       }
+
+       ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+}
+
+static void ath9k_bss_assoc_info(struct ath_softc *sc,
+                                struct ieee80211_vif *vif,
+                                struct ieee80211_bss_conf *bss_conf)
+{
+       struct ath_vif *avp = (void *)vif->drv_priv;
+
+       if (bss_conf->assoc) {
+               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
+                       bss_conf->aid, sc->curbssid);
+
+               /* New association, store aid */
+               if (avp->av_opmode == NL80211_IFTYPE_STATION) {
+                       sc->curaid = bss_conf->aid;
+                       ath9k_hw_write_associd(sc);
+               }
+
+               /* Configure the beacon */
+               ath_beacon_config(sc, vif);
+
+               /* Reset rssi stats */
+               sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
+               sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
+               sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
+               sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
+
+               /* Start ANI */
+               mod_timer(&sc->ani.timer,
+                         jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+       } else {
+               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
+               sc->curaid = 0;
+       }
+}
+
+/********************************/
+/*      LED functions          */
+/********************************/
+
+static void ath_led_blink_work(struct work_struct *work)
+{
+       struct ath_softc *sc = container_of(work, struct ath_softc,
+                                           ath_led_blink_work.work);
+
+       if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
+               return;
+
+       if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
+           (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
+               ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+       else
+               ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+                                 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
+
+       queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
+                          (sc->sc_flags & SC_OP_LED_ON) ?
+                          msecs_to_jiffies(sc->led_off_duration) :
+                          msecs_to_jiffies(sc->led_on_duration));
+
+       sc->led_on_duration = sc->led_on_cnt ?
+                       max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
+                       ATH_LED_ON_DURATION_IDLE;
+       sc->led_off_duration = sc->led_off_cnt ?
+                       max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
+                       ATH_LED_OFF_DURATION_IDLE;
+       sc->led_on_cnt = sc->led_off_cnt = 0;
+       if (sc->sc_flags & SC_OP_LED_ON)
+               sc->sc_flags &= ~SC_OP_LED_ON;
+       else
+               sc->sc_flags |= SC_OP_LED_ON;
+}
+
+static void ath_led_brightness(struct led_classdev *led_cdev,
+                              enum led_brightness brightness)
+{
+       struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
+       struct ath_softc *sc = led->sc;
+
+       switch (brightness) {
+       case LED_OFF:
+               if (led->led_type == ATH_LED_ASSOC ||
+                   led->led_type == ATH_LED_RADIO) {
+                       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+                               (led->led_type == ATH_LED_RADIO));
+                       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
+                       if (led->led_type == ATH_LED_RADIO)
+                               sc->sc_flags &= ~SC_OP_LED_ON;
+               } else {
+                       sc->led_off_cnt++;
+               }
+               break;
+       case LED_FULL:
+               if (led->led_type == ATH_LED_ASSOC) {
+                       sc->sc_flags |= SC_OP_LED_ASSOCIATED;
+                       queue_delayed_work(sc->hw->workqueue,
+                                          &sc->ath_led_blink_work, 0);
+               } else if (led->led_type == ATH_LED_RADIO) {
+                       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+                       sc->sc_flags |= SC_OP_LED_ON;
+               } else {
+                       sc->led_on_cnt++;
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
+                           char *trigger)
+{
+       int ret;
+
+       led->sc = sc;
+       led->led_cdev.name = led->name;
+       led->led_cdev.default_trigger = trigger;
+       led->led_cdev.brightness_set = ath_led_brightness;
+
+       ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
+       if (ret)
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Failed to register led:%s", led->name);
+       else
+               led->registered = 1;
+       return ret;
+}
+
+static void ath_unregister_led(struct ath_led *led)
+{
+       if (led->registered) {
+               led_classdev_unregister(&led->led_cdev);
+               led->registered = 0;
+       }
+}
+
+static void ath_deinit_leds(struct ath_softc *sc)
+{
+       cancel_delayed_work_sync(&sc->ath_led_blink_work);
+       ath_unregister_led(&sc->assoc_led);
+       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
+       ath_unregister_led(&sc->tx_led);
+       ath_unregister_led(&sc->rx_led);
+       ath_unregister_led(&sc->radio_led);
+       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+}
+
+static void ath_init_leds(struct ath_softc *sc)
+{
+       char *trigger;
+       int ret;
+
+       /* Configure gpio 1 for output */
+       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+       /* LED off, active low */
+       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+       INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
+
+       trigger = ieee80211_get_radio_led_name(sc->hw);
+       snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
+               "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
+       ret = ath_register_led(sc, &sc->radio_led, trigger);
+       sc->radio_led.led_type = ATH_LED_RADIO;
+       if (ret)
+               goto fail;
+
+       trigger = ieee80211_get_assoc_led_name(sc->hw);
+       snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
+               "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
+       ret = ath_register_led(sc, &sc->assoc_led, trigger);
+       sc->assoc_led.led_type = ATH_LED_ASSOC;
+       if (ret)
+               goto fail;
+
+       trigger = ieee80211_get_tx_led_name(sc->hw);
+       snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
+               "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
+       ret = ath_register_led(sc, &sc->tx_led, trigger);
+       sc->tx_led.led_type = ATH_LED_TX;
+       if (ret)
+               goto fail;
+
+       trigger = ieee80211_get_rx_led_name(sc->hw);
+       snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
+               "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
+       ret = ath_register_led(sc, &sc->rx_led, trigger);
+       sc->rx_led.led_type = ATH_LED_RX;
+       if (ret)
+               goto fail;
+
+       return;
+
+fail:
+       ath_deinit_leds(sc);
+}
+
+void ath_radio_enable(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ieee80211_channel *channel = sc->hw->conf.channel;
+       int r;
+
+       ath9k_ps_wakeup(sc);
+       spin_lock_bh(&sc->sc_resetlock);
+
+       r = ath9k_hw_reset(ah, ah->curchan, false);
+
+       if (r) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset channel %u (%uMhz) ",
+                       "reset status %u\n",
+                       channel->center_freq, r);
+       }
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       ath_update_txpow(sc);
+       if (ath_startrecv(sc) != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to restart recv logic\n");
+               return;
+       }
+
+       if (sc->sc_flags & SC_OP_BEACONS)
+               ath_beacon_config(sc, NULL);    /* restart beacons */
+
+       /* Re-Enable  interrupts */
+       ath9k_hw_set_interrupts(ah, sc->imask);
+
+       /* Enable LED */
+       ath9k_hw_cfg_output(ah, ATH_LED_PIN,
+                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+       ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
+
+       ieee80211_wake_queues(sc->hw);
+       ath9k_ps_restore(sc);
+}
+
+void ath_radio_disable(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ieee80211_channel *channel = sc->hw->conf.channel;
+       int r;
+
+       ath9k_ps_wakeup(sc);
+       ieee80211_stop_queues(sc->hw);
+
+       /* Disable LED */
+       ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1);
+       ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN);
+
+       /* Disable interrupts */
+       ath9k_hw_set_interrupts(ah, 0);
+
+       ath_drain_all_txq(sc, false);   /* clear pending tx frames */
+       ath_stoprecv(sc);               /* turn off frame recv */
+       ath_flushrecv(sc);              /* flush recv queue */
+
+       spin_lock_bh(&sc->sc_resetlock);
+       r = ath9k_hw_reset(ah, ah->curchan, false);
+       if (r) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset channel %u (%uMhz) "
+                       "reset status %u\n",
+                       channel->center_freq, r);
+       }
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       ath9k_hw_phy_disable(ah);
+       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+       ath9k_ps_restore(sc);
+}
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+
+/*******************/
+/*     Rfkill     */
+/*******************/
+
+static bool ath_is_rfkill_set(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+
+       return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
+                                 ah->rfkill_polarity;
+}
+
+/* h/w rfkill poll function */
+static void ath_rfkill_poll(struct work_struct *work)
+{
+       struct ath_softc *sc = container_of(work, struct ath_softc,
+                                           rf_kill.rfkill_poll.work);
+       bool radio_on;
+
+       if (sc->sc_flags & SC_OP_INVALID)
+               return;
+
+       radio_on = !ath_is_rfkill_set(sc);
+
+       /*
+        * enable/disable radio only when there is a
+        * state change in RF switch
+        */
+       if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) {
+               enum rfkill_state state;
+
+               if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) {
+                       state = radio_on ? RFKILL_STATE_SOFT_BLOCKED
+                               : RFKILL_STATE_HARD_BLOCKED;
+               } else if (radio_on) {
+                       ath_radio_enable(sc);
+                       state = RFKILL_STATE_UNBLOCKED;
+               } else {
+                       ath_radio_disable(sc);
+                       state = RFKILL_STATE_HARD_BLOCKED;
+               }
+
+               if (state == RFKILL_STATE_HARD_BLOCKED)
+                       sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED;
+               else
+                       sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED;
+
+               rfkill_force_state(sc->rf_kill.rfkill, state);
+       }
+
+       queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll,
+                          msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL));
+}
+
+/* s/w rfkill handler */
+static int ath_sw_toggle_radio(void *data, enum rfkill_state state)
+{
+       struct ath_softc *sc = data;
+
+       switch (state) {
+       case RFKILL_STATE_SOFT_BLOCKED:
+               if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED |
+                   SC_OP_RFKILL_SW_BLOCKED)))
+                       ath_radio_disable(sc);
+               sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED;
+               return 0;
+       case RFKILL_STATE_UNBLOCKED:
+               if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) {
+                       sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED;
+                       if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) {
+                               DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the"
+                                       "radio as it is disabled by h/w\n");
+                               return -EPERM;
+                       }
+                       ath_radio_enable(sc);
+               }
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+/* Init s/w rfkill */
+static int ath_init_sw_rfkill(struct ath_softc *sc)
+{
+       sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy),
+                                            RFKILL_TYPE_WLAN);
+       if (!sc->rf_kill.rfkill) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");
+               return -ENOMEM;
+       }
+
+       snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
+               "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
+       sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name;
+       sc->rf_kill.rfkill->data = sc;
+       sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio;
+       sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED;
+
+       return 0;
+}
+
+/* Deinitialize rfkill */
+static void ath_deinit_rfkill(struct ath_softc *sc)
+{
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
+
+       if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
+               rfkill_unregister(sc->rf_kill.rfkill);
+               sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED;
+               sc->rf_kill.rfkill = NULL;
+       }
+}
+
+static int ath_start_rfkill_poll(struct ath_softc *sc)
+{
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               queue_delayed_work(sc->hw->workqueue,
+                                  &sc->rf_kill.rfkill_poll, 0);
+
+       if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
+               if (rfkill_register(sc->rf_kill.rfkill)) {
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "Unable to register rfkill\n");
+                       rfkill_free(sc->rf_kill.rfkill);
+
+                       /* Deinitialize the device */
+                       ath_cleanup(sc);
+                       return -EIO;
+               } else {
+                       sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
+               }
+       }
+
+       return 0;
+}
+#endif /* CONFIG_RFKILL */
+
+void ath_cleanup(struct ath_softc *sc)
+{
+       ath_detach(sc);
+       free_irq(sc->irq, sc);
+       ath_bus_cleanup(sc);
+       kfree(sc->sec_wiphy);
+       ieee80211_free_hw(sc->hw);
+}
+
+void ath_detach(struct ath_softc *sc)
+{
+       struct ieee80211_hw *hw = sc->hw;
+       int i = 0;
+
+       ath9k_ps_wakeup(sc);
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       ath_deinit_rfkill(sc);
+#endif
+       ath_deinit_leds(sc);
+       cancel_work_sync(&sc->chan_work);
+       cancel_delayed_work_sync(&sc->wiphy_work);
+
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               struct ath_wiphy *aphy = sc->sec_wiphy[i];
+               if (aphy == NULL)
+                       continue;
+               sc->sec_wiphy[i] = NULL;
+               ieee80211_unregister_hw(aphy->hw);
+               ieee80211_free_hw(aphy->hw);
+       }
+       ieee80211_unregister_hw(hw);
+       ath_rx_cleanup(sc);
+       ath_tx_cleanup(sc);
+
+       tasklet_kill(&sc->intr_tq);
+       tasklet_kill(&sc->bcon_tasklet);
+
+       if (!(sc->sc_flags & SC_OP_INVALID))
+               ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+
+       /* cleanup tx queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+       ath9k_hw_detach(sc->sc_ah);
+       ath9k_exit_debug(sc);
+       ath9k_ps_restore(sc);
+}
+
+static int ath9k_reg_notifier(struct wiphy *wiphy,
+                             struct regulatory_request *request)
+{
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_regulatory *reg = &sc->sc_ah->regulatory;
+
+       return ath_reg_notifier_apply(wiphy, request, reg);
+}
+
+static int ath_init(u16 devid, struct ath_softc *sc)
+{
+       struct ath_hw *ah = NULL;
+       int status;
+       int error = 0, i;
+       int csz = 0;
+
+       /* XXX: hardware will not be ready until ath_open() being called */
+       sc->sc_flags |= SC_OP_INVALID;
+
+       if (ath9k_init_debug(sc) < 0)
+               printk(KERN_ERR "Unable to create debugfs files\n");
+
+       spin_lock_init(&sc->wiphy_lock);
+       spin_lock_init(&sc->sc_resetlock);
+       spin_lock_init(&sc->sc_serial_rw);
+       mutex_init(&sc->mutex);
+       tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
+       tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
+                    (unsigned long)sc);
+
+       /*
+        * Cache line size is used to size and align various
+        * structures used to communicate with the hardware.
+        */
+       ath_read_cachesize(sc, &csz);
+       /* XXX assert csz is non-zero */
+       sc->cachelsz = csz << 2;        /* convert to bytes */
+
+       ah = ath9k_hw_attach(devid, sc, &status);
+       if (ah == NULL) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to attach hardware; HAL status %d\n", status);
+               error = -ENXIO;
+               goto bad;
+       }
+       sc->sc_ah = ah;
+
+       /* Get the hardware key cache size. */
+       sc->keymax = ah->caps.keycache_size;
+       if (sc->keymax > ATH_KEYMAX) {
+               DPRINTF(sc, ATH_DBG_ANY,
+                       "Warning, using only %u entries in %u key cache\n",
+                       ATH_KEYMAX, sc->keymax);
+               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->keymax; i++)
+               ath9k_hw_keyreset(ah, (u16) i);
+
+       if (ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy,
+                         ath9k_reg_notifier))
+               goto bad;
+
+       /* default to MONITOR mode */
+       sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
+
+       /* Setup rate tables */
+
+       ath_rate_attach(sc);
+       ath_setup_rates(sc, IEEE80211_BAND_2GHZ);
+       ath_setup_rates(sc, IEEE80211_BAND_5GHZ);
+
+       /*
+        * 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.
+        */
+       sc->beacon.beaconq = ath_beaconq_setup(ah);
+       if (sc->beacon.beaconq == -1) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup a beacon xmit queue\n");
+               error = -EIO;
+               goto bad2;
+       }
+       sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
+       if (sc->beacon.cabq == NULL) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup CAB xmit queue\n");
+               error = -EIO;
+               goto bad2;
+       }
+
+       sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
+       ath_cabq_update(sc);
+
+       for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
+               sc->tx.hwq_map[i] = -1;
+
+       /* Setup data queues */
+       /* NB: ensure BK queue is the lowest priority h/w queue */
+       if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup xmit queue for BK traffic\n");
+               error = -EIO;
+               goto bad2;
+       }
+
+       if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup xmit queue for BE traffic\n");
+               error = -EIO;
+               goto bad2;
+       }
+       if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup xmit queue for VI traffic\n");
+               error = -EIO;
+               goto bad2;
+       }
+       if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup xmit queue for VO traffic\n");
+               error = -EIO;
+               goto bad2;
+       }
+
+       /* Initializes the noise floor to a reasonable default value.
+        * Later on this will be updated during ANI processing. */
+
+       sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
+       setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc);
+
+       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.
+                */
+               ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC,
+                                      0, 1, NULL);
+       }
+
+       /*
+        * 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->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->config.txpowlimit = ATH_TXPOWER_MAX;
+
+       /* 11n Capabilities */
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+               sc->sc_flags |= SC_OP_TXAGGR;
+               sc->sc_flags |= SC_OP_RXAGGR;
+       }
+
+       sc->tx_chainmask = ah->caps.tx_chainmask;
+       sc->rx_chainmask = ah->caps.rx_chainmask;
+
+       ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
+       sc->rx.defant = ath9k_hw_getdefantenna(ah);
+
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+               memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
+
+       sc->beacon.slottime = ATH9K_SLOT_TIME_9;        /* default to short slot time */
+
+       /* initialize beacon slots */
+       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+               sc->beacon.bslot[i] = NULL;
+               sc->beacon.bslot_aphy[i] = NULL;
+       }
+
+       /* setup channels and rates */
+
+       sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
+       sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
+               sc->rates[IEEE80211_BAND_2GHZ];
+       sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
+       sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
+               ARRAY_SIZE(ath9k_2ghz_chantable);
+
+       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
+               sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
+               sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
+                       sc->rates[IEEE80211_BAND_5GHZ];
+               sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
+               sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
+                       ARRAY_SIZE(ath9k_5ghz_chantable);
+       }
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
+               ath9k_hw_btcoex_enable(sc->sc_ah);
+
+       return 0;
+bad2:
+       /* cleanup tx queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+bad:
+       if (ah)
+               ath9k_hw_detach(ah);
+       ath9k_exit_debug(sc);
+
+       return error;
+}
+
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
+{
+       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+               IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+               IEEE80211_HW_SIGNAL_DBM |
+               IEEE80211_HW_AMPDU_AGGREGATION |
+               IEEE80211_HW_SUPPORTS_PS |
+               IEEE80211_HW_PS_NULLFUNC_STACK |
+               IEEE80211_HW_SPECTRUM_MGMT;
+
+       if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
+               hw->flags |= IEEE80211_HW_MFP_CAPABLE;
+
+       hw->wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_AP) |
+               BIT(NL80211_IFTYPE_STATION) |
+               BIT(NL80211_IFTYPE_ADHOC) |
+               BIT(NL80211_IFTYPE_MESH_POINT);
+
+       hw->queues = 4;
+       hw->max_rates = 4;
+       hw->channel_change_time = 5000;
+       hw->max_listen_interval = 10;
+       hw->max_rate_tries = ATH_11N_TXMAXTRY;
+       hw->sta_data_size = sizeof(struct ath_node);
+       hw->vif_data_size = sizeof(struct ath_vif);
+
+       hw->rate_control_algorithm = "ath9k_rate_control";
+
+       hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+               &sc->sbands[IEEE80211_BAND_2GHZ];
+       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+               hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+                       &sc->sbands[IEEE80211_BAND_5GHZ];
+}
+
+int ath_attach(u16 devid, struct ath_softc *sc)
+{
+       struct ieee80211_hw *hw = sc->hw;
+       int error = 0, i;
+       struct ath_regulatory *reg;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
+
+       error = ath_init(devid, sc);
+       if (error != 0)
+               return error;
+
+       reg = &sc->sc_ah->regulatory;
+
+       /* get mac address from hardware and set in mac80211 */
+
+       SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
+
+       ath_set_hw_capab(sc, hw);
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+               setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
+               if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+                       setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
+       }
+
+       /* initialize tx/rx engine */
+       error = ath_tx_init(sc, ATH_TXBUF);
+       if (error != 0)
+               goto error_attach;
+
+       error = ath_rx_init(sc, ATH_RXBUF);
+       if (error != 0)
+               goto error_attach;
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       /* Initialze h/w Rfkill */
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
+
+       /* Initialize s/w rfkill */
+       error = ath_init_sw_rfkill(sc);
+       if (error)
+               goto error_attach;
+#endif
+
+       INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
+       INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
+       sc->wiphy_scheduler_int = msecs_to_jiffies(500);
+
+       error = ieee80211_register_hw(hw);
+
+       if (!ath_is_world_regd(reg)) {
+               error = regulatory_hint(hw->wiphy, reg->alpha2);
+               if (error)
+                       goto error_attach;
+       }
+
+       /* Initialize LED control */
+       ath_init_leds(sc);
+
+
+       return 0;
+
+error_attach:
+       /* cleanup tx queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+       ath9k_hw_detach(sc->sc_ah);
+       ath9k_exit_debug(sc);
+
+       return error;
+}
+
+int ath_reset(struct ath_softc *sc, bool retry_tx)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ieee80211_hw *hw = sc->hw;
+       int r;
+
+       ath9k_hw_set_interrupts(ah, 0);
+       ath_drain_all_txq(sc, retry_tx);
+       ath_stoprecv(sc);
+       ath_flushrecv(sc);
+
+       spin_lock_bh(&sc->sc_resetlock);
+       r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
+       if (r)
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset hardware; reset status %u\n", r);
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       if (ath_startrecv(sc) != 0)
+               DPRINTF(sc, ATH_DBG_FATAL, "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.
+        */
+       ath_cache_conf_rate(sc, &hw->conf);
+
+       ath_update_txpow(sc);
+
+       if (sc->sc_flags & SC_OP_BEACONS)
+               ath_beacon_config(sc, NULL);    /* restart beacons */
+
+       ath9k_hw_set_interrupts(ah, sc->imask);
+
+       if (retry_tx) {
+               int i;
+               for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+                       if (ATH_TXQ_SETUP(sc, i)) {
+                               spin_lock_bh(&sc->tx.txq[i].axq_lock);
+                               ath_txq_schedule(sc, &sc->tx.txq[i]);
+                               spin_unlock_bh(&sc->tx.txq[i].axq_lock);
+                       }
+               }
+       }
+
+       return r;
+}
+
+/*
+ *  This function will allocate both the DMA descriptor structure, and the
+ *  buffers it contains.  These are used to contain the descriptors used
+ *  by the system.
+*/
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+                     struct list_head *head, const char *name,
+                     int nbuf, int ndesc)
+{
+#define        DS2PHYS(_dd, _ds)                                               \
+       ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
+#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
+#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
+
+       struct ath_desc *ds;
+       struct ath_buf *bf;
+       int i, bsize, error;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
+               name, nbuf, ndesc);
+
+       INIT_LIST_HEAD(head);
+       /* ath_desc must be a multiple of DWORDs */
+       if ((sizeof(struct ath_desc) % 4) != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n");
+               ASSERT((sizeof(struct ath_desc) % 4) == 0);
+               error = -ENOMEM;
+               goto fail;
+       }
+
+       dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
+
+       /*
+        * Need additional DMA memory because we can't use
+        * descriptors that cross the 4K page boundary. Assume
+        * one skipped descriptor per 4K page.
+        */
+       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+               u32 ndesc_skipped =
+                       ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
+               u32 dma_len;
+
+               while (ndesc_skipped) {
+                       dma_len = ndesc_skipped * sizeof(struct ath_desc);
+                       dd->dd_desc_len += dma_len;
+
+                       ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
+               };
+       }
+
+       /* allocate descriptors */
+       dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
+                                        &dd->dd_desc_paddr, GFP_KERNEL);
+       if (dd->dd_desc == NULL) {
+               error = -ENOMEM;
+               goto fail;
+       }
+       ds = dd->dd_desc;
+       DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
+               name, ds, (u32) dd->dd_desc_len,
+               ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
+
+       /* allocate buffers */
+       bsize = sizeof(struct ath_buf) * nbuf;
+       bf = kzalloc(bsize, GFP_KERNEL);
+       if (bf == NULL) {
+               error = -ENOMEM;
+               goto fail2;
+       }
+       dd->dd_bufptr = bf;
+
+       for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
+               bf->bf_desc = ds;
+               bf->bf_daddr = DS2PHYS(dd, ds);
+
+               if (!(sc->sc_ah->caps.hw_caps &
+                     ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+                       /*
+                        * Skip descriptor addresses which can cause 4KB
+                        * boundary crossing (addr + length) with a 32 dword
+                        * descriptor fetch.
+                        */
+                       while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
+                               ASSERT((caddr_t) bf->bf_desc <
+                                      ((caddr_t) dd->dd_desc +
+                                       dd->dd_desc_len));
+
+                               ds += ndesc;
+                               bf->bf_desc = ds;
+                               bf->bf_daddr = DS2PHYS(dd, ds);
+                       }
+               }
+               list_add_tail(&bf->list, head);
+       }
+       return 0;
+fail2:
+       dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+                         dd->dd_desc_paddr);
+fail:
+       memset(dd, 0, sizeof(*dd));
+       return error;
+#undef ATH_DESC_4KB_BOUND_CHECK
+#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
+#undef DS2PHYS
+}
+
+void ath_descdma_cleanup(struct ath_softc *sc,
+                        struct ath_descdma *dd,
+                        struct list_head *head)
+{
+       dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+                         dd->dd_desc_paddr);
+
+       INIT_LIST_HEAD(head);
+       kfree(dd->dd_bufptr);
+       memset(dd, 0, sizeof(*dd));
+}
+
+int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
+{
+       int qnum;
+
+       switch (queue) {
+       case 0:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO];
+               break;
+       case 1:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI];
+               break;
+       case 2:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
+               break;
+       case 3:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK];
+               break;
+       default:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
+               break;
+       }
+
+       return qnum;
+}
+
+int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
+{
+       int qnum;
+
+       switch (queue) {
+       case ATH9K_WME_AC_VO:
+               qnum = 0;
+               break;
+       case ATH9K_WME_AC_VI:
+               qnum = 1;
+               break;
+       case ATH9K_WME_AC_BE:
+               qnum = 2;
+               break;
+       case ATH9K_WME_AC_BK:
+               qnum = 3;
+               break;
+       default:
+               qnum = -1;
+               break;
+       }
+
+       return qnum;
+}
+
+/* XXX: Remove me once we don't depend on ath9k_channel for all
+ * this redundant data */
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                          struct ath9k_channel *ichan)
+{
+       struct ieee80211_channel *chan = hw->conf.channel;
+       struct ieee80211_conf *conf = &hw->conf;
+
+       ichan->channel = chan->center_freq;
+       ichan->chan = chan;
+
+       if (chan->band == IEEE80211_BAND_2GHZ) {
+               ichan->chanmode = CHANNEL_G;
+               ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
+       } else {
+               ichan->chanmode = CHANNEL_A;
+               ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
+       }
+
+       sc->tx_chan_width = ATH9K_HT_MACMODE_20;
+
+       if (conf_is_ht(conf)) {
+               if (conf_is_ht40(conf))
+                       sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
+
+               ichan->chanmode = ath_get_extchanmode(sc, chan,
+                                           conf->channel_type);
+       }
+}
+
+/**********************/
+/* mac80211 callbacks */
+/**********************/
+
+static int ath9k_start(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ieee80211_channel *curchan = hw->conf.channel;
+       struct ath9k_channel *init_channel;
+       int r, pos;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
+               "initial channel: %d MHz\n", curchan->center_freq);
+
+       mutex_lock(&sc->mutex);
+
+       if (ath9k_wiphy_started(sc)) {
+               if (sc->chan_idx == curchan->hw_value) {
+                       /*
+                        * Already on the operational channel, the new wiphy
+                        * can be marked active.
+                        */
+                       aphy->state = ATH_WIPHY_ACTIVE;
+                       ieee80211_wake_queues(hw);
+               } else {
+                       /*
+                        * Another wiphy is on another channel, start the new
+                        * wiphy in paused state.
+                        */
+                       aphy->state = ATH_WIPHY_PAUSED;
+                       ieee80211_stop_queues(hw);
+               }
+               mutex_unlock(&sc->mutex);
+               return 0;
+       }
+       aphy->state = ATH_WIPHY_ACTIVE;
+
+       /* setup initial channel */
+
+       pos = curchan->hw_value;
+
+       sc->chan_idx = pos;
+       init_channel = &sc->sc_ah->channels[pos];
+       ath9k_update_ichannel(sc, hw, init_channel);
+
+       /* 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.
+        */
+       spin_lock_bh(&sc->sc_resetlock);
+       r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
+       if (r) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset hardware; reset status %u "
+                       "(freq %u MHz)\n", r,
+                       curchan->center_freq);
+               spin_unlock_bh(&sc->sc_resetlock);
+               goto mutex_unlock;
+       }
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       /*
+        * This is needed only to setup initial state
+        * but it's best done after a reset.
+        */
+       ath_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 (ath_startrecv(sc) != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n");
+               r = -EIO;
+               goto mutex_unlock;
+       }
+
+       /* Setup our intr mask. */
+       sc->imask = ATH9K_INT_RX | ATH9K_INT_TX
+               | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
+               | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
+               sc->imask |= ATH9K_INT_GTT;
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
+               sc->imask |= ATH9K_INT_CST;
+
+       ath_cache_conf_rate(sc, &hw->conf);
+
+       sc->sc_flags &= ~SC_OP_INVALID;
+
+       /* Disable BMISS interrupt when we're not associated */
+       sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+       ieee80211_wake_queues(hw);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       r = ath_start_rfkill_poll(sc);
+#endif
+
+mutex_unlock:
+       mutex_unlock(&sc->mutex);
+
+       return r;
+}
+
+static int ath9k_tx(struct ieee80211_hw *hw,
+                   struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_tx_control txctl;
+       int hdrlen, padsize;
+
+       if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
+               printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state "
+                      "%d\n", wiphy_name(hw->wiphy), aphy->state);
+               goto exit;
+       }
+
+       memset(&txctl, 0, sizeof(struct ath_tx_control));
+
+       /*
+        * As a temporary workaround, assign seq# here; this will likely need
+        * to be cleaned up to work better with Beacon transmission and virtual
+        * BSSes.
+        */
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+                       sc->tx.seq_no += 0x10;
+               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+       }
+
+       /* Add the padding after the header if this is not already done */
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       if (hdrlen & 3) {
+               padsize = hdrlen % 4;
+               if (skb_headroom(skb) < padsize)
+                       return -1;
+               skb_push(skb, padsize);
+               memmove(skb->data, skb->data + padsize, hdrlen);
+       }
+
+       /* Check if a tx queue is available */
+
+       txctl.txq = ath_test_get_txq(sc, skb);
+       if (!txctl.txq)
+               goto exit;
+
+       DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
+
+       if (ath_tx_start(hw, skb, &txctl) != 0) {
+               DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n");
+               goto exit;
+       }
+
+       return 0;
+exit:
+       dev_kfree_skb_any(skb);
+       return 0;
+}
+
+static void ath9k_stop(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       aphy->state = ATH_WIPHY_INACTIVE;
+
+       if (sc->sc_flags & SC_OP_INVALID) {
+               DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
+               return;
+       }
+
+       mutex_lock(&sc->mutex);
+
+       ieee80211_stop_queues(hw);
+
+       if (ath9k_wiphy_started(sc)) {
+               mutex_unlock(&sc->mutex);
+               return; /* another wiphy still in use */
+       }
+
+       /* make sure h/w will not generate any interrupt
+        * before setting the invalid flag. */
+       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+
+       if (!(sc->sc_flags & SC_OP_INVALID)) {
+               ath_drain_all_txq(sc, false);
+               ath_stoprecv(sc);
+               ath9k_hw_phy_disable(sc->sc_ah);
+       } else
+               sc->rx.rxlink = NULL;
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
+#endif
+       /* disable HAL and put h/w to sleep */
+       ath9k_hw_disable(sc->sc_ah);
+       ath9k_hw_configpcipowersave(sc->sc_ah, 1);
+
+       sc->sc_flags |= SC_OP_INVALID;
+
+       mutex_unlock(&sc->mutex);
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n");
+}
+
+static int ath9k_add_interface(struct ieee80211_hw *hw,
+                              struct ieee80211_if_init_conf *conf)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_vif *avp = (void *)conf->vif->drv_priv;
+       enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
+       int ret = 0;
+
+       mutex_lock(&sc->mutex);
+
+       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
+           sc->nvifs > 0) {
+               ret = -ENOBUFS;
+               goto out;
+       }
+
+       switch (conf->type) {
+       case NL80211_IFTYPE_STATION:
+               ic_opmode = NL80211_IFTYPE_STATION;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_MESH_POINT:
+               if (sc->nbcnvifs >= ATH_BCBUF) {
+                       ret = -ENOBUFS;
+                       goto out;
+               }
+               ic_opmode = conf->type;
+               break;
+       default:
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Interface type %d not yet supported\n", conf->type);
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode);
+
+       /* Set the VIF opmode */
+       avp->av_opmode = ic_opmode;
+       avp->av_bslot = -1;
+
+       sc->nvifs++;
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+               ath9k_set_bssid_mask(hw);
+
+       if (sc->nvifs > 1)
+               goto out; /* skip global settings for secondary vif */
+
+       if (ic_opmode == NL80211_IFTYPE_AP) {
+               ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+               sc->sc_flags |= SC_OP_TSF_RESET;
+       }
+
+       /* Set the device opmode */
+       sc->sc_ah->opmode = ic_opmode;
+
+       /*
+        * Enable MIB interrupts when there are hardware phy counters.
+        * Note we only do this (at the moment) for station mode.
+        */
+       if ((conf->type == NL80211_IFTYPE_STATION) ||
+           (conf->type == NL80211_IFTYPE_ADHOC) ||
+           (conf->type == NL80211_IFTYPE_MESH_POINT)) {
+               if (ath9k_hw_phycounters(sc->sc_ah))
+                       sc->imask |= ATH9K_INT_MIB;
+               sc->imask |= ATH9K_INT_TSFOOR;
+       }
+
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+       if (conf->type == NL80211_IFTYPE_AP) {
+               /* TODO: is this a suitable place to start ANI for AP mode? */
+               /* Start ANI */
+               mod_timer(&sc->ani.timer,
+                         jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+       }
+
+out:
+       mutex_unlock(&sc->mutex);
+       return ret;
+}
+
+static void ath9k_remove_interface(struct ieee80211_hw *hw,
+                                  struct ieee80211_if_init_conf *conf)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_vif *avp = (void *)conf->vif->drv_priv;
+       int i;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
+
+       mutex_lock(&sc->mutex);
+
+       /* Stop ANI */
+       del_timer_sync(&sc->ani.timer);
+
+       /* Reclaim beacon resources */
+       if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
+               ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+               ath_beacon_return(sc, avp);
+       }
+
+       sc->sc_flags &= ~SC_OP_BEACONS;
+
+       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+               if (sc->beacon.bslot[i] == conf->vif) {
+                       printk(KERN_DEBUG "%s: vif had allocated beacon "
+                              "slot\n", __func__);
+                       sc->beacon.bslot[i] = NULL;
+                       sc->beacon.bslot_aphy[i] = NULL;
+               }
+       }
+
+       sc->nvifs--;
+
+       mutex_unlock(&sc->mutex);
+}
+
+static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ieee80211_conf *conf = &hw->conf;
+       struct ath_hw *ah = sc->sc_ah;
+
+       mutex_lock(&sc->mutex);
+
+       if (changed & IEEE80211_CONF_CHANGE_PS) {
+               if (conf->flags & IEEE80211_CONF_PS) {
+                       if (!(ah->caps.hw_caps &
+                             ATH9K_HW_CAP_AUTOSLEEP)) {
+                               if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
+                                       sc->imask |= ATH9K_INT_TIM_TIMER;
+                                       ath9k_hw_set_interrupts(sc->sc_ah,
+                                                       sc->imask);
+                               }
+                               ath9k_hw_setrxabort(sc->sc_ah, 1);
+                       }
+                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+               } else {
+                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+                       if (!(ah->caps.hw_caps &
+                             ATH9K_HW_CAP_AUTOSLEEP)) {
+                               ath9k_hw_setrxabort(sc->sc_ah, 0);
+                               sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+                               if (sc->imask & ATH9K_INT_TIM_TIMER) {
+                                       sc->imask &= ~ATH9K_INT_TIM_TIMER;
+                                       ath9k_hw_set_interrupts(sc->sc_ah,
+                                                       sc->imask);
+                               }
+                       }
+               }
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+               struct ieee80211_channel *curchan = hw->conf.channel;
+               int pos = curchan->hw_value;
+
+               aphy->chan_idx = pos;
+               aphy->chan_is_ht = conf_is_ht(conf);
+
+               if (aphy->state == ATH_WIPHY_SCAN ||
+                   aphy->state == ATH_WIPHY_ACTIVE)
+                       ath9k_wiphy_pause_all_forced(sc, aphy);
+               else {
+                       /*
+                        * Do not change operational channel based on a paused
+                        * wiphy changes.
+                        */
+                       goto skip_chan_change;
+               }
+
+               DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+                       curchan->center_freq);
+
+               /* XXX: remove me eventualy */
+               ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
+
+               ath_update_chainmask(sc, conf_is_ht(conf));
+
+               if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
+                       DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
+                       mutex_unlock(&sc->mutex);
+                       return -EINVAL;
+               }
+       }
+
+skip_chan_change:
+       if (changed & IEEE80211_CONF_CHANGE_POWER)
+               sc->config.txpowlimit = 2 * conf->power_level;
+
+       /*
+        * The HW TSF has to be reset when the beacon interval changes.
+        * We set the flag here, and ath_beacon_config_ap() would take this
+        * into account when it gets called through the subsequent
+        * config_interface() call - with IFCC_BEACON in the changed field.
+        */
+
+       if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
+               sc->sc_flags |= SC_OP_TSF_RESET;
+
+       mutex_unlock(&sc->mutex);
+
+       return 0;
+}
+
+static int ath9k_config_interface(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif,
+                                 struct ieee80211_if_conf *conf)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_vif *avp = (void *)vif->drv_priv;
+       u32 rfilt = 0;
+       int error, i;
+
+       mutex_lock(&sc->mutex);
+
+       /* TODO: Need to decide which hw opmode to use for multi-interface
+        * cases */
+       if (vif->type == NL80211_IFTYPE_AP &&
+           ah->opmode != NL80211_IFTYPE_AP) {
+               ah->opmode = NL80211_IFTYPE_STATION;
+               ath9k_hw_setopmode(ah);
+               memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
+               sc->curaid = 0;
+               ath9k_hw_write_associd(sc);
+               /* Request full reset to get hw opmode changed properly */
+               sc->sc_flags |= SC_OP_FULL_RESET;
+       }
+
+       if ((conf->changed & IEEE80211_IFCC_BSSID) &&
+           !is_zero_ether_addr(conf->bssid)) {
+               switch (vif->type) {
+               case NL80211_IFTYPE_STATION:
+               case NL80211_IFTYPE_ADHOC:
+               case NL80211_IFTYPE_MESH_POINT:
+                       /* Set BSSID */
+                       memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
+                       memcpy(avp->bssid, conf->bssid, ETH_ALEN);
+                       sc->curaid = 0;
+                       ath9k_hw_write_associd(sc);
+
+                       /* Set aggregation protection mode parameters */
+                       sc->config.ath_aggr_prot = 0;
+
+                       DPRINTF(sc, ATH_DBG_CONFIG,
+                               "RX filter 0x%x bssid %pM aid 0x%x\n",
+                               rfilt, sc->curbssid, sc->curaid);
+
+                       /* need to reconfigure the beacon */
+                       sc->sc_flags &= ~SC_OP_BEACONS ;
+
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+           (vif->type == NL80211_IFTYPE_AP) ||
+           (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+               if ((conf->changed & IEEE80211_IFCC_BEACON) ||
+                   (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
+                    conf->enable_beacon)) {
+                       /*
+                        * Allocate and setup the beacon frame.
+                        *
+                        * Stop any previous beacon DMA.  This may be
+                        * necessary, for example, when an ibss merge
+                        * causes reconfiguration; we may be called
+                        * with beacon transmission active.
+                        */
+                       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+
+                       error = ath_beacon_alloc(aphy, vif);
+                       if (error != 0) {
+                               mutex_unlock(&sc->mutex);
+                               return error;
+                       }
+
+                       ath_beacon_config(sc, vif);
+               }
+       }
+
+       /* Check for WLAN_CAPABILITY_PRIVACY ? */
+       if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
+               for (i = 0; i < IEEE80211_WEP_NKID; i++)
+                       if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
+                               ath9k_hw_keysetmac(sc->sc_ah,
+                                                  (u16)i,
+                                                  sc->curbssid);
+       }
+
+       /* Only legacy IBSS for now */
+       if (vif->type == NL80211_IFTYPE_ADHOC)
+               ath_update_chainmask(sc, 0);
+
+       mutex_unlock(&sc->mutex);
+
+       return 0;
+}
+
+#define SUPPORTED_FILTERS                      \
+       (FIF_PROMISC_IN_BSS |                   \
+       FIF_ALLMULTI |                          \
+       FIF_CONTROL |                           \
+       FIF_OTHER_BSS |                         \
+       FIF_BCN_PRBRESP_PROMISC |               \
+       FIF_FCSFAIL)
+
+/* FIXME: sc->sc_full_reset ? */
+static void ath9k_configure_filter(struct ieee80211_hw *hw,
+                                  unsigned int changed_flags,
+                                  unsigned int *total_flags,
+                                  int mc_count,
+                                  struct dev_mc_list *mclist)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       u32 rfilt;
+
+       changed_flags &= SUPPORTED_FILTERS;
+       *total_flags &= SUPPORTED_FILTERS;
+
+       sc->rx.rxfilter = *total_flags;
+       rfilt = ath_calcrxfilter(sc);
+       ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
+}
+
+static void ath9k_sta_notify(struct ieee80211_hw *hw,
+                            struct ieee80211_vif *vif,
+                            enum sta_notify_cmd cmd,
+                            struct ieee80211_sta *sta)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       switch (cmd) {
+       case STA_NOTIFY_ADD:
+               ath_node_attach(sc, sta);
+               break;
+       case STA_NOTIFY_REMOVE:
+               ath_node_detach(sc, sta);
+               break;
+       default:
+               break;
+       }
+}
+
+static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
+                        const struct ieee80211_tx_queue_params *params)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath9k_tx_queue_info qi;
+       int ret = 0, qnum;
+
+       if (queue >= WME_NUM_AC)
+               return 0;
+
+       mutex_lock(&sc->mutex);
+
+       memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
+
+       qi.tqi_aifs = params->aifs;
+       qi.tqi_cwmin = params->cw_min;
+       qi.tqi_cwmax = params->cw_max;
+       qi.tqi_burstTime = params->txop;
+       qnum = ath_get_hal_qnum(queue, sc);
+
+       DPRINTF(sc, ATH_DBG_CONFIG,
+               "Configure tx [queue/halq] [%d/%d],  "
+               "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
+               queue, qnum, params->aifs, params->cw_min,
+               params->cw_max, params->txop);
+
+       ret = ath_txq_update(sc, qnum, &qi);
+       if (ret)
+               DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n");
+
+       mutex_unlock(&sc->mutex);
+
+       return ret;
+}
+
+static int ath9k_set_key(struct ieee80211_hw *hw,
+                        enum set_key_cmd cmd,
+                        struct ieee80211_vif *vif,
+                        struct ieee80211_sta *sta,
+                        struct ieee80211_key_conf *key)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       int ret = 0;
+
+       if (modparam_nohwcrypt)
+               return -ENOSPC;
+
+       mutex_lock(&sc->mutex);
+       ath9k_ps_wakeup(sc);
+       DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n");
+
+       switch (cmd) {
+       case SET_KEY:
+               ret = ath_key_config(sc, vif, sta, key);
+               if (ret >= 0) {
+                       key->hw_key_idx = ret;
+                       /* push IV and Michael MIC generation to stack */
+                       key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+                       if (key->alg == ALG_TKIP)
+                               key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+                       if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+                               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
+                       ret = 0;
+               }
+               break;
+       case DISABLE_KEY:
+               ath_key_delete(sc, key);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       ath9k_ps_restore(sc);
+       mutex_unlock(&sc->mutex);
+
+       return ret;
+}
+
+static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
+                                  struct ieee80211_vif *vif,
+                                  struct ieee80211_bss_conf *bss_conf,
+                                  u32 changed)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       mutex_lock(&sc->mutex);
+
+       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
+                       bss_conf->use_short_preamble);
+               if (bss_conf->use_short_preamble)
+                       sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
+               else
+                       sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
+       }
+
+       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
+                       bss_conf->use_cts_prot);
+               if (bss_conf->use_cts_prot &&
+                   hw->conf.channel->band != IEEE80211_BAND_5GHZ)
+                       sc->sc_flags |= SC_OP_PROTECT_ENABLE;
+               else
+                       sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
+       }
+
+       if (changed & BSS_CHANGED_ASSOC) {
+               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
+                       bss_conf->assoc);
+               ath9k_bss_assoc_info(sc, vif, bss_conf);
+       }
+
+       mutex_unlock(&sc->mutex);
+}
+
+static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
+{
+       u64 tsf;
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       mutex_lock(&sc->mutex);
+       tsf = ath9k_hw_gettsf64(sc->sc_ah);
+       mutex_unlock(&sc->mutex);
+
+       return tsf;
+}
+
+static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       mutex_lock(&sc->mutex);
+       ath9k_hw_settsf64(sc->sc_ah, tsf);
+       mutex_unlock(&sc->mutex);
+}
+
+static void ath9k_reset_tsf(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       mutex_lock(&sc->mutex);
+       ath9k_hw_reset_tsf(sc->sc_ah);
+       mutex_unlock(&sc->mutex);
+}
+
+static int ath9k_ampdu_action(struct ieee80211_hw *hw,
+                             enum ieee80211_ampdu_mlme_action action,
+                             struct ieee80211_sta *sta,
+                             u16 tid, u16 *ssn)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       int ret = 0;
+
+       switch (action) {
+       case IEEE80211_AMPDU_RX_START:
+               if (!(sc->sc_flags & SC_OP_RXAGGR))
+                       ret = -ENOTSUPP;
+               break;
+       case IEEE80211_AMPDU_RX_STOP:
+               break;
+       case IEEE80211_AMPDU_TX_START:
+               ret = ath_tx_aggr_start(sc, sta, tid, ssn);
+               if (ret < 0)
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "Unable to start TX aggregation\n");
+               else
+                       ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+               break;
+       case IEEE80211_AMPDU_TX_STOP:
+               ret = ath_tx_aggr_stop(sc, sta, tid);
+               if (ret < 0)
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "Unable to stop TX aggregation\n");
+
+               ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+               break;
+       case IEEE80211_AMPDU_TX_OPERATIONAL:
+               ath_tx_aggr_resume(sc, sta, tid);
+               break;
+       default:
+               DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n");
+       }
+
+       return ret;
+}
+
+static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       if (ath9k_wiphy_scanning(sc)) {
+               printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
+                      "same time\n");
+               /*
+                * Do not allow the concurrent scanning state for now. This
+                * could be improved with scanning control moved into ath9k.
+                */
+               return;
+       }
+
+       aphy->state = ATH_WIPHY_SCAN;
+       ath9k_wiphy_pause_all_forced(sc, aphy);
+
+       mutex_lock(&sc->mutex);
+       sc->sc_flags |= SC_OP_SCANNING;
+       mutex_unlock(&sc->mutex);
+}
+
+static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       mutex_lock(&sc->mutex);
+       aphy->state = ATH_WIPHY_ACTIVE;
+       sc->sc_flags &= ~SC_OP_SCANNING;
+       mutex_unlock(&sc->mutex);
+}
+
+struct ieee80211_ops ath9k_ops = {
+       .tx                 = ath9k_tx,
+       .start              = ath9k_start,
+       .stop               = ath9k_stop,
+       .add_interface      = ath9k_add_interface,
+       .remove_interface   = ath9k_remove_interface,
+       .config             = ath9k_config,
+       .config_interface   = ath9k_config_interface,
+       .configure_filter   = ath9k_configure_filter,
+       .sta_notify         = ath9k_sta_notify,
+       .conf_tx            = ath9k_conf_tx,
+       .bss_info_changed   = ath9k_bss_info_changed,
+       .set_key            = ath9k_set_key,
+       .get_tsf            = ath9k_get_tsf,
+       .set_tsf            = ath9k_set_tsf,
+       .reset_tsf          = ath9k_reset_tsf,
+       .ampdu_action       = ath9k_ampdu_action,
+       .sw_scan_start      = ath9k_sw_scan_start,
+       .sw_scan_complete   = ath9k_sw_scan_complete,
+};
+
+static struct {
+       u32 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 {
+       u16 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.
+ */
+const char *
+ath_mac_bb_name(u32 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.
+ */
+const char *
+ath_rf_name(u16 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 int __init ath9k_init(void)
+{
+       int error;
+
+       /* Register rate control algorithm */
+       error = ath_rate_control_register();
+       if (error != 0) {
+               printk(KERN_ERR
+                       "ath9k: Unable to register rate control "
+                       "algorithm: %d\n",
+                       error);
+               goto err_out;
+       }
+
+       error = ath9k_debug_create_root();
+       if (error) {
+               printk(KERN_ERR
+                       "ath9k: Unable to create debugfs root: %d\n",
+                       error);
+               goto err_rate_unregister;
+       }
+
+       error = ath_pci_init();
+       if (error < 0) {
+               printk(KERN_ERR
+                       "ath9k: No PCI devices found, driver not installed.\n");
+               error = -ENODEV;
+               goto err_remove_root;
+       }
+
+       error = ath_ahb_init();
+       if (error < 0) {
+               error = -ENODEV;
+               goto err_pci_exit;
+       }
+
+       return 0;
+
+ err_pci_exit:
+       ath_pci_exit();
+
+ err_remove_root:
+       ath9k_debug_remove_root();
+ err_rate_unregister:
+       ath_rate_control_unregister();
+ err_out:
+       return error;
+}
+module_init(ath9k_init);
+
+static void __exit ath9k_exit(void)
+{
+       ath_ahb_exit();
+       ath_pci_exit();
+       ath9k_debug_remove_root();
+       ath_rate_control_unregister();
+       printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
+}
+module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
new file mode 100644 (file)
index 0000000..6dbc585
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2008-2009 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 <linux/nl80211.h>
+#include <linux/pci.h>
+#include "ath9k.h"
+
+static struct pci_device_id ath_pci_id_table[] __devinitdata = {
+       { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
+       { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
+       { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
+       { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
+       { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
+       { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
+       { 0 }
+};
+
+/* return bus cachesize in 4B word units */
+static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
+{
+       u8 u8tmp;
+
+       pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
+                            (u8 *)&u8tmp);
+       *csz = (int)u8tmp;
+
+       /*
+        * This check was put in to avoid "unplesant" consequences if
+        * the bootrom has not fully initialized all PCI devices.
+        * Sometimes the cache line size register is not set
+        */
+
+       if (*csz == 0)
+               *csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
+}
+
+static void ath_pci_cleanup(struct ath_softc *sc)
+{
+       struct pci_dev *pdev = to_pci_dev(sc->dev);
+
+       pci_iounmap(pdev, sc->mem);
+       pci_disable_device(pdev);
+       pci_release_region(pdev, 0);
+}
+
+static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *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,
+                          AH_WAIT_TIMEOUT)) {
+               return false;
+       }
+
+       *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
+                  AR_EEPROM_STATUS_DATA_VAL);
+
+       return true;
+}
+
+static struct ath_bus_ops ath_pci_bus_ops = {
+       .read_cachesize = ath_pci_read_cachesize,
+       .cleanup = ath_pci_cleanup,
+       .eeprom_read = ath_pci_eeprom_read,
+};
+
+static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+       void __iomem *mem;
+       struct ath_wiphy *aphy;
+       struct ath_softc *sc;
+       struct ieee80211_hw *hw;
+       u8 csz;
+       int ret = 0;
+       struct ath_hw *ah;
+
+       if (pci_enable_device(pdev))
+               return -EIO;
+
+       ret =  pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+
+       if (ret) {
+               printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
+               goto bad;
+       }
+
+       ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+
+       if (ret) {
+               printk(KERN_ERR "ath9k: 32-bit DMA consistent "
+                       "DMA enable failed\n");
+               goto bad;
+       }
+
+       /*
+        * Cache line size is used to size and align various
+        * structures used to communicate with the hardware.
+        */
+       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+       if (csz == 0) {
+               /*
+                * Linux 2.4.18 (at least) writes the cache line size
+                * register as a 16-bit wide register which is wrong.
+                * We must have this setup properly for rx buffer
+                * DMA to work so force a reasonable value here if it
+                * comes up zero.
+                */
+               csz = L1_CACHE_BYTES / sizeof(u32);
+               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+       }
+       /*
+        * The default setting of latency timer yields poor results,
+        * set it to the value used by other systems. It may be worth
+        * tweaking this setting more.
+        */
+       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+       pci_set_master(pdev);
+
+       ret = pci_request_region(pdev, 0, "ath9k");
+       if (ret) {
+               dev_err(&pdev->dev, "PCI memory region reserve error\n");
+               ret = -ENODEV;
+               goto bad;
+       }
+
+       mem = pci_iomap(pdev, 0, 0);
+       if (!mem) {
+               printk(KERN_ERR "PCI memory map error\n") ;
+               ret = -EIO;
+               goto bad1;
+       }
+
+       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+                               sizeof(struct ath_softc), &ath9k_ops);
+       if (hw == NULL) {
+               printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
+               goto bad2;
+       }
+
+       SET_IEEE80211_DEV(hw, &pdev->dev);
+       pci_set_drvdata(pdev, hw);
+
+       aphy = hw->priv;
+       sc = (struct ath_softc *) (aphy + 1);
+       aphy->sc = sc;
+       aphy->hw = hw;
+       sc->pri_wiphy = aphy;
+       sc->hw = hw;
+       sc->dev = &pdev->dev;
+       sc->mem = mem;
+       sc->bus_ops = &ath_pci_bus_ops;
+
+       if (ath_attach(id->device, sc) != 0) {
+               ret = -ENODEV;
+               goto bad3;
+       }
+
+       /* setup interrupt service routine */
+
+       if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
+               printk(KERN_ERR "%s: request_irq failed\n",
+                       wiphy_name(hw->wiphy));
+               ret = -EIO;
+               goto bad4;
+       }
+
+       sc->irq = pdev->irq;
+
+       ah = sc->sc_ah;
+       printk(KERN_INFO
+              "%s: Atheros AR%s MAC/BB Rev:%x "
+              "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
+              wiphy_name(hw->wiphy),
+              ath_mac_bb_name(ah->hw_version.macVersion),
+              ah->hw_version.macRev,
+              ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+              ah->hw_version.phyRev,
+              (unsigned long)mem, pdev->irq);
+
+       return 0;
+bad4:
+       ath_detach(sc);
+bad3:
+       ieee80211_free_hw(hw);
+bad2:
+       pci_iounmap(pdev, mem);
+bad1:
+       pci_release_region(pdev, 0);
+bad:
+       pci_disable_device(pdev);
+       return ret;
+}
+
+static void ath_pci_remove(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       ath_cleanup(sc);
+}
+
+#ifdef CONFIG_PM
+
+static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
+#endif
+
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+
+       return 0;
+}
+
+static int ath_pci_resume(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       int err;
+
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
+       pci_restore_state(pdev);
+
+       /* Enable LED */
+       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       /*
+        * check the h/w rfkill state on resume
+        * and start the rfkill poll timer
+        */
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               queue_delayed_work(sc->hw->workqueue,
+                                  &sc->rf_kill.rfkill_poll, 0);
+#endif
+
+       return 0;
+}
+
+#endif /* CONFIG_PM */
+
+MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
+
+static struct pci_driver ath_pci_driver = {
+       .name       = "ath9k",
+       .id_table   = ath_pci_id_table,
+       .probe      = ath_pci_probe,
+       .remove     = ath_pci_remove,
+#ifdef CONFIG_PM
+       .suspend    = ath_pci_suspend,
+       .resume     = ath_pci_resume,
+#endif /* CONFIG_PM */
+};
+
+int ath_pci_init(void)
+{
+       return pci_register_driver(&ath_pci_driver);
+}
+
+void ath_pci_exit(void)
+{
+       pci_unregister_driver(&ath_pci_driver);
+}
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
new file mode 100644 (file)
index 0000000..5ec9ce9
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+void
+ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
+                   int regWrites)
+{
+       REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
+}
+
+bool
+ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       u32 channelSel = 0;
+       u32 bModeSynth = 0;
+       u32 aModeRefSel = 0;
+       u32 reg32 = 0;
+       u16 freq;
+       struct chan_centers centers;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       if (freq < 4800) {
+               u32 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 {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Invalid channel %u MHz\n", freq);
+                       return 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 {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Invalid channel %u MHz\n", freq);
+               return false;
+       }
+
+       reg32 =
+           (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
+           (1 << 5) | 0x1;
+
+       REG_WRITE(ah, AR_PHY(0x37), reg32);
+
+       ah->curchan = chan;
+       ah->curchan_rad_index = -1;
+
+       return true;
+}
+
+bool
+ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
+                           struct ath9k_channel *chan)
+{
+       u16 bMode, fracMode, aModeRefSel = 0;
+       u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
+       struct chan_centers centers;
+       u32 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) {
+               u32 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;
+
+               switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
+               case 0:
+                       if ((freq % 20) == 0) {
+                               aModeRefSel = 3;
+                       } else if ((freq % 10) == 0) {
+                               aModeRefSel = 2;
+                       }
+                       if (aModeRefSel)
+                               break;
+               case 1:
+               default:
+                       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->curchan = chan;
+       ah->curchan_rad_index = -1;
+
+       return true;
+}
+
+static void
+ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
+                          u32 numBits, u32 firstBit,
+                          u32 column)
+{
+       u32 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++;
+       }
+}
+
+bool
+ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
+                    u16 modesIndex)
+{
+       u32 eepMinorRev;
+       u32 ob5GHz = 0, db5GHz = 0;
+       u32 ob2GHz = 0, db2GHz = 0;
+       int regWrites = 0;
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               return true;
+
+       eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
+
+       RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
+
+       RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
+
+       RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
+
+       RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
+                     modesIndex);
+       {
+               int i;
+               for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
+                       ah->analogBank6Data[i] =
+                           INI_RA(&ah->iniBank6TPC, i, modesIndex);
+               }
+       }
+
+       if (eepMinorRev >= 2) {
+               if (IS_CHAN_2GHZ(chan)) {
+                       ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
+                       db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
+                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                  ob2GHz, 3, 197, 0);
+                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                  db2GHz, 3, 194, 0);
+               } else {
+                       ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
+                       db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
+                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                  ob5GHz, 3, 203, 0);
+                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                  db5GHz, 3, 200, 0);
+               }
+       }
+
+       RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
+
+       REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
+                          regWrites);
+
+       return true;
+}
+
+void
+ath9k_hw_rfdetach(struct ath_hw *ah)
+{
+       if (ah->analogBank0Data != NULL) {
+               kfree(ah->analogBank0Data);
+               ah->analogBank0Data = NULL;
+       }
+       if (ah->analogBank1Data != NULL) {
+               kfree(ah->analogBank1Data);
+               ah->analogBank1Data = NULL;
+       }
+       if (ah->analogBank2Data != NULL) {
+               kfree(ah->analogBank2Data);
+               ah->analogBank2Data = NULL;
+       }
+       if (ah->analogBank3Data != NULL) {
+               kfree(ah->analogBank3Data);
+               ah->analogBank3Data = NULL;
+       }
+       if (ah->analogBank6Data != NULL) {
+               kfree(ah->analogBank6Data);
+               ah->analogBank6Data = NULL;
+       }
+       if (ah->analogBank6TPCData != NULL) {
+               kfree(ah->analogBank6TPCData);
+               ah->analogBank6TPCData = NULL;
+       }
+       if (ah->analogBank7Data != NULL) {
+               kfree(ah->analogBank7Data);
+               ah->analogBank7Data = NULL;
+       }
+       if (ah->addac5416_21 != NULL) {
+               kfree(ah->addac5416_21);
+               ah->addac5416_21 = NULL;
+       }
+       if (ah->bank6Temp != NULL) {
+               kfree(ah->bank6Temp);
+               ah->bank6Temp = NULL;
+       }
+}
+
+bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
+{
+       if (!AR_SREV_9280_10_OR_LATER(ah)) {
+               ah->analogBank0Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank0.ia_rows), GFP_KERNEL);
+               ah->analogBank1Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank1.ia_rows), GFP_KERNEL);
+               ah->analogBank2Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank2.ia_rows), GFP_KERNEL);
+               ah->analogBank3Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank3.ia_rows), GFP_KERNEL);
+               ah->analogBank6Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank6.ia_rows), GFP_KERNEL);
+               ah->analogBank6TPCData =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank6TPC.ia_rows), GFP_KERNEL);
+               ah->analogBank7Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank7.ia_rows), GFP_KERNEL);
+
+               if (ah->analogBank0Data == NULL
+                   || ah->analogBank1Data == NULL
+                   || ah->analogBank2Data == NULL
+                   || ah->analogBank3Data == NULL
+                   || ah->analogBank6Data == NULL
+                   || ah->analogBank6TPCData == NULL
+                   || ah->analogBank7Data == NULL) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Cannot allocate RF banks\n");
+                       *status = -ENOMEM;
+                       return false;
+               }
+
+               ah->addac5416_21 =
+                   kzalloc((sizeof(u32) *
+                            ah->iniAddac.ia_rows *
+                            ah->iniAddac.ia_columns), GFP_KERNEL);
+               if (ah->addac5416_21 == NULL) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Cannot allocate addac5416_21\n");
+                       *status = -ENOMEM;
+                       return false;
+               }
+
+               ah->bank6Temp =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank6.ia_rows), GFP_KERNEL);
+               if (ah->bank6Temp == NULL) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Cannot allocate bank6Temp\n");
+                       *status = -ENOMEM;
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+void
+ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       int i, regWrites = 0;
+       u32 bank6SelMask;
+       u32 *bank6Temp = ah->bank6Temp;
+
+       switch (ah->diversity_control) {
+       case ATH9K_ANT_FIXED_A:
+               bank6SelMask =
+                   (ah->
+                    antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
+                   REDUCE_CHAIN_1;
+               break;
+       case ATH9K_ANT_FIXED_B:
+               bank6SelMask =
+                   (ah->
+                    antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
+                   REDUCE_CHAIN_0;
+               break;
+       case ATH9K_ANT_VARIABLE:
+               return;
+               break;
+       default:
+               return;
+               break;
+       }
+
+       for (i = 0; i < ah->iniBank6.ia_rows; i++)
+               bank6Temp[i] = 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(&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
+}
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
new file mode 100644 (file)
index 0000000..296d0e9
--- /dev/null
@@ -0,0 +1,576 @@
+/*
+ * Copyright (c) 2008-2009 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 PHY_H
+#define PHY_H
+
+bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
+                                struct ath9k_channel
+                                *chan);
+bool ath9k_hw_set_channel(struct ath_hw *ah,
+                         struct ath9k_channel *chan);
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
+                        u32 freqIndex, int regWrites);
+bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
+                         struct ath9k_channel *chan,
+                         u16 modesIndex);
+void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
+                                  struct ath9k_channel *chan);
+bool ath9k_hw_init_rf(struct ath_hw *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_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
+
+#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_TPCRG1_PD_CAL_ENABLE   0x00400000
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR_PHY_TX_PWRCTRL4       0xa264
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
+
+#define AR_PHY_TX_PWRCTRL6_0     0xa270
+#define AR_PHY_TX_PWRCTRL6_1     0xb270
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
+
+#define AR_PHY_TX_PWRCTRL7       0xa274
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
+
+#define AR_PHY_TX_PWRCTRL9       0xa27C
+#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
+#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
+
+#define AR_PHY_TX_GAIN_TBL1      0xa300
+#define AR_PHY_TX_GAIN                     0x0007F000
+#define AR_PHY_TX_GAIN_S                   12
+
+#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
+
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR_PHY_CL_CAL_CTL       0xA358
+#define AR_PHY_CL_CAL_ENABLE    0x00000002
+#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
+
+#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]); \
+                       DO_DELAY(regWr);                                \
+               }                                                       \
+       } while (0)
+
+#define ATH9K_IS_MIC_ENABLED(ah)                                       \
+       ((ah)->sta_id1_defaults & 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);;     \
+       } while (0)
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
new file mode 100644 (file)
index 0000000..a13668b
--- /dev/null
@@ -0,0 +1,1752 @@
+/*
+ * Copyright (c) 2004 Video54 Technologies, Inc.
+ * Copyright (c) 2004-2009 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 "ath9k.h"
+
+static struct ath_rate_table ar5416_11na_ratetable = {
+       42,
+       {
+               { 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.5 Mb */
+                       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, /* 150 Mb */
+                       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,
+       {
+               { 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,
+       {
+               { 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,
+       {
+               { 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,
+       {
+               { 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 inline int8_t median(int8_t a, int8_t b, int8_t c)
+{
+       if (a >= b) {
+               if (b >= c)
+                       return b;
+               else if (a > c)
+                       return c;
+               else
+                       return a;
+       } else {
+               if (a >= c)
+                       return a;
+               else if (b >= c)
+                       return c;
+               else
+                       return b;
+       }
+}
+
+static void ath_rc_sort_validrates(struct ath_rate_table *rate_table,
+                                  struct ath_rate_priv *ath_rc_priv)
+{
+       u8 i, j, idx, idx_next;
+
+       for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
+               for (j = 0; j <= i-1; j++) {
+                       idx = ath_rc_priv->valid_rate_index[j];
+                       idx_next = ath_rc_priv->valid_rate_index[j+1];
+
+                       if (rate_table->info[idx].ratekbps >
+                               rate_table->info[idx_next].ratekbps) {
+                               ath_rc_priv->valid_rate_index[j] = idx_next;
+                               ath_rc_priv->valid_rate_index[j+1] = idx;
+                       }
+               }
+       }
+}
+
+static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
+{
+       u8 i;
+
+       for (i = 0; i < ath_rc_priv->rate_table_size; i++)
+               ath_rc_priv->valid_rate_index[i] = 0;
+}
+
+static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
+                                          u8 index, int valid_tx_rate)
+{
+       ASSERT(index <= ath_rc_priv->rate_table_size);
+       ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
+}
+
+static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
+                                       u8 index)
+{
+       ASSERT(index <= ath_rc_priv->rate_table_size);
+       return ath_rc_priv->valid_rate_index[index];
+}
+
+static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
+                                             struct ath_rate_priv *ath_rc_priv,
+                                             u8 cur_valid_txrate,
+                                             u8 *next_idx)
+{
+       u8 i;
+
+       for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) {
+               if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
+                       *next_idx = ath_rc_priv->valid_rate_index[i+1];
+                       return 1;
+               }
+       }
+
+       /* No more valid rates */
+       *next_idx = 0;
+
+       return 0;
+}
+
+/* Return true only for single stream */
+
+static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
+{
+       if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
+               return 0;
+       if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
+               return 0;
+       if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
+               return 0;
+       if (!ignore_cw && WLAN_RC_PHY_HT(phy))
+               if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
+                       return 0;
+               if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
+                       return 0;
+       return 1;
+}
+
+static inline int
+ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
+                                struct ath_rate_priv *ath_rc_priv,
+                                u8 cur_valid_txrate, u8 *next_idx)
+{
+       int8_t i;
+
+       for (i = 1; i < ath_rc_priv->max_valid_rate ; i++) {
+               if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
+                       *next_idx = ath_rc_priv->valid_rate_index[i-1];
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
+                                struct ath_rate_table *rate_table,
+                                u32 capflag)
+{
+       u8 i, hi = 0;
+       u32 valid;
+
+       for (i = 0; i < rate_table->rate_cnt; i++) {
+               valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
+                        rate_table->info[i].valid_single_stream :
+                        rate_table->info[i].valid);
+               if (valid == 1) {
+                       u32 phy = rate_table->info[i].phy;
+                       u8 valid_rate_count = 0;
+
+                       if (!ath_rc_valid_phyrate(phy, capflag, 0))
+                               continue;
+
+                       valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
+
+                       ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
+                       ath_rc_priv->valid_phy_ratecnt[phy] += 1;
+                       ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
+                       hi = A_MAX(hi, i);
+               }
+       }
+
+       return hi;
+}
+
+static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
+                               struct ath_rate_table *rate_table,
+                               struct ath_rateset *rateset,
+                               u32 capflag)
+{
+       u8 i, j, hi = 0;
+
+       /* Use intersection of working rates and valid rates */
+       for (i = 0; i < rateset->rs_nrates; i++) {
+               for (j = 0; j < rate_table->rate_cnt; j++) {
+                       u32 phy = rate_table->info[j].phy;
+                       u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
+                                    rate_table->info[j].valid_single_stream :
+                                    rate_table->info[j].valid);
+                       u8 rate = rateset->rs_rates[i];
+                       u8 dot11rate = rate_table->info[j].dot11rate;
+
+                       /* We allow a rate only if its valid and the
+                        * capflag matches one of the validity
+                        * (VALID/VALID_20/VALID_40) flags */
+
+                       if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
+                           ((valid & WLAN_RC_CAP_MODE(capflag)) ==
+                            WLAN_RC_CAP_MODE(capflag)) &&
+                           !WLAN_RC_PHY_HT(phy)) {
+                               u8 valid_rate_count = 0;
+
+                               if (!ath_rc_valid_phyrate(phy, capflag, 0))
+                                       continue;
+
+                               valid_rate_count =
+                                       ath_rc_priv->valid_phy_ratecnt[phy];
+
+                               ath_rc_priv->valid_phy_rateidx[phy]
+                                       [valid_rate_count] = j;
+                               ath_rc_priv->valid_phy_ratecnt[phy] += 1;
+                               ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
+                               hi = A_MAX(hi, j);
+                       }
+               }
+       }
+
+       return hi;
+}
+
+static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
+                                 struct ath_rate_table *rate_table,
+                                 u8 *mcs_set, u32 capflag)
+{
+       struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
+
+       u8 i, j, hi = 0;
+
+       /* Use intersection of working rates and valid rates */
+       for (i = 0; i < rateset->rs_nrates; i++) {
+               for (j = 0; j < rate_table->rate_cnt; j++) {
+                       u32 phy = rate_table->info[j].phy;
+                       u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
+                                    rate_table->info[j].valid_single_stream :
+                                    rate_table->info[j].valid);
+                       u8 rate = rateset->rs_rates[i];
+                       u8 dot11rate = rate_table->info[j].dot11rate;
+
+                       if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
+                           !WLAN_RC_PHY_HT(phy) ||
+                           !WLAN_RC_PHY_HT_VALID(valid, capflag))
+                               continue;
+
+                       if (!ath_rc_valid_phyrate(phy, capflag, 0))
+                               continue;
+
+                       ath_rc_priv->valid_phy_rateidx[phy]
+                               [ath_rc_priv->valid_phy_ratecnt[phy]] = j;
+                       ath_rc_priv->valid_phy_ratecnt[phy] += 1;
+                       ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
+                       hi = A_MAX(hi, j);
+               }
+       }
+
+       return hi;
+}
+
+static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
+                            struct ath_rate_priv *ath_rc_priv,
+                            struct ath_rate_table *rate_table,
+                            int *is_probing)
+{
+       u32 dt, best_thruput, this_thruput, now_msec;
+       u8 rate, next_rate, best_rate, maxindex, minindex;
+       int8_t  rssi_last, rssi_reduce = 0, index = 0;
+
+       *is_probing = 0;
+
+       rssi_last = median(ath_rc_priv->rssi_last,
+                          ath_rc_priv->rssi_last_prev,
+                          ath_rc_priv->rssi_last_prev2);
+
+       /*
+        * Age (reduce) last ack rssi based on how old it is.
+        * The bizarre numbers are so the delta is 160msec,
+        * meaning we divide by 16.
+        *   0msec   <= dt <= 25msec:   don't derate
+        *   25msec  <= dt <= 185msec:  derate linearly from 0 to 10dB
+        *   185msec <= dt:             derate by 10dB
+        */
+
+       now_msec = jiffies_to_msecs(jiffies);
+       dt = now_msec - ath_rc_priv->rssi_time;
+
+       if (dt >= 185)
+               rssi_reduce = 10;
+       else if (dt >= 25)
+               rssi_reduce = (u8)((dt - 25) >> 4);
+
+       /* Now reduce rssi_last by rssi_reduce */
+       if (rssi_last < rssi_reduce)
+               rssi_last = 0;
+       else
+               rssi_last -= rssi_reduce;
+
+       /*
+        * Now look up the rate in the rssi table and return it.
+        * If no rates match then we return 0 (lowest rate)
+        */
+
+       best_thruput = 0;
+       maxindex = ath_rc_priv->max_valid_rate-1;
+
+       minindex = 0;
+       best_rate = minindex;
+
+       /*
+        * Try the higher rate first. It will reduce memory moving time
+        * if we have very good channel characteristics.
+        */
+       for (index = maxindex; index >= minindex ; index--) {
+               u8 per_thres;
+
+               rate = ath_rc_priv->valid_rate_index[index];
+               if (rate > ath_rc_priv->rate_max_phy)
+                       continue;
+
+               /*
+                * For TCP the average collision rate is around 11%,
+                * so we ignore PERs less than this.  This is to
+                * prevent the rate we are currently using (whose
+                * PER might be in the 10-15 range because of TCP
+                * collisions) looking worse than the next lower
+                * rate whose PER has decayed close to 0.  If we
+                * used to next lower rate, its PER would grow to
+                * 10-15 and we would be worse off then staying
+                * at the current rate.
+                */
+               per_thres = ath_rc_priv->state[rate].per;
+               if (per_thres < 12)
+                       per_thres = 12;
+
+               this_thruput = rate_table->info[rate].user_ratekbps *
+                       (100 - per_thres);
+
+               if (best_thruput <= this_thruput) {
+                       best_thruput = this_thruput;
+                       best_rate    = rate;
+               }
+       }
+
+       rate = best_rate;
+       ath_rc_priv->rssi_last_lookup = rssi_last;
+
+       /*
+        * Must check the actual rate (ratekbps) to account for
+        * non-monoticity of 11g's rate table
+        */
+
+       if (rate >= ath_rc_priv->rate_max_phy) {
+               rate = ath_rc_priv->rate_max_phy;
+
+               /* Probe the next allowed phy state */
+               if (ath_rc_get_nextvalid_txrate(rate_table,
+                                       ath_rc_priv, rate, &next_rate) &&
+                   (now_msec - ath_rc_priv->probe_time >
+                    rate_table->probe_interval) &&
+                   (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
+                       rate = next_rate;
+                       ath_rc_priv->probe_rate = rate;
+                       ath_rc_priv->probe_time = now_msec;
+                       ath_rc_priv->hw_maxretry_pktcnt = 0;
+                       *is_probing = 1;
+               }
+       }
+
+       if (rate > (ath_rc_priv->rate_table_size - 1))
+               rate = ath_rc_priv->rate_table_size - 1;
+
+       ASSERT((rate_table->info[rate].valid &&
+               (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) ||
+              (rate_table->info[rate].valid_single_stream &&
+               !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)));
+
+       return rate;
+}
+
+static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
+                                  struct ieee80211_tx_rate *rate,
+                                  struct ieee80211_tx_rate_control *txrc,
+                                  u8 tries, u8 rix, int rtsctsenable)
+{
+       rate->count = tries;
+       rate->idx = rix;
+
+       if (txrc->short_preamble)
+               rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
+       if (txrc->rts || rtsctsenable)
+               rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
+       if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
+               rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+       if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
+               rate->flags |= IEEE80211_TX_RC_SHORT_GI;
+       if (WLAN_RC_PHY_HT(rate_table->info[rix].phy))
+               rate->flags |= IEEE80211_TX_RC_MCS;
+}
+
+static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
+                                  struct ath_rate_table *rate_table,
+                                  struct ieee80211_tx_info *tx_info)
+{
+       struct ieee80211_tx_rate *rates = tx_info->control.rates;
+       int i = 0, rix = 0, cix, enable_g_protection = 0;
+
+       /* get the cix for the lowest valid rix */
+       for (i = 3; i >= 0; i--) {
+               if (rates[i].count && (rates[i].idx >= 0)) {
+                       rix = rates[i].idx;
+                       break;
+               }
+       }
+       cix = rate_table->info[rix].ctrl_rate;
+
+       /* All protection frames are transmited at 2Mb/s for 802.11g,
+        * otherwise we transmit them at 1Mb/s */
+       if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
+           !conf_is_ht(&sc->hw->conf))
+               enable_g_protection = 1;
+
+       /*
+        * If 802.11g protection is enabled, determine whether to use RTS/CTS or
+        * just CTS.  Note that this is only done for OFDM/HT unicast frames.
+        */
+       if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
+           !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+           (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
+            WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
+               rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
+               cix = rate_table->info[enable_g_protection].ctrl_rate;
+       }
+
+       tx_info->control.rts_cts_rate_idx = cix;
+}
+
+static u8 ath_rc_rate_getidx(struct ath_softc *sc,
+                            struct ath_rate_priv *ath_rc_priv,
+                            struct ath_rate_table *rate_table,
+                            u8 rix, u16 stepdown,
+                            u16 min_rate)
+{
+       u32 j;
+       u8 nextindex;
+
+       if (min_rate) {
+               for (j = RATE_TABLE_SIZE; j > 0; j--) {
+                       if (ath_rc_get_nextlowervalid_txrate(rate_table,
+                                               ath_rc_priv, rix, &nextindex))
+                               rix = nextindex;
+                       else
+                               break;
+               }
+       } else {
+               for (j = stepdown; j > 0; j--) {
+                       if (ath_rc_get_nextlowervalid_txrate(rate_table,
+                                               ath_rc_priv, rix, &nextindex))
+                               rix = nextindex;
+                       else
+                               break;
+               }
+       }
+       return rix;
+}
+
+static void ath_rc_ratefind(struct ath_softc *sc,
+                           struct ath_rate_priv *ath_rc_priv,
+                           struct ieee80211_tx_rate_control *txrc)
+{
+       struct ath_rate_table *rate_table;
+       struct sk_buff *skb = txrc->skb;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_tx_rate *rates = tx_info->control.rates;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       __le16 fc = hdr->frame_control;
+       u8 try_per_rate = 0, i = 0, rix, nrix;
+       int is_probe = 0;
+
+       rate_table = sc->cur_rate_table;
+       rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
+       nrix = rix;
+
+       if (is_probe) {
+               /* set one try for probe rates. For the
+                * probes don't enable rts */
+               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+                                      1, nrix, 0);
+
+               try_per_rate = (ATH_11N_TXMAXTRY/4);
+               /* Get the next tried/allowed rate. No RTS for the next series
+                * after the probe rate
+                */
+               nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
+                                         rate_table, nrix, 1, 0);
+               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+                                      try_per_rate, nrix, 0);
+
+               tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
+       } else {
+               try_per_rate = (ATH_11N_TXMAXTRY/4);
+               /* Set the choosen rate. No RTS for first series entry. */
+               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+                                      try_per_rate, nrix, 0);
+       }
+
+       /* Fill in the other rates for multirate retry */
+       for ( ; i < 4; i++) {
+               u8 try_num;
+               u8 min_rate;
+
+               try_num = ((i + 1) == 4) ?
+                       ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
+               min_rate = (((i + 1) == 4) && 0);
+
+               nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
+                                         rate_table, nrix, 1, min_rate);
+               /* All other rates in the series have RTS enabled */
+               ath_rc_rate_set_series(rate_table, &rates[i], txrc,
+                                      try_num, nrix, 1);
+       }
+
+       /*
+        * NB:Change rate series to enable aggregation when operating
+        * at lower MCS rates. When first rate in series is MCS2
+        * in HT40 @ 2.4GHz, series should look like:
+        *
+        * {MCS2, MCS1, MCS0, MCS0}.
+        *
+        * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should
+        * look like:
+        *
+        * {MCS3, MCS2, MCS1, MCS1}
+        *
+        * So, set fourth rate in series to be same as third one for
+        * above conditions.
+        */
+       if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
+           (conf_is_ht(&sc->hw->conf))) {
+               u8 dot11rate = rate_table->info[rix].dot11rate;
+               u8 phy = rate_table->info[rix].phy;
+               if (i == 4 &&
+                   ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
+                    (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
+                       rates[3].idx = rates[2].idx;
+                       rates[3].flags = rates[2].flags;
+               }
+       }
+
+       /*
+        * Force hardware to use computed duration for next
+        * fragment by disabling multi-rate retry, which
+        * updates duration based on the multi-rate duration table.
+        *
+        * FIXME: Fix duration
+        */
+       if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+           (ieee80211_has_morefrags(fc) ||
+            (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
+               rates[1].count = rates[2].count = rates[3].count = 0;
+               rates[1].idx = rates[2].idx = rates[3].idx = 0;
+               rates[0].count = ATH_TXMAXTRY;
+       }
+
+       /* Setup RTS/CTS */
+       ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
+}
+
+static bool ath_rc_update_per(struct ath_softc *sc,
+                             struct ath_rate_table *rate_table,
+                             struct ath_rate_priv *ath_rc_priv,
+                             struct ath_tx_info_priv *tx_info_priv,
+                             int tx_rate, int xretries, int retries,
+                             u32 now_msec)
+{
+       bool state_change = false;
+       int count;
+       u8 last_per;
+       static u32 nretry_to_per_lookup[10] = {
+               100 * 0 / 1,
+               100 * 1 / 4,
+               100 * 1 / 2,
+               100 * 3 / 4,
+               100 * 4 / 5,
+               100 * 5 / 6,
+               100 * 6 / 7,
+               100 * 7 / 8,
+               100 * 8 / 9,
+               100 * 9 / 10
+       };
+
+       last_per = ath_rc_priv->state[tx_rate].per;
+
+       if (xretries) {
+               if (xretries == 1) {
+                       ath_rc_priv->state[tx_rate].per += 30;
+                       if (ath_rc_priv->state[tx_rate].per > 100)
+                               ath_rc_priv->state[tx_rate].per = 100;
+               } else {
+                       /* xretries == 2 */
+                       count = ARRAY_SIZE(nretry_to_per_lookup);
+                       if (retries >= count)
+                               retries = count - 1;
+
+                       /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
+                       ath_rc_priv->state[tx_rate].per =
+                               (u8)(last_per - (last_per >> 3) + (100 >> 3));
+               }
+
+               /* xretries == 1 or 2 */
+
+               if (ath_rc_priv->probe_rate == tx_rate)
+                       ath_rc_priv->probe_rate = 0;
+
+       } else { /* xretries == 0 */
+               count = ARRAY_SIZE(nretry_to_per_lookup);
+               if (retries >= count)
+                       retries = count - 1;
+
+               if (tx_info_priv->n_bad_frames) {
+                       /* new_PER = 7/8*old_PER + 1/8*(currentPER)
+                        * Assuming that n_frames is not 0.  The current PER
+                        * from the retries is 100 * retries / (retries+1),
+                        * since the first retries attempts failed, and the
+                        * next one worked.  For the one that worked,
+                        * n_bad_frames subframes out of n_frames wored,
+                        * so the PER for that part is
+                        * 100 * n_bad_frames / n_frames, and it contributes
+                        * 100 * n_bad_frames / (n_frames * (retries+1)) to
+                        * the above PER.  The expression below is a
+                        * simplified version of the sum of these two terms.
+                        */
+                       if (tx_info_priv->n_frames > 0) {
+                               int n_frames, n_bad_frames;
+                               u8 cur_per, new_per;
+
+                               n_bad_frames = retries * tx_info_priv->n_frames +
+                                       tx_info_priv->n_bad_frames;
+                               n_frames = tx_info_priv->n_frames * (retries + 1);
+                               cur_per = (100 * n_bad_frames / n_frames) >> 3;
+                               new_per = (u8)(last_per - (last_per >> 3) + cur_per);
+                               ath_rc_priv->state[tx_rate].per = new_per;
+                       }
+               } else {
+                       ath_rc_priv->state[tx_rate].per =
+                               (u8)(last_per - (last_per >> 3) +
+                                    (nretry_to_per_lookup[retries] >> 3));
+               }
+
+               ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
+               ath_rc_priv->rssi_last_prev  = ath_rc_priv->rssi_last;
+               ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi;
+               ath_rc_priv->rssi_time = now_msec;
+
+               /*
+                * If we got at most one retry then increase the max rate if
+                * this was a probe.  Otherwise, ignore the probe.
+                */
+               if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
+                       if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
+                               tx_info_priv->n_frames) {
+                               /*
+                                * Since we probed with just a single attempt,
+                                * any retries means the probe failed.  Also,
+                                * if the attempt worked, but more than half
+                                * the subframes were bad then also consider
+                                * the probe a failure.
+                                */
+                               ath_rc_priv->probe_rate = 0;
+                       } else {
+                               u8 probe_rate = 0;
+
+                               ath_rc_priv->rate_max_phy =
+                                       ath_rc_priv->probe_rate;
+                               probe_rate = ath_rc_priv->probe_rate;
+
+                               if (ath_rc_priv->state[probe_rate].per > 30)
+                                       ath_rc_priv->state[probe_rate].per = 20;
+
+                               ath_rc_priv->probe_rate = 0;
+
+                               /*
+                                * Since this probe succeeded, we allow the next
+                                * probe twice as soon.  This allows the maxRate
+                                * to move up faster if the probes are
+                                * succesful.
+                                */
+                               ath_rc_priv->probe_time =
+                                       now_msec - rate_table->probe_interval / 2;
+                       }
+               }
+
+               if (retries > 0) {
+                       /*
+                        * Don't update anything.  We don't know if
+                        * this was because of collisions or poor signal.
+                        *
+                        * Later: if rssi_ack is close to
+                        * ath_rc_priv->state[txRate].rssi_thres and we see lots
+                        * of retries, then we could increase
+                        * ath_rc_priv->state[txRate].rssi_thres.
+                        */
+                       ath_rc_priv->hw_maxretry_pktcnt = 0;
+               } else {
+                       int32_t rssi_ackAvg;
+                       int8_t rssi_thres;
+                       int8_t rssi_ack_vmin;
+
+                       /*
+                        * It worked with no retries. First ignore bogus (small)
+                        * rssi_ack values.
+                        */
+                       if (tx_rate == ath_rc_priv->rate_max_phy &&
+                           ath_rc_priv->hw_maxretry_pktcnt < 255) {
+                               ath_rc_priv->hw_maxretry_pktcnt++;
+                       }
+
+                       if (tx_info_priv->tx.ts_rssi <
+                           rate_table->info[tx_rate].rssi_ack_validmin)
+                               goto exit;
+
+                       /* Average the rssi */
+                       if (tx_rate != ath_rc_priv->rssi_sum_rate) {
+                               ath_rc_priv->rssi_sum_rate = tx_rate;
+                               ath_rc_priv->rssi_sum =
+                                       ath_rc_priv->rssi_sum_cnt = 0;
+                       }
+
+                       ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
+                       ath_rc_priv->rssi_sum_cnt++;
+
+                       if (ath_rc_priv->rssi_sum_cnt < 4)
+                               goto exit;
+
+                       rssi_ackAvg =
+                               (ath_rc_priv->rssi_sum + 2) / 4;
+                       rssi_thres =
+                               ath_rc_priv->state[tx_rate].rssi_thres;
+                       rssi_ack_vmin =
+                               rate_table->info[tx_rate].rssi_ack_validmin;
+
+                       ath_rc_priv->rssi_sum =
+                               ath_rc_priv->rssi_sum_cnt = 0;
+
+                       /* Now reduce the current rssi threshold */
+                       if ((rssi_ackAvg < rssi_thres + 2) &&
+                           (rssi_thres > rssi_ack_vmin)) {
+                               ath_rc_priv->state[tx_rate].rssi_thres--;
+                       }
+
+                       state_change = true;
+               }
+       }
+exit:
+       return state_change;
+}
+
+/* Update PER, RSSI and whatever else that the code thinks it is doing.
+   If you can make sense of all this, you really need to go out more. */
+
+static void ath_rc_update_ht(struct ath_softc *sc,
+                            struct ath_rate_priv *ath_rc_priv,
+                            struct ath_tx_info_priv *tx_info_priv,
+                            int tx_rate, int xretries, int retries)
+{
+#define CHK_RSSI(rate)                                 \
+       ((ath_rc_priv->state[(rate)].rssi_thres +       \
+         rate_table->info[(rate)].rssi_ack_deltamin) > \
+        ath_rc_priv->state[(rate)+1].rssi_thres)
+
+       u32 now_msec = jiffies_to_msecs(jiffies);
+       int rate;
+       u8 last_per;
+       bool state_change = false;
+       struct ath_rate_table *rate_table = sc->cur_rate_table;
+       int size = ath_rc_priv->rate_table_size;
+
+       if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
+               return;
+
+       /* To compensate for some imbalance between ctrl and ext. channel */
+
+       if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
+               tx_info_priv->tx.ts_rssi =
+                       tx_info_priv->tx.ts_rssi < 3 ? 0 :
+                       tx_info_priv->tx.ts_rssi - 3;
+
+       last_per = ath_rc_priv->state[tx_rate].per;
+
+       /* Update PER first */
+       state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
+                                        tx_info_priv, tx_rate, xretries,
+                                        retries, now_msec);
+
+       /*
+        * If this rate looks bad (high PER) then stop using it for
+        * a while (except if we are probing).
+        */
+       if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
+           rate_table->info[tx_rate].ratekbps <=
+           rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
+               ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
+                                (u8)tx_rate, &ath_rc_priv->rate_max_phy);
+
+               /* Don't probe for a little while. */
+               ath_rc_priv->probe_time = now_msec;
+       }
+
+       if (state_change) {
+               /*
+                * Make sure the rates above this have higher rssi thresholds.
+                * (Note:  Monotonicity is kept within the OFDM rates and
+                *         within the CCK rates. However, no adjustment is
+                *         made to keep the rssi thresholds monotonically
+                *         increasing between the CCK and OFDM rates.)
+                */
+               for (rate = tx_rate; rate < size - 1; rate++) {
+                       if (rate_table->info[rate+1].phy !=
+                           rate_table->info[tx_rate].phy)
+                               break;
+
+                       if (CHK_RSSI(rate)) {
+                               ath_rc_priv->state[rate+1].rssi_thres =
+                                       ath_rc_priv->state[rate].rssi_thres +
+                                       rate_table->info[rate].rssi_ack_deltamin;
+                       }
+               }
+
+               /* Make sure the rates below this have lower rssi thresholds. */
+               for (rate = tx_rate - 1; rate >= 0; rate--) {
+                       if (rate_table->info[rate].phy !=
+                           rate_table->info[tx_rate].phy)
+                               break;
+
+                       if (CHK_RSSI(rate)) {
+                               if (ath_rc_priv->state[rate+1].rssi_thres <
+                                   rate_table->info[rate].rssi_ack_deltamin)
+                                       ath_rc_priv->state[rate].rssi_thres = 0;
+                               else {
+                                       ath_rc_priv->state[rate].rssi_thres =
+                                       ath_rc_priv->state[rate+1].rssi_thres -
+                                       rate_table->info[rate].rssi_ack_deltamin;
+                               }
+
+                               if (ath_rc_priv->state[rate].rssi_thres <
+                                   rate_table->info[rate].rssi_ack_validmin) {
+                                       ath_rc_priv->state[rate].rssi_thres =
+                                       rate_table->info[rate].rssi_ack_validmin;
+                               }
+                       }
+               }
+       }
+
+       /* Make sure the rates below this have lower PER */
+       /* Monotonicity is kept only for rates below the current rate. */
+       if (ath_rc_priv->state[tx_rate].per < last_per) {
+               for (rate = tx_rate - 1; rate >= 0; rate--) {
+                       if (rate_table->info[rate].phy !=
+                           rate_table->info[tx_rate].phy)
+                               break;
+
+                       if (ath_rc_priv->state[rate].per >
+                           ath_rc_priv->state[rate+1].per) {
+                               ath_rc_priv->state[rate].per =
+                                       ath_rc_priv->state[rate+1].per;
+                       }
+               }
+       }
+
+       /* Maintain monotonicity for rates above the current rate */
+       for (rate = tx_rate; rate < size - 1; rate++) {
+               if (ath_rc_priv->state[rate+1].per <
+                   ath_rc_priv->state[rate].per)
+                       ath_rc_priv->state[rate+1].per =
+                               ath_rc_priv->state[rate].per;
+       }
+
+       /* Every so often, we reduce the thresholds and
+        * PER (different for CCK and OFDM). */
+       if (now_msec - ath_rc_priv->rssi_down_time >=
+           rate_table->rssi_reduce_interval) {
+
+               for (rate = 0; rate < size; rate++) {
+                       if (ath_rc_priv->state[rate].rssi_thres >
+                           rate_table->info[rate].rssi_ack_validmin)
+                               ath_rc_priv->state[rate].rssi_thres -= 1;
+               }
+               ath_rc_priv->rssi_down_time = now_msec;
+       }
+
+       /* Every so often, we reduce the thresholds
+        * and PER (different for CCK and OFDM). */
+       if (now_msec - ath_rc_priv->per_down_time >=
+           rate_table->rssi_reduce_interval) {
+               for (rate = 0; rate < size; rate++) {
+                       ath_rc_priv->state[rate].per =
+                               7 * ath_rc_priv->state[rate].per / 8;
+               }
+
+               ath_rc_priv->per_down_time = now_msec;
+       }
+
+       ath_debug_stat_retries(sc, tx_rate, xretries, retries,
+                              ath_rc_priv->state[tx_rate].per);
+
+#undef CHK_RSSI
+}
+
+static int ath_rc_get_rateindex(struct ath_rate_table *rate_table,
+                               struct ieee80211_tx_rate *rate)
+{
+       int rix;
+
+       if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+           (rate->flags & IEEE80211_TX_RC_SHORT_GI))
+               rix = rate_table->info[rate->idx].ht_index;
+       else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+               rix = rate_table->info[rate->idx].sgi_index;
+       else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+               rix = rate_table->info[rate->idx].cw40index;
+       else
+               rix = rate_table->info[rate->idx].base_index;
+
+       return rix;
+}
+
+static void ath_rc_tx_status(struct ath_softc *sc,
+                            struct ath_rate_priv *ath_rc_priv,
+                            struct ieee80211_tx_info *tx_info,
+                            int final_ts_idx, int xretries, int long_retry)
+{
+       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       struct ath_rate_table *rate_table;
+       struct ieee80211_tx_rate *rates = tx_info->status.rates;
+       u8 flags;
+       u32 i = 0, rix;
+
+       rate_table = sc->cur_rate_table;
+
+       /*
+        * If the first rate is not the final index, there
+        * are intermediate rate failures to be processed.
+        */
+       if (final_ts_idx != 0) {
+               /* Process intermediate rates that failed.*/
+               for (i = 0; i < final_ts_idx ; i++) {
+                       if (rates[i].count != 0 && (rates[i].idx >= 0)) {
+                               flags = rates[i].flags;
+
+                               /* If HT40 and we have switched mode from
+                                * 40 to 20 => don't update */
+
+                               if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+                                   !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
+                                       return;
+
+                               rix = ath_rc_get_rateindex(rate_table, &rates[i]);
+                               ath_rc_update_ht(sc, ath_rc_priv,
+                                               tx_info_priv, rix,
+                                               xretries ? 1 : 2,
+                                               rates[i].count);
+                       }
+               }
+       } else {
+               /*
+                * Handle the special case of MIMO PS burst, where the second
+                * aggregate is sent out with only one rate and one try.
+                * Treating it as an excessive retry penalizes the rate
+                * inordinately.
+                */
+               if (rates[0].count == 1 && xretries == 1)
+                       xretries = 2;
+       }
+
+       flags = rates[i].flags;
+
+       /* If HT40 and we have switched mode from 40 to 20 => don't update */
+       if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+           !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
+               return;
+
+       rix = ath_rc_get_rateindex(rate_table, &rates[i]);
+       ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
+                        xretries, long_retry);
+}
+
+static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
+                                                   enum ieee80211_band band,
+                                                   bool is_ht, bool is_cw_40)
+{
+       int mode = 0;
+
+       switch(band) {
+       case IEEE80211_BAND_2GHZ:
+               mode = ATH9K_MODE_11G;
+               if (is_ht)
+                       mode = ATH9K_MODE_11NG_HT20;
+               if (is_cw_40)
+                       mode = ATH9K_MODE_11NG_HT40PLUS;
+               break;
+       case IEEE80211_BAND_5GHZ:
+               mode = ATH9K_MODE_11A;
+               if (is_ht)
+                       mode = ATH9K_MODE_11NA_HT20;
+               if (is_cw_40)
+                       mode = ATH9K_MODE_11NA_HT40PLUS;
+               break;
+       default:
+               DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n");
+               return NULL;
+       }
+
+       BUG_ON(mode >= ATH9K_MODE_MAX);
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode);
+       return sc->hw_rate_table[mode];
+}
+
+static void ath_rc_init(struct ath_softc *sc,
+                       struct ath_rate_priv *ath_rc_priv,
+                       struct ieee80211_supported_band *sband,
+                       struct ieee80211_sta *sta,
+                       struct ath_rate_table *rate_table)
+{
+       struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
+       u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
+       u8 i, j, k, hi = 0, hthi = 0;
+
+       if (!rate_table) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
+               return;
+       }
+
+       /* Initial rate table size. Will change depending
+        * on the working rate set */
+       ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
+
+       /* Initialize thresholds according to the global rate table */
+       for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
+               ath_rc_priv->state[i].rssi_thres =
+                       rate_table->info[i].rssi_ack_validmin;
+               ath_rc_priv->state[i].per = 0;
+       }
+
+       /* Determine the valid rates */
+       ath_rc_init_valid_txmask(ath_rc_priv);
+
+       for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
+               for (j = 0; j < MAX_TX_RATE_PHY; j++)
+                       ath_rc_priv->valid_phy_rateidx[i][j] = 0;
+               ath_rc_priv->valid_phy_ratecnt[i] = 0;
+       }
+
+       if (!rateset->rs_nrates) {
+               /* No working rate, just initialize valid rates */
+               hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
+                                           ath_rc_priv->ht_cap);
+       } else {
+               /* Use intersection of working rates and valid rates */
+               hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
+                                          rateset, ath_rc_priv->ht_cap);
+               if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
+                       hthi = ath_rc_setvalid_htrates(ath_rc_priv,
+                                                      rate_table,
+                                                      ht_mcs,
+                                                      ath_rc_priv->ht_cap);
+               }
+               hi = A_MAX(hi, hthi);
+       }
+
+       ath_rc_priv->rate_table_size = hi + 1;
+       ath_rc_priv->rate_max_phy = 0;
+       ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
+
+       for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
+               for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
+                       ath_rc_priv->valid_rate_index[k++] =
+                               ath_rc_priv->valid_phy_rateidx[i][j];
+               }
+
+               if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1)
+                   || !ath_rc_priv->valid_phy_ratecnt[i])
+                       continue;
+
+               ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
+       }
+       ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
+       ASSERT(k <= RATE_TABLE_SIZE);
+
+       ath_rc_priv->max_valid_rate = k;
+       ath_rc_sort_validrates(rate_table, ath_rc_priv);
+       ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
+       sc->cur_rate_table = rate_table;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n",
+               ath_rc_priv->ht_cap);
+}
+
+static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
+                              bool is_cw40, bool is_sgi40)
+{
+       u8 caps = 0;
+
+       if (sta->ht_cap.ht_supported) {
+               caps = WLAN_RC_HT_FLAG;
+               if (sc->sc_ah->caps.tx_chainmask != 1 &&
+                   ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
+                       if (sta->ht_cap.mcs.rx_mask[1])
+                               caps |= WLAN_RC_DS_FLAG;
+               }
+               if (is_cw40)
+                       caps |= WLAN_RC_40_FLAG;
+               if (is_sgi40)
+                       caps |= WLAN_RC_SGI_FLAG;
+       }
+
+       return caps;
+}
+
+/***********************************/
+/* mac80211 Rate Control callbacks */
+/***********************************/
+
+static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
+                         struct ieee80211_sta *sta, void *priv_sta,
+                         struct sk_buff *skb)
+{
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *ath_rc_priv = priv_sta;
+       struct ath_tx_info_priv *tx_info_priv = NULL;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr;
+       int final_ts_idx, tx_status = 0, is_underrun = 0;
+       __le16 fc;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       final_ts_idx = tx_info_priv->tx.ts_rateindex;
+
+       if (!priv_sta || !ieee80211_is_data(fc) ||
+           !tx_info_priv->update_rc)
+               goto exit;
+
+       if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
+               goto exit;
+
+       /*
+        * If underrun error is seen assume it as an excessive retry only
+        * if prefetch trigger level have reached the max (0x3f for 5416)
+        * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
+        * times. This affects how ratectrl updates PER for the failed rate.
+        */
+       if (tx_info_priv->tx.ts_flags &
+           (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
+           ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
+               tx_status = 1;
+               is_underrun = 1;
+       }
+
+       if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) ||
+           (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
+               tx_status = 1;
+
+       ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
+                        (is_underrun) ? ATH_11N_TXMAXTRY :
+                        tx_info_priv->tx.ts_longretry);
+
+       /* Check if aggregation has to be enabled for this tid */
+       if (conf_is_ht(&sc->hw->conf) &&
+           !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+               if (ieee80211_is_data_qos(fc)) {
+                       u8 *qc, tid;
+                       struct ath_node *an;
+
+                       qc = ieee80211_get_qos_ctl(hdr);
+                       tid = qc[0] & 0xf;
+                       an = (struct ath_node *)sta->drv_priv;
+
+                       if(ath_tx_aggr_check(sc, an, tid))
+                               ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid);
+               }
+       }
+
+       ath_debug_stat_rc(sc, skb);
+exit:
+       kfree(tx_info_priv);
+}
+
+static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+                        struct ieee80211_tx_rate_control *txrc)
+{
+       struct ieee80211_supported_band *sband = txrc->sband;
+       struct sk_buff *skb = txrc->skb;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *ath_rc_priv = priv_sta;
+       __le16 fc = hdr->frame_control;
+
+       /* lowest rate for management and multicast/broadcast frames */
+       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
+           !sta) {
+               tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
+               tx_info->control.rates[0].count =
+                       is_multicast_ether_addr(hdr->addr1) ? 1 : ATH_MGT_TXMAXTRY;
+               return;
+       }
+
+       /* Find tx rate for unicast frames */
+       ath_rc_ratefind(sc, ath_rc_priv, txrc);
+}
+
+static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
+                          struct ieee80211_sta *sta, void *priv_sta)
+{
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *ath_rc_priv = priv_sta;
+       struct ath_rate_table *rate_table = NULL;
+       bool is_cw40, is_sgi40;
+       int i, j = 0;
+
+       for (i = 0; i < sband->n_bitrates; i++) {
+               if (sta->supp_rates[sband->band] & BIT(i)) {
+                       ath_rc_priv->neg_rates.rs_rates[j]
+                               = (sband->bitrates[i].bitrate * 2) / 10;
+                       j++;
+               }
+       }
+       ath_rc_priv->neg_rates.rs_nrates = j;
+
+       if (sta->ht_cap.ht_supported) {
+               for (i = 0, j = 0; i < 77; i++) {
+                       if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
+                               ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
+                       if (j == ATH_RATE_MAX)
+                               break;
+               }
+               ath_rc_priv->neg_ht_rates.rs_nrates = j;
+       }
+
+       is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+       is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+
+       /* Choose rate table first */
+
+       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
+               rate_table = ath_choose_rate_table(sc, sband->band,
+                                                  sta->ht_cap.ht_supported,
+                                                  is_cw40);
+       } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
+               /* cur_rate_table would be set on init through config() */
+               rate_table = sc->cur_rate_table;
+       }
+
+       ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
+       ath_rc_init(sc, priv_sta, sband, sta, rate_table);
+}
+
+static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
+                           struct ieee80211_sta *sta, void *priv_sta,
+                           u32 changed)
+{
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *ath_rc_priv = priv_sta;
+       struct ath_rate_table *rate_table = NULL;
+       bool oper_cw40 = false, oper_sgi40;
+       bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
+               true : false;
+       bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
+               true : false;
+
+       /* FIXME: Handle AP mode later when we support CWM */
+
+       if (changed & IEEE80211_RC_HT_CHANGED) {
+               if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+                       return;
+
+               if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
+                   sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
+                       oper_cw40 = true;
+
+               oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+                       true : false;
+
+               if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
+                       rate_table = ath_choose_rate_table(sc, sband->band,
+                                                  sta->ht_cap.ht_supported,
+                                                  oper_cw40);
+                       ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
+                                                  oper_cw40, oper_sgi40);
+                       ath_rc_init(sc, priv_sta, sband, sta, rate_table);
+
+                       DPRINTF(sc, ATH_DBG_CONFIG,
+                               "Operating HT Bandwidth changed to: %d\n",
+                               sc->hw->conf.channel_type);
+               }
+       }
+}
+
+static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       return aphy->sc;
+}
+
+static void ath_rate_free(void *priv)
+{
+       return;
+}
+
+static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
+{
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *rate_priv;
+
+       rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
+       if (!rate_priv) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to allocate private rc structure\n");
+               return NULL;
+       }
+
+       rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
+       rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
+
+       return rate_priv;
+}
+
+static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
+                             void *priv_sta)
+{
+       struct ath_rate_priv *rate_priv = priv_sta;
+       kfree(rate_priv);
+}
+
+static struct rate_control_ops ath_rate_ops = {
+       .module = NULL,
+       .name = "ath9k_rate_control",
+       .tx_status = ath_tx_status,
+       .get_rate = ath_get_rate,
+       .rate_init = ath_rate_init,
+       .rate_update = ath_rate_update,
+       .alloc = ath_rate_alloc,
+       .free = ath_rate_free,
+       .alloc_sta = ath_rate_alloc_sta,
+       .free_sta = ath_rate_free_sta,
+};
+
+void ath_rate_attach(struct ath_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;
+}
+
+int ath_rate_control_register(void)
+{
+       return ieee80211_rate_control_register(&ath_rate_ops);
+}
+
+void ath_rate_control_unregister(void)
+{
+       ieee80211_rate_control_unregister(&ath_rate_ops);
+}
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
new file mode 100644 (file)
index 0000000..e3abd76
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2004 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004 Video54 Technologies, Inc.
+ * Copyright (c) 2008-2009 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 RC_H
+#define RC_H
+
+struct ath_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)
+
+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
+};
+
+#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;
+       struct {
+               int valid;
+               int valid_single_stream;
+               u8 phy;
+               u32 ratekbps;
+               u32 user_ratekbps;
+               u8 ratecode;
+               u8 short_preamble;
+               u8 dot11rate;
+               u8 ctrl_rate;
+               int8_t rssi_ack_validmin;
+               int8_t rssi_ack_deltamin;
+               u8 base_index;
+               u8 cw40index;
+               u8 sgi_index;
+               u8 ht_index;
+               u32 max_4ms_framelen;
+       } info[RATE_TABLE_SIZE];
+       u32 probe_interval;
+       u32 rssi_reduce_interval;
+       u8 initial_ratemax;
+};
+
+struct ath_tx_ratectrl_state {
+       int8_t rssi_thres;      /* required rssi for this rate (dB) */
+       u8 per;                 /* recent estimate of packet error rate (%) */
+};
+
+struct ath_rateset {
+       u8 rs_nrates;
+       u8 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
+ * @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;
+       u8 rate_table_size;
+       u8 probe_rate;
+       u8 hw_maxretry_pktcnt;
+       u8 max_valid_rate;
+       u8 valid_rate_index[RATE_TABLE_SIZE];
+       u8 ht_cap;
+       u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
+       u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
+       u8 rate_max_phy;
+       u32 rssi_time;
+       u32 rssi_down_time;
+       u32 probe_time;
+       u32 per_down_time;
+       u32 probe_interval;
+       u32 prev_data_rix;
+       u32 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_rate_softc *asc;
+};
+
+enum ath9k_internal_frame_type {
+       ATH9K_NOT_INTERNAL,
+       ATH9K_INT_PAUSE,
+       ATH9K_INT_UNPAUSE
+};
+
+struct ath_tx_info_priv {
+       struct ath_wiphy *aphy;
+       struct ath_tx_status tx;
+       int n_frames;
+       int n_bad_frames;
+       bool update_rc;
+       enum ath9k_internal_frame_type frame_type;
+};
+
+#define ATH_TX_INFO_PRIV(tx_info) \
+       ((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0]))
+
+void ath_rate_attach(struct ath_softc *sc);
+u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate);
+int ath_rate_control_register(void);
+void ath_rate_control_unregister(void);
+
+#endif /* RC_H */
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
new file mode 100644 (file)
index 0000000..b46badd
--- /dev/null
@@ -0,0 +1,704 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
+                                            struct ieee80211_hdr *hdr)
+{
+       struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+       int i;
+
+       spin_lock_bh(&sc->wiphy_lock);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               struct ath_wiphy *aphy = sc->sec_wiphy[i];
+               if (aphy == NULL)
+                       continue;
+               if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr)
+                   == 0) {
+                       hw = aphy->hw;
+                       break;
+               }
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+       return hw;
+}
+
+/*
+ * Setup and link descriptors.
+ *
+ * 11N: we can no longer afford to self link the last descriptor.
+ * MAC acknowledges BA status as long as it copies frames to host
+ * buffer (or rx fifo). This can incorrectly acknowledge packets
+ * to a sender if last desc is self-linked.
+ */
+static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_desc *ds;
+       struct sk_buff *skb;
+
+       ATH_RXBUF_RESET(bf);
+
+       ds = bf->bf_desc;
+       ds->ds_link = 0; /* link to null */
+       ds->ds_data = bf->bf_buf_addr;
+
+       /* virtual addr of the beginning of the buffer. */
+       skb = bf->bf_mpdu;
+       ASSERT(skb != NULL);
+       ds->ds_vdata = skb->data;
+
+       /* setup rx descriptors. The rx.bufsize here tells the harware
+        * how much data it can DMA to us and that we are prepared
+        * to process */
+       ath9k_hw_setuprxdesc(ah, ds,
+                            sc->rx.bufsize,
+                            0);
+
+       if (sc->rx.rxlink == NULL)
+               ath9k_hw_putrxbuf(ah, bf->bf_daddr);
+       else
+               *sc->rx.rxlink = bf->bf_daddr;
+
+       sc->rx.rxlink = &ds->ds_link;
+       ath9k_hw_rxena(ah);
+}
+
+static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
+{
+       /* XXX block beacon interrupts */
+       ath9k_hw_setantenna(sc->sc_ah, antenna);
+       sc->rx.defant = antenna;
+       sc->rx.rxotherant = 0;
+}
+
+/*
+ *  Extend 15-bit time stamp from rx descriptor to
+ *  a full 64-bit TSF using the current h/w TSF.
+*/
+static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
+{
+       u64 tsf;
+
+       tsf = ath9k_hw_gettsf64(sc->sc_ah);
+       if ((tsf & 0x7fff) < rstamp)
+               tsf -= 0x8000;
+       return (tsf & ~0x7fff) | rstamp;
+}
+
+static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
+{
+       struct sk_buff *skb;
+       u32 off;
+
+       /*
+        * Cache-line-align.  This is important (for the
+        * 5210 at least) as not doing so causes bogus data
+        * in rx'd frames.
+        */
+
+       /* Note: the kernel can allocate a value greater than
+        * what we ask it to give us. We really only need 4 KB as that
+        * is this hardware supports and in fact we need at least 3849
+        * as that is the MAX AMSDU size this hardware supports.
+        * Unfortunately this means we may get 8 KB here from the
+        * kernel... and that is actually what is observed on some
+        * systems :( */
+       skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
+       if (skb != NULL) {
+               off = ((unsigned long) skb->data) % sc->cachelsz;
+               if (off != 0)
+                       skb_reserve(skb, sc->cachelsz - off);
+       } else {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "skbuff alloc of size %u failed\n", len);
+               return NULL;
+       }
+
+       return skb;
+}
+
+/*
+ * For Decrypt or Demic errors, we only mark packet status here and always push
+ * up the frame up to let mac80211 handle the actual error case, be it no
+ * decryption key or real decryption error. This let us keep statistics there.
+ */
+static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
+                         struct ieee80211_rx_status *rx_status, bool *decrypt_error,
+                         struct ath_softc *sc)
+{
+       struct ieee80211_hdr *hdr;
+       u8 ratecode;
+       __le16 fc;
+       struct ieee80211_hw *hw;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+       memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
+       hw = ath_get_virt_hw(sc, hdr);
+
+       if (ds->ds_rxstat.rs_more) {
+               /*
+                * Frame spans multiple descriptors; this cannot happen yet
+                * as we don't support jumbograms. If not in monitor mode,
+                * discard the frame. Enable this if you want to see
+                * error frames in Monitor mode.
+                */
+               if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
+                       goto rx_next;
+       } else if (ds->ds_rxstat.rs_status != 0) {
+               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
+                       rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY)
+                       goto rx_next;
+
+               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
+                       *decrypt_error = true;
+               } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
+                       if (ieee80211_is_ctl(fc))
+                               /*
+                                * Sometimes, we get invalid
+                                * MIC failures on valid control frames.
+                                * Remove these mic errors.
+                                */
+                               ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC;
+                       else
+                               rx_status->flag |= RX_FLAG_MMIC_ERROR;
+               }
+               /*
+                * Reject error frames with the exception of
+                * decryption and MIC failures. For monitor mode,
+                * we also ignore the CRC error.
+                */
+               if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
+                       if (ds->ds_rxstat.rs_status &
+                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
+                             ATH9K_RXERR_CRC))
+                               goto rx_next;
+               } else {
+                       if (ds->ds_rxstat.rs_status &
+                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
+                               goto rx_next;
+                       }
+               }
+       }
+
+       ratecode = ds->ds_rxstat.rs_rate;
+
+       if (ratecode & 0x80) {
+               /* HT rate */
+               rx_status->flag |= RX_FLAG_HT;
+               if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040)
+                       rx_status->flag |= RX_FLAG_40MHZ;
+               if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
+                       rx_status->flag |= RX_FLAG_SHORT_GI;
+               rx_status->rate_idx = ratecode & 0x7f;
+       } else {
+               int i = 0, cur_band, n_rates;
+
+               cur_band = hw->conf.channel->band;
+               n_rates = sc->sbands[cur_band].n_bitrates;
+
+               for (i = 0; i < n_rates; i++) {
+                       if (sc->sbands[cur_band].bitrates[i].hw_value ==
+                           ratecode) {
+                               rx_status->rate_idx = i;
+                               break;
+                       }
+
+                       if (sc->sbands[cur_band].bitrates[i].hw_value_short ==
+                           ratecode) {
+                               rx_status->rate_idx = i;
+                               rx_status->flag |= RX_FLAG_SHORTPRE;
+                               break;
+                       }
+               }
+       }
+
+       rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
+       rx_status->band = hw->conf.channel->band;
+       rx_status->freq = hw->conf.channel->center_freq;
+       rx_status->noise = sc->ani.noise_floor;
+       rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
+       rx_status->antenna = ds->ds_rxstat.rs_antenna;
+
+       /* at 45 you will be able to use MCS 15 reliably. A more elaborate
+        * scheme can be used here but it requires tables of SNR/throughput for
+        * each possible mode used. */
+       rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
+
+       /* rssi can be more than 45 though, anything above that
+        * should be considered at 100% */
+       if (rx_status->qual > 100)
+               rx_status->qual = 100;
+
+       rx_status->flag |= RX_FLAG_TSFT;
+
+       return 1;
+rx_next:
+       return 0;
+}
+
+static void ath_opmode_init(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       u32 rfilt, mfilt[2];
+
+       /* configure rx filter */
+       rfilt = ath_calcrxfilter(sc);
+       ath9k_hw_setrxfilter(ah, rfilt);
+
+       /* configure bssid mask */
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+               ath9k_hw_setbssidmask(sc);
+
+       /* configure operational mode */
+       ath9k_hw_setopmode(ah);
+
+       /* Handle any link-level address change. */
+       ath9k_hw_setmac(ah, sc->sc_ah->macaddr);
+
+       /* calculate and install multicast filter */
+       mfilt[0] = mfilt[1] = ~0;
+       ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
+}
+
+int ath_rx_init(struct ath_softc *sc, int nbufs)
+{
+       struct sk_buff *skb;
+       struct ath_buf *bf;
+       int error = 0;
+
+       spin_lock_init(&sc->rx.rxflushlock);
+       sc->sc_flags &= ~SC_OP_RXFLUSH;
+       spin_lock_init(&sc->rx.rxbuflock);
+
+       sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
+                                min(sc->cachelsz, (u16)64));
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
+               sc->cachelsz, sc->rx.bufsize);
+
+       /* Initialize rx descriptors */
+
+       error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
+                                 "rx", nbufs, 1);
+       if (error != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "failed to allocate rx descriptors: %d\n", error);
+               goto err;
+       }
+
+       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+               skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
+               if (skb == NULL) {
+                       error = -ENOMEM;
+                       goto err;
+               }
+
+               bf->bf_mpdu = skb;
+               bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+                                                sc->rx.bufsize,
+                                                DMA_FROM_DEVICE);
+               if (unlikely(dma_mapping_error(sc->dev,
+                                              bf->bf_buf_addr))) {
+                       dev_kfree_skb_any(skb);
+                       bf->bf_mpdu = NULL;
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "dma_mapping_error() on RX init\n");
+                       error = -ENOMEM;
+                       goto err;
+               }
+               bf->bf_dmacontext = bf->bf_buf_addr;
+       }
+       sc->rx.rxlink = NULL;
+
+err:
+       if (error)
+               ath_rx_cleanup(sc);
+
+       return error;
+}
+
+void ath_rx_cleanup(struct ath_softc *sc)
+{
+       struct sk_buff *skb;
+       struct ath_buf *bf;
+
+       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+               skb = bf->bf_mpdu;
+               if (skb) {
+                       dma_unmap_single(sc->dev, bf->bf_buf_addr,
+                                        sc->rx.bufsize, DMA_FROM_DEVICE);
+                       dev_kfree_skb(skb);
+               }
+       }
+
+       if (sc->rx.rxdma.dd_desc_len != 0)
+               ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
+}
+
+/*
+ * 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
+ */
+
+u32 ath_calcrxfilter(struct ath_softc *sc)
+{
+#define        RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
+
+       u32 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->opmode != NL80211_IFTYPE_STATION)
+               rfilt |= ATH9K_RX_FILTER_PROBEREQ;
+
+       /*
+        * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
+        * mode interface or when in monitor mode. AP mode does not need this
+        * since it receives all in-BSS frames anyway.
+        */
+       if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
+            (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
+               rfilt |= ATH9K_RX_FILTER_PROM;
+
+       if (sc->rx.rxfilter & FIF_CONTROL)
+               rfilt |= ATH9K_RX_FILTER_CONTROL;
+
+       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+           !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC))
+               rfilt |= ATH9K_RX_FILTER_MYBEACON;
+       else
+               rfilt |= ATH9K_RX_FILTER_BEACON;
+
+       /* If in HOSTAP mode, want to enable reception of PSPOLL frames */
+       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
+               rfilt |= ATH9K_RX_FILTER_PSPOLL;
+
+       if (sc->sec_wiphy) {
+               /* TODO: only needed if more than one BSSID is in use in
+                * station/adhoc mode */
+               /* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM
+                */
+               rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
+       }
+
+       return rfilt;
+
+#undef RX_FILTER_PRESERVE
+}
+
+int ath_startrecv(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf, *tbf;
+
+       spin_lock_bh(&sc->rx.rxbuflock);
+       if (list_empty(&sc->rx.rxbuf))
+               goto start_recv;
+
+       sc->rx.rxlink = NULL;
+       list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
+               ath_rx_buf_link(sc, bf);
+       }
+
+       /* We could have deleted elements so the list may be empty now */
+       if (list_empty(&sc->rx.rxbuf))
+               goto start_recv;
+
+       bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+       ath9k_hw_putrxbuf(ah, bf->bf_daddr);
+       ath9k_hw_rxena(ah);
+
+start_recv:
+       spin_unlock_bh(&sc->rx.rxbuflock);
+       ath_opmode_init(sc);
+       ath9k_hw_startpcureceive(ah);
+
+       return 0;
+}
+
+bool ath_stoprecv(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       bool stopped;
+
+       ath9k_hw_stoppcurecv(ah);
+       ath9k_hw_setrxfilter(ah, 0);
+       stopped = ath9k_hw_stopdmarecv(ah);
+       sc->rx.rxlink = NULL;
+
+       return stopped;
+}
+
+void ath_flushrecv(struct ath_softc *sc)
+{
+       spin_lock_bh(&sc->rx.rxflushlock);
+       sc->sc_flags |= SC_OP_RXFLUSH;
+       ath_rx_tasklet(sc, 1);
+       sc->sc_flags &= ~SC_OP_RXFLUSH;
+       spin_unlock_bh(&sc->rx.rxflushlock);
+}
+
+int ath_rx_tasklet(struct ath_softc *sc, int flush)
+{
+#define PA2DESC(_sc, _pa)                                               \
+       ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc +         \
+                            ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
+
+       struct ath_buf *bf;
+       struct ath_desc *ds;
+       struct sk_buff *skb = NULL, *requeue_skb;
+       struct ieee80211_rx_status rx_status;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ieee80211_hdr *hdr;
+       int hdrlen, padsize, retval;
+       bool decrypt_error = false;
+       u8 keyix;
+       __le16 fc;
+
+       spin_lock_bh(&sc->rx.rxbuflock);
+
+       do {
+               /* If handling rx interrupt and flush is in progress => exit */
+               if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
+                       break;
+
+               if (list_empty(&sc->rx.rxbuf)) {
+                       sc->rx.rxlink = NULL;
+                       break;
+               }
+
+               bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+               ds = bf->bf_desc;
+
+               /*
+                * 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.
+                */
+               retval = ath9k_hw_rxprocdesc(ah, ds,
+                                            bf->bf_daddr,
+                                            PA2DESC(sc, ds->ds_link),
+                                            0);
+               if (retval == -EINPROGRESS) {
+                       struct ath_buf *tbf;
+                       struct ath_desc *tds;
+
+                       if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
+                               sc->rx.rxlink = NULL;
+                               break;
+                       }
+
+                       tbf = list_entry(bf->list.next, struct ath_buf, list);
+
+                       /*
+                        * On some hardware the descriptor status words could
+                        * get corrupted, including the done bit. Because of
+                        * this, check if the next descriptor's done bit is
+                        * set or not.
+                        *
+                        * If the next descriptor's done bit is set, the current
+                        * descriptor has been corrupted. Force s/w to discard
+                        * this descriptor and continue...
+                        */
+
+                       tds = tbf->bf_desc;
+                       retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr,
+                                            PA2DESC(sc, tds->ds_link), 0);
+                       if (retval == -EINPROGRESS) {
+                               break;
+                       }
+               }
+
+               skb = bf->bf_mpdu;
+               if (!skb)
+                       continue;
+
+               /*
+                * Synchronize the DMA transfer with CPU before
+                * 1. accessing the frame
+                * 2. requeueing the same buffer to h/w
+                */
+               dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
+                               sc->rx.bufsize,
+                               DMA_FROM_DEVICE);
+
+               /*
+                * If we're asked to flush receive queue, directly
+                * chain it back at the queue without processing it.
+                */
+               if (flush)
+                       goto requeue;
+
+               if (!ds->ds_rxstat.rs_datalen)
+                       goto requeue;
+
+               /* The status portion of the descriptor could get corrupted. */
+               if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
+                       goto requeue;
+
+               if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
+                       goto requeue;
+
+               /* Ensure we always have an skb to requeue once we are done
+                * processing the current buffer's skb */
+               requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC);
+
+               /* If there is no memory we ignore the current RX'd frame,
+                * tell hardware it can give us a new frame using the old
+                * skb and put it at the tail of the sc->rx.rxbuf list for
+                * processing. */
+               if (!requeue_skb)
+                       goto requeue;
+
+               /* Unmap the frame */
+               dma_unmap_single(sc->dev, bf->bf_buf_addr,
+                                sc->rx.bufsize,
+                                DMA_FROM_DEVICE);
+
+               skb_put(skb, ds->ds_rxstat.rs_datalen);
+               skb->protocol = cpu_to_be16(ETH_P_CONTROL);
+
+               /* see if any padding is done by the hw and remove it */
+               hdr = (struct ieee80211_hdr *)skb->data;
+               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+               fc = hdr->frame_control;
+
+               /* The MAC header is padded to have 32-bit boundary if the
+                * packet payload is non-zero. The general calculation for
+                * padsize would take into account odd header lengths:
+                * padsize = (4 - hdrlen % 4) % 4; However, since only
+                * even-length headers are used, padding can only be 0 or 2
+                * bytes and we can optimize this a bit. In addition, we must
+                * not try to remove padding from short control frames that do
+                * not have payload. */
+               padsize = hdrlen & 3;
+               if (padsize && hdrlen >= 24) {
+                       memmove(skb->data + padsize, skb->data, hdrlen);
+                       skb_pull(skb, padsize);
+               }
+
+               keyix = ds->ds_rxstat.rs_keyix;
+
+               if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
+                       rx_status.flag |= RX_FLAG_DECRYPTED;
+               } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED)
+                          && !decrypt_error && skb->len >= hdrlen + 4) {
+                       keyix = skb->data[hdrlen + 3] >> 6;
+
+                       if (test_bit(keyix, sc->keymap))
+                               rx_status.flag |= RX_FLAG_DECRYPTED;
+               }
+               if (ah->sw_mgmt_crypto &&
+                   (rx_status.flag & RX_FLAG_DECRYPTED) &&
+                   ieee80211_is_mgmt(hdr->frame_control)) {
+                       /* Use software decrypt for management frames. */
+                       rx_status.flag &= ~RX_FLAG_DECRYPTED;
+               }
+
+               /* Send the frame to mac80211 */
+               if (hdr->addr1[5] & 0x01) {
+                       int i;
+                       /*
+                        * Deliver broadcast/multicast frames to all suitable
+                        * virtual wiphys.
+                        */
+                       /* TODO: filter based on channel configuration */
+                       for (i = 0; i < sc->num_sec_wiphy; i++) {
+                               struct ath_wiphy *aphy = sc->sec_wiphy[i];
+                               struct sk_buff *nskb;
+                               if (aphy == NULL)
+                                       continue;
+                               nskb = skb_copy(skb, GFP_ATOMIC);
+                               if (nskb)
+                                       __ieee80211_rx(aphy->hw, nskb,
+                                                      &rx_status);
+                       }
+                       __ieee80211_rx(sc->hw, skb, &rx_status);
+               } else {
+                       /* Deliver unicast frames based on receiver address */
+                       __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb,
+                                      &rx_status);
+               }
+
+               /* We will now give hardware our shiny new allocated skb */
+               bf->bf_mpdu = requeue_skb;
+               bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
+                                        sc->rx.bufsize,
+                                        DMA_FROM_DEVICE);
+               if (unlikely(dma_mapping_error(sc->dev,
+                         bf->bf_buf_addr))) {
+                       dev_kfree_skb_any(requeue_skb);
+                       bf->bf_mpdu = NULL;
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "dma_mapping_error() on RX\n");
+                       break;
+               }
+               bf->bf_dmacontext = bf->bf_buf_addr;
+
+               /*
+                * change the default rx antenna if rx diversity chooses the
+                * other antenna 3 times in a row.
+                */
+               if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
+                       if (++sc->rx.rxotherant >= 3)
+                               ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
+               } else {
+                       sc->rx.rxotherant = 0;
+               }
+
+               if (ieee80211_is_beacon(fc) &&
+                               (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) {
+                       sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+               }
+requeue:
+               list_move_tail(&bf->list, &sc->rx.rxbuf);
+               ath_rx_buf_link(sc, bf);
+       } while (1);
+
+       spin_unlock_bh(&sc->rx.rxbuflock);
+
+       return 0;
+#undef PA2DESC
+}
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
new file mode 100644 (file)
index 0000000..5260524
--- /dev/null
@@ -0,0 +1,1511 @@
+/*
+ * Copyright (c) 2008-2009 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 REG_H
+#define REG_H
+
+#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  0x00000007
+#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_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_9100                  0x14
+#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_5416(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
+        ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
+#define AR_SREV_5416_20_OR_LATER(_ah) \
+       (((AR_SREV_5416(_ah)) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
+        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+#define AR_SREV_5416_22_OR_LATER(_ah) \
+       (((AR_SREV_5416(_ah)) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
+        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
+#define AR_SREV_9100(ah) \
+       ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
+#define AR_SREV_9100_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
+#define AR_SREV_9160(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
+#define AR_SREV_9160_10_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160))
+#define AR_SREV_9160_11(_ah) \
+       (AR_SREV_9160(_ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
+#define AR_SREV_9280(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
+#define AR_SREV_9280_10_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
+#define AR_SREV_9280_20(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+               ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))
+#define AR_SREV_9280_20_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+       ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)))
+
+#define AR_SREV_9285(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
+#define AR_SREV_9285_10_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
+#define AR_SREV_9285_11(_ah) \
+       (AR_SREV_9285(ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
+#define AR_SREV_9285_11_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+        (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
+                              AR_SREV_REVISION_9285_11)))
+#define AR_SREV_9285_12(_ah) \
+       (AR_SREV_9285(ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
+#define AR_SREV_9285_12_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+        (AR_SREV_9285(ah) && ((_ah)->hw_version.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,
+
+};
+
+#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 AR9285_NUM_GPIO                          12
+
+#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 AR9285_GPIO_IN_VAL                       0x00FFF000
+#define AR9285_GPIO_IN_VAL_S                     12
+
+#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_BT_PRIORITY_DEF     0x00000004
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S      3
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF       0x00000010
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S         4
+#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_BT_ACTIVE_BB        0x00001000
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S      12
+#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_MUX1_BT_ACTIVE             0x000f0000
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
+
+#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)
+
+/* RTC_DERIVED_* - only for AR9100 */
+
+#define AR_RTC_DERIVED_CLK           (AR_RTC_BASE + 0x0038)
+#define AR_RTC_DERIVED_CLK_PERIOD    0x0000fffe
+#define AR_RTC_DERIVED_CLK_PERIOD_S  1
+
+#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_TOP1                  0x7890
+#define AR_AN_TOP1_DACIPMODE       0x00040000
+#define AR_AN_TOP1_DACIPMODE_S     18
+
+#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_COMPR_BAR     0x00000400
+
+#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_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
+
+#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_TSFOOR_THRESHOLD       0x813c
+#define AR_TSFOOR_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_PCU_MISC_MODE2               0x8344
+#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
+#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT   0x00000004
+
+#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)
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
new file mode 100644 (file)
index 0000000..1ff429b
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+struct ath9k_vif_iter_data {
+       int count;
+       u8 *addr;
+};
+
+static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct ath9k_vif_iter_data *iter_data = data;
+       u8 *nbuf;
+
+       nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN,
+                       GFP_ATOMIC);
+       if (nbuf == NULL)
+               return;
+
+       memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN);
+       iter_data->addr = nbuf;
+       iter_data->count++;
+}
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath9k_vif_iter_data iter_data;
+       int i, j;
+       u8 mask[ETH_ALEN];
+
+       /*
+        * Add primary MAC address even if it is not in active use since it
+        * will be configured to the hardware as the starting point and the
+        * BSSID mask will need to be changed if another address is active.
+        */
+       iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
+       if (iter_data.addr) {
+               memcpy(iter_data.addr, sc->sc_ah->macaddr, ETH_ALEN);
+               iter_data.count = 1;
+       } else
+               iter_data.count = 0;
+
+       /* Get list of all active MAC addresses */
+       spin_lock_bh(&sc->wiphy_lock);
+       ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter,
+                                                  &iter_data);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] == NULL)
+                       continue;
+               ieee80211_iterate_active_interfaces_atomic(
+                       sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data);
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+
+       /* Generate an address mask to cover all active addresses */
+       memset(mask, 0, ETH_ALEN);
+       for (i = 0; i < iter_data.count; i++) {
+               u8 *a1 = iter_data.addr + i * ETH_ALEN;
+               for (j = i + 1; j < iter_data.count; j++) {
+                       u8 *a2 = iter_data.addr + j * ETH_ALEN;
+                       mask[0] |= a1[0] ^ a2[0];
+                       mask[1] |= a1[1] ^ a2[1];
+                       mask[2] |= a1[2] ^ a2[2];
+                       mask[3] |= a1[3] ^ a2[3];
+                       mask[4] |= a1[4] ^ a2[4];
+                       mask[5] |= a1[5] ^ a2[5];
+               }
+       }
+
+       kfree(iter_data.addr);
+
+       /* Invert the mask and configure hardware */
+       sc->bssidmask[0] = ~mask[0];
+       sc->bssidmask[1] = ~mask[1];
+       sc->bssidmask[2] = ~mask[2];
+       sc->bssidmask[3] = ~mask[3];
+       sc->bssidmask[4] = ~mask[4];
+       sc->bssidmask[5] = ~mask[5];
+
+       ath9k_hw_setbssidmask(sc);
+}
+
+int ath9k_wiphy_add(struct ath_softc *sc)
+{
+       int i, error;
+       struct ath_wiphy *aphy;
+       struct ieee80211_hw *hw;
+       u8 addr[ETH_ALEN];
+
+       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops);
+       if (hw == NULL)
+               return -ENOMEM;
+
+       spin_lock_bh(&sc->wiphy_lock);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] == NULL)
+                       break;
+       }
+
+       if (i == sc->num_sec_wiphy) {
+               /* No empty slot available; increase array length */
+               struct ath_wiphy **n;
+               n = krealloc(sc->sec_wiphy,
+                            (sc->num_sec_wiphy + 1) *
+                            sizeof(struct ath_wiphy *),
+                            GFP_ATOMIC);
+               if (n == NULL) {
+                       spin_unlock_bh(&sc->wiphy_lock);
+                       ieee80211_free_hw(hw);
+                       return -ENOMEM;
+               }
+               n[i] = NULL;
+               sc->sec_wiphy = n;
+               sc->num_sec_wiphy++;
+       }
+
+       SET_IEEE80211_DEV(hw, sc->dev);
+
+       aphy = hw->priv;
+       aphy->sc = sc;
+       aphy->hw = hw;
+       sc->sec_wiphy[i] = aphy;
+       spin_unlock_bh(&sc->wiphy_lock);
+
+       memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN);
+       addr[0] |= 0x02; /* Locally managed address */
+       /*
+        * XOR virtual wiphy index into the least significant bits to generate
+        * a different MAC address for each virtual wiphy.
+        */
+       addr[5] ^= i & 0xff;
+       addr[4] ^= (i & 0xff00) >> 8;
+       addr[3] ^= (i & 0xff0000) >> 16;
+
+       SET_IEEE80211_PERM_ADDR(hw, addr);
+
+       ath_set_hw_capab(sc, hw);
+
+       error = ieee80211_register_hw(hw);
+
+       if (error == 0) {
+               /* Make sure wiphy scheduler is started (if enabled) */
+               ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int);
+       }
+
+       return error;
+}
+
+int ath9k_wiphy_del(struct ath_wiphy *aphy)
+{
+       struct ath_softc *sc = aphy->sc;
+       int i;
+
+       spin_lock_bh(&sc->wiphy_lock);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (aphy == sc->sec_wiphy[i]) {
+                       sc->sec_wiphy[i] = NULL;
+                       spin_unlock_bh(&sc->wiphy_lock);
+                       ieee80211_unregister_hw(aphy->hw);
+                       ieee80211_free_hw(aphy->hw);
+                       return 0;
+               }
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+       return -ENOENT;
+}
+
+static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
+                              struct ieee80211_vif *vif, const u8 *bssid,
+                              int ps)
+{
+       struct ath_softc *sc = aphy->sc;
+       struct ath_tx_control txctl;
+       struct sk_buff *skb;
+       struct ieee80211_hdr *hdr;
+       __le16 fc;
+       struct ieee80211_tx_info *info;
+
+       skb = dev_alloc_skb(24);
+       if (skb == NULL)
+               return -ENOMEM;
+       hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
+       memset(hdr, 0, 24);
+       fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+                        IEEE80211_FCTL_TODS);
+       if (ps)
+               fc |= cpu_to_le16(IEEE80211_FCTL_PM);
+       hdr->frame_control = fc;
+       memcpy(hdr->addr1, bssid, ETH_ALEN);
+       memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN);
+       memcpy(hdr->addr3, bssid, ETH_ALEN);
+
+       info = IEEE80211_SKB_CB(skb);
+       memset(info, 0, sizeof(*info));
+       info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS;
+       info->control.vif = vif;
+       info->control.rates[0].idx = 0;
+       info->control.rates[0].count = 4;
+       info->control.rates[1].idx = -1;
+
+       memset(&txctl, 0, sizeof(struct ath_tx_control));
+       txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
+       txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE;
+
+       if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
+               goto exit;
+
+       return 0;
+exit:
+       dev_kfree_skb_any(skb);
+       return -1;
+}
+
+static bool __ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+       int i;
+       if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING)
+               return true;
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING)
+                       return true;
+       }
+       return false;
+}
+
+static bool ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+       bool ret;
+       spin_lock_bh(&sc->wiphy_lock);
+       ret = __ath9k_wiphy_pausing(sc);
+       spin_unlock_bh(&sc->wiphy_lock);
+       return ret;
+}
+
+static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+       int i;
+       if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
+               return true;
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
+                       return true;
+       }
+       return false;
+}
+
+bool ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+       bool ret;
+       spin_lock_bh(&sc->wiphy_lock);
+       ret = __ath9k_wiphy_scanning(sc);
+       spin_unlock_bh(&sc->wiphy_lock);
+       return ret;
+}
+
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy)
+{
+       if (aphy == NULL)
+               return;
+       if (aphy->chan_idx != aphy->sc->chan_idx)
+               return; /* wiphy not on the selected channel */
+       __ath9k_wiphy_unpause(aphy);
+}
+
+static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
+{
+       int i;
+       spin_lock_bh(&sc->wiphy_lock);
+       __ath9k_wiphy_unpause_ch(sc->pri_wiphy);
+       for (i = 0; i < sc->num_sec_wiphy; i++)
+               __ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]);
+       spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_chan_work(struct work_struct *work)
+{
+       struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
+       struct ath_wiphy *aphy = sc->next_wiphy;
+
+       if (aphy == NULL)
+               return;
+
+       /*
+        * All pending interfaces paused; ready to change
+        * channels.
+        */
+
+       /* Change channels */
+       mutex_lock(&sc->mutex);
+       /* XXX: remove me eventually */
+       ath9k_update_ichannel(sc, aphy->hw,
+                             &sc->sc_ah->channels[sc->chan_idx]);
+       ath_update_chainmask(sc, sc->chan_is_ht);
+       if (ath_set_channel(sc, aphy->hw,
+                           &sc->sc_ah->channels[sc->chan_idx]) < 0) {
+               printk(KERN_DEBUG "ath9k: Failed to set channel for new "
+                      "virtual wiphy\n");
+               mutex_unlock(&sc->mutex);
+               return;
+       }
+       mutex_unlock(&sc->mutex);
+
+       ath9k_wiphy_unpause_channel(sc);
+}
+
+/*
+ * ath9k version of ieee80211_tx_status() for TX frames that are generated
+ * internally in the driver.
+ */
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+
+       if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE &&
+           aphy->state == ATH_WIPHY_PAUSING) {
+               if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
+                       printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
+                              "frame\n", wiphy_name(hw->wiphy));
+                       /*
+                        * The AP did not reply; ignore this to allow us to
+                        * continue.
+                        */
+               }
+               aphy->state = ATH_WIPHY_PAUSED;
+               if (!ath9k_wiphy_pausing(aphy->sc)) {
+                       /*
+                        * Drop from tasklet to work to allow mutex for channel
+                        * change.
+                        */
+                       queue_work(aphy->sc->hw->workqueue,
+                                  &aphy->sc->chan_work);
+               }
+       }
+
+       kfree(tx_info_priv);
+       tx_info->rate_driver_data[0] = NULL;
+
+       dev_kfree_skb(skb);
+}
+
+static void ath9k_mark_paused(struct ath_wiphy *aphy)
+{
+       struct ath_softc *sc = aphy->sc;
+       aphy->state = ATH_WIPHY_PAUSED;
+       if (!__ath9k_wiphy_pausing(sc))
+               queue_work(sc->hw->workqueue, &sc->chan_work);
+}
+
+static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct ath_wiphy *aphy = data;
+       struct ath_vif *avp = (void *) vif->drv_priv;
+
+       switch (vif->type) {
+       case NL80211_IFTYPE_STATION:
+               if (!vif->bss_conf.assoc) {
+                       ath9k_mark_paused(aphy);
+                       break;
+               }
+               /* TODO: could avoid this if already in PS mode */
+               if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) {
+                       printk(KERN_DEBUG "%s: failed to send PS nullfunc\n",
+                              __func__);
+                       ath9k_mark_paused(aphy);
+               }
+               break;
+       case NL80211_IFTYPE_AP:
+               /* Beacon transmission is paused by aphy->state change */
+               ath9k_mark_paused(aphy);
+               break;
+       default:
+               break;
+       }
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+       ieee80211_stop_queues(aphy->hw);
+       aphy->state = ATH_WIPHY_PAUSING;
+       /*
+        * TODO: handle PAUSING->PAUSED for the case where there are multiple
+        * active vifs (now we do it on the first vif getting ready; should be
+        * on the last)
+        */
+       ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter,
+                                                  aphy);
+       return 0;
+}
+
+int ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+       int ret;
+       spin_lock_bh(&aphy->sc->wiphy_lock);
+       ret = __ath9k_wiphy_pause(aphy);
+       spin_unlock_bh(&aphy->sc->wiphy_lock);
+       return ret;
+}
+
+static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct ath_wiphy *aphy = data;
+       struct ath_vif *avp = (void *) vif->drv_priv;
+
+       switch (vif->type) {
+       case NL80211_IFTYPE_STATION:
+               if (!vif->bss_conf.assoc)
+                       break;
+               ath9k_send_nullfunc(aphy, vif, avp->bssid, 0);
+               break;
+       case NL80211_IFTYPE_AP:
+               /* Beacon transmission is re-enabled by aphy->state change */
+               break;
+       default:
+               break;
+       }
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+       ieee80211_iterate_active_interfaces_atomic(aphy->hw,
+                                                  ath9k_unpause_iter, aphy);
+       aphy->state = ATH_WIPHY_ACTIVE;
+       ieee80211_wake_queues(aphy->hw);
+       return 0;
+}
+
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+       int ret;
+       spin_lock_bh(&aphy->sc->wiphy_lock);
+       ret = __ath9k_wiphy_unpause(aphy);
+       spin_unlock_bh(&aphy->sc->wiphy_lock);
+       return ret;
+}
+
+static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc)
+{
+       int i;
+       if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE)
+               sc->pri_wiphy->state = ATH_WIPHY_PAUSED;
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE)
+                       sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED;
+       }
+}
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_pause_all(struct ath_softc *sc)
+{
+       int i;
+       if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+               __ath9k_wiphy_pause(sc->pri_wiphy);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+                       __ath9k_wiphy_pause(sc->sec_wiphy[i]);
+       }
+}
+
+int ath9k_wiphy_select(struct ath_wiphy *aphy)
+{
+       struct ath_softc *sc = aphy->sc;
+       bool now;
+
+       spin_lock_bh(&sc->wiphy_lock);
+       if (__ath9k_wiphy_scanning(sc)) {
+               /*
+                * For now, we are using mac80211 sw scan and it expects to
+                * have full control over channel changes, so avoid wiphy
+                * scheduling during a scan. This could be optimized if the
+                * scanning control were moved into the driver.
+                */
+               spin_unlock_bh(&sc->wiphy_lock);
+               return -EBUSY;
+       }
+       if (__ath9k_wiphy_pausing(sc)) {
+               if (sc->wiphy_select_failures == 0)
+                       sc->wiphy_select_first_fail = jiffies;
+               sc->wiphy_select_failures++;
+               if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2))
+               {
+                       printk(KERN_DEBUG "ath9k: Previous wiphy select timed "
+                              "out; disable/enable hw to recover\n");
+                       __ath9k_wiphy_mark_all_paused(sc);
+                       /*
+                        * TODO: this workaround to fix hardware is unlikely to
+                        * be specific to virtual wiphy changes. It can happen
+                        * on normal channel change, too, and as such, this
+                        * should really be made more generic. For example,
+                        * tricker radio disable/enable on GTT interrupt burst
+                        * (say, 10 GTT interrupts received without any TX
+                        * frame being completed)
+                        */
+                       spin_unlock_bh(&sc->wiphy_lock);
+                       ath_radio_disable(sc);
+                       ath_radio_enable(sc);
+                       queue_work(aphy->sc->hw->workqueue,
+                                  &aphy->sc->chan_work);
+                       return -EBUSY; /* previous select still in progress */
+               }
+               spin_unlock_bh(&sc->wiphy_lock);
+               return -EBUSY; /* previous select still in progress */
+       }
+       sc->wiphy_select_failures = 0;
+
+       /* Store the new channel */
+       sc->chan_idx = aphy->chan_idx;
+       sc->chan_is_ht = aphy->chan_is_ht;
+       sc->next_wiphy = aphy;
+
+       __ath9k_wiphy_pause_all(sc);
+       now = !__ath9k_wiphy_pausing(aphy->sc);
+       spin_unlock_bh(&sc->wiphy_lock);
+
+       if (now) {
+               /* Ready to request channel change immediately */
+               queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work);
+       }
+
+       /*
+        * wiphys will be unpaused in ath9k_tx_status() once channel has been
+        * changed if any wiphy needs time to become paused.
+        */
+
+       return 0;
+}
+
+bool ath9k_wiphy_started(struct ath_softc *sc)
+{
+       int i;
+       spin_lock_bh(&sc->wiphy_lock);
+       if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+               spin_unlock_bh(&sc->wiphy_lock);
+               return true;
+       }
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) {
+                       spin_unlock_bh(&sc->wiphy_lock);
+                       return true;
+               }
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+       return false;
+}
+
+static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
+                                  struct ath_wiphy *selected)
+{
+       if (selected->state == ATH_WIPHY_SCAN) {
+               if (aphy == selected)
+                       return;
+               /*
+                * Pause all other wiphys for the duration of the scan even if
+                * they are on the current channel now.
+                */
+       } else if (aphy->chan_idx == selected->chan_idx)
+               return;
+       aphy->state = ATH_WIPHY_PAUSED;
+       ieee80211_stop_queues(aphy->hw);
+}
+
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+                                 struct ath_wiphy *selected)
+{
+       int i;
+       spin_lock_bh(&sc->wiphy_lock);
+       if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+               ath9k_wiphy_pause_chan(sc->pri_wiphy, selected);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+                       ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected);
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_work(struct work_struct *work)
+{
+       struct ath_softc *sc = container_of(work, struct ath_softc,
+                                           wiphy_work.work);
+       struct ath_wiphy *aphy = NULL;
+       bool first = true;
+
+       spin_lock_bh(&sc->wiphy_lock);
+
+       if (sc->wiphy_scheduler_int == 0) {
+               /* wiphy scheduler is disabled */
+               spin_unlock_bh(&sc->wiphy_lock);
+               return;
+       }
+
+try_again:
+       sc->wiphy_scheduler_index++;
+       while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) {
+               aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1];
+               if (aphy && aphy->state != ATH_WIPHY_INACTIVE)
+                       break;
+
+               sc->wiphy_scheduler_index++;
+               aphy = NULL;
+       }
+       if (aphy == NULL) {
+               sc->wiphy_scheduler_index = 0;
+               if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) {
+                       if (first) {
+                               first = false;
+                               goto try_again;
+                       }
+                       /* No wiphy is ready to be scheduled */
+               } else
+                       aphy = sc->pri_wiphy;
+       }
+
+       spin_unlock_bh(&sc->wiphy_lock);
+
+       if (aphy &&
+           aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN &&
+           ath9k_wiphy_select(aphy)) {
+               printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy "
+                      "change\n");
+       }
+
+       queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+                          sc->wiphy_scheduler_int);
+}
+
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
+{
+       cancel_delayed_work_sync(&sc->wiphy_work);
+       sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
+       if (sc->wiphy_scheduler_int)
+               queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+                                  sc->wiphy_scheduler_int);
+}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
new file mode 100644 (file)
index 0000000..628b780
--- /dev/null
@@ -0,0 +1,2171 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.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
+
+static u32 bits_per_symbol[][2] = {
+       /* 20MHz 40MHz */
+       {    26,   54 },     /*  0: BPSK */
+       {    52,  108 },     /*  1: QPSK 1/2 */
+       {    78,  162 },     /*  2: QPSK 3/4 */
+       {   104,  216 },     /*  3: 16-QAM 1/2 */
+       {   156,  324 },     /*  4: 16-QAM 3/4 */
+       {   208,  432 },     /*  5: 64-QAM 2/3 */
+       {   234,  486 },     /*  6: 64-QAM 3/4 */
+       {   260,  540 },     /*  7: 64-QAM 5/6 */
+       {    52,  108 },     /*  8: BPSK */
+       {   104,  216 },     /*  9: QPSK 1/2 */
+       {   156,  324 },     /* 10: QPSK 3/4 */
+       {   208,  432 },     /* 11: 16-QAM 1/2 */
+       {   312,  648 },     /* 12: 16-QAM 3/4 */
+       {   416,  864 },     /* 13: 64-QAM 2/3 */
+       {   468,  972 },     /* 14: 64-QAM 3/4 */
+       {   520, 1080 },     /* 15: 64-QAM 5/6 */
+};
+
+#define IS_HT_RATE(_rate)     ((_rate) & 0x80)
+
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+                                 struct ath_atx_tid *tid,
+                                 struct list_head *bf_head);
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+                               struct list_head *bf_q,
+                               int txok, int sendbar);
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+                            struct list_head *head);
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+                             int txok);
+static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
+                            int nbad, int txok, bool update_rc);
+
+/*********************/
+/* Aggregation logic */
+/*********************/
+
+static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
+{
+       struct ath_atx_tid *tid;
+       tid = ATH_AN_2_TID(an, tidno);
+
+       if (tid->state & AGGR_ADDBA_COMPLETE ||
+           tid->state & AGGR_ADDBA_PROGRESS)
+               return 1;
+       else
+               return 0;
+}
+
+static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
+{
+       struct ath_atx_ac *ac = tid->ac;
+
+       if (tid->paused)
+               return;
+
+       if (tid->sched)
+               return;
+
+       tid->sched = true;
+       list_add_tail(&tid->list, &ac->tid_q);
+
+       if (ac->sched)
+               return;
+
+       ac->sched = true;
+       list_add_tail(&ac->list, &txq->axq_acq);
+}
+
+static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+
+       spin_lock_bh(&txq->axq_lock);
+       tid->paused++;
+       spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+
+       ASSERT(tid->paused > 0);
+       spin_lock_bh(&txq->axq_lock);
+
+       tid->paused--;
+
+       if (tid->paused > 0)
+               goto unlock;
+
+       if (list_empty(&tid->buf_q))
+               goto unlock;
+
+       ath_tx_queue_tid(txq, tid);
+       ath_txq_schedule(sc, txq);
+unlock:
+       spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+       struct ath_buf *bf;
+       struct list_head bf_head;
+       INIT_LIST_HEAD(&bf_head);
+
+       ASSERT(tid->paused > 0);
+       spin_lock_bh(&txq->axq_lock);
+
+       tid->paused--;
+
+       if (tid->paused > 0) {
+               spin_unlock_bh(&txq->axq_lock);
+               return;
+       }
+
+       while (!list_empty(&tid->buf_q)) {
+               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+               ASSERT(!bf_isretried(bf));
+               list_move_tail(&bf->list, &bf_head);
+               ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
+       }
+
+       spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+                             int seqno)
+{
+       int index, cindex;
+
+       index  = ATH_BA_INDEX(tid->seq_start, seqno);
+       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
+
+       tid->tx_buf[cindex] = NULL;
+
+       while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) {
+               INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+               INCR(tid->baw_head, ATH_TID_MAX_BUFS);
+       }
+}
+
+static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+                            struct ath_buf *bf)
+{
+       int index, cindex;
+
+       if (bf_isretried(bf))
+               return;
+
+       index  = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
+       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
+
+       ASSERT(tid->tx_buf[cindex] == NULL);
+       tid->tx_buf[cindex] = bf;
+
+       if (index >= ((tid->baw_tail - tid->baw_head) &
+               (ATH_TID_MAX_BUFS - 1))) {
+               tid->baw_tail = cindex;
+               INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
+       }
+}
+
+/*
+ * TODO: For frame(s) that are in the retry state, we will reuse the
+ * sequence number(s) without setting the retry bit. The
+ * alternative is to give up on these and BAR the receiver's window
+ * forward.
+ */
+static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
+                         struct ath_atx_tid *tid)
+
+{
+       struct ath_buf *bf;
+       struct list_head bf_head;
+       INIT_LIST_HEAD(&bf_head);
+
+       for (;;) {
+               if (list_empty(&tid->buf_q))
+                       break;
+
+               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+               list_move_tail(&bf->list, &bf_head);
+
+               if (bf_isretried(bf))
+                       ath_tx_update_baw(sc, tid, bf->bf_seqno);
+
+               spin_unlock(&txq->axq_lock);
+               ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+               spin_lock(&txq->axq_lock);
+       }
+
+       tid->seq_next = tid->seq_start;
+       tid->baw_tail = tid->baw_head;
+}
+
+static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
+{
+       struct sk_buff *skb;
+       struct ieee80211_hdr *hdr;
+
+       bf->bf_state.bf_type |= BUF_RETRY;
+       bf->bf_retries++;
+
+       skb = bf->bf_mpdu;
+       hdr = (struct ieee80211_hdr *)skb->data;
+       hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
+}
+
+static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
+{
+       struct ath_buf *tbf;
+
+       spin_lock_bh(&sc->tx.txbuflock);
+       ASSERT(!list_empty((&sc->tx.txbuf)));
+       tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+       list_del(&tbf->list);
+       spin_unlock_bh(&sc->tx.txbuflock);
+
+       ATH_TXBUF_RESET(tbf);
+
+       tbf->bf_mpdu = bf->bf_mpdu;
+       tbf->bf_buf_addr = bf->bf_buf_addr;
+       *(tbf->bf_desc) = *(bf->bf_desc);
+       tbf->bf_state = bf->bf_state;
+       tbf->bf_dmacontext = bf->bf_dmacontext;
+
+       return tbf;
+}
+
+static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+                                struct ath_buf *bf, struct list_head *bf_q,
+                                int txok)
+{
+       struct ath_node *an = NULL;
+       struct sk_buff *skb;
+       struct ieee80211_sta *sta;
+       struct ieee80211_hdr *hdr;
+       struct ath_atx_tid *tid = NULL;
+       struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
+       struct ath_desc *ds = bf_last->bf_desc;
+       struct list_head bf_head, bf_pending;
+       u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
+       u32 ba[WME_BA_BMP_SIZE >> 5];
+       int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
+       bool rc_update = true;
+
+       skb = bf->bf_mpdu;
+       hdr = (struct ieee80211_hdr *)skb->data;
+
+       rcu_read_lock();
+
+       sta = ieee80211_find_sta(sc->hw, hdr->addr1);
+       if (!sta) {
+               rcu_read_unlock();
+               return;
+       }
+
+       an = (struct ath_node *)sta->drv_priv;
+       tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
+       isaggr = bf_isaggr(bf);
+       memset(ba, 0, WME_BA_BMP_SIZE >> 3);
+
+       if (isaggr && txok) {
+               if (ATH_DS_TX_BA(ds)) {
+                       seq_st = ATH_DS_BA_SEQ(ds);
+                       memcpy(ba, ATH_DS_BA_BITMAP(ds),
+                              WME_BA_BMP_SIZE >> 3);
+               } else {
+                       /*
+                        * AR5416 can become deaf/mute when BA
+                        * issue happens. Chip needs to be reset.
+                        * But AP code may have sychronization issues
+                        * when perform internal reset in this routine.
+                        * Only enable reset in STA mode for now.
+                        */
+                       if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION)
+                               needreset = 1;
+               }
+       }
+
+       INIT_LIST_HEAD(&bf_pending);
+       INIT_LIST_HEAD(&bf_head);
+
+       nbad = ath_tx_num_badfrms(sc, bf, txok);
+       while (bf) {
+               txfail = txpending = 0;
+               bf_next = bf->bf_next;
+
+               if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
+                       /* transmit completion, subframe is
+                        * acked by block ack */
+                       acked_cnt++;
+               } else if (!isaggr && txok) {
+                       /* transmit completion */
+                       acked_cnt++;
+               } else {
+                       if (!(tid->state & AGGR_CLEANUP) &&
+                           ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
+                               if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
+                                       ath_tx_set_retry(sc, bf);
+                                       txpending = 1;
+                               } else {
+                                       bf->bf_state.bf_type |= BUF_XRETRY;
+                                       txfail = 1;
+                                       sendbar = 1;
+                                       txfail_cnt++;
+                               }
+                       } else {
+                               /*
+                                * cleanup in progress, just fail
+                                * the un-acked sub-frames
+                                */
+                               txfail = 1;
+                       }
+               }
+
+               if (bf_next == NULL) {
+                       INIT_LIST_HEAD(&bf_head);
+               } else {
+                       ASSERT(!list_empty(bf_q));
+                       list_move_tail(&bf->list, &bf_head);
+               }
+
+               if (!txpending) {
+                       /*
+                        * complete the acked-ones/xretried ones; update
+                        * block-ack window
+                        */
+                       spin_lock_bh(&txq->axq_lock);
+                       ath_tx_update_baw(sc, tid, bf->bf_seqno);
+                       spin_unlock_bh(&txq->axq_lock);
+
+                       if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
+                               ath_tx_rc_status(bf, ds, nbad, txok, true);
+                               rc_update = false;
+                       } else {
+                               ath_tx_rc_status(bf, ds, nbad, txok, false);
+                       }
+
+                       ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
+               } else {
+                       /* retry the un-acked ones */
+                       if (bf->bf_next == NULL && bf_last->bf_stale) {
+                               struct ath_buf *tbf;
+
+                               tbf = ath_clone_txbuf(sc, bf_last);
+                               ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
+                               list_add_tail(&tbf->list, &bf_head);
+                       } else {
+                               /*
+                                * Clear descriptor status words for
+                                * software retry
+                                */
+                               ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
+                       }
+
+                       /*
+                        * Put this buffer to the temporary pending
+                        * queue to retain ordering
+                        */
+                       list_splice_tail_init(&bf_head, &bf_pending);
+               }
+
+               bf = bf_next;
+       }
+
+       if (tid->state & AGGR_CLEANUP) {
+               if (tid->baw_head == tid->baw_tail) {
+                       tid->state &= ~AGGR_ADDBA_COMPLETE;
+                       tid->addba_exchangeattempts = 0;
+                       tid->state &= ~AGGR_CLEANUP;
+
+                       /* send buffered frames as singles */
+                       ath_tx_flush_tid(sc, tid);
+               }
+               rcu_read_unlock();
+               return;
+       }
+
+       /* prepend un-acked frames to the beginning of the pending frame queue */
+       if (!list_empty(&bf_pending)) {
+               spin_lock_bh(&txq->axq_lock);
+               list_splice(&bf_pending, &tid->buf_q);
+               ath_tx_queue_tid(txq, tid);
+               spin_unlock_bh(&txq->axq_lock);
+       }
+
+       rcu_read_unlock();
+
+       if (needreset)
+               ath_reset(sc, false);
+}
+
+static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
+                          struct ath_atx_tid *tid)
+{
+       struct ath_rate_table *rate_table = sc->cur_rate_table;
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *tx_info;
+       struct ieee80211_tx_rate *rates;
+       struct ath_tx_info_priv *tx_info_priv;
+       u32 max_4ms_framelen, frmlen;
+       u16 aggr_limit, legacy = 0, maxampdu;
+       int i;
+
+       skb = bf->bf_mpdu;
+       tx_info = IEEE80211_SKB_CB(skb);
+       rates = tx_info->control.rates;
+       tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
+
+       /*
+        * Find the lowest frame length among the rate series that will have a
+        * 4ms transmit duration.
+        * TODO - TXOP limit needs to be considered.
+        */
+       max_4ms_framelen = ATH_AMPDU_LIMIT_MAX;
+
+       for (i = 0; i < 4; i++) {
+               if (rates[i].count) {
+                       if (!WLAN_RC_PHY_HT(rate_table->info[rates[i].idx].phy)) {
+                               legacy = 1;
+                               break;
+                       }
+
+                       frmlen = rate_table->info[rates[i].idx].max_4ms_framelen;
+                       max_4ms_framelen = min(max_4ms_framelen, frmlen);
+               }
+       }
+
+       /*
+        * limit aggregate size by the minimum rate if rate selected is
+        * not a probe rate, if rate selected is a probe rate then
+        * avoid aggregation of this packet.
+        */
+       if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
+               return 0;
+
+       aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT);
+
+       /*
+        * h/w can accept aggregates upto 16 bit lengths (65535).
+        * The IE, however can hold upto 65536, which shows up here
+        * as zero. Ignore 65536 since we  are constrained by hw.
+        */
+       maxampdu = tid->an->maxampdu;
+       if (maxampdu)
+               aggr_limit = min(aggr_limit, maxampdu);
+
+       return aggr_limit;
+}
+
+/*
+ * Returns the number of delimiters to be added to
+ * meet the minimum required mpdudensity.
+ * caller should make sure that the rate is HT rate .
+ */
+static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
+                                 struct ath_buf *bf, u16 frmlen)
+{
+       struct ath_rate_table *rt = sc->cur_rate_table;
+       struct sk_buff *skb = bf->bf_mpdu;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       u32 nsymbits, nsymbols, mpdudensity;
+       u16 minlen;
+       u8 rc, flags, rix;
+       int width, half_gi, ndelim, mindelim;
+
+       /* Select standard number of delimiters based on frame length alone */
+       ndelim = ATH_AGGR_GET_NDELIM(frmlen);
+
+       /*
+        * If encryption enabled, hardware requires some more padding between
+        * subframes.
+        * TODO - this could be improved to be dependent on the rate.
+        *      The hardware can keep up at lower rates, but not higher rates
+        */
+       if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR)
+               ndelim += ATH_AGGR_ENCRYPTDELIM;
+
+       /*
+        * Convert desired mpdu density from microeconds to bytes based
+        * on highest rate in rate series (i.e. first rate) to determine
+        * required minimum length for subframe. Take into account
+        * whether high rate is 20 or 40Mhz and half or full GI.
+        */
+       mpdudensity = tid->an->mpdudensity;
+
+       /*
+        * If there is no mpdu density restriction, no further calculation
+        * is needed.
+        */
+       if (mpdudensity == 0)
+               return ndelim;
+
+       rix = tx_info->control.rates[0].idx;
+       flags = tx_info->control.rates[0].flags;
+       rc = rt->info[rix].ratecode;
+       width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0;
+       half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0;
+
+       if (half_gi)
+               nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity);
+       else
+               nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity);
+
+       if (nsymbols == 0)
+               nsymbols = 1;
+
+       nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
+       minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
+
+       if (frmlen < minlen) {
+               mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
+               ndelim = max(mindelim, ndelim);
+       }
+
+       return ndelim;
+}
+
+static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
+                                            struct ath_atx_tid *tid,
+                                            struct list_head *bf_q)
+{
+#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
+       struct ath_buf *bf, *bf_first, *bf_prev = NULL;
+       int rl = 0, nframes = 0, ndelim, prev_al = 0;
+       u16 aggr_limit = 0, al = 0, bpad = 0,
+               al_delta, h_baw = tid->baw_size / 2;
+       enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
+
+       bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
+
+       do {
+               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+
+               /* do not step over block-ack window */
+               if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
+                       status = ATH_AGGR_BAW_CLOSED;
+                       break;
+               }
+
+               if (!rl) {
+                       aggr_limit = ath_lookup_rate(sc, bf, tid);
+                       rl = 1;
+               }
+
+               /* do not exceed aggregation limit */
+               al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
+
+               if (nframes &&
+                   (aggr_limit < (al + bpad + al_delta + prev_al))) {
+                       status = ATH_AGGR_LIMITED;
+                       break;
+               }
+
+               /* do not exceed subframe limit */
+               if (nframes >= min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
+                       status = ATH_AGGR_LIMITED;
+                       break;
+               }
+               nframes++;
+
+               /* add padding for previous frame to aggregation length */
+               al += bpad + al_delta;
+
+               /*
+                * Get the delimiters needed to meet the MPDU
+                * density for this node.
+                */
+               ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
+               bpad = PADBYTES(al_delta) + (ndelim << 2);
+
+               bf->bf_next = NULL;
+               bf->bf_desc->ds_link = 0;
+
+               /* link buffers of this frame to the aggregate */
+               ath_tx_addto_baw(sc, tid, bf);
+               ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
+               list_move_tail(&bf->list, bf_q);
+               if (bf_prev) {
+                       bf_prev->bf_next = bf;
+                       bf_prev->bf_desc->ds_link = bf->bf_daddr;
+               }
+               bf_prev = bf;
+       } while (!list_empty(&tid->buf_q));
+
+       bf_first->bf_al = al;
+       bf_first->bf_nframes = nframes;
+
+       return status;
+#undef PADBYTES
+}
+
+static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
+                             struct ath_atx_tid *tid)
+{
+       struct ath_buf *bf;
+       enum ATH_AGGR_STATUS status;
+       struct list_head bf_q;
+
+       do {
+               if (list_empty(&tid->buf_q))
+                       return;
+
+               INIT_LIST_HEAD(&bf_q);
+
+               status = ath_tx_form_aggr(sc, tid, &bf_q);
+
+               /*
+                * no frames picked up to be aggregated;
+                * block-ack window is not open.
+                */
+               if (list_empty(&bf_q))
+                       break;
+
+               bf = list_first_entry(&bf_q, struct ath_buf, list);
+               bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
+
+               /* if only one frame, send as non-aggregate */
+               if (bf->bf_nframes == 1) {
+                       bf->bf_state.bf_type &= ~BUF_AGGR;
+                       ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
+                       ath_buf_set_rate(sc, bf);
+                       ath_tx_txqaddbuf(sc, txq, &bf_q);
+                       continue;
+               }
+
+               /* setup first desc of aggregate */
+               bf->bf_state.bf_type |= BUF_AGGR;
+               ath_buf_set_rate(sc, bf);
+               ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
+
+               /* anchor last desc of aggregate */
+               ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
+
+               txq->axq_aggr_depth++;
+               ath_tx_txqaddbuf(sc, txq, &bf_q);
+
+       } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
+                status != ATH_AGGR_BAW_CLOSED);
+}
+
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+                     u16 tid, u16 *ssn)
+{
+       struct ath_atx_tid *txtid;
+       struct ath_node *an;
+
+       an = (struct ath_node *)sta->drv_priv;
+
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               txtid = ATH_AN_2_TID(an, tid);
+               txtid->state |= AGGR_ADDBA_PROGRESS;
+               ath_tx_pause_tid(sc, txtid);
+               *ssn = txtid->seq_start;
+       }
+
+       return 0;
+}
+
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+{
+       struct ath_node *an = (struct ath_node *)sta->drv_priv;
+       struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
+       struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
+       struct ath_buf *bf;
+       struct list_head bf_head;
+       INIT_LIST_HEAD(&bf_head);
+
+       if (txtid->state & AGGR_CLEANUP)
+               return 0;
+
+       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+               txtid->addba_exchangeattempts = 0;
+               return 0;
+       }
+
+       ath_tx_pause_tid(sc, txtid);
+
+       /* drop all software retried frames and mark this TID */
+       spin_lock_bh(&txq->axq_lock);
+       while (!list_empty(&txtid->buf_q)) {
+               bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
+               if (!bf_isretried(bf)) {
+                       /*
+                        * NB: it's based on the assumption that
+                        * software retried frame will always stay
+                        * at the head of software queue.
+                        */
+                       break;
+               }
+               list_move_tail(&bf->list, &bf_head);
+               ath_tx_update_baw(sc, txtid, bf->bf_seqno);
+               ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+       }
+       spin_unlock_bh(&txq->axq_lock);
+
+       if (txtid->baw_head != txtid->baw_tail) {
+               txtid->state |= AGGR_CLEANUP;
+       } else {
+               txtid->state &= ~AGGR_ADDBA_COMPLETE;
+               txtid->addba_exchangeattempts = 0;
+               ath_tx_flush_tid(sc, txtid);
+       }
+
+       return 0;
+}
+
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+{
+       struct ath_atx_tid *txtid;
+       struct ath_node *an;
+
+       an = (struct ath_node *)sta->drv_priv;
+
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               txtid = ATH_AN_2_TID(an, tid);
+               txtid->baw_size =
+                       IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+               txtid->state |= AGGR_ADDBA_COMPLETE;
+               txtid->state &= ~AGGR_ADDBA_PROGRESS;
+               ath_tx_resume_tid(sc, txtid);
+       }
+}
+
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
+{
+       struct ath_atx_tid *txtid;
+
+       if (!(sc->sc_flags & SC_OP_TXAGGR))
+               return false;
+
+       txtid = ATH_AN_2_TID(an, tidno);
+
+       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+               if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
+                   (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
+                       txtid->addba_exchangeattempts++;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+/********************/
+/* Queue Management */
+/********************/
+
+static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
+                                         struct ath_txq *txq)
+{
+       struct ath_atx_ac *ac, *ac_tmp;
+       struct ath_atx_tid *tid, *tid_tmp;
+
+       list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
+               list_del(&ac->list);
+               ac->sched = false;
+               list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
+                       list_del(&tid->list);
+                       tid->sched = false;
+                       ath_tid_drain(sc, txq, tid);
+               }
+       }
+}
+
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_tx_queue_info qi;
+       int qnum;
+
+       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->tx.txq)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "qnum %u out of range, max %u!\n",
+                       qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
+               ath9k_hw_releasetxqueue(ah, qnum);
+               return NULL;
+       }
+       if (!ATH_TXQ_SETUP(sc, qnum)) {
+               struct ath_txq *txq = &sc->tx.txq[qnum];
+
+               txq->axq_qnum = qnum;
+               txq->axq_link = NULL;
+               INIT_LIST_HEAD(&txq->axq_q);
+               INIT_LIST_HEAD(&txq->axq_acq);
+               spin_lock_init(&txq->axq_lock);
+               txq->axq_depth = 0;
+               txq->axq_aggr_depth = 0;
+               txq->axq_totalqueued = 0;
+               txq->axq_linkbuf = NULL;
+               sc->tx.txqsetup |= 1<<qnum;
+       }
+       return &sc->tx.txq[qnum];
+}
+
+static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
+{
+       int qnum;
+
+       switch (qtype) {
+       case ATH9K_TX_QUEUE_DATA:
+               if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "HAL AC %u out of range, max %zu!\n",
+                               haltype, ARRAY_SIZE(sc->tx.hwq_map));
+                       return -1;
+               }
+               qnum = sc->tx.hwq_map[haltype];
+               break;
+       case ATH9K_TX_QUEUE_BEACON:
+               qnum = sc->beacon.beaconq;
+               break;
+       case ATH9K_TX_QUEUE_CAB:
+               qnum = sc->beacon.cabq->axq_qnum;
+               break;
+       default:
+               qnum = -1;
+       }
+       return qnum;
+}
+
+struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
+{
+       struct ath_txq *txq = NULL;
+       int qnum;
+
+       qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
+       txq = &sc->tx.txq[qnum];
+
+       spin_lock_bh(&txq->axq_lock);
+
+       if (txq->axq_depth >= (ATH_TXBUF - 20)) {
+               DPRINTF(sc, ATH_DBG_XMIT,
+                       "TX queue: %d is full, depth: %d\n",
+                       qnum, txq->axq_depth);
+               ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
+               txq->stopped = 1;
+               spin_unlock_bh(&txq->axq_lock);
+               return NULL;
+       }
+
+       spin_unlock_bh(&txq->axq_lock);
+
+       return txq;
+}
+
+int ath_txq_update(struct ath_softc *sc, int qnum,
+                  struct ath9k_tx_queue_info *qinfo)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       int error = 0;
+       struct ath9k_tx_queue_info qi;
+
+       if (qnum == sc->beacon.beaconq) {
+               /*
+                * XXX: for beacon queue, we just save the parameter.
+                * It will be picked up by ath_beaconq_config when
+                * it's necessary.
+                */
+               sc->beacon.beacon_qi = *qinfo;
+               return 0;
+       }
+
+       ASSERT(sc->tx.txq[qnum].axq_qnum == qnum);
+
+       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)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to update hardware queue %u!\n", qnum);
+               error = -EIO;
+       } else {
+               ath9k_hw_resettxqueue(ah, qnum);
+       }
+
+       return error;
+}
+
+int ath_cabq_update(struct ath_softc *sc)
+{
+       struct ath9k_tx_queue_info qi;
+       int qnum = sc->beacon.cabq->axq_qnum;
+
+       ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
+       /*
+        * Ensure the readytime % is within the bounds.
+        */
+       if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
+               sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
+       else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
+               sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
+
+       qi.tqi_readyTime = (sc->hw->conf.beacon_int *
+                           sc->config.cabqReadytime) / 100;
+       ath_txq_update(sc, qnum, &qi);
+
+       return 0;
+}
+
+/*
+ * Drain a given TX queue (could be Beacon or Data)
+ *
+ * This assumes output has been stopped and
+ * we do not need to block ath_tx_tasklet.
+ */
+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
+{
+       struct ath_buf *bf, *lastbf;
+       struct list_head bf_head;
+
+       INIT_LIST_HEAD(&bf_head);
+
+       for (;;) {
+               spin_lock_bh(&txq->axq_lock);
+
+               if (list_empty(&txq->axq_q)) {
+                       txq->axq_link = NULL;
+                       txq->axq_linkbuf = NULL;
+                       spin_unlock_bh(&txq->axq_lock);
+                       break;
+               }
+
+               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+
+               if (bf->bf_stale) {
+                       list_del(&bf->list);
+                       spin_unlock_bh(&txq->axq_lock);
+
+                       spin_lock_bh(&sc->tx.txbuflock);
+                       list_add_tail(&bf->list, &sc->tx.txbuf);
+                       spin_unlock_bh(&sc->tx.txbuflock);
+                       continue;
+               }
+
+               lastbf = bf->bf_lastbf;
+               if (!retry_tx)
+                       lastbf->bf_desc->ds_txstat.ts_flags =
+                               ATH9K_TX_SW_ABORTED;
+
+               /* remove ath_buf's of the same mpdu from txq */
+               list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
+               txq->axq_depth--;
+
+               spin_unlock_bh(&txq->axq_lock);
+
+               if (bf_isampdu(bf))
+                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
+               else
+                       ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+       }
+
+       /* flush any pending frames if aggregation is enabled */
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               if (!retry_tx) {
+                       spin_lock_bh(&txq->axq_lock);
+                       ath_txq_drain_pending_buffers(sc, txq);
+                       spin_unlock_bh(&txq->axq_lock);
+               }
+       }
+}
+
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_txq *txq;
+       int i, npend = 0;
+
+       if (sc->sc_flags & SC_OP_INVALID)
+               return;
+
+       /* Stop beacon queue */
+       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+
+       /* Stop data queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (ATH_TXQ_SETUP(sc, i)) {
+                       txq = &sc->tx.txq[i];
+                       ath9k_hw_stoptxdma(ah, txq->axq_qnum);
+                       npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
+               }
+       }
+
+       if (npend) {
+               int r;
+
+               DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
+
+               spin_lock_bh(&sc->sc_resetlock);
+               r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
+               if (r)
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "Unable to reset hardware; reset status %u\n",
+                               r);
+               spin_unlock_bh(&sc->sc_resetlock);
+       }
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
+       }
+}
+
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
+{
+       ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
+       sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
+}
+
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
+{
+       struct ath_atx_ac *ac;
+       struct ath_atx_tid *tid;
+
+       if (list_empty(&txq->axq_acq))
+               return;
+
+       ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
+       list_del(&ac->list);
+       ac->sched = false;
+
+       do {
+               if (list_empty(&ac->tid_q))
+                       return;
+
+               tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
+               list_del(&tid->list);
+               tid->sched = false;
+
+               if (tid->paused)
+                       continue;
+
+               if ((txq->axq_depth % 2) == 0)
+                       ath_tx_sched_aggr(sc, txq, tid);
+
+               /*
+                * add tid to round-robin queue if more frames
+                * are pending for the tid
+                */
+               if (!list_empty(&tid->buf_q))
+                       ath_tx_queue_tid(txq, tid);
+
+               break;
+       } while (!list_empty(&ac->tid_q));
+
+       if (!list_empty(&ac->tid_q)) {
+               if (!ac->sched) {
+                       ac->sched = true;
+                       list_add_tail(&ac->list, &txq->axq_acq);
+               }
+       }
+}
+
+int ath_tx_setup(struct ath_softc *sc, int haltype)
+{
+       struct ath_txq *txq;
+
+       if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "HAL AC %u out of range, max %zu!\n",
+                        haltype, ARRAY_SIZE(sc->tx.hwq_map));
+               return 0;
+       }
+       txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
+       if (txq != NULL) {
+               sc->tx.hwq_map[haltype] = txq->axq_qnum;
+               return 1;
+       } else
+               return 0;
+}
+
+/***********/
+/* TX, DMA */
+/***********/
+
+/*
+ * Insert a chain of ath_buf (descriptors) on a txq and
+ * assume the descriptors are already chained together by caller.
+ */
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+                            struct list_head *head)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf;
+
+       /*
+        * Insert the frame on the outbound list and
+        * pass it on to the hardware.
+        */
+
+       if (list_empty(head))
+               return;
+
+       bf = list_first_entry(head, struct ath_buf, list);
+
+       list_splice_tail_init(head, &txq->axq_q);
+       txq->axq_depth++;
+       txq->axq_totalqueued++;
+       txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
+
+       DPRINTF(sc, ATH_DBG_QUEUE,
+               "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
+
+       if (txq->axq_link == NULL) {
+               ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+               DPRINTF(sc, ATH_DBG_XMIT,
+                       "TXDP[%u] = %llx (%p)\n",
+                       txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
+       } else {
+               *txq->axq_link = bf->bf_daddr;
+               DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
+                       txq->axq_qnum, txq->axq_link,
+                       ito64(bf->bf_daddr), bf->bf_desc);
+       }
+       txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
+       ath9k_hw_txstart(ah, txq->axq_qnum);
+}
+
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
+{
+       struct ath_buf *bf = NULL;
+
+       spin_lock_bh(&sc->tx.txbuflock);
+
+       if (unlikely(list_empty(&sc->tx.txbuf))) {
+               spin_unlock_bh(&sc->tx.txbuflock);
+               return NULL;
+       }
+
+       bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+       list_del(&bf->list);
+
+       spin_unlock_bh(&sc->tx.txbuflock);
+
+       return bf;
+}
+
+static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
+                             struct list_head *bf_head,
+                             struct ath_tx_control *txctl)
+{
+       struct ath_buf *bf;
+
+       bf = list_first_entry(bf_head, struct ath_buf, list);
+       bf->bf_state.bf_type |= BUF_AMPDU;
+
+       /*
+        * Do not queue to h/w when any of the following conditions is true:
+        * - there are pending frames in software queue
+        * - the TID is currently paused for ADDBA/BAR request
+        * - seqno is not within block-ack window
+        * - h/w queue depth exceeds low water mark
+        */
+       if (!list_empty(&tid->buf_q) || tid->paused ||
+           !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
+           txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+               /*
+                * Add this frame to software queue for scheduling later
+                * for aggregation.
+                */
+               list_move_tail(&bf->list, &tid->buf_q);
+               ath_tx_queue_tid(txctl->txq, tid);
+               return;
+       }
+
+       /* Add sub-frame to BAW */
+       ath_tx_addto_baw(sc, tid, bf);
+
+       /* Queue to h/w without aggregation */
+       bf->bf_nframes = 1;
+       bf->bf_lastbf = bf;
+       ath_buf_set_rate(sc, bf);
+       ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
+}
+
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+                                 struct ath_atx_tid *tid,
+                                 struct list_head *bf_head)
+{
+       struct ath_buf *bf;
+
+       bf = list_first_entry(bf_head, struct ath_buf, list);
+       bf->bf_state.bf_type &= ~BUF_AMPDU;
+
+       /* update starting sequence number for subsequent ADDBA request */
+       INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+
+       bf->bf_nframes = 1;
+       bf->bf_lastbf = bf;
+       ath_buf_set_rate(sc, bf);
+       ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+                              struct list_head *bf_head)
+{
+       struct ath_buf *bf;
+
+       bf = list_first_entry(bf_head, struct ath_buf, list);
+
+       bf->bf_lastbf = bf;
+       bf->bf_nframes = 1;
+       ath_buf_set_rate(sc, bf);
+       ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr;
+       enum ath9k_pkt_type htype;
+       __le16 fc;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+
+       if (ieee80211_is_beacon(fc))
+               htype = ATH9K_PKT_TYPE_BEACON;
+       else if (ieee80211_is_probe_resp(fc))
+               htype = ATH9K_PKT_TYPE_PROBE_RESP;
+       else if (ieee80211_is_atim(fc))
+               htype = ATH9K_PKT_TYPE_ATIM;
+       else if (ieee80211_is_pspoll(fc))
+               htype = ATH9K_PKT_TYPE_PSPOLL;
+       else
+               htype = ATH9K_PKT_TYPE_NORMAL;
+
+       return htype;
+}
+
+static bool is_pae(struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr;
+       __le16 fc;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+
+       if (ieee80211_is_data(fc)) {
+               if (ieee80211_is_nullfunc(fc) ||
+                   /* Port Access Entity (IEEE 802.1X) */
+                   (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+static int get_hw_crypto_keytype(struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+
+       if (tx_info->control.hw_key) {
+               if (tx_info->control.hw_key->alg == ALG_WEP)
+                       return ATH9K_KEY_TYPE_WEP;
+               else if (tx_info->control.hw_key->alg == ALG_TKIP)
+                       return ATH9K_KEY_TYPE_TKIP;
+               else if (tx_info->control.hw_key->alg == ALG_CCMP)
+                       return ATH9K_KEY_TYPE_AES;
+       }
+
+       return ATH9K_KEY_TYPE_CLEAR;
+}
+
+static void assign_aggr_tid_seqno(struct sk_buff *skb,
+                                 struct ath_buf *bf)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr;
+       struct ath_node *an;
+       struct ath_atx_tid *tid;
+       __le16 fc;
+       u8 *qc;
+
+       if (!tx_info->control.sta)
+               return;
+
+       an = (struct ath_node *)tx_info->control.sta->drv_priv;
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+
+       if (ieee80211_is_data_qos(fc)) {
+               qc = ieee80211_get_qos_ctl(hdr);
+               bf->bf_tidno = qc[0] & 0xf;
+       }
+
+       /*
+        * For HT capable stations, we save tidno for later use.
+        * We also override seqno set by upper layer with the one
+        * in tx aggregation state.
+        *
+        * If fragmentation is on, the sequence number is
+        * not overridden, since it has been
+        * incremented by the fragmentation routine.
+        *
+        * FIXME: check if the fragmentation threshold exceeds
+        * IEEE80211 max.
+        */
+       tid = ATH_AN_2_TID(an, bf->bf_tidno);
+       hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
+                       IEEE80211_SEQ_SEQ_SHIFT);
+       bf->bf_seqno = tid->seq_next;
+       INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+}
+
+static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
+                         struct ath_txq *txq)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       int flags = 0;
+
+       flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
+       flags |= ATH9K_TXDESC_INTREQ;
+
+       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
+               flags |= ATH9K_TXDESC_NOACK;
+
+       return flags;
+}
+
+/*
+ * rix - rate index
+ * pktlen - total bytes (delims + data + fcs + pads + pad delims)
+ * width  - 0 for 20 MHz, 1 for 40 MHz
+ * half_gi - to use 4us v/s 3.6 us for symbol time
+ */
+static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
+                           int width, int half_gi, bool shortPreamble)
+{
+       struct ath_rate_table *rate_table = sc->cur_rate_table;
+       u32 nbits, nsymbits, duration, nsymbols;
+       u8 rc;
+       int streams, pktlen;
+
+       pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
+       rc = rate_table->info[rix].ratecode;
+
+       /* for legacy rates, use old function to compute packet duration */
+       if (!IS_HT_RATE(rc))
+               return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
+                                             rix, shortPreamble);
+
+       /* find number of symbols: PLCP + data */
+       nbits = (pktlen << 3) + OFDM_PLCP_BITS;
+       nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
+       nsymbols = (nbits + nsymbits - 1) / nsymbits;
+
+       if (!half_gi)
+               duration = SYMBOL_TIME(nsymbols);
+       else
+               duration = SYMBOL_TIME_HALFGI(nsymbols);
+
+       /* addup duration for legacy/ht training and signal fields */
+       streams = HT_RC_2_STREAMS(rc);
+       duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+
+       return duration;
+}
+
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
+{
+       struct ath_rate_table *rt = sc->cur_rate_table;
+       struct ath9k_11n_rate_series series[4];
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *tx_info;
+       struct ieee80211_tx_rate *rates;
+       struct ieee80211_hdr *hdr;
+       int i, flags = 0;
+       u8 rix = 0, ctsrate = 0;
+       bool is_pspoll;
+
+       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
+
+       skb = bf->bf_mpdu;
+       tx_info = IEEE80211_SKB_CB(skb);
+       rates = tx_info->control.rates;
+       hdr = (struct ieee80211_hdr *)skb->data;
+       is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
+
+       /*
+        * We check if Short Preamble is needed for the CTS rate by
+        * checking the BSS's global flag.
+        * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
+        */
+       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+               ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode |
+                       rt->info[tx_info->control.rts_cts_rate_idx].short_preamble;
+       else
+               ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode;
+
+       /*
+        * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
+        * Check the first rate in the series to decide whether RTS/CTS
+        * or CTS-to-self has to be used.
+        */
+       if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+               flags = ATH9K_TXDESC_CTSENA;
+       else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+               flags = ATH9K_TXDESC_RTSENA;
+
+       /* FIXME: Handle aggregation protection */
+       if (sc->config.ath_aggr_prot &&
+           (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
+               flags = ATH9K_TXDESC_RTSENA;
+       }
+
+       /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
+       if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
+               flags &= ~(ATH9K_TXDESC_RTSENA);
+
+       for (i = 0; i < 4; i++) {
+               if (!rates[i].count || (rates[i].idx < 0))
+                       continue;
+
+               rix = rates[i].idx;
+               series[i].Tries = rates[i].count;
+               series[i].ChSel = sc->tx_chainmask;
+
+               if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+                       series[i].Rate = rt->info[rix].ratecode |
+                               rt->info[rix].short_preamble;
+               else
+                       series[i].Rate = rt->info[rix].ratecode;
+
+               if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+                       series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+               if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+                       series[i].RateFlags |= ATH9K_RATESERIES_2040;
+               if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
+                       series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
+
+               series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
+                        (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0,
+                        (rates[i].flags & IEEE80211_TX_RC_SHORT_GI),
+                        (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE));
+       }
+
+       /* set dur_update_en for l-sig computation except for PS-Poll frames */
+       ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
+                                    bf->bf_lastbf->bf_desc,
+                                    !is_pspoll, ctsrate,
+                                    0, series, 4, flags);
+
+       if (sc->config.ath_aggr_prot && flags)
+               ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
+}
+
+static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
+                               struct sk_buff *skb,
+                               struct ath_tx_control *txctl)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ath_tx_info_priv *tx_info_priv;
+       int hdrlen;
+       __le16 fc;
+
+       tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
+       if (unlikely(!tx_info_priv))
+               return -ENOMEM;
+       tx_info->rate_driver_data[0] = tx_info_priv;
+       tx_info_priv->aphy = aphy;
+       tx_info_priv->frame_type = txctl->frame_type;
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       fc = hdr->frame_control;
+
+       ATH_TXBUF_RESET(bf);
+
+       bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
+
+       if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+               bf->bf_state.bf_type |= BUF_HT;
+
+       bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+
+       bf->bf_keytype = get_hw_crypto_keytype(skb);
+       if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
+               bf->bf_frmlen += tx_info->control.hw_key->icv_len;
+               bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
+       } else {
+               bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
+       }
+
+       if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
+               assign_aggr_tid_seqno(skb, bf);
+
+       bf->bf_mpdu = skb;
+
+       bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
+                                          skb->len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
+               bf->bf_mpdu = NULL;
+               DPRINTF(sc, ATH_DBG_CONFIG,
+                       "dma_mapping_error() on TX\n");
+               return -ENOMEM;
+       }
+
+       bf->bf_buf_addr = bf->bf_dmacontext;
+       return 0;
+}
+
+/* FIXME: tx power */
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+                            struct ath_tx_control *txctl)
+{
+       struct sk_buff *skb = bf->bf_mpdu;
+       struct ieee80211_tx_info *tx_info =  IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ath_node *an = NULL;
+       struct list_head bf_head;
+       struct ath_desc *ds;
+       struct ath_atx_tid *tid;
+       struct ath_hw *ah = sc->sc_ah;
+       int frm_type;
+       __le16 fc;
+
+       frm_type = get_hw_packet_type(skb);
+       fc = hdr->frame_control;
+
+       INIT_LIST_HEAD(&bf_head);
+       list_add_tail(&bf->list, &bf_head);
+
+       ds = bf->bf_desc;
+       ds->ds_link = 0;
+       ds->ds_data = bf->bf_buf_addr;
+
+       ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
+                              bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
+
+       ath9k_hw_filltxdesc(ah, ds,
+                           skb->len,   /* segment length */
+                           true,       /* first segment */
+                           true,       /* last segment */
+                           ds);        /* first descriptor */
+
+       spin_lock_bh(&txctl->txq->axq_lock);
+
+       if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
+           tx_info->control.sta) {
+               an = (struct ath_node *)tx_info->control.sta->drv_priv;
+               tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
+               if (!ieee80211_is_data_qos(fc)) {
+                       ath_tx_send_normal(sc, txctl->txq, &bf_head);
+                       goto tx_done;
+               }
+
+               if (ath_aggr_query(sc, an, bf->bf_tidno)) {
+                       /*
+                        * Try aggregation if it's a unicast data frame
+                        * and the destination is HT capable.
+                        */
+                       ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
+               } else {
+                       /*
+                        * Send this frame as regular when ADDBA
+                        * exchange is neither complete nor pending.
+                        */
+                       ath_tx_send_ht_normal(sc, txctl->txq,
+                                             tid, &bf_head);
+               }
+       } else {
+               ath_tx_send_normal(sc, txctl->txq, &bf_head);
+       }
+
+tx_done:
+       spin_unlock_bh(&txctl->txq->axq_lock);
+}
+
+/* Upon failure caller should free skb */
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+                struct ath_tx_control *txctl)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_buf *bf;
+       int r;
+
+       bf = ath_tx_get_buffer(sc);
+       if (!bf) {
+               DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
+               return -1;
+       }
+
+       r = ath_tx_setup_buffer(hw, bf, skb, txctl);
+       if (unlikely(r)) {
+               struct ath_txq *txq = txctl->txq;
+
+               DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
+
+               /* upon ath_tx_processq() this TX queue will be resumed, we
+                * guarantee this will happen by knowing beforehand that
+                * we will at least have to run TX completionon one buffer
+                * on the queue */
+               spin_lock_bh(&txq->axq_lock);
+               if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
+                       ieee80211_stop_queue(sc->hw,
+                               skb_get_queue_mapping(skb));
+                       txq->stopped = 1;
+               }
+               spin_unlock_bh(&txq->axq_lock);
+
+               spin_lock_bh(&sc->tx.txbuflock);
+               list_add_tail(&bf->list, &sc->tx.txbuf);
+               spin_unlock_bh(&sc->tx.txbuflock);
+
+               return r;
+       }
+
+       ath_tx_start_dma(sc, bf, txctl);
+
+       return 0;
+}
+
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       int hdrlen, padsize;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ath_tx_control txctl;
+
+       memset(&txctl, 0, sizeof(struct ath_tx_control));
+
+       /*
+        * As a temporary workaround, assign seq# here; this will likely need
+        * to be cleaned up to work better with Beacon transmission and virtual
+        * BSSes.
+        */
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+                       sc->tx.seq_no += 0x10;
+               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+       }
+
+       /* Add the padding after the header if this is not already done */
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       if (hdrlen & 3) {
+               padsize = hdrlen % 4;
+               if (skb_headroom(skb) < padsize) {
+                       DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
+                       dev_kfree_skb_any(skb);
+                       return;
+               }
+               skb_push(skb, padsize);
+               memmove(skb->data, skb->data + padsize, hdrlen);
+       }
+
+       txctl.txq = sc->beacon.cabq;
+
+       DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
+
+       if (ath_tx_start(hw, skb, &txctl) != 0) {
+               DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
+               goto exit;
+       }
+
+       return;
+exit:
+       dev_kfree_skb_any(skb);
+}
+
+/*****************/
+/* TX Completion */
+/*****************/
+
+static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
+                           int tx_flags)
+{
+       struct ieee80211_hw *hw = sc->hw;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       int hdrlen, padsize;
+       int frame_type = ATH9K_NOT_INTERNAL;
+
+       DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
+
+       if (tx_info_priv) {
+               hw = tx_info_priv->aphy->hw;
+               frame_type = tx_info_priv->frame_type;
+       }
+
+       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
+           tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
+               kfree(tx_info_priv);
+               tx_info->rate_driver_data[0] = NULL;
+       }
+
+       if (tx_flags & ATH_TX_BAR)
+               tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
+
+       if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
+               /* Frame was ACKed */
+               tx_info->flags |= IEEE80211_TX_STAT_ACK;
+       }
+
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       padsize = hdrlen & 3;
+       if (padsize && hdrlen >= 24) {
+               /*
+                * Remove MAC header padding before giving the frame back to
+                * mac80211.
+                */
+               memmove(skb->data + padsize, skb->data, hdrlen);
+               skb_pull(skb, padsize);
+       }
+
+       if (frame_type == ATH9K_NOT_INTERNAL)
+               ieee80211_tx_status(hw, skb);
+       else
+               ath9k_tx_status(hw, skb);
+}
+
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+                               struct list_head *bf_q,
+                               int txok, int sendbar)
+{
+       struct sk_buff *skb = bf->bf_mpdu;
+       unsigned long flags;
+       int tx_flags = 0;
+
+
+       if (sendbar)
+               tx_flags = ATH_TX_BAR;
+
+       if (!txok) {
+               tx_flags |= ATH_TX_ERROR;
+
+               if (bf_isxretried(bf))
+                       tx_flags |= ATH_TX_XRETRY;
+       }
+
+       dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
+       ath_tx_complete(sc, skb, tx_flags);
+
+       /*
+        * Return the list of ath_buf of this mpdu to free queue
+        */
+       spin_lock_irqsave(&sc->tx.txbuflock, flags);
+       list_splice_tail_init(bf_q, &sc->tx.txbuf);
+       spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
+}
+
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+                             int txok)
+{
+       struct ath_buf *bf_last = bf->bf_lastbf;
+       struct ath_desc *ds = bf_last->bf_desc;
+       u16 seq_st = 0;
+       u32 ba[WME_BA_BMP_SIZE >> 5];
+       int ba_index;
+       int nbad = 0;
+       int isaggr = 0;
+
+       if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
+               return 0;
+
+       isaggr = bf_isaggr(bf);
+       if (isaggr) {
+               seq_st = ATH_DS_BA_SEQ(ds);
+               memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
+       }
+
+       while (bf) {
+               ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
+               if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
+                       nbad++;
+
+               bf = bf->bf_next;
+       }
+
+       return nbad;
+}
+
+static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
+                            int nbad, int txok, bool update_rc)
+{
+       struct sk_buff *skb = bf->bf_mpdu;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       struct ieee80211_hw *hw = tx_info_priv->aphy->hw;
+       u8 i, tx_rateindex;
+
+       if (txok)
+               tx_info->status.ack_signal = ds->ds_txstat.ts_rssi;
+
+       tx_rateindex = ds->ds_txstat.ts_rateindex;
+       WARN_ON(tx_rateindex >= hw->max_rates);
+
+       tx_info_priv->update_rc = update_rc;
+       if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
+               tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+
+       if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
+           (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
+               if (ieee80211_is_data(hdr->frame_control)) {
+                       memcpy(&tx_info_priv->tx, &ds->ds_txstat,
+                              sizeof(tx_info_priv->tx));
+                       tx_info_priv->n_frames = bf->bf_nframes;
+                       tx_info_priv->n_bad_frames = nbad;
+               }
+       }
+
+       for (i = tx_rateindex + 1; i < hw->max_rates; i++)
+               tx_info->status.rates[i].count = 0;
+
+       tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
+}
+
+static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
+{
+       int qnum;
+
+       spin_lock_bh(&txq->axq_lock);
+       if (txq->stopped &&
+           sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
+               qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
+               if (qnum != -1) {
+                       ieee80211_wake_queue(sc->hw, qnum);
+                       txq->stopped = 0;
+               }
+       }
+       spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf, *lastbf, *bf_held = NULL;
+       struct list_head bf_head;
+       struct ath_desc *ds;
+       int txok;
+       int status;
+
+       DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
+               txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
+               txq->axq_link);
+
+       for (;;) {
+               spin_lock_bh(&txq->axq_lock);
+               if (list_empty(&txq->axq_q)) {
+                       txq->axq_link = NULL;
+                       txq->axq_linkbuf = NULL;
+                       spin_unlock_bh(&txq->axq_lock);
+                       break;
+               }
+               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+
+               /*
+                * There is a race condition that a BH gets scheduled
+                * after sw writes TxE and before hw re-load the last
+                * descriptor to get the newly chained one.
+                * Software must keep the last DONE descriptor as a
+                * holding descriptor - software does so by marking
+                * it with the STALE flag.
+                */
+               bf_held = NULL;
+               if (bf->bf_stale) {
+                       bf_held = bf;
+                       if (list_is_last(&bf_held->list, &txq->axq_q)) {
+                               txq->axq_link = NULL;
+                               txq->axq_linkbuf = NULL;
+                               spin_unlock_bh(&txq->axq_lock);
+
+                               /*
+                                * The holding descriptor is the last
+                                * descriptor in queue. It's safe to remove
+                                * the last holding descriptor in BH context.
+                                */
+                               spin_lock_bh(&sc->tx.txbuflock);
+                               list_move_tail(&bf_held->list, &sc->tx.txbuf);
+                               spin_unlock_bh(&sc->tx.txbuflock);
+
+                               break;
+                       } else {
+                               bf = list_entry(bf_held->list.next,
+                                               struct ath_buf, list);
+                       }
+               }
+
+               lastbf = bf->bf_lastbf;
+               ds = lastbf->bf_desc;
+
+               status = ath9k_hw_txprocdesc(ah, ds);
+               if (status == -EINPROGRESS) {
+                       spin_unlock_bh(&txq->axq_lock);
+                       break;
+               }
+               if (bf->bf_desc == txq->axq_lastdsWithCTS)
+                       txq->axq_lastdsWithCTS = NULL;
+               if (ds == txq->axq_gatingds)
+                       txq->axq_gatingds = NULL;
+
+               /*
+                * Remove ath_buf's of the same transmit unit from txq,
+                * however leave the last descriptor back as the holding
+                * descriptor for hw.
+                */
+               lastbf->bf_stale = true;
+               INIT_LIST_HEAD(&bf_head);
+               if (!list_is_singular(&lastbf->list))
+                       list_cut_position(&bf_head,
+                               &txq->axq_q, lastbf->list.prev);
+
+               txq->axq_depth--;
+               if (bf_isaggr(bf))
+                       txq->axq_aggr_depth--;
+
+               txok = (ds->ds_txstat.ts_status == 0);
+               spin_unlock_bh(&txq->axq_lock);
+
+               if (bf_held) {
+                       spin_lock_bh(&sc->tx.txbuflock);
+                       list_move_tail(&bf_held->list, &sc->tx.txbuf);
+                       spin_unlock_bh(&sc->tx.txbuflock);
+               }
+
+               if (!bf_isampdu(bf)) {
+                       /*
+                        * This frame is sent out as a single frame.
+                        * Use hardware retry status for this frame.
+                        */
+                       bf->bf_retries = ds->ds_txstat.ts_longretry;
+                       if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
+                               bf->bf_state.bf_type |= BUF_XRETRY;
+                       ath_tx_rc_status(bf, ds, 0, txok, true);
+               }
+
+               if (bf_isampdu(bf))
+                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
+               else
+                       ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
+
+               ath_wake_mac80211_queue(sc, txq);
+
+               spin_lock_bh(&txq->axq_lock);
+               if (sc->sc_flags & SC_OP_TXAGGR)
+                       ath_txq_schedule(sc, txq);
+               spin_unlock_bh(&txq->axq_lock);
+       }
+}
+
+
+void ath_tx_tasklet(struct ath_softc *sc)
+{
+       int i;
+       u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
+
+       ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
+                       ath_tx_processq(sc, &sc->tx.txq[i]);
+       }
+}
+
+/*****************/
+/* Init, Cleanup */
+/*****************/
+
+int ath_tx_init(struct ath_softc *sc, int nbufs)
+{
+       int error = 0;
+
+       spin_lock_init(&sc->tx.txbuflock);
+
+       error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
+                                 "tx", nbufs, 1);
+       if (error != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Failed to allocate tx descriptors: %d\n", error);
+               goto err;
+       }
+
+       error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
+                                 "beacon", ATH_BCBUF, 1);
+       if (error != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Failed to allocate beacon descriptors: %d\n", error);
+               goto err;
+       }
+
+err:
+       if (error != 0)
+               ath_tx_cleanup(sc);
+
+       return error;
+}
+
+void ath_tx_cleanup(struct ath_softc *sc)
+{
+       if (sc->beacon.bdma.dd_desc_len != 0)
+               ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
+
+       if (sc->tx.txdma.dd_desc_len != 0)
+               ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+}
+
+void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
+{
+       struct ath_atx_tid *tid;
+       struct ath_atx_ac *ac;
+       int tidno, acno;
+
+       for (tidno = 0, tid = &an->tid[tidno];
+            tidno < WME_NUM_TID;
+            tidno++, tid++) {
+               tid->an        = an;
+               tid->tidno     = tidno;
+               tid->seq_start = tid->seq_next = 0;
+               tid->baw_size  = WME_MAX_BA;
+               tid->baw_head  = tid->baw_tail = 0;
+               tid->sched     = false;
+               tid->paused    = false;
+               tid->state &= ~AGGR_CLEANUP;
+               INIT_LIST_HEAD(&tid->buf_q);
+               acno = TID_TO_WME_AC(tidno);
+               tid->ac = &an->ac[acno];
+               tid->state &= ~AGGR_ADDBA_COMPLETE;
+               tid->state &= ~AGGR_ADDBA_PROGRESS;
+               tid->addba_exchangeattempts = 0;
+       }
+
+       for (acno = 0, ac = &an->ac[acno];
+            acno < WME_NUM_AC; acno++, ac++) {
+               ac->sched    = false;
+               INIT_LIST_HEAD(&ac->tid_q);
+
+               switch (acno) {
+               case WME_AC_BE:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
+                       break;
+               case WME_AC_BK:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
+                       break;
+               case WME_AC_VI:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
+                       break;
+               case WME_AC_VO:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
+                       break;
+               }
+       }
+}
+
+void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
+{
+       int i;
+       struct ath_atx_ac *ac, *ac_tmp;
+       struct ath_atx_tid *tid, *tid_tmp;
+       struct ath_txq *txq;
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (ATH_TXQ_SETUP(sc, i)) {
+                       txq = &sc->tx.txq[i];
+
+                       spin_lock(&txq->axq_lock);
+
+                       list_for_each_entry_safe(ac,
+                                       ac_tmp, &txq->axq_acq, list) {
+                               tid = list_first_entry(&ac->tid_q,
+                                               struct ath_atx_tid, list);
+                               if (tid && tid->an != an)
+                                       continue;
+                               list_del(&ac->list);
+                               ac->sched = false;
+
+                               list_for_each_entry_safe(tid,
+                                               tid_tmp, &ac->tid_q, list) {
+                                       list_del(&tid->list);
+                                       tid->sched = false;
+                                       ath_tid_drain(sc, txq, tid);
+                                       tid->state &= ~AGGR_ADDBA_COMPLETE;
+                                       tid->addba_exchangeattempts = 0;
+                                       tid->state &= ~AGGR_CLEANUP;
+                               }
+                       }
+
+                       spin_unlock(&txq->axq_lock);
+               }
+       }
+}
diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath5k/Kconfig
deleted file mode 100644 (file)
index 509b6f9..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-config ATH5K
-       tristate "Atheros 5xxx wireless cards support"
-       depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
-       select ATH_COMMON
-       select MAC80211_LEDS
-       select LEDS_CLASS
-       select NEW_LEDS
-       ---help---
-         This module adds support for wireless adapters based on
-         Atheros 5xxx chipset.
-
-         Currently the following chip versions are supported:
-
-         MAC: AR5211 AR5212
-         PHY: RF5111/2111 RF5112/2112 RF5413/2413
-
-         This driver uses the kernel's mac80211 subsystem.
-
-         If you choose to build a module, it'll be called ath5k. Say M if
-         unsure.
-
-config ATH5K_DEBUG
-       bool "Atheros 5xxx debugging"
-       depends on ATH5K
-       ---help---
-         Atheros 5xxx debugging messages.
-
-         Say Y, if and you will get debug options for ath5k.
-         To use this, you need to mount debugfs:
-
-         mkdir /debug/
-         mount -t debugfs debug /debug/
-
-         You will get access to files under:
-         /debug/ath5k/phy0/
-
-         To enable debug, pass the debug level to the debug module
-         parameter. For example:
-
-         modprobe ath5k debug=0x00000400
-
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile
deleted file mode 100644 (file)
index 84a74c5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-ath5k-y                                += caps.o
-ath5k-y                                += initvals.o
-ath5k-y                                += eeprom.o
-ath5k-y                                += gpio.o
-ath5k-y                                += desc.o
-ath5k-y                                += dma.o
-ath5k-y                                += qcu.o
-ath5k-y                                += pcu.o
-ath5k-y                                += phy.o
-ath5k-y                                += reset.o
-ath5k-y                                += attach.o
-ath5k-y                                += base.o
-ath5k-y                                += led.o
-ath5k-$(CONFIG_ATH5K_DEBUG)    += debug.o
-obj-$(CONFIG_ATH5K)            += ath5k.o
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
deleted file mode 100644 (file)
index 48c18d1..0000000
+++ /dev/null
@@ -1,1354 +0,0 @@
-/*
- * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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 _ATH5K_H
-#define _ATH5K_H
-
-/* TODO: Clean up channel debuging -doesn't work anyway- and start
- * working on reg. control code using all available eeprom information
- * -rev. engineering needed- */
-#define CHAN_DEBUG     0
-
-#include <linux/io.h>
-#include <linux/types.h>
-#include <net/mac80211.h>
-
-#include "../ath/regd.h"
-
-/* RX/TX descriptor hw structs
- * TODO: Driver part should only see sw structs */
-#include "desc.h"
-
-/* EEPROM structs/offsets
- * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
- * and clean up common bits, then introduce set/get functions in eeprom.c */
-#include "eeprom.h"
-
-/* PCI IDs */
-#define PCI_DEVICE_ID_ATHEROS_AR5210           0x0007 /* AR5210 */
-#define PCI_DEVICE_ID_ATHEROS_AR5311           0x0011 /* AR5311 */
-#define PCI_DEVICE_ID_ATHEROS_AR5211           0x0012 /* AR5211 */
-#define PCI_DEVICE_ID_ATHEROS_AR5212           0x0013 /* AR5212 */
-#define PCI_DEVICE_ID_3COM_3CRDAG675           0x0013 /* 3CRDAG675 (Atheros AR5212) */
-#define PCI_DEVICE_ID_3COM_2_3CRPAG175                 0x0013 /* 3CRPAG175 (Atheros AR5212) */
-#define PCI_DEVICE_ID_ATHEROS_AR5210_AP        0x0207 /* AR5210 (Early) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_IBM       0x1014 /* AR5212 (IBM MiniPCI) */
-#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT   0x1107 /* AR5210 (no eeprom) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT   0x1113 /* AR5212 (no eeprom) */
-#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT   0x1112 /* AR5211 (no eeprom) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA      0xf013 /* AR5212 (emulation board) */
-#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY    0xff12 /* AR5211 (emulation board) */
-#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B   0xf11b /* AR5211 (emulation board) */
-#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2      0x0052 /* AR5312 WMAC (AP31) */
-#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7      0x0057 /* AR5312 WMAC (AP30-040) */
-#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8      0x0058 /* AR5312 WMAC (AP43-030) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0014      0x0014 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0015      0x0015 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0016      0x0016 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0017      0x0017 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0018      0x0018 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0019      0x0019 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR2413           0x001a /* AR2413 (Griffin-lite) */
-#define PCI_DEVICE_ID_ATHEROS_AR5413           0x001b /* AR5413 (Eagle) */
-#define PCI_DEVICE_ID_ATHEROS_AR5424           0x001c /* AR5424 (Condor PCI-E) */
-#define PCI_DEVICE_ID_ATHEROS_AR5416           0x0023 /* AR5416 */
-#define PCI_DEVICE_ID_ATHEROS_AR5418           0x0024 /* AR5418 */
-
-/****************************\
-  GENERIC DRIVER DEFINITIONS
-\****************************/
-
-#define ATH5K_PRINTF(fmt, ...)   printk("%s: " fmt, __func__, ##__VA_ARGS__)
-
-#define ATH5K_PRINTK(_sc, _level, _fmt, ...) \
-       printk(_level "ath5k %s: " _fmt, \
-               ((_sc) && (_sc)->hw) ? wiphy_name((_sc)->hw->wiphy) : "", \
-               ##__VA_ARGS__)
-
-#define ATH5K_PRINTK_LIMIT(_sc, _level, _fmt, ...) do { \
-       if (net_ratelimit()) \
-               ATH5K_PRINTK(_sc, _level, _fmt, ##__VA_ARGS__); \
-       } while (0)
-
-#define ATH5K_INFO(_sc, _fmt, ...) \
-       ATH5K_PRINTK(_sc, KERN_INFO, _fmt, ##__VA_ARGS__)
-
-#define ATH5K_WARN(_sc, _fmt, ...) \
-       ATH5K_PRINTK_LIMIT(_sc, KERN_WARNING, _fmt, ##__VA_ARGS__)
-
-#define ATH5K_ERR(_sc, _fmt, ...) \
-       ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__)
-
-/*
- * AR5K REGISTER ACCESS
- */
-
-/* Some macros to read/write fields */
-
-/* First shift, then mask */
-#define AR5K_REG_SM(_val, _flags)                                      \
-       (((_val) << _flags##_S) & (_flags))
-
-/* First mask, then shift */
-#define AR5K_REG_MS(_val, _flags)                                      \
-       (((_val) & (_flags)) >> _flags##_S)
-
-/* Some registers can hold multiple values of interest. For this
- * reason when we want to write to these registers we must first
- * retrieve the values which we do not want to clear (lets call this
- * old_data) and then set the register with this and our new_value:
- * ( old_data | new_value) */
-#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val)                    \
-       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \
-           (((_val) << _flags##_S) & (_flags)), _reg)
-
-#define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask)                  \
-       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) &           \
-                       (_mask)) | (_flags), _reg)
-
-#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)                         \
-       ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg)
-
-#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags)                        \
-       ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg)
-
-/* Access to PHY registers */
-#define AR5K_PHY_READ(ah, _reg)                                        \
-       ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
-
-#define AR5K_PHY_WRITE(ah, _reg, _val)                                 \
-       ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
-
-/* Access QCU registers per queue */
-#define AR5K_REG_READ_Q(ah, _reg, _queue)                              \
-       (ath5k_hw_reg_read(ah, _reg) & (1 << _queue))                   \
-
-#define AR5K_REG_WRITE_Q(ah, _reg, _queue)                             \
-       ath5k_hw_reg_write(ah, (1 << _queue), _reg)
-
-#define AR5K_Q_ENABLE_BITS(_reg, _queue) do {                          \
-       _reg |= 1 << _queue;                                            \
-} while (0)
-
-#define AR5K_Q_DISABLE_BITS(_reg, _queue) do {                         \
-       _reg &= ~(1 << _queue);                                         \
-} while (0)
-
-/* Used while writing initvals */
-#define AR5K_REG_WAIT(_i) do {                                         \
-       if (_i % 64)                                                    \
-               udelay(1);                                              \
-} while (0)
-
-/* Register dumps are done per operation mode */
-#define AR5K_INI_RFGAIN_5GHZ           0
-#define AR5K_INI_RFGAIN_2GHZ           1
-
-/* TODO: Clean this up */
-#define AR5K_INI_VAL_11A               0
-#define AR5K_INI_VAL_11A_TURBO         1
-#define AR5K_INI_VAL_11B               2
-#define AR5K_INI_VAL_11G               3
-#define AR5K_INI_VAL_11G_TURBO         4
-#define AR5K_INI_VAL_XR                        0
-#define AR5K_INI_VAL_MAX               5
-
-/* Used for BSSID etc manipulation */
-#define AR5K_LOW_ID(_a)(                               \
-(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
-)
-
-#define AR5K_HIGH_ID(_a)       ((_a)[4] | (_a)[5] << 8)
-
-/*
- * Some tuneable values (these should be changeable by the user)
- * TODO: Make use of them and add more options OR use debug/configfs
- */
-#define AR5K_TUNE_DMA_BEACON_RESP              2
-#define AR5K_TUNE_SW_BEACON_RESP               10
-#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF      0
-#define AR5K_TUNE_RADAR_ALERT                  false
-#define AR5K_TUNE_MIN_TX_FIFO_THRES            1
-#define AR5K_TUNE_MAX_TX_FIFO_THRES            ((IEEE80211_MAX_LEN / 64) + 1)
-#define AR5K_TUNE_REGISTER_TIMEOUT             20000
-/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
- * be the max value. */
-#define AR5K_TUNE_RSSI_THRES                   129
-/* This must be set when setting the RSSI threshold otherwise it can
- * prevent a reset. If AR5K_RSSI_THR is read after writing to it
- * the BMISS_THRES will be seen as 0, seems harware doesn't keep
- * track of it. Max value depends on harware. For AR5210 this is just 7.
- * For AR5211+ this seems to be up to 255. */
-#define AR5K_TUNE_BMISS_THRES                  7
-#define AR5K_TUNE_REGISTER_DWELL_TIME          20000
-#define AR5K_TUNE_BEACON_INTERVAL              100
-#define AR5K_TUNE_AIFS                         2
-#define AR5K_TUNE_AIFS_11B                     2
-#define AR5K_TUNE_AIFS_XR                      0
-#define AR5K_TUNE_CWMIN                                15
-#define AR5K_TUNE_CWMIN_11B                    31
-#define AR5K_TUNE_CWMIN_XR                     3
-#define AR5K_TUNE_CWMAX                                1023
-#define AR5K_TUNE_CWMAX_11B                    1023
-#define AR5K_TUNE_CWMAX_XR                     7
-#define AR5K_TUNE_NOISE_FLOOR                  -72
-#define AR5K_TUNE_MAX_TXPOWER                  63
-#define AR5K_TUNE_DEFAULT_TXPOWER              25
-#define AR5K_TUNE_TPC_TXPOWER                  false
-#define AR5K_TUNE_ANT_DIVERSITY                        true
-#define AR5K_TUNE_HWTXTRIES                    4
-
-#define AR5K_INIT_CARR_SENSE_EN                        1
-
-/*Swap RX/TX Descriptor for big endian archs*/
-#if defined(__BIG_ENDIAN)
-#define AR5K_INIT_CFG  (               \
-       AR5K_CFG_SWTD | AR5K_CFG_SWRD   \
-)
-#else
-#define AR5K_INIT_CFG  0x00000000
-#endif
-
-/* Initial values */
-#define        AR5K_INIT_CYCRSSI_THR1                  2
-#define AR5K_INIT_TX_LATENCY                   502
-#define AR5K_INIT_USEC                         39
-#define AR5K_INIT_USEC_TURBO                   79
-#define AR5K_INIT_USEC_32                      31
-#define AR5K_INIT_SLOT_TIME                    396
-#define AR5K_INIT_SLOT_TIME_TURBO              480
-#define AR5K_INIT_ACK_CTS_TIMEOUT              1024
-#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO                0x08000800
-#define AR5K_INIT_PROG_IFS                     920
-#define AR5K_INIT_PROG_IFS_TURBO               960
-#define AR5K_INIT_EIFS                         3440
-#define AR5K_INIT_EIFS_TURBO                   6880
-#define AR5K_INIT_SIFS                         560
-#define AR5K_INIT_SIFS_TURBO                   480
-#define AR5K_INIT_SH_RETRY                     10
-#define AR5K_INIT_LG_RETRY                     AR5K_INIT_SH_RETRY
-#define AR5K_INIT_SSH_RETRY                    32
-#define AR5K_INIT_SLG_RETRY                    AR5K_INIT_SSH_RETRY
-#define AR5K_INIT_TX_RETRY                     10
-
-#define AR5K_INIT_TRANSMIT_LATENCY             (                       \
-       (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) |       \
-       (AR5K_INIT_USEC)                                                \
-)
-#define AR5K_INIT_TRANSMIT_LATENCY_TURBO       (                       \
-       (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) |       \
-       (AR5K_INIT_USEC_TURBO)                                          \
-)
-#define AR5K_INIT_PROTO_TIME_CNTRL             (                       \
-       (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) |      \
-       (AR5K_INIT_PROG_IFS)                                            \
-)
-#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO       (                       \
-       (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
-       (AR5K_INIT_PROG_IFS_TURBO)                                      \
-)
-
-/* token to use for aifs, cwmin, cwmax in MadWiFi */
-#define        AR5K_TXQ_USEDEFAULT     ((u32) -1)
-
-/* GENERIC CHIPSET DEFINITIONS */
-
-/* MAC Chips */
-enum ath5k_version {
-       AR5K_AR5210     = 0,
-       AR5K_AR5211     = 1,
-       AR5K_AR5212     = 2,
-};
-
-/* PHY Chips */
-enum ath5k_radio {
-       AR5K_RF5110     = 0,
-       AR5K_RF5111     = 1,
-       AR5K_RF5112     = 2,
-       AR5K_RF2413     = 3,
-       AR5K_RF5413     = 4,
-       AR5K_RF2316     = 5,
-       AR5K_RF2317     = 6,
-       AR5K_RF2425     = 7,
-};
-
-/*
- * Common silicon revision/version values
- */
-
-enum ath5k_srev_type {
-       AR5K_VERSION_MAC,
-       AR5K_VERSION_RAD,
-};
-
-struct ath5k_srev_name {
-       const char              *sr_name;
-       enum ath5k_srev_type    sr_type;
-       u_int                   sr_val;
-};
-
-#define AR5K_SREV_UNKNOWN      0xffff
-
-#define AR5K_SREV_AR5210       0x00 /* Crete */
-#define AR5K_SREV_AR5311       0x10 /* Maui 1 */
-#define AR5K_SREV_AR5311A      0x20 /* Maui 2 */
-#define AR5K_SREV_AR5311B      0x30 /* Spirit */
-#define AR5K_SREV_AR5211       0x40 /* Oahu */
-#define AR5K_SREV_AR5212       0x50 /* Venice */
-#define AR5K_SREV_AR5213       0x55 /* ??? */
-#define AR5K_SREV_AR5213A      0x59 /* Hainan */
-#define AR5K_SREV_AR2413       0x78 /* Griffin lite */
-#define AR5K_SREV_AR2414       0x70 /* Griffin */
-#define AR5K_SREV_AR5424       0x90 /* Condor */
-#define AR5K_SREV_AR5413       0xa4 /* Eagle lite */
-#define AR5K_SREV_AR5414       0xa0 /* Eagle */
-#define AR5K_SREV_AR2415       0xb0 /* Talon */
-#define AR5K_SREV_AR5416       0xc0 /* PCI-E */
-#define AR5K_SREV_AR5418       0xca /* PCI-E */
-#define AR5K_SREV_AR2425       0xe0 /* Swan */
-#define AR5K_SREV_AR2417       0xf0 /* Nala */
-
-#define AR5K_SREV_RAD_5110     0x00
-#define AR5K_SREV_RAD_5111     0x10
-#define AR5K_SREV_RAD_5111A    0x15
-#define AR5K_SREV_RAD_2111     0x20
-#define AR5K_SREV_RAD_5112     0x30
-#define AR5K_SREV_RAD_5112A    0x35
-#define        AR5K_SREV_RAD_5112B     0x36
-#define AR5K_SREV_RAD_2112     0x40
-#define AR5K_SREV_RAD_2112A    0x45
-#define        AR5K_SREV_RAD_2112B     0x46
-#define AR5K_SREV_RAD_2413     0x50
-#define AR5K_SREV_RAD_5413     0x60
-#define AR5K_SREV_RAD_2316     0x70 /* Cobra SoC */
-#define AR5K_SREV_RAD_2317     0x80
-#define AR5K_SREV_RAD_5424     0xa0 /* Mostly same as 5413 */
-#define AR5K_SREV_RAD_2425     0xa2
-#define AR5K_SREV_RAD_5133     0xc0
-
-#define AR5K_SREV_PHY_5211     0x30
-#define AR5K_SREV_PHY_5212     0x41
-#define        AR5K_SREV_PHY_5212A     0x42
-#define AR5K_SREV_PHY_5212B    0x43
-#define AR5K_SREV_PHY_2413     0x45
-#define AR5K_SREV_PHY_5413     0x61
-#define AR5K_SREV_PHY_2425     0x70
-
-/* IEEE defs */
-#define IEEE80211_MAX_LEN       2500
-
-/* TODO add support to mac80211 for vendor-specific rates and modes */
-
-/*
- * Some of this information is based on Documentation from:
- *
- * http://madwifi.org/wiki/ChipsetFeatures/SuperAG
- *
- * Modulation for Atheros' eXtended Range - range enhancing extension that is
- * supposed to double the distance an Atheros client device can keep a
- * connection with an Atheros access point. This is achieved by increasing
- * the receiver sensitivity up to, -105dBm, which is about 20dB above what
- * the 802.11 specifications demand. In addition, new (proprietary) data rates
- * are introduced: 3, 2, 1, 0.5 and 0.25 MBit/s.
- *
- * Please note that can you either use XR or TURBO but you cannot use both,
- * they are exclusive.
- *
- */
-#define MODULATION_XR          0x00000200
-/*
- * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a
- * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s
- * signaling rate achieved through the bonding of two 54Mbit/s 802.11g
- * channels. To use this feature your Access Point must also suport it.
- * There is also a distinction between "static" and "dynamic" turbo modes:
- *
- * - Static: is the dumb version: devices set to this mode stick to it until
- *     the mode is turned off.
- * - Dynamic: is the intelligent version, the network decides itself if it
- *     is ok to use turbo. As soon as traffic is detected on adjacent channels
- *     (which would get used in turbo mode), or when a non-turbo station joins
- *     the network, turbo mode won't be used until the situation changes again.
- *     Dynamic mode is achieved by Atheros' Adaptive Radio (AR) feature which
- *     monitors the used radio band in order to decide whether turbo mode may
- *     be used or not.
- *
- * This article claims Super G sticks to bonding of channels 5 and 6 for
- * USA:
- *
- * http://www.pcworld.com/article/id,113428-page,1/article.html
- *
- * The channel bonding seems to be driver specific though. In addition to
- * deciding what channels will be used, these "Turbo" modes are accomplished
- * by also enabling the following features:
- *
- * - Bursting: allows multiple frames to be sent at once, rather than pausing
- *     after each frame. Bursting is a standards-compliant feature that can be
- *     used with any Access Point.
- * - Fast frames: increases the amount of information that can be sent per
- *     frame, also resulting in a reduction of transmission overhead. It is a
- *     proprietary feature that needs to be supported by the Access Point.
- * - Compression: data frames are compressed in real time using a Lempel Ziv
- *     algorithm. This is done transparently. Once this feature is enabled,
- *     compression and decompression takes place inside the chipset, without
- *     putting additional load on the host CPU.
- *
- */
-#define MODULATION_TURBO       0x00000080
-
-enum ath5k_driver_mode {
-       AR5K_MODE_11A           =       0,
-       AR5K_MODE_11A_TURBO     =       1,
-       AR5K_MODE_11B           =       2,
-       AR5K_MODE_11G           =       3,
-       AR5K_MODE_11G_TURBO     =       4,
-       AR5K_MODE_XR            =       0,
-       AR5K_MODE_MAX           =       5
-};
-
-
-/****************\
-  TX DEFINITIONS
-\****************/
-
-/*
- * TX Status descriptor
- */
-struct ath5k_tx_status {
-       u16     ts_seqnum;
-       u16     ts_tstamp;
-       u8      ts_status;
-       u8      ts_rate[4];
-       u8      ts_retry[4];
-       u8      ts_final_idx;
-       s8      ts_rssi;
-       u8      ts_shortretry;
-       u8      ts_longretry;
-       u8      ts_virtcol;
-       u8      ts_antenna;
-};
-
-#define AR5K_TXSTAT_ALTRATE    0x80
-#define AR5K_TXERR_XRETRY      0x01
-#define AR5K_TXERR_FILT                0x02
-#define AR5K_TXERR_FIFO                0x04
-
-/**
- * enum ath5k_tx_queue - Queue types used to classify tx queues.
- * @AR5K_TX_QUEUE_INACTIVE: q is unused -- see ath5k_hw_release_tx_queue
- * @AR5K_TX_QUEUE_DATA: A normal data queue
- * @AR5K_TX_QUEUE_XR_DATA: An XR-data queue
- * @AR5K_TX_QUEUE_BEACON: The beacon queue
- * @AR5K_TX_QUEUE_CAB: The after-beacon queue
- * @AR5K_TX_QUEUE_UAPSD: Unscheduled Automatic Power Save Delivery queue
- */
-enum ath5k_tx_queue {
-       AR5K_TX_QUEUE_INACTIVE = 0,
-       AR5K_TX_QUEUE_DATA,
-       AR5K_TX_QUEUE_XR_DATA,
-       AR5K_TX_QUEUE_BEACON,
-       AR5K_TX_QUEUE_CAB,
-       AR5K_TX_QUEUE_UAPSD,
-};
-
-#define        AR5K_NUM_TX_QUEUES              10
-#define        AR5K_NUM_TX_QUEUES_NOQCU        2
-
-/*
- * Queue syb-types to classify normal data queues.
- * These are the 4 Access Categories as defined in
- * WME spec. 0 is the lowest priority and 4 is the
- * highest. Normal data that hasn't been classified
- * goes to the Best Effort AC.
- */
-enum ath5k_tx_queue_subtype {
-       AR5K_WME_AC_BK = 0,     /*Background traffic*/
-       AR5K_WME_AC_BE,         /*Best-effort (normal) traffic)*/
-       AR5K_WME_AC_VI,         /*Video traffic*/
-       AR5K_WME_AC_VO,         /*Voice traffic*/
-};
-
-/*
- * Queue ID numbers as returned by the hw functions, each number
- * represents a hw queue. If hw does not support hw queues
- * (eg 5210) all data goes in one queue. These match
- * d80211 definitions (net80211/MadWiFi don't use them).
- */
-enum ath5k_tx_queue_id {
-       AR5K_TX_QUEUE_ID_NOQCU_DATA     = 0,
-       AR5K_TX_QUEUE_ID_NOQCU_BEACON   = 1,
-       AR5K_TX_QUEUE_ID_DATA_MIN       = 0, /*IEEE80211_TX_QUEUE_DATA0*/
-       AR5K_TX_QUEUE_ID_DATA_MAX       = 4, /*IEEE80211_TX_QUEUE_DATA4*/
-       AR5K_TX_QUEUE_ID_DATA_SVP       = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/
-       AR5K_TX_QUEUE_ID_CAB            = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/
-       AR5K_TX_QUEUE_ID_BEACON         = 7, /*IEEE80211_TX_QUEUE_BEACON*/
-       AR5K_TX_QUEUE_ID_UAPSD          = 8,
-       AR5K_TX_QUEUE_ID_XR_DATA        = 9,
-};
-
-/*
- * Flags to set hw queue's parameters...
- */
-#define AR5K_TXQ_FLAG_TXOKINT_ENABLE           0x0001  /* Enable TXOK interrupt */
-#define AR5K_TXQ_FLAG_TXERRINT_ENABLE          0x0002  /* Enable TXERR interrupt */
-#define AR5K_TXQ_FLAG_TXEOLINT_ENABLE          0x0004  /* Enable TXEOL interrupt -not used- */
-#define AR5K_TXQ_FLAG_TXDESCINT_ENABLE         0x0008  /* Enable TXDESC interrupt -not used- */
-#define AR5K_TXQ_FLAG_TXURNINT_ENABLE          0x0010  /* Enable TXURN interrupt */
-#define AR5K_TXQ_FLAG_CBRORNINT_ENABLE         0x0020  /* Enable CBRORN interrupt */
-#define AR5K_TXQ_FLAG_CBRURNINT_ENABLE         0x0040  /* Enable CBRURN interrupt */
-#define AR5K_TXQ_FLAG_QTRIGINT_ENABLE          0x0080  /* Enable QTRIG interrupt */
-#define AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE                0x0100  /* Enable TXNOFRM interrupt */
-#define AR5K_TXQ_FLAG_BACKOFF_DISABLE          0x0200  /* Disable random post-backoff */
-#define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE        0x0300  /* Enable ready time expiry policy (?)*/
-#define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE        0x0800  /* Enable backoff while bursting */
-#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS                0x1000  /* Disable backoff while bursting */
-#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE       0x2000  /* Enable hw compression -not implemented-*/
-
-/*
- * A struct to hold tx queue's parameters
- */
-struct ath5k_txq_info {
-       enum ath5k_tx_queue tqi_type;
-       enum ath5k_tx_queue_subtype tqi_subtype;
-       u16     tqi_flags;      /* Tx queue flags (see above) */
-       u32     tqi_aifs;       /* Arbitrated Interframe Space */
-       s32     tqi_cw_min;     /* Minimum Contention Window */
-       s32     tqi_cw_max;     /* Maximum Contention Window */
-       u32     tqi_cbr_period; /* Constant bit rate period */
-       u32     tqi_cbr_overflow_limit;
-       u32     tqi_burst_time;
-       u32     tqi_ready_time; /* Not used */
-};
-
-/*
- * Transmit packet types.
- * used on tx control descriptor
- * TODO: Use them inside base.c corectly
- */
-enum ath5k_pkt_type {
-       AR5K_PKT_TYPE_NORMAL            = 0,
-       AR5K_PKT_TYPE_ATIM              = 1,
-       AR5K_PKT_TYPE_PSPOLL            = 2,
-       AR5K_PKT_TYPE_BEACON            = 3,
-       AR5K_PKT_TYPE_PROBE_RESP        = 4,
-       AR5K_PKT_TYPE_PIFS              = 5,
-};
-
-/*
- * TX power and TPC settings
- */
-#define AR5K_TXPOWER_OFDM(_r, _v)      (                       \
-       ((0 & 1) << ((_v) + 6)) |                               \
-       (((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v)) \
-)
-
-#define AR5K_TXPOWER_CCK(_r, _v)       (                       \
-       (ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v)     \
-)
-
-/*
- * DMA size definitions (2^n+2)
- */
-enum ath5k_dmasize {
-       AR5K_DMASIZE_4B = 0,
-       AR5K_DMASIZE_8B,
-       AR5K_DMASIZE_16B,
-       AR5K_DMASIZE_32B,
-       AR5K_DMASIZE_64B,
-       AR5K_DMASIZE_128B,
-       AR5K_DMASIZE_256B,
-       AR5K_DMASIZE_512B
-};
-
-
-/****************\
-  RX DEFINITIONS
-\****************/
-
-/*
- * RX Status descriptor
- */
-struct ath5k_rx_status {
-       u16     rs_datalen;
-       u16     rs_tstamp;
-       u8      rs_status;
-       u8      rs_phyerr;
-       s8      rs_rssi;
-       u8      rs_keyix;
-       u8      rs_rate;
-       u8      rs_antenna;
-       u8      rs_more;
-};
-
-#define AR5K_RXERR_CRC         0x01
-#define AR5K_RXERR_PHY         0x02
-#define AR5K_RXERR_FIFO                0x04
-#define AR5K_RXERR_DECRYPT     0x08
-#define AR5K_RXERR_MIC         0x10
-#define AR5K_RXKEYIX_INVALID   ((u8) - 1)
-#define AR5K_TXKEYIX_INVALID   ((u32) - 1)
-
-
-/**************************\
- BEACON TIMERS DEFINITIONS
-\**************************/
-
-#define AR5K_BEACON_PERIOD     0x0000ffff
-#define AR5K_BEACON_ENA                0x00800000 /*enable beacon xmit*/
-#define AR5K_BEACON_RESET_TSF  0x01000000 /*force a TSF reset*/
-
-#if 0
-/**
- * struct ath5k_beacon_state - Per-station beacon timer state.
- * @bs_interval: in TU's, can also include the above flags
- * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a
- *     Point Coordination Function capable AP
- */
-struct ath5k_beacon_state {
-       u32     bs_next_beacon;
-       u32     bs_next_dtim;
-       u32     bs_interval;
-       u8      bs_dtim_period;
-       u8      bs_cfp_period;
-       u16     bs_cfp_max_duration;
-       u16     bs_cfp_du_remain;
-       u16     bs_tim_offset;
-       u16     bs_sleep_duration;
-       u16     bs_bmiss_threshold;
-       u32     bs_cfp_next;
-};
-#endif
-
-
-/*
- * TSF to TU conversion:
- *
- * TSF is a 64bit value in usec (microseconds).
- * TU is a 32bit value and defined by IEEE802.11 (page 6) as "A measurement of
- * time equal to 1024 usec", so it's roughly milliseconds (usec / 1024).
- */
-#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10)
-
-
-/*******************************\
-  GAIN OPTIMIZATION DEFINITIONS
-\*******************************/
-
-enum ath5k_rfgain {
-       AR5K_RFGAIN_INACTIVE = 0,
-       AR5K_RFGAIN_ACTIVE,
-       AR5K_RFGAIN_READ_REQUESTED,
-       AR5K_RFGAIN_NEED_CHANGE,
-};
-
-struct ath5k_gain {
-       u8                      g_step_idx;
-       u8                      g_current;
-       u8                      g_target;
-       u8                      g_low;
-       u8                      g_high;
-       u8                      g_f_corr;
-       u8                      g_state;
-};
-
-/********************\
-  COMMON DEFINITIONS
-\********************/
-
-#define AR5K_SLOT_TIME_9       396
-#define AR5K_SLOT_TIME_20      880
-#define AR5K_SLOT_TIME_MAX     0xffff
-
-/* channel_flags */
-#define        CHANNEL_CW_INT  0x0008  /* Contention Window interference detected */
-#define        CHANNEL_TURBO   0x0010  /* Turbo Channel */
-#define        CHANNEL_CCK     0x0020  /* CCK channel */
-#define        CHANNEL_OFDM    0x0040  /* OFDM channel */
-#define        CHANNEL_2GHZ    0x0080  /* 2GHz channel. */
-#define        CHANNEL_5GHZ    0x0100  /* 5GHz channel */
-#define        CHANNEL_PASSIVE 0x0200  /* Only passive scan allowed */
-#define        CHANNEL_DYN     0x0400  /* Dynamic CCK-OFDM channel (for g operation) */
-#define        CHANNEL_XR      0x0800  /* XR channel */
-
-#define        CHANNEL_A       (CHANNEL_5GHZ|CHANNEL_OFDM)
-#define        CHANNEL_B       (CHANNEL_2GHZ|CHANNEL_CCK)
-#define        CHANNEL_G       (CHANNEL_2GHZ|CHANNEL_OFDM)
-#define        CHANNEL_T       (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define        CHANNEL_TG      (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define        CHANNEL_108A    CHANNEL_T
-#define        CHANNEL_108G    CHANNEL_TG
-#define        CHANNEL_X       (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
-
-#define        CHANNEL_ALL     (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \
-               CHANNEL_TURBO)
-
-#define        CHANNEL_ALL_NOTURBO     (CHANNEL_ALL & ~CHANNEL_TURBO)
-#define CHANNEL_MODES          CHANNEL_ALL
-
-/*
- * Used internaly for reset_tx_queue).
- * Also see struct struct ieee80211_channel.
- */
-#define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0)
-#define IS_CHAN_B(_c)  ((_c.hw_value & CHANNEL_B) != 0)
-
-/*
- * The following structure is used to map 2GHz channels to
- * 5GHz Atheros channels.
- * TODO: Clean up
- */
-struct ath5k_athchan_2ghz {
-       u32     a2_flags;
-       u16     a2_athchan;
-};
-
-
-/******************\
-  RATE DEFINITIONS
-\******************/
-
-/**
- * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32.
- *
- * The rate code is used to get the RX rate or set the TX rate on the
- * hardware descriptors. It is also used for internal modulation control
- * and settings.
- *
- * This is the hardware rate map we are aware of:
- *
- * rate_code   0x01    0x02    0x03    0x04    0x05    0x06    0x07    0x08
- * rate_kbps   3000    1000    ?       ?       ?       2000    500     48000
- *
- * rate_code   0x09    0x0A    0x0B    0x0C    0x0D    0x0E    0x0F    0x10
- * rate_kbps   24000   12000   6000    54000   36000   18000   9000    ?
- *
- * rate_code   17      18      19      20      21      22      23      24
- * rate_kbps   ?       ?       ?       ?       ?       ?       ?       11000
- *
- * rate_code   25      26      27      28      29      30      31      32
- * rate_kbps   5500    2000    1000    11000S  5500S   2000S   ?       ?
- *
- * "S" indicates CCK rates with short preamble.
- *
- * AR5211 has different rate codes for CCK (802.11B) rates. It only uses the
- * lowest 4 bits, so they are the same as below with a 0xF mask.
- * (0xB, 0xA, 0x9 and 0x8 for 1M, 2M, 5.5M and 11M).
- * We handle this in ath5k_setup_bands().
- */
-#define AR5K_MAX_RATES 32
-
-/* B */
-#define ATH5K_RATE_CODE_1M     0x1B
-#define ATH5K_RATE_CODE_2M     0x1A
-#define ATH5K_RATE_CODE_5_5M   0x19
-#define ATH5K_RATE_CODE_11M    0x18
-/* A and G */
-#define ATH5K_RATE_CODE_6M     0x0B
-#define ATH5K_RATE_CODE_9M     0x0F
-#define ATH5K_RATE_CODE_12M    0x0A
-#define ATH5K_RATE_CODE_18M    0x0E
-#define ATH5K_RATE_CODE_24M    0x09
-#define ATH5K_RATE_CODE_36M    0x0D
-#define ATH5K_RATE_CODE_48M    0x08
-#define ATH5K_RATE_CODE_54M    0x0C
-/* XR */
-#define ATH5K_RATE_CODE_XR_500K        0x07
-#define ATH5K_RATE_CODE_XR_1M  0x02
-#define ATH5K_RATE_CODE_XR_2M  0x06
-#define ATH5K_RATE_CODE_XR_3M  0x01
-
-/* adding this flag to rate_code enables short preamble */
-#define AR5K_SET_SHORT_PREAMBLE 0x04
-
-/*
- * Crypto definitions
- */
-
-#define AR5K_KEYCACHE_SIZE     8
-
-/***********************\
- HW RELATED DEFINITIONS
-\***********************/
-
-/*
- * Misc definitions
- */
-#define        AR5K_RSSI_EP_MULTIPLIER (1<<7)
-
-#define AR5K_ASSERT_ENTRY(_e, _s) do {         \
-       if (_e >= _s)                           \
-               return (false);                 \
-} while (0)
-
-/*
- * Hardware interrupt abstraction
- */
-
-/**
- * enum ath5k_int - Hardware interrupt masks helpers
- *
- * @AR5K_INT_RX: mask to identify received frame interrupts, of type
- *     AR5K_ISR_RXOK or AR5K_ISR_RXERR
- * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor (?)
- * @AR5K_INT_RXNOFRM: No frame received (?)
- * @AR5K_INT_RXEOL: received End Of List for VEOL (Virtual End Of List). The
- *     Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's
- *     LinkPtr is NULL. For more details, refer to:
- *     http://www.freepatentsonline.com/20030225739.html
- * @AR5K_INT_RXORN: Indicates we got RX overrun (eg. no more descriptors).
- *     Note that Rx overrun is not always fatal, on some chips we can continue
- *     operation without reseting the card, that's why int_fatal is not
- *     common for all chips.
- * @AR5K_INT_TX: mask to identify received frame interrupts, of type
- *     AR5K_ISR_TXOK or AR5K_ISR_TXERR
- * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor (?)
- * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
- *     We currently do increments on interrupt by
- *     (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
- * @AR5K_INT_MIB: Indicates the Management Information Base counters should be
- *     checked. We should do this with ath5k_hw_update_mib_counters() but
- *     it seems we should also then do some noise immunity work.
- * @AR5K_INT_RXPHY: RX PHY Error
- * @AR5K_INT_RXKCM: RX Key cache miss
- * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
- *     beacon that must be handled in software. The alternative is if you
- *     have VEOL support, in that case you let the hardware deal with things.
- * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing
- *     beacons from the AP have associated with, we should probably try to
- *     reassociate. When in IBSS mode this might mean we have not received
- *     any beacons from any local stations. Note that every station in an
- *     IBSS schedules to send beacons at the Target Beacon Transmission Time
- *     (TBTT) with a random backoff.
- * @AR5K_INT_BNR: Beacon Not Ready interrupt - ??
- * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill, disabled for now
- *     until properly handled
- * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA
- *     errors. These types of errors we can enable seem to be of type
- *     AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR.
- * @AR5K_INT_GLOBAL: Used to clear and set the IER
- * @AR5K_INT_NOCARD: signals the card has been removed
- * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same
- *     bit value
- *
- * These are mapped to take advantage of some common bits
- * between the MACs, to be able to set intr properties
- * easier. Some of them are not used yet inside hw.c. Most map
- * to the respective hw interrupt value as they are common amogst different
- * MACs.
- */
-enum ath5k_int {
-       AR5K_INT_RXOK   = 0x00000001,
-       AR5K_INT_RXDESC = 0x00000002,
-       AR5K_INT_RXERR  = 0x00000004,
-       AR5K_INT_RXNOFRM = 0x00000008,
-       AR5K_INT_RXEOL  = 0x00000010,
-       AR5K_INT_RXORN  = 0x00000020,
-       AR5K_INT_TXOK   = 0x00000040,
-       AR5K_INT_TXDESC = 0x00000080,
-       AR5K_INT_TXERR  = 0x00000100,
-       AR5K_INT_TXNOFRM = 0x00000200,
-       AR5K_INT_TXEOL  = 0x00000400,
-       AR5K_INT_TXURN  = 0x00000800,
-       AR5K_INT_MIB    = 0x00001000,
-       AR5K_INT_SWI    = 0x00002000,
-       AR5K_INT_RXPHY  = 0x00004000,
-       AR5K_INT_RXKCM  = 0x00008000,
-       AR5K_INT_SWBA   = 0x00010000,
-       AR5K_INT_BRSSI  = 0x00020000,
-       AR5K_INT_BMISS  = 0x00040000,
-       AR5K_INT_FATAL  = 0x00080000, /* Non common */
-       AR5K_INT_BNR    = 0x00100000, /* Non common */
-       AR5K_INT_TIM    = 0x00200000, /* Non common */
-       AR5K_INT_DTIM   = 0x00400000, /* Non common */
-       AR5K_INT_DTIM_SYNC =    0x00800000, /* Non common */
-       AR5K_INT_GPIO   =       0x01000000,
-       AR5K_INT_BCN_TIMEOUT =  0x02000000, /* Non common */
-       AR5K_INT_CAB_TIMEOUT =  0x04000000, /* Non common */
-       AR5K_INT_RX_DOPPLER =   0x08000000, /* Non common */
-       AR5K_INT_QCBRORN =      0x10000000, /* Non common */
-       AR5K_INT_QCBRURN =      0x20000000, /* Non common */
-       AR5K_INT_QTRIG  =       0x40000000, /* Non common */
-       AR5K_INT_GLOBAL =       0x80000000,
-
-       AR5K_INT_COMMON  = AR5K_INT_RXOK
-               | AR5K_INT_RXDESC
-               | AR5K_INT_RXERR
-               | AR5K_INT_RXNOFRM
-               | AR5K_INT_RXEOL
-               | AR5K_INT_RXORN
-               | AR5K_INT_TXOK
-               | AR5K_INT_TXDESC
-               | AR5K_INT_TXERR
-               | AR5K_INT_TXNOFRM
-               | AR5K_INT_TXEOL
-               | AR5K_INT_TXURN
-               | AR5K_INT_MIB
-               | AR5K_INT_SWI
-               | AR5K_INT_RXPHY
-               | AR5K_INT_RXKCM
-               | AR5K_INT_SWBA
-               | AR5K_INT_BRSSI
-               | AR5K_INT_BMISS
-               | AR5K_INT_GPIO
-               | AR5K_INT_GLOBAL,
-
-       AR5K_INT_NOCARD = 0xffffffff
-};
-
-/*
- * Power management
- */
-enum ath5k_power_mode {
-       AR5K_PM_UNDEFINED = 0,
-       AR5K_PM_AUTO,
-       AR5K_PM_AWAKE,
-       AR5K_PM_FULL_SLEEP,
-       AR5K_PM_NETWORK_SLEEP,
-};
-
-/*
- * These match net80211 definitions (not used in
- * mac80211).
- * TODO: Clean this up
- */
-#define AR5K_LED_INIT  0 /*IEEE80211_S_INIT*/
-#define AR5K_LED_SCAN  1 /*IEEE80211_S_SCAN*/
-#define AR5K_LED_AUTH  2 /*IEEE80211_S_AUTH*/
-#define AR5K_LED_ASSOC 3 /*IEEE80211_S_ASSOC*/
-#define AR5K_LED_RUN   4 /*IEEE80211_S_RUN*/
-
-/* GPIO-controlled software LED */
-#define AR5K_SOFTLED_PIN       0
-#define AR5K_SOFTLED_ON                0
-#define AR5K_SOFTLED_OFF       1
-
-/*
- * Chipset capabilities -see ath5k_hw_get_capability-
- * get_capability function is not yet fully implemented
- * in ath5k so most of these don't work yet...
- * TODO: Implement these & merge with _TUNE_ stuff above
- */
-enum ath5k_capability_type {
-       AR5K_CAP_REG_DMN                = 0,    /* Used to get current reg. domain id */
-       AR5K_CAP_TKIP_MIC               = 2,    /* Can handle TKIP MIC in hardware */
-       AR5K_CAP_TKIP_SPLIT             = 3,    /* TKIP uses split keys */
-       AR5K_CAP_PHYCOUNTERS            = 4,    /* PHY error counters */
-       AR5K_CAP_DIVERSITY              = 5,    /* Supports fast diversity */
-       AR5K_CAP_NUM_TXQUEUES           = 6,    /* Used to get max number of hw txqueues */
-       AR5K_CAP_VEOL                   = 7,    /* Supports virtual EOL */
-       AR5K_CAP_COMPRESSION            = 8,    /* Supports compression */
-       AR5K_CAP_BURST                  = 9,    /* Supports packet bursting */
-       AR5K_CAP_FASTFRAME              = 10,   /* Supports fast frames */
-       AR5K_CAP_TXPOW                  = 11,   /* Used to get global tx power limit */
-       AR5K_CAP_TPC                    = 12,   /* Can do per-packet tx power control (needed for 802.11a) */
-       AR5K_CAP_BSSIDMASK              = 13,   /* Supports bssid mask */
-       AR5K_CAP_MCAST_KEYSRCH          = 14,   /* Supports multicast key search */
-       AR5K_CAP_TSF_ADJUST             = 15,   /* Supports beacon tsf adjust */
-       AR5K_CAP_XR                     = 16,   /* Supports XR mode */
-       AR5K_CAP_WME_TKIPMIC            = 17,   /* Supports TKIP MIC when using WMM */
-       AR5K_CAP_CHAN_HALFRATE          = 18,   /* Supports half rate channels */
-       AR5K_CAP_CHAN_QUARTERRATE       = 19,   /* Supports quarter rate channels */
-       AR5K_CAP_RFSILENT               = 20,   /* Supports RFsilent */
-};
-
-
-/* XXX: we *may* move cap_range stuff to struct wiphy */
-struct ath5k_capabilities {
-       /*
-        * Supported PHY modes
-        * (ie. CHANNEL_A, CHANNEL_B, ...)
-        */
-       DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX);
-
-       /*
-        * Frequency range (without regulation restrictions)
-        */
-       struct {
-               u16     range_2ghz_min;
-               u16     range_2ghz_max;
-               u16     range_5ghz_min;
-               u16     range_5ghz_max;
-       } cap_range;
-
-       /*
-        * Values stored in the EEPROM (some of them...)
-        */
-       struct ath5k_eeprom_info        cap_eeprom;
-
-       /*
-        * Queue information
-        */
-       struct {
-               u8      q_tx_num;
-       } cap_queues;
-};
-
-
-/***************************************\
-  HARDWARE ABSTRACTION LAYER STRUCTURE
-\***************************************/
-
-/*
- * Misc defines
- */
-
-#define AR5K_MAX_GPIO          10
-#define AR5K_MAX_RF_BANKS      8
-
-/* TODO: Clean up and merge with ath5k_softc */
-struct ath5k_hw {
-       u32                     ah_magic;
-
-       struct ath5k_softc      *ah_sc;
-       void __iomem            *ah_iobase;
-
-       enum ath5k_int          ah_imr;
-
-       enum nl80211_iftype     ah_op_mode;
-       enum ath5k_power_mode   ah_power_mode;
-       struct ieee80211_channel ah_current_channel;
-       bool                    ah_turbo;
-       bool                    ah_calibration;
-       bool                    ah_running;
-       bool                    ah_single_chip;
-       bool                    ah_combined_mic;
-
-       u32                     ah_mac_srev;
-       u16                     ah_mac_version;
-       u16                     ah_mac_revision;
-       u16                     ah_phy_revision;
-       u16                     ah_radio_5ghz_revision;
-       u16                     ah_radio_2ghz_revision;
-
-       enum ath5k_version      ah_version;
-       enum ath5k_radio        ah_radio;
-       u32                     ah_phy;
-
-       bool                    ah_5ghz;
-       bool                    ah_2ghz;
-
-#define ah_modes               ah_capabilities.cap_mode
-#define ah_ee_version          ah_capabilities.cap_eeprom.ee_version
-
-       u32                     ah_atim_window;
-       u32                     ah_aifs;
-       u32                     ah_cw_min;
-       u32                     ah_cw_max;
-       bool                    ah_software_retry;
-       u32                     ah_limit_tx_retries;
-
-       u32                     ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
-       bool                    ah_ant_diversity;
-
-       u8                      ah_sta_id[ETH_ALEN];
-
-       /* Current BSSID we are trying to assoc to / create.
-        * This is passed by mac80211 on config_interface() and cached here for
-        * use in resets */
-       u8                      ah_bssid[ETH_ALEN];
-       u8                      ah_bssid_mask[ETH_ALEN];
-
-       u32                     ah_gpio[AR5K_MAX_GPIO];
-       int                     ah_gpio_npins;
-
-       struct ath_regulatory   ah_regulatory;
-       struct ath5k_capabilities ah_capabilities;
-
-       struct ath5k_txq_info   ah_txq[AR5K_NUM_TX_QUEUES];
-       u32                     ah_txq_status;
-       u32                     ah_txq_imr_txok;
-       u32                     ah_txq_imr_txerr;
-       u32                     ah_txq_imr_txurn;
-       u32                     ah_txq_imr_txdesc;
-       u32                     ah_txq_imr_txeol;
-       u32                     ah_txq_imr_cbrorn;
-       u32                     ah_txq_imr_cbrurn;
-       u32                     ah_txq_imr_qtrig;
-       u32                     ah_txq_imr_nofrm;
-       u32                     ah_txq_isr;
-       u32                     *ah_rf_banks;
-       size_t                  ah_rf_banks_size;
-       size_t                  ah_rf_regs_count;
-       struct ath5k_gain       ah_gain;
-       u8                      ah_offset[AR5K_MAX_RF_BANKS];
-
-
-       struct {
-               /* Temporary tables used for interpolation */
-               u8              tmpL[AR5K_EEPROM_N_PD_GAINS]
-                                       [AR5K_EEPROM_POWER_TABLE_SIZE];
-               u8              tmpR[AR5K_EEPROM_N_PD_GAINS]
-                                       [AR5K_EEPROM_POWER_TABLE_SIZE];
-               u8              txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2];
-               u16             txp_rates_power_table[AR5K_MAX_RATES];
-               u8              txp_min_idx;
-               bool            txp_tpc;
-               /* Values in 0.25dB units */
-               s16             txp_min_pwr;
-               s16             txp_max_pwr;
-               s16             txp_offset;
-               s16             txp_ofdm;
-               /* Values in dB units */
-               s16             txp_cck_ofdm_pwr_delta;
-               s16             txp_cck_ofdm_gainf_delta;
-       } ah_txpower;
-
-       struct {
-               bool            r_enabled;
-               int             r_last_alert;
-               struct ieee80211_channel r_last_channel;
-       } ah_radar;
-
-       /* noise floor from last periodic calibration */
-       s32                     ah_noise_floor;
-
-       /*
-        * Function pointers
-        */
-       int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc,
-                               u32 size, unsigned int flags);
-       int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-               unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
-               unsigned int, unsigned int, unsigned int, unsigned int,
-               unsigned int, unsigned int, unsigned int);
-       int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-               unsigned int, unsigned int, unsigned int, unsigned int,
-               unsigned int, unsigned int);
-       int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-               struct ath5k_tx_status *);
-       int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-               struct ath5k_rx_status *);
-};
-
-/*
- * Prototypes
- */
-
-/* Attach/Detach Functions */
-extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
-extern void ath5k_hw_detach(struct ath5k_hw *ah);
-
-/* LED functions */
-extern int ath5k_init_leds(struct ath5k_softc *sc);
-extern void ath5k_led_enable(struct ath5k_softc *sc);
-extern void ath5k_led_off(struct ath5k_softc *sc);
-extern void ath5k_unregister_leds(struct ath5k_softc *sc);
-
-/* Reset Functions */
-extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
-extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
-/* Power management functions */
-extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
-
-/* DMA Related Functions */
-extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
-extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
-extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
-extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
-extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
-extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
-extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
-extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
-                               u32 phys_addr);
-extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
-/* Interrupt handling */
-extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
-extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
-extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum
-ath5k_int new_mask);
-extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats);
-
-/* EEPROM access functions */
-extern int ath5k_eeprom_init(struct ath5k_hw *ah);
-extern void ath5k_eeprom_detach(struct ath5k_hw *ah);
-extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
-extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
-
-/* Protocol Control Unit Functions */
-extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
-/* BSSID Functions */
-extern void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac);
-extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
-extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id);
-extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
-/* Receive start/stop functions */
-extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
-extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
-/* RX Filter functions */
-extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
-extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
-extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
-extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
-extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
-/* Beacon control functions */
-extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
-extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
-extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
-extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
-extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
-#if 0
-extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state);
-extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
-extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
-#endif
-/* ACK bit rate */
-void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
-/* ACK/CTS Timeouts */
-extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
-extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
-extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
-extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
-/* Key table (WEP) functions */
-extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
-extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
-extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac);
-extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
-
-/* Queue Control Unit, DFS Control Unit Functions */
-extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info);
-extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
-                               const struct ath5k_txq_info *queue_info);
-extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
-                               enum ath5k_tx_queue queue_type,
-                               struct ath5k_txq_info *queue_info);
-extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
-extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
-extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
-extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah);
-extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
-
-/* Hardware Descriptor Functions */
-extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
-
-/* GPIO Functions */
-extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
-extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
-extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
-extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
-extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
-extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
-
-/* Misc functions */
-int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
-extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
-extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
-extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
-
-/* Initial register settings functions */
-extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
-
-/* Initialize RF */
-extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
-                               struct ieee80211_channel *channel,
-                               unsigned int mode);
-extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
-extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
-extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
-/* PHY/RF channel functions */
-extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
-extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
-/* PHY calibration */
-extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
-extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
-/* Misc PHY functions */
-extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
-extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
-extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
-extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
-/* TX power setup */
-extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
-extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower);
-
-/*
- * Functions used internaly
- */
-
-/*
- * Translate usec to hw clock units
- * TODO: Half/quarter rate
- */
-static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
-{
-       return turbo ? (usec * 80) : (usec * 40);
-}
-
-/*
- * Translate hw clock units to usec
- * TODO: Half/quarter rate
- */
-static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
-{
-       return turbo ? (clock / 80) : (clock / 40);
-}
-
-/*
- * Read from a register
- */
-static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
-{
-       return ioread32(ah->ah_iobase + reg);
-}
-
-/*
- * Write to a register
- */
-static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
-{
-       iowrite32(val, ah->ah_iobase + reg);
-}
-
-#if defined(_ATH5K_RESET) || defined(_ATH5K_PHY)
-/*
- * Check if a register write has been completed
- */
-static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag,
-               u32 val, bool is_set)
-{
-       int i;
-       u32 data;
-
-       for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
-               data = ath5k_hw_reg_read(ah, reg);
-               if (is_set && (data & flag))
-                       break;
-               else if ((data & flag) == val)
-                       break;
-               udelay(15);
-       }
-
-       return (i <= 0) ? -EAGAIN : 0;
-}
-#endif
-
-static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
-{
-       u32 retval = 0, bit, i;
-
-       for (i = 0; i < bits; i++) {
-               bit = (val >> i) & 1;
-               retval = (retval << 1) | bit;
-       }
-
-       return retval;
-}
-
-static inline int ath5k_pad_size(int hdrlen)
-{
-       return (hdrlen < 24) ? 0 : hdrlen & 3;
-}
-
-#endif
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c
deleted file mode 100644 (file)
index 70d376c..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*************************************\
-* Attach/Detach Functions and helpers *
-\*************************************/
-
-#include <linux/pci.h>
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/**
- * ath5k_hw_post - Power On Self Test helper function
- *
- * @ah: The &struct ath5k_hw
- */
-static int ath5k_hw_post(struct ath5k_hw *ah)
-{
-
-       static const u32 static_pattern[4] = {
-               0x55555555,     0xaaaaaaaa,
-               0x66666666,     0x99999999
-       };
-       static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
-       int i, c;
-       u16 cur_reg;
-       u32 var_pattern;
-       u32 init_val;
-       u32 cur_val;
-
-       for (c = 0; c < 2; c++) {
-
-               cur_reg = regs[c];
-
-               /* Save previous value */
-               init_val = ath5k_hw_reg_read(ah, cur_reg);
-
-               for (i = 0; i < 256; i++) {
-                       var_pattern = i << 16 | i;
-                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-                       cur_val = ath5k_hw_reg_read(ah, cur_reg);
-
-                       if (cur_val != var_pattern) {
-                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
-                               return -EAGAIN;
-                       }
-
-                       /* Found on ndiswrapper dumps */
-                       var_pattern = 0x0039080f;
-                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-               }
-
-               for (i = 0; i < 4; i++) {
-                       var_pattern = static_pattern[i];
-                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-                       cur_val = ath5k_hw_reg_read(ah, cur_reg);
-
-                       if (cur_val != var_pattern) {
-                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
-                               return -EAGAIN;
-                       }
-
-                       /* Found on ndiswrapper dumps */
-                       var_pattern = 0x003b080f;
-                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-               }
-
-               /* Restore previous value */
-               ath5k_hw_reg_write(ah, init_val, cur_reg);
-
-       }
-
-       return 0;
-
-}
-
-/**
- * ath5k_hw_attach - Check if hw is supported and init the needed structs
- *
- * @sc: The &struct ath5k_softc we got from the driver's attach function
- * @mac_version: The mac version id (check out ath5k.h) based on pci id
- *
- * Check if the device is supported, perform a POST and initialize the needed
- * structs. Returns -ENOMEM if we don't have memory for the needed structs,
- * -ENODEV if the device is not supported or prints an error msg if something
- * else went wrong.
- */
-struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
-{
-       struct ath5k_hw *ah;
-       struct pci_dev *pdev = sc->pdev;
-       int ret;
-       u32 srev;
-
-       /*If we passed the test malloc a ath5k_hw struct*/
-       ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
-       if (ah == NULL) {
-               ret = -ENOMEM;
-               ATH5K_ERR(sc, "out of memory\n");
-               goto err;
-       }
-
-       ah->ah_sc = sc;
-       ah->ah_iobase = sc->iobase;
-
-       /*
-        * HW information
-        */
-       ah->ah_op_mode = NL80211_IFTYPE_STATION;
-       ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
-       ah->ah_turbo = false;
-       ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
-       ah->ah_imr = 0;
-       ah->ah_atim_window = 0;
-       ah->ah_aifs = AR5K_TUNE_AIFS;
-       ah->ah_cw_min = AR5K_TUNE_CWMIN;
-       ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
-       ah->ah_software_retry = false;
-       ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
-
-       /*
-        * Set the mac version based on the pci id
-        */
-       ah->ah_version = mac_version;
-
-       /*Fill the ath5k_hw struct with the needed functions*/
-       ret = ath5k_hw_init_desc_functions(ah);
-       if (ret)
-               goto err_free;
-
-       /* Bring device out of sleep and reset it's units */
-       ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
-       if (ret)
-               goto err_free;
-
-       /* Get MAC, PHY and RADIO revisions */
-       srev = ath5k_hw_reg_read(ah, AR5K_SREV);
-       ah->ah_mac_srev = srev;
-       ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
-       ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
-       ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
-                       0xffffffff;
-       ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
-                       CHANNEL_5GHZ);
-       ah->ah_phy = AR5K_PHY(0);
-
-       /* Try to identify radio chip based on it's srev */
-       switch (ah->ah_radio_5ghz_revision & 0xf0) {
-       case AR5K_SREV_RAD_5111:
-               ah->ah_radio = AR5K_RF5111;
-               ah->ah_single_chip = false;
-               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
-                                                       CHANNEL_2GHZ);
-               break;
-       case AR5K_SREV_RAD_5112:
-       case AR5K_SREV_RAD_2112:
-               ah->ah_radio = AR5K_RF5112;
-               ah->ah_single_chip = false;
-               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
-                                                       CHANNEL_2GHZ);
-               break;
-       case AR5K_SREV_RAD_2413:
-               ah->ah_radio = AR5K_RF2413;
-               ah->ah_single_chip = true;
-               break;
-       case AR5K_SREV_RAD_5413:
-               ah->ah_radio = AR5K_RF5413;
-               ah->ah_single_chip = true;
-               break;
-       case AR5K_SREV_RAD_2316:
-               ah->ah_radio = AR5K_RF2316;
-               ah->ah_single_chip = true;
-               break;
-       case AR5K_SREV_RAD_2317:
-               ah->ah_radio = AR5K_RF2317;
-               ah->ah_single_chip = true;
-               break;
-       case AR5K_SREV_RAD_5424:
-               if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
-               ah->ah_mac_version == AR5K_SREV_AR2417){
-                       ah->ah_radio = AR5K_RF2425;
-                       ah->ah_single_chip = true;
-               } else {
-                       ah->ah_radio = AR5K_RF5413;
-                       ah->ah_single_chip = true;
-               }
-               break;
-       default:
-               /* Identify radio based on mac/phy srev */
-               if (ah->ah_version == AR5K_AR5210) {
-                       ah->ah_radio = AR5K_RF5110;
-                       ah->ah_single_chip = false;
-               } else if (ah->ah_version == AR5K_AR5211) {
-                       ah->ah_radio = AR5K_RF5111;
-                       ah->ah_single_chip = false;
-                       ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
-                                                               CHANNEL_2GHZ);
-               } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
-               ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
-               ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
-                       ah->ah_radio = AR5K_RF2425;
-                       ah->ah_single_chip = true;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
-               } else if (srev == AR5K_SREV_AR5213A &&
-               ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
-                       ah->ah_radio = AR5K_RF5112;
-                       ah->ah_single_chip = false;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
-               } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
-                       ah->ah_radio = AR5K_RF2316;
-                       ah->ah_single_chip = true;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
-               } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
-               ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
-                       ah->ah_radio = AR5K_RF5413;
-                       ah->ah_single_chip = true;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
-               } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
-               ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
-                       ah->ah_radio = AR5K_RF2413;
-                       ah->ah_single_chip = true;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
-               } else {
-                       ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
-                       ret = -ENODEV;
-                       goto err_free;
-               }
-       }
-
-
-       /* Return on unsuported chips (unsupported eeprom etc) */
-       if ((srev >= AR5K_SREV_AR5416) &&
-       (srev < AR5K_SREV_AR2425)) {
-               ATH5K_ERR(sc, "Device not yet supported.\n");
-               ret = -ENODEV;
-               goto err_free;
-       }
-
-       /*
-        * Write PCI-E power save settings
-        */
-       if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
-               ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
-               ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
-               /* Shut off RX when elecidle is asserted */
-               ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
-               ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
-               /* TODO: EEPROM work */
-               ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
-               /* Shut off PLL and CLKREQ active in L1 */
-               ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
-               /* Preserce other settings */
-               ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
-               ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
-               ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
-               /* Reset SERDES to load new settings */
-               ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
-               mdelay(1);
-       }
-
-       /*
-        * POST
-        */
-       ret = ath5k_hw_post(ah);
-       if (ret)
-               goto err_free;
-
-       /* Enable pci core retry fix on Hainan (5213A) and later chips */
-       if (srev >= AR5K_SREV_AR5213A)
-               ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG);
-
-       /*
-        * Get card capabilities, calibration values etc
-        * TODO: EEPROM work
-        */
-       ret = ath5k_eeprom_init(ah);
-       if (ret) {
-               ATH5K_ERR(sc, "unable to init EEPROM\n");
-               goto err_free;
-       }
-
-       /* Get misc capabilities */
-       ret = ath5k_hw_set_capabilities(ah);
-       if (ret) {
-               ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
-                       sc->pdev->device);
-               goto err_free;
-       }
-
-       if (srev >= AR5K_SREV_AR2414) {
-               ah->ah_combined_mic = true;
-               AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
-                       AR5K_MISC_MODE_COMBINED_MIC);
-       }
-
-       /* MAC address is cleared until add_interface */
-       ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
-
-       /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
-       memset(ah->ah_bssid, 0xff, ETH_ALEN);
-       ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
-       ath5k_hw_set_opmode(ah);
-
-       ath5k_hw_rfgain_opt_init(ah);
-
-       return ah;
-err_free:
-       kfree(ah);
-err:
-       return ERR_PTR(ret);
-}
-
-/**
- * ath5k_hw_detach - Free the ath5k_hw struct
- *
- * @ah: The &struct ath5k_hw
- */
-void ath5k_hw_detach(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
-
-       if (ah->ah_rf_banks != NULL)
-               kfree(ah->ah_rf_banks);
-
-       ath5k_eeprom_detach(ah);
-
-       /* assume interrupts are down */
-       kfree(ah);
-}
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
deleted file mode 100644 (file)
index ff6d4f8..0000000
+++ /dev/null
@@ -1,3110 +0,0 @@
-/*-
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * Copyright (c) 2004-2005 Atheros Communications, Inc.
- * Copyright (c) 2006 Devicescape Software, Inc.
- * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- *
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/hardirq.h>
-#include <linux/if.h>
-#include <linux/io.h>
-#include <linux/netdevice.h>
-#include <linux/cache.h>
-#include <linux/pci.h>
-#include <linux/ethtool.h>
-#include <linux/uaccess.h>
-
-#include <net/ieee80211_radiotap.h>
-
-#include <asm/unaligned.h>
-
-#include "base.h"
-#include "reg.h"
-#include "debug.h"
-
-static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-
-static int modparam_all_channels;
-module_param_named(all_channels, modparam_all_channels, int, 0444);
-MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
-
-
-/******************\
-* Internal defines *
-\******************/
-
-/* Module info */
-MODULE_AUTHOR("Jiri Slaby");
-MODULE_AUTHOR("Nick Kossifidis");
-MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
-MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
-
-
-/* Known PCI ids */
-static const struct pci_device_id ath5k_pci_id_table[] = {
-       { PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
-       { PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
-       { PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
-       { PCI_VDEVICE(ATHEROS, 0x0012), .driver_data = AR5K_AR5211 }, /* 5211 */
-       { PCI_VDEVICE(ATHEROS, 0x0013), .driver_data = AR5K_AR5212 }, /* 5212 */
-       { PCI_VDEVICE(3COM_2,  0x0013), .driver_data = AR5K_AR5212 }, /* 3com 5212 */
-       { PCI_VDEVICE(3COM,    0x0013), .driver_data = AR5K_AR5212 }, /* 3com 3CRDAG675 5212 */
-       { PCI_VDEVICE(ATHEROS, 0x1014), .driver_data = AR5K_AR5212 }, /* IBM minipci 5212 */
-       { PCI_VDEVICE(ATHEROS, 0x0014), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0015), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0016), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0017), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0018), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */
-       { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */
-       { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */
-       { PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */
-       { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
-
-/* Known SREVs */
-static const struct ath5k_srev_name srev_names[] = {
-       { "5210",       AR5K_VERSION_MAC,       AR5K_SREV_AR5210 },
-       { "5311",       AR5K_VERSION_MAC,       AR5K_SREV_AR5311 },
-       { "5311A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311A },
-       { "5311B",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311B },
-       { "5211",       AR5K_VERSION_MAC,       AR5K_SREV_AR5211 },
-       { "5212",       AR5K_VERSION_MAC,       AR5K_SREV_AR5212 },
-       { "5213",       AR5K_VERSION_MAC,       AR5K_SREV_AR5213 },
-       { "5213A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5213A },
-       { "2413",       AR5K_VERSION_MAC,       AR5K_SREV_AR2413 },
-       { "2414",       AR5K_VERSION_MAC,       AR5K_SREV_AR2414 },
-       { "5424",       AR5K_VERSION_MAC,       AR5K_SREV_AR5424 },
-       { "5413",       AR5K_VERSION_MAC,       AR5K_SREV_AR5413 },
-       { "5414",       AR5K_VERSION_MAC,       AR5K_SREV_AR5414 },
-       { "2415",       AR5K_VERSION_MAC,       AR5K_SREV_AR2415 },
-       { "5416",       AR5K_VERSION_MAC,       AR5K_SREV_AR5416 },
-       { "5418",       AR5K_VERSION_MAC,       AR5K_SREV_AR5418 },
-       { "2425",       AR5K_VERSION_MAC,       AR5K_SREV_AR2425 },
-       { "2417",       AR5K_VERSION_MAC,       AR5K_SREV_AR2417 },
-       { "xxxxx",      AR5K_VERSION_MAC,       AR5K_SREV_UNKNOWN },
-       { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
-       { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
-       { "5111A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111A },
-       { "2111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2111 },
-       { "5112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112 },
-       { "5112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112A },
-       { "5112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112B },
-       { "2112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112 },
-       { "2112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112A },
-       { "2112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112B },
-       { "2413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2413 },
-       { "5413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5413 },
-       { "2316",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2316 },
-       { "2317",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2317 },
-       { "5424",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5424 },
-       { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
-       { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
-};
-
-static const struct ieee80211_rate ath5k_rates[] = {
-       { .bitrate = 10,
-         .hw_value = ATH5K_RATE_CODE_1M, },
-       { .bitrate = 20,
-         .hw_value = ATH5K_RATE_CODE_2M,
-         .hw_value_short = ATH5K_RATE_CODE_2M | AR5K_SET_SHORT_PREAMBLE,
-         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 55,
-         .hw_value = ATH5K_RATE_CODE_5_5M,
-         .hw_value_short = ATH5K_RATE_CODE_5_5M | AR5K_SET_SHORT_PREAMBLE,
-         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 110,
-         .hw_value = ATH5K_RATE_CODE_11M,
-         .hw_value_short = ATH5K_RATE_CODE_11M | AR5K_SET_SHORT_PREAMBLE,
-         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 60,
-         .hw_value = ATH5K_RATE_CODE_6M,
-         .flags = 0 },
-       { .bitrate = 90,
-         .hw_value = ATH5K_RATE_CODE_9M,
-         .flags = 0 },
-       { .bitrate = 120,
-         .hw_value = ATH5K_RATE_CODE_12M,
-         .flags = 0 },
-       { .bitrate = 180,
-         .hw_value = ATH5K_RATE_CODE_18M,
-         .flags = 0 },
-       { .bitrate = 240,
-         .hw_value = ATH5K_RATE_CODE_24M,
-         .flags = 0 },
-       { .bitrate = 360,
-         .hw_value = ATH5K_RATE_CODE_36M,
-         .flags = 0 },
-       { .bitrate = 480,
-         .hw_value = ATH5K_RATE_CODE_48M,
-         .flags = 0 },
-       { .bitrate = 540,
-         .hw_value = ATH5K_RATE_CODE_54M,
-         .flags = 0 },
-       /* XR missing */
-};
-
-/*
- * Prototypes - PCI stack related functions
- */
-static int __devinit   ath5k_pci_probe(struct pci_dev *pdev,
-                               const struct pci_device_id *id);
-static void __devexit  ath5k_pci_remove(struct pci_dev *pdev);
-#ifdef CONFIG_PM
-static int             ath5k_pci_suspend(struct pci_dev *pdev,
-                                       pm_message_t state);
-static int             ath5k_pci_resume(struct pci_dev *pdev);
-#else
-#define ath5k_pci_suspend NULL
-#define ath5k_pci_resume NULL
-#endif /* CONFIG_PM */
-
-static struct pci_driver ath5k_pci_driver = {
-       .name           = KBUILD_MODNAME,
-       .id_table       = ath5k_pci_id_table,
-       .probe          = ath5k_pci_probe,
-       .remove         = __devexit_p(ath5k_pci_remove),
-       .suspend        = ath5k_pci_suspend,
-       .resume         = ath5k_pci_resume,
-};
-
-
-
-/*
- * Prototypes - MAC 802.11 stack related functions
- */
-static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel);
-static int ath5k_reset_wake(struct ath5k_softc *sc);
-static int ath5k_start(struct ieee80211_hw *hw);
-static void ath5k_stop(struct ieee80211_hw *hw);
-static int ath5k_add_interface(struct ieee80211_hw *hw,
-               struct ieee80211_if_init_conf *conf);
-static void ath5k_remove_interface(struct ieee80211_hw *hw,
-               struct ieee80211_if_init_conf *conf);
-static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
-static int ath5k_config_interface(struct ieee80211_hw *hw,
-               struct ieee80211_vif *vif,
-               struct ieee80211_if_conf *conf);
-static void ath5k_configure_filter(struct ieee80211_hw *hw,
-               unsigned int changed_flags,
-               unsigned int *new_flags,
-               int mc_count, struct dev_mc_list *mclist);
-static int ath5k_set_key(struct ieee80211_hw *hw,
-               enum set_key_cmd cmd,
-               struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-               struct ieee80211_key_conf *key);
-static int ath5k_get_stats(struct ieee80211_hw *hw,
-               struct ieee80211_low_level_stats *stats);
-static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
-               struct ieee80211_tx_queue_stats *stats);
-static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
-static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
-static void ath5k_reset_tsf(struct ieee80211_hw *hw);
-static int ath5k_beacon_update(struct ath5k_softc *sc,
-               struct sk_buff *skb);
-static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
-               struct ieee80211_vif *vif,
-               struct ieee80211_bss_conf *bss_conf,
-               u32 changes);
-
-static const struct ieee80211_ops ath5k_hw_ops = {
-       .tx             = ath5k_tx,
-       .start          = ath5k_start,
-       .stop           = ath5k_stop,
-       .add_interface  = ath5k_add_interface,
-       .remove_interface = ath5k_remove_interface,
-       .config         = ath5k_config,
-       .config_interface = ath5k_config_interface,
-       .configure_filter = ath5k_configure_filter,
-       .set_key        = ath5k_set_key,
-       .get_stats      = ath5k_get_stats,
-       .conf_tx        = NULL,
-       .get_tx_stats   = ath5k_get_tx_stats,
-       .get_tsf        = ath5k_get_tsf,
-       .set_tsf        = ath5k_set_tsf,
-       .reset_tsf      = ath5k_reset_tsf,
-       .bss_info_changed = ath5k_bss_info_changed,
-};
-
-/*
- * Prototypes - Internal functions
- */
-/* Attach detach */
-static int     ath5k_attach(struct pci_dev *pdev,
-                       struct ieee80211_hw *hw);
-static void    ath5k_detach(struct pci_dev *pdev,
-                       struct ieee80211_hw *hw);
-/* Channel/mode setup */
-static inline short ath5k_ieee2mhz(short chan);
-static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
-                               struct ieee80211_channel *channels,
-                               unsigned int mode,
-                               unsigned int max);
-static int     ath5k_setup_bands(struct ieee80211_hw *hw);
-static int     ath5k_chan_set(struct ath5k_softc *sc,
-                               struct ieee80211_channel *chan);
-static void    ath5k_setcurmode(struct ath5k_softc *sc,
-                               unsigned int mode);
-static void    ath5k_mode_setup(struct ath5k_softc *sc);
-
-/* Descriptor setup */
-static int     ath5k_desc_alloc(struct ath5k_softc *sc,
-                               struct pci_dev *pdev);
-static void    ath5k_desc_free(struct ath5k_softc *sc,
-                               struct pci_dev *pdev);
-/* Buffers setup */
-static int     ath5k_rxbuf_setup(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf);
-static int     ath5k_txbuf_setup(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf);
-static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf)
-{
-       BUG_ON(!bf);
-       if (!bf->skb)
-               return;
-       pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
-                       PCI_DMA_TODEVICE);
-       dev_kfree_skb_any(bf->skb);
-       bf->skb = NULL;
-}
-
-static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf)
-{
-       BUG_ON(!bf);
-       if (!bf->skb)
-               return;
-       pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
-                       PCI_DMA_FROMDEVICE);
-       dev_kfree_skb_any(bf->skb);
-       bf->skb = NULL;
-}
-
-
-/* Queues setup */
-static struct  ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
-                               int qtype, int subtype);
-static int     ath5k_beaconq_setup(struct ath5k_hw *ah);
-static int     ath5k_beaconq_config(struct ath5k_softc *sc);
-static void    ath5k_txq_drainq(struct ath5k_softc *sc,
-                               struct ath5k_txq *txq);
-static void    ath5k_txq_cleanup(struct ath5k_softc *sc);
-static void    ath5k_txq_release(struct ath5k_softc *sc);
-/* Rx handling */
-static int     ath5k_rx_start(struct ath5k_softc *sc);
-static void    ath5k_rx_stop(struct ath5k_softc *sc);
-static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
-                                       struct ath5k_desc *ds,
-                                       struct sk_buff *skb,
-                                       struct ath5k_rx_status *rs);
-static void    ath5k_tasklet_rx(unsigned long data);
-/* Tx handling */
-static void    ath5k_tx_processq(struct ath5k_softc *sc,
-                               struct ath5k_txq *txq);
-static void    ath5k_tasklet_tx(unsigned long data);
-/* Beacon handling */
-static int     ath5k_beacon_setup(struct ath5k_softc *sc,
-                                       struct ath5k_buf *bf);
-static void    ath5k_beacon_send(struct ath5k_softc *sc);
-static void    ath5k_beacon_config(struct ath5k_softc *sc);
-static void    ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
-static void    ath5k_tasklet_beacon(unsigned long data);
-
-static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
-{
-       u64 tsf = ath5k_hw_get_tsf64(ah);
-
-       if ((tsf & 0x7fff) < rstamp)
-               tsf -= 0x8000;
-
-       return (tsf & ~0x7fff) | rstamp;
-}
-
-/* Interrupt handling */
-static int     ath5k_init(struct ath5k_softc *sc);
-static int     ath5k_stop_locked(struct ath5k_softc *sc);
-static int     ath5k_stop_hw(struct ath5k_softc *sc);
-static irqreturn_t ath5k_intr(int irq, void *dev_id);
-static void    ath5k_tasklet_reset(unsigned long data);
-
-static void    ath5k_calibrate(unsigned long data);
-
-/*
- * Module init/exit functions
- */
-static int __init
-init_ath5k_pci(void)
-{
-       int ret;
-
-       ath5k_debug_init();
-
-       ret = pci_register_driver(&ath5k_pci_driver);
-       if (ret) {
-               printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-static void __exit
-exit_ath5k_pci(void)
-{
-       pci_unregister_driver(&ath5k_pci_driver);
-
-       ath5k_debug_finish();
-}
-
-module_init(init_ath5k_pci);
-module_exit(exit_ath5k_pci);
-
-
-/********************\
-* PCI Initialization *
-\********************/
-
-static const char *
-ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
-{
-       const char *name = "xxxxx";
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(srev_names); i++) {
-               if (srev_names[i].sr_type != type)
-                       continue;
-
-               if ((val & 0xf0) == srev_names[i].sr_val)
-                       name = srev_names[i].sr_name;
-
-               if ((val & 0xff) == srev_names[i].sr_val) {
-                       name = srev_names[i].sr_name;
-                       break;
-               }
-       }
-
-       return name;
-}
-
-static int __devinit
-ath5k_pci_probe(struct pci_dev *pdev,
-               const struct pci_device_id *id)
-{
-       void __iomem *mem;
-       struct ath5k_softc *sc;
-       struct ieee80211_hw *hw;
-       int ret;
-       u8 csz;
-
-       ret = pci_enable_device(pdev);
-       if (ret) {
-               dev_err(&pdev->dev, "can't enable device\n");
-               goto err;
-       }
-
-       /* XXX 32-bit addressing only */
-       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-       if (ret) {
-               dev_err(&pdev->dev, "32-bit DMA not available\n");
-               goto err_dis;
-       }
-
-       /*
-        * Cache line size is used to size and align various
-        * structures used to communicate with the hardware.
-        */
-       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
-       if (csz == 0) {
-               /*
-                * Linux 2.4.18 (at least) writes the cache line size
-                * register as a 16-bit wide register which is wrong.
-                * We must have this setup properly for rx buffer
-                * DMA to work so force a reasonable value here if it
-                * comes up zero.
-                */
-               csz = L1_CACHE_BYTES / sizeof(u32);
-               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
-       }
-       /*
-        * The default setting of latency timer yields poor results,
-        * set it to the value used by other systems.  It may be worth
-        * tweaking this setting more.
-        */
-       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
-       /* Enable bus mastering */
-       pci_set_master(pdev);
-
-       /*
-        * Disable the RETRY_TIMEOUT register (0x41) to keep
-        * PCI Tx retries from interfering with C3 CPU state.
-        */
-       pci_write_config_byte(pdev, 0x41, 0);
-
-       ret = pci_request_region(pdev, 0, "ath5k");
-       if (ret) {
-               dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
-               goto err_dis;
-       }
-
-       mem = pci_iomap(pdev, 0, 0);
-       if (!mem) {
-               dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
-               ret = -EIO;
-               goto err_reg;
-       }
-
-       /*
-        * Allocate hw (mac80211 main struct)
-        * and hw->priv (driver private data)
-        */
-       hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
-       if (hw == NULL) {
-               dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
-               ret = -ENOMEM;
-               goto err_map;
-       }
-
-       dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
-
-       /* Initialize driver private data */
-       SET_IEEE80211_DEV(hw, &pdev->dev);
-       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-                   IEEE80211_HW_SIGNAL_DBM |
-                   IEEE80211_HW_NOISE_DBM;
-
-       hw->wiphy->interface_modes =
-               BIT(NL80211_IFTYPE_STATION) |
-               BIT(NL80211_IFTYPE_ADHOC) |
-               BIT(NL80211_IFTYPE_MESH_POINT);
-
-       hw->extra_tx_headroom = 2;
-       hw->channel_change_time = 5000;
-       sc = hw->priv;
-       sc->hw = hw;
-       sc->pdev = pdev;
-
-       ath5k_debug_init_device(sc);
-
-       /*
-        * Mark the device as detached to avoid processing
-        * interrupts until setup is complete.
-        */
-       __set_bit(ATH_STAT_INVALID, sc->status);
-
-       sc->iobase = mem; /* So we can unmap it on detach */
-       sc->cachelsz = csz * sizeof(u32); /* convert to bytes */
-       sc->opmode = NL80211_IFTYPE_STATION;
-       mutex_init(&sc->lock);
-       spin_lock_init(&sc->rxbuflock);
-       spin_lock_init(&sc->txbuflock);
-       spin_lock_init(&sc->block);
-
-       /* Set private data */
-       pci_set_drvdata(pdev, hw);
-
-       /* Setup interrupt handler */
-       ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
-       if (ret) {
-               ATH5K_ERR(sc, "request_irq failed\n");
-               goto err_free;
-       }
-
-       /* Initialize device */
-       sc->ah = ath5k_hw_attach(sc, id->driver_data);
-       if (IS_ERR(sc->ah)) {
-               ret = PTR_ERR(sc->ah);
-               goto err_irq;
-       }
-
-       /* set up multi-rate retry capabilities */
-       if (sc->ah->ah_version == AR5K_AR5212) {
-               hw->max_rates = 4;
-               hw->max_rate_tries = 11;
-       }
-
-       /* Finish private driver data initialization */
-       ret = ath5k_attach(pdev, hw);
-       if (ret)
-               goto err_ah;
-
-       ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
-                       ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
-                                       sc->ah->ah_mac_srev,
-                                       sc->ah->ah_phy_revision);
-
-       if (!sc->ah->ah_single_chip) {
-               /* Single chip radio (!RF5111) */
-               if (sc->ah->ah_radio_5ghz_revision &&
-                       !sc->ah->ah_radio_2ghz_revision) {
-                       /* No 5GHz support -> report 2GHz radio */
-                       if (!test_bit(AR5K_MODE_11A,
-                               sc->ah->ah_capabilities.cap_mode)) {
-                               ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
-                                       ath5k_chip_name(AR5K_VERSION_RAD,
-                                               sc->ah->ah_radio_5ghz_revision),
-                                               sc->ah->ah_radio_5ghz_revision);
-                       /* No 2GHz support (5110 and some
-                        * 5Ghz only cards) -> report 5Ghz radio */
-                       } else if (!test_bit(AR5K_MODE_11B,
-                               sc->ah->ah_capabilities.cap_mode)) {
-                               ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
-                                       ath5k_chip_name(AR5K_VERSION_RAD,
-                                               sc->ah->ah_radio_5ghz_revision),
-                                               sc->ah->ah_radio_5ghz_revision);
-                       /* Multiband radio */
-                       } else {
-                               ATH5K_INFO(sc, "RF%s multiband radio found"
-                                       " (0x%x)\n",
-                                       ath5k_chip_name(AR5K_VERSION_RAD,
-                                               sc->ah->ah_radio_5ghz_revision),
-                                               sc->ah->ah_radio_5ghz_revision);
-                       }
-               }
-               /* Multi chip radio (RF5111 - RF2111) ->
-                * report both 2GHz/5GHz radios */
-               else if (sc->ah->ah_radio_5ghz_revision &&
-                               sc->ah->ah_radio_2ghz_revision){
-                       ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
-                               ath5k_chip_name(AR5K_VERSION_RAD,
-                                       sc->ah->ah_radio_5ghz_revision),
-                                       sc->ah->ah_radio_5ghz_revision);
-                       ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
-                               ath5k_chip_name(AR5K_VERSION_RAD,
-                                       sc->ah->ah_radio_2ghz_revision),
-                                       sc->ah->ah_radio_2ghz_revision);
-               }
-       }
-
-
-       /* ready to process interrupts */
-       __clear_bit(ATH_STAT_INVALID, sc->status);
-
-       return 0;
-err_ah:
-       ath5k_hw_detach(sc->ah);
-err_irq:
-       free_irq(pdev->irq, sc);
-err_free:
-       ieee80211_free_hw(hw);
-err_map:
-       pci_iounmap(pdev, mem);
-err_reg:
-       pci_release_region(pdev, 0);
-err_dis:
-       pci_disable_device(pdev);
-err:
-       return ret;
-}
-
-static void __devexit
-ath5k_pci_remove(struct pci_dev *pdev)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath5k_softc *sc = hw->priv;
-
-       ath5k_debug_finish_device(sc);
-       ath5k_detach(pdev, hw);
-       ath5k_hw_detach(sc->ah);
-       free_irq(pdev->irq, sc);
-       pci_iounmap(pdev, sc->iobase);
-       pci_release_region(pdev, 0);
-       pci_disable_device(pdev);
-       ieee80211_free_hw(hw);
-}
-
-#ifdef CONFIG_PM
-static int
-ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath5k_softc *sc = hw->priv;
-
-       ath5k_led_off(sc);
-
-       free_irq(pdev->irq, sc);
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       return 0;
-}
-
-static int
-ath5k_pci_resume(struct pci_dev *pdev)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath5k_softc *sc = hw->priv;
-       int err;
-
-       pci_restore_state(pdev);
-
-       err = pci_enable_device(pdev);
-       if (err)
-               return err;
-
-       err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
-       if (err) {
-               ATH5K_ERR(sc, "request_irq failed\n");
-               goto err_no_irq;
-       }
-
-       ath5k_led_enable(sc);
-       return 0;
-
-err_no_irq:
-       pci_disable_device(pdev);
-       return err;
-}
-#endif /* CONFIG_PM */
-
-
-/***********************\
-* Driver Initialization *
-\***********************/
-
-static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
-{
-       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-       struct ath5k_softc *sc = hw->priv;
-       struct ath_regulatory *reg = &sc->ah->ah_regulatory;
-
-       return ath_reg_notifier_apply(wiphy, request, reg);
-}
-
-static int
-ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       u8 mac[ETH_ALEN] = {};
-       int ret;
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
-
-       /*
-        * Check if the MAC has multi-rate retry support.
-        * We do this by trying to setup a fake extended
-        * descriptor.  MAC's that don't have support will
-        * return false w/o doing anything.  MAC's that do
-        * support it will return true w/o doing anything.
-        */
-       ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
-       if (ret < 0)
-               goto err;
-       if (ret > 0)
-               __set_bit(ATH_STAT_MRRETRY, sc->status);
-
-       /*
-        * Collect the channel list.  The 802.11 layer
-        * is resposible for filtering this list based
-        * on settings like the phy mode and regulatory
-        * domain restrictions.
-        */
-       ret = ath5k_setup_bands(hw);
-       if (ret) {
-               ATH5K_ERR(sc, "can't get channels\n");
-               goto err;
-       }
-
-       /* NB: setup here so ath5k_rate_update is happy */
-       if (test_bit(AR5K_MODE_11A, ah->ah_modes))
-               ath5k_setcurmode(sc, AR5K_MODE_11A);
-       else
-               ath5k_setcurmode(sc, AR5K_MODE_11B);
-
-       /*
-        * Allocate tx+rx descriptors and populate the lists.
-        */
-       ret = ath5k_desc_alloc(sc, pdev);
-       if (ret) {
-               ATH5K_ERR(sc, "can't allocate descriptors\n");
-               goto err;
-       }
-
-       /*
-        * Allocate hardware transmit queues: one queue for
-        * beacon frames and one data queue for each QoS
-        * priority.  Note that hw functions handle reseting
-        * these queues at the needed time.
-        */
-       ret = ath5k_beaconq_setup(ah);
-       if (ret < 0) {
-               ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
-               goto err_desc;
-       }
-       sc->bhalq = ret;
-
-       sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
-       if (IS_ERR(sc->txq)) {
-               ATH5K_ERR(sc, "can't setup xmit queue\n");
-               ret = PTR_ERR(sc->txq);
-               goto err_bhal;
-       }
-
-       tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
-       tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
-       tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
-       tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
-       setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
-
-       ret = ath5k_eeprom_read_mac(ah, mac);
-       if (ret) {
-               ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
-                       sc->pdev->device);
-               goto err_queues;
-       }
-
-       SET_IEEE80211_PERM_ADDR(hw, mac);
-       /* All MAC address bits matter for ACKs */
-       memset(sc->bssidmask, 0xff, ETH_ALEN);
-       ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
-
-       ah->ah_regulatory.current_rd =
-               ah->ah_capabilities.cap_eeprom.ee_regdomain;
-       ret = ath_regd_init(&ah->ah_regulatory, hw->wiphy, ath5k_reg_notifier);
-       if (ret) {
-               ATH5K_ERR(sc, "can't initialize regulatory system\n");
-               goto err_queues;
-       }
-
-       ret = ieee80211_register_hw(hw);
-       if (ret) {
-               ATH5K_ERR(sc, "can't register ieee80211 hw\n");
-               goto err_queues;
-       }
-
-       if (!ath_is_world_regd(&sc->ah->ah_regulatory))
-               regulatory_hint(hw->wiphy, sc->ah->ah_regulatory.alpha2);
-
-       ath5k_init_leds(sc);
-
-       return 0;
-err_queues:
-       ath5k_txq_release(sc);
-err_bhal:
-       ath5k_hw_release_tx_queue(ah, sc->bhalq);
-err_desc:
-       ath5k_desc_free(sc, pdev);
-err:
-       return ret;
-}
-
-static void
-ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       /*
-        * NB: the order of these is important:
-        * o call the 802.11 layer before detaching ath5k_hw 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
-        * XXX: ??? detach ath5k_hw ???
-        * Other than that, it's straightforward...
-        */
-       ieee80211_unregister_hw(hw);
-       ath5k_desc_free(sc, pdev);
-       ath5k_txq_release(sc);
-       ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
-       ath5k_unregister_leds(sc);
-
-       /*
-        * NB: can't reclaim these until after ieee80211_ifdetach
-        * returns because we'll get called back to reclaim node
-        * state and potentially want to use them.
-        */
-}
-
-
-
-
-/********************\
-* Channel/mode setup *
-\********************/
-
-/*
- * Convert IEEE channel number to MHz frequency.
- */
-static inline short
-ath5k_ieee2mhz(short chan)
-{
-       if (chan <= 14 || chan >= 27)
-               return ieee80211chan2mhz(chan);
-       else
-               return 2212 + chan * 20;
-}
-
-/*
- * Returns true for the channel numbers used without all_channels modparam.
- */
-static bool ath5k_is_standard_channel(short chan)
-{
-       return ((chan <= 14) ||
-               /* UNII 1,2 */
-               ((chan & 3) == 0 && chan >= 36 && chan <= 64) ||
-               /* midband */
-               ((chan & 3) == 0 && chan >= 100 && chan <= 140) ||
-               /* UNII-3 */
-               ((chan & 3) == 1 && chan >= 149 && chan <= 165));
-}
-
-static unsigned int
-ath5k_copy_channels(struct ath5k_hw *ah,
-               struct ieee80211_channel *channels,
-               unsigned int mode,
-               unsigned int max)
-{
-       unsigned int i, count, size, chfreq, freq, ch;
-
-       if (!test_bit(mode, ah->ah_modes))
-               return 0;
-
-       switch (mode) {
-       case AR5K_MODE_11A:
-       case AR5K_MODE_11A_TURBO:
-               /* 1..220, but 2GHz frequencies are filtered by check_channel */
-               size = 220 ;
-               chfreq = CHANNEL_5GHZ;
-               break;
-       case AR5K_MODE_11B:
-       case AR5K_MODE_11G:
-       case AR5K_MODE_11G_TURBO:
-               size = 26;
-               chfreq = CHANNEL_2GHZ;
-               break;
-       default:
-               ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n");
-               return 0;
-       }
-
-       for (i = 0, count = 0; i < size && max > 0; i++) {
-               ch = i + 1 ;
-               freq = ath5k_ieee2mhz(ch);
-
-               /* Check if channel is supported by the chipset */
-               if (!ath5k_channel_ok(ah, freq, chfreq))
-                       continue;
-
-               if (!modparam_all_channels && !ath5k_is_standard_channel(ch))
-                       continue;
-
-               /* Write channel info and increment counter */
-               channels[count].center_freq = freq;
-               channels[count].band = (chfreq == CHANNEL_2GHZ) ?
-                       IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
-               switch (mode) {
-               case AR5K_MODE_11A:
-               case AR5K_MODE_11G:
-                       channels[count].hw_value = chfreq | CHANNEL_OFDM;
-                       break;
-               case AR5K_MODE_11A_TURBO:
-               case AR5K_MODE_11G_TURBO:
-                       channels[count].hw_value = chfreq |
-                               CHANNEL_OFDM | CHANNEL_TURBO;
-                       break;
-               case AR5K_MODE_11B:
-                       channels[count].hw_value = CHANNEL_B;
-               }
-
-               count++;
-               max--;
-       }
-
-       return count;
-}
-
-static void
-ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b)
-{
-       u8 i;
-
-       for (i = 0; i < AR5K_MAX_RATES; i++)
-               sc->rate_idx[b->band][i] = -1;
-
-       for (i = 0; i < b->n_bitrates; i++) {
-               sc->rate_idx[b->band][b->bitrates[i].hw_value] = i;
-               if (b->bitrates[i].hw_value_short)
-                       sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i;
-       }
-}
-
-static int
-ath5k_setup_bands(struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       struct ieee80211_supported_band *sband;
-       int max_c, count_c = 0;
-       int i;
-
-       BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS);
-       max_c = ARRAY_SIZE(sc->channels);
-
-       /* 2GHz band */
-       sband = &sc->sbands[IEEE80211_BAND_2GHZ];
-       sband->band = IEEE80211_BAND_2GHZ;
-       sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0];
-
-       if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) {
-               /* G mode */
-               memcpy(sband->bitrates, &ath5k_rates[0],
-                      sizeof(struct ieee80211_rate) * 12);
-               sband->n_bitrates = 12;
-
-               sband->channels = sc->channels;
-               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
-                                       AR5K_MODE_11G, max_c);
-
-               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
-               count_c = sband->n_channels;
-               max_c -= count_c;
-       } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) {
-               /* B mode */
-               memcpy(sband->bitrates, &ath5k_rates[0],
-                      sizeof(struct ieee80211_rate) * 4);
-               sband->n_bitrates = 4;
-
-               /* 5211 only supports B rates and uses 4bit rate codes
-                * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B)
-                * fix them up here:
-                */
-               if (ah->ah_version == AR5K_AR5211) {
-                       for (i = 0; i < 4; i++) {
-                               sband->bitrates[i].hw_value =
-                                       sband->bitrates[i].hw_value & 0xF;
-                               sband->bitrates[i].hw_value_short =
-                                       sband->bitrates[i].hw_value_short & 0xF;
-                       }
-               }
-
-               sband->channels = sc->channels;
-               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
-                                       AR5K_MODE_11B, max_c);
-
-               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
-               count_c = sband->n_channels;
-               max_c -= count_c;
-       }
-       ath5k_setup_rate_idx(sc, sband);
-
-       /* 5GHz band, A mode */
-       if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) {
-               sband = &sc->sbands[IEEE80211_BAND_5GHZ];
-               sband->band = IEEE80211_BAND_5GHZ;
-               sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0];
-
-               memcpy(sband->bitrates, &ath5k_rates[4],
-                      sizeof(struct ieee80211_rate) * 8);
-               sband->n_bitrates = 8;
-
-               sband->channels = &sc->channels[count_c];
-               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
-                                       AR5K_MODE_11A, max_c);
-
-               hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
-       }
-       ath5k_setup_rate_idx(sc, sband);
-
-       ath5k_debug_dump_bands(sc);
-
-       return 0;
-}
-
-/*
- * 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 after a la
- * ath5k_init.
- *
- * Called with sc->lock.
- */
-static int
-ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
-{
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
-               sc->curchan->center_freq, chan->center_freq);
-
-       if (chan->center_freq != sc->curchan->center_freq ||
-               chan->hw_value != sc->curchan->hw_value) {
-
-               sc->curchan = chan;
-               sc->curband = &sc->sbands[chan->band];
-
-               /*
-                * 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.
-                */
-               return ath5k_reset(sc, true, true);
-       }
-
-       return 0;
-}
-
-static void
-ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
-{
-       sc->curmode = mode;
-
-       if (mode == AR5K_MODE_11A) {
-               sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ];
-       } else {
-               sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ];
-       }
-}
-
-static void
-ath5k_mode_setup(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       u32 rfilt;
-
-       /* configure rx filter */
-       rfilt = sc->filter_flags;
-       ath5k_hw_set_rx_filter(ah, rfilt);
-
-       if (ath5k_hw_hasbssidmask(ah))
-               ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
-
-       /* configure operational mode */
-       ath5k_hw_set_opmode(ah);
-
-       ath5k_hw_set_mcast_filter(ah, 0, 0);
-       ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
-}
-
-static inline int
-ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
-{
-       int rix;
-
-       /* return base rate on errors */
-       if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
-                       "hw_rix out of bounds: %x\n", hw_rix))
-               return 0;
-
-       rix = sc->rate_idx[sc->curband->band][hw_rix];
-       if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
-               rix = 0;
-
-       return rix;
-}
-
-/***************\
-* Buffers setup *
-\***************/
-
-static
-struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
-{
-       struct sk_buff *skb;
-       unsigned int off;
-
-       /*
-        * Allocate buffer with headroom_needed space for the
-        * fake physical layer header at the start.
-        */
-       skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
-
-       if (!skb) {
-               ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
-                               sc->rxbufsize + sc->cachelsz - 1);
-               return NULL;
-       }
-       /*
-        * Cache-line-align.  This is important (for the
-        * 5210 at least) as not doing so causes bogus data
-        * in rx'd frames.
-        */
-       off = ((unsigned long)skb->data) % sc->cachelsz;
-       if (off != 0)
-               skb_reserve(skb, sc->cachelsz - off);
-
-       *skb_addr = pci_map_single(sc->pdev,
-               skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
-       if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
-               ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
-               dev_kfree_skb(skb);
-               return NULL;
-       }
-       return skb;
-}
-
-static int
-ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct sk_buff *skb = bf->skb;
-       struct ath5k_desc *ds;
-
-       if (!skb) {
-               skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr);
-               if (!skb)
-                       return -ENOMEM;
-               bf->skb = skb;
-       }
-
-       /*
-        * Setup descriptors.  For receive we always terminate
-        * the descriptor list with a self-linked entry so we'll
-        * not get overrun under high load (as can happen with a
-        * 5212 when ANI processing enables PHY error frames).
-        *
-        * To insure the last descriptor is self-linked we create
-        * each descriptor as self-linked and add it to the end.  As
-        * each additional descriptor is added the previous self-linked
-        * entry is ``fixed'' naturally.  This should be safe even
-        * if DMA is happening.  When processing RX interrupts we
-        * never remove/process the last, self-linked, entry on the
-        * descriptor list.  This insures the hardware always has
-        * someplace to write a new frame.
-        */
-       ds = bf->desc;
-       ds->ds_link = bf->daddr;        /* link to self */
-       ds->ds_data = bf->skbaddr;
-       ah->ah_setup_rx_desc(ah, ds,
-               skb_tailroom(skb),      /* buffer size */
-               0);
-
-       if (sc->rxlink != NULL)
-               *sc->rxlink = bf->daddr;
-       sc->rxlink = &ds->ds_link;
-       return 0;
-}
-
-static int
-ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_txq *txq = sc->txq;
-       struct ath5k_desc *ds = bf->desc;
-       struct sk_buff *skb = bf->skb;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
-       struct ieee80211_rate *rate;
-       unsigned int mrr_rate[3], mrr_tries[3];
-       int i, ret;
-       u16 hw_rate;
-       u16 cts_rate = 0;
-       u16 duration = 0;
-       u8 rc_flags;
-
-       flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
-
-       /* XXX endianness */
-       bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
-                       PCI_DMA_TODEVICE);
-
-       rate = ieee80211_get_tx_rate(sc->hw, info);
-
-       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-               flags |= AR5K_TXDESC_NOACK;
-
-       rc_flags = info->control.rates[0].flags;
-       hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
-               rate->hw_value_short : rate->hw_value;
-
-       pktlen = skb->len;
-
-       /* FIXME: If we are in g mode and rate is a CCK rate
-        * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
-        * from tx power (value is in dB units already) */
-       if (info->control.hw_key) {
-               keyidx = info->control.hw_key->hw_key_idx;
-               pktlen += info->control.hw_key->icv_len;
-       }
-       if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
-               flags |= AR5K_TXDESC_RTSENA;
-               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
-               duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
-                       sc->vif, pktlen, info));
-       }
-       if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
-               flags |= AR5K_TXDESC_CTSENA;
-               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
-               duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
-                       sc->vif, pktlen, info));
-       }
-       ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
-               ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
-               (sc->power_level * 2),
-               hw_rate,
-               info->control.rates[0].count, keyidx, 0, flags,
-               cts_rate, duration);
-       if (ret)
-               goto err_unmap;
-
-       memset(mrr_rate, 0, sizeof(mrr_rate));
-       memset(mrr_tries, 0, sizeof(mrr_tries));
-       for (i = 0; i < 3; i++) {
-               rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
-               if (!rate)
-                       break;
-
-               mrr_rate[i] = rate->hw_value;
-               mrr_tries[i] = info->control.rates[i + 1].count;
-       }
-
-       ah->ah_setup_mrr_tx_desc(ah, ds,
-               mrr_rate[0], mrr_tries[0],
-               mrr_rate[1], mrr_tries[1],
-               mrr_rate[2], mrr_tries[2]);
-
-       ds->ds_link = 0;
-       ds->ds_data = bf->skbaddr;
-
-       spin_lock_bh(&txq->lock);
-       list_add_tail(&bf->list, &txq->q);
-       sc->tx_stats[txq->qnum].len++;
-       if (txq->link == NULL) /* is this first packet? */
-               ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
-       else /* no, so only link it */
-               *txq->link = bf->daddr;
-
-       txq->link = &ds->ds_link;
-       ath5k_hw_start_tx_dma(ah, txq->qnum);
-       mmiowb();
-       spin_unlock_bh(&txq->lock);
-
-       return 0;
-err_unmap:
-       pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
-       return ret;
-}
-
-/*******************\
-* Descriptors setup *
-\*******************/
-
-static int
-ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
-{
-       struct ath5k_desc *ds;
-       struct ath5k_buf *bf;
-       dma_addr_t da;
-       unsigned int i;
-       int ret;
-
-       /* allocate descriptors */
-       sc->desc_len = sizeof(struct ath5k_desc) *
-                       (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);
-       sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr);
-       if (sc->desc == NULL) {
-               ATH5K_ERR(sc, "can't allocate descriptors\n");
-               ret = -ENOMEM;
-               goto err;
-       }
-       ds = sc->desc;
-       da = sc->desc_daddr;
-       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n",
-               ds, sc->desc_len, (unsigned long long)sc->desc_daddr);
-
-       bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF,
-                       sizeof(struct ath5k_buf), GFP_KERNEL);
-       if (bf == NULL) {
-               ATH5K_ERR(sc, "can't allocate bufptr\n");
-               ret = -ENOMEM;
-               goto err_free;
-       }
-       sc->bufptr = bf;
-
-       INIT_LIST_HEAD(&sc->rxbuf);
-       for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
-               bf->desc = ds;
-               bf->daddr = da;
-               list_add_tail(&bf->list, &sc->rxbuf);
-       }
-
-       INIT_LIST_HEAD(&sc->txbuf);
-       sc->txbuf_len = ATH_TXBUF;
-       for (i = 0; i < ATH_TXBUF; i++, bf++, ds++,
-                       da += sizeof(*ds)) {
-               bf->desc = ds;
-               bf->daddr = da;
-               list_add_tail(&bf->list, &sc->txbuf);
-       }
-
-       /* beacon buffer */
-       bf->desc = ds;
-       bf->daddr = da;
-       sc->bbuf = bf;
-
-       return 0;
-err_free:
-       pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
-err:
-       sc->desc = NULL;
-       return ret;
-}
-
-static void
-ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
-{
-       struct ath5k_buf *bf;
-
-       ath5k_txbuf_free(sc, sc->bbuf);
-       list_for_each_entry(bf, &sc->txbuf, list)
-               ath5k_txbuf_free(sc, bf);
-       list_for_each_entry(bf, &sc->rxbuf, list)
-               ath5k_rxbuf_free(sc, bf);
-
-       /* Free memory associated with all descriptors */
-       pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
-
-       kfree(sc->bufptr);
-       sc->bufptr = NULL;
-}
-
-
-
-
-
-/**************\
-* Queues setup *
-\**************/
-
-static struct ath5k_txq *
-ath5k_txq_setup(struct ath5k_softc *sc,
-               int qtype, int subtype)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_txq *txq;
-       struct ath5k_txq_info qi = {
-               .tqi_subtype = subtype,
-               .tqi_aifs = AR5K_TXQ_USEDEFAULT,
-               .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
-               .tqi_cw_max = AR5K_TXQ_USEDEFAULT
-       };
-       int qnum;
-
-       /*
-        * 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.
-        */
-       qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE |
-                               AR5K_TXQ_FLAG_TXDESCINT_ENABLE;
-       qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi);
-       if (qnum < 0) {
-               /*
-                * NB: don't print a message, this happens
-                * normally on parts with too few tx queues
-                */
-               return ERR_PTR(qnum);
-       }
-       if (qnum >= ARRAY_SIZE(sc->txqs)) {
-               ATH5K_ERR(sc, "hw qnum %u out of range, max %tu!\n",
-                       qnum, ARRAY_SIZE(sc->txqs));
-               ath5k_hw_release_tx_queue(ah, qnum);
-               return ERR_PTR(-EINVAL);
-       }
-       txq = &sc->txqs[qnum];
-       if (!txq->setup) {
-               txq->qnum = qnum;
-               txq->link = NULL;
-               INIT_LIST_HEAD(&txq->q);
-               spin_lock_init(&txq->lock);
-               txq->setup = true;
-       }
-       return &sc->txqs[qnum];
-}
-
-static int
-ath5k_beaconq_setup(struct ath5k_hw *ah)
-{
-       struct ath5k_txq_info qi = {
-               .tqi_aifs = AR5K_TXQ_USEDEFAULT,
-               .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
-               .tqi_cw_max = AR5K_TXQ_USEDEFAULT,
-               /* NB: for dynamic turbo, don't enable any other interrupts */
-               .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE
-       };
-
-       return ath5k_hw_setup_tx_queue(ah, AR5K_TX_QUEUE_BEACON, &qi);
-}
-
-static int
-ath5k_beaconq_config(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_txq_info qi;
-       int ret;
-
-       ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
-       if (ret)
-               return ret;
-       if (sc->opmode == NL80211_IFTYPE_AP ||
-               sc->opmode == NL80211_IFTYPE_MESH_POINT) {
-               /*
-                * Always burst out beacon and CAB traffic
-                * (aifs = cwmin = cwmax = 0)
-                */
-               qi.tqi_aifs = 0;
-               qi.tqi_cw_min = 0;
-               qi.tqi_cw_max = 0;
-       } else if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-               /*
-                * Adhoc mode; backoff between 0 and (2 * cw_min).
-                */
-               qi.tqi_aifs = 0;
-               qi.tqi_cw_min = 0;
-               qi.tqi_cw_max = 2 * ah->ah_cw_min;
-       }
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-               "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n",
-               qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max);
-
-       ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi);
-       if (ret) {
-               ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
-                       "hardware queue!\n", __func__);
-               return ret;
-       }
-
-       return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */;
-}
-
-static void
-ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
-{
-       struct ath5k_buf *bf, *bf0;
-
-       /*
-        * NB: this assumes output has been stopped and
-        *     we do not need to block ath5k_tx_tasklet
-        */
-       spin_lock_bh(&txq->lock);
-       list_for_each_entry_safe(bf, bf0, &txq->q, list) {
-               ath5k_debug_printtxbuf(sc, bf);
-
-               ath5k_txbuf_free(sc, bf);
-
-               spin_lock_bh(&sc->txbuflock);
-               sc->tx_stats[txq->qnum].len--;
-               list_move_tail(&bf->list, &sc->txbuf);
-               sc->txbuf_len++;
-               spin_unlock_bh(&sc->txbuflock);
-       }
-       txq->link = NULL;
-       spin_unlock_bh(&txq->lock);
-}
-
-/*
- * Drain the transmit queues and reclaim resources.
- */
-static void
-ath5k_txq_cleanup(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       unsigned int i;
-
-       /* XXX return value */
-       if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) {
-               /* don't touch the hardware if marked invalid */
-               ath5k_hw_stop_tx_dma(ah, sc->bhalq);
-               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",
-                       ath5k_hw_get_txdp(ah, sc->bhalq));
-               for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
-                       if (sc->txqs[i].setup) {
-                               ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
-                               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
-                                       "link %p\n",
-                                       sc->txqs[i].qnum,
-                                       ath5k_hw_get_txdp(ah,
-                                                       sc->txqs[i].qnum),
-                                       sc->txqs[i].link);
-                       }
-       }
-       ieee80211_wake_queues(sc->hw); /* XXX move to callers */
-
-       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
-               if (sc->txqs[i].setup)
-                       ath5k_txq_drainq(sc, &sc->txqs[i]);
-}
-
-static void
-ath5k_txq_release(struct ath5k_softc *sc)
-{
-       struct ath5k_txq *txq = sc->txqs;
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++, txq++)
-               if (txq->setup) {
-                       ath5k_hw_release_tx_queue(sc->ah, txq->qnum);
-                       txq->setup = false;
-               }
-}
-
-
-
-
-/*************\
-* RX Handling *
-\*************/
-
-/*
- * Enable the receive h/w following a reset.
- */
-static int
-ath5k_rx_start(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_buf *bf;
-       int ret;
-
-       sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->cachelsz);
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
-               sc->cachelsz, sc->rxbufsize);
-
-       sc->rxlink = NULL;
-
-       spin_lock_bh(&sc->rxbuflock);
-       list_for_each_entry(bf, &sc->rxbuf, list) {
-               ret = ath5k_rxbuf_setup(sc, bf);
-               if (ret != 0) {
-                       spin_unlock_bh(&sc->rxbuflock);
-                       goto err;
-               }
-       }
-       bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
-       spin_unlock_bh(&sc->rxbuflock);
-
-       ath5k_hw_set_rxdp(ah, bf->daddr);
-       ath5k_hw_start_rx_dma(ah);      /* enable recv descriptors */
-       ath5k_mode_setup(sc);           /* set filters, etc. */
-       ath5k_hw_start_rx_pcu(ah);      /* re-enable PCU/DMA engine */
-
-       return 0;
-err:
-       return ret;
-}
-
-/*
- * Disable the receive h/w in preparation for a reset.
- */
-static void
-ath5k_rx_stop(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-
-       ath5k_hw_stop_rx_pcu(ah);       /* disable PCU */
-       ath5k_hw_set_rx_filter(ah, 0);  /* clear recv filter */
-       ath5k_hw_stop_rx_dma(ah);       /* disable DMA engine */
-
-       ath5k_debug_printrxbuffs(sc, ah);
-
-       sc->rxlink = NULL;              /* just in case */
-}
-
-static unsigned int
-ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
-               struct sk_buff *skb, struct ath5k_rx_status *rs)
-{
-       struct ieee80211_hdr *hdr = (void *)skb->data;
-       unsigned int keyix, hlen;
-
-       if (!(rs->rs_status & AR5K_RXERR_DECRYPT) &&
-                       rs->rs_keyix != AR5K_RXKEYIX_INVALID)
-               return RX_FLAG_DECRYPTED;
-
-       /* Apparently when a default key is used to decrypt the packet
-          the hw does not set the index used to decrypt.  In such cases
-          get the index from the packet. */
-       hlen = ieee80211_hdrlen(hdr->frame_control);
-       if (ieee80211_has_protected(hdr->frame_control) &&
-           !(rs->rs_status & AR5K_RXERR_DECRYPT) &&
-           skb->len >= hlen + 4) {
-               keyix = skb->data[hlen + 3] >> 6;
-
-               if (test_bit(keyix, sc->keymap))
-                       return RX_FLAG_DECRYPTED;
-       }
-
-       return 0;
-}
-
-
-static void
-ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
-                    struct ieee80211_rx_status *rxs)
-{
-       u64 tsf, bc_tstamp;
-       u32 hw_tu;
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-
-       if (ieee80211_is_beacon(mgmt->frame_control) &&
-           le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
-           memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
-               /*
-                * Received an IBSS beacon with the same BSSID. Hardware *must*
-                * have updated the local TSF. We have to work around various
-                * hardware bugs, though...
-                */
-               tsf = ath5k_hw_get_tsf64(sc->ah);
-               bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp);
-               hw_tu = TSF_TO_TU(tsf);
-
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "beacon %llx mactime %llx (diff %lld) tsf now %llx\n",
-                       (unsigned long long)bc_tstamp,
-                       (unsigned long long)rxs->mactime,
-                       (unsigned long long)(rxs->mactime - bc_tstamp),
-                       (unsigned long long)tsf);
-
-               /*
-                * Sometimes the HW will give us a wrong tstamp in the rx
-                * status, causing the timestamp extension to go wrong.
-                * (This seems to happen especially with beacon frames bigger
-                * than 78 byte (incl. FCS))
-                * But we know that the receive timestamp must be later than the
-                * timestamp of the beacon since HW must have synced to that.
-                *
-                * NOTE: here we assume mactime to be after the frame was
-                * received, not like mac80211 which defines it at the start.
-                */
-               if (bc_tstamp > rxs->mactime) {
-                       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                               "fixing mactime from %llx to %llx\n",
-                               (unsigned long long)rxs->mactime,
-                               (unsigned long long)tsf);
-                       rxs->mactime = tsf;
-               }
-
-               /*
-                * Local TSF might have moved higher than our beacon timers,
-                * in that case we have to update them to continue sending
-                * beacons. This also takes care of synchronizing beacon sending
-                * times with other stations.
-                */
-               if (hw_tu >= sc->nexttbtt)
-                       ath5k_beacon_update_timers(sc, bc_tstamp);
-       }
-}
-
-static void ath5k_tasklet_beacon(unsigned long data)
-{
-       struct ath5k_softc *sc = (struct ath5k_softc *) data;
-
-       /*
-        * Software beacon alert--time to send a beacon.
-        *
-        * In IBSS mode we use this interrupt just to
-        * keep track of the next TBTT (target beacon
-        * transmission time) in order to detect wether
-        * automatic TSF updates happened.
-        */
-       if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-               /* XXX: only if VEOL suppported */
-               u64 tsf = ath5k_hw_get_tsf64(sc->ah);
-               sc->nexttbtt += sc->bintval;
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-                               "SWBA nexttbtt: %x hw_tu: %x "
-                               "TSF: %llx\n",
-                               sc->nexttbtt,
-                               TSF_TO_TU(tsf),
-                               (unsigned long long) tsf);
-       } else {
-               spin_lock(&sc->block);
-               ath5k_beacon_send(sc);
-               spin_unlock(&sc->block);
-       }
-}
-
-static void
-ath5k_tasklet_rx(unsigned long data)
-{
-       struct ieee80211_rx_status rxs = {};
-       struct ath5k_rx_status rs = {};
-       struct sk_buff *skb, *next_skb;
-       dma_addr_t next_skb_addr;
-       struct ath5k_softc *sc = (void *)data;
-       struct ath5k_buf *bf, *bf_last;
-       struct ath5k_desc *ds;
-       int ret;
-       int hdrlen;
-       int padsize;
-
-       spin_lock(&sc->rxbuflock);
-       if (list_empty(&sc->rxbuf)) {
-               ATH5K_WARN(sc, "empty rx buf pool\n");
-               goto unlock;
-       }
-       bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list);
-       do {
-               rxs.flag = 0;
-
-               bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
-               BUG_ON(bf->skb == NULL);
-               skb = bf->skb;
-               ds = bf->desc;
-
-               /*
-                * last buffer must not be freed to ensure proper hardware
-                * function. When the hardware finishes also a packet next to
-                * it, we are sure, it doesn't use it anymore and we can go on.
-                */
-               if (bf_last == bf)
-                       bf->flags |= 1;
-               if (bf->flags) {
-                       struct ath5k_buf *bf_next = list_entry(bf->list.next,
-                                       struct ath5k_buf, list);
-                       ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc,
-                                       &rs);
-                       if (ret)
-                               break;
-                       bf->flags &= ~1;
-                       /* skip the overwritten one (even status is martian) */
-                       goto next;
-               }
-
-               ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
-               if (unlikely(ret == -EINPROGRESS))
-                       break;
-               else if (unlikely(ret)) {
-                       ATH5K_ERR(sc, "error in processing rx descriptor\n");
-                       spin_unlock(&sc->rxbuflock);
-                       return;
-               }
-
-               if (unlikely(rs.rs_more)) {
-                       ATH5K_WARN(sc, "unsupported jumbo\n");
-                       goto next;
-               }
-
-               if (unlikely(rs.rs_status)) {
-                       if (rs.rs_status & AR5K_RXERR_PHY)
-                               goto next;
-                       if (rs.rs_status & AR5K_RXERR_DECRYPT) {
-                               /*
-                                * Decrypt error.  If the error occurred
-                                * because there was no hardware key, then
-                                * let the frame through so the upper layers
-                                * can process it.  This is necessary for 5210
-                                * parts which have no way to setup a ``clear''
-                                * key cache entry.
-                                *
-                                * XXX do key cache faulting
-                                */
-                               if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
-                                   !(rs.rs_status & AR5K_RXERR_CRC))
-                                       goto accept;
-                       }
-                       if (rs.rs_status & AR5K_RXERR_MIC) {
-                               rxs.flag |= RX_FLAG_MMIC_ERROR;
-                               goto accept;
-                       }
-
-                       /* let crypto-error packets fall through in MNTR */
-                       if ((rs.rs_status &
-                               ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
-                                       sc->opmode != NL80211_IFTYPE_MONITOR)
-                               goto next;
-               }
-accept:
-               next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
-
-               /*
-                * If we can't replace bf->skb with a new skb under memory
-                * pressure, just skip this packet
-                */
-               if (!next_skb)
-                       goto next;
-
-               pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
-                               PCI_DMA_FROMDEVICE);
-               skb_put(skb, rs.rs_datalen);
-
-               /* The MAC header is padded to have 32-bit boundary if the
-                * packet payload is non-zero. The general calculation for
-                * padsize would take into account odd header lengths:
-                * padsize = (4 - hdrlen % 4) % 4; However, since only
-                * even-length headers are used, padding can only be 0 or 2
-                * bytes and we can optimize this a bit. In addition, we must
-                * not try to remove padding from short control frames that do
-                * not have payload. */
-               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-               padsize = ath5k_pad_size(hdrlen);
-               if (padsize) {
-                       memmove(skb->data + padsize, skb->data, hdrlen);
-                       skb_pull(skb, padsize);
-               }
-
-               /*
-                * always extend the mac timestamp, since this information is
-                * also needed for proper IBSS merging.
-                *
-                * XXX: it might be too late to do it here, since rs_tstamp is
-                * 15bit only. that means TSF extension has to be done within
-                * 32768usec (about 32ms). it might be necessary to move this to
-                * the interrupt handler, like it is done in madwifi.
-                *
-                * Unfortunately we don't know when the hardware takes the rx
-                * timestamp (beginning of phy frame, data frame, end of rx?).
-                * The only thing we know is that it is hardware specific...
-                * On AR5213 it seems the rx timestamp is at the end of the
-                * frame, but i'm not sure.
-                *
-                * NOTE: mac80211 defines mactime at the beginning of the first
-                * data symbol. Since we don't have any time references it's
-                * impossible to comply to that. This affects IBSS merge only
-                * right now, so it's not too bad...
-                */
-               rxs.mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp);
-               rxs.flag |= RX_FLAG_TSFT;
-
-               rxs.freq = sc->curchan->center_freq;
-               rxs.band = sc->curband->band;
-
-               rxs.noise = sc->ah->ah_noise_floor;
-               rxs.signal = rxs.noise + rs.rs_rssi;
-
-               /* An rssi of 35 indicates you should be able use
-                * 54 Mbps reliably. A more elaborate scheme can be used
-                * here but it requires a map of SNR/throughput for each
-                * possible mode used */
-               rxs.qual = rs.rs_rssi * 100 / 35;
-
-               /* rssi can be more than 35 though, anything above that
-                * should be considered at 100% */
-               if (rxs.qual > 100)
-                       rxs.qual = 100;
-
-               rxs.antenna = rs.rs_antenna;
-               rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
-               rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
-
-               if (rxs.rate_idx >= 0 && rs.rs_rate ==
-                   sc->curband->bitrates[rxs.rate_idx].hw_value_short)
-                       rxs.flag |= RX_FLAG_SHORTPRE;
-
-               ath5k_debug_dump_skb(sc, skb, "RX  ", 0);
-
-               /* check beacons in IBSS mode */
-               if (sc->opmode == NL80211_IFTYPE_ADHOC)
-                       ath5k_check_ibss_tsf(sc, skb, &rxs);
-
-               __ieee80211_rx(sc->hw, skb, &rxs);
-
-               bf->skb = next_skb;
-               bf->skbaddr = next_skb_addr;
-next:
-               list_move_tail(&bf->list, &sc->rxbuf);
-       } while (ath5k_rxbuf_setup(sc, bf) == 0);
-unlock:
-       spin_unlock(&sc->rxbuflock);
-}
-
-
-
-
-/*************\
-* TX Handling *
-\*************/
-
-static void
-ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
-{
-       struct ath5k_tx_status ts = {};
-       struct ath5k_buf *bf, *bf0;
-       struct ath5k_desc *ds;
-       struct sk_buff *skb;
-       struct ieee80211_tx_info *info;
-       int i, ret;
-
-       spin_lock(&txq->lock);
-       list_for_each_entry_safe(bf, bf0, &txq->q, list) {
-               ds = bf->desc;
-
-               ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
-               if (unlikely(ret == -EINPROGRESS))
-                       break;
-               else if (unlikely(ret)) {
-                       ATH5K_ERR(sc, "error %d while processing queue %u\n",
-                               ret, txq->qnum);
-                       break;
-               }
-
-               skb = bf->skb;
-               info = IEEE80211_SKB_CB(skb);
-               bf->skb = NULL;
-
-               pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
-                               PCI_DMA_TODEVICE);
-
-               ieee80211_tx_info_clear_status(info);
-               for (i = 0; i < 4; i++) {
-                       struct ieee80211_tx_rate *r =
-                               &info->status.rates[i];
-
-                       if (ts.ts_rate[i]) {
-                               r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
-                               r->count = ts.ts_retry[i];
-                       } else {
-                               r->idx = -1;
-                               r->count = 0;
-                       }
-               }
-
-               /* count the successful attempt as well */
-               info->status.rates[ts.ts_final_idx].count++;
-
-               if (unlikely(ts.ts_status)) {
-                       sc->ll_stats.dot11ACKFailureCount++;
-                       if (ts.ts_status & AR5K_TXERR_FILT)
-                               info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-               } else {
-                       info->flags |= IEEE80211_TX_STAT_ACK;
-                       info->status.ack_signal = ts.ts_rssi;
-               }
-
-               ieee80211_tx_status(sc->hw, skb);
-               sc->tx_stats[txq->qnum].count++;
-
-               spin_lock(&sc->txbuflock);
-               sc->tx_stats[txq->qnum].len--;
-               list_move_tail(&bf->list, &sc->txbuf);
-               sc->txbuf_len++;
-               spin_unlock(&sc->txbuflock);
-       }
-       if (likely(list_empty(&txq->q)))
-               txq->link = NULL;
-       spin_unlock(&txq->lock);
-       if (sc->txbuf_len > ATH_TXBUF / 5)
-               ieee80211_wake_queues(sc->hw);
-}
-
-static void
-ath5k_tasklet_tx(unsigned long data)
-{
-       struct ath5k_softc *sc = (void *)data;
-
-       ath5k_tx_processq(sc, sc->txq);
-}
-
-
-/*****************\
-* Beacon handling *
-\*****************/
-
-/*
- * Setup the beacon frame for transmit.
- */
-static int
-ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
-{
-       struct sk_buff *skb = bf->skb;
-       struct  ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_desc *ds;
-       int ret, antenna = 0;
-       u32 flags;
-
-       bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
-                       PCI_DMA_TODEVICE);
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
-                       "skbaddr %llx\n", skb, skb->data, skb->len,
-                       (unsigned long long)bf->skbaddr);
-       if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) {
-               ATH5K_ERR(sc, "beacon DMA mapping failed\n");
-               return -EIO;
-       }
-
-       ds = bf->desc;
-
-       flags = AR5K_TXDESC_NOACK;
-       if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
-               ds->ds_link = bf->daddr;        /* self-linked */
-               flags |= AR5K_TXDESC_VEOL;
-               /*
-                * Let hardware handle antenna switching if txantenna is not set
-                */
-       } else {
-               ds->ds_link = 0;
-               /*
-                * Switch antenna every 4 beacons if txantenna is not set
-                * XXX assumes two antennas
-                */
-               if (antenna == 0)
-                       antenna = sc->bsent & 4 ? 2 : 1;
-       }
-
-       /* FIXME: If we are in g mode and rate is a CCK rate
-        * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
-        * from tx power (value is in dB units already) */
-       ds->ds_data = bf->skbaddr;
-       ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
-                       ieee80211_get_hdrlen_from_skb(skb),
-                       AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
-                       ieee80211_get_tx_rate(sc->hw, info)->hw_value,
-                       1, AR5K_TXKEYIX_INVALID,
-                       antenna, flags, 0, 0);
-       if (ret)
-               goto err_unmap;
-
-       return 0;
-err_unmap:
-       pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
-       return ret;
-}
-
-/*
- * Transmit a beacon frame at SWBA.  Dynamic updates to the
- * frame contents are done as needed and the slot time is
- * also adjusted based on current state.
- *
- * This is called from software irq context (beacontq or restq
- * tasklets) or user context from ath5k_beacon_config.
- */
-static void
-ath5k_beacon_send(struct ath5k_softc *sc)
-{
-       struct ath5k_buf *bf = sc->bbuf;
-       struct ath5k_hw *ah = sc->ah;
-
-       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
-
-       if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
-                       sc->opmode == NL80211_IFTYPE_MONITOR)) {
-               ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
-               return;
-       }
-       /*
-        * Check if the previous beacon has gone out.  If
-        * not don't don't try to post another, skip this
-        * period and wait for the next.  Missed beacons
-        * indicate a problem and should not occur.  If we
-        * miss too many consecutive beacons reset the device.
-        */
-       if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
-               sc->bmisscount++;
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-                       "missed %u consecutive beacons\n", sc->bmisscount);
-               if (sc->bmisscount > 3) {               /* NB: 3 is a guess */
-                       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-                               "stuck beacon time (%u missed)\n",
-                               sc->bmisscount);
-                       tasklet_schedule(&sc->restq);
-               }
-               return;
-       }
-       if (unlikely(sc->bmisscount != 0)) {
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-                       "resume beacon xmit after %u misses\n",
-                       sc->bmisscount);
-               sc->bmisscount = 0;
-       }
-
-       /*
-        * 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 (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
-               ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq);
-               /* NB: hw still stops DMA, so proceed */
-       }
-
-       ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
-       ath5k_hw_start_tx_dma(ah, sc->bhalq);
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
-               sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
-
-       sc->bsent++;
-}
-
-
-/**
- * ath5k_beacon_update_timers - update beacon timers
- *
- * @sc: struct ath5k_softc pointer we are operating on
- * @bc_tsf: the timestamp of the beacon. 0 to reset the TSF. -1 to perform a
- *          beacon timer update based on the current HW TSF.
- *
- * Calculate the next target beacon transmit time (TBTT) based on the timestamp
- * of a received beacon or the current local hardware TSF and write it to the
- * beacon timer registers.
- *
- * This is called in a variety of situations, e.g. when a beacon is received,
- * when a TSF update has been detected, but also when an new IBSS is created or
- * when we otherwise know we have to update the timers, but we keep it in this
- * function to have it all together in one place.
- */
-static void
-ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
-{
-       struct ath5k_hw *ah = sc->ah;
-       u32 nexttbtt, intval, hw_tu, bc_tu;
-       u64 hw_tsf;
-
-       intval = sc->bintval & AR5K_BEACON_PERIOD;
-       if (WARN_ON(!intval))
-               return;
-
-       /* beacon TSF converted to TU */
-       bc_tu = TSF_TO_TU(bc_tsf);
-
-       /* current TSF converted to TU */
-       hw_tsf = ath5k_hw_get_tsf64(ah);
-       hw_tu = TSF_TO_TU(hw_tsf);
-
-#define FUDGE 3
-       /* we use FUDGE to make sure the next TBTT is ahead of the current TU */
-       if (bc_tsf == -1) {
-               /*
-                * no beacons received, called internally.
-                * just need to refresh timers based on HW TSF.
-                */
-               nexttbtt = roundup(hw_tu + FUDGE, intval);
-       } else if (bc_tsf == 0) {
-               /*
-                * no beacon received, probably called by ath5k_reset_tsf().
-                * reset TSF to start with 0.
-                */
-               nexttbtt = intval;
-               intval |= AR5K_BEACON_RESET_TSF;
-       } else if (bc_tsf > hw_tsf) {
-               /*
-                * beacon received, SW merge happend but HW TSF not yet updated.
-                * not possible to reconfigure timers yet, but next time we
-                * receive a beacon with the same BSSID, the hardware will
-                * automatically update the TSF and then we need to reconfigure
-                * the timers.
-                */
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "need to wait for HW TSF sync\n");
-               return;
-       } else {
-               /*
-                * most important case for beacon synchronization between STA.
-                *
-                * beacon received and HW TSF has been already updated by HW.
-                * update next TBTT based on the TSF of the beacon, but make
-                * sure it is ahead of our local TSF timer.
-                */
-               nexttbtt = bc_tu + roundup(hw_tu + FUDGE - bc_tu, intval);
-       }
-#undef FUDGE
-
-       sc->nexttbtt = nexttbtt;
-
-       intval |= AR5K_BEACON_ENA;
-       ath5k_hw_init_beacon(ah, nexttbtt, intval);
-
-       /*
-        * debugging output last in order to preserve the time critical aspect
-        * of this function
-        */
-       if (bc_tsf == -1)
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "reconfigured timers based on HW TSF\n");
-       else if (bc_tsf == 0)
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "reset HW TSF and timers\n");
-       else
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "updated timers based on beacon TSF\n");
-
-       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                         "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n",
-                         (unsigned long long) bc_tsf,
-                         (unsigned long long) hw_tsf, bc_tu, hw_tu, nexttbtt);
-       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "intval %u %s %s\n",
-               intval & AR5K_BEACON_PERIOD,
-               intval & AR5K_BEACON_ENA ? "AR5K_BEACON_ENA" : "",
-               intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : "");
-}
-
-
-/**
- * ath5k_beacon_config - Configure the beacon queues and interrupts
- *
- * @sc: struct ath5k_softc pointer we are operating on
- *
- * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
- * interrupts to detect TSF updates only.
- */
-static void
-ath5k_beacon_config(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       unsigned long flags;
-
-       ath5k_hw_set_imr(ah, 0);
-       sc->bmisscount = 0;
-       sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
-
-       if (sc->opmode == NL80211_IFTYPE_ADHOC ||
-                       sc->opmode == NL80211_IFTYPE_MESH_POINT ||
-                       sc->opmode == NL80211_IFTYPE_AP) {
-               /*
-                * In IBSS mode we use a self-linked tx descriptor and let the
-                * hardware send the beacons automatically. We have to load it
-                * only once here.
-                * We use the SWBA interrupt only to keep track of the beacon
-                * timers in order to detect automatic TSF updates.
-                */
-               ath5k_beaconq_config(sc);
-
-               sc->imask |= AR5K_INT_SWBA;
-
-               if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-                       if (ath5k_hw_hasveol(ah)) {
-                               spin_lock_irqsave(&sc->block, flags);
-                               ath5k_beacon_send(sc);
-                               spin_unlock_irqrestore(&sc->block, flags);
-                       }
-               } else
-                       ath5k_beacon_update_timers(sc, -1);
-       }
-
-       ath5k_hw_set_imr(ah, sc->imask);
-}
-
-
-/********************\
-* Interrupt handling *
-\********************/
-
-static int
-ath5k_init(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       int ret, i;
-
-       mutex_lock(&sc->lock);
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
-
-       /*
-        * Stop anything previously setup.  This is safe
-        * no matter this is the first time through or not.
-        */
-       ath5k_stop_locked(sc);
-
-       /*
-        * 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.
-        */
-       sc->curchan = sc->hw->conf.channel;
-       sc->curband = &sc->sbands[sc->curchan->band];
-       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
-               AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
-               AR5K_INT_FATAL | AR5K_INT_GLOBAL;
-       ret = ath5k_reset(sc, false, false);
-       if (ret)
-               goto done;
-
-       /*
-        * Reset the key cache since some parts do not reset the
-        * contents on initial power up or resume from suspend.
-        */
-       for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
-               ath5k_hw_reset_key(ah, i);
-
-       /* Set ack to be sent at low bit-rates */
-       ath5k_hw_set_ack_bitrate_high(ah, false);
-
-       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
-                       msecs_to_jiffies(ath5k_calinterval * 1000)));
-
-       ret = 0;
-done:
-       mmiowb();
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-static int
-ath5k_stop_locked(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
-                       test_bit(ATH_STAT_INVALID, sc->status));
-
-       /*
-        * Shutdown the hardware and driver:
-        *    stop output from above
-        *    disable interrupts
-        *    turn off timers
-        *    turn off the radio
-        *    clear transmit machinery
-        *    clear receive machinery
-        *    drain and release tx queues
-        *    reclaim beacon resources
-        *    power down hardware
-        *
-        * Note that some of this work is not possible if the
-        * hardware is gone (invalid).
-        */
-       ieee80211_stop_queues(sc->hw);
-
-       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
-               ath5k_led_off(sc);
-               ath5k_hw_set_imr(ah, 0);
-               synchronize_irq(sc->pdev->irq);
-       }
-       ath5k_txq_cleanup(sc);
-       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
-               ath5k_rx_stop(sc);
-               ath5k_hw_phy_disable(ah);
-       } else
-               sc->rxlink = NULL;
-
-       return 0;
-}
-
-/*
- * Stop the device, grabbing the top-level lock to protect
- * against concurrent entry through ath5k_init (which can happen
- * if another thread does a system call and the thread doing the
- * stop is preempted).
- */
-static int
-ath5k_stop_hw(struct ath5k_softc *sc)
-{
-       int ret;
-
-       mutex_lock(&sc->lock);
-       ret = ath5k_stop_locked(sc);
-       if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
-               /*
-                * Set the chip in full sleep mode.  Note that we are
-                * careful to do this only when bringing the interface
-                * completely to a stop.  When the chip is in this state
-                * it must be carefully woken up or references to
-                * registers in the PCI clock domain may freeze the bus
-                * (and system).  This varies by chip and is mostly an
-                * issue with newer parts that go to sleep more quickly.
-                */
-               if (sc->ah->ah_mac_srev >= 0x78) {
-                       /*
-                        * XXX
-                        * don't put newer MAC revisions > 7.8 to sleep because
-                        * of the above mentioned problems
-                        */
-                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, "
-                               "not putting device to sleep\n");
-               } else {
-                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
-                               "putting device to full sleep\n");
-                       ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0);
-               }
-       }
-       ath5k_txbuf_free(sc, sc->bbuf);
-
-       mmiowb();
-       mutex_unlock(&sc->lock);
-
-       del_timer_sync(&sc->calib_tim);
-       tasklet_kill(&sc->rxtq);
-       tasklet_kill(&sc->txtq);
-       tasklet_kill(&sc->restq);
-       tasklet_kill(&sc->beacontq);
-
-       return ret;
-}
-
-static irqreturn_t
-ath5k_intr(int irq, void *dev_id)
-{
-       struct ath5k_softc *sc = dev_id;
-       struct ath5k_hw *ah = sc->ah;
-       enum ath5k_int status;
-       unsigned int counter = 1000;
-
-       if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
-                               !ath5k_hw_is_intr_pending(ah)))
-               return IRQ_NONE;
-
-       do {
-               ath5k_hw_get_isr(ah, &status);          /* NB: clears IRQ too */
-               ATH5K_DBG(sc, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
-                               status, sc->imask);
-               if (unlikely(status & AR5K_INT_FATAL)) {
-                       /*
-                        * Fatal errors are unrecoverable.
-                        * Typically these are caused by DMA errors.
-                        */
-                       tasklet_schedule(&sc->restq);
-               } else if (unlikely(status & AR5K_INT_RXORN)) {
-                       tasklet_schedule(&sc->restq);
-               } else {
-                       if (status & AR5K_INT_SWBA) {
-                               tasklet_schedule(&sc->beacontq);
-                       }
-                       if (status & AR5K_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.
-                               */
-                               sc->rxlink = NULL;
-                       }
-                       if (status & AR5K_INT_TXURN) {
-                               /* bump tx trigger level */
-                               ath5k_hw_update_tx_triglevel(ah, true);
-                       }
-                       if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
-                               tasklet_schedule(&sc->rxtq);
-                       if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
-                                       | AR5K_INT_TXERR | AR5K_INT_TXEOL))
-                               tasklet_schedule(&sc->txtq);
-                       if (status & AR5K_INT_BMISS) {
-                               /* TODO */
-                       }
-                       if (status & AR5K_INT_MIB) {
-                               /*
-                                * These stats are also used for ANI i think
-                                * so how about updating them more often ?
-                                */
-                               ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
-                       }
-               }
-       } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0);
-
-       if (unlikely(!counter))
-               ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
-
-       return IRQ_HANDLED;
-}
-
-static void
-ath5k_tasklet_reset(unsigned long data)
-{
-       struct ath5k_softc *sc = (void *)data;
-
-       ath5k_reset_wake(sc);
-}
-
-/*
- * Periodically recalibrate the PHY to account
- * for temperature/environment changes.
- */
-static void
-ath5k_calibrate(unsigned long data)
-{
-       struct ath5k_softc *sc = (void *)data;
-       struct ath5k_hw *ah = sc->ah;
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
-               ieee80211_frequency_to_channel(sc->curchan->center_freq),
-               sc->curchan->hw_value);
-
-       if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
-               /*
-                * Rfgain is out of bounds, reset the chip
-                * to load new gain values.
-                */
-               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
-               ath5k_reset_wake(sc);
-       }
-       if (ath5k_hw_phy_calibrate(ah, sc->curchan))
-               ATH5K_ERR(sc, "calibration of channel %u failed\n",
-                       ieee80211_frequency_to_channel(
-                               sc->curchan->center_freq));
-
-       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
-                       msecs_to_jiffies(ath5k_calinterval * 1000)));
-}
-
-
-/********************\
-* Mac80211 functions *
-\********************/
-
-static int
-ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_buf *bf;
-       unsigned long flags;
-       int hdrlen;
-       int padsize;
-
-       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
-
-       if (sc->opmode == NL80211_IFTYPE_MONITOR)
-               ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n");
-
-       /*
-        * the hardware expects the header padded to 4 byte boundaries
-        * if this is not the case we add the padding after the header
-        */
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       padsize = ath5k_pad_size(hdrlen);
-       if (padsize) {
-
-               if (skb_headroom(skb) < padsize) {
-                       ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
-                                 " headroom to pad %d\n", hdrlen, padsize);
-                       goto drop_packet;
-               }
-               skb_push(skb, padsize);
-               memmove(skb->data, skb->data+padsize, hdrlen);
-       }
-
-       spin_lock_irqsave(&sc->txbuflock, flags);
-       if (list_empty(&sc->txbuf)) {
-               ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
-               spin_unlock_irqrestore(&sc->txbuflock, flags);
-               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
-               goto drop_packet;
-       }
-       bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
-       list_del(&bf->list);
-       sc->txbuf_len--;
-       if (list_empty(&sc->txbuf))
-               ieee80211_stop_queues(hw);
-       spin_unlock_irqrestore(&sc->txbuflock, flags);
-
-       bf->skb = skb;
-
-       if (ath5k_txbuf_setup(sc, bf)) {
-               bf->skb = NULL;
-               spin_lock_irqsave(&sc->txbuflock, flags);
-               list_add_tail(&bf->list, &sc->txbuf);
-               sc->txbuf_len++;
-               spin_unlock_irqrestore(&sc->txbuflock, flags);
-               goto drop_packet;
-       }
-       return NETDEV_TX_OK;
-
-drop_packet:
-       dev_kfree_skb_any(skb);
-       return NETDEV_TX_OK;
-}
-
-static int
-ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
-{
-       struct ath5k_hw *ah = sc->ah;
-       int ret;
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
-
-       if (stop) {
-               ath5k_hw_set_imr(ah, 0);
-               ath5k_txq_cleanup(sc);
-               ath5k_rx_stop(sc);
-       }
-       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
-       if (ret) {
-               ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
-               goto err;
-       }
-
-       ret = ath5k_rx_start(sc);
-       if (ret) {
-               ATH5K_ERR(sc, "can't start recv logic\n");
-               goto err;
-       }
-
-       /*
-        * Change channels and update the h/w rate map if we're switching;
-        * e.g. 11a to 11b/g.
-        *
-        * We may be doing a reset in response to an ioctl that changes the
-        * channel so update any state that might change as a result.
-        *
-        * XXX needed?
-        */
-/*     ath5k_chan_change(sc, c); */
-
-       ath5k_beacon_config(sc);
-       /* intrs are enabled by ath5k_beacon_config */
-
-       return 0;
-err:
-       return ret;
-}
-
-static int
-ath5k_reset_wake(struct ath5k_softc *sc)
-{
-       int ret;
-
-       ret = ath5k_reset(sc, true, true);
-       if (!ret)
-               ieee80211_wake_queues(sc->hw);
-
-       return ret;
-}
-
-static int ath5k_start(struct ieee80211_hw *hw)
-{
-       return ath5k_init(hw->priv);
-}
-
-static void ath5k_stop(struct ieee80211_hw *hw)
-{
-       ath5k_stop_hw(hw->priv);
-}
-
-static int ath5k_add_interface(struct ieee80211_hw *hw,
-               struct ieee80211_if_init_conf *conf)
-{
-       struct ath5k_softc *sc = hw->priv;
-       int ret;
-
-       mutex_lock(&sc->lock);
-       if (sc->vif) {
-               ret = 0;
-               goto end;
-       }
-
-       sc->vif = conf->vif;
-
-       switch (conf->type) {
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_MESH_POINT:
-       case NL80211_IFTYPE_MONITOR:
-               sc->opmode = conf->type;
-               break;
-       default:
-               ret = -EOPNOTSUPP;
-               goto end;
-       }
-
-       /* Set to a reasonable value. Note that this will
-        * be set to mac80211's value at ath5k_config(). */
-       sc->bintval = 1000;
-       ath5k_hw_set_lladdr(sc->ah, conf->mac_addr);
-
-       ret = 0;
-end:
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-static void
-ath5k_remove_interface(struct ieee80211_hw *hw,
-                       struct ieee80211_if_init_conf *conf)
-{
-       struct ath5k_softc *sc = hw->priv;
-       u8 mac[ETH_ALEN] = {};
-
-       mutex_lock(&sc->lock);
-       if (sc->vif != conf->vif)
-               goto end;
-
-       ath5k_hw_set_lladdr(sc->ah, mac);
-       sc->vif = NULL;
-end:
-       mutex_unlock(&sc->lock);
-}
-
-/*
- * TODO: Phy disable/diversity etc
- */
-static int
-ath5k_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ieee80211_conf *conf = &hw->conf;
-       int ret;
-
-       mutex_lock(&sc->lock);
-
-       sc->bintval = conf->beacon_int;
-       sc->power_level = conf->power_level;
-
-       ret = ath5k_chan_set(sc, conf->channel);
-
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-static int
-ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                       struct ieee80211_if_conf *conf)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       int ret = 0;
-
-       mutex_lock(&sc->lock);
-       if (sc->vif != vif) {
-               ret = -EIO;
-               goto unlock;
-       }
-       if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
-               /* Cache for later use during resets */
-               memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
-               /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
-                * a clean way of letting us retrieve this yet. */
-               ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
-               mmiowb();
-       }
-       if (conf->changed & IEEE80211_IFCC_BEACON &&
-                       (vif->type == NL80211_IFTYPE_ADHOC ||
-                        vif->type == NL80211_IFTYPE_MESH_POINT ||
-                        vif->type == NL80211_IFTYPE_AP)) {
-               struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-               if (!beacon) {
-                       ret = -ENOMEM;
-                       goto unlock;
-               }
-               ath5k_beacon_update(sc, beacon);
-       }
-
-unlock:
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-#define SUPPORTED_FIF_FLAGS \
-       FIF_PROMISC_IN_BSS |  FIF_ALLMULTI | FIF_FCSFAIL | \
-       FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
-       FIF_BCN_PRBRESP_PROMISC
-/*
- * o always accept unicast, broadcast, and multicast traffic
- * o multicast traffic for all BSSIDs will be enabled if mac80211
- *   says it should be
- * o maintain current state of phy ofdm or phy cck error reception.
- *   If the hardware detects any of these type of errors then
- *   ath5k_hw_get_rx_filter() will pass to us the respective
- *   hardware filters to be able to receive these type of frames.
- * 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 scanning
- */
-static void ath5k_configure_filter(struct ieee80211_hw *hw,
-               unsigned int changed_flags,
-               unsigned int *new_flags,
-               int mc_count, struct dev_mc_list *mclist)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       u32 mfilt[2], val, rfilt;
-       u8 pos;
-       int i;
-
-       mfilt[0] = 0;
-       mfilt[1] = 0;
-
-       /* Only deal with supported flags */
-       changed_flags &= SUPPORTED_FIF_FLAGS;
-       *new_flags &= SUPPORTED_FIF_FLAGS;
-
-       /* If HW detects any phy or radar errors, leave those filters on.
-        * Also, always enable Unicast, Broadcasts and Multicast
-        * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
-       rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
-               (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
-               AR5K_RX_FILTER_MCAST);
-
-       if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
-               if (*new_flags & FIF_PROMISC_IN_BSS) {
-                       rfilt |= AR5K_RX_FILTER_PROM;
-                       __set_bit(ATH_STAT_PROMISC, sc->status);
-               } else {
-                       __clear_bit(ATH_STAT_PROMISC, sc->status);
-               }
-       }
-
-       /* Note, AR5K_RX_FILTER_MCAST is already enabled */
-       if (*new_flags & FIF_ALLMULTI) {
-               mfilt[0] =  ~0;
-               mfilt[1] =  ~0;
-       } else {
-               for (i = 0; i < mc_count; i++) {
-                       if (!mclist)
-                               break;
-                       /* calculate XOR of eight 6-bit values */
-                       val = get_unaligned_le32(mclist->dmi_addr + 0);
-                       pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
-                       val = get_unaligned_le32(mclist->dmi_addr + 3);
-                       pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
-                       pos &= 0x3f;
-                       mfilt[pos / 32] |= (1 << (pos % 32));
-                       /* XXX: we might be able to just do this instead,
-                       * but not sure, needs testing, if we do use this we'd
-                       * neet to inform below to not reset the mcast */
-                       /* ath5k_hw_set_mcast_filterindex(ah,
-                        *      mclist->dmi_addr[5]); */
-                       mclist = mclist->next;
-               }
-       }
-
-       /* This is the best we can do */
-       if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
-               rfilt |= AR5K_RX_FILTER_PHYERR;
-
-       /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
-       * and probes for any BSSID, this needs testing */
-       if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
-               rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ;
-
-       /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
-        * set we should only pass on control frames for this
-        * station. This needs testing. I believe right now this
-        * enables *all* control frames, which is OK.. but
-        * but we should see if we can improve on granularity */
-       if (*new_flags & FIF_CONTROL)
-               rfilt |= AR5K_RX_FILTER_CONTROL;
-
-       /* Additional settings per mode -- this is per ath5k */
-
-       /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
-
-       if (sc->opmode == NL80211_IFTYPE_MONITOR)
-               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
-                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
-       if (sc->opmode != NL80211_IFTYPE_STATION)
-               rfilt |= AR5K_RX_FILTER_PROBEREQ;
-       if (sc->opmode != NL80211_IFTYPE_AP &&
-               sc->opmode != NL80211_IFTYPE_MESH_POINT &&
-               test_bit(ATH_STAT_PROMISC, sc->status))
-               rfilt |= AR5K_RX_FILTER_PROM;
-       if ((sc->opmode == NL80211_IFTYPE_STATION && sc->assoc) ||
-               sc->opmode == NL80211_IFTYPE_ADHOC ||
-               sc->opmode == NL80211_IFTYPE_AP)
-               rfilt |= AR5K_RX_FILTER_BEACON;
-       if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
-               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
-                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
-
-       /* Set filters */
-       ath5k_hw_set_rx_filter(ah, rfilt);
-
-       /* Set multicast bits */
-       ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
-       /* Set the cached hw filter flags, this will alter actually
-        * be set in HW */
-       sc->filter_flags = rfilt;
-}
-
-static int
-ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-             struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-             struct ieee80211_key_conf *key)
-{
-       struct ath5k_softc *sc = hw->priv;
-       int ret = 0;
-
-       if (modparam_nohwcrypt)
-               return -EOPNOTSUPP;
-
-       switch (key->alg) {
-       case ALG_WEP:
-       case ALG_TKIP:
-               break;
-       case ALG_CCMP:
-               return -EOPNOTSUPP;
-       default:
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       mutex_lock(&sc->lock);
-
-       switch (cmd) {
-       case SET_KEY:
-               ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
-                                      sta ? sta->addr : NULL);
-               if (ret) {
-                       ATH5K_ERR(sc, "can't set the key\n");
-                       goto unlock;
-               }
-               __set_bit(key->keyidx, sc->keymap);
-               key->hw_key_idx = key->keyidx;
-               key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
-                              IEEE80211_KEY_FLAG_GENERATE_MMIC);
-               break;
-       case DISABLE_KEY:
-               ath5k_hw_reset_key(sc->ah, key->keyidx);
-               __clear_bit(key->keyidx, sc->keymap);
-               break;
-       default:
-               ret = -EINVAL;
-               goto unlock;
-       }
-
-unlock:
-       mmiowb();
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-static int
-ath5k_get_stats(struct ieee80211_hw *hw,
-               struct ieee80211_low_level_stats *stats)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-
-       /* Force update */
-       ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
-
-       memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats));
-
-       return 0;
-}
-
-static int
-ath5k_get_tx_stats(struct ieee80211_hw *hw,
-               struct ieee80211_tx_queue_stats *stats)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats));
-
-       return 0;
-}
-
-static u64
-ath5k_get_tsf(struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       return ath5k_hw_get_tsf64(sc->ah);
-}
-
-static void
-ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       ath5k_hw_set_tsf64(sc->ah, tsf);
-}
-
-static void
-ath5k_reset_tsf(struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       /*
-        * in IBSS mode we need to update the beacon timers too.
-        * this will also reset the TSF if we call it with 0
-        */
-       if (sc->opmode == NL80211_IFTYPE_ADHOC)
-               ath5k_beacon_update_timers(sc, 0);
-       else
-               ath5k_hw_reset_tsf(sc->ah);
-}
-
-static int
-ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb)
-{
-       unsigned long flags;
-       int ret;
-
-       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
-
-       spin_lock_irqsave(&sc->block, flags);
-       ath5k_txbuf_free(sc, sc->bbuf);
-       sc->bbuf->skb = skb;
-       ret = ath5k_beacon_setup(sc, sc->bbuf);
-       if (ret)
-               sc->bbuf->skb = NULL;
-       spin_unlock_irqrestore(&sc->block, flags);
-       if (!ret) {
-               ath5k_beacon_config(sc);
-               mmiowb();
-       }
-
-       return ret;
-}
-static void
-set_beacon_filter(struct ieee80211_hw *hw, bool enable)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       u32 rfilt;
-       rfilt = ath5k_hw_get_rx_filter(ah);
-       if (enable)
-               rfilt |= AR5K_RX_FILTER_BEACON;
-       else
-               rfilt &= ~AR5K_RX_FILTER_BEACON;
-       ath5k_hw_set_rx_filter(ah, rfilt);
-       sc->filter_flags = rfilt;
-}
-
-static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
-                                   struct ieee80211_vif *vif,
-                                   struct ieee80211_bss_conf *bss_conf,
-                                   u32 changes)
-{
-       struct ath5k_softc *sc = hw->priv;
-       if (changes & BSS_CHANGED_ASSOC) {
-               mutex_lock(&sc->lock);
-               sc->assoc = bss_conf->assoc;
-               if (sc->opmode == NL80211_IFTYPE_STATION)
-                       set_beacon_filter(hw, sc->assoc);
-               mutex_unlock(&sc->lock);
-       }
-}
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
deleted file mode 100644 (file)
index 8229561..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*-
- * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- *
- */
-
-/*
- * Defintions for the Atheros Wireless LAN controller driver.
- */
-#ifndef _DEV_ATH_ATHVAR_H
-#define _DEV_ATH_ATHVAR_H
-
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/wireless.h>
-#include <linux/if_ether.h>
-#include <linux/leds.h>
-
-#include "ath5k.h"
-#include "debug.h"
-
-#define        ATH_RXBUF       40              /* number of RX buffers */
-#define        ATH_TXBUF       200             /* number of TX buffers */
-#define ATH_BCBUF      1               /* number of beacon buffers */
-
-struct ath5k_buf {
-       struct list_head        list;
-       unsigned int            flags;  /* rx descriptor flags */
-       struct ath5k_desc       *desc;  /* virtual addr of desc */
-       dma_addr_t              daddr;  /* physical addr of desc */
-       struct sk_buff          *skb;   /* skbuff for buf */
-       dma_addr_t              skbaddr;/* physical addr of skb data */
-};
-
-/*
- * 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 ath5k_txq {
-       unsigned int            qnum;   /* hardware q number */
-       u32                     *link;  /* link ptr in last TX desc */
-       struct list_head        q;      /* transmit queue */
-       spinlock_t              lock;   /* lock on q and link */
-       bool                    setup;
-};
-
-#define ATH5K_LED_MAX_NAME_LEN 31
-
-/*
- * State for LED triggers
- */
-struct ath5k_led
-{
-       char name[ATH5K_LED_MAX_NAME_LEN + 1];  /* name of the LED in sysfs */
-       struct ath5k_softc *sc;                 /* driver state */
-       struct led_classdev led_dev;            /* led classdev */
-};
-
-
-#if CHAN_DEBUG
-#define ATH_CHAN_MAX   (26+26+26+200+200)
-#else
-#define ATH_CHAN_MAX   (14+14+14+252+20)
-#endif
-
-/* Software Carrier, keeps track of the driver state
- * associated with an instance of a device */
-struct ath5k_softc {
-       struct pci_dev          *pdev;          /* for dma mapping */
-       void __iomem            *iobase;        /* address of the device */
-       struct mutex            lock;           /* dev-level lock */
-       /* FIXME: how many does it really need? */
-       struct ieee80211_tx_queue_stats tx_stats[16];
-       struct ieee80211_low_level_stats ll_stats;
-       struct ieee80211_hw     *hw;            /* IEEE 802.11 common */
-       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
-       struct ieee80211_channel channels[ATH_CHAN_MAX];
-       struct ieee80211_rate   rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
-       s8                      rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
-       enum nl80211_iftype     opmode;
-       struct ath5k_hw         *ah;            /* Atheros HW */
-
-       struct ieee80211_supported_band         *curband;
-
-#ifdef CONFIG_ATH5K_DEBUG
-       struct ath5k_dbg_info   debug;          /* debug info */
-#endif /* CONFIG_ATH5K_DEBUG */
-
-       struct ath5k_buf        *bufptr;        /* allocated buffer ptr */
-       struct ath5k_desc       *desc;          /* TX/RX descriptors */
-       dma_addr_t              desc_daddr;     /* DMA (physical) address */
-       size_t                  desc_len;       /* size of TX/RX descriptors */
-       u16                     cachelsz;       /* cache line size */
-
-       DECLARE_BITMAP(status, 5);
-#define ATH_STAT_INVALID       0               /* disable hardware accesses */
-#define ATH_STAT_MRRETRY       1               /* multi-rate retry support */
-#define ATH_STAT_PROMISC       2
-#define ATH_STAT_LEDSOFT       3               /* enable LED gpio status */
-#define ATH_STAT_STARTED       4               /* opened & irqs enabled */
-
-       unsigned int            filter_flags;   /* HW flags, AR5K_RX_FILTER_* */
-       unsigned int            curmode;        /* current phy mode */
-       struct ieee80211_channel *curchan;      /* current h/w channel */
-
-       struct ieee80211_vif *vif;
-
-       enum ath5k_int          imask;          /* interrupt mask copy */
-
-       DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
-
-       u8                      bssidmask[ETH_ALEN];
-
-       unsigned int            led_pin,        /* GPIO pin for driving LED */
-                               led_on;         /* pin setting for LED on */
-
-       struct tasklet_struct   restq;          /* reset tasklet */
-
-       unsigned int            rxbufsize;      /* rx size based on mtu */
-       struct list_head        rxbuf;          /* receive buffer */
-       spinlock_t              rxbuflock;
-       u32                     *rxlink;        /* link ptr in last RX desc */
-       struct tasklet_struct   rxtq;           /* rx intr tasklet */
-       struct ath5k_led        rx_led;         /* rx led */
-
-       struct list_head        txbuf;          /* transmit buffer */
-       spinlock_t              txbuflock;
-       unsigned int            txbuf_len;      /* buf count in txbuf list */
-       struct ath5k_txq        txqs[2];        /* beacon and tx */
-
-       struct ath5k_txq        *txq;           /* beacon and tx*/
-       struct tasklet_struct   txtq;           /* tx intr tasklet */
-       struct ath5k_led        tx_led;         /* tx led */
-
-       spinlock_t              block;          /* protects beacon */
-       struct tasklet_struct   beacontq;       /* beacon intr tasklet */
-       struct ath5k_buf        *bbuf;          /* beacon buffer */
-       unsigned int            bhalq,          /* SW q for outgoing beacons */
-                               bmisscount,     /* missed beacon transmits */
-                               bintval,        /* beacon interval in TU */
-                               bsent;
-       unsigned int            nexttbtt;       /* next beacon time in TU */
-
-       struct timer_list       calib_tim;      /* calibration timer */
-       int                     power_level;    /* Requested tx power in dbm */
-       bool                    assoc;          /* assocate state */
-};
-
-#define ath5k_hw_hasbssidmask(_ah) \
-       (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0)
-#define ath5k_hw_hasveol(_ah) \
-       (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
-
-#endif
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath5k/caps.c
deleted file mode 100644 (file)
index 367a6c7..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/**************\
-* Capabilities *
-\**************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Fill the capabilities struct
- * TODO: Merge this with EEPROM code when we are done with it
- */
-int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
-{
-       u16 ee_header;
-
-       ATH5K_TRACE(ah->ah_sc);
-       /* Capabilities stored in the EEPROM */
-       ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
-
-       if (ah->ah_version == AR5K_AR5210) {
-               /*
-                * Set radio capabilities
-                * (The AR5110 only supports the middle 5GHz band)
-                */
-               ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
-               ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
-               ah->ah_capabilities.cap_range.range_2ghz_min = 0;
-               ah->ah_capabilities.cap_range.range_2ghz_max = 0;
-
-               /* Set supported modes */
-               __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
-               __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
-       } else {
-               /*
-                * XXX The tranceiver supports frequencies from 4920 to 6100GHz
-                * XXX and from 2312 to 2732GHz. There are problems with the
-                * XXX current ieee80211 implementation because the IEEE
-                * XXX channel mapping does not support negative channel
-                * XXX numbers (2312MHz is channel -19). Of course, this
-                * XXX doesn't matter because these channels are out of range
-                * XXX but some regulation domains like MKK (Japan) will
-                * XXX support frequencies somewhere around 4.8GHz.
-                */
-
-               /*
-                * Set radio capabilities
-                */
-
-               if (AR5K_EEPROM_HDR_11A(ee_header)) {
-                       /* 4920 */
-                       ah->ah_capabilities.cap_range.range_5ghz_min = 5005;
-                       ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
-
-                       /* Set supported modes */
-                       __set_bit(AR5K_MODE_11A,
-                                       ah->ah_capabilities.cap_mode);
-                       __set_bit(AR5K_MODE_11A_TURBO,
-                                       ah->ah_capabilities.cap_mode);
-                       if (ah->ah_version == AR5K_AR5212)
-                               __set_bit(AR5K_MODE_11G_TURBO,
-                                               ah->ah_capabilities.cap_mode);
-               }
-
-               /* Enable  802.11b if a 2GHz capable radio (2111/5112) is
-                * connected */
-               if (AR5K_EEPROM_HDR_11B(ee_header) ||
-                   (AR5K_EEPROM_HDR_11G(ee_header) &&
-                    ah->ah_version != AR5K_AR5211)) {
-                       /* 2312 */
-                       ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
-                       ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
-
-                       if (AR5K_EEPROM_HDR_11B(ee_header))
-                               __set_bit(AR5K_MODE_11B,
-                                               ah->ah_capabilities.cap_mode);
-
-                       if (AR5K_EEPROM_HDR_11G(ee_header) &&
-                           ah->ah_version != AR5K_AR5211)
-                               __set_bit(AR5K_MODE_11G,
-                                               ah->ah_capabilities.cap_mode);
-               }
-       }
-
-       /* GPIO */
-       ah->ah_gpio_npins = AR5K_NUM_GPIO;
-
-       /* Set number of supported TX queues */
-       if (ah->ah_version == AR5K_AR5210)
-               ah->ah_capabilities.cap_queues.q_tx_num =
-                       AR5K_NUM_TX_QUEUES_NOQCU;
-       else
-               ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
-
-       return 0;
-}
-
-/* Main function used by the driver part to check caps */
-int ath5k_hw_get_capability(struct ath5k_hw *ah,
-               enum ath5k_capability_type cap_type,
-               u32 capability, u32 *result)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       switch (cap_type) {
-       case AR5K_CAP_NUM_TXQUEUES:
-               if (result) {
-                       if (ah->ah_version == AR5K_AR5210)
-                               *result = AR5K_NUM_TX_QUEUES_NOQCU;
-                       else
-                               *result = AR5K_NUM_TX_QUEUES;
-                       goto yes;
-               }
-       case AR5K_CAP_VEOL:
-               goto yes;
-       case AR5K_CAP_COMPRESSION:
-               if (ah->ah_version == AR5K_AR5212)
-                       goto yes;
-               else
-                       goto no;
-       case AR5K_CAP_BURST:
-               goto yes;
-       case AR5K_CAP_TPC:
-               goto yes;
-       case AR5K_CAP_BSSIDMASK:
-               if (ah->ah_version == AR5K_AR5212)
-                       goto yes;
-               else
-                       goto no;
-       case AR5K_CAP_XR:
-               if (ah->ah_version == AR5K_AR5212)
-                       goto yes;
-               else
-                       goto no;
-       default:
-               goto no;
-       }
-
-no:
-       return -EINVAL;
-yes:
-       return 0;
-}
-
-/*
- * TODO: Following functions should be part of a new function
- * set_capability
- */
-
-int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
-               u16 assoc_id)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (ah->ah_version == AR5K_AR5210) {
-               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
-                       AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
-               return 0;
-       }
-
-       return -EIO;
-}
-
-int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (ah->ah_version == AR5K_AR5210) {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
-                       AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
-               return 0;
-       }
-
-       return -EIO;
-}
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
deleted file mode 100644 (file)
index 9770bb3..0000000
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
- *
- *  This file is free software: you may copy, redistribute and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation, either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  This file is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * Copyright (c) 2004-2005 Atheros Communications, Inc.
- * Copyright (c) 2006 Devicescape Software, Inc.
- * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- */
-
-#include "base.h"
-#include "debug.h"
-
-static unsigned int ath5k_debug;
-module_param_named(debug, ath5k_debug, uint, 0);
-
-
-#ifdef CONFIG_ATH5K_DEBUG
-
-#include <linux/seq_file.h>
-#include "reg.h"
-
-static struct dentry *ath5k_global_debugfs;
-
-static int ath5k_debugfs_open(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-
-/* debugfs: registers */
-
-struct reg {
-       const char *name;
-       int addr;
-};
-
-#define REG_STRUCT_INIT(r) { #r, r }
-
-/* just a few random registers, might want to add more */
-static const struct reg regs[] = {
-       REG_STRUCT_INIT(AR5K_CR),
-       REG_STRUCT_INIT(AR5K_RXDP),
-       REG_STRUCT_INIT(AR5K_CFG),
-       REG_STRUCT_INIT(AR5K_IER),
-       REG_STRUCT_INIT(AR5K_BCR),
-       REG_STRUCT_INIT(AR5K_RTSD0),
-       REG_STRUCT_INIT(AR5K_RTSD1),
-       REG_STRUCT_INIT(AR5K_TXCFG),
-       REG_STRUCT_INIT(AR5K_RXCFG),
-       REG_STRUCT_INIT(AR5K_RXJLA),
-       REG_STRUCT_INIT(AR5K_MIBC),
-       REG_STRUCT_INIT(AR5K_TOPS),
-       REG_STRUCT_INIT(AR5K_RXNOFRM),
-       REG_STRUCT_INIT(AR5K_TXNOFRM),
-       REG_STRUCT_INIT(AR5K_RPGTO),
-       REG_STRUCT_INIT(AR5K_RFCNT),
-       REG_STRUCT_INIT(AR5K_MISC),
-       REG_STRUCT_INIT(AR5K_QCUDCU_CLKGT),
-       REG_STRUCT_INIT(AR5K_ISR),
-       REG_STRUCT_INIT(AR5K_PISR),
-       REG_STRUCT_INIT(AR5K_SISR0),
-       REG_STRUCT_INIT(AR5K_SISR1),
-       REG_STRUCT_INIT(AR5K_SISR2),
-       REG_STRUCT_INIT(AR5K_SISR3),
-       REG_STRUCT_INIT(AR5K_SISR4),
-       REG_STRUCT_INIT(AR5K_IMR),
-       REG_STRUCT_INIT(AR5K_PIMR),
-       REG_STRUCT_INIT(AR5K_SIMR0),
-       REG_STRUCT_INIT(AR5K_SIMR1),
-       REG_STRUCT_INIT(AR5K_SIMR2),
-       REG_STRUCT_INIT(AR5K_SIMR3),
-       REG_STRUCT_INIT(AR5K_SIMR4),
-       REG_STRUCT_INIT(AR5K_DCM_ADDR),
-       REG_STRUCT_INIT(AR5K_DCCFG),
-       REG_STRUCT_INIT(AR5K_CCFG),
-       REG_STRUCT_INIT(AR5K_CPC0),
-       REG_STRUCT_INIT(AR5K_CPC1),
-       REG_STRUCT_INIT(AR5K_CPC2),
-       REG_STRUCT_INIT(AR5K_CPC3),
-       REG_STRUCT_INIT(AR5K_CPCOVF),
-       REG_STRUCT_INIT(AR5K_RESET_CTL),
-       REG_STRUCT_INIT(AR5K_SLEEP_CTL),
-       REG_STRUCT_INIT(AR5K_INTPEND),
-       REG_STRUCT_INIT(AR5K_SFR),
-       REG_STRUCT_INIT(AR5K_PCICFG),
-       REG_STRUCT_INIT(AR5K_GPIOCR),
-       REG_STRUCT_INIT(AR5K_GPIODO),
-       REG_STRUCT_INIT(AR5K_SREV),
-};
-
-static void *reg_start(struct seq_file *seq, loff_t *pos)
-{
-       return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
-}
-
-static void reg_stop(struct seq_file *seq, void *p)
-{
-       /* nothing to do */
-}
-
-static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
-{
-       ++*pos;
-       return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
-}
-
-static int reg_show(struct seq_file *seq, void *p)
-{
-       struct ath5k_softc *sc = seq->private;
-       struct reg *r = p;
-       seq_printf(seq, "%-25s0x%08x\n", r->name,
-               ath5k_hw_reg_read(sc->ah, r->addr));
-       return 0;
-}
-
-static const struct seq_operations register_seq_ops = {
-       .start = reg_start,
-       .next  = reg_next,
-       .stop  = reg_stop,
-       .show  = reg_show
-};
-
-static int open_file_registers(struct inode *inode, struct file *file)
-{
-       struct seq_file *s;
-       int res;
-       res = seq_open(file, &register_seq_ops);
-       if (res == 0) {
-               s = file->private_data;
-               s->private = inode->i_private;
-       }
-       return res;
-}
-
-static const struct file_operations fops_registers = {
-       .open = open_file_registers,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .release = seq_release,
-       .owner = THIS_MODULE,
-};
-
-
-/* debugfs: beacons */
-
-static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       struct ath5k_hw *ah = sc->ah;
-       char buf[500];
-       unsigned int len = 0;
-       unsigned int v;
-       u64 tsf;
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON);
-       len += snprintf(buf+len, sizeof(buf)-len,
-               "%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
-               "AR5K_BEACON", v, v & AR5K_BEACON_PERIOD,
-               (v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S);
-
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n",
-               "AR5K_LAST_TSTP", ath5k_hw_reg_read(sc->ah, AR5K_LAST_TSTP));
-
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n\n",
-               "AR5K_BEACON_CNT", ath5k_hw_reg_read(sc->ah, AR5K_BEACON_CNT));
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER0);
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
-               "AR5K_TIMER0 (TBTT)", v, v);
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER1);
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
-               "AR5K_TIMER1 (DMA)", v, v >> 3);
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER2);
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
-               "AR5K_TIMER2 (SWBA)", v, v >> 3);
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER3);
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
-               "AR5K_TIMER3 (ATIM)", v, v);
-
-       tsf = ath5k_hw_get_tsf64(sc->ah);
-       len += snprintf(buf+len, sizeof(buf)-len,
-               "TSF\t\t0x%016llx\tTU: %08x\n",
-               (unsigned long long)tsf, TSF_TO_TU(tsf));
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t write_file_beacon(struct file *file,
-                                const char __user *userbuf,
-                                size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       struct ath5k_hw *ah = sc->ah;
-       char buf[20];
-
-       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
-               return -EFAULT;
-
-       if (strncmp(buf, "disable", 7) == 0) {
-               AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
-               printk(KERN_INFO "debugfs disable beacons\n");
-       } else if (strncmp(buf, "enable", 6) == 0) {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
-               printk(KERN_INFO "debugfs enable beacons\n");
-       }
-       return count;
-}
-
-static const struct file_operations fops_beacon = {
-       .read = read_file_beacon,
-       .write = write_file_beacon,
-       .open = ath5k_debugfs_open,
-       .owner = THIS_MODULE,
-};
-
-
-/* debugfs: reset */
-
-static ssize_t write_file_reset(struct file *file,
-                                const char __user *userbuf,
-                                size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       tasklet_schedule(&sc->restq);
-       return count;
-}
-
-static const struct file_operations fops_reset = {
-       .write = write_file_reset,
-       .open = ath5k_debugfs_open,
-       .owner = THIS_MODULE,
-};
-
-
-/* debugfs: debug level */
-
-static const struct {
-       enum ath5k_debug_level level;
-       const char *name;
-       const char *desc;
-} dbg_info[] = {
-       { ATH5K_DEBUG_RESET,    "reset",        "reset and initialization" },
-       { ATH5K_DEBUG_INTR,     "intr",         "interrupt handling" },
-       { ATH5K_DEBUG_MODE,     "mode",         "mode init/setup" },
-       { ATH5K_DEBUG_XMIT,     "xmit",         "basic xmit operation" },
-       { ATH5K_DEBUG_BEACON,   "beacon",       "beacon handling" },
-       { ATH5K_DEBUG_CALIBRATE, "calib",       "periodic calibration" },
-       { ATH5K_DEBUG_TXPOWER,  "txpower",      "transmit power setting" },
-       { ATH5K_DEBUG_LED,      "led",          "LED management" },
-       { ATH5K_DEBUG_DUMP_RX,  "dumprx",       "print received skb content" },
-       { ATH5K_DEBUG_DUMP_TX,  "dumptx",       "print transmit skb content" },
-       { ATH5K_DEBUG_DUMPBANDS, "dumpbands",   "dump bands" },
-       { ATH5K_DEBUG_TRACE,    "trace",        "trace function calls" },
-       { ATH5K_DEBUG_ANY,      "all",          "show all debug levels" },
-};
-
-static ssize_t read_file_debug(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       char buf[700];
-       unsigned int len = 0;
-       unsigned int i;
-
-       len += snprintf(buf+len, sizeof(buf)-len,
-               "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
-
-       for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
-               len += snprintf(buf+len, sizeof(buf)-len,
-                       "%10s %c 0x%08x - %s\n", dbg_info[i].name,
-                       sc->debug.level & dbg_info[i].level ? '+' : ' ',
-                       dbg_info[i].level, dbg_info[i].desc);
-       }
-       len += snprintf(buf+len, sizeof(buf)-len,
-               "%10s %c 0x%08x - %s\n", dbg_info[i].name,
-               sc->debug.level == dbg_info[i].level ? '+' : ' ',
-               dbg_info[i].level, dbg_info[i].desc);
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t write_file_debug(struct file *file,
-                                const char __user *userbuf,
-                                size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       unsigned int i;
-       char buf[20];
-
-       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
-               return -EFAULT;
-
-       for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
-               if (strncmp(buf, dbg_info[i].name,
-                                       strlen(dbg_info[i].name)) == 0) {
-                       sc->debug.level ^= dbg_info[i].level; /* toggle bit */
-                       break;
-               }
-       }
-       return count;
-}
-
-static const struct file_operations fops_debug = {
-       .read = read_file_debug,
-       .write = write_file_debug,
-       .open = ath5k_debugfs_open,
-       .owner = THIS_MODULE,
-};
-
-
-/* init */
-
-void
-ath5k_debug_init(void)
-{
-       ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
-}
-
-void
-ath5k_debug_init_device(struct ath5k_softc *sc)
-{
-       sc->debug.level = ath5k_debug;
-
-       sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
-                               ath5k_global_debugfs);
-
-       sc->debug.debugfs_debug = debugfs_create_file("debug", S_IWUSR | S_IRUGO,
-                               sc->debug.debugfs_phydir, sc, &fops_debug);
-
-       sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO,
-                               sc->debug.debugfs_phydir, sc, &fops_registers);
-
-       sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO,
-                               sc->debug.debugfs_phydir, sc, &fops_beacon);
-
-       sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
-                               sc->debug.debugfs_phydir, sc, &fops_reset);
-}
-
-void
-ath5k_debug_finish(void)
-{
-       debugfs_remove(ath5k_global_debugfs);
-}
-
-void
-ath5k_debug_finish_device(struct ath5k_softc *sc)
-{
-       debugfs_remove(sc->debug.debugfs_debug);
-       debugfs_remove(sc->debug.debugfs_registers);
-       debugfs_remove(sc->debug.debugfs_beacon);
-       debugfs_remove(sc->debug.debugfs_reset);
-       debugfs_remove(sc->debug.debugfs_phydir);
-}
-
-
-/* functions used in other places */
-
-void
-ath5k_debug_dump_bands(struct ath5k_softc *sc)
-{
-       unsigned int b, i;
-
-       if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPBANDS)))
-               return;
-
-       BUG_ON(!sc->sbands);
-
-       for (b = 0; b < IEEE80211_NUM_BANDS; b++) {
-               struct ieee80211_supported_band *band = &sc->sbands[b];
-               char bname[5];
-               switch (band->band) {
-               case IEEE80211_BAND_2GHZ:
-                       strcpy(bname, "2 GHz");
-                       break;
-               case IEEE80211_BAND_5GHZ:
-                       strcpy(bname, "5 GHz");
-                       break;
-               default:
-                       printk(KERN_DEBUG "Band not supported: %d\n",
-                               band->band);
-                       return;
-               }
-               printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname,
-                               band->n_channels, band->n_bitrates);
-               printk(KERN_DEBUG " channels:\n");
-               for (i = 0; i < band->n_channels; i++)
-                       printk(KERN_DEBUG "  %3d %d %.4x %.4x\n",
-                                       ieee80211_frequency_to_channel(
-                                               band->channels[i].center_freq),
-                                       band->channels[i].center_freq,
-                                       band->channels[i].hw_value,
-                                       band->channels[i].flags);
-               printk(KERN_DEBUG " rates:\n");
-               for (i = 0; i < band->n_bitrates; i++)
-                       printk(KERN_DEBUG "  %4d %.4x %.4x %.4x\n",
-                                       band->bitrates[i].bitrate,
-                                       band->bitrates[i].hw_value,
-                                       band->bitrates[i].flags,
-                                       band->bitrates[i].hw_value_short);
-       }
-}
-
-static inline void
-ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
-                      struct ath5k_rx_status *rs)
-{
-       struct ath5k_desc *ds = bf->desc;
-       struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx;
-
-       printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n",
-               ds, (unsigned long long)bf->daddr,
-               ds->ds_link, ds->ds_data,
-               rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1,
-               rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0,
-               !done ? ' ' : (rs->rs_status == 0) ? '*' : '!');
-}
-
-void
-ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
-{
-       struct ath5k_desc *ds;
-       struct ath5k_buf *bf;
-       struct ath5k_rx_status rs = {};
-       int status;
-
-       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
-               return;
-
-       printk(KERN_DEBUG "rx queue %x, link %p\n",
-               ath5k_hw_get_rxdp(ah), sc->rxlink);
-
-       spin_lock_bh(&sc->rxbuflock);
-       list_for_each_entry(bf, &sc->rxbuf, list) {
-               ds = bf->desc;
-               status = ah->ah_proc_rx_desc(ah, ds, &rs);
-               if (!status)
-                       ath5k_debug_printrxbuf(bf, status == 0, &rs);
-       }
-       spin_unlock_bh(&sc->rxbuflock);
-}
-
-void
-ath5k_debug_dump_skb(struct ath5k_softc *sc,
-                       struct sk_buff *skb, const char *prefix, int tx)
-{
-       char buf[16];
-
-       if (likely(!((tx && (sc->debug.level & ATH5K_DEBUG_DUMP_TX)) ||
-                    (!tx && (sc->debug.level & ATH5K_DEBUG_DUMP_RX)))))
-               return;
-
-       snprintf(buf, sizeof(buf), "%s %s", wiphy_name(sc->hw->wiphy), prefix);
-
-       print_hex_dump_bytes(buf, DUMP_PREFIX_NONE, skb->data,
-               min(200U, skb->len));
-
-       printk(KERN_DEBUG "\n");
-}
-
-void
-ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
-{
-       struct ath5k_desc *ds = bf->desc;
-       struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212;
-       struct ath5k_tx_status ts = {};
-       int done;
-
-       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
-               return;
-
-       done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
-
-       printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
-               "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
-               ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1,
-               td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3,
-               td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
-               done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
-}
-
-#endif /* ifdef CONFIG_ATH5K_DEBUG */
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
deleted file mode 100644 (file)
index 66f69f0..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com>
- *
- *  This file is free software: you may copy, redistribute and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation, either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  This file is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * Copyright (c) 2004-2005 Atheros Communications, Inc.
- * Copyright (c) 2006 Devicescape Software, Inc.
- * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- */
-
-#ifndef _ATH5K_DEBUG_H
-#define _ATH5K_DEBUG_H
-
-struct ath5k_softc;
-struct ath5k_hw;
-struct sk_buff;
-struct ath5k_buf;
-
-struct ath5k_dbg_info {
-       unsigned int            level;          /* debug level */
-       /* debugfs entries */
-       struct dentry           *debugfs_phydir;
-       struct dentry           *debugfs_debug;
-       struct dentry           *debugfs_registers;
-       struct dentry           *debugfs_beacon;
-       struct dentry           *debugfs_reset;
-};
-
-/**
- * enum ath5k_debug_level - ath5k debug level
- *
- * @ATH5K_DEBUG_RESET: reset processing
- * @ATH5K_DEBUG_INTR: interrupt handling
- * @ATH5K_DEBUG_MODE: mode init/setup
- * @ATH5K_DEBUG_XMIT: basic xmit operation
- * @ATH5K_DEBUG_BEACON: beacon handling
- * @ATH5K_DEBUG_CALIBRATE: periodic calibration
- * @ATH5K_DEBUG_TXPOWER: transmit power setting
- * @ATH5K_DEBUG_LED: led management
- * @ATH5K_DEBUG_DUMP_RX: print received skb content
- * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
- * @ATH5K_DEBUG_DUMPBANDS: dump bands
- * @ATH5K_DEBUG_TRACE: trace function calls
- * @ATH5K_DEBUG_ANY: show at any debug level
- *
- * The debug level is used to control the amount and type of debugging output
- * we want to see. The debug level is given in calls to ATH5K_DBG to specify
- * where the message should appear, and the user can control the debugging
- * messages he wants to see, either by the module parameter 'debug' on module
- * load, or dynamically by using debugfs 'ath5k/phyX/debug'. these levels can
- * be combined together by bitwise OR.
- */
-enum ath5k_debug_level {
-       ATH5K_DEBUG_RESET       = 0x00000001,
-       ATH5K_DEBUG_INTR        = 0x00000002,
-       ATH5K_DEBUG_MODE        = 0x00000004,
-       ATH5K_DEBUG_XMIT        = 0x00000008,
-       ATH5K_DEBUG_BEACON      = 0x00000010,
-       ATH5K_DEBUG_CALIBRATE   = 0x00000020,
-       ATH5K_DEBUG_TXPOWER     = 0x00000040,
-       ATH5K_DEBUG_LED         = 0x00000080,
-       ATH5K_DEBUG_DUMP_RX     = 0x00000100,
-       ATH5K_DEBUG_DUMP_TX     = 0x00000200,
-       ATH5K_DEBUG_DUMPBANDS   = 0x00000400,
-       ATH5K_DEBUG_TRACE       = 0x00001000,
-       ATH5K_DEBUG_ANY         = 0xffffffff
-};
-
-#ifdef CONFIG_ATH5K_DEBUG
-
-#define ATH5K_TRACE(_sc) do { \
-       if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \
-               printk(KERN_DEBUG "ath5k trace %s:%d\n", __func__, __LINE__); \
-       } while (0)
-
-#define ATH5K_DBG(_sc, _m, _fmt, ...) do { \
-       if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \
-               ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
-                       __func__, __LINE__, ##__VA_ARGS__); \
-       } while (0)
-
-#define ATH5K_DBG_UNLIMIT(_sc, _m, _fmt, ...) do { \
-       if (unlikely((_sc)->debug.level & (_m))) \
-               ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
-                       __func__, __LINE__, ##__VA_ARGS__); \
-       } while (0)
-
-void
-ath5k_debug_init(void);
-
-void
-ath5k_debug_init_device(struct ath5k_softc *sc);
-
-void
-ath5k_debug_finish(void);
-
-void
-ath5k_debug_finish_device(struct ath5k_softc *sc);
-
-void
-ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
-
-void
-ath5k_debug_dump_bands(struct ath5k_softc *sc);
-
-void
-ath5k_debug_dump_skb(struct ath5k_softc *sc,
-                       struct sk_buff *skb, const char *prefix, int tx);
-
-void
-ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
-
-#else /* no debugging */
-
-#include <linux/compiler.h>
-
-#define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc))
-
-static inline void __attribute__ ((format (printf, 3, 4)))
-ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {}
-
-static inline void __attribute__ ((format (printf, 3, 4)))
-ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
-{}
-
-static inline void
-ath5k_debug_init(void) {}
-
-static inline void
-ath5k_debug_init_device(struct ath5k_softc *sc) {}
-
-static inline void
-ath5k_debug_finish(void) {}
-
-static inline void
-ath5k_debug_finish_device(struct ath5k_softc *sc) {}
-
-static inline void
-ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
-
-static inline void
-ath5k_debug_dump_bands(struct ath5k_softc *sc) {}
-
-static inline void
-ath5k_debug_dump_skb(struct ath5k_softc *sc,
-                       struct sk_buff *skb, const char *prefix, int tx) {}
-
-static inline void
-ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {}
-
-#endif /* ifdef CONFIG_ATH5K_DEBUG */
-
-#endif /* ifndef _ATH5K_DEBUG_H */
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c
deleted file mode 100644 (file)
index dc30a2b..0000000
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/******************************\
- Hardware Descriptor Functions
-\******************************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * TX Descriptors
- */
-
-/*
- * Initialize the 2-word tx control descriptor on 5210/5211
- */
-static int
-ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
-       unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
-       unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
-       unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
-       unsigned int rtscts_rate, unsigned int rtscts_duration)
-{
-       u32 frame_type;
-       struct ath5k_hw_2w_tx_ctl *tx_ctl;
-       unsigned int frame_len;
-
-       tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
-
-       /*
-        * Validate input
-        * - Zero retries don't make sense.
-        * - A zero rate will put the HW into a mode where it continously sends
-        *   noise on the channel, so it is important to avoid this.
-        */
-       if (unlikely(tx_tries0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero retries\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       if (unlikely(tx_rate0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero rate\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       /* Clear descriptor */
-       memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
-
-       /* Setup control descriptor */
-
-       /* Verify and set frame length */
-
-       /* remove padding we might have added before */
-       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
-
-       if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
-               return -EINVAL;
-
-       tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
-
-       /* Verify and set buffer length */
-
-       /* NB: beacon's BufLen must be a multiple of 4 bytes */
-       if (type == AR5K_PKT_TYPE_BEACON)
-               pkt_len = roundup(pkt_len, 4);
-
-       if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
-               return -EINVAL;
-
-       tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
-
-       /*
-        * Verify and set header length
-        * XXX: I only found that on 5210 code, does it work on 5211 ?
-        */
-       if (ah->ah_version == AR5K_AR5210) {
-               if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
-                       return -EINVAL;
-               tx_ctl->tx_control_0 |=
-                       AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
-       }
-
-       /*Diferences between 5210-5211*/
-       if (ah->ah_version == AR5K_AR5210) {
-               switch (type) {
-               case AR5K_PKT_TYPE_BEACON:
-               case AR5K_PKT_TYPE_PROBE_RESP:
-                       frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
-               case AR5K_PKT_TYPE_PIFS:
-                       frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
-               default:
-                       frame_type = type /*<< 2 ?*/;
-               }
-
-               tx_ctl->tx_control_0 |=
-               AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
-               AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
-
-       } else {
-               tx_ctl->tx_control_0 |=
-                       AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
-                       AR5K_REG_SM(antenna_mode,
-                               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
-               tx_ctl->tx_control_1 |=
-                       AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
-       }
-#define _TX_FLAGS(_c, _flag)                                   \
-       if (flags & AR5K_TXDESC_##_flag) {                      \
-               tx_ctl->tx_control_##_c |=                      \
-                       AR5K_2W_TX_DESC_CTL##_c##_##_flag;      \
-       }
-
-       _TX_FLAGS(0, CLRDMASK);
-       _TX_FLAGS(0, VEOL);
-       _TX_FLAGS(0, INTREQ);
-       _TX_FLAGS(0, RTSENA);
-       _TX_FLAGS(1, NOACK);
-
-#undef _TX_FLAGS
-
-       /*
-        * WEP crap
-        */
-       if (key_index != AR5K_TXKEYIX_INVALID) {
-               tx_ctl->tx_control_0 |=
-                       AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
-               tx_ctl->tx_control_1 |=
-                       AR5K_REG_SM(key_index,
-                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
-       }
-
-       /*
-        * RTS/CTS Duration [5210 ?]
-        */
-       if ((ah->ah_version == AR5K_AR5210) &&
-                       (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
-               tx_ctl->tx_control_1 |= rtscts_duration &
-                               AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
-
-       return 0;
-}
-
-/*
- * Initialize the 4-word tx control descriptor on 5212
- */
-static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
-       struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
-       enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
-       unsigned int tx_tries0, unsigned int key_index,
-       unsigned int antenna_mode, unsigned int flags,
-       unsigned int rtscts_rate,
-       unsigned int rtscts_duration)
-{
-       struct ath5k_hw_4w_tx_ctl *tx_ctl;
-       unsigned int frame_len;
-
-       ATH5K_TRACE(ah->ah_sc);
-       tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
-
-       /*
-        * Validate input
-        * - Zero retries don't make sense.
-        * - A zero rate will put the HW into a mode where it continously sends
-        *   noise on the channel, so it is important to avoid this.
-        */
-       if (unlikely(tx_tries0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero retries\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       if (unlikely(tx_rate0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero rate\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       tx_power += ah->ah_txpower.txp_offset;
-       if (tx_power > AR5K_TUNE_MAX_TXPOWER)
-               tx_power = AR5K_TUNE_MAX_TXPOWER;
-
-       /* Clear descriptor */
-       memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
-
-       /* Setup control descriptor */
-
-       /* Verify and set frame length */
-
-       /* remove padding we might have added before */
-       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
-
-       if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
-               return -EINVAL;
-
-       tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
-
-       /* Verify and set buffer length */
-
-       /* NB: beacon's BufLen must be a multiple of 4 bytes */
-       if (type == AR5K_PKT_TYPE_BEACON)
-               pkt_len = roundup(pkt_len, 4);
-
-       if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
-               return -EINVAL;
-
-       tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
-
-       tx_ctl->tx_control_0 |=
-               AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
-               AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
-       tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
-                                       AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
-       tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
-                                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
-       tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
-
-#define _TX_FLAGS(_c, _flag)                                   \
-       if (flags & AR5K_TXDESC_##_flag) {                      \
-               tx_ctl->tx_control_##_c |=                      \
-                       AR5K_4W_TX_DESC_CTL##_c##_##_flag;      \
-       }
-
-       _TX_FLAGS(0, CLRDMASK);
-       _TX_FLAGS(0, VEOL);
-       _TX_FLAGS(0, INTREQ);
-       _TX_FLAGS(0, RTSENA);
-       _TX_FLAGS(0, CTSENA);
-       _TX_FLAGS(1, NOACK);
-
-#undef _TX_FLAGS
-
-       /*
-        * WEP crap
-        */
-       if (key_index != AR5K_TXKEYIX_INVALID) {
-               tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
-               tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
-                               AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
-       }
-
-       /*
-        * RTS/CTS
-        */
-       if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
-               if ((flags & AR5K_TXDESC_RTSENA) &&
-                               (flags & AR5K_TXDESC_CTSENA))
-                       return -EINVAL;
-               tx_ctl->tx_control_2 |= rtscts_duration &
-                               AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
-               tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
-                               AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
-       }
-
-       return 0;
-}
-
-/*
- * Initialize a 4-word multi rate retry tx control descriptor on 5212
- */
-static int
-ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
-       unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
-       u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
-{
-       struct ath5k_hw_4w_tx_ctl *tx_ctl;
-
-       /*
-        * Rates can be 0 as long as the retry count is 0 too.
-        * A zero rate and nonzero retry count will put the HW into a mode where
-        * it continously sends noise on the channel, so it is important to
-        * avoid this.
-        */
-       if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
-                    (tx_rate2 == 0 && tx_tries2 != 0) ||
-                    (tx_rate3 == 0 && tx_tries3 != 0))) {
-               ATH5K_ERR(ah->ah_sc, "zero rate\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       if (ah->ah_version == AR5K_AR5212) {
-               tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
-
-#define _XTX_TRIES(_n)                                                 \
-       if (tx_tries##_n) {                                             \
-               tx_ctl->tx_control_2 |=                                 \
-                   AR5K_REG_SM(tx_tries##_n,                           \
-                   AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n);               \
-               tx_ctl->tx_control_3 |=                                 \
-                   AR5K_REG_SM(tx_rate##_n,                            \
-                   AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n);                \
-       }
-
-               _XTX_TRIES(1);
-               _XTX_TRIES(2);
-               _XTX_TRIES(3);
-
-#undef _XTX_TRIES
-
-               return 1;
-       }
-
-       return 0;
-}
-
-/* no mrr support for cards older than 5212 */
-static int
-ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
-       unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
-       u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
-{
-       return 0;
-}
-
-/*
- * Proccess the tx status descriptor on 5210/5211
- */
-static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
-               struct ath5k_desc *desc, struct ath5k_tx_status *ts)
-{
-       struct ath5k_hw_2w_tx_ctl *tx_ctl;
-       struct ath5k_hw_tx_status *tx_status;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
-       tx_status = &desc->ud.ds_tx5210.tx_stat;
-
-       /* No frame has been send or error */
-       if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
-               return -EINPROGRESS;
-
-       /*
-        * Get descriptor status
-        */
-       ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
-       ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
-       ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
-       /*TODO: ts->ts_virtcol + test*/
-       ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
-               AR5K_DESC_TX_STATUS1_SEQ_NUM);
-       ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
-               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
-       ts->ts_antenna = 1;
-       ts->ts_status = 0;
-       ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
-               AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
-       ts->ts_retry[0] = ts->ts_longretry;
-       ts->ts_final_idx = 0;
-
-       if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
-               if (tx_status->tx_status_0 &
-                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
-                       ts->ts_status |= AR5K_TXERR_XRETRY;
-
-               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
-                       ts->ts_status |= AR5K_TXERR_FIFO;
-
-               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
-                       ts->ts_status |= AR5K_TXERR_FILT;
-       }
-
-       return 0;
-}
-
-/*
- * Proccess a tx status descriptor on 5212
- */
-static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
-               struct ath5k_desc *desc, struct ath5k_tx_status *ts)
-{
-       struct ath5k_hw_4w_tx_ctl *tx_ctl;
-       struct ath5k_hw_tx_status *tx_status;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
-       tx_status = &desc->ud.ds_tx5212.tx_stat;
-
-       /* No frame has been send or error */
-       if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE)))
-               return -EINPROGRESS;
-
-       /*
-        * Get descriptor status
-        */
-       ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
-       ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
-       ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
-       ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
-               AR5K_DESC_TX_STATUS1_SEQ_NUM);
-       ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
-               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
-       ts->ts_antenna = (tx_status->tx_status_1 &
-               AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
-       ts->ts_status = 0;
-
-       ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
-                       AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX);
-
-       /* The longretry counter has the number of un-acked retries
-        * for the final rate. To get the total number of retries
-        * we have to add the retry counters for the other rates
-        * as well
-        */
-       ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
-       switch (ts->ts_final_idx) {
-       case 3:
-               ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
-                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
-
-               ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
-                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
-               ts->ts_longretry += ts->ts_retry[2];
-               /* fall through */
-       case 2:
-               ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
-                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
-
-               ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
-                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
-               ts->ts_longretry += ts->ts_retry[1];
-               /* fall through */
-       case 1:
-               ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
-                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
-
-               ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
-                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
-               ts->ts_longretry += ts->ts_retry[0];
-               /* fall through */
-       case 0:
-               ts->ts_rate[0] = tx_ctl->tx_control_3 &
-                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
-               break;
-       }
-
-       /* TX error */
-       if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
-               if (tx_status->tx_status_0 &
-                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
-                       ts->ts_status |= AR5K_TXERR_XRETRY;
-
-               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
-                       ts->ts_status |= AR5K_TXERR_FIFO;
-
-               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
-                       ts->ts_status |= AR5K_TXERR_FILT;
-       }
-
-       return 0;
-}
-
-/*
- * RX Descriptors
- */
-
-/*
- * Initialize an rx control descriptor
- */
-static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
-                       u32 size, unsigned int flags)
-{
-       struct ath5k_hw_rx_ctl *rx_ctl;
-
-       ATH5K_TRACE(ah->ah_sc);
-       rx_ctl = &desc->ud.ds_rx.rx_ctl;
-
-       /*
-        * Clear the descriptor
-        * If we don't clean the status descriptor,
-        * while scanning we get too many results,
-        * most of them virtual, after some secs
-        * of scanning system hangs. M.F.
-       */
-       memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
-
-       /* Setup descriptor */
-       rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
-       if (unlikely(rx_ctl->rx_control_1 != size))
-               return -EINVAL;
-
-       if (flags & AR5K_RXDESC_INTREQ)
-               rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
-
-       return 0;
-}
-
-/*
- * Proccess the rx status descriptor on 5210/5211
- */
-static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
-               struct ath5k_desc *desc, struct ath5k_rx_status *rs)
-{
-       struct ath5k_hw_rx_status *rx_status;
-
-       rx_status = &desc->ud.ds_rx.u.rx_stat;
-
-       /* No frame received / not ready */
-       if (unlikely(!(rx_status->rx_status_1 &
-       AR5K_5210_RX_DESC_STATUS1_DONE)))
-               return -EINPROGRESS;
-
-       /*
-        * Frame receive status
-        */
-       rs->rs_datalen = rx_status->rx_status_0 &
-               AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
-       rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
-       rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
-       rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA);
-       rs->rs_more = !!(rx_status->rx_status_0 &
-               AR5K_5210_RX_DESC_STATUS0_MORE);
-       /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
-       rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
-               AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
-       rs->rs_status = 0;
-       rs->rs_phyerr = 0;
-
-       /*
-        * Key table status
-        */
-       if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
-               rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
-                       AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
-       else
-               rs->rs_keyix = AR5K_RXKEYIX_INVALID;
-
-       /*
-        * Receive/descriptor errors
-        */
-       if (!(rx_status->rx_status_1 &
-       AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
-               if (rx_status->rx_status_1 &
-                               AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_CRC;
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
-                       rs->rs_status |= AR5K_RXERR_FIFO;
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
-                       rs->rs_status |= AR5K_RXERR_PHY;
-                       rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1,
-                               AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
-               }
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_DECRYPT;
-       }
-
-       return 0;
-}
-
-/*
- * Proccess the rx status descriptor on 5212
- */
-static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
-               struct ath5k_desc *desc, struct ath5k_rx_status *rs)
-{
-       struct ath5k_hw_rx_status *rx_status;
-       struct ath5k_hw_rx_error *rx_err;
-
-       ATH5K_TRACE(ah->ah_sc);
-       rx_status = &desc->ud.ds_rx.u.rx_stat;
-
-       /* Overlay on error */
-       rx_err = &desc->ud.ds_rx.u.rx_err;
-
-       /* No frame received / not ready */
-       if (unlikely(!(rx_status->rx_status_1 &
-       AR5K_5212_RX_DESC_STATUS1_DONE)))
-               return -EINPROGRESS;
-
-       /*
-        * Frame receive status
-        */
-       rs->rs_datalen = rx_status->rx_status_0 &
-               AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
-       rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
-       rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
-       rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
-       rs->rs_more = !!(rx_status->rx_status_0 &
-               AR5K_5212_RX_DESC_STATUS0_MORE);
-       rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
-               AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
-       rs->rs_status = 0;
-       rs->rs_phyerr = 0;
-
-       /*
-        * Key table status
-        */
-       if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
-               rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
-                               AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
-       else
-               rs->rs_keyix = AR5K_RXKEYIX_INVALID;
-
-       /*
-        * Receive/descriptor errors
-        */
-       if (!(rx_status->rx_status_1 &
-       AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
-               if (rx_status->rx_status_1 &
-                               AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_CRC;
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
-                       rs->rs_status |= AR5K_RXERR_PHY;
-                       rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
-                                          AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
-               }
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_DECRYPT;
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_MIC;
-       }
-
-       return 0;
-}
-
-/*
- * Init function pointers inside ath5k_hw struct
- */
-int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
-{
-
-       if (ah->ah_version != AR5K_AR5210 &&
-               ah->ah_version != AR5K_AR5211 &&
-               ah->ah_version != AR5K_AR5212)
-                       return -ENOTSUPP;
-
-       /* XXX: What is this magic value and where is it used ? */
-       if (ah->ah_version == AR5K_AR5212)
-               ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
-       else if (ah->ah_version == AR5K_AR5211)
-               ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
-
-       if (ah->ah_version == AR5K_AR5212) {
-               ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
-               ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
-               ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
-               ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
-       } else {
-               ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
-               ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
-               ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
-               ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
-       }
-
-       if (ah->ah_version == AR5K_AR5212)
-               ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
-       else if (ah->ah_version <= AR5K_AR5211)
-               ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
-
-       return 0;
-}
-
diff --git a/drivers/net/wireless/ath5k/desc.h b/drivers/net/wireless/ath5k/desc.h
deleted file mode 100644 (file)
index 56158c8..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*
- * Internal RX/TX descriptor structures
- * (rX: reserved fields possibily used by future versions of the ar5k chipset)
- */
-
-/*
- * common hardware RX control descriptor
- */
-struct ath5k_hw_rx_ctl {
-       u32     rx_control_0; /* RX control word 0 */
-       u32     rx_control_1; /* RX control word 1 */
-} __packed;
-
-/* RX control word 0 field/sflags */
-#define AR5K_DESC_RX_CTL0                      0x00000000
-
-/* RX control word 1 fields/flags */
-#define AR5K_DESC_RX_CTL1_BUF_LEN              0x00000fff
-#define AR5K_DESC_RX_CTL1_INTREQ               0x00002000
-
-/*
- * common hardware RX status descriptor
- * 5210/11 and 5212 differ only in the flags defined below
- */
-struct ath5k_hw_rx_status {
-       u32     rx_status_0; /* RX status word 0 */
-       u32     rx_status_1; /* RX status word 1 */
-} __packed;
-
-/* 5210/5211 */
-/* RX status word 0 fields/flags */
-#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN             0x00000fff
-#define AR5K_5210_RX_DESC_STATUS0_MORE                 0x00001000
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE         0x00078000
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S       15
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL       0x07f80000
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S     19
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA      0x38000000
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S    27
-
-/* RX status word 1 fields/flags */
-#define AR5K_5210_RX_DESC_STATUS1_DONE                 0x00000001
-#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK     0x00000002
-#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR            0x00000004
-#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN         0x00000008
-#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR    0x00000010
-#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR            0x000000e0
-#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S          5
-#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID      0x00000100
-#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX            0x00007e00
-#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S          9
-#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP    0x0fff8000
-#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S  15
-#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS       0x10000000
-
-/* 5212 */
-/* RX status word 0 fields/flags */
-#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN             0x00000fff
-#define AR5K_5212_RX_DESC_STATUS0_MORE                 0x00001000
-#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR     0x00002000
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE         0x000f8000
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S       15
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL       0x0ff00000
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S     20
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA      0xf0000000
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S    28
-
-/* RX status word 1 fields/flags */
-#define AR5K_5212_RX_DESC_STATUS1_DONE                 0x00000001
-#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK     0x00000002
-#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR            0x00000004
-#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR    0x00000008
-#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR            0x00000010
-#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR            0x00000020
-#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID      0x00000100
-#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX            0x0000fe00
-#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S          9
-#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP    0x7fff0000
-#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S  16
-#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS       0x80000000
-
-/*
- * common hardware RX error descriptor
- */
-struct ath5k_hw_rx_error {
-       u32     rx_error_0; /* RX status word 0 */
-       u32     rx_error_1; /* RX status word 1 */
-} __packed;
-
-/* RX error word 0 fields/flags */
-#define AR5K_RX_DESC_ERROR0                    0x00000000
-
-/* RX error word 1 fields/flags */
-#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE     0x0000ff00
-#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S   8
-
-/* PHY Error codes */
-#define AR5K_DESC_RX_PHY_ERROR_NONE            0x00
-#define AR5K_DESC_RX_PHY_ERROR_TIMING          0x20
-#define AR5K_DESC_RX_PHY_ERROR_PARITY          0x40
-#define AR5K_DESC_RX_PHY_ERROR_RATE            0x60
-#define AR5K_DESC_RX_PHY_ERROR_LENGTH          0x80
-#define AR5K_DESC_RX_PHY_ERROR_64QAM           0xa0
-#define AR5K_DESC_RX_PHY_ERROR_SERVICE         0xc0
-#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR     0xe0
-
-/*
- * 5210/5211 hardware 2-word TX control descriptor
- */
-struct ath5k_hw_2w_tx_ctl {
-       u32     tx_control_0; /* TX control word 0 */
-       u32     tx_control_1; /* TX control word 1 */
-} __packed;
-
-/* TX control word 0 fields/flags */
-#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN         0x00000fff
-#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN                0x0003f000 /*[5210 ?]*/
-#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S      12
-#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE         0x003c0000
-#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S       18
-#define AR5K_2W_TX_DESC_CTL0_RTSENA            0x00400000
-#define AR5K_2W_TX_DESC_CTL0_CLRDMASK          0x01000000
-#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET       0x00800000 /*[5210]*/
-#define AR5K_2W_TX_DESC_CTL0_VEOL              0x00800000 /*[5211]*/
-#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE                0x1c000000 /*[5210]*/
-#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S      26
-#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210        0x02000000
-#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211        0x1e000000
-
-#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT                     \
-               (ah->ah_version == AR5K_AR5210 ?                \
-               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 :       \
-               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211)
-
-#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S   25
-#define AR5K_2W_TX_DESC_CTL0_INTREQ            0x20000000
-#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
-
-/* TX control word 1 fields/flags */
-#define AR5K_2W_TX_DESC_CTL1_BUF_LEN           0x00000fff
-#define AR5K_2W_TX_DESC_CTL1_MORE              0x00001000
-#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210    0x0007e000
-#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211    0x000fe000
-
-#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX                         \
-                       (ah->ah_version == AR5K_AR5210 ?                \
-                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 :   \
-                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211)
-
-#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S       13
-#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE                0x00700000 /*[5211]*/
-#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S      20
-#define AR5K_2W_TX_DESC_CTL1_NOACK             0x00800000 /*[5211]*/
-#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION      0xfff80000 /*[5210 ?]*/
-
-/* Frame types */
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL   0x00
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM     0x04
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL   0x08
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 0x0c
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS     0x10
-
-/*
- * 5212 hardware 4-word TX control descriptor
- */
-struct ath5k_hw_4w_tx_ctl {
-       u32     tx_control_0; /* TX control word 0 */
-
-#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN         0x00000fff
-#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER                0x003f0000
-#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S      16
-#define AR5K_4W_TX_DESC_CTL0_RTSENA            0x00400000
-#define AR5K_4W_TX_DESC_CTL0_VEOL              0x00800000
-#define AR5K_4W_TX_DESC_CTL0_CLRDMASK          0x01000000
-#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT     0x1e000000
-#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S   25
-#define AR5K_4W_TX_DESC_CTL0_INTREQ            0x20000000
-#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
-#define AR5K_4W_TX_DESC_CTL0_CTSENA            0x80000000
-
-       u32     tx_control_1; /* TX control word 1 */
-
-#define AR5K_4W_TX_DESC_CTL1_BUF_LEN           0x00000fff
-#define AR5K_4W_TX_DESC_CTL1_MORE              0x00001000
-#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX 0x000fe000
-#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S       13
-#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE                0x00f00000
-#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S      20
-#define AR5K_4W_TX_DESC_CTL1_NOACK             0x01000000
-#define AR5K_4W_TX_DESC_CTL1_COMP_PROC         0x06000000
-#define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S       25
-#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN       0x18000000
-#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S     27
-#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN      0x60000000
-#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S    29
-
-       u32     tx_control_2; /* TX control word 2 */
-
-#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION              0x00007fff
-#define AR5K_4W_TX_DESC_CTL2_DURATION_UPDATE_ENABLE    0x00008000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0               0x000f0000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S             16
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1               0x00f00000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S             20
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2               0x0f000000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S             24
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3               0xf0000000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S             28
-
-       u32     tx_control_3; /* TX control word 3 */
-
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0                0x0000001f
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1                0x000003e0
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S      5
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2                0x00007c00
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S      10
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3                0x000f8000
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S      15
-#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE      0x01f00000
-#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S    20
-} __packed;
-
-/*
- * Common TX status descriptor
- */
-struct ath5k_hw_tx_status {
-       u32     tx_status_0; /* TX status word 0 */
-       u32     tx_status_1; /* TX status word 1 */
-} __packed;
-
-/* TX status word 0 fields/flags */
-#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK     0x00000001
-#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002
-#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN     0x00000004
-#define AR5K_DESC_TX_STATUS0_FILTERED          0x00000008
-/*???
-#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT    0x000000f0
-#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT_S  4
-*/
-#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0
-#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S       4
-/*???
-#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT   0x00000f00
-#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT_S 8
-*/
-#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT  0x00000f00
-#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S        8
-#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT   0x0000f000
-#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT_S 12
-#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP    0xffff0000
-#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S  16
-
-/* TX status word 1 fields/flags */
-#define AR5K_DESC_TX_STATUS1_DONE              0x00000001
-#define AR5K_DESC_TX_STATUS1_SEQ_NUM           0x00001ffe
-#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S         1
-#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH  0x001fe000
-#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S        13
-#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX    0x00600000
-#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S  21
-#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS      0x00800000
-#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA      0x01000000
-
-/*
- * 5210/5211 hardware TX descriptor
- */
-struct ath5k_hw_5210_tx_desc {
-       struct ath5k_hw_2w_tx_ctl       tx_ctl;
-       struct ath5k_hw_tx_status       tx_stat;
-} __packed;
-
-/*
- * 5212 hardware TX descriptor
- */
-struct ath5k_hw_5212_tx_desc {
-       struct ath5k_hw_4w_tx_ctl       tx_ctl;
-       struct ath5k_hw_tx_status       tx_stat;
-} __packed;
-
-/*
- * common hardware RX descriptor
- */
-struct ath5k_hw_all_rx_desc {
-       struct ath5k_hw_rx_ctl                  rx_ctl;
-       union {
-               struct ath5k_hw_rx_status       rx_stat;
-               struct ath5k_hw_rx_error        rx_err;
-       } u;
-} __packed;
-
-/*
- * Atheros hardware descriptor
- * This is read and written to by the hardware
- */
-struct ath5k_desc {
-       u32     ds_link;        /* physical address of the next descriptor */
-       u32     ds_data;        /* physical address of data buffer (skb) */
-
-       union {
-               struct ath5k_hw_5210_tx_desc    ds_tx5210;
-               struct ath5k_hw_5212_tx_desc    ds_tx5212;
-               struct ath5k_hw_all_rx_desc     ds_rx;
-       } ud;
-} __packed;
-
-#define AR5K_RXDESC_INTREQ     0x0020
-
-#define AR5K_TXDESC_CLRDMASK   0x0001
-#define AR5K_TXDESC_NOACK      0x0002  /*[5211+]*/
-#define AR5K_TXDESC_RTSENA     0x0004
-#define AR5K_TXDESC_CTSENA     0x0008
-#define AR5K_TXDESC_INTREQ     0x0010
-#define AR5K_TXDESC_VEOL       0x0020  /*[5211+]*/
-
diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath5k/dma.c
deleted file mode 100644 (file)
index b65b4fe..0000000
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*************************************\
-* DMA and interrupt masking functions *
-\*************************************/
-
-/*
- * dma.c - DMA and interrupt masking functions
- *
- * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and
- * handle queue setup for 5210 chipset (rest are handled on qcu.c).
- * Also we setup interrupt mask register (IMR) and read the various iterrupt
- * status registers (ISR).
- *
- * TODO: Handle SISR on 5211+ and introduce a function to return the queue
- * number that resulted the interrupt.
- */
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*********\
-* Receive *
-\*********/
-
-/**
- * ath5k_hw_start_rx_dma - Start DMA receive
- *
- * @ah:        The &struct ath5k_hw
- */
-void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
-       ath5k_hw_reg_read(ah, AR5K_CR);
-}
-
-/**
- * ath5k_hw_stop_rx_dma - Stop DMA receive
- *
- * @ah:        The &struct ath5k_hw
- */
-int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
-{
-       unsigned int i;
-
-       ATH5K_TRACE(ah->ah_sc);
-       ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
-
-       /*
-        * It may take some time to disable the DMA receive unit
-        */
-       for (i = 1000; i > 0 &&
-                       (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
-                       i--)
-               udelay(10);
-
-       return i ? 0 : -EBUSY;
-}
-
-/**
- * ath5k_hw_get_rxdp - Get RX Descriptor's address
- *
- * @ah: The &struct ath5k_hw
- *
- * XXX: Is RXDP read and clear ?
- */
-u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
-{
-       return ath5k_hw_reg_read(ah, AR5K_RXDP);
-}
-
-/**
- * ath5k_hw_set_rxdp - Set RX Descriptor's address
- *
- * @ah: The &struct ath5k_hw
- * @phys_addr: RX descriptor address
- *
- * XXX: Should we check if rx is enabled before setting rxdp ?
- */
-void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
-}
-
-
-/**********\
-* Transmit *
-\**********/
-
-/**
- * ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue
- *
- * @ah: The &struct ath5k_hw
- * @queue: The hw queue number
- *
- * Start DMA transmit for a specific queue and since 5210 doesn't have
- * QCU/DCU, set up queue parameters for 5210 here based on queue type (one
- * queue for normal data and one queue for beacons). For queue setup
- * on newer chips check out qcu.c. Returns -EINVAL if queue number is out
- * of range or if queue is already disabled.
- *
- * NOTE: Must be called after setting up tx control descriptor for that
- * queue (see below).
- */
-int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
-{
-       u32 tx_queue;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /* Return if queue is declared inactive */
-       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return -EIO;
-
-       if (ah->ah_version == AR5K_AR5210) {
-               tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
-
-               /*
-                * Set the queue by type on 5210
-                */
-               switch (ah->ah_txq[queue].tqi_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-                       tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
-                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
-                                       AR5K_BSR);
-                       break;
-               case AR5K_TX_QUEUE_CAB:
-                       tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
-                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
-                               AR5K_BCR_BDMAE, AR5K_BSR);
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               /* Start queue */
-               ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
-               ath5k_hw_reg_read(ah, AR5K_CR);
-       } else {
-               /* Return if queue is disabled */
-               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
-                       return -EIO;
-
-               /* Start queue */
-               AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
-       }
-
-       return 0;
-}
-
-/**
- * ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue
- *
- * @ah: The &struct ath5k_hw
- * @queue: The hw queue number
- *
- * Stop DMA transmit on a specific hw queue and drain queue so we don't
- * have any pending frames. Returns -EBUSY if we still have pending frames,
- * -EINVAL if queue number is out of range.
- *
- */
-int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
-{
-       unsigned int i = 40;
-       u32 tx_queue, pending;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /* Return if queue is declared inactive */
-       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return -EIO;
-
-       if (ah->ah_version == AR5K_AR5210) {
-               tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
-
-               /*
-                * Set by queue type
-                */
-               switch (ah->ah_txq[queue].tqi_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-               case AR5K_TX_QUEUE_CAB:
-                       /* XXX Fix me... */
-                       tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
-                       ath5k_hw_reg_write(ah, 0, AR5K_BSR);
-                       break;
-               default:
-                       return -EINVAL;
-               }
-
-               /* Stop queue */
-               ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
-               ath5k_hw_reg_read(ah, AR5K_CR);
-       } else {
-               /*
-                * Schedule TX disable and wait until queue is empty
-                */
-               AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
-
-               /*Check for pending frames*/
-               do {
-                       pending = ath5k_hw_reg_read(ah,
-                               AR5K_QUEUE_STATUS(queue)) &
-                               AR5K_QCU_STS_FRMPENDCNT;
-                       udelay(100);
-               } while (--i && pending);
-
-               /* For 2413+ order PCU to drop packets using
-                * QUIET mechanism */
-               if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) &&
-               pending){
-                       /* Set periodicity and duration */
-                       ath5k_hw_reg_write(ah,
-                               AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)|
-                               AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR),
-                               AR5K_QUIET_CTL2);
-
-                       /* Enable quiet period for current TSF */
-                       ath5k_hw_reg_write(ah,
-                               AR5K_QUIET_CTL1_QT_EN |
-                               AR5K_REG_SM(ath5k_hw_reg_read(ah,
-                                               AR5K_TSF_L32_5211) >> 10,
-                                               AR5K_QUIET_CTL1_NEXT_QT_TSF),
-                               AR5K_QUIET_CTL1);
-
-                       /* Force channel idle high */
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
-                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
-
-                       /* Wait a while and disable mechanism */
-                       udelay(200);
-                       AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
-                                               AR5K_QUIET_CTL1_QT_EN);
-
-                       /* Re-check for pending frames */
-                       i = 40;
-                       do {
-                               pending = ath5k_hw_reg_read(ah,
-                                       AR5K_QUEUE_STATUS(queue)) &
-                                       AR5K_QCU_STS_FRMPENDCNT;
-                               udelay(100);
-                       } while (--i && pending);
-
-                       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
-                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
-               }
-
-               /* Clear register */
-               ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
-               if (pending)
-                       return -EBUSY;
-       }
-
-       /* TODO: Check for success on 5210 else return error */
-       return 0;
-}
-
-/**
- * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
- *
- * @ah: The &struct ath5k_hw
- * @queue: The hw queue number
- *
- * Get TX descriptor's address for a specific queue. For 5210 we ignore
- * the queue number and use tx queue type since we only have 2 queues.
- * We use TXDP0 for normal data queue and TXDP1 for beacon queue.
- * For newer chips with QCU/DCU we just read the corresponding TXDP register.
- *
- * XXX: Is TXDP read and clear ?
- */
-u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue)
-{
-       u16 tx_reg;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /*
-        * Get the transmit queue descriptor pointer from the selected queue
-        */
-       /*5210 doesn't have QCU*/
-       if (ah->ah_version == AR5K_AR5210) {
-               switch (ah->ah_txq[queue].tqi_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       tx_reg = AR5K_NOQCU_TXDP0;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-               case AR5K_TX_QUEUE_CAB:
-                       tx_reg = AR5K_NOQCU_TXDP1;
-                       break;
-               default:
-                       return 0xffffffff;
-               }
-       } else {
-               tx_reg = AR5K_QUEUE_TXDP(queue);
-       }
-
-       return ath5k_hw_reg_read(ah, tx_reg);
-}
-
-/**
- * ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue
- *
- * @ah: The &struct ath5k_hw
- * @queue: The hw queue number
- *
- * Set TX descriptor's address for a specific queue. For 5210 we ignore
- * the queue number and we use tx queue type since we only have 2 queues
- * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue.
- * For newer chips with QCU/DCU we just set the corresponding TXDP register.
- * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still
- * active.
- */
-int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
-{
-       u16 tx_reg;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /*
-        * Set the transmit queue descriptor pointer register by type
-        * on 5210
-        */
-       if (ah->ah_version == AR5K_AR5210) {
-               switch (ah->ah_txq[queue].tqi_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       tx_reg = AR5K_NOQCU_TXDP0;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-               case AR5K_TX_QUEUE_CAB:
-                       tx_reg = AR5K_NOQCU_TXDP1;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       } else {
-               /*
-                * Set the transmit queue descriptor pointer for
-                * the selected queue on QCU for 5211+
-                * (this won't work if the queue is still active)
-                */
-               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
-                       return -EIO;
-
-               tx_reg = AR5K_QUEUE_TXDP(queue);
-       }
-
-       /* Set descriptor pointer */
-       ath5k_hw_reg_write(ah, phys_addr, tx_reg);
-
-       return 0;
-}
-
-/**
- * ath5k_hw_update_tx_triglevel - Update tx trigger level
- *
- * @ah: The &struct ath5k_hw
- * @increase: Flag to force increase of trigger level
- *
- * This function increases/decreases the tx trigger level for the tx fifo
- * buffer (aka FIFO threshold) that is used to indicate when PCU flushes
- * the buffer and transmits it's data. Lowering this results sending small
- * frames more quickly but can lead to tx underruns, raising it a lot can
- * result other problems (i think bmiss is related). Right now we start with
- * the lowest possible (64Bytes) and if we get tx underrun we increase it using
- * the increase flag. Returns -EIO if we have have reached maximum/minimum.
- *
- * XXX: Link this with tx DMA size ?
- * XXX: Use it to save interrupts ?
- * TODO: Needs testing, i think it's related to bmiss...
- */
-int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
-{
-       u32 trigger_level, imr;
-       int ret = -EIO;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*
-        * Disable interrupts by setting the mask
-        */
-       imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
-
-       trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
-                       AR5K_TXCFG_TXFULL);
-
-       if (!increase) {
-               if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
-                       goto done;
-       } else
-               trigger_level +=
-                       ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
-
-       /*
-        * Update trigger level on success
-        */
-       if (ah->ah_version == AR5K_AR5210)
-               ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
-       else
-               AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
-                               AR5K_TXCFG_TXFULL, trigger_level);
-
-       ret = 0;
-
-done:
-       /*
-        * Restore interrupt mask
-        */
-       ath5k_hw_set_imr(ah, imr);
-
-       return ret;
-}
-
-/*******************\
-* Interrupt masking *
-\*******************/
-
-/**
- * ath5k_hw_is_intr_pending - Check if we have pending interrupts
- *
- * @ah: The &struct ath5k_hw
- *
- * Check if we have pending interrupts to process. Returns 1 if we
- * have pending interrupts and 0 if we haven't.
- */
-bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
-}
-
-/**
- * ath5k_hw_get_isr - Get interrupt status
- *
- * @ah: The @struct ath5k_hw
- * @interrupt_mask: Driver's interrupt mask used to filter out
- * interrupts in sw.
- *
- * This function is used inside our interrupt handler to determine the reason
- * for the interrupt by reading Primary Interrupt Status Register. Returns an
- * abstract interrupt status mask which is mostly ISR with some uncommon bits
- * being mapped on some standard non hw-specific positions
- * (check out &ath5k_int).
- *
- * NOTE: We use read-and-clear register, so after this function is called ISR
- * is zeroed.
- */
-int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
-{
-       u32 data;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*
-        * Read interrupt status from the Interrupt Status register
-        * on 5210
-        */
-       if (ah->ah_version == AR5K_AR5210) {
-               data = ath5k_hw_reg_read(ah, AR5K_ISR);
-               if (unlikely(data == AR5K_INT_NOCARD)) {
-                       *interrupt_mask = data;
-                       return -ENODEV;
-               }
-       } else {
-               /*
-                * Read interrupt status from Interrupt
-                * Status Register shadow copy (Read And Clear)
-                *
-                * Note: PISR/SISR Not available on 5210
-                */
-               data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
-               if (unlikely(data == AR5K_INT_NOCARD)) {
-                       *interrupt_mask = data;
-                       return -ENODEV;
-               }
-       }
-
-       /*
-        * Get abstract interrupt mask (driver-compatible)
-        */
-       *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
-
-       if (ah->ah_version != AR5K_AR5210) {
-               u32 sisr2 = ath5k_hw_reg_read(ah, AR5K_RAC_SISR2);
-
-               /*HIU = Host Interface Unit (PCI etc)*/
-               if (unlikely(data & (AR5K_ISR_HIUERR)))
-                       *interrupt_mask |= AR5K_INT_FATAL;
-
-               /*Beacon Not Ready*/
-               if (unlikely(data & (AR5K_ISR_BNR)))
-                       *interrupt_mask |= AR5K_INT_BNR;
-
-               if (unlikely(sisr2 & (AR5K_SISR2_SSERR |
-                                       AR5K_SISR2_DPERR |
-                                       AR5K_SISR2_MCABT)))
-                       *interrupt_mask |= AR5K_INT_FATAL;
-
-               if (data & AR5K_ISR_TIM)
-                       *interrupt_mask |= AR5K_INT_TIM;
-
-               if (data & AR5K_ISR_BCNMISC) {
-                       if (sisr2 & AR5K_SISR2_TIM)
-                               *interrupt_mask |= AR5K_INT_TIM;
-                       if (sisr2 & AR5K_SISR2_DTIM)
-                               *interrupt_mask |= AR5K_INT_DTIM;
-                       if (sisr2 & AR5K_SISR2_DTIM_SYNC)
-                               *interrupt_mask |= AR5K_INT_DTIM_SYNC;
-                       if (sisr2 & AR5K_SISR2_BCN_TIMEOUT)
-                               *interrupt_mask |= AR5K_INT_BCN_TIMEOUT;
-                       if (sisr2 & AR5K_SISR2_CAB_TIMEOUT)
-                               *interrupt_mask |= AR5K_INT_CAB_TIMEOUT;
-               }
-
-               if (data & AR5K_ISR_RXDOPPLER)
-                       *interrupt_mask |= AR5K_INT_RX_DOPPLER;
-               if (data & AR5K_ISR_QCBRORN) {
-                       *interrupt_mask |= AR5K_INT_QCBRORN;
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
-                                       AR5K_SISR3_QCBRORN);
-               }
-               if (data & AR5K_ISR_QCBRURN) {
-                       *interrupt_mask |= AR5K_INT_QCBRURN;
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
-                                       AR5K_SISR3_QCBRURN);
-               }
-               if (data & AR5K_ISR_QTRIG) {
-                       *interrupt_mask |= AR5K_INT_QTRIG;
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR4),
-                                       AR5K_SISR4_QTRIG);
-               }
-
-               if (data & AR5K_ISR_TXOK)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
-                                       AR5K_SISR0_QCU_TXOK);
-
-               if (data & AR5K_ISR_TXDESC)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
-                                       AR5K_SISR0_QCU_TXDESC);
-
-               if (data & AR5K_ISR_TXERR)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
-                                       AR5K_SISR1_QCU_TXERR);
-
-               if (data & AR5K_ISR_TXEOL)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
-                                       AR5K_SISR1_QCU_TXEOL);
-
-               if (data & AR5K_ISR_TXURN)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR2),
-                                       AR5K_SISR2_QCU_TXURN);
-       } else {
-               if (unlikely(data & (AR5K_ISR_SSERR | AR5K_ISR_MCABT
-                               | AR5K_ISR_HIUERR | AR5K_ISR_DPERR)))
-                       *interrupt_mask |= AR5K_INT_FATAL;
-
-               /*
-                * XXX: BMISS interrupts may occur after association.
-                * I found this on 5210 code but it needs testing. If this is
-                * true we should disable them before assoc and re-enable them
-                * after a successful assoc + some jiffies.
-                       interrupt_mask &= ~AR5K_INT_BMISS;
-                */
-       }
-
-       /*
-        * In case we didn't handle anything,
-        * print the register value.
-        */
-       if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
-               ATH5K_PRINTF("ISR: 0x%08x IMR: 0x%08x\n", data, ah->ah_imr);
-
-       return 0;
-}
-
-/**
- * ath5k_hw_set_imr - Set interrupt mask
- *
- * @ah: The &struct ath5k_hw
- * @new_mask: The new interrupt mask to be set
- *
- * Set the interrupt mask in hw to save interrupts. We do that by mapping
- * ath5k_int bits to hw-specific bits to remove abstraction and writing
- * Interrupt Mask Register.
- */
-enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
-{
-       enum ath5k_int old_mask, int_mask;
-
-       old_mask = ah->ah_imr;
-
-       /*
-        * Disable card interrupts to prevent any race conditions
-        * (they will be re-enabled afterwards if AR5K_INT GLOBAL
-        * is set again on the new mask).
-        */
-       if (old_mask & AR5K_INT_GLOBAL) {
-               ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
-               ath5k_hw_reg_read(ah, AR5K_IER);
-       }
-
-       /*
-        * Add additional, chipset-dependent interrupt mask flags
-        * and write them to the IMR (interrupt mask register).
-        */
-       int_mask = new_mask & AR5K_INT_COMMON;
-
-       if (ah->ah_version != AR5K_AR5210) {
-               /* Preserve per queue TXURN interrupt mask */
-               u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2)
-                               & AR5K_SIMR2_QCU_TXURN;
-
-               if (new_mask & AR5K_INT_FATAL) {
-                       int_mask |= AR5K_IMR_HIUERR;
-                       simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR
-                               | AR5K_SIMR2_DPERR);
-               }
-
-               /*Beacon Not Ready*/
-               if (new_mask & AR5K_INT_BNR)
-                       int_mask |= AR5K_INT_BNR;
-
-               if (new_mask & AR5K_INT_TIM)
-                       int_mask |= AR5K_IMR_TIM;
-
-               if (new_mask & AR5K_INT_TIM)
-                       simr2 |= AR5K_SISR2_TIM;
-               if (new_mask & AR5K_INT_DTIM)
-                       simr2 |= AR5K_SISR2_DTIM;
-               if (new_mask & AR5K_INT_DTIM_SYNC)
-                       simr2 |= AR5K_SISR2_DTIM_SYNC;
-               if (new_mask & AR5K_INT_BCN_TIMEOUT)
-                       simr2 |= AR5K_SISR2_BCN_TIMEOUT;
-               if (new_mask & AR5K_INT_CAB_TIMEOUT)
-                       simr2 |= AR5K_SISR2_CAB_TIMEOUT;
-
-               if (new_mask & AR5K_INT_RX_DOPPLER)
-                       int_mask |= AR5K_IMR_RXDOPPLER;
-
-               /* Note: Per queue interrupt masks
-                * are set via reset_tx_queue (qcu.c) */
-               ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
-               ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2);
-
-       } else {
-               if (new_mask & AR5K_INT_FATAL)
-                       int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT
-                               | AR5K_IMR_HIUERR | AR5K_IMR_DPERR);
-
-               ath5k_hw_reg_write(ah, int_mask, AR5K_IMR);
-       }
-
-       /* If RXNOFRM interrupt is masked disable it
-        * by setting AR5K_RXNOFRM to zero */
-       if (!(new_mask & AR5K_INT_RXNOFRM))
-               ath5k_hw_reg_write(ah, 0, AR5K_RXNOFRM);
-
-       /* Store new interrupt mask */
-       ah->ah_imr = new_mask;
-
-       /* ..re-enable interrupts if AR5K_INT_GLOBAL is set */
-       if (new_mask & AR5K_INT_GLOBAL) {
-               ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
-               ath5k_hw_reg_read(ah, AR5K_IER);
-       }
-
-       return old_mask;
-}
-
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c
deleted file mode 100644 (file)
index c0fb3b0..0000000
+++ /dev/null
@@ -1,1769 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*************************************\
-* EEPROM access functions and helpers *
-\*************************************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Read from eeprom
- */
-static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
-{
-       u32 status, timeout;
-
-       ATH5K_TRACE(ah->ah_sc);
-       /*
-        * Initialize EEPROM access
-        */
-       if (ah->ah_version == AR5K_AR5210) {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
-               (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
-       } else {
-               ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
-               AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
-                               AR5K_EEPROM_CMD_READ);
-       }
-
-       for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
-               status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
-               if (status & AR5K_EEPROM_STAT_RDDONE) {
-                       if (status & AR5K_EEPROM_STAT_RDERR)
-                               return -EIO;
-                       *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
-                                       0xffff);
-                       return 0;
-               }
-               udelay(15);
-       }
-
-       return -ETIMEDOUT;
-}
-
-/*
- * Translate binary channel representation in EEPROM to frequency
- */
-static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
-                                 unsigned int mode)
-{
-       u16 val;
-
-       if (bin == AR5K_EEPROM_CHANNEL_DIS)
-               return bin;
-
-       if (mode == AR5K_EEPROM_MODE_11A) {
-               if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
-                       val = (5 * bin) + 4800;
-               else
-                       val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
-                               (bin * 10) + 5100;
-       } else {
-               if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
-                       val = bin + 2300;
-               else
-                       val = bin + 2400;
-       }
-
-       return val;
-}
-
-/*
- * Initialize eeprom & capabilities structs
- */
-static int
-ath5k_eeprom_init_header(struct ath5k_hw *ah)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       int ret;
-       u16 val;
-
-       /*
-        * Read values from EEPROM and store them in the capability structure
-        */
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
-
-       /* Return if we have an old EEPROM */
-       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
-               return 0;
-
-#ifdef notyet
-       /*
-        * Validate the checksum of the EEPROM date. There are some
-        * devices with invalid EEPROMs.
-        */
-       for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
-               AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
-               cksum ^= val;
-       }
-       if (cksum != AR5K_EEPROM_INFO_CKSUM) {
-               ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
-               return -EIO;
-       }
-#endif
-
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
-           ee_ant_gain);
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
-               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
-               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
-
-               /* XXX: Don't know which versions include these two */
-               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
-
-               if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
-                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
-
-               if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
-                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
-                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
-                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
-               }
-       }
-
-       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
-               AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
-               ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
-               ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
-
-               AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
-               ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
-               ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
-       }
-
-       return 0;
-}
-
-
-/*
- * Read antenna infos from eeprom
- */
-static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
-               unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 o = *offset;
-       u16 val;
-       int ret, i = 0;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_switch_settling[mode]    = (val >> 8) & 0x7f;
-       ee->ee_atn_tx_rx[mode]          = (val >> 2) & 0x3f;
-       ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
-       ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
-       ee->ee_ant_control[mode][i++]   = val & 0x3f;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_ant_control[mode][i++]   = (val >> 10) & 0x3f;
-       ee->ee_ant_control[mode][i++]   = (val >> 4) & 0x3f;
-       ee->ee_ant_control[mode][i]     = (val << 2) & 0x3f;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_ant_control[mode][i++]   |= (val >> 14) & 0x3;
-       ee->ee_ant_control[mode][i++]   = (val >> 8) & 0x3f;
-       ee->ee_ant_control[mode][i++]   = (val >> 2) & 0x3f;
-       ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
-       ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
-       ee->ee_ant_control[mode][i++]   = val & 0x3f;
-
-       /* Get antenna modes */
-       ah->ah_antenna[mode][0] =
-           (ee->ee_ant_control[mode][0] << 4);
-       ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
-            ee->ee_ant_control[mode][1]        |
-           (ee->ee_ant_control[mode][2] << 6)  |
-           (ee->ee_ant_control[mode][3] << 12) |
-           (ee->ee_ant_control[mode][4] << 18) |
-           (ee->ee_ant_control[mode][5] << 24);
-       ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
-            ee->ee_ant_control[mode][6]        |
-           (ee->ee_ant_control[mode][7] << 6)  |
-           (ee->ee_ant_control[mode][8] << 12) |
-           (ee->ee_ant_control[mode][9] << 18) |
-           (ee->ee_ant_control[mode][10] << 24);
-
-       /* return new offset */
-       *offset = o;
-
-       return 0;
-}
-
-/*
- * Read supported modes and some mode-specific calibration data
- * from eeprom
- */
-static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
-               unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 o = *offset;
-       u16 val;
-       int ret;
-
-       ee->ee_n_piers[mode] = 0;
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_adc_desired_size[mode]   = (s8)((val >> 8) & 0xff);
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11A:
-               ee->ee_ob[mode][3]      = (val >> 5) & 0x7;
-               ee->ee_db[mode][3]      = (val >> 2) & 0x7;
-               ee->ee_ob[mode][2]      = (val << 1) & 0x7;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_ob[mode][2]      |= (val >> 15) & 0x1;
-               ee->ee_db[mode][2]      = (val >> 12) & 0x7;
-               ee->ee_ob[mode][1]      = (val >> 9) & 0x7;
-               ee->ee_db[mode][1]      = (val >> 6) & 0x7;
-               ee->ee_ob[mode][0]      = (val >> 3) & 0x7;
-               ee->ee_db[mode][0]      = val & 0x7;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-       case AR5K_EEPROM_MODE_11B:
-               ee->ee_ob[mode][1]      = (val >> 4) & 0x7;
-               ee->ee_db[mode][1]      = val & 0x7;
-               break;
-       }
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
-       ee->ee_thr_62[mode]             = val & 0xff;
-
-       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
-               ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
-       ee->ee_tx_frm2xpa_enable[mode]  = val & 0xff;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_pga_desired_size[mode]   = (val >> 8) & 0xff;
-
-       if ((val & 0xff) & 0x80)
-               ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
-       else
-               ee->ee_noise_floor_thr[mode] = val & 0xff;
-
-       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
-               ee->ee_noise_floor_thr[mode] =
-                   mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_xlna_gain[mode]          = (val >> 5) & 0xff;
-       ee->ee_x_gain[mode]             = (val >> 1) & 0xf;
-       ee->ee_xpd[mode]                = val & 0x1;
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
-               ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
-
-               if (mode == AR5K_EEPROM_MODE_11A)
-                       ee->ee_xr_power[mode] = val & 0x3f;
-               else {
-                       ee->ee_ob[mode][0] = val & 0x7;
-                       ee->ee_db[mode][0] = (val >> 3) & 0x7;
-               }
-       }
-
-       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
-               ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
-               ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
-       } else {
-               ee->ee_i_gain[mode] = (val >> 13) & 0x7;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_i_gain[mode] |= (val << 3) & 0x38;
-
-               if (mode == AR5K_EEPROM_MODE_11G) {
-                       ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
-                       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
-                               ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
-               }
-       }
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
-                       mode == AR5K_EEPROM_MODE_11A) {
-               ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
-               ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
-       }
-
-       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
-               goto done;
-
-       /* Note: >= v5 have bg freq piers on another location
-        * so these freq piers are ignored for >= v5 (should be 0xff
-        * anyway) */
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11A:
-               if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
-                       break;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_margin_tx_rx[mode] = val & 0x3f;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               AR5K_EEPROM_READ(o++, val);
-
-               ee->ee_pwr_cal_b[0].freq =
-                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-               if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               ee->ee_pwr_cal_b[1].freq =
-                       ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
-               if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_pwr_cal_b[2].freq =
-                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-               if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
-                       ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               AR5K_EEPROM_READ(o++, val);
-
-               ee->ee_pwr_cal_g[0].freq =
-                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-               if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               ee->ee_pwr_cal_g[1].freq =
-                       ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
-               if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_turbo_max_power[mode] = val & 0x7f;
-               ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_pwr_cal_g[2].freq =
-                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-               if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
-                       ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
-               ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
-
-               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
-                       AR5K_EEPROM_READ(o++, val);
-                       ee->ee_cck_ofdm_gain_delta = val & 0xff;
-               }
-               break;
-       }
-
-done:
-       /* return new offset */
-       *offset = o;
-
-       return 0;
-}
-
-/*
- * Read turbo mode information on newer EEPROM versions
- */
-static int
-ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
-                             u32 *offset, unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 o = *offset;
-       u16 val;
-       int ret;
-
-       if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
-               return 0;
-
-       switch (mode){
-       case AR5K_EEPROM_MODE_11A:
-               ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
-
-               ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
-               ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
-
-               ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
-               ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
-
-               if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2)
-                       ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
-
-               ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
-               ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
-
-               ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
-               ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
-               break;
-       }
-
-       /* return new offset */
-       *offset = o;
-
-       return 0;
-}
-
-/* Read mode-specific data (except power calibration data) */
-static int
-ath5k_eeprom_init_modes(struct ath5k_hw *ah)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 mode_offset[3];
-       unsigned int mode;
-       u32 offset;
-       int ret;
-
-       /*
-        * Get values for all modes
-        */
-       mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
-       mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
-       mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
-
-       ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] =
-               AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
-
-       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
-               offset = mode_offset[mode];
-
-               ret = ath5k_eeprom_read_ants(ah, &offset, mode);
-               if (ret)
-                       return ret;
-
-               ret = ath5k_eeprom_read_modes(ah, &offset, mode);
-               if (ret)
-                       return ret;
-
-               ret = ath5k_eeprom_read_turbo_modes(ah, &offset, mode);
-               if (ret)
-                       return ret;
-       }
-
-       /* override for older eeprom versions for better performance */
-       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
-               ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15;
-               ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28;
-               ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28;
-       }
-
-       return 0;
-}
-
-/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
- * frequency mask) */
-static inline int
-ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
-                       struct ath5k_chan_pcal_info *pc, unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       int o = *offset;
-       int i = 0;
-       u8 freq1, freq2;
-       int ret;
-       u16 val;
-
-       ee->ee_n_piers[mode] = 0;
-       while(i < max) {
-               AR5K_EEPROM_READ(o++, val);
-
-               freq1 = val & 0xff;
-               if (!freq1)
-                       break;
-
-               pc[i++].freq = ath5k_eeprom_bin2freq(ee,
-                               freq1, mode);
-               ee->ee_n_piers[mode]++;
-
-               freq2 = (val >> 8) & 0xff;
-               if (!freq2)
-                       break;
-
-               pc[i++].freq = ath5k_eeprom_bin2freq(ee,
-                               freq2, mode);
-               ee->ee_n_piers[mode]++;
-       }
-
-       /* return new offset */
-       *offset = o;
-
-       return 0;
-}
-
-/* Read frequency piers for 802.11a */
-static int
-ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
-       int i, ret;
-       u16 val;
-       u8 mask;
-
-       if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
-               ath5k_eeprom_read_freq_list(ah, &offset,
-                       AR5K_EEPROM_N_5GHZ_CHAN, pcal,
-                       AR5K_EEPROM_MODE_11A);
-       } else {
-               mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[0].freq  = (val >> 9) & mask;
-               pcal[1].freq  = (val >> 2) & mask;
-               pcal[2].freq  = (val << 5) & mask;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[2].freq |= (val >> 11) & 0x1f;
-               pcal[3].freq  = (val >> 4) & mask;
-               pcal[4].freq  = (val << 3) & mask;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[4].freq |= (val >> 13) & 0x7;
-               pcal[5].freq  = (val >> 6) & mask;
-               pcal[6].freq  = (val << 1) & mask;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[6].freq |= (val >> 15) & 0x1;
-               pcal[7].freq  = (val >> 8) & mask;
-               pcal[8].freq  = (val >> 1) & mask;
-               pcal[9].freq  = (val << 6) & mask;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[9].freq |= (val >> 10) & 0x3f;
-
-               /* Fixed number of piers */
-               ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
-
-               for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
-                       pcal[i].freq = ath5k_eeprom_bin2freq(ee,
-                               pcal[i].freq, AR5K_EEPROM_MODE_11A);
-               }
-       }
-
-       return 0;
-}
-
-/* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
-static inline int
-ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *pcal;
-
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11B:
-               pcal = ee->ee_pwr_cal_b;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               pcal = ee->ee_pwr_cal_g;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       ath5k_eeprom_read_freq_list(ah, &offset,
-               AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
-               mode);
-
-       return 0;
-}
-
-/*
- * Read power calibration for RF5111 chips
- *
- * For RF5111 we have an XPD -eXternal Power Detector- curve
- * for each calibrated channel. Each curve has 0,5dB Power steps
- * on x axis and PCDAC steps (offsets) on y axis and looks like an
- * exponential function. To recreate the curve we read 11 points
- * here and interpolate later.
- */
-
-/* Used to match PCDAC steps with power values on RF5111 chips
- * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
- * steps that match with the power values we read from eeprom. On
- * older eeprom versions (< 3.2) these steps are equaly spaced at
- * 10% of the pcdac curve -until the curve reaches it's maximum-
- * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
- * these 11 steps are spaced in a different way. This function returns
- * the pcdac steps based on eeprom version and curve min/max so that we
- * can have pcdac/pwr points.
- */
-static inline void
-ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
-{
-       const static u16 intercepts3[] =
-               { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
-       const static u16 intercepts3_2[] =
-               { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
-       const u16 *ip;
-       int i;
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
-               ip = intercepts3_2;
-       else
-               ip = intercepts3;
-
-       for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
-               vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
-}
-
-/* Convert RF5111 specific data to generic raw data
- * used by interpolation code */
-static int
-ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
-                               struct ath5k_chan_pcal_info *chinfo)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf5111 *pcinfo;
-       struct ath5k_pdgain_info *pd;
-       u8 pier, point, idx;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-
-       /* Fill raw data for each calibration pier */
-       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
-
-               pcinfo = &chinfo[pier].rf5111_info;
-
-               /* Allocate pd_curves for this cal pier */
-               chinfo[pier].pd_curves =
-                       kcalloc(AR5K_EEPROM_N_PD_CURVES,
-                               sizeof(struct ath5k_pdgain_info),
-                               GFP_KERNEL);
-
-               if (!chinfo[pier].pd_curves)
-                       return -ENOMEM;
-
-               /* Only one curve for RF5111
-                * find out which one and place
-                * in in pd_curves.
-                * Note: ee_x_gain is reversed here */
-               for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
-
-                       if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
-                               pdgain_idx[0] = idx;
-                               break;
-                       }
-               }
-
-               ee->ee_pd_gains[mode] = 1;
-
-               pd = &chinfo[pier].pd_curves[idx];
-
-               pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
-
-               /* Allocate pd points for this curve */
-               pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
-                                       sizeof(u8), GFP_KERNEL);
-               if (!pd->pd_step)
-                       return -ENOMEM;
-
-               pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
-                                       sizeof(s16), GFP_KERNEL);
-               if (!pd->pd_pwr)
-                       return -ENOMEM;
-
-               /* Fill raw dataset
-                * (convert power to 0.25dB units
-                * for RF5112 combatibility) */
-               for (point = 0; point < pd->pd_points; point++) {
-
-                       /* Absolute values */
-                       pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
-
-                       /* Already sorted */
-                       pd->pd_step[point] = pcinfo->pcdac[point];
-               }
-
-               /* Set min/max pwr */
-               chinfo[pier].min_pwr = pd->pd_pwr[0];
-               chinfo[pier].max_pwr = pd->pd_pwr[10];
-
-       }
-
-       return 0;
-}
-
-/* Parse EEPROM data */
-static int
-ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *pcal;
-       int offset, ret;
-       int i;
-       u16 val;
-
-       offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11A:
-               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       return 0;
-
-               ret = ath5k_eeprom_init_11a_pcal_freq(ah,
-                       offset + AR5K_EEPROM_GROUP1_OFFSET);
-               if (ret < 0)
-                       return ret;
-
-               offset += AR5K_EEPROM_GROUP2_OFFSET;
-               pcal = ee->ee_pwr_cal_a;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
-                   !AR5K_EEPROM_HDR_11G(ee->ee_header))
-                       return 0;
-
-               pcal = ee->ee_pwr_cal_b;
-               offset += AR5K_EEPROM_GROUP3_OFFSET;
-
-               /* fixed piers */
-               pcal[0].freq = 2412;
-               pcal[1].freq = 2447;
-               pcal[2].freq = 2484;
-               ee->ee_n_piers[mode] = 3;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
-                       return 0;
-
-               pcal = ee->ee_pwr_cal_g;
-               offset += AR5K_EEPROM_GROUP4_OFFSET;
-
-               /* fixed piers */
-               pcal[0].freq = 2312;
-               pcal[1].freq = 2412;
-               pcal[2].freq = 2484;
-               ee->ee_n_piers[mode] = 3;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
-               struct ath5k_chan_pcal_info_rf5111 *cdata =
-                       &pcal[i].rf5111_info;
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
-               cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
-               cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pwr[0] |= ((val >> 14) & 0x3);
-               cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pwr[3] |= ((val >> 12) & 0xf);
-               cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[5] = (val  & AR5K_EEPROM_POWER_M);
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pwr[8] |= ((val >> 14) & 0x3);
-               cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
-
-               ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
-                       cdata->pcdac_max, cdata->pcdac);
-       }
-
-       return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
-}
-
-
-/*
- * Read power calibration for RF5112 chips
- *
- * For RF5112 we have 4 XPD -eXternal Power Detector- curves
- * for each calibrated channel on 0, -6, -12 and -18dbm but we only
- * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
- * power steps on x axis and PCDAC steps on y axis and looks like a
- * linear function. To recreate the curve and pass the power values
- * on hw, we read 4 points for xpd 0 (lower gain -> max power)
- * and 3 points for xpd 3 (higher gain -> lower power) here and
- * interpolate later.
- *
- * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
- */
-
-/* Convert RF5112 specific data to generic raw data
- * used by interpolation code */
-static int
-ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
-                               struct ath5k_chan_pcal_info *chinfo)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf5112 *pcinfo;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-       unsigned int pier, pdg, point;
-
-       /* Fill raw data for each calibration pier */
-       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
-
-               pcinfo = &chinfo[pier].rf5112_info;
-
-               /* Allocate pd_curves for this cal pier */
-               chinfo[pier].pd_curves =
-                               kcalloc(AR5K_EEPROM_N_PD_CURVES,
-                                       sizeof(struct ath5k_pdgain_info),
-                                       GFP_KERNEL);
-
-               if (!chinfo[pier].pd_curves)
-                       return -ENOMEM;
-
-               /* Fill pd_curves */
-               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
-
-                       u8 idx = pdgain_idx[pdg];
-                       struct ath5k_pdgain_info *pd =
-                                       &chinfo[pier].pd_curves[idx];
-
-                       /* Lowest gain curve (max power) */
-                       if (pdg == 0) {
-                               /* One more point for better accuracy */
-                               pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
-
-                               /* Allocate pd points for this curve */
-                               pd->pd_step = kcalloc(pd->pd_points,
-                                               sizeof(u8), GFP_KERNEL);
-
-                               if (!pd->pd_step)
-                                       return -ENOMEM;
-
-                               pd->pd_pwr = kcalloc(pd->pd_points,
-                                               sizeof(s16), GFP_KERNEL);
-
-                               if (!pd->pd_pwr)
-                                       return -ENOMEM;
-
-
-                               /* Fill raw dataset
-                                * (all power levels are in 0.25dB units) */
-                               pd->pd_step[0] = pcinfo->pcdac_x0[0];
-                               pd->pd_pwr[0] = pcinfo->pwr_x0[0];
-
-                               for (point = 1; point < pd->pd_points;
-                               point++) {
-                                       /* Absolute values */
-                                       pd->pd_pwr[point] =
-                                               pcinfo->pwr_x0[point];
-
-                                       /* Deltas */
-                                       pd->pd_step[point] =
-                                               pd->pd_step[point - 1] +
-                                               pcinfo->pcdac_x0[point];
-                               }
-
-                               /* Set min power for this frequency */
-                               chinfo[pier].min_pwr = pd->pd_pwr[0];
-
-                       /* Highest gain curve (min power) */
-                       } else if (pdg == 1) {
-
-                               pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
-
-                               /* Allocate pd points for this curve */
-                               pd->pd_step = kcalloc(pd->pd_points,
-                                               sizeof(u8), GFP_KERNEL);
-
-                               if (!pd->pd_step)
-                                       return -ENOMEM;
-
-                               pd->pd_pwr = kcalloc(pd->pd_points,
-                                               sizeof(s16), GFP_KERNEL);
-
-                               if (!pd->pd_pwr)
-                                       return -ENOMEM;
-
-                               /* Fill raw dataset
-                                * (all power levels are in 0.25dB units) */
-                               for (point = 0; point < pd->pd_points;
-                               point++) {
-                                       /* Absolute values */
-                                       pd->pd_pwr[point] =
-                                               pcinfo->pwr_x3[point];
-
-                                       /* Fixed points */
-                                       pd->pd_step[point] =
-                                               pcinfo->pcdac_x3[point];
-                               }
-
-                               /* Since we have a higher gain curve
-                                * override min power */
-                               chinfo[pier].min_pwr = pd->pd_pwr[0];
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/* Parse EEPROM data */
-static int
-ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
-       struct ath5k_chan_pcal_info *gen_chan_info;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-       u32 offset;
-       u8 i, c;
-       u16 val;
-       int ret;
-       u8 pd_gains = 0;
-
-       /* Count how many curves we have and
-        * identify them (which one of the 4
-        * available curves we have on each count).
-        * Curves are stored from lower (x0) to
-        * higher (x3) gain */
-       for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
-               /* ee_x_gain[mode] is x gain mask */
-               if ((ee->ee_x_gain[mode] >> i) & 0x1)
-                       pdgain_idx[pd_gains++] = i;
-       }
-       ee->ee_pd_gains[mode] = pd_gains;
-
-       if (pd_gains == 0 || pd_gains > 2)
-               return -EINVAL;
-
-       switch (mode) {
-       case AR5K_EEPROM_MODE_11A:
-               /*
-                * Read 5GHz EEPROM channels
-                */
-               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
-               ath5k_eeprom_init_11a_pcal_freq(ah, offset);
-
-               offset += AR5K_EEPROM_GROUP2_OFFSET;
-               gen_chan_info = ee->ee_pwr_cal_a;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
-               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       offset += AR5K_EEPROM_GROUP3_OFFSET;
-
-               /* NB: frequency piers parsed during mode init */
-               gen_chan_info = ee->ee_pwr_cal_b;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
-               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       offset += AR5K_EEPROM_GROUP4_OFFSET;
-               else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
-                       offset += AR5K_EEPROM_GROUP2_OFFSET;
-
-               /* NB: frequency piers parsed during mode init */
-               gen_chan_info = ee->ee_pwr_cal_g;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
-               chan_pcal_info = &gen_chan_info[i].rf5112_info;
-
-               /* Power values in quarter dB
-                * for the lower xpd gain curve
-                * (0 dBm -> higher output power) */
-               for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
-                       AR5K_EEPROM_READ(offset++, val);
-                       chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
-                       chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
-               }
-
-               /* PCDAC steps
-                * corresponding to the above power
-                * measurements */
-               AR5K_EEPROM_READ(offset++, val);
-               chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
-               chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
-               chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
-
-               /* Power values in quarter dB
-                * for the higher xpd gain curve
-                * (18 dBm -> lower output power) */
-               AR5K_EEPROM_READ(offset++, val);
-               chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
-               chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
-
-               AR5K_EEPROM_READ(offset++, val);
-               chan_pcal_info->pwr_x3[2] = (val & 0xff);
-
-               /* PCDAC steps
-                * corresponding to the above power
-                * measurements (fixed) */
-               chan_pcal_info->pcdac_x3[0] = 20;
-               chan_pcal_info->pcdac_x3[1] = 35;
-               chan_pcal_info->pcdac_x3[2] = 63;
-
-               if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
-                       chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
-
-                       /* Last xpd0 power level is also channel maximum */
-                       gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
-               } else {
-                       chan_pcal_info->pcdac_x0[0] = 1;
-                       gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
-               }
-
-       }
-
-       return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
-}
-
-
-/*
- * Read power calibration for RF2413 chips
- *
- * For RF2413 we have a Power to PDDAC table (Power Detector)
- * instead of a PCDAC and 4 pd gain curves for each calibrated channel.
- * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y
- * axis and looks like an exponential function like the RF5111 curve.
- *
- * To recreate the curves we read here the points and interpolate
- * later. Note that in most cases only 2 (higher and lower) curves are
- * used (like RF5112) but vendors have the oportunity to include all
- * 4 curves on eeprom. The final curve (higher power) has an extra
- * point for better accuracy like RF5112.
- */
-
-/* For RF2413 power calibration data doesn't start on a fixed location and
- * if a mode is not supported, it's section is missing -not zeroed-.
- * So we need to calculate the starting offset for each section by using
- * these two functions */
-
-/* Return the size of each section based on the mode and the number of pd
- * gains available (maximum 4). */
-static inline unsigned int
-ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
-{
-       static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
-       unsigned int sz;
-
-       sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
-       sz *= ee->ee_n_piers[mode];
-
-       return sz;
-}
-
-/* Return the starting offset for a section based on the modes supported
- * and each section's size. */
-static unsigned int
-ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
-{
-       u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
-
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11G:
-               if (AR5K_EEPROM_HDR_11B(ee->ee_header))
-                       offset += ath5k_pdgains_size_2413(ee,
-                                       AR5K_EEPROM_MODE_11B) +
-                                       AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
-               /* fall through */
-       case AR5K_EEPROM_MODE_11B:
-               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       offset += ath5k_pdgains_size_2413(ee,
-                                       AR5K_EEPROM_MODE_11A) +
-                                       AR5K_EEPROM_N_5GHZ_CHAN / 2;
-               /* fall through */
-       case AR5K_EEPROM_MODE_11A:
-               break;
-       default:
-               break;
-       }
-
-       return offset;
-}
-
-/* Convert RF2413 specific data to generic raw data
- * used by interpolation code */
-static int
-ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
-                               struct ath5k_chan_pcal_info *chinfo)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf2413 *pcinfo;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-       unsigned int pier, pdg, point;
-
-       /* Fill raw data for each calibration pier */
-       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
-
-               pcinfo = &chinfo[pier].rf2413_info;
-
-               /* Allocate pd_curves for this cal pier */
-               chinfo[pier].pd_curves =
-                               kcalloc(AR5K_EEPROM_N_PD_CURVES,
-                                       sizeof(struct ath5k_pdgain_info),
-                                       GFP_KERNEL);
-
-               if (!chinfo[pier].pd_curves)
-                       return -ENOMEM;
-
-               /* Fill pd_curves */
-               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
-
-                       u8 idx = pdgain_idx[pdg];
-                       struct ath5k_pdgain_info *pd =
-                                       &chinfo[pier].pd_curves[idx];
-
-                       /* One more point for the highest power
-                        * curve (lowest gain) */
-                       if (pdg == ee->ee_pd_gains[mode] - 1)
-                               pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
-                       else
-                               pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
-
-                       /* Allocate pd points for this curve */
-                       pd->pd_step = kcalloc(pd->pd_points,
-                                       sizeof(u8), GFP_KERNEL);
-
-                       if (!pd->pd_step)
-                               return -ENOMEM;
-
-                       pd->pd_pwr = kcalloc(pd->pd_points,
-                                       sizeof(s16), GFP_KERNEL);
-
-                       if (!pd->pd_pwr)
-                               return -ENOMEM;
-
-                       /* Fill raw dataset
-                        * convert all pwr levels to
-                        * quarter dB for RF5112 combatibility */
-                       pd->pd_step[0] = pcinfo->pddac_i[pdg];
-                       pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
-
-                       for (point = 1; point < pd->pd_points; point++) {
-
-                               pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
-                                       2 * pcinfo->pwr[pdg][point - 1];
-
-                               pd->pd_step[point] = pd->pd_step[point - 1] +
-                                               pcinfo->pddac[pdg][point - 1];
-
-                       }
-
-                       /* Highest gain curve -> min power */
-                       if (pdg == 0)
-                               chinfo[pier].min_pwr = pd->pd_pwr[0];
-
-                       /* Lowest gain curve -> max power */
-                       if (pdg == ee->ee_pd_gains[mode] - 1)
-                               chinfo[pier].max_pwr =
-                                       pd->pd_pwr[pd->pd_points - 1];
-               }
-       }
-
-       return 0;
-}
-
-/* Parse EEPROM data */
-static int
-ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf2413 *pcinfo;
-       struct ath5k_chan_pcal_info *chinfo;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-       u32 offset;
-       int idx, i, ret;
-       u16 val;
-       u8 pd_gains = 0;
-
-       /* Count how many curves we have and
-        * identify them (which one of the 4
-        * available curves we have on each count).
-        * Curves are stored from higher to
-        * lower gain so we go backwards */
-       for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
-               /* ee_x_gain[mode] is x gain mask */
-               if ((ee->ee_x_gain[mode] >> idx) & 0x1)
-                       pdgain_idx[pd_gains++] = idx;
-
-       }
-       ee->ee_pd_gains[mode] = pd_gains;
-
-       if (pd_gains == 0)
-               return -EINVAL;
-
-       offset = ath5k_cal_data_offset_2413(ee, mode);
-       switch (mode) {
-       case AR5K_EEPROM_MODE_11A:
-               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       return 0;
-
-               ath5k_eeprom_init_11a_pcal_freq(ah, offset);
-               offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
-               chinfo = ee->ee_pwr_cal_a;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
-                       return 0;
-
-               ath5k_eeprom_init_11bg_2413(ah, mode, offset);
-               offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
-               chinfo = ee->ee_pwr_cal_b;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
-                       return 0;
-
-               ath5k_eeprom_init_11bg_2413(ah, mode, offset);
-               offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
-               chinfo = ee->ee_pwr_cal_g;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
-               pcinfo = &chinfo[i].rf2413_info;
-
-               /*
-                * Read pwr_i, pddac_i and the first
-                * 2 pd points (pwr, pddac)
-                */
-               AR5K_EEPROM_READ(offset++, val);
-               pcinfo->pwr_i[0] = val & 0x1f;
-               pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
-               pcinfo->pwr[0][0] = (val >> 12) & 0xf;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcinfo->pddac[0][0] = val & 0x3f;
-               pcinfo->pwr[0][1] = (val >> 6) & 0xf;
-               pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcinfo->pwr[0][2] = val & 0xf;
-               pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
-
-               pcinfo->pwr[0][3] = 0;
-               pcinfo->pddac[0][3] = 0;
-
-               if (pd_gains > 1) {
-                       /*
-                        * Pd gain 0 is not the last pd gain
-                        * so it only has 2 pd points.
-                        * Continue wih pd gain 1.
-                        */
-                       pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
-
-                       pcinfo->pddac_i[1] = (val >> 15) & 0x1;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
-
-                       pcinfo->pwr[1][0] = (val >> 6) & 0xf;
-                       pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr[1][1] = val & 0xf;
-                       pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
-                       pcinfo->pwr[1][2] = (val >> 10) & 0xf;
-
-                       pcinfo->pddac[1][2] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[1][2] |= (val & 0xF) << 2;
-
-                       pcinfo->pwr[1][3] = 0;
-                       pcinfo->pddac[1][3] = 0;
-               } else if (pd_gains == 1) {
-                       /*
-                        * Pd gain 0 is the last one so
-                        * read the extra point.
-                        */
-                       pcinfo->pwr[0][3] = (val >> 10) & 0xf;
-
-                       pcinfo->pddac[0][3] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[0][3] |= (val & 0xF) << 2;
-               }
-
-               /*
-                * Proceed with the other pd_gains
-                * as above.
-                */
-               if (pd_gains > 2) {
-                       pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
-                       pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr[2][0] = (val >> 0) & 0xf;
-                       pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
-                       pcinfo->pwr[2][1] = (val >> 10) & 0xf;
-
-                       pcinfo->pddac[2][1] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[2][1] |= (val & 0xF) << 2;
-
-                       pcinfo->pwr[2][2] = (val >> 4) & 0xf;
-                       pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
-
-                       pcinfo->pwr[2][3] = 0;
-                       pcinfo->pddac[2][3] = 0;
-               } else if (pd_gains == 2) {
-                       pcinfo->pwr[1][3] = (val >> 4) & 0xf;
-                       pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
-               }
-
-               if (pd_gains > 3) {
-                       pcinfo->pwr_i[3] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
-
-                       pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
-                       pcinfo->pwr[3][0] = (val >> 10) & 0xf;
-                       pcinfo->pddac[3][0] = (val >> 14) & 0x3;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[3][0] |= (val & 0xF) << 2;
-                       pcinfo->pwr[3][1] = (val >> 4) & 0xf;
-                       pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
-
-                       pcinfo->pwr[3][2] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
-
-                       pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
-                       pcinfo->pwr[3][3] = (val >> 8) & 0xf;
-
-                       pcinfo->pddac[3][3] = (val >> 12) & 0xF;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
-               } else if (pd_gains == 3) {
-                       pcinfo->pwr[2][3] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
-
-                       pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
-               }
-       }
-
-       return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
-}
-
-
-/*
- * Read per rate target power (this is the maximum tx power
- * supported by the card). This info is used when setting
- * tx power, no matter the channel.
- *
- * This also works for v5 EEPROMs.
- */
-static int
-ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_rate_pcal_info *rate_pcal_info;
-       u8 *rate_target_pwr_num;
-       u32 offset;
-       u16 val;
-       int ret, i;
-
-       offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
-       rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
-       switch (mode) {
-       case AR5K_EEPROM_MODE_11A:
-               offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
-               rate_pcal_info = ee->ee_rate_tpwr_a;
-               ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
-               rate_pcal_info = ee->ee_rate_tpwr_b;
-               ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
-               rate_pcal_info = ee->ee_rate_tpwr_g;
-               ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* Different freq mask for older eeproms (<= v3.2) */
-       if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
-               for (i = 0; i < (*rate_target_pwr_num); i++) {
-                       AR5K_EEPROM_READ(offset++, val);
-                       rate_pcal_info[i].freq =
-                           ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
-
-                       rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
-                       rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
-
-                       AR5K_EEPROM_READ(offset++, val);
-
-                       if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
-                           val == 0) {
-                               (*rate_target_pwr_num) = i;
-                               break;
-                       }
-
-                       rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
-                       rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
-                       rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
-               }
-       } else {
-               for (i = 0; i < (*rate_target_pwr_num); i++) {
-                       AR5K_EEPROM_READ(offset++, val);
-                       rate_pcal_info[i].freq =
-                           ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
-
-                       rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
-                       rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
-
-                       AR5K_EEPROM_READ(offset++, val);
-
-                       if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
-                           val == 0) {
-                               (*rate_target_pwr_num) = i;
-                               break;
-                       }
-
-                       rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
-                       rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
-                       rate_pcal_info[i].target_power_54 = (val & 0x3f);
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Read per channel calibration info from EEPROM
- *
- * This info is used to calibrate the baseband power table. Imagine
- * that for each channel there is a power curve that's hw specific
- * (depends on amplifier etc) and we try to "correct" this curve using
- * offests we pass on to phy chip (baseband -> before amplifier) so that
- * it can use accurate power values when setting tx power (takes amplifier's
- * performance on each channel into account).
- *
- * EEPROM provides us with the offsets for some pre-calibrated channels
- * and we have to interpolate to create the full table for these channels and
- * also the table for any channel.
- */
-static int
-ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       int (*read_pcal)(struct ath5k_hw *hw, int mode);
-       int mode;
-       int err;
-
-       if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
-                       (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
-               read_pcal = ath5k_eeprom_read_pcal_info_5112;
-       else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
-                       (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
-               read_pcal = ath5k_eeprom_read_pcal_info_2413;
-       else
-               read_pcal = ath5k_eeprom_read_pcal_info_5111;
-
-
-       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
-       mode++) {
-               err = read_pcal(ah, mode);
-               if (err)
-                       return err;
-
-               err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode);
-               if (err < 0)
-                       return err;
-       }
-
-       return 0;
-}
-
-static int
-ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *chinfo;
-       u8 pier, pdg;
-
-       switch (mode) {
-       case AR5K_EEPROM_MODE_11A:
-               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       return 0;
-               chinfo = ee->ee_pwr_cal_a;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
-                       return 0;
-               chinfo = ee->ee_pwr_cal_b;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
-                       return 0;
-               chinfo = ee->ee_pwr_cal_g;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
-               if (!chinfo[pier].pd_curves)
-                       continue;
-
-               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
-                       struct ath5k_pdgain_info *pd =
-                                       &chinfo[pier].pd_curves[pdg];
-
-                       if (pd != NULL) {
-                               kfree(pd->pd_step);
-                               kfree(pd->pd_pwr);
-                       }
-               }
-
-               kfree(chinfo[pier].pd_curves);
-       }
-
-       return 0;
-}
-
-void
-ath5k_eeprom_detach(struct ath5k_hw *ah)
-{
-       u8 mode;
-
-       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
-               ath5k_eeprom_free_pcal_info(ah, mode);
-}
-
-/* Read conformance test limits used for regulatory control */
-static int
-ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_edge_power *rep;
-       unsigned int fmask, pmask;
-       unsigned int ctl_mode;
-       int ret, i, j;
-       u32 offset;
-       u16 val;
-
-       pmask = AR5K_EEPROM_POWER_M;
-       fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
-       offset = AR5K_EEPROM_CTL(ee->ee_version);
-       ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version);
-       for (i = 0; i < ee->ee_ctls; i += 2) {
-               AR5K_EEPROM_READ(offset++, val);
-               ee->ee_ctl[i] = (val >> 8) & 0xff;
-               ee->ee_ctl[i + 1] = val & 0xff;
-       }
-
-       offset = AR5K_EEPROM_GROUP8_OFFSET;
-       if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
-               offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) -
-                       AR5K_EEPROM_GROUP5_OFFSET;
-       else
-               offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
-
-       rep = ee->ee_ctl_pwr;
-       for(i = 0; i < ee->ee_ctls; i++) {
-               switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
-               case AR5K_CTL_11A:
-               case AR5K_CTL_TURBO:
-                       ctl_mode = AR5K_EEPROM_MODE_11A;
-                       break;
-               default:
-                       ctl_mode = AR5K_EEPROM_MODE_11G;
-                       break;
-               }
-               if (ee->ee_ctl[i] == 0) {
-                       if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3)
-                               offset += 8;
-                       else
-                               offset += 7;
-                       rep += AR5K_EEPROM_N_EDGES;
-                       continue;
-               }
-               if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
-                       for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
-                               AR5K_EEPROM_READ(offset++, val);
-                               rep[j].freq = (val >> 8) & fmask;
-                               rep[j + 1].freq = val & fmask;
-                       }
-                       for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
-                               AR5K_EEPROM_READ(offset++, val);
-                               rep[j].edge = (val >> 8) & pmask;
-                               rep[j].flag = (val >> 14) & 1;
-                               rep[j + 1].edge = val & pmask;
-                               rep[j + 1].flag = (val >> 6) & 1;
-                       }
-               } else {
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[0].freq = (val >> 9) & fmask;
-                       rep[1].freq = (val >> 2) & fmask;
-                       rep[2].freq = (val << 5) & fmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[2].freq |= (val >> 11) & 0x1f;
-                       rep[3].freq = (val >> 4) & fmask;
-                       rep[4].freq = (val << 3) & fmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[4].freq |= (val >> 13) & 0x7;
-                       rep[5].freq = (val >> 6) & fmask;
-                       rep[6].freq = (val << 1) & fmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[6].freq |= (val >> 15) & 0x1;
-                       rep[7].freq = (val >> 8) & fmask;
-
-                       rep[0].edge = (val >> 2) & pmask;
-                       rep[1].edge = (val << 4) & pmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[1].edge |= (val >> 12) & 0xf;
-                       rep[2].edge = (val >> 6) & pmask;
-                       rep[3].edge = val & pmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[4].edge = (val >> 10) & pmask;
-                       rep[5].edge = (val >> 4) & pmask;
-                       rep[6].edge = (val << 2) & pmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[6].edge |= (val >> 14) & 0x3;
-                       rep[7].edge = (val >> 8) & pmask;
-               }
-               for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
-                       rep[j].freq = ath5k_eeprom_bin2freq(ee,
-                               rep[j].freq, ctl_mode);
-               }
-               rep += AR5K_EEPROM_N_EDGES;
-       }
-
-       return 0;
-}
-
-
-/*
- * Initialize eeprom power tables
- */
-int
-ath5k_eeprom_init(struct ath5k_hw *ah)
-{
-       int err;
-
-       err = ath5k_eeprom_init_header(ah);
-       if (err < 0)
-               return err;
-
-       err = ath5k_eeprom_init_modes(ah);
-       if (err < 0)
-               return err;
-
-       err = ath5k_eeprom_read_pcal_info(ah);
-       if (err < 0)
-               return err;
-
-       err = ath5k_eeprom_read_ctl_info(ah);
-       if (err < 0)
-               return err;
-
-       return 0;
-}
-
-/*
- * Read the MAC address from eeprom
- */
-int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
-{
-       u8 mac_d[ETH_ALEN] = {};
-       u32 total, offset;
-       u16 data;
-       int octet, ret;
-
-       ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
-       if (ret)
-               return ret;
-
-       for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
-               ret = ath5k_hw_eeprom_read(ah, offset, &data);
-               if (ret)
-                       return ret;
-
-               total += data;
-               mac_d[octet + 1] = data & 0xff;
-               mac_d[octet] = data >> 8;
-               octet += 2;
-       }
-
-       if (!total || total == 3 * 0xffff)
-               return -EINVAL;
-
-       memcpy(mac, mac_d, ETH_ALEN);
-
-       return 0;
-}
-
-bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
-{
-       u16 data;
-
-       ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
-
-       if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
-               return true;
-       else
-               return false;
-}
-
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h
deleted file mode 100644 (file)
index b0c0606..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*
- * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
- */
-#define AR5K_EEPROM_MAGIC              0x003d  /* EEPROM Magic number */
-#define AR5K_EEPROM_MAGIC_VALUE                0x5aa5  /* Default - found on EEPROM */
-#define AR5K_EEPROM_MAGIC_5212         0x0000145c /* 5212 */
-#define AR5K_EEPROM_MAGIC_5211         0x0000145b /* 5211 */
-#define AR5K_EEPROM_MAGIC_5210         0x0000145a /* 5210 */
-
-#define        AR5K_EEPROM_IS_HB63             0x000b  /* Talon detect */
-#define AR5K_EEPROM_REG_DOMAIN         0x00bf  /* EEPROM regdom */
-#define AR5K_EEPROM_CHECKSUM           0x00c0  /* EEPROM checksum */
-#define AR5K_EEPROM_INFO_BASE          0x00c0  /* EEPROM header */
-#define AR5K_EEPROM_INFO_MAX           (0x400 - AR5K_EEPROM_INFO_BASE)
-#define AR5K_EEPROM_INFO_CKSUM         0xffff
-#define AR5K_EEPROM_INFO(_n)           (AR5K_EEPROM_INFO_BASE + (_n))
-
-#define AR5K_EEPROM_VERSION            AR5K_EEPROM_INFO(1)     /* EEPROM Version */
-#define AR5K_EEPROM_VERSION_3_0                0x3000  /* No idea what's going on before this version */
-#define AR5K_EEPROM_VERSION_3_1                0x3001  /* ob/db values for 2Ghz (ar5211_rfregs) */
-#define AR5K_EEPROM_VERSION_3_2                0x3002  /* different frequency representation (eeprom_bin2freq) */
-#define AR5K_EEPROM_VERSION_3_3                0x3003  /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
-#define AR5K_EEPROM_VERSION_3_4                0x3004  /* has ee_i_gain, ee_cck_ofdm_power_delta (eeprom_read_modes) */
-#define AR5K_EEPROM_VERSION_4_0                0x4000  /* has ee_misc, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
-#define AR5K_EEPROM_VERSION_4_1                0x4001  /* has ee_margin_tx_rx (eeprom_init) */
-#define AR5K_EEPROM_VERSION_4_2                0x4002  /* has ee_cck_ofdm_gain_delta (eeprom_init) */
-#define AR5K_EEPROM_VERSION_4_3                0x4003  /* power calibration changes */
-#define AR5K_EEPROM_VERSION_4_4                0x4004
-#define AR5K_EEPROM_VERSION_4_5                0x4005
-#define AR5K_EEPROM_VERSION_4_6                0x4006  /* has ee_scaled_cck_delta */
-#define AR5K_EEPROM_VERSION_4_7                0x3007  /* 4007 ? */
-#define AR5K_EEPROM_VERSION_4_9                0x4009  /* EAR futureproofing */
-#define AR5K_EEPROM_VERSION_5_0                0x5000  /* Has 2413 PDADC calibration etc */
-#define AR5K_EEPROM_VERSION_5_1                0x5001  /* Has capability values */
-#define AR5K_EEPROM_VERSION_5_3                0x5003  /* Has spur mitigation tables */
-
-#define AR5K_EEPROM_MODE_11A           0
-#define AR5K_EEPROM_MODE_11B           1
-#define AR5K_EEPROM_MODE_11G           2
-
-#define AR5K_EEPROM_HDR                        AR5K_EEPROM_INFO(2)     /* Header that contains the device caps */
-#define AR5K_EEPROM_HDR_11A(_v)                (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
-#define AR5K_EEPROM_HDR_11B(_v)                (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
-#define AR5K_EEPROM_HDR_11G(_v)                (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
-#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1)     /* Disable turbo for 2Ghz (?) */
-#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f)    /* Max turbo power for a/XR mode (eeprom_init) */
-#define AR5K_EEPROM_HDR_DEVICE(_v)     (((_v) >> 11) & 0x7)
-#define AR5K_EEPROM_HDR_RFKILL(_v)     (((_v) >> 14) & 0x1)    /* Device has RFKill support */
-#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1)    /* Disable turbo for 5Ghz */
-
-#define AR5K_EEPROM_RFKILL_GPIO_SEL    0x0000001c
-#define AR5K_EEPROM_RFKILL_GPIO_SEL_S  2
-#define AR5K_EEPROM_RFKILL_POLARITY    0x00000002
-#define AR5K_EEPROM_RFKILL_POLARITY_S  1
-
-/* Newer EEPROMs are using a different offset */
-#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
-       (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
-
-#define AR5K_EEPROM_ANT_GAIN(_v)       AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
-#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v)  ((s8)(((_v) >> 8) & 0xff))
-#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v)  ((s8)((_v) & 0xff))
-
-/* Misc values available since EEPROM 4.0 */
-#define AR5K_EEPROM_MISC0              AR5K_EEPROM_INFO(4)
-#define AR5K_EEPROM_EARSTART(_v)       ((_v) & 0xfff)
-#define AR5K_EEPROM_HDR_XR2_DIS(_v)    (((_v) >> 12) & 0x1)
-#define AR5K_EEPROM_HDR_XR5_DIS(_v)    (((_v) >> 13) & 0x1)
-#define AR5K_EEPROM_EEMAP(_v)          (((_v) >> 14) & 0x3)
-
-#define AR5K_EEPROM_MISC1                      AR5K_EEPROM_INFO(5)
-#define AR5K_EEPROM_TARGET_PWRSTART(_v)                ((_v) & 0xfff)
-#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v)                (((_v) >> 14) & 0x1)
-#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v)    (((_v) >> 15) & 0x1)
-
-#define AR5K_EEPROM_MISC2                      AR5K_EEPROM_INFO(6)
-#define AR5K_EEPROM_EEP_FILE_VERSION(_v)       (((_v) >> 8) & 0xff)
-#define AR5K_EEPROM_EAR_FILE_VERSION(_v)       ((_v) & 0xff)
-
-#define AR5K_EEPROM_MISC3              AR5K_EEPROM_INFO(7)
-#define AR5K_EEPROM_ART_BUILD_NUM(_v)  (((_v) >> 10) & 0x3f)
-#define AR5K_EEPROM_EAR_FILE_ID(_v)    ((_v) & 0xff)
-
-#define AR5K_EEPROM_MISC4              AR5K_EEPROM_INFO(8)
-#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff)
-#define AR5K_EEPROM_MASK_R0(_v)                (((_v) >> 2) & 0x3)
-#define AR5K_EEPROM_MASK_R1(_v)                ((_v) & 0x3)
-
-#define AR5K_EEPROM_MISC5              AR5K_EEPROM_INFO(9)
-#define AR5K_EEPROM_COMP_DIS(_v)       ((_v) & 0x1)
-#define AR5K_EEPROM_AES_DIS(_v)                (((_v) >> 1) & 0x1)
-#define AR5K_EEPROM_FF_DIS(_v)         (((_v) >> 2) & 0x1)
-#define AR5K_EEPROM_BURST_DIS(_v)      (((_v) >> 3) & 0x1)
-#define AR5K_EEPROM_MAX_QCU(_v)                (((_v) >> 4) & 0xf)
-#define AR5K_EEPROM_HEAVY_CLIP_EN(_v)  (((_v) >> 8) & 0x1)
-#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf)
-
-#define AR5K_EEPROM_MISC6              AR5K_EEPROM_INFO(10)
-#define AR5K_EEPROM_TX_CHAIN_DIS       ((_v) & 0x8)
-#define AR5K_EEPROM_RX_CHAIN_DIS       (((_v) >> 3) & 0x8)
-#define AR5K_EEPROM_FCC_MID_EN         (((_v) >> 6) & 0x1)
-#define AR5K_EEPROM_JAP_U1EVEN_EN      (((_v) >> 7) & 0x1)
-#define AR5K_EEPROM_JAP_U2_EN          (((_v) >> 8) & 0x1)
-#define AR5K_EEPROM_JAP_U1ODD_EN       (((_v) >> 9) & 0x1)
-#define AR5K_EEPROM_JAP_11A_NEW_EN     (((_v) >> 10) & 0x1)
-
-/* calibration settings */
-#define AR5K_EEPROM_MODES_11A(_v)      AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
-#define AR5K_EEPROM_MODES_11B(_v)      AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
-#define AR5K_EEPROM_MODES_11G(_v)      AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
-#define AR5K_EEPROM_CTL(_v)            AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128)     /* Conformance test limits */
-#define AR5K_EEPROM_GROUPS_START(_v)   AR5K_EEPROM_OFF(_v, 0x0100, 0x0150)     /* Start of Groups */
-#define AR5K_EEPROM_GROUP1_OFFSET      0x0
-#define AR5K_EEPROM_GROUP2_OFFSET      0x5
-#define AR5K_EEPROM_GROUP3_OFFSET      0x37
-#define AR5K_EEPROM_GROUP4_OFFSET      0x46
-#define AR5K_EEPROM_GROUP5_OFFSET      0x55
-#define AR5K_EEPROM_GROUP6_OFFSET      0x65
-#define AR5K_EEPROM_GROUP7_OFFSET      0x69
-#define AR5K_EEPROM_GROUP8_OFFSET      0x6f
-
-#define AR5K_EEPROM_TARGET_PWR_OFF_11A(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
-                                                               AR5K_EEPROM_GROUP5_OFFSET, 0x0000)
-#define AR5K_EEPROM_TARGET_PWR_OFF_11B(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
-                                                               AR5K_EEPROM_GROUP6_OFFSET, 0x0010)
-#define AR5K_EEPROM_TARGET_PWR_OFF_11G(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
-                                                               AR5K_EEPROM_GROUP7_OFFSET, 0x0014)
-
-/* [3.1 - 3.3] */
-#define AR5K_EEPROM_OBDB0_2GHZ         0x00ec
-#define AR5K_EEPROM_OBDB1_2GHZ         0x00ed
-
-#define AR5K_EEPROM_PROTECT            0x003f  /* EEPROM protect status */
-#define AR5K_EEPROM_PROTECT_RD_0_31    0x0001  /* Read protection bit for offsets 0x0 - 0x1f */
-#define AR5K_EEPROM_PROTECT_WR_0_31    0x0002  /* Write protection bit for offsets 0x0 - 0x1f */
-#define AR5K_EEPROM_PROTECT_RD_32_63   0x0004  /* 0x20 - 0x3f */
-#define AR5K_EEPROM_PROTECT_WR_32_63   0x0008
-#define AR5K_EEPROM_PROTECT_RD_64_127  0x0010  /* 0x40 - 0x7f */
-#define AR5K_EEPROM_PROTECT_WR_64_127  0x0020
-#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040  /* 0x80 - 0xbf (regdom) */
-#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
-#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100  /* 0xc0 - 0xcf */
-#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
-#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400  /* 0xd0 - 0xdf */
-#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
-#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000  /* 0xe0 - 0xef */
-#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
-#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000  /* 0xf0 - 0xff */
-#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
-
-/* Some EEPROM defines */
-#define AR5K_EEPROM_EEP_SCALE          100
-#define AR5K_EEPROM_EEP_DELTA          10
-#define AR5K_EEPROM_N_MODES            3
-#define AR5K_EEPROM_N_5GHZ_CHAN                10
-#define AR5K_EEPROM_N_2GHZ_CHAN                3
-#define AR5K_EEPROM_N_2GHZ_CHAN_2413   4
-#define        AR5K_EEPROM_N_2GHZ_CHAN_MAX     4
-#define AR5K_EEPROM_MAX_CHAN           10
-#define AR5K_EEPROM_N_PWR_POINTS_5111  11
-#define AR5K_EEPROM_N_PCDAC            11
-#define AR5K_EEPROM_N_PHASE_CAL                5
-#define AR5K_EEPROM_N_TEST_FREQ                8
-#define AR5K_EEPROM_N_EDGES            8
-#define AR5K_EEPROM_N_INTERCEPTS       11
-#define AR5K_EEPROM_FREQ_M(_v)         AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
-#define AR5K_EEPROM_PCDAC_M            0x3f
-#define AR5K_EEPROM_PCDAC_START                1
-#define AR5K_EEPROM_PCDAC_STOP         63
-#define AR5K_EEPROM_PCDAC_STEP         1
-#define AR5K_EEPROM_NON_EDGE_M         0x40
-#define AR5K_EEPROM_CHANNEL_POWER      8
-#define AR5K_EEPROM_N_OBDB             4
-#define AR5K_EEPROM_OBDB_DIS           0xffff
-#define AR5K_EEPROM_CHANNEL_DIS                0xff
-#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
-#define AR5K_EEPROM_N_CTLS(_v)         AR5K_EEPROM_OFF(_v, 16, 32)
-#define AR5K_EEPROM_MAX_CTLS           32
-#define AR5K_EEPROM_N_PD_CURVES                4
-#define AR5K_EEPROM_N_XPD0_POINTS      4
-#define AR5K_EEPROM_N_XPD3_POINTS      3
-#define AR5K_EEPROM_N_PD_GAINS         4
-#define AR5K_EEPROM_N_PD_POINTS                5
-#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ        35
-#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ        55
-#define AR5K_EEPROM_POWER_M            0x3f
-#define AR5K_EEPROM_POWER_MIN          0
-#define AR5K_EEPROM_POWER_MAX          3150
-#define AR5K_EEPROM_POWER_STEP         50
-#define AR5K_EEPROM_POWER_TABLE_SIZE   64
-#define AR5K_EEPROM_N_POWER_LOC_11B    4
-#define AR5K_EEPROM_N_POWER_LOC_11G    6
-#define AR5K_EEPROM_I_GAIN             10
-#define AR5K_EEPROM_CCK_OFDM_DELTA     15
-#define AR5K_EEPROM_N_IQ_CAL           2
-
-#define AR5K_EEPROM_READ(_o, _v) do {                  \
-       ret = ath5k_hw_eeprom_read(ah, (_o), &(_v));    \
-       if (ret)                                        \
-               return ret;                             \
-} while (0)
-
-#define AR5K_EEPROM_READ_HDR(_o, _v)                                   \
-       AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v);        \
-
-enum ath5k_ant_setting {
-       AR5K_ANT_VARIABLE       = 0,    /* variable by programming */
-       AR5K_ANT_FIXED_A        = 1,    /* fixed to 11a frequencies */
-       AR5K_ANT_FIXED_B        = 2,    /* fixed to 11b frequencies */
-       AR5K_ANT_MAX            = 3,
-};
-
-enum ath5k_ctl_mode {
-       AR5K_CTL_11A = 0,
-       AR5K_CTL_11B = 1,
-       AR5K_CTL_11G = 2,
-       AR5K_CTL_TURBO = 3,
-       AR5K_CTL_TURBOG = 4,
-       AR5K_CTL_2GHT20 = 5,
-       AR5K_CTL_5GHT20 = 6,
-       AR5K_CTL_2GHT40 = 7,
-       AR5K_CTL_5GHT40 = 8,
-       AR5K_CTL_MODE_M = 15,
-};
-
-/* Default CTL ids for the 3 main reg domains.
- * Atheros only uses these by default but vendors
- * can have up to 32 different CTLs for different
- * scenarios. Note that theese values are ORed with
- * the mode id (above) so we can have up to 24 CTL
- * datasets out of these 3 main regdomains. That leaves
- * 8 ids that can be used by vendors and since 0x20 is
- * missing from HAL sources i guess this is the set of
- * custom CTLs vendors can use. */
-#define        AR5K_CTL_FCC    0x10
-#define        AR5K_CTL_CUSTOM 0x20
-#define        AR5K_CTL_ETSI   0x30
-#define        AR5K_CTL_MKK    0x40
-
-/* Indicates a CTL with only mode set and
- * no reg domain mapping, such CTLs are used
- * for world roaming domains or simply when
- * a reg domain is not set */
-#define        AR5K_CTL_NO_REGDOMAIN   0xf0
-
-/* Indicates an empty (invalid) CTL */
-#define AR5K_CTL_NO_CTL                0xff
-
-/* Per channel calibration data, used for power table setup */
-struct ath5k_chan_pcal_info_rf5111 {
-       /* Power levels in half dbm units
-        * for one power curve. */
-       u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
-       /* PCDAC table steps
-        * for the above values */
-       u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111];
-       /* Starting PCDAC step */
-       u8 pcdac_min;
-       /* Final PCDAC step */
-       u8 pcdac_max;
-};
-
-struct ath5k_chan_pcal_info_rf5112 {
-       /* Power levels in quarter dBm units
-        * for lower (0) and higher (3)
-        * level curves in 0.25dB units */
-       s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
-       s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
-       /* PCDAC table steps
-        * for the above values */
-       u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
-       u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
-};
-
-struct ath5k_chan_pcal_info_rf2413 {
-       /* Starting pwr/pddac values */
-       s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
-       u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
-       /* (pwr,pddac) points
-        * power levels in 0.5dB units */
-       s8 pwr[AR5K_EEPROM_N_PD_GAINS]
-               [AR5K_EEPROM_N_PD_POINTS];
-       u8 pddac[AR5K_EEPROM_N_PD_GAINS]
-               [AR5K_EEPROM_N_PD_POINTS];
-};
-
-enum ath5k_powertable_type {
-       AR5K_PWRTABLE_PWR_TO_PCDAC = 0,
-       AR5K_PWRTABLE_LINEAR_PCDAC = 1,
-       AR5K_PWRTABLE_PWR_TO_PDADC = 2,
-};
-
-struct ath5k_pdgain_info {
-       u8 pd_points;
-       u8 *pd_step;
-       /* Power values are in
-        * 0.25dB units */
-       s16 *pd_pwr;
-};
-
-struct ath5k_chan_pcal_info {
-       /* Frequency */
-       u16     freq;
-       /* Tx power boundaries */
-       s16     max_pwr;
-       s16     min_pwr;
-       union {
-               struct ath5k_chan_pcal_info_rf5111 rf5111_info;
-               struct ath5k_chan_pcal_info_rf5112 rf5112_info;
-               struct ath5k_chan_pcal_info_rf2413 rf2413_info;
-       };
-       /* Raw values used by phy code
-        * Curves are stored in order from lower
-        * gain to higher gain (max txpower -> min txpower) */
-       struct ath5k_pdgain_info *pd_curves;
-};
-
-/* Per rate calibration data for each mode,
- * used for rate power table setup.
- * Note: Values in 0.5dB units */
-struct ath5k_rate_pcal_info {
-       u16     freq; /* Frequency */
-       /* Power level for 6-24Mbit/s rates or
-        * 1Mb rate */
-       u16     target_power_6to24;
-       /* Power level for 36Mbit rate or
-        * 2Mb rate */
-       u16     target_power_36;
-       /* Power level for 48Mbit rate or
-        * 5.5Mbit rate */
-       u16     target_power_48;
-       /* Power level for 54Mbit rate or
-        * 11Mbit rate */
-       u16     target_power_54;
-};
-
-/* Power edges for conformance test limits */
-struct ath5k_edge_power {
-       u16 freq;
-       u16 edge; /* in half dBm */
-       bool flag;
-};
-
-/* EEPROM calibration data */
-struct ath5k_eeprom_info {
-
-       /* Header information */
-       u16     ee_magic;
-       u16     ee_protect;
-       u16     ee_regdomain;
-       u16     ee_version;
-       u16     ee_header;
-       u16     ee_ant_gain;
-       u16     ee_misc0;
-       u16     ee_misc1;
-       u16     ee_misc2;
-       u16     ee_misc3;
-       u16     ee_misc4;
-       u16     ee_misc5;
-       u16     ee_misc6;
-       u16     ee_cck_ofdm_gain_delta;
-       u16     ee_cck_ofdm_power_delta;
-       u16     ee_scaled_cck_delta;
-
-       /* RF Calibration settings (reset, rfregs) */
-       u16     ee_i_cal[AR5K_EEPROM_N_MODES];
-       u16     ee_q_cal[AR5K_EEPROM_N_MODES];
-       u16     ee_fixed_bias[AR5K_EEPROM_N_MODES];
-       u16     ee_turbo_max_power[AR5K_EEPROM_N_MODES];
-       u16     ee_xr_power[AR5K_EEPROM_N_MODES];
-       u16     ee_switch_settling[AR5K_EEPROM_N_MODES];
-       u16     ee_atn_tx_rx[AR5K_EEPROM_N_MODES];
-       u16     ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
-       u16     ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
-       u16     ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
-       u16     ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
-       u16     ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
-       u16     ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
-       u16     ee_thr_62[AR5K_EEPROM_N_MODES];
-       u16     ee_xlna_gain[AR5K_EEPROM_N_MODES];
-       u16     ee_xpd[AR5K_EEPROM_N_MODES];
-       u16     ee_x_gain[AR5K_EEPROM_N_MODES];
-       u16     ee_i_gain[AR5K_EEPROM_N_MODES];
-       u16     ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
-       u16     ee_switch_settling_turbo[AR5K_EEPROM_N_MODES];
-       u16     ee_margin_tx_rx_turbo[AR5K_EEPROM_N_MODES];
-       u16     ee_atn_tx_rx_turbo[AR5K_EEPROM_N_MODES];
-
-       /* Power calibration data */
-       u16     ee_false_detect[AR5K_EEPROM_N_MODES];
-
-       /* Number of pd gain curves per mode */
-       u8      ee_pd_gains[AR5K_EEPROM_N_MODES];
-       /* Back mapping pdcurve number -> pdcurve index in pd->pd_curves */
-       u8      ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS];
-
-       u8      ee_n_piers[AR5K_EEPROM_N_MODES];
-       struct ath5k_chan_pcal_info     ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
-       struct ath5k_chan_pcal_info     ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
-       struct ath5k_chan_pcal_info     ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
-
-       /* Per rate target power levels */
-       u8      ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES];
-       struct ath5k_rate_pcal_info     ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
-       struct ath5k_rate_pcal_info     ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
-       struct ath5k_rate_pcal_info     ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
-
-       /* Conformance test limits (Unused) */
-       u8      ee_ctls;
-       u8      ee_ctl[AR5K_EEPROM_MAX_CTLS];
-       struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS];
-
-       /* Noise Floor Calibration settings */
-       s16     ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
-       s8      ee_adc_desired_size[AR5K_EEPROM_N_MODES];
-       s8      ee_pga_desired_size[AR5K_EEPROM_N_MODES];
-       s8      ee_adc_desired_size_turbo[AR5K_EEPROM_N_MODES];
-       s8      ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES];
-       s8      ee_pd_gain_overlap;
-
-       u32     ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
-};
-
diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath5k/gpio.c
deleted file mode 100644 (file)
index 64a27e7..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/****************\
-  GPIO Functions
-\****************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Set led state
- */
-void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
-{
-       u32 led;
-       /*5210 has different led mode handling*/
-       u32 led_5210;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*Reset led status*/
-       if (ah->ah_version != AR5K_AR5210)
-               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
-                       AR5K_PCICFG_LEDMODE |  AR5K_PCICFG_LED);
-       else
-               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
-
-       /*
-        * Some blinking values, define at your wish
-        */
-       switch (state) {
-       case AR5K_LED_SCAN:
-       case AR5K_LED_AUTH:
-               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
-               led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
-               break;
-
-       case AR5K_LED_INIT:
-               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
-               led_5210 = AR5K_PCICFG_LED_PEND;
-               break;
-
-       case AR5K_LED_ASSOC:
-       case AR5K_LED_RUN:
-               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
-               led_5210 = AR5K_PCICFG_LED_ASSOC;
-               break;
-
-       default:
-               led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
-               led_5210 = AR5K_PCICFG_LED_PEND;
-               break;
-       }
-
-       /*Write new status to the register*/
-       if (ah->ah_version != AR5K_AR5210)
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
-       else
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
-}
-
-/*
- * Set GPIO inputs
- */
-int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (gpio >= AR5K_NUM_GPIO)
-               return -EINVAL;
-
-       ath5k_hw_reg_write(ah,
-               (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
-               | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
-
-       return 0;
-}
-
-/*
- * Set GPIO outputs
- */
-int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (gpio >= AR5K_NUM_GPIO)
-               return -EINVAL;
-
-       ath5k_hw_reg_write(ah,
-               (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
-               | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
-
-       return 0;
-}
-
-/*
- * Get GPIO state
- */
-u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (gpio >= AR5K_NUM_GPIO)
-               return 0xffffffff;
-
-       /* GPIO input magic */
-       return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
-               0x1;
-}
-
-/*
- * Set GPIO state
- */
-int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
-{
-       u32 data;
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (gpio >= AR5K_NUM_GPIO)
-               return -EINVAL;
-
-       /* GPIO output magic */
-       data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
-
-       data &= ~(1 << gpio);
-       data |= (val & 1) << gpio;
-
-       ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
-
-       return 0;
-}
-
-/*
- * Initialize the GPIO interrupt (RFKill switch)
- */
-void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
-               u32 interrupt_level)
-{
-       u32 data;
-
-       ATH5K_TRACE(ah->ah_sc);
-       if (gpio >= AR5K_NUM_GPIO)
-               return;
-
-       /*
-        * Set the GPIO interrupt
-        */
-       data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
-               ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
-               AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
-               (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
-
-       ath5k_hw_reg_write(ah, interrupt_level ? data :
-               (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
-
-       ah->ah_imr |= AR5K_IMR_GPIO;
-
-       /* Enable GPIO interrupts */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
-}
-
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
deleted file mode 100644 (file)
index 61fb621..0000000
+++ /dev/null
@@ -1,1557 +0,0 @@
-/*
- * Initial register settings functions
- *
- * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- *
- * Permission to use, copy, modify, and 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 "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Mode-independent initial register writes
- */
-
-struct ath5k_ini {
-       u16     ini_register;
-       u32     ini_value;
-
-       enum {
-               AR5K_INI_WRITE = 0,     /* Default */
-               AR5K_INI_READ = 1,      /* Cleared on read */
-       } ini_mode;
-};
-
-/*
- * Mode specific initial register values
- */
-
-struct ath5k_ini_mode {
-       u16     mode_register;
-       u32     mode_value[5];
-};
-
-/* Initial register settings for AR5210 */
-static const struct ath5k_ini ar5210_ini[] = {
-       /* PCU and MAC registers */
-       { AR5K_NOQCU_TXDP0,     0 },
-       { AR5K_NOQCU_TXDP1,     0 },
-       { AR5K_RXDP,            0 },
-       { AR5K_CR,              0 },
-       { AR5K_ISR,             0, AR5K_INI_READ },
-       { AR5K_IMR,             0 },
-       { AR5K_IER,             AR5K_IER_DISABLE },
-       { AR5K_BSR,             0, AR5K_INI_READ },
-       { AR5K_TXCFG,           AR5K_DMASIZE_128B },
-       { AR5K_RXCFG,           AR5K_DMASIZE_128B },
-       { AR5K_CFG,             AR5K_INIT_CFG },
-       { AR5K_TOPS,            8 },
-       { AR5K_RXNOFRM,         8 },
-       { AR5K_RPGTO,           0 },
-       { AR5K_TXNOFRM,         0 },
-       { AR5K_SFR,             0 },
-       { AR5K_MIBC,            0 },
-       { AR5K_MISC,            0 },
-       { AR5K_RX_FILTER_5210,  0 },
-       { AR5K_MCAST_FILTER0_5210, 0 },
-       { AR5K_MCAST_FILTER1_5210, 0 },
-       { AR5K_TX_MASK0,        0 },
-       { AR5K_TX_MASK1,        0 },
-       { AR5K_CLR_TMASK,       0 },
-       { AR5K_TRIG_LVL,        AR5K_TUNE_MIN_TX_FIFO_THRES },
-       { AR5K_DIAG_SW_5210,    0 },
-       { AR5K_RSSI_THR,        AR5K_TUNE_RSSI_THRES },
-       { AR5K_TSF_L32_5210,    0 },
-       { AR5K_TIMER0_5210,     0 },
-       { AR5K_TIMER1_5210,     0xffffffff },
-       { AR5K_TIMER2_5210,     0xffffffff },
-       { AR5K_TIMER3_5210,     1 },
-       { AR5K_CFP_DUR_5210,    0 },
-       { AR5K_CFP_PERIOD_5210, 0 },
-       /* PHY registers */
-       { AR5K_PHY(0),  0x00000047 },
-       { AR5K_PHY_AGC, 0x00000000 },
-       { AR5K_PHY(3),  0x09848ea6 },
-       { AR5K_PHY(4),  0x3d32e000 },
-       { AR5K_PHY(5),  0x0000076b },
-       { AR5K_PHY_ACT, AR5K_PHY_ACT_DISABLE },
-       { AR5K_PHY(8),  0x02020200 },
-       { AR5K_PHY(9),  0x00000e0e },
-       { AR5K_PHY(10), 0x0a020201 },
-       { AR5K_PHY(11), 0x00036ffc },
-       { AR5K_PHY(12), 0x00000000 },
-       { AR5K_PHY(13), 0x00000e0e },
-       { AR5K_PHY(14), 0x00000007 },
-       { AR5K_PHY(15), 0x00020100 },
-       { AR5K_PHY(16), 0x89630000 },
-       { AR5K_PHY(17), 0x1372169c },
-       { AR5K_PHY(18), 0x0018b633 },
-       { AR5K_PHY(19), 0x1284613c },
-       { AR5K_PHY(20), 0x0de8b8e0 },
-       { AR5K_PHY(21), 0x00074859 },
-       { AR5K_PHY(22), 0x7e80beba },
-       { AR5K_PHY(23), 0x313a665e },
-       { AR5K_PHY_AGCCTL, 0x00001d08 },
-       { AR5K_PHY(25), 0x0001ce00 },
-       { AR5K_PHY(26), 0x409a4190 },
-       { AR5K_PHY(28), 0x0000000f },
-       { AR5K_PHY(29), 0x00000080 },
-       { AR5K_PHY(30), 0x00000004 },
-       { AR5K_PHY(31), 0x00000018 },   /* 0x987c */
-       { AR5K_PHY(64), 0x00000000 },   /* 0x9900 */
-       { AR5K_PHY(65), 0x00000000 },
-       { AR5K_PHY(66), 0x00000000 },
-       { AR5K_PHY(67), 0x00800000 },
-       { AR5K_PHY(68), 0x00000003 },
-       /* BB gain table (64bytes) */
-       { AR5K_BB_GAIN(0), 0x00000000 },
-       { AR5K_BB_GAIN(1), 0x00000020 },
-       { AR5K_BB_GAIN(2), 0x00000010 },
-       { AR5K_BB_GAIN(3), 0x00000030 },
-       { AR5K_BB_GAIN(4), 0x00000008 },
-       { AR5K_BB_GAIN(5), 0x00000028 },
-       { AR5K_BB_GAIN(6), 0x00000028 },
-       { AR5K_BB_GAIN(7), 0x00000004 },
-       { AR5K_BB_GAIN(8), 0x00000024 },
-       { AR5K_BB_GAIN(9), 0x00000014 },
-       { AR5K_BB_GAIN(10), 0x00000034 },
-       { AR5K_BB_GAIN(11), 0x0000000c },
-       { AR5K_BB_GAIN(12), 0x0000002c },
-       { AR5K_BB_GAIN(13), 0x00000002 },
-       { AR5K_BB_GAIN(14), 0x00000022 },
-       { AR5K_BB_GAIN(15), 0x00000012 },
-       { AR5K_BB_GAIN(16), 0x00000032 },
-       { AR5K_BB_GAIN(17), 0x0000000a },
-       { AR5K_BB_GAIN(18), 0x0000002a },
-       { AR5K_BB_GAIN(19), 0x00000001 },
-       { AR5K_BB_GAIN(20), 0x00000021 },
-       { AR5K_BB_GAIN(21), 0x00000011 },
-       { AR5K_BB_GAIN(22), 0x00000031 },
-       { AR5K_BB_GAIN(23), 0x00000009 },
-       { AR5K_BB_GAIN(24), 0x00000029 },
-       { AR5K_BB_GAIN(25), 0x00000005 },
-       { AR5K_BB_GAIN(26), 0x00000025 },
-       { AR5K_BB_GAIN(27), 0x00000015 },
-       { AR5K_BB_GAIN(28), 0x00000035 },
-       { AR5K_BB_GAIN(29), 0x0000000d },
-       { AR5K_BB_GAIN(30), 0x0000002d },
-       { AR5K_BB_GAIN(31), 0x00000003 },
-       { AR5K_BB_GAIN(32), 0x00000023 },
-       { AR5K_BB_GAIN(33), 0x00000013 },
-       { AR5K_BB_GAIN(34), 0x00000033 },
-       { AR5K_BB_GAIN(35), 0x0000000b },
-       { AR5K_BB_GAIN(36), 0x0000002b },
-       { AR5K_BB_GAIN(37), 0x00000007 },
-       { AR5K_BB_GAIN(38), 0x00000027 },
-       { AR5K_BB_GAIN(39), 0x00000017 },
-       { AR5K_BB_GAIN(40), 0x00000037 },
-       { AR5K_BB_GAIN(41), 0x0000000f },
-       { AR5K_BB_GAIN(42), 0x0000002f },
-       { AR5K_BB_GAIN(43), 0x0000002f },
-       { AR5K_BB_GAIN(44), 0x0000002f },
-       { AR5K_BB_GAIN(45), 0x0000002f },
-       { AR5K_BB_GAIN(46), 0x0000002f },
-       { AR5K_BB_GAIN(47), 0x0000002f },
-       { AR5K_BB_GAIN(48), 0x0000002f },
-       { AR5K_BB_GAIN(49), 0x0000002f },
-       { AR5K_BB_GAIN(50), 0x0000002f },
-       { AR5K_BB_GAIN(51), 0x0000002f },
-       { AR5K_BB_GAIN(52), 0x0000002f },
-       { AR5K_BB_GAIN(53), 0x0000002f },
-       { AR5K_BB_GAIN(54), 0x0000002f },
-       { AR5K_BB_GAIN(55), 0x0000002f },
-       { AR5K_BB_GAIN(56), 0x0000002f },
-       { AR5K_BB_GAIN(57), 0x0000002f },
-       { AR5K_BB_GAIN(58), 0x0000002f },
-       { AR5K_BB_GAIN(59), 0x0000002f },
-       { AR5K_BB_GAIN(60), 0x0000002f },
-       { AR5K_BB_GAIN(61), 0x0000002f },
-       { AR5K_BB_GAIN(62), 0x0000002f },
-       { AR5K_BB_GAIN(63), 0x0000002f },
-       /* 5110 RF gain table (64btes) */
-       { AR5K_RF_GAIN(0), 0x0000001d },
-       { AR5K_RF_GAIN(1), 0x0000005d },
-       { AR5K_RF_GAIN(2), 0x0000009d },
-       { AR5K_RF_GAIN(3), 0x000000dd },
-       { AR5K_RF_GAIN(4), 0x0000011d },
-       { AR5K_RF_GAIN(5), 0x00000021 },
-       { AR5K_RF_GAIN(6), 0x00000061 },
-       { AR5K_RF_GAIN(7), 0x000000a1 },
-       { AR5K_RF_GAIN(8), 0x000000e1 },
-       { AR5K_RF_GAIN(9), 0x00000031 },
-       { AR5K_RF_GAIN(10), 0x00000071 },
-       { AR5K_RF_GAIN(11), 0x000000b1 },
-       { AR5K_RF_GAIN(12), 0x0000001c },
-       { AR5K_RF_GAIN(13), 0x0000005c },
-       { AR5K_RF_GAIN(14), 0x00000029 },
-       { AR5K_RF_GAIN(15), 0x00000069 },
-       { AR5K_RF_GAIN(16), 0x000000a9 },
-       { AR5K_RF_GAIN(17), 0x00000020 },
-       { AR5K_RF_GAIN(18), 0x00000019 },
-       { AR5K_RF_GAIN(19), 0x00000059 },
-       { AR5K_RF_GAIN(20), 0x00000099 },
-       { AR5K_RF_GAIN(21), 0x00000030 },
-       { AR5K_RF_GAIN(22), 0x00000005 },
-       { AR5K_RF_GAIN(23), 0x00000025 },
-       { AR5K_RF_GAIN(24), 0x00000065 },
-       { AR5K_RF_GAIN(25), 0x000000a5 },
-       { AR5K_RF_GAIN(26), 0x00000028 },
-       { AR5K_RF_GAIN(27), 0x00000068 },
-       { AR5K_RF_GAIN(28), 0x0000001f },
-       { AR5K_RF_GAIN(29), 0x0000001e },
-       { AR5K_RF_GAIN(30), 0x00000018 },
-       { AR5K_RF_GAIN(31), 0x00000058 },
-       { AR5K_RF_GAIN(32), 0x00000098 },
-       { AR5K_RF_GAIN(33), 0x00000003 },
-       { AR5K_RF_GAIN(34), 0x00000004 },
-       { AR5K_RF_GAIN(35), 0x00000044 },
-       { AR5K_RF_GAIN(36), 0x00000084 },
-       { AR5K_RF_GAIN(37), 0x00000013 },
-       { AR5K_RF_GAIN(38), 0x00000012 },
-       { AR5K_RF_GAIN(39), 0x00000052 },
-       { AR5K_RF_GAIN(40), 0x00000092 },
-       { AR5K_RF_GAIN(41), 0x000000d2 },
-       { AR5K_RF_GAIN(42), 0x0000002b },
-       { AR5K_RF_GAIN(43), 0x0000002a },
-       { AR5K_RF_GAIN(44), 0x0000006a },
-       { AR5K_RF_GAIN(45), 0x000000aa },
-       { AR5K_RF_GAIN(46), 0x0000001b },
-       { AR5K_RF_GAIN(47), 0x0000001a },
-       { AR5K_RF_GAIN(48), 0x0000005a },
-       { AR5K_RF_GAIN(49), 0x0000009a },
-       { AR5K_RF_GAIN(50), 0x000000da },
-       { AR5K_RF_GAIN(51), 0x00000006 },
-       { AR5K_RF_GAIN(52), 0x00000006 },
-       { AR5K_RF_GAIN(53), 0x00000006 },
-       { AR5K_RF_GAIN(54), 0x00000006 },
-       { AR5K_RF_GAIN(55), 0x00000006 },
-       { AR5K_RF_GAIN(56), 0x00000006 },
-       { AR5K_RF_GAIN(57), 0x00000006 },
-       { AR5K_RF_GAIN(58), 0x00000006 },
-       { AR5K_RF_GAIN(59), 0x00000006 },
-       { AR5K_RF_GAIN(60), 0x00000006 },
-       { AR5K_RF_GAIN(61), 0x00000006 },
-       { AR5K_RF_GAIN(62), 0x00000006 },
-       { AR5K_RF_GAIN(63), 0x00000006 },
-       /* PHY activation */
-       { AR5K_PHY(53), 0x00000020 },
-       { AR5K_PHY(51), 0x00000004 },
-       { AR5K_PHY(50), 0x00060106 },
-       { AR5K_PHY(39), 0x0000006d },
-       { AR5K_PHY(48), 0x00000000 },
-       { AR5K_PHY(52), 0x00000014 },
-       { AR5K_PHY_ACT, AR5K_PHY_ACT_ENABLE },
-};
-
-/* Initial register settings for AR5211 */
-static const struct ath5k_ini ar5211_ini[] = {
-       { AR5K_RXDP,            0x00000000 },
-       { AR5K_RTSD0,           0x84849c9c },
-       { AR5K_RTSD1,           0x7c7c7c7c },
-       { AR5K_RXCFG,           0x00000005 },
-       { AR5K_MIBC,            0x00000000 },
-       { AR5K_TOPS,            0x00000008 },
-       { AR5K_RXNOFRM,         0x00000008 },
-       { AR5K_TXNOFRM,         0x00000010 },
-       { AR5K_RPGTO,           0x00000000 },
-       { AR5K_RFCNT,           0x0000001f },
-       { AR5K_QUEUE_TXDP(0),   0x00000000 },
-       { AR5K_QUEUE_TXDP(1),   0x00000000 },
-       { AR5K_QUEUE_TXDP(2),   0x00000000 },
-       { AR5K_QUEUE_TXDP(3),   0x00000000 },
-       { AR5K_QUEUE_TXDP(4),   0x00000000 },
-       { AR5K_QUEUE_TXDP(5),   0x00000000 },
-       { AR5K_QUEUE_TXDP(6),   0x00000000 },
-       { AR5K_QUEUE_TXDP(7),   0x00000000 },
-       { AR5K_QUEUE_TXDP(8),   0x00000000 },
-       { AR5K_QUEUE_TXDP(9),   0x00000000 },
-       { AR5K_DCU_FP,          0x00000000 },
-       { AR5K_STA_ID1,         0x00000000 },
-       { AR5K_BSS_ID0,         0x00000000 },
-       { AR5K_BSS_ID1,         0x00000000 },
-       { AR5K_RSSI_THR,        0x00000000 },
-       { AR5K_CFP_PERIOD_5211, 0x00000000 },
-       { AR5K_TIMER0_5211,     0x00000030 },
-       { AR5K_TIMER1_5211,     0x0007ffff },
-       { AR5K_TIMER2_5211,     0x01ffffff },
-       { AR5K_TIMER3_5211,     0x00000031 },
-       { AR5K_CFP_DUR_5211,    0x00000000 },
-       { AR5K_RX_FILTER_5211,  0x00000000 },
-       { AR5K_MCAST_FILTER0_5211, 0x00000000 },
-       { AR5K_MCAST_FILTER1_5211, 0x00000002 },
-       { AR5K_DIAG_SW_5211,    0x00000000 },
-       { AR5K_ADDAC_TEST,      0x00000000 },
-       { AR5K_DEFAULT_ANTENNA, 0x00000000 },
-       /* PHY registers */
-       { AR5K_PHY_AGC, 0x00000000 },
-       { AR5K_PHY(3),  0x2d849093 },
-       { AR5K_PHY(4),  0x7d32e000 },
-       { AR5K_PHY(5),  0x00000f6b },
-       { AR5K_PHY_ACT, 0x00000000 },
-       { AR5K_PHY(11), 0x00026ffe },
-       { AR5K_PHY(12), 0x00000000 },
-       { AR5K_PHY(15), 0x00020100 },
-       { AR5K_PHY(16), 0x206a017a },
-       { AR5K_PHY(19), 0x1284613c },
-       { AR5K_PHY(21), 0x00000859 },
-       { AR5K_PHY(26), 0x409a4190 },   /* 0x9868 */
-       { AR5K_PHY(27), 0x050cb081 },
-       { AR5K_PHY(28), 0x0000000f },
-       { AR5K_PHY(29), 0x00000080 },
-       { AR5K_PHY(30), 0x0000000c },
-       { AR5K_PHY(64), 0x00000000 },
-       { AR5K_PHY(65), 0x00000000 },
-       { AR5K_PHY(66), 0x00000000 },
-       { AR5K_PHY(67), 0x00800000 },
-       { AR5K_PHY(68), 0x00000001 },
-       { AR5K_PHY(71), 0x0000092a },
-       { AR5K_PHY_IQ,  0x00000000 },
-       { AR5K_PHY(73), 0x00058a05 },
-       { AR5K_PHY(74), 0x00000001 },
-       { AR5K_PHY(75), 0x00000000 },
-       { AR5K_PHY_PAPD_PROBE, 0x00000000 },
-       { AR5K_PHY(77), 0x00000000 },   /* 0x9934 */
-       { AR5K_PHY(78), 0x00000000 },   /* 0x9938 */
-       { AR5K_PHY(79), 0x0000003f },   /* 0x993c */
-       { AR5K_PHY(80), 0x00000004 },
-       { AR5K_PHY(82), 0x00000000 },
-       { AR5K_PHY(83), 0x00000000 },
-       { AR5K_PHY(84), 0x00000000 },
-       { AR5K_PHY_RADAR, 0x5d50f14c },
-       { AR5K_PHY(86), 0x00000018 },
-       { AR5K_PHY(87), 0x004b6a8e },
-       /* Initial Power table (32bytes)
-        * common on all cards/modes.
-        * Note: Table is rewritten during
-        * txpower setup later using calibration
-        * data etc. so next write is non-common */
-       { AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff },
-       { AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff },
-       { AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff },
-       { AR5K_PHY_PCDAC_TXPOWER(4), 0x09ff09ff },
-       { AR5K_PHY_PCDAC_TXPOWER(5), 0x0aff0aff },
-       { AR5K_PHY_PCDAC_TXPOWER(6), 0x0bff0bff },
-       { AR5K_PHY_PCDAC_TXPOWER(7), 0x0cff0cff },
-       { AR5K_PHY_PCDAC_TXPOWER(8), 0x0dff0dff },
-       { AR5K_PHY_PCDAC_TXPOWER(9), 0x0fff0eff },
-       { AR5K_PHY_PCDAC_TXPOWER(10), 0x12ff12ff },
-       { AR5K_PHY_PCDAC_TXPOWER(11), 0x14ff13ff },
-       { AR5K_PHY_PCDAC_TXPOWER(12), 0x16ff15ff },
-       { AR5K_PHY_PCDAC_TXPOWER(13), 0x19ff17ff },
-       { AR5K_PHY_PCDAC_TXPOWER(14), 0x1bff1aff },
-       { AR5K_PHY_PCDAC_TXPOWER(15), 0x1eff1dff },
-       { AR5K_PHY_PCDAC_TXPOWER(16), 0x23ff20ff },
-       { AR5K_PHY_PCDAC_TXPOWER(17), 0x27ff25ff },
-       { AR5K_PHY_PCDAC_TXPOWER(18), 0x2cff29ff },
-       { AR5K_PHY_PCDAC_TXPOWER(19), 0x31ff2fff },
-       { AR5K_PHY_PCDAC_TXPOWER(20), 0x37ff34ff },
-       { AR5K_PHY_PCDAC_TXPOWER(21), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(22), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(23), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(24), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(25), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(26), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(27), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },
-       { AR5K_PHY_CCKTXCTL, 0x00000000 },
-       { AR5K_PHY(642), 0x503e4646 },
-       { AR5K_PHY_GAIN_2GHZ, 0x6480416c },
-       { AR5K_PHY(644), 0x0199a003 },
-       { AR5K_PHY(645), 0x044cd610 },
-       { AR5K_PHY(646), 0x13800040 },
-       { AR5K_PHY(647), 0x1be00060 },
-       { AR5K_PHY(648), 0x0c53800a },
-       { AR5K_PHY(649), 0x0014df3b },
-       { AR5K_PHY(650), 0x000001b5 },
-       { AR5K_PHY(651), 0x00000020 },
-};
-
-/* Initial mode-specific settings for AR5211
- * 5211 supports OFDM-only g (draft g) but we
- * need to test it !
- */
-static const struct ath5k_ini_mode ar5211_ini_mode[] = {
-       { AR5K_TXCFG,
-       /*        a         aTurbo        b       g (OFDM)    */
-          { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(1),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(2),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(3),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(4),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(5),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(6),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(7),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(8),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(9),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_DCU_GBL_IFS_SLOT,
-          { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
-       { AR5K_DCU_GBL_IFS_SIFS,
-          { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
-       { AR5K_DCU_GBL_IFS_EIFS,
-          { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
-       { AR5K_DCU_GBL_IFS_MISC,
-          { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
-       { AR5K_TIME_OUT,
-          { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
-       { AR5K_USEC_5211,
-          { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
-       { AR5K_PHY_TURBO,
-          { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
-       { AR5K_PHY(8),
-          { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
-       { AR5K_PHY(9),
-          { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
-       { AR5K_PHY(10),
-          { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
-       { AR5K_PHY(13),
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY(14),
-          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY(17),
-          { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
-       { AR5K_PHY(18),
-          { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
-       { AR5K_PHY(20),
-          { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
-       { AR5K_PHY_SIG,
-          { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
-       { AR5K_PHY_AGCCTL,
-          { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
-       { AR5K_PHY_NF,
-          { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
-       { AR5K_PHY(70),
-          { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
-       { AR5K_PHY_PCDAC_TXPOWER_BASE,
-          { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
-       { AR5K_RF_BUFFER_CONTROL_4,
-          { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
-};
-
-/* Initial register settings for AR5212 */
-static const struct ath5k_ini ar5212_ini_common_start[] = {
-       { AR5K_RXDP,            0x00000000 },
-       { AR5K_RXCFG,           0x00000005 },
-       { AR5K_MIBC,            0x00000000 },
-       { AR5K_TOPS,            0x00000008 },
-       { AR5K_RXNOFRM,         0x00000008 },
-       { AR5K_TXNOFRM,         0x00000010 },
-       { AR5K_RPGTO,           0x00000000 },
-       { AR5K_RFCNT,           0x0000001f },
-       { AR5K_QUEUE_TXDP(0),   0x00000000 },
-       { AR5K_QUEUE_TXDP(1),   0x00000000 },
-       { AR5K_QUEUE_TXDP(2),   0x00000000 },
-       { AR5K_QUEUE_TXDP(3),   0x00000000 },
-       { AR5K_QUEUE_TXDP(4),   0x00000000 },
-       { AR5K_QUEUE_TXDP(5),   0x00000000 },
-       { AR5K_QUEUE_TXDP(6),   0x00000000 },
-       { AR5K_QUEUE_TXDP(7),   0x00000000 },
-       { AR5K_QUEUE_TXDP(8),   0x00000000 },
-       { AR5K_QUEUE_TXDP(9),   0x00000000 },
-       { AR5K_DCU_FP,          0x00000000 },
-       { AR5K_DCU_TXP,         0x00000000 },
-       /* Tx filter table 0 (32 entries) */
-       { AR5K_DCU_TX_FILTER_0(0),  0x00000000 }, /* DCU 0 */
-       { AR5K_DCU_TX_FILTER_0(1),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(2),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(3),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(4),  0x00000000 }, /* DCU 1 */
-       { AR5K_DCU_TX_FILTER_0(5),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(6),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(7),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(8),  0x00000000 }, /* DCU 2 */
-       { AR5K_DCU_TX_FILTER_0(9),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(10), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(11), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(12), 0x00000000 }, /* DCU 3 */
-       { AR5K_DCU_TX_FILTER_0(13), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(14), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(15), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(16), 0x00000000 }, /* DCU 4 */
-       { AR5K_DCU_TX_FILTER_0(17), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(18), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(19), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(20), 0x00000000 }, /* DCU 5 */
-       { AR5K_DCU_TX_FILTER_0(21), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(22), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(23), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(24), 0x00000000 }, /* DCU 6 */
-       { AR5K_DCU_TX_FILTER_0(25), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(26), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(27), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(28), 0x00000000 }, /* DCU 7 */
-       { AR5K_DCU_TX_FILTER_0(29), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(30), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(31), 0x00000000 },
-       /* Tx filter table 1 (16 entries) */
-       { AR5K_DCU_TX_FILTER_1(0),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(1),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(2),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(3),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(4),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(5),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(6),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(7),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(8),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(9),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(10), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(11), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(12), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(13), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(14), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
-       { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
-       { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
-       { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
-       { AR5K_STA_ID1,         0x00000000 },
-       { AR5K_BSS_ID0,         0x00000000 },
-       { AR5K_BSS_ID1,         0x00000000 },
-       { AR5K_BEACON_5211,     0x00000000 },
-       { AR5K_CFP_PERIOD_5211, 0x00000000 },
-       { AR5K_TIMER0_5211,     0x00000030 },
-       { AR5K_TIMER1_5211,     0x0007ffff },
-       { AR5K_TIMER2_5211,     0x01ffffff },
-       { AR5K_TIMER3_5211,     0x00000031 },
-       { AR5K_CFP_DUR_5211,    0x00000000 },
-       { AR5K_RX_FILTER_5211,  0x00000000 },
-       { AR5K_DIAG_SW_5211,    0x00000000 },
-       { AR5K_ADDAC_TEST,      0x00000000 },
-       { AR5K_DEFAULT_ANTENNA, 0x00000000 },
-       { AR5K_FRAME_CTL_QOSM,  0x000fc78f },
-       { AR5K_XRMODE,          0x2a82301a },
-       { AR5K_XRDELAY,         0x05dc01e0 },
-       { AR5K_XRTIMEOUT,       0x1f402710 },
-       { AR5K_XRCHIRP,         0x01f40000 },
-       { AR5K_XRSTOMP,         0x00001e1c },
-       { AR5K_SLEEP0,          0x0002aaaa },
-       { AR5K_SLEEP1,          0x02005555 },
-       { AR5K_SLEEP2,          0x00000000 },
-       { AR5K_BSS_IDM0,        0xffffffff },
-       { AR5K_BSS_IDM1,        0x0000ffff },
-       { AR5K_TXPC,            0x00000000 },
-       { AR5K_PROFCNT_TX,      0x00000000 },
-       { AR5K_PROFCNT_RX,      0x00000000 },
-       { AR5K_PROFCNT_RXCLR,   0x00000000 },
-       { AR5K_PROFCNT_CYCLE,   0x00000000 },
-       { AR5K_QUIET_CTL1,      0x00000088 },
-       /* Initial rate duration table (32 entries )*/
-       { AR5K_RATE_DUR(0),     0x00000000 },
-       { AR5K_RATE_DUR(1),     0x0000008c },
-       { AR5K_RATE_DUR(2),     0x000000e4 },
-       { AR5K_RATE_DUR(3),     0x000002d5 },
-       { AR5K_RATE_DUR(4),     0x00000000 },
-       { AR5K_RATE_DUR(5),     0x00000000 },
-       { AR5K_RATE_DUR(6),     0x000000a0 },
-       { AR5K_RATE_DUR(7),     0x000001c9 },
-       { AR5K_RATE_DUR(8),     0x0000002c },
-       { AR5K_RATE_DUR(9),     0x0000002c },
-       { AR5K_RATE_DUR(10),    0x00000030 },
-       { AR5K_RATE_DUR(11),    0x0000003c },
-       { AR5K_RATE_DUR(12),    0x0000002c },
-       { AR5K_RATE_DUR(13),    0x0000002c },
-       { AR5K_RATE_DUR(14),    0x00000030 },
-       { AR5K_RATE_DUR(15),    0x0000003c },
-       { AR5K_RATE_DUR(16),    0x00000000 },
-       { AR5K_RATE_DUR(17),    0x00000000 },
-       { AR5K_RATE_DUR(18),    0x00000000 },
-       { AR5K_RATE_DUR(19),    0x00000000 },
-       { AR5K_RATE_DUR(20),    0x00000000 },
-       { AR5K_RATE_DUR(21),    0x00000000 },
-       { AR5K_RATE_DUR(22),    0x00000000 },
-       { AR5K_RATE_DUR(23),    0x00000000 },
-       { AR5K_RATE_DUR(24),    0x000000d5 },
-       { AR5K_RATE_DUR(25),    0x000000df },
-       { AR5K_RATE_DUR(26),    0x00000102 },
-       { AR5K_RATE_DUR(27),    0x0000013a },
-       { AR5K_RATE_DUR(28),    0x00000075 },
-       { AR5K_RATE_DUR(29),    0x0000007f },
-       { AR5K_RATE_DUR(30),    0x000000a2 },
-       { AR5K_RATE_DUR(31),    0x00000000 },
-       { AR5K_QUIET_CTL2,      0x00010002 },
-       { AR5K_TSF_PARM,        0x00000001 },
-       { AR5K_QOS_NOACK,       0x000000c0 },
-       { AR5K_PHY_ERR_FIL,     0x00000000 },
-       { AR5K_XRLAT_TX,        0x00000168 },
-       { AR5K_ACKSIFS,         0x00000000 },
-       /* Rate -> db table
-        * notice ...03<-02<-01<-00 ! */
-       { AR5K_RATE2DB(0),      0x03020100 },
-       { AR5K_RATE2DB(1),      0x07060504 },
-       { AR5K_RATE2DB(2),      0x0b0a0908 },
-       { AR5K_RATE2DB(3),      0x0f0e0d0c },
-       { AR5K_RATE2DB(4),      0x13121110 },
-       { AR5K_RATE2DB(5),      0x17161514 },
-       { AR5K_RATE2DB(6),      0x1b1a1918 },
-       { AR5K_RATE2DB(7),      0x1f1e1d1c },
-       /* Db -> Rate table */
-       { AR5K_DB2RATE(0),      0x03020100 },
-       { AR5K_DB2RATE(1),      0x07060504 },
-       { AR5K_DB2RATE(2),      0x0b0a0908 },
-       { AR5K_DB2RATE(3),      0x0f0e0d0c },
-       { AR5K_DB2RATE(4),      0x13121110 },
-       { AR5K_DB2RATE(5),      0x17161514 },
-       { AR5K_DB2RATE(6),      0x1b1a1918 },
-       { AR5K_DB2RATE(7),      0x1f1e1d1c },
-       /* PHY registers (Common settings
-        * for all chips/modes) */
-       { AR5K_PHY(3),          0xad848e19 },
-       { AR5K_PHY(4),          0x7d28e000 },
-       { AR5K_PHY_TIMING_3,    0x9c0a9f6b },
-       { AR5K_PHY_ACT,         0x00000000 },
-       { AR5K_PHY(16),         0x206a017a },
-       { AR5K_PHY(21),         0x00000859 },
-       { AR5K_PHY_BIN_MASK_1,  0x00000000 },
-       { AR5K_PHY_BIN_MASK_2,  0x00000000 },
-       { AR5K_PHY_BIN_MASK_3,  0x00000000 },
-       { AR5K_PHY_BIN_MASK_CTL, 0x00800000 },
-       { AR5K_PHY_ANT_CTL,     0x00000001 },
-       /*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
-       { AR5K_PHY_MAX_RX_LEN,  0x00000c80 },
-       { AR5K_PHY_IQ,          0x05100000 },
-       { AR5K_PHY_WARM_RESET,  0x00000001 },
-       { AR5K_PHY_CTL,         0x00000004 },
-       { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
-       { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
-       { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
-       { AR5K_PHY(82),         0x9280b212 },
-       { AR5K_PHY_RADAR,       0x5d50e188 },
-       /*{ AR5K_PHY(86), 0x000000ff },*/
-       { AR5K_PHY(87),         0x004b6a8e },
-       { AR5K_PHY_NFTHRES,     0x000003ce },
-       { AR5K_PHY_RESTART,     0x192fb515 },
-       { AR5K_PHY(94),         0x00000001 },
-       { AR5K_PHY_RFBUS_REQ,   0x00000000 },
-       /*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */
-       /*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */
-       { AR5K_PHY(644),        0x00806333 },
-       { AR5K_PHY(645),        0x00106c10 },
-       { AR5K_PHY(646),        0x009c4060 },
-       /* { AR5K_PHY(647), 0x1483800a }, */
-       /* { AR5K_PHY(648), 0x01831061 }, */ /* Old value */
-       { AR5K_PHY(648),        0x018830c6 },
-       { AR5K_PHY(649),        0x00000400 },
-       /*{ AR5K_PHY(650), 0x000001b5 },*/
-       { AR5K_PHY(651),        0x00000000 },
-       { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
-       { AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
-       /*{ AR5K_PHY(655), 0x13c889af },*/
-       { AR5K_PHY(656),        0x38490a20 },
-       { AR5K_PHY(657),        0x00007bb6 },
-       { AR5K_PHY(658),        0x0fff3ffc },
-};
-
-/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
-static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
-       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(1),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(2),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(3),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(4),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(5),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(6),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(7),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(8),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(9),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_DCU_GBL_IFS_SIFS,
-          { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
-       { AR5K_DCU_GBL_IFS_SLOT,
-          { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
-       { AR5K_DCU_GBL_IFS_EIFS,
-          { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
-       { AR5K_DCU_GBL_IFS_MISC,
-          { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
-       { AR5K_TIME_OUT,
-          { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
-       { AR5K_PHY_TURBO,
-          { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
-       { AR5K_PHY(8),
-          { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
-       { AR5K_PHY_RF_CTL2,
-          { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_SETTLING,
-          { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
-       { AR5K_PHY_AGCCTL,
-          { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
-       { AR5K_PHY_NF,
-          { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
-       { AR5K_PHY_WEAK_OFDM_HIGH_THR,
-          { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
-       { AR5K_PHY(70),
-          { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
-       { AR5K_PHY_OFDM_SELFCORR,
-          { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
-       { 0xa230,
-          { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
-};
-
-/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
-static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
-       { AR5K_USEC_5211,
-          { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY_GAIN,
-          { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
-       { AR5K_PHY_SIG,
-          { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
-};
-
-static const struct ath5k_ini rf5111_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x00022ffe },
-       { 0x983c,               0x00020100 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
-       { AR5K_PHY_PAPD_PROBE,  0x00004883 },
-       { 0x9940,               0x00000004 },
-       { 0x9958,               0x000000ff },
-       { 0x9974,               0x00000000 },
-       { AR5K_PHY_SPENDING,    0x00000018 },
-       { AR5K_PHY_CCKTXCTL,    0x00000000 },
-       { AR5K_PHY_CCK_CROSSCORR, 0xd03e6788 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
-       { 0xa23c,               0x13c889af },
-};
-
-/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
-static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
-       { AR5K_USEC_5211,
-          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY_GAIN,
-          { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
-       { AR5K_PHY_SIG,
-          { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
-       { AR5K_PHY_CCKTXCTL,
-          { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
-       { AR5K_PHY_CCK_CROSSCORR,
-          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
-};
-
-static const struct ath5k_ini rf5112_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x00022ffe },
-       { 0x983c,               0x00020100 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
-       { AR5K_PHY_PAPD_PROBE,  0x00004882 },
-       { 0x9940,               0x00000004 },
-       { 0x9958,               0x000000ff },
-       { 0x9974,               0x00000000 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
-       { 0xa23c,               0x13c889af },
-};
-
-/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
-static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
-       { AR5K_USEC_5211,
-          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY_GAIN,
-          { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
-       { AR5K_PHY_SIG,
-          { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
-       { AR5K_PHY_CCKTXCTL,
-          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { AR5K_PHY_CCK_CROSSCORR,
-          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
-       { 0xa300,
-          { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
-       { 0xa304,
-          { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
-       { 0xa308,
-          { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
-       { 0xa30c,
-          { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
-       { 0xa310,
-          { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
-       { 0xa314,
-          { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
-       { 0xa318,
-          { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
-       { 0xa31c,
-          { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
-       { 0xa320,
-          { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
-       { 0xa324,
-          { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
-       { 0xa328,
-          { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
-       { 0xa32c,
-          { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
-       { 0xa330,
-          { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
-       { 0xa334,
-          { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
-};
-
-static const struct ath5k_ini rf5413_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x000003e0 },
-       { AR5K_5414_CBCFG,      0x00000010 },
-       { AR5K_SEQ_MASK,        0x0000000f },
-       { 0x809c,               0x00000000 },
-       { 0x80a0,               0x00000000 },
-       { AR5K_MIC_QOS_CTL,     0x00000000 },
-       { AR5K_MIC_QOS_SEL,     0x00000000 },
-       { AR5K_MISC_MODE,       0x00000000 },
-       { AR5K_OFDM_FIL_CNT,    0x00000000 },
-       { AR5K_CCK_FIL_CNT,     0x00000000 },
-       { AR5K_PHYERR_CNT1,     0x00000000 },
-       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
-       { AR5K_PHYERR_CNT2,     0x00000000 },
-       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
-       { AR5K_TSF_THRES,       0x00000000 },
-       { 0x8140,               0x800003f9 },
-       { 0x8144,               0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x0000a000 },
-       { 0x983c,               0x00200400 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
-       { AR5K_PHY_SCR,         0x0000001f },
-       { AR5K_PHY_SLMT,        0x00000080 },
-       { AR5K_PHY_SCAL,        0x0000000e },
-       { 0x9958,               0x00081fff },
-       { AR5K_PHY_TIMING_7,    0x00000000 },
-       { AR5K_PHY_TIMING_8,    0x02800000 },
-       { AR5K_PHY_TIMING_11,   0x00000000 },
-       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
-       { 0x99e4,               0xaaaaaaaa },
-       { 0x99e8,               0x3c466478 },
-       { 0x99ec,               0x000000aa },
-       { AR5K_PHY_SCLOCK,      0x0000000c },
-       { AR5K_PHY_SDELAY,      0x000000ff },
-       { AR5K_PHY_SPENDING,    0x00000014 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
-       { 0xa23c,               0x93c889af },
-       { AR5K_PHY_FAST_ADC,    0x00000001 },
-       { 0xa250,               0x0000a000 },
-       { AR5K_PHY_BLUETOOTH,   0x00000000 },
-       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
-       { 0xa25c,               0x0f0f0f01 },
-       { 0xa260,               0x5f690f01 },
-       { 0xa264,               0x00418a11 },
-       { 0xa268,               0x00000000 },
-       { AR5K_PHY_TPC_RG5,     0x0c30c16a },
-       { 0xa270, 0x00820820 },
-       { 0xa274, 0x081b7caa },
-       { 0xa278, 0x1ce739ce },
-       { 0xa27c, 0x051701ce },
-       { 0xa338, 0x00000000 },
-       { 0xa33c, 0x00000000 },
-       { 0xa340, 0x00000000 },
-       { 0xa344, 0x00000000 },
-       { 0xa348, 0x3fffffff },
-       { 0xa34c, 0x3fffffff },
-       { 0xa350, 0x3fffffff },
-       { 0xa354, 0x0003ffff },
-       { 0xa358, 0x79a8aa1f },
-       { 0xa35c, 0x066c420f },
-       { 0xa360, 0x0f282207 },
-       { 0xa364, 0x17601685 },
-       { 0xa368, 0x1f801104 },
-       { 0xa36c, 0x37a00c03 },
-       { 0xa370, 0x3fc40883 },
-       { 0xa374, 0x57c00803 },
-       { 0xa378, 0x5fd80682 },
-       { 0xa37c, 0x7fe00482 },
-       { 0xa380, 0x7f3c7bba },
-       { 0xa384, 0xf3307ff0 },
-};
-
-/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
-/* XXX: a mode ? */
-static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
-       { AR5K_USEC_5211,
-          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
-       { AR5K_PHY_GAIN,
-          { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
-       { AR5K_PHY_SIG,
-          { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
-       { AR5K_PHY_CCKTXCTL,
-          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { AR5K_PHY_CCK_CROSSCORR,
-          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
-};
-
-static const struct ath5k_ini rf2413_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x000003e0 },
-       { AR5K_SEQ_MASK,        0x0000000f },
-       { AR5K_MIC_QOS_CTL,     0x00000000 },
-       { AR5K_MIC_QOS_SEL,     0x00000000 },
-       { AR5K_MISC_MODE,       0x00000000 },
-       { AR5K_OFDM_FIL_CNT,    0x00000000 },
-       { AR5K_CCK_FIL_CNT,     0x00000000 },
-       { AR5K_PHYERR_CNT1,     0x00000000 },
-       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
-       { AR5K_PHYERR_CNT2,     0x00000000 },
-       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
-       { AR5K_TSF_THRES,       0x00000000 },
-       { 0x8140,               0x800000a8 },
-       { 0x8144,               0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x0000a000 },
-       { 0x983c,               0x00200400 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
-       { AR5K_PHY_SCR,         0x0000001f },
-       { AR5K_PHY_SLMT,        0x00000080 },
-       { AR5K_PHY_SCAL,        0x0000000e },
-       { 0x9958,               0x000000ff },
-       { AR5K_PHY_TIMING_7,    0x00000000 },
-       { AR5K_PHY_TIMING_8,    0x02800000 },
-       { AR5K_PHY_TIMING_11,   0x00000000 },
-       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
-       { 0x99e4,               0xaaaaaaaa },
-       { 0x99e8,               0x3c466478 },
-       { 0x99ec,               0x000000aa },
-       { AR5K_PHY_SCLOCK,      0x0000000c },
-       { AR5K_PHY_SDELAY,      0x000000ff },
-       { AR5K_PHY_SPENDING,    0x00000014 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
-       { 0xa23c,               0x93c889af },
-       { AR5K_PHY_FAST_ADC,    0x00000001 },
-       { 0xa250,               0x0000a000 },
-       { AR5K_PHY_BLUETOOTH,   0x00000000 },
-       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
-       { 0xa25c,               0x0f0f0f01 },
-       { 0xa260,               0x5f690f01 },
-       { 0xa264,               0x00418a11 },
-       { 0xa268,               0x00000000 },
-       { AR5K_PHY_TPC_RG5,     0x0c30c16a },
-       { 0xa270, 0x00820820 },
-       { 0xa274, 0x001b7caa },
-       { 0xa278, 0x1ce739ce },
-       { 0xa27c, 0x051701ce },
-       { 0xa300, 0x18010000 },
-       { 0xa304, 0x30032602 },
-       { 0xa308, 0x48073e06 },
-       { 0xa30c, 0x560b4c0a },
-       { 0xa310, 0x641a600f },
-       { 0xa314, 0x784f6e1b },
-       { 0xa318, 0x868f7c5a },
-       { 0xa31c, 0x8ecf865b },
-       { 0xa320, 0x9d4f970f },
-       { 0xa324, 0xa5cfa18f },
-       { 0xa328, 0xb55faf1f },
-       { 0xa32c, 0xbddfb99f },
-       { 0xa330, 0xcd7fc73f },
-       { 0xa334, 0xd5ffd1bf },
-       { 0xa338, 0x00000000 },
-       { 0xa33c, 0x00000000 },
-       { 0xa340, 0x00000000 },
-       { 0xa344, 0x00000000 },
-       { 0xa348, 0x3fffffff },
-       { 0xa34c, 0x3fffffff },
-       { 0xa350, 0x3fffffff },
-       { 0xa354, 0x0003ffff },
-       { 0xa358, 0x79a8aa1f },
-       { 0xa35c, 0x066c420f },
-       { 0xa360, 0x0f282207 },
-       { 0xa364, 0x17601685 },
-       { 0xa368, 0x1f801104 },
-       { 0xa36c, 0x37a00c03 },
-       { 0xa370, 0x3fc40883 },
-       { 0xa374, 0x57c00803 },
-       { 0xa378, 0x5fd80682 },
-       { 0xa37c, 0x7fe00482 },
-       { 0xa380, 0x7f3c7bba },
-       { 0xa384, 0xf3307ff0 },
-};
-
-/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */
-/* XXX: a mode ? */
-static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
-       { AR5K_USEC_5211,
-          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-       { AR5K_PHY_TURBO,
-          { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY_SETTLING,
-          { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
-       { AR5K_PHY_GAIN,
-          { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
-       { AR5K_PHY_SIG,
-          { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
-       { AR5K_PHY_CCKTXCTL,
-          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { AR5K_PHY_CCK_CROSSCORR,
-          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
-       { 0xa324,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-       { 0xa328,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-       { 0xa32c,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-       { 0xa330,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-       { 0xa334,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-};
-
-static const struct ath5k_ini rf2425_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x000003e0 },
-       { AR5K_SEQ_MASK,        0x0000000f },
-       { 0x809c,               0x00000000 },
-       { 0x80a0,               0x00000000 },
-       { AR5K_MIC_QOS_CTL,     0x00000000 },
-       { AR5K_MIC_QOS_SEL,     0x00000000 },
-       { AR5K_MISC_MODE,       0x00000000 },
-       { AR5K_OFDM_FIL_CNT,    0x00000000 },
-       { AR5K_CCK_FIL_CNT,     0x00000000 },
-       { AR5K_PHYERR_CNT1,     0x00000000 },
-       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
-       { AR5K_PHYERR_CNT2,     0x00000000 },
-       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
-       { AR5K_TSF_THRES,       0x00000000 },
-       { 0x8140,               0x800003f9 },
-       { 0x8144,               0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x0000a000 },
-       { 0x983c,               0x00200400 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
-       { AR5K_PHY_SCR,         0x0000001f },
-       { AR5K_PHY_SLMT,        0x00000080 },
-       { AR5K_PHY_SCAL,        0x0000000e },
-       { 0x9958,               0x00081fff },
-       { AR5K_PHY_TIMING_7,    0x00000000 },
-       { AR5K_PHY_TIMING_8,    0x02800000 },
-       { AR5K_PHY_TIMING_11,   0x00000000 },
-       { 0x99dc,               0xfebadbe8 },
-       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
-       { 0x99e4,               0xaaaaaaaa },
-       { 0x99e8,               0x3c466478 },
-       { 0x99ec,               0x000000aa },
-       { AR5K_PHY_SCLOCK,      0x0000000c },
-       { AR5K_PHY_SDELAY,      0x000000ff },
-       { AR5K_PHY_SPENDING,    0x00000014 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
-       { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
-       { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
-       { 0xa23c,               0x93c889af },
-       { AR5K_PHY_FAST_ADC,    0x00000001 },
-       { 0xa250,               0x0000a000 },
-       { AR5K_PHY_BLUETOOTH,   0x00000000 },
-       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
-       { 0xa25c,               0x0f0f0f01 },
-       { 0xa260,               0x5f690f01 },
-       { 0xa264,               0x00418a11 },
-       { 0xa268,               0x00000000 },
-       { AR5K_PHY_TPC_RG5,     0x0c30c166 },
-       { 0xa270, 0x00820820 },
-       { 0xa274, 0x081a3caa },
-       { 0xa278, 0x1ce739ce },
-       { 0xa27c, 0x051701ce },
-       { 0xa300, 0x16010000 },
-       { 0xa304, 0x2c032402 },
-       { 0xa308, 0x48433e42 },
-       { 0xa30c, 0x5a0f500b },
-       { 0xa310, 0x6c4b624a },
-       { 0xa314, 0x7e8b748a },
-       { 0xa318, 0x96cf8ccb },
-       { 0xa31c, 0xa34f9d0f },
-       { 0xa320, 0xa7cfa58f },
-       { 0xa348, 0x3fffffff },
-       { 0xa34c, 0x3fffffff },
-       { 0xa350, 0x3fffffff },
-       { 0xa354, 0x0003ffff },
-       { 0xa358, 0x79a8aa1f },
-       { 0xa35c, 0x066c420f },
-       { 0xa360, 0x0f282207 },
-       { 0xa364, 0x17601685 },
-       { 0xa368, 0x1f801104 },
-       { 0xa36c, 0x37a00c03 },
-       { 0xa370, 0x3fc40883 },
-       { 0xa374, 0x57c00803 },
-       { 0xa378, 0x5fd80682 },
-       { 0xa37c, 0x7fe00482 },
-       { 0xa380, 0x7f3c7bba },
-       { 0xa384, 0xf3307ff0 },
-};
-
-/*
- * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with
- * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI)
- */
-
-/* RF5111 Initial BaseBand Gain settings */
-static const struct ath5k_ini rf5111_ini_bbgain[] = {
-       { AR5K_BB_GAIN(0), 0x00000000 },
-       { AR5K_BB_GAIN(1), 0x00000020 },
-       { AR5K_BB_GAIN(2), 0x00000010 },
-       { AR5K_BB_GAIN(3), 0x00000030 },
-       { AR5K_BB_GAIN(4), 0x00000008 },
-       { AR5K_BB_GAIN(5), 0x00000028 },
-       { AR5K_BB_GAIN(6), 0x00000004 },
-       { AR5K_BB_GAIN(7), 0x00000024 },
-       { AR5K_BB_GAIN(8), 0x00000014 },
-       { AR5K_BB_GAIN(9), 0x00000034 },
-       { AR5K_BB_GAIN(10), 0x0000000c },
-       { AR5K_BB_GAIN(11), 0x0000002c },
-       { AR5K_BB_GAIN(12), 0x00000002 },
-       { AR5K_BB_GAIN(13), 0x00000022 },
-       { AR5K_BB_GAIN(14), 0x00000012 },
-       { AR5K_BB_GAIN(15), 0x00000032 },
-       { AR5K_BB_GAIN(16), 0x0000000a },
-       { AR5K_BB_GAIN(17), 0x0000002a },
-       { AR5K_BB_GAIN(18), 0x00000006 },
-       { AR5K_BB_GAIN(19), 0x00000026 },
-       { AR5K_BB_GAIN(20), 0x00000016 },
-       { AR5K_BB_GAIN(21), 0x00000036 },
-       { AR5K_BB_GAIN(22), 0x0000000e },
-       { AR5K_BB_GAIN(23), 0x0000002e },
-       { AR5K_BB_GAIN(24), 0x00000001 },
-       { AR5K_BB_GAIN(25), 0x00000021 },
-       { AR5K_BB_GAIN(26), 0x00000011 },
-       { AR5K_BB_GAIN(27), 0x00000031 },
-       { AR5K_BB_GAIN(28), 0x00000009 },
-       { AR5K_BB_GAIN(29), 0x00000029 },
-       { AR5K_BB_GAIN(30), 0x00000005 },
-       { AR5K_BB_GAIN(31), 0x00000025 },
-       { AR5K_BB_GAIN(32), 0x00000015 },
-       { AR5K_BB_GAIN(33), 0x00000035 },
-       { AR5K_BB_GAIN(34), 0x0000000d },
-       { AR5K_BB_GAIN(35), 0x0000002d },
-       { AR5K_BB_GAIN(36), 0x00000003 },
-       { AR5K_BB_GAIN(37), 0x00000023 },
-       { AR5K_BB_GAIN(38), 0x00000013 },
-       { AR5K_BB_GAIN(39), 0x00000033 },
-       { AR5K_BB_GAIN(40), 0x0000000b },
-       { AR5K_BB_GAIN(41), 0x0000002b },
-       { AR5K_BB_GAIN(42), 0x0000002b },
-       { AR5K_BB_GAIN(43), 0x0000002b },
-       { AR5K_BB_GAIN(44), 0x0000002b },
-       { AR5K_BB_GAIN(45), 0x0000002b },
-       { AR5K_BB_GAIN(46), 0x0000002b },
-       { AR5K_BB_GAIN(47), 0x0000002b },
-       { AR5K_BB_GAIN(48), 0x0000002b },
-       { AR5K_BB_GAIN(49), 0x0000002b },
-       { AR5K_BB_GAIN(50), 0x0000002b },
-       { AR5K_BB_GAIN(51), 0x0000002b },
-       { AR5K_BB_GAIN(52), 0x0000002b },
-       { AR5K_BB_GAIN(53), 0x0000002b },
-       { AR5K_BB_GAIN(54), 0x0000002b },
-       { AR5K_BB_GAIN(55), 0x0000002b },
-       { AR5K_BB_GAIN(56), 0x0000002b },
-       { AR5K_BB_GAIN(57), 0x0000002b },
-       { AR5K_BB_GAIN(58), 0x0000002b },
-       { AR5K_BB_GAIN(59), 0x0000002b },
-       { AR5K_BB_GAIN(60), 0x0000002b },
-       { AR5K_BB_GAIN(61), 0x0000002b },
-       { AR5K_BB_GAIN(62), 0x00000002 },
-       { AR5K_BB_GAIN(63), 0x00000016 },
-};
-
-/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */
-static const struct ath5k_ini rf5112_ini_bbgain[] = {
-       { AR5K_BB_GAIN(0), 0x00000000 },
-       { AR5K_BB_GAIN(1), 0x00000001 },
-       { AR5K_BB_GAIN(2), 0x00000002 },
-       { AR5K_BB_GAIN(3), 0x00000003 },
-       { AR5K_BB_GAIN(4), 0x00000004 },
-       { AR5K_BB_GAIN(5), 0x00000005 },
-       { AR5K_BB_GAIN(6), 0x00000008 },
-       { AR5K_BB_GAIN(7), 0x00000009 },
-       { AR5K_BB_GAIN(8), 0x0000000a },
-       { AR5K_BB_GAIN(9), 0x0000000b },
-       { AR5K_BB_GAIN(10), 0x0000000c },
-       { AR5K_BB_GAIN(11), 0x0000000d },
-       { AR5K_BB_GAIN(12), 0x00000010 },
-       { AR5K_BB_GAIN(13), 0x00000011 },
-       { AR5K_BB_GAIN(14), 0x00000012 },
-       { AR5K_BB_GAIN(15), 0x00000013 },
-       { AR5K_BB_GAIN(16), 0x00000014 },
-       { AR5K_BB_GAIN(17), 0x00000015 },
-       { AR5K_BB_GAIN(18), 0x00000018 },
-       { AR5K_BB_GAIN(19), 0x00000019 },
-       { AR5K_BB_GAIN(20), 0x0000001a },
-       { AR5K_BB_GAIN(21), 0x0000001b },
-       { AR5K_BB_GAIN(22), 0x0000001c },
-       { AR5K_BB_GAIN(23), 0x0000001d },
-       { AR5K_BB_GAIN(24), 0x00000020 },
-       { AR5K_BB_GAIN(25), 0x00000021 },
-       { AR5K_BB_GAIN(26), 0x00000022 },
-       { AR5K_BB_GAIN(27), 0x00000023 },
-       { AR5K_BB_GAIN(28), 0x00000024 },
-       { AR5K_BB_GAIN(29), 0x00000025 },
-       { AR5K_BB_GAIN(30), 0x00000028 },
-       { AR5K_BB_GAIN(31), 0x00000029 },
-       { AR5K_BB_GAIN(32), 0x0000002a },
-       { AR5K_BB_GAIN(33), 0x0000002b },
-       { AR5K_BB_GAIN(34), 0x0000002c },
-       { AR5K_BB_GAIN(35), 0x0000002d },
-       { AR5K_BB_GAIN(36), 0x00000030 },
-       { AR5K_BB_GAIN(37), 0x00000031 },
-       { AR5K_BB_GAIN(38), 0x00000032 },
-       { AR5K_BB_GAIN(39), 0x00000033 },
-       { AR5K_BB_GAIN(40), 0x00000034 },
-       { AR5K_BB_GAIN(41), 0x00000035 },
-       { AR5K_BB_GAIN(42), 0x00000035 },
-       { AR5K_BB_GAIN(43), 0x00000035 },
-       { AR5K_BB_GAIN(44), 0x00000035 },
-       { AR5K_BB_GAIN(45), 0x00000035 },
-       { AR5K_BB_GAIN(46), 0x00000035 },
-       { AR5K_BB_GAIN(47), 0x00000035 },
-       { AR5K_BB_GAIN(48), 0x00000035 },
-       { AR5K_BB_GAIN(49), 0x00000035 },
-       { AR5K_BB_GAIN(50), 0x00000035 },
-       { AR5K_BB_GAIN(51), 0x00000035 },
-       { AR5K_BB_GAIN(52), 0x00000035 },
-       { AR5K_BB_GAIN(53), 0x00000035 },
-       { AR5K_BB_GAIN(54), 0x00000035 },
-       { AR5K_BB_GAIN(55), 0x00000035 },
-       { AR5K_BB_GAIN(56), 0x00000035 },
-       { AR5K_BB_GAIN(57), 0x00000035 },
-       { AR5K_BB_GAIN(58), 0x00000035 },
-       { AR5K_BB_GAIN(59), 0x00000035 },
-       { AR5K_BB_GAIN(60), 0x00000035 },
-       { AR5K_BB_GAIN(61), 0x00000035 },
-       { AR5K_BB_GAIN(62), 0x00000010 },
-       { AR5K_BB_GAIN(63), 0x0000001a },
-};
-
-
-/*
- * Write initial register dump
- */
-static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
-               const struct ath5k_ini *ini_regs, bool change_channel)
-{
-       unsigned int i;
-
-       /* Write initial registers */
-       for (i = 0; i < size; i++) {
-               /* On channel change there is
-                * no need to mess with PCU */
-               if (change_channel &&
-                               ini_regs[i].ini_register >= AR5K_PCU_MIN &&
-                               ini_regs[i].ini_register <= AR5K_PCU_MAX)
-                       continue;
-
-               switch (ini_regs[i].ini_mode) {
-               case AR5K_INI_READ:
-                       /* Cleared on read */
-                       ath5k_hw_reg_read(ah, ini_regs[i].ini_register);
-                       break;
-               case AR5K_INI_WRITE:
-               default:
-                       AR5K_REG_WAIT(i);
-                       ath5k_hw_reg_write(ah, ini_regs[i].ini_value,
-                                       ini_regs[i].ini_register);
-               }
-       }
-}
-
-static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah,
-               unsigned int size, const struct ath5k_ini_mode *ini_mode,
-               u8 mode)
-{
-       unsigned int i;
-
-       for (i = 0; i < size; i++) {
-               AR5K_REG_WAIT(i);
-               ath5k_hw_reg_write(ah, ini_mode[i].mode_value[mode],
-                       (u32)ini_mode[i].mode_register);
-       }
-
-}
-
-int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
-{
-       /*
-        * Write initial register settings
-        */
-
-       /* For AR5212 and combatible */
-       if (ah->ah_version == AR5K_AR5212) {
-
-               /* First set of mode-specific settings */
-               ath5k_hw_ini_mode_registers(ah,
-                       ARRAY_SIZE(ar5212_ini_mode_start),
-                       ar5212_ini_mode_start, mode);
-
-               /*
-                * Write initial settings common for all modes
-                */
-               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
-                               ar5212_ini_common_start, change_channel);
-
-               /* Second set of mode-specific settings */
-               switch (ah->ah_radio) {
-               case AR5K_RF5111:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf5111_ini_mode_end),
-                                       rf5111_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5111_ini_common_end),
-                                       rf5111_ini_common_end, change_channel);
-
-                       /* Baseband gain table */
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5111_ini_bbgain),
-                                       rf5111_ini_bbgain, change_channel);
-
-                       break;
-               case AR5K_RF5112:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_mode_end),
-                                       rf5112_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_common_end),
-                                       rf5112_ini_common_end, change_channel);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_bbgain),
-                                       rf5112_ini_bbgain, change_channel);
-
-                       break;
-               case AR5K_RF5413:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf5413_ini_mode_end),
-                                       rf5413_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5413_ini_common_end),
-                                       rf5413_ini_common_end, change_channel);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_bbgain),
-                                       rf5112_ini_bbgain, change_channel);
-
-                       break;
-               case AR5K_RF2316:
-               case AR5K_RF2413:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf2413_ini_mode_end),
-                                       rf2413_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf2413_ini_common_end),
-                                       rf2413_ini_common_end, change_channel);
-
-                       /* Override settings from rf2413_ini_common_end */
-                       if (ah->ah_radio == AR5K_RF2316) {
-                               ath5k_hw_reg_write(ah, 0x00004000,
-                                                       AR5K_PHY_AGC);
-                               ath5k_hw_reg_write(ah, 0x081b7caa,
-                                                       0xa274);
-                       }
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_bbgain),
-                                       rf5112_ini_bbgain, change_channel);
-                       break;
-               case AR5K_RF2317:
-               case AR5K_RF2425:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf2425_ini_mode_end),
-                                       rf2425_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf2425_ini_common_end),
-                                       rf2425_ini_common_end, change_channel);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_bbgain),
-                                       rf5112_ini_bbgain, change_channel);
-                       break;
-               default:
-                       return -EINVAL;
-
-               }
-
-       /* For AR5211 */
-       } else if (ah->ah_version == AR5K_AR5211) {
-
-               /* AR5K_MODE_11B */
-               if (mode > 2) {
-                       ATH5K_ERR(ah->ah_sc,
-                               "unsupported channel mode: %d\n", mode);
-                       return -EINVAL;
-               }
-
-               /* Mode-specific settings */
-               ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5211_ini_mode),
-                               ar5211_ini_mode, mode);
-
-               /*
-                * Write initial settings common for all modes
-                */
-               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini),
-                               ar5211_ini, change_channel);
-
-               /* AR5211 only comes with 5111 */
-
-               /* Baseband gain table */
-               ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain),
-                               rf5111_ini_bbgain, change_channel);
-       /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */
-       } else if (ah->ah_version == AR5K_AR5210) {
-               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini),
-                               ar5210_ini, change_channel);
-       }
-
-       return 0;
-}
diff --git a/drivers/net/wireless/ath5k/led.c b/drivers/net/wireless/ath5k/led.c
deleted file mode 100644 (file)
index 19555fb..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * Copyright (c) 2004-2005 Atheros Communications, Inc.
- * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2009 Bob Copeland <me@bobcopeland.com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- *
- */
-
-#include <linux/pci.h>
-#include "ath5k.h"
-#include "base.h"
-
-#define ATH_SDEVICE(subv,subd) \
-       .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
-       .subvendor = (subv), .subdevice = (subd)
-
-#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity))
-#define ATH_PIN(data) ((data) >> 8)
-#define ATH_POLARITY(data) ((data) & 0xff)
-
-/* Devices we match on for LED config info (typically laptops) */
-static const struct pci_device_id ath5k_led_devices[] = {
-       /* IBM-specific AR5212 */
-       { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
-       /* AR5211 */
-       { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
-       /* HP Compaq nc6xx, nc4000, nx6000 */
-       { ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) },
-       /* Acer Aspire One A150 (maximlevitsky@gmail.com) */
-       { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) },
-       /* Acer Ferrari 5000 (russ.dill@gmail.com) */
-       { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
-       /* E-machines E510 (tuliom@gmail.com) */
-       { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
-       /* Acer Extensa 5620z (nekoreeve@gmail.com) */
-       { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
-       { }
-};
-
-void ath5k_led_enable(struct ath5k_softc *sc)
-{
-       if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
-               ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
-               ath5k_led_off(sc);
-       }
-}
-
-void ath5k_led_on(struct ath5k_softc *sc)
-{
-       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
-               return;
-       ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
-}
-
-void ath5k_led_off(struct ath5k_softc *sc)
-{
-       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
-               return;
-       ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
-}
-
-static void
-ath5k_led_brightness_set(struct led_classdev *led_dev,
-       enum led_brightness brightness)
-{
-       struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
-               led_dev);
-
-       if (brightness == LED_OFF)
-               ath5k_led_off(led->sc);
-       else
-               ath5k_led_on(led->sc);
-}
-
-static int
-ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
-                  const char *name, char *trigger)
-{
-       int err;
-
-       led->sc = sc;
-       strncpy(led->name, name, sizeof(led->name));
-       led->led_dev.name = led->name;
-       led->led_dev.default_trigger = trigger;
-       led->led_dev.brightness_set = ath5k_led_brightness_set;
-
-       err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
-       if (err) {
-               ATH5K_WARN(sc, "could not register LED %s\n", name);
-               led->sc = NULL;
-       }
-       return err;
-}
-
-static void
-ath5k_unregister_led(struct ath5k_led *led)
-{
-       if (!led->sc)
-               return;
-       led_classdev_unregister(&led->led_dev);
-       ath5k_led_off(led->sc);
-       led->sc = NULL;
-}
-
-void ath5k_unregister_leds(struct ath5k_softc *sc)
-{
-       ath5k_unregister_led(&sc->rx_led);
-       ath5k_unregister_led(&sc->tx_led);
-}
-
-int ath5k_init_leds(struct ath5k_softc *sc)
-{
-       int ret = 0;
-       struct ieee80211_hw *hw = sc->hw;
-       struct pci_dev *pdev = sc->pdev;
-       char name[ATH5K_LED_MAX_NAME_LEN + 1];
-       const struct pci_device_id *match;
-
-       match = pci_match_id(&ath5k_led_devices[0], pdev);
-       if (match) {
-               __set_bit(ATH_STAT_LEDSOFT, sc->status);
-               sc->led_pin = ATH_PIN(match->driver_data);
-               sc->led_on = ATH_POLARITY(match->driver_data);
-       }
-
-       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
-               goto out;
-
-       ath5k_led_enable(sc);
-
-       snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
-       ret = ath5k_register_led(sc, &sc->rx_led, name,
-               ieee80211_get_rx_led_name(hw));
-       if (ret)
-               goto out;
-
-       snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
-       ret = ath5k_register_led(sc, &sc->tx_led, name,
-               ieee80211_get_tx_led_name(hw));
-out:
-       return ret;
-}
-
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c
deleted file mode 100644 (file)
index 55122f1..0000000
+++ /dev/null
@@ -1,1174 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Matthew W. S. Bell  <mentor@madwifi.org>
- * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
- * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*********************************\
-* Protocol Control Unit Functions *
-\*********************************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*******************\
-* Generic functions *
-\*******************/
-
-/**
- * ath5k_hw_set_opmode - Set PCU operating mode
- *
- * @ah: The &struct ath5k_hw
- *
- * Initialize PCU for the various operating modes (AP/STA etc)
- *
- * NOTE: ah->ah_op_mode must be set before calling this.
- */
-int ath5k_hw_set_opmode(struct ath5k_hw *ah)
-{
-       u32 pcu_reg, beacon_reg, low_id, high_id;
-
-
-       /* Preserve rest settings */
-       pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
-       pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
-                       | AR5K_STA_ID1_KEYSRCH_MODE
-                       | (ah->ah_version == AR5K_AR5210 ?
-                       (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
-
-       beacon_reg = 0;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       switch (ah->ah_op_mode) {
-       case NL80211_IFTYPE_ADHOC:
-               pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
-               beacon_reg |= AR5K_BCR_ADHOC;
-               if (ah->ah_version == AR5K_AR5210)
-                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
-               else
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
-               break;
-
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_MESH_POINT:
-               pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
-               beacon_reg |= AR5K_BCR_AP;
-               if (ah->ah_version == AR5K_AR5210)
-                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
-               else
-                       AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
-               break;
-
-       case NL80211_IFTYPE_STATION:
-               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
-                       | (ah->ah_version == AR5K_AR5210 ?
-                               AR5K_STA_ID1_PWR_SV : 0);
-       case NL80211_IFTYPE_MONITOR:
-               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
-                       | (ah->ah_version == AR5K_AR5210 ?
-                               AR5K_STA_ID1_NO_PSPOLL : 0);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       /*
-        * Set PCU registers
-        */
-       low_id = AR5K_LOW_ID(ah->ah_sta_id);
-       high_id = AR5K_HIGH_ID(ah->ah_sta_id);
-       ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
-       ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
-
-       /*
-        * Set Beacon Control Register on 5210
-        */
-       if (ah->ah_version == AR5K_AR5210)
-               ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
-
-       return 0;
-}
-
-/**
- * ath5k_hw_update - Update mib counters (mac layer statistics)
- *
- * @ah: The &struct ath5k_hw
- * @stats: The &struct ieee80211_low_level_stats we use to track
- * statistics on the driver
- *
- * Reads MIB counters from PCU and updates sw statistics. Must be
- * called after a MIB interrupt.
- */
-void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
-               struct ieee80211_low_level_stats  *stats)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Read-And-Clear */
-       stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
-       stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
-       stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
-       stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
-
-       /* XXX: Should we use this to track beacon count ?
-        * -we read it anyway to clear the register */
-       ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
-
-       /* Reset profile count registers on 5212*/
-       if (ah->ah_version == AR5K_AR5212) {
-               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
-               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
-               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
-               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
-       }
-
-       /* TODO: Handle ANI stats */
-}
-
-/**
- * ath5k_hw_set_ack_bitrate - set bitrate for ACKs
- *
- * @ah: The &struct ath5k_hw
- * @high: Flag to determine if we want to use high transmition rate
- * for ACKs or not
- *
- * If high flag is set, we tell hw to use a set of control rates based on
- * the current transmition rate (check out control_rates array inside reset.c).
- * If not hw just uses the lowest rate available for the current modulation
- * scheme being used (1Mbit for CCK and 6Mbits for OFDM).
- */
-void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
-{
-       if (ah->ah_version != AR5K_AR5212)
-               return;
-       else {
-               u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
-               if (high)
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
-               else
-                       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
-       }
-}
-
-
-/******************\
-* ACK/CTS Timeouts *
-\******************/
-
-/**
- * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
- *
- * @ah: The &struct ath5k_hw
- */
-unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
-                       AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
-}
-
-/**
- * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
- *
- * @ah: The &struct ath5k_hw
- * @timeout: Timeout in usec
- */
-int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
-                       ah->ah_turbo) <= timeout)
-               return -EINVAL;
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
-               ath5k_hw_htoclock(timeout, ah->ah_turbo));
-
-       return 0;
-}
-
-/**
- * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
- *
- * @ah: The &struct ath5k_hw
- */
-unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
-                       AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
-}
-
-/**
- * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
- *
- * @ah: The &struct ath5k_hw
- * @timeout: Timeout in usec
- */
-int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
-                       ah->ah_turbo) <= timeout)
-               return -EINVAL;
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
-                       ath5k_hw_htoclock(timeout, ah->ah_turbo));
-
-       return 0;
-}
-
-
-/****************\
-* BSSID handling *
-\****************/
-
-/**
- * ath5k_hw_get_lladdr - Get station id
- *
- * @ah: The &struct ath5k_hw
- * @mac: The card's mac address
- *
- * Initialize ah->ah_sta_id using the mac address provided
- * (just a memcpy).
- *
- * TODO: Remove it once we merge ath5k_softc and ath5k_hw
- */
-void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       memcpy(mac, ah->ah_sta_id, ETH_ALEN);
-}
-
-/**
- * ath5k_hw_set_lladdr - Set station id
- *
- * @ah: The &struct ath5k_hw
- * @mac: The card's mac address
- *
- * Set station id on hw using the provided mac address
- */
-int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
-{
-       u32 low_id, high_id;
-       u32 pcu_reg;
-
-       ATH5K_TRACE(ah->ah_sc);
-       /* Set new station ID */
-       memcpy(ah->ah_sta_id, mac, ETH_ALEN);
-
-       pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
-
-       low_id = AR5K_LOW_ID(mac);
-       high_id = AR5K_HIGH_ID(mac);
-
-       ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
-       ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
-
-       return 0;
-}
-
-/**
- * ath5k_hw_set_associd - Set BSSID for association
- *
- * @ah: The &struct ath5k_hw
- * @bssid: BSSID
- * @assoc_id: Assoc id
- *
- * Sets the BSSID which trigers the "SME Join" operation
- */
-void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
-{
-       u32 low_id, high_id;
-       u16 tim_offset = 0;
-
-       /*
-        * Set simple BSSID mask on 5212
-        */
-       if (ah->ah_version == AR5K_AR5212) {
-               ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask),
-                                                       AR5K_BSS_IDM0);
-               ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask),
-                                                       AR5K_BSS_IDM1);
-       }
-
-       /*
-        * Set BSSID which triggers the "SME Join" operation
-        */
-       low_id = AR5K_LOW_ID(bssid);
-       high_id = AR5K_HIGH_ID(bssid);
-       ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
-       ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
-                               AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
-
-       if (assoc_id == 0) {
-               ath5k_hw_disable_pspoll(ah);
-               return;
-       }
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
-                       tim_offset ? tim_offset + 4 : 0);
-
-       ath5k_hw_enable_pspoll(ah, NULL, 0);
-}
-
-/**
- * ath5k_hw_set_bssid_mask - filter out bssids we listen
- *
- * @ah: the &struct ath5k_hw
- * @mask: the bssid_mask, a u8 array of size ETH_ALEN
- *
- * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
- * which bits of the interface's MAC address should be looked at when trying
- * to decide which packets to ACK. In station mode and AP mode with a single
- * BSS every bit matters since we lock to only one BSS. In AP mode with
- * multiple BSSes (virtual interfaces) not every bit matters because hw must
- * accept frames for all BSSes and so we tweak some bits of our mac address
- * in order to have multiple BSSes.
- *
- * NOTE: This is a simple filter and does *not* filter out all
- * relevant frames. Some frames that are not for us might get ACKed from us
- * by PCU because they just match the mask.
- *
- * When handling multiple BSSes you can get the BSSID mask by computing the
- * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
- *
- * When you do this you are essentially computing the common bits of all your
- * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
- * the MAC address to obtain the relevant bits and compare the result with
- * (frame's BSSID & mask) to see if they match.
- */
-/*
- * Simple example: on your card you have have two BSSes you have created with
- * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
- * There is another BSSID-03 but you are not part of it. For simplicity's sake,
- * assuming only 4 bits for a mac address and for BSSIDs you can then have:
- *
- *                  \
- * MAC:                0001 |
- * BSSID-01:   0100 | --> Belongs to us
- * BSSID-02:   1001 |
- *                  /
- * -------------------
- * BSSID-03:   0110  | --> External
- * -------------------
- *
- * Our bssid_mask would then be:
- *
- *             On loop iteration for BSSID-01:
- *             ~(0001 ^ 0100)  -> ~(0101)
- *                             ->   1010
- *             bssid_mask      =    1010
- *
- *             On loop iteration for BSSID-02:
- *             bssid_mask &= ~(0001   ^   1001)
- *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
- *             bssid_mask =   (1010)  & ~(1001)
- *             bssid_mask =   (1010)  &  (0110)
- *             bssid_mask =   0010
- *
- * A bssid_mask of 0010 means "only pay attention to the second least
- * significant bit". This is because its the only bit common
- * amongst the MAC and all BSSIDs we support. To findout what the real
- * common bit is we can simply "&" the bssid_mask now with any BSSID we have
- * or our MAC address (we assume the hardware uses the MAC address).
- *
- * Now, suppose there's an incoming frame for BSSID-03:
- *
- * IFRAME-01:  0110
- *
- * An easy eye-inspeciton of this already should tell you that this frame
- * will not pass our check. This is beacuse the bssid_mask tells the
- * hardware to only look at the second least significant bit and the
- * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
- * as 1, which does not match 0.
- *
- * So with IFRAME-01 we *assume* the hardware will do:
- *
- *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
- *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
- *  --> allow = (0010) == 0000 ? 1 : 0;
- *  --> allow = 0
- *
- *  Lets now test a frame that should work:
- *
- * IFRAME-02:  0001 (we should allow)
- *
- *     allow = (0001 & 1010) == 1010
- *
- *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
- *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
- *  --> allow = (0010) == (0010)
- *  --> allow = 1
- *
- * Other examples:
- *
- * IFRAME-03:  0100 --> allowed
- * IFRAME-04:  1001 --> allowed
- * IFRAME-05:  1101 --> allowed but its not for us!!!
- *
- */
-int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
-{
-       u32 low_id, high_id;
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Cache bssid mask so that we can restore it
-        * on reset */
-       memcpy(ah->ah_bssid_mask, mask, ETH_ALEN);
-       if (ah->ah_version == AR5K_AR5212) {
-               low_id = AR5K_LOW_ID(mask);
-               high_id = AR5K_HIGH_ID(mask);
-
-               ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
-               ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
-
-               return 0;
-       }
-
-       return -EIO;
-}
-
-
-/************\
-* RX Control *
-\************/
-
-/**
- * ath5k_hw_start_rx_pcu - Start RX engine
- *
- * @ah: The &struct ath5k_hw
- *
- * Starts RX engine on PCU so that hw can process RXed frames
- * (ACK etc).
- *
- * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
- * TODO: Init ANI here
- */
-void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-}
-
-/**
- * at5k_hw_stop_rx_pcu - Stop RX engine
- *
- * @ah: The &struct ath5k_hw
- *
- * Stops RX engine on PCU
- *
- * TODO: Detach ANI here
- */
-void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-}
-
-/*
- * Set multicast filter
- */
-void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /* Set the multicat filter */
-       ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
-       ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
-}
-
-/*
- * Set multicast filter by index
- */
-int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
-{
-
-       ATH5K_TRACE(ah->ah_sc);
-       if (index >= 64)
-               return -EINVAL;
-       else if (index >= 32)
-               AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
-                               (1 << (index - 32)));
-       else
-               AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
-
-       return 0;
-}
-
-/*
- * Clear Multicast filter by index
- */
-int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
-{
-
-       ATH5K_TRACE(ah->ah_sc);
-       if (index >= 64)
-               return -EINVAL;
-       else if (index >= 32)
-               AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
-                               (1 << (index - 32)));
-       else
-               AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
-
-       return 0;
-}
-
-/**
- * ath5k_hw_get_rx_filter - Get current rx filter
- *
- * @ah: The &struct ath5k_hw
- *
- * Returns the RX filter by reading rx filter and
- * phy error filter registers. RX filter is used
- * to set the allowed frame types that PCU will accept
- * and pass to the driver. For a list of frame types
- * check out reg.h.
- */
-u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
-{
-       u32 data, filter = 0;
-
-       ATH5K_TRACE(ah->ah_sc);
-       filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
-
-       /*Radar detection for 5212*/
-       if (ah->ah_version == AR5K_AR5212) {
-               data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
-
-               if (data & AR5K_PHY_ERR_FIL_RADAR)
-                       filter |= AR5K_RX_FILTER_RADARERR;
-               if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
-                       filter |= AR5K_RX_FILTER_PHYERR;
-       }
-
-       return filter;
-}
-
-/**
- * ath5k_hw_set_rx_filter - Set rx filter
- *
- * @ah: The &struct ath5k_hw
- * @filter: RX filter mask (see reg.h)
- *
- * Sets RX filter register and also handles PHY error filter
- * register on 5212 and newer chips so that we have proper PHY
- * error reporting.
- */
-void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
-{
-       u32 data = 0;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Set PHY error filter register on 5212*/
-       if (ah->ah_version == AR5K_AR5212) {
-               if (filter & AR5K_RX_FILTER_RADARERR)
-                       data |= AR5K_PHY_ERR_FIL_RADAR;
-               if (filter & AR5K_RX_FILTER_PHYERR)
-                       data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
-       }
-
-       /*
-        * The AR5210 uses promiscous mode to detect radar activity
-        */
-       if (ah->ah_version == AR5K_AR5210 &&
-                       (filter & AR5K_RX_FILTER_RADARERR)) {
-               filter &= ~AR5K_RX_FILTER_RADARERR;
-               filter |= AR5K_RX_FILTER_PROM;
-       }
-
-       /*Zero length DMA (phy error reporting) */
-       if (data)
-               AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
-       else
-               AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
-
-       /*Write RX Filter register*/
-       ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
-
-       /*Write PHY error filter register on 5212*/
-       if (ah->ah_version == AR5K_AR5212)
-               ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
-
-}
-
-
-/****************\
-* Beacon control *
-\****************/
-
-/**
- * ath5k_hw_get_tsf32 - Get a 32bit TSF
- *
- * @ah: The &struct ath5k_hw
- *
- * Returns lower 32 bits of current TSF
- */
-u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
-}
-
-/**
- * ath5k_hw_get_tsf64 - Get the full 64bit TSF
- *
- * @ah: The &struct ath5k_hw
- *
- * Returns the current TSF
- */
-u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
-{
-       u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
-       ATH5K_TRACE(ah->ah_sc);
-
-       return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
-}
-
-/**
- * ath5k_hw_set_tsf64 - Set a new 64bit TSF
- *
- * @ah: The &struct ath5k_hw
- * @tsf64: The new 64bit TSF
- *
- * Sets the new TSF
- */
-void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
-       ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
-}
-
-/**
- * ath5k_hw_reset_tsf - Force a TSF reset
- *
- * @ah: The &struct ath5k_hw
- *
- * Forces a TSF reset on PCU
- */
-void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
-{
-       u32 val;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
-
-       /*
-        * Each write to the RESET_TSF bit toggles a hardware internal
-        * signal to reset TSF, but if left high it will cause a TSF reset
-        * on the next chip reset as well.  Thus we always write the value
-        * twice to clear the signal.
-        */
-       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
-       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
-}
-
-/*
- * Initialize beacon timers
- */
-void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
-{
-       u32 timer1, timer2, timer3;
-
-       ATH5K_TRACE(ah->ah_sc);
-       /*
-        * Set the additional timers by mode
-        */
-       switch (ah->ah_op_mode) {
-       case NL80211_IFTYPE_MONITOR:
-       case NL80211_IFTYPE_STATION:
-               /* In STA mode timer1 is used as next wakeup
-                * timer and timer2 as next CFP duration start
-                * timer. Both in 1/8TUs. */
-               /* TODO: PCF handling */
-               if (ah->ah_version == AR5K_AR5210) {
-                       timer1 = 0xffffffff;
-                       timer2 = 0xffffffff;
-               } else {
-                       timer1 = 0x0000ffff;
-                       timer2 = 0x0007ffff;
-               }
-               /* Mark associated AP as PCF incapable for now */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PCF);
-               break;
-       case NL80211_IFTYPE_ADHOC:
-               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_ADHOC_BCN_ATIM);
-       default:
-               /* On non-STA modes timer1 is used as next DMA
-                * beacon alert (DBA) timer and timer2 as next
-                * software beacon alert. Both in 1/8TUs. */
-               timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
-               timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
-               break;
-       }
-
-       /* Timer3 marks the end of our ATIM window
-        * a zero length window is not allowed because
-        * we 'll get no beacons */
-       timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
-
-       /*
-        * Set the beacon register and enable all timers.
-        */
-       /* When in AP mode zero timer0 to start TSF */
-       if (ah->ah_op_mode == NL80211_IFTYPE_AP)
-               ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
-       else
-               ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
-       ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
-       ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
-       ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
-
-       /* Force a TSF reset if requested and enable beacons */
-       if (interval & AR5K_BEACON_RESET_TSF)
-               ath5k_hw_reset_tsf(ah);
-
-       ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
-                                       AR5K_BEACON_ENABLE),
-                                               AR5K_BEACON);
-
-       /* Flush any pending BMISS interrupts on ISR by
-        * performing a clear-on-write operation on PISR
-        * register for the BMISS bit (writing a bit on
-        * ISR togles a reset for that bit and leaves
-        * the rest bits intact) */
-       if (ah->ah_version == AR5K_AR5210)
-               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR);
-       else
-               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR);
-
-       /* TODO: Set enchanced sleep registers on AR5212
-        * based on vif->bss_conf params, until then
-        * disable power save reporting.*/
-       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV);
-
-}
-
-#if 0
-/*
- * Set beacon timers
- */
-int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
-               const struct ath5k_beacon_state *state)
-{
-       u32 cfp_period, next_cfp, dtim, interval, next_beacon;
-
-       /*
-        * TODO: should be changed through *state
-        * review struct ath5k_beacon_state struct
-        *
-        * XXX: These are used for cfp period bellow, are they
-        * ok ? Is it O.K. for tsf here to be 0 or should we use
-        * get_tsf ?
-        */
-       u32 dtim_count = 0; /* XXX */
-       u32 cfp_count = 0; /* XXX */
-       u32 tsf = 0; /* XXX */
-
-       ATH5K_TRACE(ah->ah_sc);
-       /* Return on an invalid beacon state */
-       if (state->bs_interval < 1)
-               return -EINVAL;
-
-       interval = state->bs_interval;
-       dtim = state->bs_dtim_period;
-
-       /*
-        * PCF support?
-        */
-       if (state->bs_cfp_period > 0) {
-               /*
-                * Enable PCF mode and set the CFP
-                * (Contention Free Period) and timer registers
-                */
-               cfp_period = state->bs_cfp_period * state->bs_dtim_period *
-                       state->bs_interval;
-               next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
-                       state->bs_interval;
-
-               AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
-                               AR5K_STA_ID1_DEFAULT_ANTENNA |
-                               AR5K_STA_ID1_PCF);
-               ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
-               ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
-                               AR5K_CFP_DUR);
-               ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
-                                               next_cfp)) << 3, AR5K_TIMER2);
-       } else {
-               /* Disable PCF mode */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
-                               AR5K_STA_ID1_DEFAULT_ANTENNA |
-                               AR5K_STA_ID1_PCF);
-       }
-
-       /*
-        * Enable the beacon timer register
-        */
-       ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
-
-       /*
-        * Start the beacon timers
-        */
-       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &
-               ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
-               AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
-               AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
-               AR5K_BEACON_PERIOD), AR5K_BEACON);
-
-       /*
-        * Write new beacon miss threshold, if it appears to be valid
-        * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
-        * and return if its not in range. We can test this by reading value and
-        * setting value to a largest value and seeing which values register.
-        */
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
-                       state->bs_bmiss_threshold);
-
-       /*
-        * Set sleep control register
-        * XXX: Didn't find this in 5210 code but since this register
-        * exists also in ar5k's 5210 headers i leave it as common code.
-        */
-       AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
-                       (state->bs_sleep_duration - 3) << 3);
-
-       /*
-        * Set enhanced sleep registers on 5212
-        */
-       if (ah->ah_version == AR5K_AR5212) {
-               if (state->bs_sleep_duration > state->bs_interval &&
-                               roundup(state->bs_sleep_duration, interval) ==
-                               state->bs_sleep_duration)
-                       interval = state->bs_sleep_duration;
-
-               if (state->bs_sleep_duration > dtim && (dtim == 0 ||
-                               roundup(state->bs_sleep_duration, dtim) ==
-                               state->bs_sleep_duration))
-                       dtim = state->bs_sleep_duration;
-
-               if (interval > dtim)
-                       return -EINVAL;
-
-               next_beacon = interval == dtim ? state->bs_next_dtim :
-                       state->bs_next_beacon;
-
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
-                       AR5K_SLEEP0_NEXT_DTIM) |
-                       AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
-                       AR5K_SLEEP0_ENH_SLEEP_EN |
-                       AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
-
-               ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
-                       AR5K_SLEEP1_NEXT_TIM) |
-                       AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
-
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
-                       AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
-       }
-
-       return 0;
-}
-
-/*
- * Reset beacon timers
- */
-void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /*
-        * Disable beacon timer
-        */
-       ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
-
-       /*
-        * Disable some beacon register values
-        */
-       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
-                       AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
-       ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
-}
-
-/*
- * Wait for beacon queue to finish
- */
-int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
-{
-       unsigned int i;
-       int ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* 5210 doesn't have QCU*/
-       if (ah->ah_version == AR5K_AR5210) {
-               /*
-                * Wait for beaconn queue to finish by checking
-                * Control Register and Beacon Status Register.
-                */
-               for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
-                       if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
-                                       ||
-                           !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
-                               break;
-                       udelay(10);
-               }
-
-               /* Timeout... */
-               if (i <= 0) {
-                       /*
-                        * Re-schedule the beacon queue
-                        */
-                       ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
-                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
-                                       AR5K_BCR);
-
-                       return -EIO;
-               }
-               ret = 0;
-       } else {
-       /*5211/5212*/
-               ret = ath5k_hw_register_timeout(ah,
-                       AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
-                       AR5K_QCU_STS_FRMPENDCNT, 0, false);
-
-               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
-                       return -EIO;
-       }
-
-       return ret;
-}
-#endif
-
-
-/*********************\
-* Key table functions *
-\*********************/
-
-/*
- * Reset a key entry on the table
- */
-int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
-{
-       unsigned int i, type;
-       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
-
-       type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry));
-
-       for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
-               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
-
-       /* Reset associated MIC entry if TKIP
-        * is enabled located at offset (entry + 64) */
-       if (type == AR5K_KEYTABLE_TYPE_TKIP) {
-               AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE);
-               for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
-                       ath5k_hw_reg_write(ah, 0,
-                               AR5K_KEYTABLE_OFF(micentry, i));
-       }
-
-       /*
-        * Set NULL encryption on AR5212+
-        *
-        * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
-        *       AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
-        *
-        * Note2: Windows driver (ndiswrapper) sets this to
-        *        0x00000714 instead of 0x00000007
-        */
-       if (ah->ah_version > AR5K_AR5211) {
-               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
-                               AR5K_KEYTABLE_TYPE(entry));
-
-               if (type == AR5K_KEYTABLE_TYPE_TKIP) {
-                       ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
-                               AR5K_KEYTABLE_TYPE(micentry));
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Check if a table entry is valid
- */
-int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
-
-       /* Check the validation flag at the end of the entry */
-       return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
-               AR5K_KEYTABLE_VALID;
-}
-
-static
-int ath5k_keycache_type(const struct ieee80211_key_conf *key)
-{
-       switch (key->alg) {
-       case ALG_TKIP:
-               return AR5K_KEYTABLE_TYPE_TKIP;
-       case ALG_CCMP:
-               return AR5K_KEYTABLE_TYPE_CCM;
-       case ALG_WEP:
-               if (key->keylen == LEN_WEP40)
-                       return AR5K_KEYTABLE_TYPE_40;
-               else if (key->keylen == LEN_WEP104)
-                       return AR5K_KEYTABLE_TYPE_104;
-               return -EINVAL;
-       default:
-               return -EINVAL;
-       }
-       return -EINVAL;
-}
-
-/*
- * Set a key entry on the table
- */
-int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
-               const struct ieee80211_key_conf *key, const u8 *mac)
-{
-       unsigned int i;
-       int keylen;
-       __le32 key_v[5] = {};
-       __le32 key0 = 0, key1 = 0;
-       __le32 *rxmic, *txmic;
-       int keytype;
-       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
-       bool is_tkip;
-       const u8 *key_ptr;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       is_tkip = (key->alg == ALG_TKIP);
-
-       /*
-        * key->keylen comes in from mac80211 in bytes.
-        * TKIP is 128 bit + 128 bit mic
-        */
-       keylen = (is_tkip) ? (128 / 8) : key->keylen;
-
-       if (entry > AR5K_KEYTABLE_SIZE ||
-               (is_tkip && micentry > AR5K_KEYTABLE_SIZE))
-               return -EOPNOTSUPP;
-
-       if (unlikely(keylen > 16))
-               return -EOPNOTSUPP;
-
-       keytype = ath5k_keycache_type(key);
-       if (keytype < 0)
-               return keytype;
-
-       /*
-        * each key block is 6 bytes wide, written as pairs of
-        * alternating 32 and 16 bit le values.
-        */
-       key_ptr = key->key;
-       for (i = 0; keylen >= 6; keylen -= 6) {
-               memcpy(&key_v[i], key_ptr, 6);
-               i += 2;
-               key_ptr += 6;
-       }
-       if (keylen)
-               memcpy(&key_v[i], key_ptr, keylen);
-
-       /* intentionally corrupt key until mic is installed */
-       if (is_tkip) {
-               key0 = key_v[0] = ~key_v[0];
-               key1 = key_v[1] = ~key_v[1];
-       }
-
-       for (i = 0; i < ARRAY_SIZE(key_v); i++)
-               ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
-                               AR5K_KEYTABLE_OFF(entry, i));
-
-       ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
-
-       if (is_tkip) {
-               /* Install rx/tx MIC */
-               rxmic = (__le32 *) &key->key[16];
-               txmic = (__le32 *) &key->key[24];
-
-               if (ah->ah_combined_mic) {
-                       key_v[0] = rxmic[0];
-                       key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16);
-                       key_v[2] = rxmic[1];
-                       key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff);
-                       key_v[4] = txmic[1];
-               } else {
-                       key_v[0] = rxmic[0];
-                       key_v[1] = 0;
-                       key_v[2] = rxmic[1];
-                       key_v[3] = 0;
-                       key_v[4] = 0;
-               }
-               for (i = 0; i < ARRAY_SIZE(key_v); i++)
-                       ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
-                               AR5K_KEYTABLE_OFF(micentry, i));
-
-               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
-                       AR5K_KEYTABLE_TYPE(micentry));
-               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry));
-               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry));
-
-               /* restore first 2 words of key */
-               ath5k_hw_reg_write(ah, le32_to_cpu(~key0),
-                       AR5K_KEYTABLE_OFF(entry, 0));
-               ath5k_hw_reg_write(ah, le32_to_cpu(~key1),
-                       AR5K_KEYTABLE_OFF(entry, 1));
-       }
-
-       return ath5k_hw_set_key_lladdr(ah, entry, mac);
-}
-
-int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
-{
-       u32 low_id, high_id;
-
-       ATH5K_TRACE(ah->ah_sc);
-        /* Invalid entry (key table overflow) */
-       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
-
-       /* MAC may be NULL if it's a broadcast key. In this case no need to
-        * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
-       if (!mac) {
-               low_id = 0xffffffff;
-               high_id = 0xffff | AR5K_KEYTABLE_VALID;
-       } else {
-               low_id = AR5K_LOW_ID(mac);
-               high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
-       }
-
-       ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
-       ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
-
-       return 0;
-}
-
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
deleted file mode 100644 (file)
index 9e2faae..0000000
+++ /dev/null
@@ -1,2599 +0,0 @@
-/*
- * PHY functions
- *
- * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-#define _ATH5K_PHY
-
-#include <linux/delay.h>
-
-#include "ath5k.h"
-#include "reg.h"
-#include "base.h"
-#include "rfbuffer.h"
-#include "rfgain.h"
-
-/*
- * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
- */
-static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
-                                       const struct ath5k_rf_reg *rf_regs,
-                                       u32 val, u8 reg_id, bool set)
-{
-       const struct ath5k_rf_reg *rfreg = NULL;
-       u8 offset, bank, num_bits, col, position;
-       u16 entry;
-       u32 mask, data, last_bit, bits_shifted, first_bit;
-       u32 *rfb;
-       s32 bits_left;
-       int i;
-
-       data = 0;
-       rfb = ah->ah_rf_banks;
-
-       for (i = 0; i < ah->ah_rf_regs_count; i++) {
-               if (rf_regs[i].index == reg_id) {
-                       rfreg = &rf_regs[i];
-                       break;
-               }
-       }
-
-       if (rfb == NULL || rfreg == NULL) {
-               ATH5K_PRINTF("Rf register not found!\n");
-               /* should not happen */
-               return 0;
-       }
-
-       bank = rfreg->bank;
-       num_bits = rfreg->field.len;
-       first_bit = rfreg->field.pos;
-       col = rfreg->field.col;
-
-       /* first_bit is an offset from bank's
-        * start. Since we have all banks on
-        * the same array, we use this offset
-        * to mark each bank's start */
-       offset = ah->ah_offset[bank];
-
-       /* Boundary check */
-       if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
-               ATH5K_PRINTF("invalid values at offset %u\n", offset);
-               return 0;
-       }
-
-       entry = ((first_bit - 1) / 8) + offset;
-       position = (first_bit - 1) % 8;
-
-       if (set)
-               data = ath5k_hw_bitswap(val, num_bits);
-
-       for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
-       position = 0, entry++) {
-
-               last_bit = (position + bits_left > 8) ? 8 :
-                                       position + bits_left;
-
-               mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
-                                                               (col * 8);
-
-               if (set) {
-                       rfb[entry] &= ~mask;
-                       rfb[entry] |= ((data << position) << (col * 8)) & mask;
-                       data >>= (8 - position);
-               } else {
-                       data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
-                               << bits_shifted;
-                       bits_shifted += last_bit - position;
-               }
-
-               bits_left -= 8 - position;
-       }
-
-       data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
-
-       return data;
-}
-
-/**********************\
-* RF Gain optimization *
-\**********************/
-
-/*
- * This code is used to optimize rf gain on different environments
- * (temprature mostly) based on feedback from a power detector.
- *
- * It's only used on RF5111 and RF5112, later RF chips seem to have
- * auto adjustment on hw -notice they have a much smaller BANK 7 and
- * no gain optimization ladder-.
- *
- * For more infos check out this patent doc
- * http://www.freepatentsonline.com/7400691.html
- *
- * This paper describes power drops as seen on the receiver due to
- * probe packets
- * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
- * %20of%20Power%20Control.pdf
- *
- * And this is the MadWiFi bug entry related to the above
- * http://madwifi-project.org/ticket/1659
- * with various measurements and diagrams
- *
- * TODO: Deal with power drops due to probes by setting an apropriate
- * tx power on the probe packets ! Make this part of the calibration process.
- */
-
-/* Initialize ah_gain durring attach */
-int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
-{
-       /* Initialize the gain optimization values */
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
-               ah->ah_gain.g_low = 20;
-               ah->ah_gain.g_high = 35;
-               ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-               break;
-       case AR5K_RF5112:
-               ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
-               ah->ah_gain.g_low = 20;
-               ah->ah_gain.g_high = 85;
-               ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/* Schedule a gain probe check on the next transmited packet.
- * That means our next packet is going to be sent with lower
- * tx power and a Peak to Average Power Detector (PAPD) will try
- * to measure the gain.
- *
- * TODO: Use propper tx power setting for the probe packet so
- * that we don't observe a serious power drop on the receiver
- *
- * XXX:  How about forcing a tx packet (bypassing PCU arbitrator etc)
- * just after we enable the probe so that we don't mess with
- * standard traffic ? Maybe it's time to use sw interrupts and
- * a probe tasklet !!!
- */
-static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
-{
-
-       /* Skip if gain calibration is inactive or
-        * we already handle a probe request */
-       if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
-               return;
-
-       /* Send the packet with 2dB below max power as
-        * patent doc suggest */
-       ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4,
-                       AR5K_PHY_PAPD_PROBE_TXPOWER) |
-                       AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
-
-       ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
-
-}
-
-/* Calculate gain_F measurement correction
- * based on the current step for RF5112 rev. 2 */
-static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
-{
-       u32 mix, step;
-       u32 *rf;
-       const struct ath5k_gain_opt *go;
-       const struct ath5k_gain_opt_step *g_step;
-       const struct ath5k_rf_reg *rf_regs;
-
-       /* Only RF5112 Rev. 2 supports it */
-       if ((ah->ah_radio != AR5K_RF5112) ||
-       (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
-               return 0;
-
-       go = &rfgain_opt_5112;
-       rf_regs = rf_regs_5112a;
-       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
-
-       g_step = &go->go_step[ah->ah_gain.g_step_idx];
-
-       if (ah->ah_rf_banks == NULL)
-               return 0;
-
-       rf = ah->ah_rf_banks;
-       ah->ah_gain.g_f_corr = 0;
-
-       /* No VGA (Variable Gain Amplifier) override, skip */
-       if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
-               return 0;
-
-       /* Mix gain stepping */
-       step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
-
-       /* Mix gain override */
-       mix = g_step->gos_param[0];
-
-       switch (mix) {
-       case 3:
-               ah->ah_gain.g_f_corr = step * 2;
-               break;
-       case 2:
-               ah->ah_gain.g_f_corr = (step - 5) * 2;
-               break;
-       case 1:
-               ah->ah_gain.g_f_corr = step;
-               break;
-       default:
-               ah->ah_gain.g_f_corr = 0;
-               break;
-       }
-
-       return ah->ah_gain.g_f_corr;
-}
-
-/* Check if current gain_F measurement is in the range of our
- * power detector windows. If we get a measurement outside range
- * we know it's not accurate (detectors can't measure anything outside
- * their detection window) so we must ignore it */
-static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
-{
-       const struct ath5k_rf_reg *rf_regs;
-       u32 step, mix_ovr, level[4];
-       u32 *rf;
-
-       if (ah->ah_rf_banks == NULL)
-               return false;
-
-       rf = ah->ah_rf_banks;
-
-       if (ah->ah_radio == AR5K_RF5111) {
-
-               rf_regs = rf_regs_5111;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
-
-               step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
-                       false);
-
-               level[0] = 0;
-               level[1] = (step == 63) ? 50 : step + 4;
-               level[2] = (step != 63) ? 64 : level[0];
-               level[3] = level[2] + 50 ;
-
-               ah->ah_gain.g_high = level[3] -
-                       (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
-               ah->ah_gain.g_low = level[0] +
-                       (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
-       } else {
-
-               rf_regs = rf_regs_5112;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
-
-               mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
-                       false);
-
-               level[0] = level[2] = 0;
-
-               if (mix_ovr == 1) {
-                       level[1] = level[3] = 83;
-               } else {
-                       level[1] = level[3] = 107;
-                       ah->ah_gain.g_high = 55;
-               }
-       }
-
-       return (ah->ah_gain.g_current >= level[0] &&
-                       ah->ah_gain.g_current <= level[1]) ||
-               (ah->ah_gain.g_current >= level[2] &&
-                       ah->ah_gain.g_current <= level[3]);
-}
-
-/* Perform gain_F adjustment by choosing the right set
- * of parameters from rf gain optimization ladder */
-static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
-{
-       const struct ath5k_gain_opt *go;
-       const struct ath5k_gain_opt_step *g_step;
-       int ret = 0;
-
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               go = &rfgain_opt_5111;
-               break;
-       case AR5K_RF5112:
-               go = &rfgain_opt_5112;
-               break;
-       default:
-               return 0;
-       }
-
-       g_step = &go->go_step[ah->ah_gain.g_step_idx];
-
-       if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
-
-               /* Reached maximum */
-               if (ah->ah_gain.g_step_idx == 0)
-                       return -1;
-
-               for (ah->ah_gain.g_target = ah->ah_gain.g_current;
-                               ah->ah_gain.g_target >=  ah->ah_gain.g_high &&
-                               ah->ah_gain.g_step_idx > 0;
-                               g_step = &go->go_step[ah->ah_gain.g_step_idx])
-                       ah->ah_gain.g_target -= 2 *
-                           (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
-                           g_step->gos_gain);
-
-               ret = 1;
-               goto done;
-       }
-
-       if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
-
-               /* Reached minimum */
-               if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
-                       return -2;
-
-               for (ah->ah_gain.g_target = ah->ah_gain.g_current;
-                               ah->ah_gain.g_target <= ah->ah_gain.g_low &&
-                               ah->ah_gain.g_step_idx < go->go_steps_count-1;
-                               g_step = &go->go_step[ah->ah_gain.g_step_idx])
-                       ah->ah_gain.g_target -= 2 *
-                           (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
-                           g_step->gos_gain);
-
-               ret = 2;
-               goto done;
-       }
-
-done:
-       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
-               "ret %d, gain step %u, current gain %u, target gain %u\n",
-               ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
-               ah->ah_gain.g_target);
-
-       return ret;
-}
-
-/* Main callback for thermal rf gain calibration engine
- * Check for a new gain reading and schedule an adjustment
- * if needed.
- *
- * TODO: Use sw interrupt to schedule reset if gain_F needs
- * adjustment */
-enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
-{
-       u32 data, type;
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (ah->ah_rf_banks == NULL ||
-       ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
-               return AR5K_RFGAIN_INACTIVE;
-
-       /* No check requested, either engine is inactive
-        * or an adjustment is already requested */
-       if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
-               goto done;
-
-       /* Read the PAPD (Peak to Average Power Detector)
-        * register */
-       data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
-
-       /* No probe is scheduled, read gain_F measurement */
-       if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
-               ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
-               type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
-
-               /* If tx packet is CCK correct the gain_F measurement
-                * by cck ofdm gain delta */
-               if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
-                       if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
-                               ah->ah_gain.g_current +=
-                                       ee->ee_cck_ofdm_gain_delta;
-                       else
-                               ah->ah_gain.g_current +=
-                                       AR5K_GAIN_CCK_PROBE_CORR;
-               }
-
-               /* Further correct gain_F measurement for
-                * RF5112A radios */
-               if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
-                       ath5k_hw_rf_gainf_corr(ah);
-                       ah->ah_gain.g_current =
-                               ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
-                               (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
-                               0;
-               }
-
-               /* Check if measurement is ok and if we need
-                * to adjust gain, schedule a gain adjustment,
-                * else switch back to the acive state */
-               if (ath5k_hw_rf_check_gainf_readback(ah) &&
-               AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
-               ath5k_hw_rf_gainf_adjust(ah)) {
-                       ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
-               } else {
-                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-               }
-       }
-
-done:
-       return ah->ah_gain.g_state;
-}
-
-/* Write initial rf gain table to set the RF sensitivity
- * this one works on all RF chips and has nothing to do
- * with gain_F calibration */
-int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
-{
-       const struct ath5k_ini_rfgain *ath5k_rfg;
-       unsigned int i, size;
-
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               ath5k_rfg = rfgain_5111;
-               size = ARRAY_SIZE(rfgain_5111);
-               break;
-       case AR5K_RF5112:
-               ath5k_rfg = rfgain_5112;
-               size = ARRAY_SIZE(rfgain_5112);
-               break;
-       case AR5K_RF2413:
-               ath5k_rfg = rfgain_2413;
-               size = ARRAY_SIZE(rfgain_2413);
-               break;
-       case AR5K_RF2316:
-               ath5k_rfg = rfgain_2316;
-               size = ARRAY_SIZE(rfgain_2316);
-               break;
-       case AR5K_RF5413:
-               ath5k_rfg = rfgain_5413;
-               size = ARRAY_SIZE(rfgain_5413);
-               break;
-       case AR5K_RF2317:
-       case AR5K_RF2425:
-               ath5k_rfg = rfgain_2425;
-               size = ARRAY_SIZE(rfgain_2425);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       switch (freq) {
-       case AR5K_INI_RFGAIN_2GHZ:
-       case AR5K_INI_RFGAIN_5GHZ:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (i = 0; i < size; i++) {
-               AR5K_REG_WAIT(i);
-               ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
-                       (u32)ath5k_rfg[i].rfg_register);
-       }
-
-       return 0;
-}
-
-
-
-/********************\
-* RF Registers setup *
-\********************/
-
-
-/*
- * Setup RF registers by writing rf buffer on hw
- */
-int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
-               unsigned int mode)
-{
-       const struct ath5k_rf_reg *rf_regs;
-       const struct ath5k_ini_rfbuffer *ini_rfb;
-       const struct ath5k_gain_opt *go = NULL;
-       const struct ath5k_gain_opt_step *g_step;
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u8 ee_mode = 0;
-       u32 *rfb;
-       int i, obdb = -1, bank = -1;
-
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               rf_regs = rf_regs_5111;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
-               ini_rfb = rfb_5111;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
-               go = &rfgain_opt_5111;
-               break;
-       case AR5K_RF5112:
-               if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
-                       rf_regs = rf_regs_5112a;
-                       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
-                       ini_rfb = rfb_5112a;
-                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
-               } else {
-                       rf_regs = rf_regs_5112;
-                       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
-                       ini_rfb = rfb_5112;
-                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
-               }
-               go = &rfgain_opt_5112;
-               break;
-       case AR5K_RF2413:
-               rf_regs = rf_regs_2413;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
-               ini_rfb = rfb_2413;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
-               break;
-       case AR5K_RF2316:
-               rf_regs = rf_regs_2316;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
-               ini_rfb = rfb_2316;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
-               break;
-       case AR5K_RF5413:
-               rf_regs = rf_regs_5413;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
-               ini_rfb = rfb_5413;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
-               break;
-       case AR5K_RF2317:
-               rf_regs = rf_regs_2425;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
-               ini_rfb = rfb_2317;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
-               break;
-       case AR5K_RF2425:
-               rf_regs = rf_regs_2425;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
-               if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
-                       ini_rfb = rfb_2425;
-                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
-               } else {
-                       ini_rfb = rfb_2417;
-                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
-               }
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* If it's the first time we set rf buffer, allocate
-        * ah->ah_rf_banks based on ah->ah_rf_banks_size
-        * we set above */
-       if (ah->ah_rf_banks == NULL) {
-               ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
-                                                               GFP_KERNEL);
-               if (ah->ah_rf_banks == NULL) {
-                       ATH5K_ERR(ah->ah_sc, "out of memory\n");
-                       return -ENOMEM;
-               }
-       }
-
-       /* Copy values to modify them */
-       rfb = ah->ah_rf_banks;
-
-       for (i = 0; i < ah->ah_rf_banks_size; i++) {
-               if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
-                       ATH5K_ERR(ah->ah_sc, "invalid bank\n");
-                       return -EINVAL;
-               }
-
-               /* Bank changed, write down the offset */
-               if (bank != ini_rfb[i].rfb_bank) {
-                       bank = ini_rfb[i].rfb_bank;
-                       ah->ah_offset[bank] = i;
-               }
-
-               rfb[i] = ini_rfb[i].rfb_mode_data[mode];
-       }
-
-       /* Set Output and Driver bias current (OB/DB) */
-       if (channel->hw_value & CHANNEL_2GHZ) {
-
-               if (channel->hw_value & CHANNEL_CCK)
-                       ee_mode = AR5K_EEPROM_MODE_11B;
-               else
-                       ee_mode = AR5K_EEPROM_MODE_11G;
-
-               /* For RF511X/RF211X combination we
-                * use b_OB and b_DB parameters stored
-                * in eeprom on ee->ee_ob[ee_mode][0]
-                *
-                * For all other chips we use OB/DB for 2Ghz
-                * stored in the b/g modal section just like
-                * 802.11a on ee->ee_ob[ee_mode][1] */
-               if ((ah->ah_radio == AR5K_RF5111) ||
-               (ah->ah_radio == AR5K_RF5112))
-                       obdb = 0;
-               else
-                       obdb = 1;
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
-                                               AR5K_RF_OB_2GHZ, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
-                                               AR5K_RF_DB_2GHZ, true);
-
-       /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
-       } else if ((channel->hw_value & CHANNEL_5GHZ) ||
-                       (ah->ah_radio == AR5K_RF5111)) {
-
-               /* For 11a, Turbo and XR we need to choose
-                * OB/DB based on frequency range */
-               ee_mode = AR5K_EEPROM_MODE_11A;
-               obdb =   channel->center_freq >= 5725 ? 3 :
-                       (channel->center_freq >= 5500 ? 2 :
-                       (channel->center_freq >= 5260 ? 1 :
-                        (channel->center_freq > 4000 ? 0 : -1)));
-
-               if (obdb < 0)
-                       return -EINVAL;
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
-                                               AR5K_RF_OB_5GHZ, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
-                                               AR5K_RF_DB_5GHZ, true);
-       }
-
-       g_step = &go->go_step[ah->ah_gain.g_step_idx];
-
-       /* Bank Modifications (chip-specific) */
-       if (ah->ah_radio == AR5K_RF5111) {
-
-               /* Set gain_F settings according to current step */
-               if (channel->hw_value & CHANNEL_OFDM) {
-
-                       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
-                                       AR5K_PHY_FRAME_CTL_TX_CLIP,
-                                       g_step->gos_param[0]);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
-                                                       AR5K_RF_PWD_90, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
-                                                       AR5K_RF_PWD_84, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
-                                               AR5K_RF_RFGAIN_SEL, true);
-
-                       /* We programmed gain_F parameters, switch back
-                        * to active state */
-                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-
-               }
-
-               /* Bank 6/7 setup */
-
-               ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
-                                               AR5K_RF_PWD_XPD, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
-                                               AR5K_RF_XPD_GAIN, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
-                                               AR5K_RF_GAIN_I, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
-                                               AR5K_RF_PLO_SEL, true);
-
-               /* TODO: Half/quarter channel support */
-       }
-
-       if (ah->ah_radio == AR5K_RF5112) {
-
-               /* Set gain_F settings according to current step */
-               if (channel->hw_value & CHANNEL_OFDM) {
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
-                                               AR5K_RF_MIXGAIN_OVR, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
-                                               AR5K_RF_PWD_138, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
-                                               AR5K_RF_PWD_137, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
-                                               AR5K_RF_PWD_136, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
-                                               AR5K_RF_PWD_132, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
-                                               AR5K_RF_PWD_131, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
-                                               AR5K_RF_PWD_130, true);
-
-                       /* We programmed gain_F parameters, switch back
-                        * to active state */
-                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-               }
-
-               /* Bank 6/7 setup */
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
-                                               AR5K_RF_XPD_SEL, true);
-
-               if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
-                       /* Rev. 1 supports only one xpd */
-                       ath5k_hw_rfb_op(ah, rf_regs,
-                                               ee->ee_x_gain[ee_mode],
-                                               AR5K_RF_XPD_GAIN, true);
-
-               } else {
-                       /* TODO: Set high and low gain bits */
-                       ath5k_hw_rfb_op(ah, rf_regs,
-                                               ee->ee_x_gain[ee_mode],
-                                               AR5K_RF_PD_GAIN_LO, true);
-                       ath5k_hw_rfb_op(ah, rf_regs,
-                                               ee->ee_x_gain[ee_mode],
-                                               AR5K_RF_PD_GAIN_HI, true);
-
-                       /* Lower synth voltage on Rev 2 */
-                       ath5k_hw_rfb_op(ah, rf_regs, 2,
-                                       AR5K_RF_HIGH_VC_CP, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, 2,
-                                       AR5K_RF_MID_VC_CP, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, 2,
-                                       AR5K_RF_LOW_VC_CP, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, 2,
-                                       AR5K_RF_PUSH_UP, true);
-
-                       /* Decrease power consumption on 5213+ BaseBand */
-                       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_PAD2GND, true);
-
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_XB2_LVL, true);
-
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_XB5_LVL, true);
-
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_PWD_167, true);
-
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_PWD_166, true);
-                       }
-               }
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
-                                               AR5K_RF_GAIN_I, true);
-
-               /* TODO: Half/quarter channel support */
-
-       }
-
-       if (ah->ah_radio == AR5K_RF5413 &&
-       channel->hw_value & CHANNEL_2GHZ) {
-
-               ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
-                                                                       true);
-
-               /* Set optimum value for early revisions (on pci-e chips) */
-               if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
-               ah->ah_mac_srev < AR5K_SREV_AR5413)
-                       ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
-                                               AR5K_RF_PWD_ICLOBUF_2G, true);
-
-       }
-
-       /* Write RF banks on hw */
-       for (i = 0; i < ah->ah_rf_banks_size; i++) {
-               AR5K_REG_WAIT(i);
-               ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
-       }
-
-       return 0;
-}
-
-
-/**************************\
-  PHY/RF channel functions
-\**************************/
-
-/*
- * Check if a channel is supported
- */
-bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
-{
-       /* Check if the channel is in our supported range */
-       if (flags & CHANNEL_2GHZ) {
-               if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
-                   (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
-                       return true;
-       } else if (flags & CHANNEL_5GHZ)
-               if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
-                   (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
-                       return true;
-
-       return false;
-}
-
-/*
- * Convertion needed for RF5110
- */
-static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
-{
-       u32 athchan;
-
-       /*
-        * Convert IEEE channel/MHz to an internal channel value used
-        * by the AR5210 chipset. This has not been verified with
-        * newer chipsets like the AR5212A who have a completely
-        * different RF/PHY part.
-        */
-       athchan = (ath5k_hw_bitswap(
-                       (ieee80211_frequency_to_channel(
-                               channel->center_freq) - 24) / 2, 5)
-                               << 1) | (1 << 6) | 0x1;
-       return athchan;
-}
-
-/*
- * Set channel on RF5110
- */
-static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 data;
-
-       /*
-        * Set the channel and wait
-        */
-       data = ath5k_hw_rf5110_chan2athchan(channel);
-       ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER);
-       ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0);
-       mdelay(1);
-
-       return 0;
-}
-
-/*
- * Convertion needed for 5111
- */
-static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
-               struct ath5k_athchan_2ghz *athchan)
-{
-       int channel;
-
-       /* Cast this value to catch negative channel numbers (>= -19) */
-       channel = (int)ieee;
-
-       /*
-        * Map 2GHz IEEE channel to 5GHz Atheros channel
-        */
-       if (channel <= 13) {
-               athchan->a2_athchan = 115 + channel;
-               athchan->a2_flags = 0x46;
-       } else if (channel == 14) {
-               athchan->a2_athchan = 124;
-               athchan->a2_flags = 0x44;
-       } else if (channel >= 15 && channel <= 26) {
-               athchan->a2_athchan = ((channel - 14) * 4) + 132;
-               athchan->a2_flags = 0x46;
-       } else
-               return -EINVAL;
-
-       return 0;
-}
-
-/*
- * Set channel on 5111
- */
-static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       struct ath5k_athchan_2ghz ath5k_channel_2ghz;
-       unsigned int ath5k_channel =
-               ieee80211_frequency_to_channel(channel->center_freq);
-       u32 data0, data1, clock;
-       int ret;
-
-       /*
-        * Set the channel on the RF5111 radio
-        */
-       data0 = data1 = 0;
-
-       if (channel->hw_value & CHANNEL_2GHZ) {
-               /* Map 2GHz channel to 5GHz Atheros channel ID */
-               ret = ath5k_hw_rf5111_chan2athchan(
-                       ieee80211_frequency_to_channel(channel->center_freq),
-                       &ath5k_channel_2ghz);
-               if (ret)
-                       return ret;
-
-               ath5k_channel = ath5k_channel_2ghz.a2_athchan;
-               data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
-                   << 5) | (1 << 4);
-       }
-
-       if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
-               clock = 1;
-               data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
-                       (clock << 1) | (1 << 10) | 1;
-       } else {
-               clock = 0;
-               data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
-                       << 2) | (clock << 1) | (1 << 10) | 1;
-       }
-
-       ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
-                       AR5K_RF_BUFFER);
-       ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
-                       AR5K_RF_BUFFER_CONTROL_3);
-
-       return 0;
-}
-
-/*
- * Set channel on 5112 and newer
- */
-static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 data, data0, data1, data2;
-       u16 c;
-
-       data = data0 = data1 = data2 = 0;
-       c = channel->center_freq;
-
-       if (c < 4800) {
-               if (!((c - 2224) % 5)) {
-                       data0 = ((2 * (c - 704)) - 3040) / 10;
-                       data1 = 1;
-               } else if (!((c - 2192) % 5)) {
-                       data0 = ((2 * (c - 672)) - 3040) / 10;
-                       data1 = 0;
-               } else
-                       return -EINVAL;
-
-               data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
-       } else if ((c - (c % 5)) != 2 || c > 5435) {
-               if (!(c % 20) && c >= 5120) {
-                       data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
-                       data2 = ath5k_hw_bitswap(3, 2);
-               } else if (!(c % 10)) {
-                       data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
-                       data2 = ath5k_hw_bitswap(2, 2);
-               } else if (!(c % 5)) {
-                       data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
-                       data2 = ath5k_hw_bitswap(1, 2);
-               } else
-                       return -EINVAL;
-       } else {
-               data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
-               data2 = ath5k_hw_bitswap(0, 2);
-       }
-
-       data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
-
-       ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
-       ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
-
-       return 0;
-}
-
-/*
- * Set the channel on the RF2425
- */
-static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 data, data0, data2;
-       u16 c;
-
-       data = data0 = data2 = 0;
-       c = channel->center_freq;
-
-       if (c < 4800) {
-               data0 = ath5k_hw_bitswap((c - 2272), 8);
-               data2 = 0;
-       /* ? 5GHz ? */
-       } else if ((c - (c % 5)) != 2 || c > 5435) {
-               if (!(c % 20) && c < 5120)
-                       data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
-               else if (!(c % 10))
-                       data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
-               else if (!(c % 5))
-                       data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
-               else
-                       return -EINVAL;
-               data2 = ath5k_hw_bitswap(1, 2);
-       } else {
-               data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
-               data2 = ath5k_hw_bitswap(0, 2);
-       }
-
-       data = (data0 << 4) | data2 << 2 | 0x1001;
-
-       ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
-       ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
-
-       return 0;
-}
-
-/*
- * Set a channel on the radio chip
- */
-int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
-{
-       int ret;
-       /*
-        * Check bounds supported by the PHY (we don't care about regultory
-        * restrictions at this point). Note: hw_value already has the band
-        * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok()
-        * of the band by that */
-       if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) {
-               ATH5K_ERR(ah->ah_sc,
-                       "channel frequency (%u MHz) out of supported "
-                       "band range\n",
-                       channel->center_freq);
-                       return -EINVAL;
-       }
-
-       /*
-        * Set the channel and wait
-        */
-       switch (ah->ah_radio) {
-       case AR5K_RF5110:
-               ret = ath5k_hw_rf5110_channel(ah, channel);
-               break;
-       case AR5K_RF5111:
-               ret = ath5k_hw_rf5111_channel(ah, channel);
-               break;
-       case AR5K_RF2425:
-               ret = ath5k_hw_rf2425_channel(ah, channel);
-               break;
-       default:
-               ret = ath5k_hw_rf5112_channel(ah, channel);
-               break;
-       }
-
-       if (ret)
-               return ret;
-
-       /* Set JAPAN setting for channel 14 */
-       if (channel->center_freq == 2484) {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
-                               AR5K_PHY_CCKTXCTL_JAPAN);
-       } else {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
-                               AR5K_PHY_CCKTXCTL_WORLD);
-       }
-
-       ah->ah_current_channel.center_freq = channel->center_freq;
-       ah->ah_current_channel.hw_value = channel->hw_value;
-       ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
-
-       return 0;
-}
-
-/*****************\
-  PHY calibration
-\*****************/
-
-/**
- * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
- *
- * @ah: struct ath5k_hw pointer we are operating on
- * @freq: the channel frequency, just used for error logging
- *
- * This function performs a noise floor calibration of the PHY and waits for
- * it to complete. Then the noise floor value is compared to some maximum
- * noise floor we consider valid.
- *
- * Note that this is different from what the madwifi HAL does: it reads the
- * noise floor and afterwards initiates the calibration. Since the noise floor
- * calibration can take some time to finish, depending on the current channel
- * use, that avoids the occasional timeout warnings we are seeing now.
- *
- * See the following link for an Atheros patent on noise floor calibration:
- * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \
- * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7
- *
- * XXX: Since during noise floor calibration antennas are detached according to
- * the patent, we should stop tx queues here.
- */
-int
-ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
-{
-       int ret;
-       unsigned int i;
-       s32 noise_floor;
-
-       /*
-        * Enable noise floor calibration
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
-                               AR5K_PHY_AGCCTL_NF);
-
-       ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
-                       AR5K_PHY_AGCCTL_NF, 0, false);
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc,
-                       "noise floor calibration timeout (%uMHz)\n", freq);
-               return -EAGAIN;
-       }
-
-       /* Wait until the noise floor is calibrated and read the value */
-       for (i = 20; i > 0; i--) {
-               mdelay(1);
-               noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
-               noise_floor = AR5K_PHY_NF_RVAL(noise_floor);
-               if (noise_floor & AR5K_PHY_NF_ACTIVE) {
-                       noise_floor = AR5K_PHY_NF_AVAL(noise_floor);
-
-                       if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
-                               break;
-               }
-       }
-
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
-               "noise floor %d\n", noise_floor);
-
-       if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
-               ATH5K_ERR(ah->ah_sc,
-                       "noise floor calibration failed (%uMHz)\n", freq);
-               return -EAGAIN;
-       }
-
-       ah->ah_noise_floor = noise_floor;
-
-       return 0;
-}
-
-/*
- * Perform a PHY calibration on RF5110
- * -Fix BPSK/QAM Constellation (I/Q correction)
- * -Calculate Noise Floor
- */
-static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 phy_sig, phy_agc, phy_sat, beacon;
-       int ret;
-
-       /*
-        * Disable beacons and RX/TX queues, wait
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
-               AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
-       beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
-       ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
-
-       mdelay(2);
-
-       /*
-        * Set the channel (with AGC turned off)
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
-       udelay(10);
-       ret = ath5k_hw_channel(ah, channel);
-
-       /*
-        * Activate PHY and wait
-        */
-       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
-       mdelay(1);
-
-       AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
-
-       if (ret)
-               return ret;
-
-       /*
-        * Calibrate the radio chip
-        */
-
-       /* Remember normal state */
-       phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG);
-       phy_agc = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCOARSE);
-       phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT);
-
-       /* Update radio registers */
-       ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
-               AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG);
-
-       ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI |
-                       AR5K_PHY_AGCCOARSE_LO)) |
-               AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) |
-               AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE);
-
-       ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT |
-                       AR5K_PHY_ADCSAT_THR)) |
-               AR5K_REG_SM(2, AR5K_PHY_ADCSAT_ICNT) |
-               AR5K_REG_SM(12, AR5K_PHY_ADCSAT_THR), AR5K_PHY_ADCSAT);
-
-       udelay(20);
-
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
-       udelay(10);
-       ath5k_hw_reg_write(ah, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG);
-       AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
-
-       mdelay(1);
-
-       /*
-        * Enable calibration and wait until completion
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL);
-
-       ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
-                       AR5K_PHY_AGCCTL_CAL, 0, false);
-
-       /* Reset to normal state */
-       ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG);
-       ath5k_hw_reg_write(ah, phy_agc, AR5K_PHY_AGCCOARSE);
-       ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT);
-
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
-                               channel->center_freq);
-               return ret;
-       }
-
-       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-
-       /*
-        * Re-enable RX/TX and beacons
-        */
-       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
-               AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
-       ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
-
-       return 0;
-}
-
-/*
- * Perform a PHY calibration on RF5111/5112 and newer chips
- */
-static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 i_pwr, q_pwr;
-       s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
-       int i;
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (!ah->ah_calibration ||
-               ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
-               goto done;
-
-       /* Calibration has finished, get the results and re-run */
-       for (i = 0; i <= 10; i++) {
-               iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
-               i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
-               q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
-       }
-
-       i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
-       q_coffd = q_pwr >> 7;
-
-       /* No correction */
-       if (i_coffd == 0 || q_coffd == 0)
-               goto done;
-
-       i_coff = ((-iq_corr) / i_coffd) & 0x3f;
-
-       /* Boundary check */
-       if (i_coff > 31)
-               i_coff = 31;
-       if (i_coff < -32)
-               i_coff = -32;
-
-       q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f;
-
-       /* Boundary check */
-       if (q_coff > 15)
-               q_coff = 15;
-       if (q_coff < -16)
-               q_coff = -16;
-
-       /* Commit new I/Q value */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
-               ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
-
-       /* Re-enable calibration -if we don't we'll commit
-        * the same values again and again */
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
-                       AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
-
-done:
-
-       /* TODO: Separate noise floor calibration from I/Q calibration
-        * since noise floor calibration interrupts rx path while I/Q
-        * calibration doesn't. We don't need to run noise floor calibration
-        * as often as I/Q calibration.*/
-       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-
-       /* Initiate a gain_F calibration */
-       ath5k_hw_request_rfgain_probe(ah);
-
-       return 0;
-}
-
-/*
- * Perform a PHY calibration
- */
-int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       int ret;
-
-       if (ah->ah_radio == AR5K_RF5110)
-               ret = ath5k_hw_rf5110_calibrate(ah, channel);
-       else
-               ret = ath5k_hw_rf511x_calibrate(ah, channel);
-
-       return ret;
-}
-
-int ath5k_hw_phy_disable(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /*Just a try M.F.*/
-       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
-
-       return 0;
-}
-
-/********************\
-  Misc PHY functions
-\********************/
-
-/*
- * Get the PHY Chip revision
- */
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
-{
-       unsigned int i;
-       u32 srev;
-       u16 ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*
-        * Set the radio chip access register
-        */
-       switch (chan) {
-       case CHANNEL_2GHZ:
-               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
-               break;
-       case CHANNEL_5GHZ:
-               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
-               break;
-       default:
-               return 0;
-       }
-
-       mdelay(2);
-
-       /* ...wait until PHY is ready and read the selected radio revision */
-       ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
-
-       for (i = 0; i < 8; i++)
-               ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
-
-       if (ah->ah_version == AR5K_AR5210) {
-               srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
-               ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
-       } else {
-               srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
-               ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
-                               ((srev & 0x0f) << 4), 8);
-       }
-
-       /* Reset to the 5GHz mode */
-       ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
-
-       return ret;
-}
-
-void /*TODO:Boundary check*/
-ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /*Just a try M.F.*/
-       if (ah->ah_version != AR5K_AR5210)
-               ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA);
-}
-
-unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /*Just a try M.F.*/
-       if (ah->ah_version != AR5K_AR5210)
-               return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
-
-       return false; /*XXX: What do we return for 5210 ?*/
-}
-
-
-/****************\
-* TX power setup *
-\****************/
-
-/*
- * Helper functions
- */
-
-/*
- * Do linear interpolation between two given (x, y) points
- */
-static s16
-ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
-                                       s16 y_left, s16 y_right)
-{
-       s16 ratio, result;
-
-       /* Avoid divide by zero and skip interpolation
-        * if we have the same point */
-       if ((x_left == x_right) || (y_left == y_right))
-               return y_left;
-
-       /*
-        * Since we use ints and not fps, we need to scale up in
-        * order to get a sane ratio value (or else we 'll eg. get
-        * always 1 instead of 1.25, 1.75 etc). We scale up by 100
-        * to have some accuracy both for 0.5 and 0.25 steps.
-        */
-       ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left));
-
-       /* Now scale down to be in range */
-       result = y_left + (ratio * (target - x_left) / 100);
-
-       return result;
-}
-
-/*
- * Find vertical boundary (min pwr) for the linear PCDAC curve.
- *
- * Since we have the top of the curve and we draw the line below
- * until we reach 1 (1 pcdac step) we need to know which point
- * (x value) that is so that we don't go below y axis and have negative
- * pcdac values when creating the curve, or fill the table with zeroes.
- */
-static s16
-ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
-                               const s16 *pwrL, const s16 *pwrR)
-{
-       s8 tmp;
-       s16 min_pwrL, min_pwrR;
-       s16 pwr_i = pwrL[0];
-
-       do {
-               pwr_i--;
-               tmp = (s8) ath5k_get_interpolated_value(pwr_i,
-                                               pwrL[0], pwrL[1],
-                                               stepL[0], stepL[1]);
-
-       } while (tmp > 1);
-
-       min_pwrL = pwr_i;
-
-       pwr_i = pwrR[0];
-       do {
-               pwr_i--;
-               tmp = (s8) ath5k_get_interpolated_value(pwr_i,
-                                               pwrR[0], pwrR[1],
-                                               stepR[0], stepR[1]);
-
-       } while (tmp > 1);
-
-       min_pwrR = pwr_i;
-
-       /* Keep the right boundary so that it works for both curves */
-       return max(min_pwrL, min_pwrR);
-}
-
-/*
- * Interpolate (pwr,vpd) points to create a Power to PDADC or a
- * Power to PCDAC curve.
- *
- * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC
- * steps (offsets) on y axis. Power can go up to 31.5dB and max
- * PCDAC/PDADC step for each curve is 64 but we can write more than
- * one curves on hw so we can go up to 128 (which is the max step we
- * can write on the final table).
- *
- * We write y values (PCDAC/PDADC steps) on hw.
- */
-static void
-ath5k_create_power_curve(s16 pmin, s16 pmax,
-                       const s16 *pwr, const u8 *vpd,
-                       u8 num_points,
-                       u8 *vpd_table, u8 type)
-{
-       u8 idx[2] = { 0, 1 };
-       s16 pwr_i = 2*pmin;
-       int i;
-
-       if (num_points < 2)
-               return;
-
-       /* We want the whole line, so adjust boundaries
-        * to cover the entire power range. Note that
-        * power values are already 0.25dB so no need
-        * to multiply pwr_i by 2 */
-       if (type == AR5K_PWRTABLE_LINEAR_PCDAC) {
-               pwr_i = pmin;
-               pmin = 0;
-               pmax = 63;
-       }
-
-       /* Find surrounding turning points (TPs)
-        * and interpolate between them */
-       for (i = 0; (i <= (u16) (pmax - pmin)) &&
-       (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
-
-               /* We passed the right TP, move to the next set of TPs
-                * if we pass the last TP, extrapolate above using the last
-                * two TPs for ratio */
-               if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
-                       idx[0]++;
-                       idx[1]++;
-               }
-
-               vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
-                                               pwr[idx[0]], pwr[idx[1]],
-                                               vpd[idx[0]], vpd[idx[1]]);
-
-               /* Increase by 0.5dB
-                * (0.25 dB units) */
-               pwr_i += 2;
-       }
-}
-
-/*
- * Get the surrounding per-channel power calibration piers
- * for a given frequency so that we can interpolate between
- * them and come up with an apropriate dataset for our current
- * channel.
- */
-static void
-ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
-                       struct ieee80211_channel *channel,
-                       struct ath5k_chan_pcal_info **pcinfo_l,
-                       struct ath5k_chan_pcal_info **pcinfo_r)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *pcinfo;
-       u8 idx_l, idx_r;
-       u8 mode, max, i;
-       u32 target = channel->center_freq;
-
-       idx_l = 0;
-       idx_r = 0;
-
-       if (!(channel->hw_value & CHANNEL_OFDM)) {
-               pcinfo = ee->ee_pwr_cal_b;
-               mode = AR5K_EEPROM_MODE_11B;
-       } else if (channel->hw_value & CHANNEL_2GHZ) {
-               pcinfo = ee->ee_pwr_cal_g;
-               mode = AR5K_EEPROM_MODE_11G;
-       } else {
-               pcinfo = ee->ee_pwr_cal_a;
-               mode = AR5K_EEPROM_MODE_11A;
-       }
-       max = ee->ee_n_piers[mode] - 1;
-
-       /* Frequency is below our calibrated
-        * range. Use the lowest power curve
-        * we have */
-       if (target < pcinfo[0].freq) {
-               idx_l = idx_r = 0;
-               goto done;
-       }
-
-       /* Frequency is above our calibrated
-        * range. Use the highest power curve
-        * we have */
-       if (target > pcinfo[max].freq) {
-               idx_l = idx_r = max;
-               goto done;
-       }
-
-       /* Frequency is inside our calibrated
-        * channel range. Pick the surrounding
-        * calibration piers so that we can
-        * interpolate */
-       for (i = 0; i <= max; i++) {
-
-               /* Frequency matches one of our calibration
-                * piers, no need to interpolate, just use
-                * that calibration pier */
-               if (pcinfo[i].freq == target) {
-                       idx_l = idx_r = i;
-                       goto done;
-               }
-
-               /* We found a calibration pier that's above
-                * frequency, use this pier and the previous
-                * one to interpolate */
-               if (target < pcinfo[i].freq) {
-                       idx_r = i;
-                       idx_l = idx_r - 1;
-                       goto done;
-               }
-       }
-
-done:
-       *pcinfo_l = &pcinfo[idx_l];
-       *pcinfo_r = &pcinfo[idx_r];
-
-       return;
-}
-
-/*
- * Get the surrounding per-rate power calibration data
- * for a given frequency and interpolate between power
- * values to set max target power supported by hw for
- * each rate.
- */
-static void
-ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
-                       struct ieee80211_channel *channel,
-                       struct ath5k_rate_pcal_info *rates)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_rate_pcal_info *rpinfo;
-       u8 idx_l, idx_r;
-       u8 mode, max, i;
-       u32 target = channel->center_freq;
-
-       idx_l = 0;
-       idx_r = 0;
-
-       if (!(channel->hw_value & CHANNEL_OFDM)) {
-               rpinfo = ee->ee_rate_tpwr_b;
-               mode = AR5K_EEPROM_MODE_11B;
-       } else if (channel->hw_value & CHANNEL_2GHZ) {
-               rpinfo = ee->ee_rate_tpwr_g;
-               mode = AR5K_EEPROM_MODE_11G;
-       } else {
-               rpinfo = ee->ee_rate_tpwr_a;
-               mode = AR5K_EEPROM_MODE_11A;
-       }
-       max = ee->ee_rate_target_pwr_num[mode] - 1;
-
-       /* Get the surrounding calibration
-        * piers - same as above */
-       if (target < rpinfo[0].freq) {
-               idx_l = idx_r = 0;
-               goto done;
-       }
-
-       if (target > rpinfo[max].freq) {
-               idx_l = idx_r = max;
-               goto done;
-       }
-
-       for (i = 0; i <= max; i++) {
-
-               if (rpinfo[i].freq == target) {
-                       idx_l = idx_r = i;
-                       goto done;
-               }
-
-               if (target < rpinfo[i].freq) {
-                       idx_r = i;
-                       idx_l = idx_r - 1;
-                       goto done;
-               }
-       }
-
-done:
-       /* Now interpolate power value, based on the frequency */
-       rates->freq = target;
-
-       rates->target_power_6to24 =
-               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
-                                       rpinfo[idx_r].freq,
-                                       rpinfo[idx_l].target_power_6to24,
-                                       rpinfo[idx_r].target_power_6to24);
-
-       rates->target_power_36 =
-               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
-                                       rpinfo[idx_r].freq,
-                                       rpinfo[idx_l].target_power_36,
-                                       rpinfo[idx_r].target_power_36);
-
-       rates->target_power_48 =
-               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
-                                       rpinfo[idx_r].freq,
-                                       rpinfo[idx_l].target_power_48,
-                                       rpinfo[idx_r].target_power_48);
-
-       rates->target_power_54 =
-               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
-                                       rpinfo[idx_r].freq,
-                                       rpinfo[idx_l].target_power_54,
-                                       rpinfo[idx_r].target_power_54);
-}
-
-/*
- * Get the max edge power for this channel if
- * we have such data from EEPROM's Conformance Test
- * Limits (CTL), and limit max power if needed.
- *
- * FIXME: Only works for world regulatory domains
- */
-static void
-ath5k_get_max_ctl_power(struct ath5k_hw *ah,
-                       struct ieee80211_channel *channel)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
-       u8 *ctl_val = ee->ee_ctl;
-       s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
-       s16 edge_pwr = 0;
-       u8 rep_idx;
-       u8 i, ctl_mode;
-       u8 ctl_idx = 0xFF;
-       u32 target = channel->center_freq;
-
-       /* Find out a CTL for our mode that's not mapped
-        * on a specific reg domain.
-        *
-        * TODO: Map our current reg domain to one of the 3 available
-        * reg domain ids so that we can support more CTLs. */
-       switch (channel->hw_value & CHANNEL_MODES) {
-       case CHANNEL_A:
-               ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_G:
-               ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_B:
-               ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_T:
-               ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_TG:
-               ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_XR:
-               /* Fall through */
-       default:
-               return;
-       }
-
-       for (i = 0; i < ee->ee_ctls; i++) {
-               if (ctl_val[i] == ctl_mode) {
-                       ctl_idx = i;
-                       break;
-               }
-       }
-
-       /* If we have a CTL dataset available grab it and find the
-        * edge power for our frequency */
-       if (ctl_idx == 0xFF)
-               return;
-
-       /* Edge powers are sorted by frequency from lower
-        * to higher. Each CTL corresponds to 8 edge power
-        * measurements. */
-       rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
-
-       /* Don't do boundaries check because we
-        * might have more that one bands defined
-        * for this mode */
-
-       /* Get the edge power that's closer to our
-        * frequency */
-       for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
-               rep_idx += i;
-               if (target <= rep[rep_idx].freq)
-                       edge_pwr = (s16) rep[rep_idx].edge;
-       }
-
-       if (edge_pwr)
-               ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr);
-}
-
-
-/*
- * Power to PCDAC table functions
- */
-
-/*
- * Fill Power to PCDAC table on RF5111
- *
- * No further processing is needed for RF5111, the only thing we have to
- * do is fill the values below and above calibration range since eeprom data
- * may not cover the entire PCDAC table.
- */
-static void
-ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
-                                                       s16 *table_max)
-{
-       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
-       u8      *pcdac_tmp = ah->ah_txpower.tmpL[0];
-       u8      pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
-       s16     min_pwr, max_pwr;
-
-       /* Get table boundaries */
-       min_pwr = table_min[0];
-       pcdac_0 = pcdac_tmp[0];
-
-       max_pwr = table_max[0];
-       pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
-
-       /* Extrapolate below minimum using pcdac_0 */
-       pcdac_i = 0;
-       for (i = 0; i < min_pwr; i++)
-               pcdac_out[pcdac_i++] = pcdac_0;
-
-       /* Copy values from pcdac_tmp */
-       pwr_idx = min_pwr;
-       for (i = 0 ; pwr_idx <= max_pwr &&
-       pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
-               pcdac_out[pcdac_i++] = pcdac_tmp[i];
-               pwr_idx++;
-       }
-
-       /* Extrapolate above maximum */
-       while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
-               pcdac_out[pcdac_i++] = pcdac_n;
-
-}
-
-/*
- * Combine available XPD Curves and fill Linear Power to PCDAC table
- * on RF5112
- *
- * RFX112 can have up to 2 curves (one for low txpower range and one for
- * higher txpower range). We need to put them both on pcdac_out and place
- * them in the correct location. In case we only have one curve available
- * just fit it on pcdac_out (it's supposed to cover the entire range of
- * available pwr levels since it's always the higher power curve). Extrapolate
- * below and above final table if needed.
- */
-static void
-ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
-                                               s16 *table_max, u8 pdcurves)
-{
-       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
-       u8      *pcdac_low_pwr;
-       u8      *pcdac_high_pwr;
-       u8      *pcdac_tmp;
-       u8      pwr;
-       s16     max_pwr_idx;
-       s16     min_pwr_idx;
-       s16     mid_pwr_idx = 0;
-       /* Edge flag turs on the 7nth bit on the PCDAC
-        * to delcare the higher power curve (force values
-        * to be greater than 64). If we only have one curve
-        * we don't need to set this, if we have 2 curves and
-        * fill the table backwards this can also be used to
-        * switch from higher power curve to lower power curve */
-       u8      edge_flag;
-       int     i;
-
-       /* When we have only one curve available
-        * that's the higher power curve. If we have
-        * two curves the first is the high power curve
-        * and the next is the low power curve. */
-       if (pdcurves > 1) {
-               pcdac_low_pwr = ah->ah_txpower.tmpL[1];
-               pcdac_high_pwr = ah->ah_txpower.tmpL[0];
-               mid_pwr_idx = table_max[1] - table_min[1] - 1;
-               max_pwr_idx = (table_max[0] - table_min[0]) / 2;
-
-               /* If table size goes beyond 31.5dB, keep the
-                * upper 31.5dB range when setting tx power.
-                * Note: 126 = 31.5 dB in quarter dB steps */
-               if (table_max[0] - table_min[1] > 126)
-                       min_pwr_idx = table_max[0] - 126;
-               else
-                       min_pwr_idx = table_min[1];
-
-               /* Since we fill table backwards
-                * start from high power curve */
-               pcdac_tmp = pcdac_high_pwr;
-
-               edge_flag = 0x40;
-#if 0
-               /* If both min and max power limits are in lower
-                * power curve's range, only use the low power curve.
-                * TODO: min/max levels are related to target
-                * power values requested from driver/user
-                * XXX: Is this really needed ? */
-               if (min_pwr < table_max[1] &&
-               max_pwr < table_max[1]) {
-                       edge_flag = 0;
-                       pcdac_tmp = pcdac_low_pwr;
-                       max_pwr_idx = (table_max[1] - table_min[1])/2;
-               }
-#endif
-       } else {
-               pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
-               pcdac_high_pwr = ah->ah_txpower.tmpL[0];
-               min_pwr_idx = table_min[0];
-               max_pwr_idx = (table_max[0] - table_min[0]) / 2;
-               pcdac_tmp = pcdac_high_pwr;
-               edge_flag = 0;
-       }
-
-       /* This is used when setting tx power*/
-       ah->ah_txpower.txp_min_idx = min_pwr_idx/2;
-
-       /* Fill Power to PCDAC table backwards */
-       pwr = max_pwr_idx;
-       for (i = 63; i >= 0; i--) {
-               /* Entering lower power range, reset
-                * edge flag and set pcdac_tmp to lower
-                * power curve.*/
-               if (edge_flag == 0x40 &&
-               (2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
-                       edge_flag = 0x00;
-                       pcdac_tmp = pcdac_low_pwr;
-                       pwr = mid_pwr_idx/2;
-               }
-
-               /* Don't go below 1, extrapolate below if we have
-                * already swithced to the lower power curve -or
-                * we only have one curve and edge_flag is zero
-                * anyway */
-               if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
-                       while (i >= 0) {
-                               pcdac_out[i] = pcdac_out[i + 1];
-                               i--;
-                       }
-                       break;
-               }
-
-               pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
-
-               /* Extrapolate above if pcdac is greater than
-                * 126 -this can happen because we OR pcdac_out
-                * value with edge_flag on high power curve */
-               if (pcdac_out[i] > 126)
-                       pcdac_out[i] = 126;
-
-               /* Decrease by a 0.5dB step */
-               pwr--;
-       }
-}
-
-/* Write PCDAC values on hw */
-static void
-ath5k_setup_pcdac_table(struct ath5k_hw *ah)
-{
-       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
-       int     i;
-
-       /*
-        * Write TX power values
-        */
-       for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
-               ath5k_hw_reg_write(ah,
-                       (((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) |
-                       (((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16),
-                       AR5K_PHY_PCDAC_TXPOWER(i));
-       }
-}
-
-
-/*
- * Power to PDADC table functions
- */
-
-/*
- * Set the gain boundaries and create final Power to PDADC table
- *
- * We can have up to 4 pd curves, we need to do a simmilar process
- * as we do for RF5112. This time we don't have an edge_flag but we
- * set the gain boundaries on a separate register.
- */
-static void
-ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
-                       s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
-{
-       u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
-       u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
-       u8 *pdadc_tmp;
-       s16 pdadc_0;
-       u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
-       u8 pd_gain_overlap;
-
-       /* Note: Register value is initialized on initvals
-        * there is no feedback from hw.
-        * XXX: What about pd_gain_overlap from EEPROM ? */
-       pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
-               AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
-
-       /* Create final PDADC table */
-       for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
-               pdadc_tmp = ah->ah_txpower.tmpL[pdg];
-
-               if (pdg == pdcurves - 1)
-                       /* 2 dB boundary stretch for last
-                        * (higher power) curve */
-                       gain_boundaries[pdg] = pwr_max[pdg] + 4;
-               else
-                       /* Set gain boundary in the middle
-                        * between this curve and the next one */
-                       gain_boundaries[pdg] =
-                               (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
-
-               /* Sanity check in case our 2 db stretch got out of
-                * range. */
-               if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
-                       gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
-
-               /* For the first curve (lower power)
-                * start from 0 dB */
-               if (pdg == 0)
-                       pdadc_0 = 0;
-               else
-                       /* For the other curves use the gain overlap */
-                       pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
-                                                       pd_gain_overlap;
-
-               /* Force each power step to be at least 0.5 dB */
-               if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
-                       pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
-               else
-                       pwr_step = 1;
-
-               /* If pdadc_0 is negative, we need to extrapolate
-                * below this pdgain by a number of pwr_steps */
-               while ((pdadc_0 < 0) && (pdadc_i < 128)) {
-                       s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
-                       pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
-                       pdadc_0++;
-               }
-
-               /* Set last pwr level, using gain boundaries */
-               pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
-               /* Limit it to be inside pwr range */
-               table_size = pwr_max[pdg] - pwr_min[pdg];
-               max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
-
-               /* Fill pdadc_out table */
-               while (pdadc_0 < max_idx)
-                       pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
-
-               /* Need to extrapolate above this pdgain? */
-               if (pdadc_n <= max_idx)
-                       continue;
-
-               /* Force each power step to be at least 0.5 dB */
-               if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
-                       pwr_step = pdadc_tmp[table_size - 1] -
-                                               pdadc_tmp[table_size - 2];
-               else
-                       pwr_step = 1;
-
-               /* Extrapolate above */
-               while ((pdadc_0 < (s16) pdadc_n) &&
-               (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
-                       s16 tmp = pdadc_tmp[table_size - 1] +
-                                       (pdadc_0 - max_idx) * pwr_step;
-                       pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
-                       pdadc_0++;
-               }
-       }
-
-       while (pdg < AR5K_EEPROM_N_PD_GAINS) {
-               gain_boundaries[pdg] = gain_boundaries[pdg - 1];
-               pdg++;
-       }
-
-       while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
-               pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
-               pdadc_i++;
-       }
-
-       /* Set gain boundaries */
-       ath5k_hw_reg_write(ah,
-               AR5K_REG_SM(pd_gain_overlap,
-                       AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
-               AR5K_REG_SM(gain_boundaries[0],
-                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
-               AR5K_REG_SM(gain_boundaries[1],
-                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
-               AR5K_REG_SM(gain_boundaries[2],
-                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
-               AR5K_REG_SM(gain_boundaries[3],
-                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
-               AR5K_PHY_TPC_RG5);
-
-       /* Used for setting rate power table */
-       ah->ah_txpower.txp_min_idx = pwr_min[0];
-
-}
-
-/* Write PDADC values on hw */
-static void
-ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah,
-                       u8 pdcurves, u8 *pdg_to_idx)
-{
-       u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
-       u32 reg;
-       u8 i;
-
-       /* Select the right pdgain curves */
-
-       /* Clear current settings */
-       reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
-       reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
-               AR5K_PHY_TPC_RG1_PDGAIN_2 |
-               AR5K_PHY_TPC_RG1_PDGAIN_3 |
-               AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
-
-       /*
-        * Use pd_gains curve from eeprom
-        *
-        * This overrides the default setting from initvals
-        * in case some vendors (e.g. Zcomax) don't use the default
-        * curves. If we don't honor their settings we 'll get a
-        * 5dB (1 * gain overlap ?) drop.
-        */
-       reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
-
-       switch (pdcurves) {
-       case 3:
-               reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
-               /* Fall through */
-       case 2:
-               reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
-               /* Fall through */
-       case 1:
-               reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
-               break;
-       }
-       ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
-
-       /*
-        * Write TX power values
-        */
-       for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
-               ath5k_hw_reg_write(ah,
-                       ((pdadc_out[4*i + 0] & 0xff) << 0) |
-                       ((pdadc_out[4*i + 1] & 0xff) << 8) |
-                       ((pdadc_out[4*i + 2] & 0xff) << 16) |
-                       ((pdadc_out[4*i + 3] & 0xff) << 24),
-                       AR5K_PHY_PDADC_TXPOWER(i));
-       }
-}
-
-
-/*
- * Common code for PCDAC/PDADC tables
- */
-
-/*
- * This is the main function that uses all of the above
- * to set PCDAC/PDADC table on hw for the current channel.
- * This table is used for tx power calibration on the basband,
- * without it we get weird tx power levels and in some cases
- * distorted spectral mask
- */
-static int
-ath5k_setup_channel_powertable(struct ath5k_hw *ah,
-                       struct ieee80211_channel *channel,
-                       u8 ee_mode, u8 type)
-{
-       struct ath5k_pdgain_info *pdg_L, *pdg_R;
-       struct ath5k_chan_pcal_info *pcinfo_L;
-       struct ath5k_chan_pcal_info *pcinfo_R;
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
-       s16 table_min[AR5K_EEPROM_N_PD_GAINS];
-       s16 table_max[AR5K_EEPROM_N_PD_GAINS];
-       u8 *tmpL;
-       u8 *tmpR;
-       u32 target = channel->center_freq;
-       int pdg, i;
-
-       /* Get surounding freq piers for this channel */
-       ath5k_get_chan_pcal_surrounding_piers(ah, channel,
-                                               &pcinfo_L,
-                                               &pcinfo_R);
-
-       /* Loop over pd gain curves on
-        * surounding freq piers by index */
-       for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
-
-               /* Fill curves in reverse order
-                * from lower power (max gain)
-                * to higher power. Use curve -> idx
-                * backmaping we did on eeprom init */
-               u8 idx = pdg_curve_to_idx[pdg];
-
-               /* Grab the needed curves by index */
-               pdg_L = &pcinfo_L->pd_curves[idx];
-               pdg_R = &pcinfo_R->pd_curves[idx];
-
-               /* Initialize the temp tables */
-               tmpL = ah->ah_txpower.tmpL[pdg];
-               tmpR = ah->ah_txpower.tmpR[pdg];
-
-               /* Set curve's x boundaries and create
-                * curves so that they cover the same
-                * range (if we don't do that one table
-                * will have values on some range and the
-                * other one won't have any so interpolation
-                * will fail) */
-               table_min[pdg] = min(pdg_L->pd_pwr[0],
-                                       pdg_R->pd_pwr[0]) / 2;
-
-               table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
-                               pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
-
-               /* Now create the curves on surrounding channels
-                * and interpolate if needed to get the final
-                * curve for this gain on this channel */
-               switch (type) {
-               case AR5K_PWRTABLE_LINEAR_PCDAC:
-                       /* Override min/max so that we don't loose
-                        * accuracy (don't divide by 2) */
-                       table_min[pdg] = min(pdg_L->pd_pwr[0],
-                                               pdg_R->pd_pwr[0]);
-
-                       table_max[pdg] =
-                               max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
-                                       pdg_R->pd_pwr[pdg_R->pd_points - 1]);
-
-                       /* Override minimum so that we don't get
-                        * out of bounds while extrapolating
-                        * below. Don't do this when we have 2
-                        * curves and we are on the high power curve
-                        * because table_min is ok in this case */
-                       if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
-
-                               table_min[pdg] =
-                                       ath5k_get_linear_pcdac_min(pdg_L->pd_step,
-                                                               pdg_R->pd_step,
-                                                               pdg_L->pd_pwr,
-                                                               pdg_R->pd_pwr);
-
-                               /* Don't go too low because we will
-                                * miss the upper part of the curve.
-                                * Note: 126 = 31.5dB (max power supported)
-                                * in 0.25dB units */
-                               if (table_max[pdg] - table_min[pdg] > 126)
-                                       table_min[pdg] = table_max[pdg] - 126;
-                       }
-
-                       /* Fall through */
-               case AR5K_PWRTABLE_PWR_TO_PCDAC:
-               case AR5K_PWRTABLE_PWR_TO_PDADC:
-
-                       ath5k_create_power_curve(table_min[pdg],
-                                               table_max[pdg],
-                                               pdg_L->pd_pwr,
-                                               pdg_L->pd_step,
-                                               pdg_L->pd_points, tmpL, type);
-
-                       /* We are in a calibration
-                        * pier, no need to interpolate
-                        * between freq piers */
-                       if (pcinfo_L == pcinfo_R)
-                               continue;
-
-                       ath5k_create_power_curve(table_min[pdg],
-                                               table_max[pdg],
-                                               pdg_R->pd_pwr,
-                                               pdg_R->pd_step,
-                                               pdg_R->pd_points, tmpR, type);
-                       break;
-               default:
-                       return -EINVAL;
-               }
-
-               /* Interpolate between curves
-                * of surounding freq piers to
-                * get the final curve for this
-                * pd gain. Re-use tmpL for interpolation
-                * output */
-               for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
-               (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
-                       tmpL[i] = (u8) ath5k_get_interpolated_value(target,
-                                                       (s16) pcinfo_L->freq,
-                                                       (s16) pcinfo_R->freq,
-                                                       (s16) tmpL[i],
-                                                       (s16) tmpR[i]);
-               }
-       }
-
-       /* Now we have a set of curves for this
-        * channel on tmpL (x range is table_max - table_min
-        * and y values are tmpL[pdg][]) sorted in the same
-        * order as EEPROM (because we've used the backmaping).
-        * So for RF5112 it's from higher power to lower power
-        * and for RF2413 it's from lower power to higher power.
-        * For RF5111 we only have one curve. */
-
-       /* Fill min and max power levels for this
-        * channel by interpolating the values on
-        * surounding channels to complete the dataset */
-       ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
-                                       (s16) pcinfo_L->freq,
-                                       (s16) pcinfo_R->freq,
-                                       pcinfo_L->min_pwr, pcinfo_R->min_pwr);
-
-       ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
-                                       (s16) pcinfo_L->freq,
-                                       (s16) pcinfo_R->freq,
-                                       pcinfo_L->max_pwr, pcinfo_R->max_pwr);
-
-       /* We are ready to go, fill PCDAC/PDADC
-        * table and write settings on hardware */
-       switch (type) {
-       case AR5K_PWRTABLE_LINEAR_PCDAC:
-               /* For RF5112 we can have one or two curves
-                * and each curve covers a certain power lvl
-                * range so we need to do some more processing */
-               ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
-                                               ee->ee_pd_gains[ee_mode]);
-
-               /* Set txp.offset so that we can
-                * match max power value with max
-                * table index */
-               ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
-
-               /* Write settings on hw */
-               ath5k_setup_pcdac_table(ah);
-               break;
-       case AR5K_PWRTABLE_PWR_TO_PCDAC:
-               /* We are done for RF5111 since it has only
-                * one curve, just fit the curve on the table */
-               ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
-
-               /* No rate powertable adjustment for RF5111 */
-               ah->ah_txpower.txp_min_idx = 0;
-               ah->ah_txpower.txp_offset = 0;
-
-               /* Write settings on hw */
-               ath5k_setup_pcdac_table(ah);
-               break;
-       case AR5K_PWRTABLE_PWR_TO_PDADC:
-               /* Set PDADC boundaries and fill
-                * final PDADC table */
-               ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
-                                               ee->ee_pd_gains[ee_mode]);
-
-               /* Write settings on hw */
-               ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
-
-               /* Set txp.offset, note that table_min
-                * can be negative */
-               ah->ah_txpower.txp_offset = table_min[0];
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-
-/*
- * Per-rate tx power setting
- *
- * This is the code that sets the desired tx power (below
- * maximum) on hw for each rate (we also have TPC that sets
- * power per packet). We do that by providing an index on the
- * PCDAC/PDADC table we set up.
- */
-
-/*
- * Set rate power table
- *
- * For now we only limit txpower based on maximum tx power
- * supported by hw (what's inside rate_info). We need to limit
- * this even more, based on regulatory domain etc.
- *
- * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps)
- * and is indexed as follows:
- * rates[0] - rates[7] -> OFDM rates
- * rates[8] - rates[14] -> CCK rates
- * rates[15] -> XR rates (they all have the same power)
- */
-static void
-ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
-                       struct ath5k_rate_pcal_info *rate_info,
-                       u8 ee_mode)
-{
-       unsigned int i;
-       u16 *rates;
-
-       /* max_pwr is power level we got from driver/user in 0.5dB
-        * units, switch to 0.25dB units so we can compare */
-       max_pwr *= 2;
-       max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
-
-       /* apply rate limits */
-       rates = ah->ah_txpower.txp_rates_power_table;
-
-       /* OFDM rates 6 to 24Mb/s */
-       for (i = 0; i < 5; i++)
-               rates[i] = min(max_pwr, rate_info->target_power_6to24);
-
-       /* Rest OFDM rates */
-       rates[5] = min(rates[0], rate_info->target_power_36);
-       rates[6] = min(rates[0], rate_info->target_power_48);
-       rates[7] = min(rates[0], rate_info->target_power_54);
-
-       /* CCK rates */
-       /* 1L */
-       rates[8] = min(rates[0], rate_info->target_power_6to24);
-       /* 2L */
-       rates[9] = min(rates[0], rate_info->target_power_36);
-       /* 2S */
-       rates[10] = min(rates[0], rate_info->target_power_36);
-       /* 5L */
-       rates[11] = min(rates[0], rate_info->target_power_48);
-       /* 5S */
-       rates[12] = min(rates[0], rate_info->target_power_48);
-       /* 11L */
-       rates[13] = min(rates[0], rate_info->target_power_54);
-       /* 11S */
-       rates[14] = min(rates[0], rate_info->target_power_54);
-
-       /* XR rates */
-       rates[15] = min(rates[0], rate_info->target_power_6to24);
-
-       /* CCK rates have different peak to average ratio
-        * so we have to tweak their power so that gainf
-        * correction works ok. For this we use OFDM to
-        * CCK delta from eeprom */
-       if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
-       (ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
-               for (i = 8; i <= 15; i++)
-                       rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
-
-       ah->ah_txpower.txp_min_pwr = rates[7];
-       ah->ah_txpower.txp_max_pwr = rates[0];
-       ah->ah_txpower.txp_ofdm = rates[7];
-}
-
-
-/*
- * Set transmition power
- */
-int
-ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
-               u8 ee_mode, u8 txpower)
-{
-       struct ath5k_rate_pcal_info rate_info;
-       u8 type;
-       int ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-       if (txpower > AR5K_TUNE_MAX_TXPOWER) {
-               ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
-               return -EINVAL;
-       }
-       if (txpower == 0)
-               txpower = AR5K_TUNE_DEFAULT_TXPOWER;
-
-       /* Reset TX power values */
-       memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
-       ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
-       ah->ah_txpower.txp_min_pwr = 0;
-       ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
-
-       /* Initialize TX power table */
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               type = AR5K_PWRTABLE_PWR_TO_PCDAC;
-               break;
-       case AR5K_RF5112:
-               type = AR5K_PWRTABLE_LINEAR_PCDAC;
-               break;
-       case AR5K_RF2413:
-       case AR5K_RF5413:
-       case AR5K_RF2316:
-       case AR5K_RF2317:
-       case AR5K_RF2425:
-               type = AR5K_PWRTABLE_PWR_TO_PDADC;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* FIXME: Only on channel/mode change */
-       ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
-       if (ret)
-               return ret;
-
-       /* Limit max power if we have a CTL available */
-       ath5k_get_max_ctl_power(ah, channel);
-
-       /* FIXME: Tx power limit for this regdomain
-        * XXX: Mac80211/CRDA will do that anyway ? */
-
-       /* FIXME: Antenna reduction stuff */
-
-       /* FIXME: Limit power on turbo modes */
-
-       /* FIXME: TPC scale reduction */
-
-       /* Get surounding channels for per-rate power table
-        * calibration */
-       ath5k_get_rate_pcal_data(ah, channel, &rate_info);
-
-       /* Setup rate power table */
-       ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
-
-       /* Write rate power table on hw */
-       ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
-               AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
-               AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
-
-       ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(7, 24) |
-               AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) |
-               AR5K_TXPOWER_OFDM(4, 0), AR5K_PHY_TXPOWER_RATE2);
-
-       ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(10, 24) |
-               AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) |
-               AR5K_TXPOWER_CCK(8, 0), AR5K_PHY_TXPOWER_RATE3);
-
-       ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(14, 24) |
-               AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
-               AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
-
-       /* FIXME: TPC support */
-       if (ah->ah_txpower.txp_tpc) {
-               ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
-                       AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
-
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
-                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
-                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
-                       AR5K_TPC);
-       } else {
-               ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
-                       AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
-       }
-
-       return 0;
-}
-
-int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower)
-{
-       /*Just a try M.F.*/
-       struct ieee80211_channel *channel = &ah->ah_current_channel;
-
-       ATH5K_TRACE(ah->ah_sc);
-       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
-               "changing txpower to %d\n", txpower);
-
-       return ath5k_hw_txpower(ah, channel, mode, txpower);
-}
-
-#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c
deleted file mode 100644 (file)
index 5094c39..0000000
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/********************************************\
-Queue Control Unit, DFS Control Unit Functions
-\********************************************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Get properties for a transmit queue
- */
-int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
-               struct ath5k_txq_info *queue_info)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
-       return 0;
-}
-
-/*
- * Set properties for a transmit queue
- */
-int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
-                               const struct ath5k_txq_info *queue_info)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return -EIO;
-
-       memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
-
-       /*XXX: Is this supported on 5210 ?*/
-       if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
-                       ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
-                       (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
-                       queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
-               ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
-
-       return 0;
-}
-
-/*
- * Initialize a transmit queue
- */
-int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
-               struct ath5k_txq_info *queue_info)
-{
-       unsigned int queue;
-       int ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*
-        * Get queue by type
-        */
-       /*5210 only has 2 queues*/
-       if (ah->ah_version == AR5K_AR5210) {
-               switch (queue_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-               case AR5K_TX_QUEUE_CAB:
-                       queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       } else {
-               switch (queue_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
-                               ah->ah_txq[queue].tqi_type !=
-                               AR5K_TX_QUEUE_INACTIVE; queue++) {
-
-                               if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
-                                       return -EINVAL;
-                       }
-                       break;
-               case AR5K_TX_QUEUE_UAPSD:
-                       queue = AR5K_TX_QUEUE_ID_UAPSD;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-                       queue = AR5K_TX_QUEUE_ID_BEACON;
-                       break;
-               case AR5K_TX_QUEUE_CAB:
-                       queue = AR5K_TX_QUEUE_ID_CAB;
-                       break;
-               case AR5K_TX_QUEUE_XR_DATA:
-                       if (ah->ah_version != AR5K_AR5212)
-                               ATH5K_ERR(ah->ah_sc,
-                                       "XR data queues only supported in"
-                                       " 5212!\n");
-                       queue = AR5K_TX_QUEUE_ID_XR_DATA;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
-
-       /*
-        * Setup internal queue structure
-        */
-       memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
-       ah->ah_txq[queue].tqi_type = queue_type;
-
-       if (queue_info != NULL) {
-               queue_info->tqi_type = queue_type;
-               ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
-               if (ret)
-                       return ret;
-       }
-
-       /*
-        * We use ah_txq_status to hold a temp value for
-        * the Secondary interrupt mask registers on 5211+
-        * check out ath5k_hw_reset_tx_queue
-        */
-       AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
-
-       return queue;
-}
-
-/*
- * Get number of pending frames
- * for a specific queue [5211+]
- */
-u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
-{
-       u32 pending;
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /* Return if queue is declared inactive */
-       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return false;
-
-       /* XXX: How about AR5K_CFG_TXCNT ? */
-       if (ah->ah_version == AR5K_AR5210)
-               return false;
-
-       pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT);
-
-       /* It's possible to have no frames pending even if TXE
-        * is set. To indicate that q has not stopped return
-        * true */
-       if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
-               return true;
-
-       return pending;
-}
-
-/*
- * Set a transmit queue inactive
- */
-void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
-               return;
-
-       /* This queue will be skipped in further operations */
-       ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
-       /*For SIMR setup*/
-       AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
-}
-
-/*
- * Set DFS properties for a transmit queue on DCU
- */
-int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
-{
-       u32 cw_min, cw_max, retry_lg, retry_sh;
-       struct ath5k_txq_info *tq = &ah->ah_txq[queue];
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       tq = &ah->ah_txq[queue];
-
-       if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return 0;
-
-       if (ah->ah_version == AR5K_AR5210) {
-               /* Only handle data queues, others will be ignored */
-               if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
-                       return 0;
-
-               /* Set Slot time */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
-                       AR5K_SLOT_TIME);
-               /* Set ACK_CTS timeout */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
-                       AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
-               /* Set Transmit Latency */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       AR5K_INIT_TRANSMIT_LATENCY_TURBO :
-                       AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
-
-               /* Set IFS0 */
-               if (ah->ah_turbo) {
-                        ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
-                               (ah->ah_aifs + tq->tqi_aifs) *
-                               AR5K_INIT_SLOT_TIME_TURBO) <<
-                               AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
-                               AR5K_IFS0);
-               } else {
-                       ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
-                               (ah->ah_aifs + tq->tqi_aifs) *
-                               AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
-                               AR5K_INIT_SIFS, AR5K_IFS0);
-               }
-
-               /* Set IFS1 */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
-                       AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
-               /* Set AR5K_PHY_SETTLING */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
-                       | 0x38 :
-                       (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
-                       | 0x1C,
-                       AR5K_PHY_SETTLING);
-               /* Set Frame Control Register */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
-                       AR5K_PHY_TURBO_SHORT | 0x2020) :
-                       (AR5K_PHY_FRAME_CTL_INI | 0x1020),
-                       AR5K_PHY_FRAME_CTL_5210);
-       }
-
-       /*
-        * Calculate cwmin/max by channel mode
-        */
-       cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
-       cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
-       ah->ah_aifs = AR5K_TUNE_AIFS;
-       /*XR is only supported on 5212*/
-       if (IS_CHAN_XR(ah->ah_current_channel) &&
-                       ah->ah_version == AR5K_AR5212) {
-               cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
-               cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
-               ah->ah_aifs = AR5K_TUNE_AIFS_XR;
-       /*B mode is not supported on 5210*/
-       } else if (IS_CHAN_B(ah->ah_current_channel) &&
-                       ah->ah_version != AR5K_AR5210) {
-               cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
-               cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
-               ah->ah_aifs = AR5K_TUNE_AIFS_11B;
-       }
-
-       cw_min = 1;
-       while (cw_min < ah->ah_cw_min)
-               cw_min = (cw_min << 1) | 1;
-
-       cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
-               ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
-       cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
-               ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
-
-       /*
-        * Calculate and set retry limits
-        */
-       if (ah->ah_software_retry) {
-               /* XXX Need to test this */
-               retry_lg = ah->ah_limit_tx_retries;
-               retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
-                       AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
-       } else {
-               retry_lg = AR5K_INIT_LG_RETRY;
-               retry_sh = AR5K_INIT_SH_RETRY;
-       }
-
-       /*No QCU/DCU [5210]*/
-       if (ah->ah_version == AR5K_AR5210) {
-               ath5k_hw_reg_write(ah,
-                       (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
-                       | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
-                               AR5K_NODCU_RETRY_LMT_SLG_RETRY)
-                       | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
-                               AR5K_NODCU_RETRY_LMT_SSH_RETRY)
-                       | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
-                       | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
-                       AR5K_NODCU_RETRY_LMT);
-       } else {
-               /*QCU/DCU [5211+]*/
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
-                               AR5K_DCU_RETRY_LMT_SLG_RETRY) |
-                       AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
-                               AR5K_DCU_RETRY_LMT_SSH_RETRY) |
-                       AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
-                       AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
-                       AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
-
-       /*===Rest is also for QCU/DCU only [5211+]===*/
-
-               /*
-                * Set initial content window (cw_min/cw_max)
-                * and arbitrated interframe space (aifs)...
-                */
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
-                       AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
-                       AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
-                               AR5K_DCU_LCL_IFS_AIFS),
-                       AR5K_QUEUE_DFS_LOCAL_IFS(queue));
-
-               /*
-                * Set misc registers
-                */
-               /* Enable DCU early termination for this queue */
-               AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                                       AR5K_QCU_MISC_DCU_EARLY);
-
-               /* Enable DCU to wait for next fragment from QCU */
-               AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
-                                       AR5K_DCU_MISC_FRAG_WAIT);
-
-               /* On Maui and Spirit use the global seqnum on DCU */
-               if (ah->ah_mac_version < AR5K_SREV_AR5211)
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
-                                               AR5K_DCU_MISC_SEQNUM_CTL);
-
-               if (tq->tqi_cbr_period) {
-                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
-                               AR5K_QCU_CBRCFG_INTVAL) |
-                               AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
-                               AR5K_QCU_CBRCFG_ORN_THRES),
-                               AR5K_QUEUE_CBRCFG(queue));
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_FRSHED_CBR);
-                       if (tq->tqi_cbr_overflow_limit)
-                               AR5K_REG_ENABLE_BITS(ah,
-                                       AR5K_QUEUE_MISC(queue),
-                                       AR5K_QCU_MISC_CBR_THRES_ENABLE);
-               }
-
-               if (tq->tqi_ready_time &&
-               (tq->tqi_type != AR5K_TX_QUEUE_ID_CAB))
-                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
-                               AR5K_QCU_RDYTIMECFG_INTVAL) |
-                               AR5K_QCU_RDYTIMECFG_ENABLE,
-                               AR5K_QUEUE_RDYTIMECFG(queue));
-
-               if (tq->tqi_burst_time) {
-                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
-                               AR5K_DCU_CHAN_TIME_DUR) |
-                               AR5K_DCU_CHAN_TIME_ENABLE,
-                               AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
-
-                       if (tq->tqi_flags
-                       & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
-                               AR5K_REG_ENABLE_BITS(ah,
-                                       AR5K_QUEUE_MISC(queue),
-                                       AR5K_QCU_MISC_RDY_VEOL_POLICY);
-               }
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
-                       ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
-                               AR5K_QUEUE_DFS_MISC(queue));
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
-                       ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
-                               AR5K_QUEUE_DFS_MISC(queue));
-
-               /*
-                * Set registers by queue type
-                */
-               switch (tq->tqi_type) {
-               case AR5K_TX_QUEUE_BEACON:
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_FRSHED_DBA_GT |
-                               AR5K_QCU_MISC_CBREXP_BCN_DIS |
-                               AR5K_QCU_MISC_BCN_ENABLE);
-
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
-                               (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
-                               AR5K_DCU_MISC_ARBLOCK_CTL_S) |
-                               AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
-                               AR5K_DCU_MISC_BCN_ENABLE);
-                       break;
-
-               case AR5K_TX_QUEUE_CAB:
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_FRSHED_DBA_GT |
-                               AR5K_QCU_MISC_CBREXP_DIS |
-                               AR5K_QCU_MISC_CBREXP_BCN_DIS);
-
-                       ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
-                               (AR5K_TUNE_SW_BEACON_RESP -
-                               AR5K_TUNE_DMA_BEACON_RESP) -
-                               AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
-                               AR5K_QCU_RDYTIMECFG_ENABLE,
-                               AR5K_QUEUE_RDYTIMECFG(queue));
-
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
-                               (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
-                               AR5K_DCU_MISC_ARBLOCK_CTL_S));
-                       break;
-
-               case AR5K_TX_QUEUE_UAPSD:
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_CBREXP_DIS);
-                       break;
-
-               case AR5K_TX_QUEUE_DATA:
-               default:
-                       break;
-               }
-
-               /* TODO: Handle frame compression */
-
-               /*
-                * Enable interrupts for this tx queue
-                * in the secondary interrupt mask registers
-                */
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
-
-               /* Update secondary interrupt mask registers */
-
-               /* Filter out inactive queues */
-               ah->ah_txq_imr_txok &= ah->ah_txq_status;
-               ah->ah_txq_imr_txerr &= ah->ah_txq_status;
-               ah->ah_txq_imr_txurn &= ah->ah_txq_status;
-               ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
-               ah->ah_txq_imr_txeol &= ah->ah_txq_status;
-               ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
-               ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
-               ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
-               ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
-
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
-                       AR5K_SIMR0_QCU_TXOK) |
-                       AR5K_REG_SM(ah->ah_txq_imr_txdesc,
-                       AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
-                       AR5K_SIMR1_QCU_TXERR) |
-                       AR5K_REG_SM(ah->ah_txq_imr_txeol,
-                       AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
-               /* Update simr2 but don't overwrite rest simr2 settings */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
-               AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
-                       AR5K_REG_SM(ah->ah_txq_imr_txurn,
-                       AR5K_SIMR2_QCU_TXURN));
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
-                       AR5K_SIMR3_QCBRORN) |
-                       AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
-                       AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
-                       AR5K_SIMR4_QTRIG), AR5K_SIMR4);
-               /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
-                       AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
-               /* No queue has TXNOFRM enabled, disable the interrupt
-                * by setting AR5K_TXNOFRM to zero */
-               if (ah->ah_txq_imr_nofrm == 0)
-                       ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
-
-               /* Set QCU mask for this DCU to save power */
-               AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
-       }
-
-       return 0;
-}
-
-/*
- * Get slot time from DCU
- */
-unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (ah->ah_version == AR5K_AR5210)
-               return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
-                               AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
-       else
-               return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
-}
-
-/*
- * Set slot time on DCU
- */
-int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
-               return -EINVAL;
-
-       if (ah->ah_version == AR5K_AR5210)
-               ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
-                               ah->ah_turbo), AR5K_SLOT_TIME);
-       else
-               ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
-
-       return 0;
-}
-
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
deleted file mode 100644 (file)
index 7070d15..0000000
+++ /dev/null
@@ -1,2589 +0,0 @@
-/*
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*
- * Register values for Atheros 5210/5211/5212 cards from OpenBSD's ar5k
- * maintained by Reyk Floeter
- *
- * I tried to document those registers by looking at ar5k code, some
- * 802.11 (802.11e mostly) papers and by reading various public available
- * Atheros presentations and papers like these:
- *
- * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf
- *        http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf
- *
- * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf
- *
- * This file also contains register values found on a memory dump of
- * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal
- * released by Atheros and on various debug messages found on the net.
- */
-
-
-
-/*====MAC DMA REGISTERS====*/
-
-/*
- * AR5210-Specific TXDP registers
- * 5210 has only 2 transmit queues so no DCU/QCU, just
- * 2 transmit descriptor pointers...
- */
-#define AR5K_NOQCU_TXDP0       0x0000          /* Queue 0 - data */
-#define AR5K_NOQCU_TXDP1       0x0004          /* Queue 1 - beacons */
-
-/*
- * Mac Control Register
- */
-#define        AR5K_CR         0x0008                  /* Register Address */
-#define AR5K_CR_TXE0   0x00000001      /* TX Enable for queue 0 on 5210 */
-#define AR5K_CR_TXE1   0x00000002      /* TX Enable for queue 1 on 5210 */
-#define        AR5K_CR_RXE     0x00000004      /* RX Enable */
-#define AR5K_CR_TXD0   0x00000008      /* TX Disable for queue 0 on 5210 */
-#define AR5K_CR_TXD1   0x00000010      /* TX Disable for queue 1 on 5210 */
-#define        AR5K_CR_RXD     0x00000020      /* RX Disable */
-#define        AR5K_CR_SWI     0x00000040      /* Software Interrupt */
-
-/*
- * RX Descriptor Pointer register
- */
-#define        AR5K_RXDP       0x000c
-
-/*
- * Configuration and status register
- */
-#define        AR5K_CFG                0x0014                  /* Register Address */
-#define        AR5K_CFG_SWTD           0x00000001      /* Byte-swap TX descriptor (for big endian archs) */
-#define        AR5K_CFG_SWTB           0x00000002      /* Byte-swap TX buffer */
-#define        AR5K_CFG_SWRD           0x00000004      /* Byte-swap RX descriptor */
-#define        AR5K_CFG_SWRB           0x00000008      /* Byte-swap RX buffer */
-#define        AR5K_CFG_SWRG           0x00000010      /* Byte-swap Register access */
-#define AR5K_CFG_IBSS          0x00000020      /* 0-BSS, 1-IBSS [5211+] */
-#define AR5K_CFG_PHY_OK                0x00000100      /* [5211+] */
-#define AR5K_CFG_EEBS          0x00000200      /* EEPROM is busy */
-#define        AR5K_CFG_CLKGD          0x00000400      /* Clock gated (Disable dynamic clock) */
-#define AR5K_CFG_TXCNT         0x00007800      /* Tx frame count (?) [5210] */
-#define AR5K_CFG_TXCNT_S       11
-#define AR5K_CFG_TXFSTAT       0x00008000      /* Tx frame status (?) [5210] */
-#define AR5K_CFG_TXFSTRT       0x00010000      /* [5210] */
-#define        AR5K_CFG_PCI_THRES      0x00060000      /* PCI Master req q threshold [5211+] */
-#define        AR5K_CFG_PCI_THRES_S    17
-
-/*
- * Interrupt enable register
- */
-#define AR5K_IER               0x0024          /* Register Address */
-#define AR5K_IER_DISABLE       0x00000000      /* Disable card interrupts */
-#define AR5K_IER_ENABLE                0x00000001      /* Enable card interrupts */
-
-
-/*
- * 0x0028 is Beacon Control Register on 5210
- * and first RTS duration register on 5211
- */
-
-/*
- * Beacon control register [5210]
- */
-#define AR5K_BCR               0x0028          /* Register Address */
-#define AR5K_BCR_AP            0x00000000      /* AP mode */
-#define AR5K_BCR_ADHOC         0x00000001      /* Ad-Hoc mode */
-#define AR5K_BCR_BDMAE         0x00000002      /* DMA enable */
-#define AR5K_BCR_TQ1FV         0x00000004      /* Use Queue1 for CAB traffic */
-#define AR5K_BCR_TQ1V          0x00000008      /* Use Queue1 for Beacon traffic */
-#define AR5K_BCR_BCGET         0x00000010
-
-/*
- * First RTS duration register [5211]
- */
-#define AR5K_RTSD0             0x0028          /* Register Address */
-#define        AR5K_RTSD0_6            0x000000ff      /* 6Mb RTS duration mask (?) */
-#define        AR5K_RTSD0_6_S          0               /* 6Mb RTS duration shift (?) */
-#define        AR5K_RTSD0_9            0x0000ff00      /* 9Mb*/
-#define        AR5K_RTSD0_9_S          8
-#define        AR5K_RTSD0_12           0x00ff0000      /* 12Mb*/
-#define        AR5K_RTSD0_12_S         16
-#define        AR5K_RTSD0_18           0xff000000      /* 16Mb*/
-#define        AR5K_RTSD0_18_S         24
-
-
-/*
- * 0x002c is Beacon Status Register on 5210
- * and second RTS duration register on 5211
- */
-
-/*
- * Beacon status register [5210]
- *
- * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR
- * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning
- * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR).
- * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i
- * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what
- * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR.
- */
-#define AR5K_BSR               0x002c                  /* Register Address */
-#define AR5K_BSR_BDLYSW                0x00000001      /* SW Beacon delay (?) */
-#define AR5K_BSR_BDLYDMA       0x00000002      /* DMA Beacon delay (?) */
-#define AR5K_BSR_TXQ1F         0x00000004      /* Beacon queue (1) finished */
-#define AR5K_BSR_ATIMDLY       0x00000008      /* ATIM delay (?) */
-#define AR5K_BSR_SNPADHOC      0x00000100      /* Ad-hoc mode set (?) */
-#define AR5K_BSR_SNPBDMAE      0x00000200      /* Beacon DMA enabled (?) */
-#define AR5K_BSR_SNPTQ1FV      0x00000400      /* Queue1 is used for CAB traffic (?) */
-#define AR5K_BSR_SNPTQ1V       0x00000800      /* Queue1 is used for Beacon traffic (?) */
-#define AR5K_BSR_SNAPSHOTSVALID        0x00001000      /* BCR snapshots are valid (?) */
-#define AR5K_BSR_SWBA_CNT      0x00ff0000
-
-/*
- * Second RTS duration register [5211]
- */
-#define AR5K_RTSD1             0x002c                  /* Register Address */
-#define        AR5K_RTSD1_24           0x000000ff      /* 24Mb */
-#define        AR5K_RTSD1_24_S         0
-#define        AR5K_RTSD1_36           0x0000ff00      /* 36Mb */
-#define        AR5K_RTSD1_36_S         8
-#define        AR5K_RTSD1_48           0x00ff0000      /* 48Mb */
-#define        AR5K_RTSD1_48_S         16
-#define        AR5K_RTSD1_54           0xff000000      /* 54Mb */
-#define        AR5K_RTSD1_54_S         24
-
-
-/*
- * Transmit configuration register
- */
-#define AR5K_TXCFG                     0x0030                  /* Register Address */
-#define AR5K_TXCFG_SDMAMR              0x00000007      /* DMA size (read) */
-#define AR5K_TXCFG_SDMAMR_S            0
-#define AR5K_TXCFG_B_MODE              0x00000008      /* Set b mode for 5111 (enable 2111) */
-#define AR5K_TXCFG_TXFSTP              0x00000008      /* TX DMA full Stop [5210] */
-#define AR5K_TXCFG_TXFULL              0x000003f0      /* TX Triger level mask */
-#define AR5K_TXCFG_TXFULL_S            4
-#define AR5K_TXCFG_TXFULL_0B           0x00000000
-#define AR5K_TXCFG_TXFULL_64B          0x00000010
-#define AR5K_TXCFG_TXFULL_128B         0x00000020
-#define AR5K_TXCFG_TXFULL_192B         0x00000030
-#define AR5K_TXCFG_TXFULL_256B         0x00000040
-#define AR5K_TXCFG_TXCONT_EN           0x00000080
-#define AR5K_TXCFG_DMASIZE             0x00000100      /* Flag for passing DMA size [5210] */
-#define AR5K_TXCFG_JUMBO_DESC_EN       0x00000400      /* Enable jumbo tx descriptors [5211+] */
-#define AR5K_TXCFG_ADHOC_BCN_ATIM      0x00000800      /* Adhoc Beacon ATIM Policy */
-#define AR5K_TXCFG_ATIM_WINDOW_DEF_DIS 0x00001000      /* Disable ATIM window defer [5211+] */
-#define AR5K_TXCFG_RTSRND              0x00001000      /* [5211+] */
-#define AR5K_TXCFG_FRMPAD_DIS          0x00002000      /* [5211+] */
-#define AR5K_TXCFG_RDY_CBR_DIS         0x00004000      /* Ready time CBR disable [5211+] */
-#define AR5K_TXCFG_JUMBO_FRM_MODE      0x00008000      /* Jumbo frame mode [5211+] */
-#define        AR5K_TXCFG_DCU_DBL_BUF_DIS      0x00008000      /* Disable double buffering on DCU */
-#define AR5K_TXCFG_DCU_CACHING_DIS     0x00010000      /* Disable DCU caching */
-
-/*
- * Receive configuration register
- */
-#define AR5K_RXCFG             0x0034                  /* Register Address */
-#define AR5K_RXCFG_SDMAMW      0x00000007      /* DMA size (write) */
-#define AR5K_RXCFG_SDMAMW_S    0
-#define AR5K_RXCFG_ZLFDMA      0x00000008      /* Enable Zero-length frame DMA */
-#define        AR5K_RXCFG_DEF_ANTENNA  0x00000010      /* Default antenna (?) */
-#define AR5K_RXCFG_JUMBO_RXE   0x00000020      /* Enable jumbo rx descriptors [5211+] */
-#define AR5K_RXCFG_JUMBO_WRAP  0x00000040      /* Wrap jumbo frames [5211+] */
-#define AR5K_RXCFG_SLE_ENTRY   0x00000080      /* Sleep entry policy */
-
-/*
- * Receive jumbo descriptor last address register
- * Only found in 5211 (?)
- */
-#define AR5K_RXJLA             0x0038
-
-/*
- * MIB control register
- */
-#define AR5K_MIBC              0x0040                  /* Register Address */
-#define AR5K_MIBC_COW          0x00000001      /* Warn test indicator */
-#define AR5K_MIBC_FMC          0x00000002      /* Freeze MIB Counters  */
-#define AR5K_MIBC_CMC          0x00000004      /* Clean MIB Counters  */
-#define AR5K_MIBC_MCS          0x00000008      /* MIB counter strobe */
-
-/*
- * Timeout prescale register
- */
-#define AR5K_TOPS              0x0044
-#define        AR5K_TOPS_M             0x0000ffff
-
-/*
- * Receive timeout register (no frame received)
- */
-#define AR5K_RXNOFRM           0x0048
-#define        AR5K_RXNOFRM_M          0x000003ff
-
-/*
- * Transmit timeout register (no frame sent)
- */
-#define AR5K_TXNOFRM           0x004c
-#define        AR5K_TXNOFRM_M          0x000003ff
-#define        AR5K_TXNOFRM_QCU        0x000ffc00
-#define        AR5K_TXNOFRM_QCU_S      10
-
-/*
- * Receive frame gap timeout register
- */
-#define AR5K_RPGTO             0x0050
-#define AR5K_RPGTO_M           0x000003ff
-
-/*
- * Receive frame count limit register
- */
-#define AR5K_RFCNT             0x0054
-#define AR5K_RFCNT_M           0x0000001f      /* [5211+] (?) */
-#define AR5K_RFCNT_RFCL                0x0000000f      /* [5210] */
-
-/*
- * Misc settings register
- * (reserved0-3)
- */
-#define AR5K_MISC              0x0058                  /* Register Address */
-#define        AR5K_MISC_DMA_OBS_M     0x000001e0
-#define        AR5K_MISC_DMA_OBS_S     5
-#define        AR5K_MISC_MISC_OBS_M    0x00000e00
-#define        AR5K_MISC_MISC_OBS_S    9
-#define        AR5K_MISC_MAC_OBS_LSB_M 0x00007000
-#define        AR5K_MISC_MAC_OBS_LSB_S 12
-#define        AR5K_MISC_MAC_OBS_MSB_M 0x00038000
-#define        AR5K_MISC_MAC_OBS_MSB_S 15
-#define AR5K_MISC_LED_DECAY    0x001c0000      /* [5210] */
-#define AR5K_MISC_LED_BLINK    0x00e00000      /* [5210] */
-
-/*
- * QCU/DCU clock gating register (5311)
- * (reserved4-5)
- */
-#define        AR5K_QCUDCU_CLKGT       0x005c                  /* Register Address (?) */
-#define        AR5K_QCUDCU_CLKGT_QCU   0x0000ffff      /* Mask for QCU clock */
-#define        AR5K_QCUDCU_CLKGT_DCU   0x07ff0000      /* Mask for DCU clock */
-
-/*
- * Interrupt Status Registers
- *
- * For 5210 there is only one status register but for
- * 5211/5212 we have one primary and 4 secondary registers.
- * So we have AR5K_ISR for 5210 and AR5K_PISR /SISRx for 5211/5212.
- * Most of these bits are common for all chipsets.
- */
-#define AR5K_ISR               0x001c                  /* Register Address [5210] */
-#define AR5K_PISR              0x0080                  /* Register Address [5211+] */
-#define AR5K_ISR_RXOK          0x00000001      /* Frame successfuly recieved */
-#define AR5K_ISR_RXDESC                0x00000002      /* RX descriptor request */
-#define AR5K_ISR_RXERR         0x00000004      /* Receive error */
-#define AR5K_ISR_RXNOFRM       0x00000008      /* No frame received (receive timeout) */
-#define AR5K_ISR_RXEOL         0x00000010      /* Empty RX descriptor */
-#define AR5K_ISR_RXORN         0x00000020      /* Receive FIFO overrun */
-#define AR5K_ISR_TXOK          0x00000040      /* Frame successfuly transmited */
-#define AR5K_ISR_TXDESC                0x00000080      /* TX descriptor request */
-#define AR5K_ISR_TXERR         0x00000100      /* Transmit error */
-#define AR5K_ISR_TXNOFRM       0x00000200      /* No frame transmited (transmit timeout) */
-#define AR5K_ISR_TXEOL         0x00000400      /* Empty TX descriptor */
-#define AR5K_ISR_TXURN         0x00000800      /* Transmit FIFO underrun */
-#define AR5K_ISR_MIB           0x00001000      /* Update MIB counters */
-#define AR5K_ISR_SWI           0x00002000      /* Software interrupt */
-#define AR5K_ISR_RXPHY         0x00004000      /* PHY error */
-#define AR5K_ISR_RXKCM         0x00008000      /* RX Key cache miss */
-#define AR5K_ISR_SWBA          0x00010000      /* Software beacon alert */
-#define AR5K_ISR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
-#define AR5K_ISR_BMISS         0x00040000      /* Beacon missed */
-#define AR5K_ISR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
-#define AR5K_ISR_BNR           0x00100000      /* Beacon not ready [5211+] */
-#define AR5K_ISR_MCABT         0x00100000      /* Master Cycle Abort [5210] */
-#define AR5K_ISR_RXCHIRP       0x00200000      /* CHIRP Received [5212+] */
-#define AR5K_ISR_SSERR         0x00200000      /* Signaled System Error [5210] */
-#define AR5K_ISR_DPERR         0x00400000      /* Det par Error (?) [5210] */
-#define AR5K_ISR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
-#define AR5K_ISR_TIM           0x00800000      /* [5211+] */
-#define AR5K_ISR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
-                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
-#define AR5K_ISR_GPIO          0x01000000      /* GPIO (rf kill) */
-#define AR5K_ISR_QCBRORN       0x02000000      /* QCU CBR overrun [5211+] */
-#define AR5K_ISR_QCBRURN       0x04000000      /* QCU CBR underrun [5211+] */
-#define AR5K_ISR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
-
-/*
- * Secondary status registers [5211+] (0 - 4)
- *
- * These give the status for each QCU, only QCUs 0-9 are
- * represented.
- */
-#define AR5K_SISR0             0x0084                  /* Register Address [5211+] */
-#define AR5K_SISR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
-#define AR5K_SISR0_QCU_TXOK_S  0
-#define AR5K_SISR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
-#define AR5K_SISR0_QCU_TXDESC_S        16
-
-#define AR5K_SISR1             0x0088                  /* Register Address [5211+] */
-#define AR5K_SISR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
-#define AR5K_SISR1_QCU_TXERR_S 0
-#define AR5K_SISR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
-#define AR5K_SISR1_QCU_TXEOL_S 16
-
-#define AR5K_SISR2             0x008c                  /* Register Address [5211+] */
-#define AR5K_SISR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
-#define        AR5K_SISR2_QCU_TXURN_S  0
-#define        AR5K_SISR2_MCABT        0x00100000      /* Master Cycle Abort */
-#define        AR5K_SISR2_SSERR        0x00200000      /* Signaled System Error */
-#define        AR5K_SISR2_DPERR        0x00400000      /* Bus parity error */
-#define        AR5K_SISR2_TIM          0x01000000      /* [5212+] */
-#define        AR5K_SISR2_CAB_END      0x02000000      /* [5212+] */
-#define        AR5K_SISR2_DTIM_SYNC    0x04000000      /* DTIM sync lost [5212+] */
-#define        AR5K_SISR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
-#define        AR5K_SISR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
-#define        AR5K_SISR2_DTIM         0x20000000      /* [5212+] */
-#define        AR5K_SISR2_TSFOOR       0x80000000      /* TSF OOR (?) */
-
-#define AR5K_SISR3             0x0090                  /* Register Address [5211+] */
-#define AR5K_SISR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
-#define AR5K_SISR3_QCBRORN_S   0
-#define AR5K_SISR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
-#define AR5K_SISR3_QCBRURN_S   16
-
-#define AR5K_SISR4             0x0094                  /* Register Address [5211+] */
-#define AR5K_SISR4_QTRIG       0x000003ff      /* Mask for QTRIG */
-#define AR5K_SISR4_QTRIG_S     0
-
-/*
- * Shadow read-and-clear interrupt status registers [5211+]
- */
-#define AR5K_RAC_PISR          0x00c0          /* Read and clear PISR */
-#define AR5K_RAC_SISR0         0x00c4          /* Read and clear SISR0 */
-#define AR5K_RAC_SISR1         0x00c8          /* Read and clear SISR1 */
-#define AR5K_RAC_SISR2         0x00cc          /* Read and clear SISR2 */
-#define AR5K_RAC_SISR3         0x00d0          /* Read and clear SISR3 */
-#define AR5K_RAC_SISR4         0x00d4          /* Read and clear SISR4 */
-
-/*
- * Interrupt Mask Registers
- *
- * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary
- * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match.
- */
-#define        AR5K_IMR                0x0020                  /* Register Address [5210] */
-#define AR5K_PIMR              0x00a0                  /* Register Address [5211+] */
-#define AR5K_IMR_RXOK          0x00000001      /* Frame successfuly recieved*/
-#define AR5K_IMR_RXDESC                0x00000002      /* RX descriptor request*/
-#define AR5K_IMR_RXERR         0x00000004      /* Receive error*/
-#define AR5K_IMR_RXNOFRM       0x00000008      /* No frame received (receive timeout)*/
-#define AR5K_IMR_RXEOL         0x00000010      /* Empty RX descriptor*/
-#define AR5K_IMR_RXORN         0x00000020      /* Receive FIFO overrun*/
-#define AR5K_IMR_TXOK          0x00000040      /* Frame successfuly transmited*/
-#define AR5K_IMR_TXDESC                0x00000080      /* TX descriptor request*/
-#define AR5K_IMR_TXERR         0x00000100      /* Transmit error*/
-#define AR5K_IMR_TXNOFRM       0x00000200      /* No frame transmited (transmit timeout)*/
-#define AR5K_IMR_TXEOL         0x00000400      /* Empty TX descriptor*/
-#define AR5K_IMR_TXURN         0x00000800      /* Transmit FIFO underrun*/
-#define AR5K_IMR_MIB           0x00001000      /* Update MIB counters*/
-#define AR5K_IMR_SWI           0x00002000      /* Software interrupt */
-#define AR5K_IMR_RXPHY         0x00004000      /* PHY error*/
-#define AR5K_IMR_RXKCM         0x00008000      /* RX Key cache miss */
-#define AR5K_IMR_SWBA          0x00010000      /* Software beacon alert*/
-#define AR5K_IMR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
-#define AR5K_IMR_BMISS         0x00040000      /* Beacon missed*/
-#define AR5K_IMR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
-#define AR5K_IMR_BNR           0x00100000      /* Beacon not ready [5211+] */
-#define AR5K_IMR_MCABT         0x00100000      /* Master Cycle Abort [5210] */
-#define AR5K_IMR_RXCHIRP       0x00200000      /* CHIRP Received [5212+]*/
-#define AR5K_IMR_SSERR         0x00200000      /* Signaled System Error [5210] */
-#define AR5K_IMR_DPERR         0x00400000      /* Det par Error (?) [5210] */
-#define AR5K_IMR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
-#define AR5K_IMR_TIM           0x00800000      /* [5211+] */
-#define AR5K_IMR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
-                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
-#define AR5K_IMR_GPIO          0x01000000      /* GPIO (rf kill)*/
-#define AR5K_IMR_QCBRORN       0x02000000      /* QCU CBR overrun (?) [5211+] */
-#define AR5K_IMR_QCBRURN       0x04000000      /* QCU CBR underrun (?) [5211+] */
-#define AR5K_IMR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
-
-/*
- * Secondary interrupt mask registers [5211+] (0 - 4)
- */
-#define AR5K_SIMR0             0x00a4                  /* Register Address [5211+] */
-#define AR5K_SIMR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
-#define AR5K_SIMR0_QCU_TXOK_S  0
-#define AR5K_SIMR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
-#define AR5K_SIMR0_QCU_TXDESC_S        16
-
-#define AR5K_SIMR1             0x00a8                  /* Register Address [5211+] */
-#define AR5K_SIMR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
-#define AR5K_SIMR1_QCU_TXERR_S 0
-#define AR5K_SIMR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
-#define AR5K_SIMR1_QCU_TXEOL_S 16
-
-#define AR5K_SIMR2             0x00ac                  /* Register Address [5211+] */
-#define AR5K_SIMR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
-#define AR5K_SIMR2_QCU_TXURN_S 0
-#define        AR5K_SIMR2_MCABT        0x00100000      /* Master Cycle Abort */
-#define        AR5K_SIMR2_SSERR        0x00200000      /* Signaled System Error */
-#define        AR5K_SIMR2_DPERR        0x00400000      /* Bus parity error */
-#define        AR5K_SIMR2_TIM          0x01000000      /* [5212+] */
-#define        AR5K_SIMR2_CAB_END      0x02000000      /* [5212+] */
-#define        AR5K_SIMR2_DTIM_SYNC    0x04000000      /* DTIM Sync lost [5212+] */
-#define        AR5K_SIMR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
-#define        AR5K_SIMR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
-#define        AR5K_SIMR2_DTIM         0x20000000      /* [5212+] */
-#define        AR5K_SIMR2_TSFOOR       0x80000000      /* TSF OOR (?) */
-
-#define AR5K_SIMR3             0x00b0                  /* Register Address [5211+] */
-#define AR5K_SIMR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
-#define AR5K_SIMR3_QCBRORN_S   0
-#define AR5K_SIMR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
-#define AR5K_SIMR3_QCBRURN_S   16
-
-#define AR5K_SIMR4             0x00b4                  /* Register Address [5211+] */
-#define AR5K_SIMR4_QTRIG       0x000003ff      /* Mask for QTRIG */
-#define AR5K_SIMR4_QTRIG_S     0
-
-/*
- * DMA Debug registers 0-7
- * 0xe0 - 0xfc
- */
-
-/*
- * Decompression mask registers [5212+]
- */
-#define AR5K_DCM_ADDR          0x0400          /*Decompression mask address (index) */
-#define AR5K_DCM_DATA          0x0404          /*Decompression mask data */
-
-/*
- * Wake On Wireless pattern control register [5212+]
- */
-#define        AR5K_WOW_PCFG                   0x0410                  /* Register Address */
-#define        AR5K_WOW_PCFG_PAT_MATCH_EN      0x00000001      /* Pattern match enable */
-#define        AR5K_WOW_PCFG_LONG_FRAME_POL    0x00000002      /* Long frame policy */
-#define        AR5K_WOW_PCFG_WOBMISS           0x00000004      /* Wake on bea(con) miss (?) */
-#define        AR5K_WOW_PCFG_PAT_0_EN          0x00000100      /* Enable pattern 0 */
-#define        AR5K_WOW_PCFG_PAT_1_EN          0x00000200      /* Enable pattern 1 */
-#define        AR5K_WOW_PCFG_PAT_2_EN          0x00000400      /* Enable pattern 2 */
-#define        AR5K_WOW_PCFG_PAT_3_EN          0x00000800      /* Enable pattern 3 */
-#define        AR5K_WOW_PCFG_PAT_4_EN          0x00001000      /* Enable pattern 4 */
-#define        AR5K_WOW_PCFG_PAT_5_EN          0x00002000      /* Enable pattern 5 */
-
-/*
- * Wake On Wireless pattern index register (?) [5212+]
- */
-#define        AR5K_WOW_PAT_IDX        0x0414
-
-/*
- * Wake On Wireless pattern data register [5212+]
- */
-#define        AR5K_WOW_PAT_DATA       0x0418                  /* Register Address */
-#define        AR5K_WOW_PAT_DATA_0_3_V 0x00000001      /* Pattern 0, 3 value */
-#define        AR5K_WOW_PAT_DATA_1_4_V 0x00000100      /* Pattern 1, 4 value */
-#define        AR5K_WOW_PAT_DATA_2_5_V 0x00010000      /* Pattern 2, 5 value */
-#define        AR5K_WOW_PAT_DATA_0_3_M 0x01000000      /* Pattern 0, 3 mask */
-#define        AR5K_WOW_PAT_DATA_1_4_M 0x04000000      /* Pattern 1, 4 mask */
-#define        AR5K_WOW_PAT_DATA_2_5_M 0x10000000      /* Pattern 2, 5 mask */
-
-/*
- * Decompression configuration registers [5212+]
- */
-#define AR5K_DCCFG             0x0420                  /* Register Address */
-#define AR5K_DCCFG_GLOBAL_EN   0x00000001      /* Enable decompression on all queues */
-#define AR5K_DCCFG_BYPASS_EN   0x00000002      /* Bypass decompression */
-#define AR5K_DCCFG_BCAST_EN    0x00000004      /* Enable decompression for bcast frames */
-#define AR5K_DCCFG_MCAST_EN    0x00000008      /* Enable decompression for mcast frames */
-
-/*
- * Compression configuration registers [5212+]
- */
-#define AR5K_CCFG              0x0600                  /* Register Address */
-#define        AR5K_CCFG_WINDOW_SIZE   0x00000007      /* Compression window size */
-#define        AR5K_CCFG_CPC_EN        0x00000008      /* Enable performance counters */
-
-#define AR5K_CCFG_CCU          0x0604                  /* Register Address */
-#define AR5K_CCFG_CCU_CUP_EN   0x00000001      /* CCU Catchup enable */
-#define AR5K_CCFG_CCU_CREDIT   0x00000002      /* CCU Credit (field) */
-#define AR5K_CCFG_CCU_CD_THRES 0x00000080      /* CCU Cyc(lic?) debt threshold (field) */
-#define AR5K_CCFG_CCU_CUP_LCNT 0x00010000      /* CCU Catchup lit(?) count */
-#define        AR5K_CCFG_CCU_INIT      0x00100200      /* Initial value during reset */
-
-/*
- * Compression performance counter registers [5212+]
- */
-#define AR5K_CPC0              0x0610          /* Compression performance counter 0 */
-#define AR5K_CPC1              0x0614          /* Compression performance counter 1*/
-#define AR5K_CPC2              0x0618          /* Compression performance counter 2 */
-#define AR5K_CPC3              0x061c          /* Compression performance counter 3 */
-#define AR5K_CPCOVF            0x0620          /* Compression performance overflow */
-
-
-/*
- * Queue control unit (QCU) registers [5211+]
- *
- * Card has 12 TX Queues but i see that only 0-9 are used (?)
- * both in binary HAL (see ah.h) and ar5k. Each queue has it's own
- * TXDP at addresses 0x0800 - 0x082c, a CBR (Constant Bit Rate)
- * configuration register (0x08c0 - 0x08ec), a ready time configuration
- * register (0x0900 - 0x092c), a misc configuration register (0x09c0 -
- * 0x09ec) and a status register (0x0a00 - 0x0a2c). We also have some
- * global registers, QCU transmit enable/disable and "one shot arm (?)"
- * set/clear, which contain status for all queues (we shift by 1 for each
- * queue). To access these registers easily we define some macros here
- * that are used inside HAL. For more infos check out *_tx_queue functs.
- */
-
-/*
- * Generic QCU Register access macros
- */
-#define        AR5K_QUEUE_REG(_r, _q)          (((_q) << 2) + _r)
-#define AR5K_QCU_GLOBAL_READ(_r, _q)   (AR5K_REG_READ(_r) & (1 << _q))
-#define AR5K_QCU_GLOBAL_WRITE(_r, _q)  AR5K_REG_WRITE(_r, (1 << _q))
-
-/*
- * QCU Transmit descriptor pointer registers
- */
-#define AR5K_QCU_TXDP_BASE     0x0800          /* Register Address - Queue0 TXDP */
-#define AR5K_QUEUE_TXDP(_q)    AR5K_QUEUE_REG(AR5K_QCU_TXDP_BASE, _q)
-
-/*
- * QCU Transmit enable register
- */
-#define AR5K_QCU_TXE           0x0840
-#define AR5K_ENABLE_QUEUE(_q)  AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXE, _q)
-#define AR5K_QUEUE_ENABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXE, _q)
-
-/*
- * QCU Transmit disable register
- */
-#define AR5K_QCU_TXD           0x0880
-#define AR5K_DISABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXD, _q)
-#define AR5K_QUEUE_DISABLED(_q)        AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXD, _q)
-
-/*
- * QCU Constant Bit Rate configuration registers
- */
-#define        AR5K_QCU_CBRCFG_BASE            0x08c0  /* Register Address - Queue0 CBRCFG */
-#define        AR5K_QCU_CBRCFG_INTVAL          0x00ffffff      /* CBR Interval mask */
-#define AR5K_QCU_CBRCFG_INTVAL_S       0
-#define        AR5K_QCU_CBRCFG_ORN_THRES       0xff000000      /* CBR overrun threshold mask */
-#define AR5K_QCU_CBRCFG_ORN_THRES_S    24
-#define        AR5K_QUEUE_CBRCFG(_q)           AR5K_QUEUE_REG(AR5K_QCU_CBRCFG_BASE, _q)
-
-/*
- * QCU Ready time configuration registers
- */
-#define        AR5K_QCU_RDYTIMECFG_BASE        0x0900  /* Register Address - Queue0 RDYTIMECFG */
-#define        AR5K_QCU_RDYTIMECFG_INTVAL      0x00ffffff      /* Ready time interval mask */
-#define AR5K_QCU_RDYTIMECFG_INTVAL_S   0
-#define        AR5K_QCU_RDYTIMECFG_ENABLE      0x01000000      /* Ready time enable mask */
-#define AR5K_QUEUE_RDYTIMECFG(_q)      AR5K_QUEUE_REG(AR5K_QCU_RDYTIMECFG_BASE, _q)
-
-/*
- * QCU one shot arm set registers
- */
-#define        AR5K_QCU_ONESHOTARM_SET         0x0940  /* Register Address -QCU "one shot arm set (?)" */
-#define        AR5K_QCU_ONESHOTARM_SET_M       0x0000ffff
-
-/*
- * QCU one shot arm clear registers
- */
-#define        AR5K_QCU_ONESHOTARM_CLEAR       0x0980  /* Register Address -QCU "one shot arm clear (?)" */
-#define        AR5K_QCU_ONESHOTARM_CLEAR_M     0x0000ffff
-
-/*
- * QCU misc registers
- */
-#define AR5K_QCU_MISC_BASE             0x09c0                  /* Register Address -Queue0 MISC */
-#define        AR5K_QCU_MISC_FRSHED_M          0x0000000f      /* Frame sheduling mask */
-#define        AR5K_QCU_MISC_FRSHED_ASAP               0       /* ASAP */
-#define        AR5K_QCU_MISC_FRSHED_CBR                1       /* Constant Bit Rate */
-#define        AR5K_QCU_MISC_FRSHED_DBA_GT             2       /* DMA Beacon alert gated */
-#define        AR5K_QCU_MISC_FRSHED_TIM_GT             3       /* TIMT gated */
-#define        AR5K_QCU_MISC_FRSHED_BCN_SENT_GT        4       /* Beacon sent gated */
-#define        AR5K_QCU_MISC_ONESHOT_ENABLE    0x00000010      /* Oneshot enable */
-#define        AR5K_QCU_MISC_CBREXP_DIS        0x00000020      /* Disable CBR expired counter (normal queue) */
-#define        AR5K_QCU_MISC_CBREXP_BCN_DIS    0x00000040      /* Disable CBR expired counter (beacon queue) */
-#define        AR5K_QCU_MISC_BCN_ENABLE        0x00000080      /* Enable Beacon use */
-#define        AR5K_QCU_MISC_CBR_THRES_ENABLE  0x00000100      /* CBR expired threshold enabled */
-#define        AR5K_QCU_MISC_RDY_VEOL_POLICY   0x00000200      /* TXE reset when RDYTIME expired or VEOL */
-#define        AR5K_QCU_MISC_CBR_RESET_CNT     0x00000400      /* CBR threshold (counter) reset */
-#define        AR5K_QCU_MISC_DCU_EARLY         0x00000800      /* DCU early termination */
-#define AR5K_QCU_MISC_DCU_CMP_EN       0x00001000      /* Enable frame compression */
-#define AR5K_QUEUE_MISC(_q)            AR5K_QUEUE_REG(AR5K_QCU_MISC_BASE, _q)
-
-
-/*
- * QCU status registers
- */
-#define AR5K_QCU_STS_BASE      0x0a00                  /* Register Address - Queue0 STS */
-#define        AR5K_QCU_STS_FRMPENDCNT 0x00000003      /* Frames pending counter */
-#define        AR5K_QCU_STS_CBREXPCNT  0x0000ff00      /* CBR expired counter */
-#define        AR5K_QUEUE_STATUS(_q)   AR5K_QUEUE_REG(AR5K_QCU_STS_BASE, _q)
-
-/*
- * QCU ready time shutdown register
- */
-#define AR5K_QCU_RDYTIMESHDN   0x0a40
-#define AR5K_QCU_RDYTIMESHDN_M 0x000003ff
-
-/*
- * QCU compression buffer base registers [5212+]
- */
-#define AR5K_QCU_CBB_SELECT    0x0b00
-#define AR5K_QCU_CBB_ADDR      0x0b04
-#define AR5K_QCU_CBB_ADDR_S    9
-
-/*
- * QCU compression buffer configuration register [5212+]
- * (buffer size)
- */
-#define AR5K_QCU_CBCFG         0x0b08
-
-
-
-/*
- * Distributed Coordination Function (DCF) control unit (DCU)
- * registers [5211+]
- *
- * These registers control the various characteristics of each queue
- * for 802.11e (WME) combatibility so they go together with
- * QCU registers in pairs. For each queue we have a QCU mask register,
- * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c),
- * a retry limit register (0x1080 - 0x10ac), a channel time register
- * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and
- * a sequence number register (0x1140 - 0x116c). It seems that "global"
- * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k).
- * We use the same macros here for easier register access.
- *
- */
-
-/*
- * DCU QCU mask registers
- */
-#define AR5K_DCU_QCUMASK_BASE  0x1000          /* Register Address -Queue0 DCU_QCUMASK */
-#define AR5K_DCU_QCUMASK_M     0x000003ff
-#define AR5K_QUEUE_QCUMASK(_q) AR5K_QUEUE_REG(AR5K_DCU_QCUMASK_BASE, _q)
-
-/*
- * DCU local Inter Frame Space settings register
- */
-#define AR5K_DCU_LCL_IFS_BASE          0x1040                  /* Register Address -Queue0 DCU_LCL_IFS */
-#define        AR5K_DCU_LCL_IFS_CW_MIN         0x000003ff      /* Minimum Contention Window */
-#define        AR5K_DCU_LCL_IFS_CW_MIN_S       0
-#define        AR5K_DCU_LCL_IFS_CW_MAX         0x000ffc00      /* Maximum Contention Window */
-#define        AR5K_DCU_LCL_IFS_CW_MAX_S       10
-#define        AR5K_DCU_LCL_IFS_AIFS           0x0ff00000      /* Arbitrated Interframe Space */
-#define        AR5K_DCU_LCL_IFS_AIFS_S         20
-#define        AR5K_DCU_LCL_IFS_AIFS_MAX       0xfc            /* Anything above that can cause DCU to hang */
-#define        AR5K_QUEUE_DFS_LOCAL_IFS(_q)    AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q)
-
-/*
- * DCU retry limit registers
- */
-#define AR5K_DCU_RETRY_LMT_BASE                0x1080                  /* Register Address -Queue0 DCU_RETRY_LMT */
-#define AR5K_DCU_RETRY_LMT_SH_RETRY    0x0000000f      /* Short retry limit mask */
-#define AR5K_DCU_RETRY_LMT_SH_RETRY_S  0
-#define AR5K_DCU_RETRY_LMT_LG_RETRY    0x000000f0      /* Long retry limit mask */
-#define AR5K_DCU_RETRY_LMT_LG_RETRY_S  4
-#define AR5K_DCU_RETRY_LMT_SSH_RETRY   0x00003f00      /* Station short retry limit mask (?) */
-#define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8
-#define AR5K_DCU_RETRY_LMT_SLG_RETRY   0x000fc000      /* Station long retry limit mask (?) */
-#define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14
-#define        AR5K_QUEUE_DFS_RETRY_LIMIT(_q)  AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q)
-
-/*
- * DCU channel time registers
- */
-#define AR5K_DCU_CHAN_TIME_BASE                0x10c0                  /* Register Address -Queue0 DCU_CHAN_TIME */
-#define        AR5K_DCU_CHAN_TIME_DUR          0x000fffff      /* Channel time duration */
-#define        AR5K_DCU_CHAN_TIME_DUR_S        0
-#define        AR5K_DCU_CHAN_TIME_ENABLE       0x00100000      /* Enable channel time */
-#define AR5K_QUEUE_DFS_CHANNEL_TIME(_q)        AR5K_QUEUE_REG(AR5K_DCU_CHAN_TIME_BASE, _q)
-
-/*
- * DCU misc registers [5211+]
- *
- * Note: Arbiter lockout control controls the
- * behaviour on low priority queues when we have multiple queues
- * with pending frames. Intra-frame lockout means we wait until
- * the queue's current frame transmits (with post frame backoff and bursting)
- * before we transmit anything else and global lockout means we
- * wait for the whole queue to finish before higher priority queues
- * can transmit (this is used on beacon and CAB queues).
- * No lockout means there is no special handling.
- */
-#define AR5K_DCU_MISC_BASE             0x1100                  /* Register Address -Queue0 DCU_MISC */
-#define        AR5K_DCU_MISC_BACKOFF           0x0000003f      /* Mask for backoff threshold */
-#define        AR5K_DCU_MISC_ETS_RTS_POL       0x00000040      /* End of transmission series
-                                                       station RTS/data failure count
-                                                       reset policy (?) */
-#define AR5K_DCU_MISC_ETS_CW_POL       0x00000080      /* End of transmission series
-                                                       CW reset policy */
-#define        AR5K_DCU_MISC_FRAG_WAIT         0x00000100      /* Wait for next fragment */
-#define AR5K_DCU_MISC_BACKOFF_FRAG     0x00000200      /* Enable backoff while bursting */
-#define        AR5K_DCU_MISC_HCFPOLL_ENABLE    0x00000800      /* CF - Poll enable */
-#define        AR5K_DCU_MISC_BACKOFF_PERSIST   0x00001000      /* Persistent backoff */
-#define        AR5K_DCU_MISC_FRMPRFTCH_ENABLE  0x00002000      /* Enable frame pre-fetch */
-#define        AR5K_DCU_MISC_VIRTCOL           0x0000c000      /* Mask for Virtual Collision (?) */
-#define        AR5K_DCU_MISC_VIRTCOL_NORMAL    0
-#define        AR5K_DCU_MISC_VIRTCOL_IGNORE    1
-#define        AR5K_DCU_MISC_BCN_ENABLE        0x00010000      /* Enable Beacon use */
-#define        AR5K_DCU_MISC_ARBLOCK_CTL       0x00060000      /* Arbiter lockout control mask */
-#define        AR5K_DCU_MISC_ARBLOCK_CTL_S     17
-#define        AR5K_DCU_MISC_ARBLOCK_CTL_NONE          0       /* No arbiter lockout */
-#define        AR5K_DCU_MISC_ARBLOCK_CTL_INTFRM        1       /* Intra-frame lockout */
-#define        AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL        2       /* Global lockout */
-#define        AR5K_DCU_MISC_ARBLOCK_IGNORE    0x00080000      /* Ignore Arbiter lockout */
-#define        AR5K_DCU_MISC_SEQ_NUM_INCR_DIS  0x00100000      /* Disable sequence number increment */
-#define        AR5K_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000      /* Disable post-frame backoff */
-#define        AR5K_DCU_MISC_VIRT_COLL_POLICY  0x00400000      /* Virtual Collision cw policy */
-#define        AR5K_DCU_MISC_BLOWN_IFS_POLICY  0x00800000      /* Blown IFS policy (?) */
-#define        AR5K_DCU_MISC_SEQNUM_CTL        0x01000000      /* Sequence number control (?) */
-#define AR5K_QUEUE_DFS_MISC(_q)                AR5K_QUEUE_REG(AR5K_DCU_MISC_BASE, _q)
-
-/*
- * DCU frame sequence number registers
- */
-#define AR5K_DCU_SEQNUM_BASE           0x1140
-#define        AR5K_DCU_SEQNUM_M               0x00000fff
-#define        AR5K_QUEUE_DCU_SEQNUM(_q)       AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
-
-/*
- * DCU global IFS SIFS register
- */
-#define AR5K_DCU_GBL_IFS_SIFS  0x1030
-#define AR5K_DCU_GBL_IFS_SIFS_M        0x0000ffff
-
-/*
- * DCU global IFS slot interval register
- */
-#define AR5K_DCU_GBL_IFS_SLOT  0x1070
-#define AR5K_DCU_GBL_IFS_SLOT_M        0x0000ffff
-
-/*
- * DCU global IFS EIFS register
- */
-#define AR5K_DCU_GBL_IFS_EIFS  0x10b0
-#define AR5K_DCU_GBL_IFS_EIFS_M        0x0000ffff
-
-/*
- * DCU global IFS misc register
- *
- * LFSR stands for Linear Feedback Shift Register
- * and it's used for generating pseudo-random
- * number sequences.
- *
- * (If i understand corectly, random numbers are
- * used for idle sensing -multiplied with cwmin/max etc-)
- */
-#define AR5K_DCU_GBL_IFS_MISC                  0x10f0                  /* Register Address */
-#define        AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE        0x00000007      /* LFSR Slice Select */
-#define        AR5K_DCU_GBL_IFS_MISC_TURBO_MODE        0x00000008      /* Turbo mode */
-#define        AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC     0x000003f0      /* SIFS Duration mask */
-#define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR          0x000ffc00      /* USEC Duration mask */
-#define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S        10
-#define        AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY     0x00300000      /* DCU Arbiter delay mask */
-#define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST     0x00400000      /* SIFS cnt reset policy (?) */
-#define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST     0x00800000      /* AIFS cnt reset policy (?) */
-#define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS  0x01000000      /* Disable random LFSR slice */
-
-/*
- * DCU frame prefetch control register
- */
-#define AR5K_DCU_FP                    0x1230                  /* Register Address */
-#define AR5K_DCU_FP_NOBURST_DCU_EN     0x00000001      /* Enable non-burst prefetch on DCU (?) */
-#define AR5K_DCU_FP_NOBURST_EN         0x00000010      /* Enable non-burst prefetch (?) */
-#define AR5K_DCU_FP_BURST_DCU_EN       0x00000020      /* Enable burst prefetch on DCU (?) */
-
-/*
- * DCU transmit pause control/status register
- */
-#define AR5K_DCU_TXP           0x1270                  /* Register Address */
-#define        AR5K_DCU_TXP_M          0x000003ff      /* Tx pause mask */
-#define        AR5K_DCU_TXP_STATUS     0x00010000      /* Tx pause status */
-
-/*
- * DCU transmit filter table 0 (32 entries)
- * each entry contains a 32bit slice of the
- * 128bit tx filter for each DCU (4 slices per DCU)
- */
-#define AR5K_DCU_TX_FILTER_0_BASE      0x1038
-#define        AR5K_DCU_TX_FILTER_0(_n)        (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64))
-
-/*
- * DCU transmit filter table 1 (16 entries)
- */
-#define AR5K_DCU_TX_FILTER_1_BASE      0x103c
-#define        AR5K_DCU_TX_FILTER_1(_n)        (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64))
-
-/*
- * DCU clear transmit filter register
- */
-#define AR5K_DCU_TX_FILTER_CLR 0x143c
-
-/*
- * DCU set transmit filter register
- */
-#define AR5K_DCU_TX_FILTER_SET 0x147c
-
-/*
- * Reset control register
- */
-#define AR5K_RESET_CTL         0x4000                  /* Register Address */
-#define AR5K_RESET_CTL_PCU     0x00000001      /* Protocol Control Unit reset */
-#define AR5K_RESET_CTL_DMA     0x00000002      /* DMA (Rx/Tx) reset [5210] */
-#define        AR5K_RESET_CTL_BASEBAND 0x00000002      /* Baseband reset [5211+] */
-#define AR5K_RESET_CTL_MAC     0x00000004      /* MAC reset (PCU+Baseband ?) [5210] */
-#define AR5K_RESET_CTL_PHY     0x00000008      /* PHY reset [5210] */
-#define AR5K_RESET_CTL_PCI     0x00000010      /* PCI Core reset (interrupts etc) */
-
-/*
- * Sleep control register
- */
-#define AR5K_SLEEP_CTL                 0x4004                  /* Register Address */
-#define AR5K_SLEEP_CTL_SLDUR           0x0000ffff      /* Sleep duration mask */
-#define AR5K_SLEEP_CTL_SLDUR_S         0
-#define AR5K_SLEEP_CTL_SLE             0x00030000      /* Sleep enable mask */
-#define AR5K_SLEEP_CTL_SLE_S           16
-#define AR5K_SLEEP_CTL_SLE_WAKE                0x00000000      /* Force chip awake */
-#define AR5K_SLEEP_CTL_SLE_SLP         0x00010000      /* Force chip sleep */
-#define AR5K_SLEEP_CTL_SLE_ALLOW       0x00020000      /* Normal sleep policy */
-#define AR5K_SLEEP_CTL_SLE_UNITS       0x00000008      /* [5211+] */
-#define AR5K_SLEEP_CTL_DUR_TIM_POL     0x00040000      /* Sleep duration timing policy */
-#define AR5K_SLEEP_CTL_DUR_WRITE_POL   0x00080000      /* Sleep duration write policy */
-#define AR5K_SLEEP_CTL_SLE_POL         0x00100000      /* Sleep policy mode */
-
-/*
- * Interrupt pending register
- */
-#define AR5K_INTPEND   0x4008
-#define AR5K_INTPEND_M 0x00000001
-
-/*
- * Sleep force register
- */
-#define AR5K_SFR       0x400c
-#define AR5K_SFR_EN    0x00000001
-
-/*
- * PCI configuration register
- * TODO: Fix LED stuff
- */
-#define AR5K_PCICFG                    0x4010                  /* Register Address */
-#define AR5K_PCICFG_EEAE               0x00000001      /* Eeprom access enable [5210] */
-#define AR5K_PCICFG_SLEEP_CLOCK_EN     0x00000002      /* Enable sleep clock */
-#define AR5K_PCICFG_CLKRUNEN           0x00000004      /* CLKRUN enable [5211+] */
-#define AR5K_PCICFG_EESIZE             0x00000018      /* Mask for EEPROM size [5211+] */
-#define AR5K_PCICFG_EESIZE_S           3
-#define AR5K_PCICFG_EESIZE_4K          0               /* 4K */
-#define AR5K_PCICFG_EESIZE_8K          1               /* 8K */
-#define AR5K_PCICFG_EESIZE_16K         2               /* 16K */
-#define AR5K_PCICFG_EESIZE_FAIL                3               /* Failed to get size [5211+] */
-#define AR5K_PCICFG_LED                        0x00000060      /* Led status [5211+] */
-#define AR5K_PCICFG_LED_NONE           0x00000000      /* Default [5211+] */
-#define AR5K_PCICFG_LED_PEND           0x00000020      /* Scan / Auth pending */
-#define AR5K_PCICFG_LED_ASSOC          0x00000040      /* Associated */
-#define        AR5K_PCICFG_BUS_SEL             0x00000380      /* Mask for "bus select" [5211+] (?) */
-#define AR5K_PCICFG_CBEFIX_DIS         0x00000400      /* Disable CBE fix */
-#define AR5K_PCICFG_SL_INTEN           0x00000800      /* Enable interrupts when asleep */
-#define AR5K_PCICFG_LED_BCTL           0x00001000      /* Led blink (?) [5210] */
-#define AR5K_PCICFG_RETRY_FIX          0x00001000      /* Enable pci core retry fix */
-#define AR5K_PCICFG_SL_INPEN           0x00002000      /* Sleep even whith pending interrupts*/
-#define AR5K_PCICFG_SPWR_DN            0x00010000      /* Mask for power status */
-#define AR5K_PCICFG_LEDMODE            0x000e0000      /* Ledmode [5211+] */
-#define AR5K_PCICFG_LEDMODE_PROP       0x00000000      /* Blink on standard traffic [5211+] */
-#define AR5K_PCICFG_LEDMODE_PROM       0x00020000      /* Default mode (blink on any traffic) [5211+] */
-#define AR5K_PCICFG_LEDMODE_PWR                0x00040000      /* Some other blinking mode  (?) [5211+] */
-#define AR5K_PCICFG_LEDMODE_RAND       0x00060000      /* Random blinking (?) [5211+] */
-#define AR5K_PCICFG_LEDBLINK           0x00700000      /* Led blink rate */
-#define AR5K_PCICFG_LEDBLINK_S         20
-#define AR5K_PCICFG_LEDSLOW            0x00800000      /* Slowest led blink rate [5211+] */
-#define AR5K_PCICFG_LEDSTATE                           \
-       (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE |        \
-       AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW)
-#define        AR5K_PCICFG_SLEEP_CLOCK_RATE    0x03000000      /* Sleep clock rate */
-#define        AR5K_PCICFG_SLEEP_CLOCK_RATE_S  24
-
-/*
- * "General Purpose Input/Output" (GPIO) control register
- *
- * I'm not sure about this but after looking at the code
- * for all chipsets here is what i got.
- *
- * We have 6 GPIOs (pins), each GPIO has 4 modes (2 bits)
- * Mode 0 -> always input
- * Mode 1 -> output when GPIODO for this GPIO is set to 0
- * Mode 2 -> output when GPIODO for this GPIO is set to 1
- * Mode 3 -> always output
- *
- * For more infos check out get_gpio/set_gpio and
- * set_gpio_input/set_gpio_output functs.
- * For more infos on gpio interrupt check out set_gpio_intr.
- */
-#define AR5K_NUM_GPIO  6
-
-#define AR5K_GPIOCR            0x4014                          /* Register Address */
-#define AR5K_GPIOCR_INT_ENA    0x00008000              /* Enable GPIO interrupt */
-#define AR5K_GPIOCR_INT_SELL   0x00000000              /* Generate interrupt when pin is low */
-#define AR5K_GPIOCR_INT_SELH   0x00010000              /* Generate interrupt when pin is high */
-#define AR5K_GPIOCR_IN(n)      (0 << ((n) * 2))        /* Mode 0 for pin n */
-#define AR5K_GPIOCR_OUT0(n)    (1 << ((n) * 2))        /* Mode 1 for pin n */
-#define AR5K_GPIOCR_OUT1(n)    (2 << ((n) * 2))        /* Mode 2 for pin n */
-#define AR5K_GPIOCR_OUT(n)     (3 << ((n) * 2))        /* Mode 3 for pin n */
-#define AR5K_GPIOCR_INT_SEL(n) ((n) << 12)             /* Interrupt for GPIO pin n */
-
-/*
- * "General Purpose Input/Output" (GPIO) data output register
- */
-#define AR5K_GPIODO    0x4018
-
-/*
- * "General Purpose Input/Output" (GPIO) data input register
- */
-#define AR5K_GPIODI    0x401c
-#define AR5K_GPIODI_M  0x0000002f
-
-/*
- * Silicon revision register
- */
-#define AR5K_SREV              0x4020                  /* Register Address */
-#define AR5K_SREV_REV          0x0000000f      /* Mask for revision */
-#define AR5K_SREV_REV_S                0
-#define AR5K_SREV_VER          0x000000ff      /* Mask for version */
-#define AR5K_SREV_VER_S                4
-
-/*
- * TXE write posting register
- */
-#define        AR5K_TXEPOST    0x4028
-
-/*
- * QCU sleep mask
- */
-#define        AR5K_QCU_SLEEP_MASK     0x402c
-
-/* 0x4068 is compression buffer configuration
- * register on 5414 and pm configuration register
- * on 5424 and newer pci-e chips. */
-
-/*
- * Compression buffer configuration
- * register (enable/disable) [5414]
- */
-#define AR5K_5414_CBCFG                0x4068
-#define AR5K_5414_CBCFG_BUF_DIS        0x10    /* Disable buffer */
-
-/*
- * PCI-E Power managment configuration
- * and status register [5424+]
- */
-#define        AR5K_PCIE_PM_CTL                0x4068                  /* Register address */
-/* Only 5424 */
-#define        AR5K_PCIE_PM_CTL_L1_WHEN_D2     0x00000001      /* enable PCIe core enter L1
-                                                       when d2_sleep_en is asserted */
-#define        AR5K_PCIE_PM_CTL_L0_L0S_CLEAR   0x00000002      /* Clear L0 and L0S counters */
-#define        AR5K_PCIE_PM_CTL_L0_L0S_EN      0x00000004      /* Start L0 nd L0S counters */
-#define        AR5K_PCIE_PM_CTL_LDRESET_EN     0x00000008      /* Enable reset when link goes
-                                                       down */
-/* Wake On Wireless */
-#define        AR5K_PCIE_PM_CTL_PME_EN         0x00000010      /* PME Enable */
-#define        AR5K_PCIE_PM_CTL_AUX_PWR_DET    0x00000020      /* Aux power detect */
-#define        AR5K_PCIE_PM_CTL_PME_CLEAR      0x00000040      /* Clear PME */
-#define        AR5K_PCIE_PM_CTL_PSM_D0         0x00000080
-#define        AR5K_PCIE_PM_CTL_PSM_D1         0x00000100
-#define        AR5K_PCIE_PM_CTL_PSM_D2         0x00000200
-#define        AR5K_PCIE_PM_CTL_PSM_D3         0x00000400
-
-/*
- * PCI-E Workaround enable register
- */
-#define        AR5K_PCIE_WAEN  0x407c
-
-/*
- * PCI-E Serializer/Desirializer
- * registers
- */
-#define        AR5K_PCIE_SERDES        0x4080
-#define        AR5K_PCIE_SERDES_RESET  0x4084
-
-/*====EEPROM REGISTERS====*/
-
-/*
- * EEPROM access registers
- *
- * Here we got a difference between 5210/5211-12
- * read data register for 5210 is at 0x6800 and
- * status register is at 0x6c00. There is also
- * no eeprom command register on 5210 and the
- * offsets are different.
- *
- * To read eeprom data for a specific offset:
- * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
- *        read AR5K_EEPROM_BASE +(4 * offset)
- *        check the eeprom status register
- *        and read eeprom data register.
- *
- * 5211 - write offset to AR5K_EEPROM_BASE
- * 5212   write AR5K_EEPROM_CMD_READ on AR5K_EEPROM_CMD
- *        check the eeprom status register
- *        and read eeprom data register.
- *
- * To write eeprom data for a specific offset:
- * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
- *        write data to AR5K_EEPROM_BASE +(4 * offset)
- *        check the eeprom status register
- * 5211 - write AR5K_EEPROM_CMD_RESET on AR5K_EEPROM_CMD
- * 5212   write offset to AR5K_EEPROM_BASE
- *        write data to data register
- *       write AR5K_EEPROM_CMD_WRITE on AR5K_EEPROM_CMD
- *        check the eeprom status register
- *
- * For more infos check eeprom_* functs and the ar5k.c
- * file posted in madwifi-devel mailing list.
- * http://sourceforge.net/mailarchive/message.php?msg_id=8966525
- *
- */
-#define AR5K_EEPROM_BASE       0x6000
-
-/*
- * EEPROM data register
- */
-#define AR5K_EEPROM_DATA_5211  0x6004
-#define AR5K_EEPROM_DATA_5210  0x6800
-#define        AR5K_EEPROM_DATA        (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211)
-
-/*
- * EEPROM command register
- */
-#define AR5K_EEPROM_CMD                0x6008                  /* Register Addres */
-#define AR5K_EEPROM_CMD_READ   0x00000001      /* EEPROM read */
-#define AR5K_EEPROM_CMD_WRITE  0x00000002      /* EEPROM write */
-#define AR5K_EEPROM_CMD_RESET  0x00000004      /* EEPROM reset */
-
-/*
- * EEPROM status register
- */
-#define AR5K_EEPROM_STAT_5210  0x6c00                  /* Register Address [5210] */
-#define AR5K_EEPROM_STAT_5211  0x600c                  /* Register Address [5211+] */
-#define        AR5K_EEPROM_STATUS      (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211)
-#define AR5K_EEPROM_STAT_RDERR 0x00000001      /* EEPROM read failed */
-#define AR5K_EEPROM_STAT_RDDONE        0x00000002      /* EEPROM read successful */
-#define AR5K_EEPROM_STAT_WRERR 0x00000004      /* EEPROM write failed */
-#define AR5K_EEPROM_STAT_WRDONE        0x00000008      /* EEPROM write successful */
-
-/*
- * EEPROM config register
- */
-#define AR5K_EEPROM_CFG                        0x6010                  /* Register Addres */
-#define AR5K_EEPROM_CFG_SIZE           0x00000003              /* Size determination override */
-#define AR5K_EEPROM_CFG_SIZE_AUTO      0
-#define AR5K_EEPROM_CFG_SIZE_4KBIT     1
-#define AR5K_EEPROM_CFG_SIZE_8KBIT     2
-#define AR5K_EEPROM_CFG_SIZE_16KBIT    3
-#define AR5K_EEPROM_CFG_WR_WAIT_DIS    0x00000004      /* Disable write wait */
-#define AR5K_EEPROM_CFG_CLK_RATE       0x00000018      /* Clock rate */
-#define AR5K_EEPROM_CFG_CLK_RATE_S             3
-#define AR5K_EEPROM_CFG_CLK_RATE_156KHZ        0
-#define AR5K_EEPROM_CFG_CLK_RATE_312KHZ        1
-#define AR5K_EEPROM_CFG_CLK_RATE_625KHZ        2
-#define AR5K_EEPROM_CFG_PROT_KEY       0x00ffff00      /* Protection key */
-#define AR5K_EEPROM_CFG_PROT_KEY_S     8
-#define AR5K_EEPROM_CFG_LIND_EN                0x01000000      /* Enable length indicator (?) */
-
-
-/*
- * TODO: Wake On Wireless registers
- * Range 0x7000 - 0x7ce0
- */
-
-/*
- * Protocol Control Unit (PCU) registers
- */
-/*
- * Used for checking initial register writes
- * during channel reset (see reset func)
- */
-#define AR5K_PCU_MIN   0x8000
-#define AR5K_PCU_MAX   0x8fff
-
-/*
- * First station id register (Lower 32 bits of MAC address)
- */
-#define AR5K_STA_ID0           0x8000
-#define        AR5K_STA_ID0_ARRD_L32   0xffffffff
-
-/*
- * Second station id register (Upper 16 bits of MAC address + PCU settings)
- */
-#define AR5K_STA_ID1                   0x8004                  /* Register Address */
-#define        AR5K_STA_ID1_ADDR_U16           0x0000ffff      /* Upper 16 bits of MAC addres */
-#define AR5K_STA_ID1_AP                        0x00010000      /* Set AP mode */
-#define AR5K_STA_ID1_ADHOC             0x00020000      /* Set Ad-Hoc mode */
-#define AR5K_STA_ID1_PWR_SV            0x00040000      /* Power save reporting */
-#define AR5K_STA_ID1_NO_KEYSRCH                0x00080000      /* No key search */
-#define AR5K_STA_ID1_NO_PSPOLL         0x00100000      /* No power save polling [5210] */
-#define AR5K_STA_ID1_PCF_5211          0x00100000      /* Enable PCF on [5211+] */
-#define AR5K_STA_ID1_PCF_5210          0x00200000      /* Enable PCF on [5210]*/
-#define        AR5K_STA_ID1_PCF                (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_STA_ID1_PCF_5210 : AR5K_STA_ID1_PCF_5211)
-#define AR5K_STA_ID1_DEFAULT_ANTENNA   0x00200000      /* Use default antenna */
-#define AR5K_STA_ID1_DESC_ANTENNA      0x00400000      /* Update antenna from descriptor */
-#define AR5K_STA_ID1_RTS_DEF_ANTENNA   0x00800000      /* Use default antenna for RTS */
-#define AR5K_STA_ID1_ACKCTS_6MB                0x01000000      /* Use 6Mbit/s for ACK/CTS */
-#define AR5K_STA_ID1_BASE_RATE_11B     0x02000000      /* Use 11b base rate for ACK/CTS [5211+] */
-#define AR5K_STA_ID1_SELFGEN_DEF_ANT   0x04000000      /* Use def. antenna for self generated frames */
-#define AR5K_STA_ID1_CRYPT_MIC_EN      0x08000000      /* Enable MIC */
-#define AR5K_STA_ID1_KEYSRCH_MODE      0x10000000      /* Look up key when key id != 0 */
-#define AR5K_STA_ID1_PRESERVE_SEQ_NUM  0x20000000      /* Preserve sequence number */
-#define AR5K_STA_ID1_CBCIV_ENDIAN      0x40000000      /* ??? */
-#define AR5K_STA_ID1_KEYSRCH_MCAST     0x80000000      /* Do key cache search for mcast frames */
-
-/*
- * First BSSID register (MAC address, lower 32bits)
- */
-#define AR5K_BSS_ID0   0x8008
-
-/*
- * Second BSSID register (MAC address in upper 16 bits)
- *
- * AID: Association ID
- */
-#define AR5K_BSS_ID1           0x800c
-#define AR5K_BSS_ID1_AID       0xffff0000
-#define AR5K_BSS_ID1_AID_S     16
-
-/*
- * Backoff slot time register
- */
-#define AR5K_SLOT_TIME 0x8010
-
-/*
- * ACK/CTS timeout register
- */
-#define AR5K_TIME_OUT          0x8014                  /* Register Address */
-#define AR5K_TIME_OUT_ACK      0x00001fff      /* ACK timeout mask */
-#define AR5K_TIME_OUT_ACK_S    0
-#define AR5K_TIME_OUT_CTS      0x1fff0000      /* CTS timeout mask */
-#define AR5K_TIME_OUT_CTS_S    16
-
-/*
- * RSSI threshold register
- */
-#define AR5K_RSSI_THR                  0x8018          /* Register Address */
-#define AR5K_RSSI_THR_M                        0x000000ff      /* Mask for RSSI threshold [5211+] */
-#define AR5K_RSSI_THR_BMISS_5210       0x00000700      /* Mask for Beacon Missed threshold [5210] */
-#define AR5K_RSSI_THR_BMISS_5210_S     8
-#define AR5K_RSSI_THR_BMISS_5211       0x0000ff00      /* Mask for Beacon Missed threshold [5211+] */
-#define AR5K_RSSI_THR_BMISS_5211_S     8
-#define        AR5K_RSSI_THR_BMISS             (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_RSSI_THR_BMISS_5210 : AR5K_RSSI_THR_BMISS_5211)
-#define        AR5K_RSSI_THR_BMISS_S           8
-
-/*
- * 5210 has more PCU registers because there is no QCU/DCU
- * so queue parameters are set here, this way a lot common
- * registers have different address for 5210. To make things
- * easier we define a macro based on ah->ah_version for common
- * registers with different addresses and common flags.
- */
-
-/*
- * Retry limit register
- *
- * Retry limit register for 5210 (no QCU/DCU so it's done in PCU)
- */
-#define AR5K_NODCU_RETRY_LMT           0x801c                  /* Register Address */
-#define AR5K_NODCU_RETRY_LMT_SH_RETRY  0x0000000f      /* Short retry limit mask */
-#define AR5K_NODCU_RETRY_LMT_SH_RETRY_S        0
-#define AR5K_NODCU_RETRY_LMT_LG_RETRY  0x000000f0      /* Long retry mask */
-#define AR5K_NODCU_RETRY_LMT_LG_RETRY_S        4
-#define AR5K_NODCU_RETRY_LMT_SSH_RETRY 0x00003f00      /* Station short retry limit mask */
-#define AR5K_NODCU_RETRY_LMT_SSH_RETRY_S       8
-#define AR5K_NODCU_RETRY_LMT_SLG_RETRY 0x000fc000      /* Station long retry limit mask */
-#define AR5K_NODCU_RETRY_LMT_SLG_RETRY_S       14
-#define AR5K_NODCU_RETRY_LMT_CW_MIN    0x3ff00000      /* Minimum contention window mask */
-#define AR5K_NODCU_RETRY_LMT_CW_MIN_S  20
-
-/*
- * Transmit latency register
- */
-#define AR5K_USEC_5210                 0x8020                  /* Register Address [5210] */
-#define AR5K_USEC_5211                 0x801c                  /* Register Address [5211+] */
-#define AR5K_USEC                      (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_USEC_5210 : AR5K_USEC_5211)
-#define AR5K_USEC_1                    0x0000007f      /* clock cycles for 1us */
-#define AR5K_USEC_1_S                  0
-#define AR5K_USEC_32                   0x00003f80      /* clock cycles for 1us while on 32Mhz clock */
-#define AR5K_USEC_32_S                 7
-#define AR5K_USEC_TX_LATENCY_5211      0x007fc000
-#define AR5K_USEC_TX_LATENCY_5211_S    14
-#define AR5K_USEC_RX_LATENCY_5211      0x1f800000
-#define AR5K_USEC_RX_LATENCY_5211_S    23
-#define AR5K_USEC_TX_LATENCY_5210      0x000fc000      /* also for 5311 */
-#define AR5K_USEC_TX_LATENCY_5210_S    14
-#define AR5K_USEC_RX_LATENCY_5210      0x03f00000      /* also for 5311 */
-#define AR5K_USEC_RX_LATENCY_5210_S    20
-
-/*
- * PCU beacon control register
- */
-#define AR5K_BEACON_5210       0x8024                  /*Register Address [5210] */
-#define AR5K_BEACON_5211       0x8020                  /*Register Address [5211+] */
-#define AR5K_BEACON            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_BEACON_5210 : AR5K_BEACON_5211)
-#define AR5K_BEACON_PERIOD     0x0000ffff      /* Mask for beacon period */
-#define AR5K_BEACON_PERIOD_S   0
-#define AR5K_BEACON_TIM                0x007f0000      /* Mask for TIM offset */
-#define AR5K_BEACON_TIM_S      16
-#define AR5K_BEACON_ENABLE     0x00800000      /* Enable beacons */
-#define AR5K_BEACON_RESET_TSF  0x01000000      /* Force TSF reset */
-
-/*
- * CFP period register
- */
-#define AR5K_CFP_PERIOD_5210   0x8028
-#define AR5K_CFP_PERIOD_5211   0x8024
-#define AR5K_CFP_PERIOD                (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_CFP_PERIOD_5210 : AR5K_CFP_PERIOD_5211)
-
-/*
- * Next beacon time register
- */
-#define AR5K_TIMER0_5210       0x802c
-#define AR5K_TIMER0_5211       0x8028
-#define AR5K_TIMER0            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TIMER0_5210 : AR5K_TIMER0_5211)
-
-/*
- * Next DMA beacon alert register
- */
-#define AR5K_TIMER1_5210       0x8030
-#define AR5K_TIMER1_5211       0x802c
-#define AR5K_TIMER1            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TIMER1_5210 : AR5K_TIMER1_5211)
-
-/*
- * Next software beacon alert register
- */
-#define AR5K_TIMER2_5210       0x8034
-#define AR5K_TIMER2_5211       0x8030
-#define AR5K_TIMER2            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TIMER2_5210 : AR5K_TIMER2_5211)
-
-/*
- * Next ATIM window time register
- */
-#define AR5K_TIMER3_5210       0x8038
-#define AR5K_TIMER3_5211       0x8034
-#define AR5K_TIMER3            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TIMER3_5210 : AR5K_TIMER3_5211)
-
-
-/*
- * 5210 First inter frame spacing register (IFS)
- */
-#define AR5K_IFS0              0x8040
-#define AR5K_IFS0_SIFS         0x000007ff
-#define AR5K_IFS0_SIFS_S       0
-#define AR5K_IFS0_DIFS         0x007ff800
-#define AR5K_IFS0_DIFS_S       11
-
-/*
- * 5210 Second inter frame spacing register (IFS)
- */
-#define AR5K_IFS1              0x8044
-#define AR5K_IFS1_PIFS         0x00000fff
-#define AR5K_IFS1_PIFS_S       0
-#define AR5K_IFS1_EIFS         0x03fff000
-#define AR5K_IFS1_EIFS_S       12
-#define AR5K_IFS1_CS_EN                0x04000000
-
-
-/*
- * CFP duration register
- */
-#define AR5K_CFP_DUR_5210      0x8048
-#define AR5K_CFP_DUR_5211      0x8038
-#define AR5K_CFP_DUR           (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_CFP_DUR_5210 : AR5K_CFP_DUR_5211)
-
-/*
- * Receive filter register
- */
-#define AR5K_RX_FILTER_5210    0x804c                  /* Register Address [5210] */
-#define AR5K_RX_FILTER_5211    0x803c                  /* Register Address [5211+] */
-#define AR5K_RX_FILTER         (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211)
-#define        AR5K_RX_FILTER_UCAST    0x00000001      /* Don't filter unicast frames */
-#define        AR5K_RX_FILTER_MCAST    0x00000002      /* Don't filter multicast frames */
-#define        AR5K_RX_FILTER_BCAST    0x00000004      /* Don't filter broadcast frames */
-#define        AR5K_RX_FILTER_CONTROL  0x00000008      /* Don't filter control frames */
-#define        AR5K_RX_FILTER_BEACON   0x00000010      /* Don't filter beacon frames */
-#define        AR5K_RX_FILTER_PROM     0x00000020      /* Set promiscuous mode */
-#define        AR5K_RX_FILTER_XRPOLL   0x00000040      /* Don't filter XR poll frame [5212+] */
-#define        AR5K_RX_FILTER_PROBEREQ 0x00000080      /* Don't filter probe requests [5212+] */
-#define        AR5K_RX_FILTER_PHYERR_5212      0x00000100      /* Don't filter phy errors [5212+] */
-#define        AR5K_RX_FILTER_RADARERR_5212    0x00000200      /* Don't filter phy radar errors [5212+] */
-#define AR5K_RX_FILTER_PHYERR_5211     0x00000040      /* [5211] */
-#define AR5K_RX_FILTER_RADARERR_5211   0x00000080      /* [5211] */
-#define AR5K_RX_FILTER_PHYERR  \
-       ((ah->ah_version == AR5K_AR5211 ? \
-       AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212))
-#define        AR5K_RX_FILTER_RADARERR \
-       ((ah->ah_version == AR5K_AR5211 ? \
-       AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212))
-
-/*
- * Multicast filter register (lower 32 bits)
- */
-#define AR5K_MCAST_FILTER0_5210        0x8050
-#define AR5K_MCAST_FILTER0_5211        0x8040
-#define AR5K_MCAST_FILTER0     (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_MCAST_FILTER0_5210 : AR5K_MCAST_FILTER0_5211)
-
-/*
- * Multicast filter register (higher 16 bits)
- */
-#define AR5K_MCAST_FILTER1_5210        0x8054
-#define AR5K_MCAST_FILTER1_5211        0x8044
-#define AR5K_MCAST_FILTER1     (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_MCAST_FILTER1_5210 : AR5K_MCAST_FILTER1_5211)
-
-
-/*
- * Transmit mask register (lower 32 bits) [5210]
- */
-#define AR5K_TX_MASK0  0x8058
-
-/*
- * Transmit mask register (higher 16 bits) [5210]
- */
-#define AR5K_TX_MASK1  0x805c
-
-/*
- * Clear transmit mask [5210]
- */
-#define AR5K_CLR_TMASK 0x8060
-
-/*
- * Trigger level register (before transmission) [5210]
- */
-#define AR5K_TRIG_LVL  0x8064
-
-
-/*
- * PCU control register
- *
- * Only DIS_RX is used in the code, the rest i guess are
- * for tweaking/diagnostics.
- */
-#define AR5K_DIAG_SW_5210              0x8068                  /* Register Address [5210] */
-#define AR5K_DIAG_SW_5211              0x8048                  /* Register Address [5211+] */
-#define AR5K_DIAG_SW                   (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_5210 : AR5K_DIAG_SW_5211)
-#define AR5K_DIAG_SW_DIS_WEP_ACK       0x00000001      /* Disable ACKs if WEP key is invalid */
-#define AR5K_DIAG_SW_DIS_ACK           0x00000002      /* Disable ACKs */
-#define AR5K_DIAG_SW_DIS_CTS           0x00000004      /* Disable CTSs */
-#define AR5K_DIAG_SW_DIS_ENC           0x00000008      /* Disable encryption */
-#define AR5K_DIAG_SW_DIS_DEC           0x00000010      /* Disable decryption */
-#define AR5K_DIAG_SW_DIS_TX            0x00000020      /* Disable transmit [5210] */
-#define AR5K_DIAG_SW_DIS_RX_5210       0x00000040      /* Disable recieve */
-#define AR5K_DIAG_SW_DIS_RX_5211       0x00000020
-#define        AR5K_DIAG_SW_DIS_RX             (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211)
-#define AR5K_DIAG_SW_LOOP_BACK_5210    0x00000080      /* Loopback (i guess it goes with DIS_TX) [5210] */
-#define AR5K_DIAG_SW_LOOP_BACK_5211    0x00000040
-#define AR5K_DIAG_SW_LOOP_BACK         (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211)
-#define AR5K_DIAG_SW_CORR_FCS_5210     0x00000100      /* Corrupted FCS */
-#define AR5K_DIAG_SW_CORR_FCS_5211     0x00000080
-#define AR5K_DIAG_SW_CORR_FCS          (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211)
-#define AR5K_DIAG_SW_CHAN_INFO_5210    0x00000200      /* Dump channel info */
-#define AR5K_DIAG_SW_CHAN_INFO_5211    0x00000100
-#define AR5K_DIAG_SW_CHAN_INFO         (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211)
-#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210        0x00000400      /* Enable fixed scrambler seed */
-#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211        0x00000200
-#define AR5K_DIAG_SW_EN_SCRAM_SEED     (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211)
-#define AR5K_DIAG_SW_ECO_ENABLE                0x00000400      /* [5211+] */
-#define AR5K_DIAG_SW_SCVRAM_SEED       0x0003f800      /* [5210] */
-#define AR5K_DIAG_SW_SCRAM_SEED_M      0x0001fc00      /* Scrambler seed mask */
-#define AR5K_DIAG_SW_SCRAM_SEED_S      10
-#define AR5K_DIAG_SW_DIS_SEQ_INC       0x00040000      /* Disable seqnum increment (?)[5210] */
-#define AR5K_DIAG_SW_FRAME_NV0_5210    0x00080000
-#define AR5K_DIAG_SW_FRAME_NV0_5211    0x00020000      /* Accept frames of non-zero protocol number */
-#define        AR5K_DIAG_SW_FRAME_NV0          (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211)
-#define AR5K_DIAG_SW_OBSPT_M           0x000c0000      /* Observation point select (?) */
-#define AR5K_DIAG_SW_OBSPT_S           18
-#define AR5K_DIAG_SW_RX_CLEAR_HIGH     0x0010000       /* Force RX Clear high */
-#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000       /* Ignore virtual carrier sense */
-#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH  0x0040000       /* Force channel idle high */
-#define AR5K_DIAG_SW_PHEAR_ME          0x0080000       /* ??? */
-
-/*
- * TSF (clock) register (lower 32 bits)
- */
-#define AR5K_TSF_L32_5210      0x806c
-#define AR5K_TSF_L32_5211      0x804c
-#define        AR5K_TSF_L32            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
-
-/*
- * TSF (clock) register (higher 32 bits)
- */
-#define AR5K_TSF_U32_5210      0x8070
-#define AR5K_TSF_U32_5211      0x8050
-#define        AR5K_TSF_U32            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
-
-/*
- * Last beacon timestamp register (Read Only)
- */
-#define AR5K_LAST_TSTP 0x8080
-
-/*
- * ADDAC test register [5211+]
- */
-#define AR5K_ADDAC_TEST                        0x8054                  /* Register Address */
-#define AR5K_ADDAC_TEST_TXCONT                 0x00000001      /* Test continuous tx */
-#define AR5K_ADDAC_TEST_TST_MODE       0x00000002      /* Test mode */
-#define AR5K_ADDAC_TEST_LOOP_EN                0x00000004      /* Enable loop */
-#define AR5K_ADDAC_TEST_LOOP_LEN       0x00000008      /* Loop length (field) */
-#define AR5K_ADDAC_TEST_USE_U8         0x00004000      /* Use upper 8 bits */
-#define AR5K_ADDAC_TEST_MSB            0x00008000      /* State of MSB */
-#define AR5K_ADDAC_TEST_TRIG_SEL       0x00010000      /* Trigger select */
-#define AR5K_ADDAC_TEST_TRIG_PTY       0x00020000      /* Trigger polarity */
-#define AR5K_ADDAC_TEST_RXCONT         0x00040000      /* Continuous capture */
-#define AR5K_ADDAC_TEST_CAPTURE                0x00080000      /* Begin capture */
-#define AR5K_ADDAC_TEST_TST_ARM                0x00100000      /* ARM rx buffer for capture */
-
-/*
- * Default antenna register [5211+]
- */
-#define AR5K_DEFAULT_ANTENNA   0x8058
-
-/*
- * Frame control QoS mask register (?) [5211+]
- * (FC_QOS_MASK)
- */
-#define AR5K_FRAME_CTL_QOSM    0x805c
-
-/*
- * Seq mask register (?) [5211+]
- */
-#define AR5K_SEQ_MASK  0x8060
-
-/*
- * Retry count register [5210]
- */
-#define AR5K_RETRY_CNT         0x8084                  /* Register Address [5210] */
-#define AR5K_RETRY_CNT_SSH     0x0000003f      /* Station short retry count (?) */
-#define AR5K_RETRY_CNT_SLG     0x00000fc0      /* Station long retry count (?) */
-
-/*
- * Back-off status register [5210]
- */
-#define AR5K_BACKOFF           0x8088                  /* Register Address [5210] */
-#define AR5K_BACKOFF_CW                0x000003ff      /* Backoff Contention Window (?) */
-#define AR5K_BACKOFF_CNT       0x03ff0000      /* Backoff count (?) */
-
-
-
-/*
- * NAV register (current)
- */
-#define AR5K_NAV_5210          0x808c
-#define AR5K_NAV_5211          0x8084
-#define        AR5K_NAV                (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_NAV_5210 : AR5K_NAV_5211)
-
-/*
- * RTS success register
- */
-#define AR5K_RTS_OK_5210       0x8090
-#define AR5K_RTS_OK_5211       0x8088
-#define        AR5K_RTS_OK             (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211)
-
-/*
- * RTS failure register
- */
-#define AR5K_RTS_FAIL_5210     0x8094
-#define AR5K_RTS_FAIL_5211     0x808c
-#define        AR5K_RTS_FAIL           (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211)
-
-/*
- * ACK failure register
- */
-#define AR5K_ACK_FAIL_5210     0x8098
-#define AR5K_ACK_FAIL_5211     0x8090
-#define        AR5K_ACK_FAIL           (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211)
-
-/*
- * FCS failure register
- */
-#define AR5K_FCS_FAIL_5210     0x809c
-#define AR5K_FCS_FAIL_5211     0x8094
-#define        AR5K_FCS_FAIL           (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_FCS_FAIL_5210 : AR5K_FCS_FAIL_5211)
-
-/*
- * Beacon count register
- */
-#define AR5K_BEACON_CNT_5210   0x80a0
-#define AR5K_BEACON_CNT_5211   0x8098
-#define        AR5K_BEACON_CNT         (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_BEACON_CNT_5210 : AR5K_BEACON_CNT_5211)
-
-
-/*===5212 Specific PCU registers===*/
-
-/*
- * Transmit power control register
- */
-#define AR5K_TPC                       0x80e8
-#define AR5K_TPC_ACK                   0x0000003f      /* ack frames */
-#define AR5K_TPC_ACK_S                 0
-#define AR5K_TPC_CTS                   0x00003f00      /* cts frames */
-#define AR5K_TPC_CTS_S                 8
-#define AR5K_TPC_CHIRP                 0x003f0000      /* chirp frames */
-#define AR5K_TPC_CHIRP_S               16
-#define AR5K_TPC_DOPPLER               0x0f000000      /* doppler chirp span */
-#define AR5K_TPC_DOPPLER_S             24
-
-/*
- * XR (eXtended Range) mode register
- */
-#define AR5K_XRMODE                    0x80c0                  /* Register Address */
-#define        AR5K_XRMODE_POLL_TYPE_M         0x0000003f      /* Mask for Poll type (?) */
-#define        AR5K_XRMODE_POLL_TYPE_S         0
-#define        AR5K_XRMODE_POLL_SUBTYPE_M      0x0000003c      /* Mask for Poll subtype (?) */
-#define        AR5K_XRMODE_POLL_SUBTYPE_S      2
-#define        AR5K_XRMODE_POLL_WAIT_ALL       0x00000080      /* Wait for poll */
-#define        AR5K_XRMODE_SIFS_DELAY          0x000fff00      /* Mask for SIFS delay */
-#define        AR5K_XRMODE_FRAME_HOLD_M        0xfff00000      /* Mask for frame hold (?) */
-#define        AR5K_XRMODE_FRAME_HOLD_S        20
-
-/*
- * XR delay register
- */
-#define AR5K_XRDELAY                   0x80c4                  /* Register Address */
-#define AR5K_XRDELAY_SLOT_DELAY_M      0x0000ffff      /* Mask for slot delay */
-#define AR5K_XRDELAY_SLOT_DELAY_S      0
-#define AR5K_XRDELAY_CHIRP_DELAY_M     0xffff0000      /* Mask for CHIRP data delay */
-#define AR5K_XRDELAY_CHIRP_DELAY_S     16
-
-/*
- * XR timeout register
- */
-#define AR5K_XRTIMEOUT                 0x80c8                  /* Register Address */
-#define AR5K_XRTIMEOUT_CHIRP_M         0x0000ffff      /* Mask for CHIRP timeout */
-#define AR5K_XRTIMEOUT_CHIRP_S         0
-#define AR5K_XRTIMEOUT_POLL_M          0xffff0000      /* Mask for Poll timeout */
-#define AR5K_XRTIMEOUT_POLL_S          16
-
-/*
- * XR chirp register
- */
-#define AR5K_XRCHIRP                   0x80cc                  /* Register Address */
-#define AR5K_XRCHIRP_SEND              0x00000001      /* Send CHIRP */
-#define AR5K_XRCHIRP_GAP               0xffff0000      /* Mask for CHIRP gap (?) */
-
-/*
- * XR stomp register
- */
-#define AR5K_XRSTOMP                   0x80d0                  /* Register Address */
-#define AR5K_XRSTOMP_TX                        0x00000001      /* Stomp Tx (?) */
-#define AR5K_XRSTOMP_RX                        0x00000002      /* Stomp Rx (?) */
-#define AR5K_XRSTOMP_TX_RSSI           0x00000004      /* Stomp Tx RSSI (?) */
-#define AR5K_XRSTOMP_TX_BSSID          0x00000008      /* Stomp Tx BSSID (?) */
-#define AR5K_XRSTOMP_DATA              0x00000010      /* Stomp data (?)*/
-#define AR5K_XRSTOMP_RSSI_THRES                0x0000ff00      /* Mask for XR RSSI threshold */
-
-/*
- * First enhanced sleep register
- */
-#define AR5K_SLEEP0                    0x80d4                  /* Register Address */
-#define AR5K_SLEEP0_NEXT_DTIM          0x0007ffff      /* Mask for next DTIM (?) */
-#define AR5K_SLEEP0_NEXT_DTIM_S                0
-#define AR5K_SLEEP0_ASSUME_DTIM                0x00080000      /* Assume DTIM */
-#define AR5K_SLEEP0_ENH_SLEEP_EN       0x00100000      /* Enable enchanced sleep control */
-#define AR5K_SLEEP0_CABTO              0xff000000      /* Mask for CAB Time Out */
-#define AR5K_SLEEP0_CABTO_S            24
-
-/*
- * Second enhanced sleep register
- */
-#define AR5K_SLEEP1                    0x80d8                  /* Register Address */
-#define AR5K_SLEEP1_NEXT_TIM           0x0007ffff      /* Mask for next TIM (?) */
-#define AR5K_SLEEP1_NEXT_TIM_S         0
-#define AR5K_SLEEP1_BEACON_TO          0xff000000      /* Mask for Beacon Time Out */
-#define AR5K_SLEEP1_BEACON_TO_S                24
-
-/*
- * Third enhanced sleep register
- */
-#define AR5K_SLEEP2                    0x80dc                  /* Register Address */
-#define AR5K_SLEEP2_TIM_PER            0x0000ffff      /* Mask for TIM period (?) */
-#define AR5K_SLEEP2_TIM_PER_S          0
-#define AR5K_SLEEP2_DTIM_PER           0xffff0000      /* Mask for DTIM period (?) */
-#define AR5K_SLEEP2_DTIM_PER_S         16
-
-/*
- * BSSID mask registers
- */
-#define AR5K_BSS_IDM0                  0x80e0  /* Upper bits */
-#define AR5K_BSS_IDM1                  0x80e4  /* Lower bits */
-
-/*
- * TX power control (TPC) register
- *
- * XXX: PCDAC steps (0.5dbm) or DBM ?
- *
- */
-#define AR5K_TXPC                      0x80e8                  /* Register Address */
-#define AR5K_TXPC_ACK_M                        0x0000003f      /* ACK tx power */
-#define AR5K_TXPC_ACK_S                        0
-#define AR5K_TXPC_CTS_M                        0x00003f00      /* CTS tx power */
-#define AR5K_TXPC_CTS_S                        8
-#define AR5K_TXPC_CHIRP_M              0x003f0000      /* CHIRP tx power */
-#define AR5K_TXPC_CHIRP_S              16
-#define AR5K_TXPC_DOPPLER              0x0f000000      /* Doppler chirp span (?) */
-#define AR5K_TXPC_DOPPLER_S            24
-
-/*
- * Profile count registers
- */
-#define AR5K_PROFCNT_TX                        0x80ec  /* Tx count */
-#define AR5K_PROFCNT_RX                        0x80f0  /* Rx count */
-#define AR5K_PROFCNT_RXCLR             0x80f4  /* Clear Rx count */
-#define AR5K_PROFCNT_CYCLE             0x80f8  /* Cycle count (?) */
-
-/*
- * Quiet period control registers
- */
-#define AR5K_QUIET_CTL1                        0x80fc                  /* Register Address */
-#define AR5K_QUIET_CTL1_NEXT_QT_TSF    0x0000ffff      /* Next quiet period TSF (TU) */
-#define AR5K_QUIET_CTL1_NEXT_QT_TSF_S  0
-#define AR5K_QUIET_CTL1_QT_EN          0x00010000      /* Enable quiet period */
-#define AR5K_QUIET_CTL1_ACK_CTS_EN     0x00020000      /* Send ACK/CTS during quiet period */
-
-#define AR5K_QUIET_CTL2                        0x8100                  /* Register Address */
-#define AR5K_QUIET_CTL2_QT_PER         0x0000ffff      /* Mask for quiet period periodicity */
-#define AR5K_QUIET_CTL2_QT_PER_S       0
-#define AR5K_QUIET_CTL2_QT_DUR         0xffff0000      /* Mask for quiet period duration */
-#define AR5K_QUIET_CTL2_QT_DUR_S       16
-
-/*
- * TSF parameter register
- */
-#define AR5K_TSF_PARM                  0x8104                  /* Register Address */
-#define AR5K_TSF_PARM_INC              0x000000ff      /* Mask for TSF increment */
-#define AR5K_TSF_PARM_INC_S            0
-
-/*
- * QoS NOACK policy
- */
-#define AR5K_QOS_NOACK                 0x8108                  /* Register Address */
-#define AR5K_QOS_NOACK_2BIT_VALUES     0x0000000f      /* ??? */
-#define AR5K_QOS_NOACK_2BIT_VALUES_S   0
-#define AR5K_QOS_NOACK_BIT_OFFSET      0x00000070      /* ??? */
-#define AR5K_QOS_NOACK_BIT_OFFSET_S    4
-#define AR5K_QOS_NOACK_BYTE_OFFSET     0x00000180      /* ??? */
-#define AR5K_QOS_NOACK_BYTE_OFFSET_S   7
-
-/*
- * PHY error filter register
- */
-#define AR5K_PHY_ERR_FIL               0x810c
-#define AR5K_PHY_ERR_FIL_RADAR         0x00000020      /* Radar signal */
-#define AR5K_PHY_ERR_FIL_OFDM          0x00020000      /* OFDM false detect (ANI) */
-#define AR5K_PHY_ERR_FIL_CCK           0x02000000      /* CCK false detect (ANI) */
-
-/*
- * XR latency register
- */
-#define AR5K_XRLAT_TX          0x8110
-
-/*
- * ACK SIFS register
- */
-#define AR5K_ACKSIFS           0x8114                  /* Register Address */
-#define AR5K_ACKSIFS_INC       0x00000000      /* ACK SIFS Increment (field) */
-
-/*
- * MIC QoS control register (?)
- */
-#define        AR5K_MIC_QOS_CTL                0x8118                  /* Register Address */
-#define        AR5K_MIC_QOS_CTL_OFF(_n)        (1 << (_n * 2))
-#define        AR5K_MIC_QOS_CTL_MQ_EN          0x00010000      /* Enable MIC QoS */
-
-/*
- * MIC QoS select register (?)
- */
-#define        AR5K_MIC_QOS_SEL                0x811c
-#define        AR5K_MIC_QOS_SEL_OFF(_n)        (1 << (_n * 4))
-
-/*
- * Misc mode control register (?)
- */
-#define        AR5K_MISC_MODE                  0x8120                  /* Register Address */
-#define        AR5K_MISC_MODE_FBSSID_MATCH     0x00000001      /* Force BSSID match */
-#define        AR5K_MISC_MODE_ACKSIFS_MEM      0x00000002      /* ACK SIFS memory (?) */
-#define        AR5K_MISC_MODE_COMBINED_MIC     0x00000004      /* use rx/tx MIC key */
-/* more bits */
-
-/*
- * OFDM Filter counter
- */
-#define        AR5K_OFDM_FIL_CNT               0x8124
-
-/*
- * CCK Filter counter
- */
-#define        AR5K_CCK_FIL_CNT                0x8128
-
-/*
- * PHY Error Counters (?)
- */
-#define        AR5K_PHYERR_CNT1                0x812c
-#define        AR5K_PHYERR_CNT1_MASK           0x8130
-
-#define        AR5K_PHYERR_CNT2                0x8134
-#define        AR5K_PHYERR_CNT2_MASK           0x8138
-
-/*
- * TSF Threshold register (?)
- */
-#define        AR5K_TSF_THRES                  0x813c
-
-/*
- * TODO: Wake On Wireless registers
- * Range: 0x8147 - 0x818c
- */
-
-/*
- * Rate -> ACK SIFS mapping table (32 entries)
- */
-#define        AR5K_RATE_ACKSIFS_BASE          0x8680                  /* Register Address */
-#define        AR5K_RATE_ACKSIFS(_n)           (AR5K_RATE_ACKSIFS_BSE + ((_n) << 2))
-#define        AR5K_RATE_ACKSIFS_NORMAL        0x00000001      /* Normal SIFS (field) */
-#define        AR5K_RATE_ACKSIFS_TURBO         0x00000400      /* Turbo SIFS (field) */
-
-/*
- * Rate -> duration mapping table (32 entries)
- */
-#define AR5K_RATE_DUR_BASE             0x8700
-#define AR5K_RATE_DUR(_n)              (AR5K_RATE_DUR_BASE + ((_n) << 2))
-
-/*
- * Rate -> db mapping table
- * (8 entries, each one has 4 8bit fields)
- */
-#define AR5K_RATE2DB_BASE              0x87c0
-#define AR5K_RATE2DB(_n)               (AR5K_RATE2DB_BASE + ((_n) << 2))
-
-/*
- * db -> Rate mapping table
- * (8 entries, each one has 4 8bit fields)
- */
-#define AR5K_DB2RATE_BASE              0x87e0
-#define AR5K_DB2RATE(_n)               (AR5K_DB2RATE_BASE + ((_n) << 2))
-
-/*===5212 end===*/
-
-/*
- * Key table (WEP) register
- */
-#define AR5K_KEYTABLE_0_5210           0x9000
-#define AR5K_KEYTABLE_0_5211           0x8800
-#define AR5K_KEYTABLE_5210(_n)         (AR5K_KEYTABLE_0_5210 + ((_n) << 5))
-#define AR5K_KEYTABLE_5211(_n)         (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
-#define        AR5K_KEYTABLE(_n)               (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n))
-#define AR5K_KEYTABLE_OFF(_n, x)       (AR5K_KEYTABLE(_n) + (x << 2))
-#define AR5K_KEYTABLE_TYPE(_n)         AR5K_KEYTABLE_OFF(_n, 5)
-#define AR5K_KEYTABLE_TYPE_40          0x00000000
-#define AR5K_KEYTABLE_TYPE_104         0x00000001
-#define AR5K_KEYTABLE_TYPE_128         0x00000003
-#define AR5K_KEYTABLE_TYPE_TKIP                0x00000004      /* [5212+] */
-#define AR5K_KEYTABLE_TYPE_AES         0x00000005      /* [5211+] */
-#define AR5K_KEYTABLE_TYPE_CCM         0x00000006      /* [5212+] */
-#define AR5K_KEYTABLE_TYPE_NULL                0x00000007      /* [5211+] */
-#define AR5K_KEYTABLE_ANTENNA          0x00000008      /* [5212+] */
-#define AR5K_KEYTABLE_MAC0(_n)         AR5K_KEYTABLE_OFF(_n, 6)
-#define AR5K_KEYTABLE_MAC1(_n)         AR5K_KEYTABLE_OFF(_n, 7)
-#define AR5K_KEYTABLE_VALID            0x00008000
-
-/* If key type is TKIP and MIC is enabled
- * MIC key goes in offset entry + 64 */
-#define        AR5K_KEYTABLE_MIC_OFFSET        64
-
-/* WEP 40-bit  = 40-bit  entered key + 24 bit IV = 64-bit
- * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit
- * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit
- *
- * Some vendors have introduced bigger WEP keys to address
- * security vulnerabilities in WEP. This includes:
- *
- * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit
- *
- * We can expand this if we find ar5k Atheros cards with a larger
- * key table size.
- */
-#define AR5K_KEYTABLE_SIZE_5210                64
-#define AR5K_KEYTABLE_SIZE_5211                128
-#define        AR5K_KEYTABLE_SIZE              (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211)
-
-
-/*===PHY REGISTERS===*/
-
-/*
- * PHY registers start
- */
-#define        AR5K_PHY_BASE                   0x9800
-#define        AR5K_PHY(_n)                    (AR5K_PHY_BASE + ((_n) << 2))
-
-/*
- * TST_2 (Misc config parameters)
- */
-#define        AR5K_PHY_TST2                   0x9800                  /* Register Address */
-#define AR5K_PHY_TST2_TRIG_SEL         0x00000007      /* Trigger select (?)*/
-#define AR5K_PHY_TST2_TRIG             0x00000010      /* Trigger (?) */
-#define AR5K_PHY_TST2_CBUS_MODE                0x00000060      /* Cardbus mode (?) */
-#define AR5K_PHY_TST2_CLK32            0x00000400      /* CLK_OUT is CLK32 (32Khz external) */
-#define AR5K_PHY_TST2_CHANCOR_DUMP_EN  0x00000800      /* Enable Chancor dump (?) */
-#define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP        0x00001000      /* Even Chancor dump (?) */
-#define AR5K_PHY_TST2_RFSILENT_EN      0x00002000      /* Enable RFSILENT */
-#define AR5K_PHY_TST2_ALT_RFDATA       0x00004000      /* Alternate RFDATA (5-2GHz switch ?) */
-#define AR5K_PHY_TST2_MINI_OBS_EN      0x00008000      /* Enable mini OBS (?) */
-#define AR5K_PHY_TST2_RX2_IS_RX5_INV   0x00010000      /* 2GHz rx path is the 5GHz path inverted (?) */
-#define AR5K_PHY_TST2_SLOW_CLK160      0x00020000      /* Slow CLK160 (?) */
-#define AR5K_PHY_TST2_AGC_OBS_SEL_3    0x00040000      /* AGC OBS Select 3 (?) */
-#define AR5K_PHY_TST2_BBB_OBS_SEL      0x00080000      /* BB OBS Select (field ?) */
-#define AR5K_PHY_TST2_ADC_OBS_SEL      0x00800000      /* ADC OBS Select (field ?) */
-#define AR5K_PHY_TST2_RX_CLR_SEL       0x08000000      /* RX Clear Select (?) */
-#define AR5K_PHY_TST2_FORCE_AGC_CLR    0x10000000      /* Force AGC clear (?) */
-#define AR5K_PHY_SHIFT_2GHZ            0x00004007      /* Used to access 2GHz radios */
-#define AR5K_PHY_SHIFT_5GHZ            0x00000007      /* Used to access 5GHz radios (default) */
-
-/*
- * PHY frame control register [5110] /turbo mode register [5111+]
- *
- * There is another frame control register for [5111+]
- * at address 0x9944 (see below) but the 2 first flags
- * are common here between 5110 frame control register
- * and [5111+] turbo mode register, so this also works as
- * a "turbo mode register" for 5110. We treat this one as
- * a frame control register for 5110 below.
- */
-#define        AR5K_PHY_TURBO                  0x9804                  /* Register Address */
-#define        AR5K_PHY_TURBO_MODE             0x00000001      /* Enable turbo mode */
-#define        AR5K_PHY_TURBO_SHORT            0x00000002      /* Set short symbols to turbo mode */
-#define        AR5K_PHY_TURBO_MIMO             0x00000004      /* Set turbo for mimo mimo */
-
-/*
- * PHY agility command register
- * (aka TST_1)
- */
-#define        AR5K_PHY_AGC                    0x9808                  /* Register Address */
-#define        AR5K_PHY_TST1                   0x9808
-#define        AR5K_PHY_AGC_DISABLE            0x08000000      /* Disable AGC to A2 (?)*/
-#define        AR5K_PHY_TST1_TXHOLD            0x00003800      /* Set tx hold (?) */
-#define        AR5K_PHY_TST1_TXSRC_SRC         0x00000002      /* Used with bit 7 (?) */
-#define        AR5K_PHY_TST1_TXSRC_SRC_S       1
-#define        AR5K_PHY_TST1_TXSRC_ALT         0x00000080      /* Set input to tsdac (?) */
-#define        AR5K_PHY_TST1_TXSRC_ALT_S       7
-
-
-/*
- * PHY timing register 3 [5112+]
- */
-#define        AR5K_PHY_TIMING_3               0x9814
-#define        AR5K_PHY_TIMING_3_DSC_MAN       0xfffe0000
-#define        AR5K_PHY_TIMING_3_DSC_MAN_S     17
-#define        AR5K_PHY_TIMING_3_DSC_EXP       0x0001e000
-#define        AR5K_PHY_TIMING_3_DSC_EXP_S     13
-
-/*
- * PHY chip revision register
- */
-#define        AR5K_PHY_CHIP_ID                0x9818
-
-/*
- * PHY activation register
- */
-#define        AR5K_PHY_ACT                    0x981c                  /* Register Address */
-#define        AR5K_PHY_ACT_ENABLE             0x00000001      /* Activate PHY */
-#define        AR5K_PHY_ACT_DISABLE            0x00000002      /* Deactivate PHY */
-
-/*
- * PHY RF control registers
- */
-#define AR5K_PHY_RF_CTL2               0x9824                  /* Register Address */
-#define        AR5K_PHY_RF_CTL2_TXF2TXD_START  0x0000000f      /* TX frame to TX data start */
-#define        AR5K_PHY_RF_CTL2_TXF2TXD_START_S        0
-
-#define AR5K_PHY_RF_CTL3               0x9828                  /* Register Address */
-#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON   0x0000ff00      /* TX end to XLNA on */
-#define        AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S  8
-
-#define        AR5K_PHY_ADC_CTL                        0x982c
-#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF          0x00000003
-#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S        0
-#define        AR5K_PHY_ADC_CTL_PWD_DAC_OFF            0x00002000
-#define        AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF       0x00004000
-#define        AR5K_PHY_ADC_CTL_PWD_ADC_OFF            0x00008000
-#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON           0x00030000
-#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S         16
-
-#define AR5K_PHY_RF_CTL4               0x9834                  /* Register Address */
-#define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON  0x00000001      /* TX frame to XPA A on (field) */
-#define AR5K_PHY_RF_CTL4_TXF2XPA_B_ON  0x00000100      /* TX frame to XPA B on (field) */
-#define        AR5K_PHY_RF_CTL4_TXE2XPA_A_OFF  0x00010000      /* TX end to XPA A off (field) */
-#define AR5K_PHY_RF_CTL4_TXE2XPA_B_OFF 0x01000000      /* TX end to XPA B off (field) */
-
-/*
- * Pre-Amplifier control register
- * (XPA -> external pre-amplifier)
- */
-#define        AR5K_PHY_PA_CTL                 0x9838                  /* Register Address */
-#define        AR5K_PHY_PA_CTL_XPA_A_HI        0x00000001      /* XPA A high (?) */
-#define        AR5K_PHY_PA_CTL_XPA_B_HI        0x00000002      /* XPA B high (?) */
-#define        AR5K_PHY_PA_CTL_XPA_A_EN        0x00000004      /* Enable XPA A */
-#define        AR5K_PHY_PA_CTL_XPA_B_EN        0x00000008      /* Enable XPA B */
-
-/*
- * PHY settling register
- */
-#define AR5K_PHY_SETTLING              0x9844                  /* Register Address */
-#define        AR5K_PHY_SETTLING_AGC           0x0000007f      /* AGC settling time */
-#define        AR5K_PHY_SETTLING_AGC_S         0
-#define        AR5K_PHY_SETTLING_SWITCH        0x00003f80      /* Switch settlig time */
-#define        AR5K_PHY_SETTLING_SWITCH_S      7
-
-/*
- * PHY Gain registers
- */
-#define AR5K_PHY_GAIN                  0x9848                  /* Register Address */
-#define        AR5K_PHY_GAIN_TXRX_ATTEN        0x0003f000      /* TX-RX Attenuation */
-#define        AR5K_PHY_GAIN_TXRX_ATTEN_S      12
-#define        AR5K_PHY_GAIN_TXRX_RF_MAX       0x007c0000
-#define        AR5K_PHY_GAIN_TXRX_RF_MAX_S     18
-
-#define        AR5K_PHY_GAIN_OFFSET            0x984c                  /* Register Address */
-#define        AR5K_PHY_GAIN_OFFSET_RXTX_FLAG  0x00020000      /* RX-TX flag (?) */
-
-/*
- * Desired ADC/PGA size register
- * (for more infos read ANI patent)
- */
-#define AR5K_PHY_DESIRED_SIZE          0x9850                  /* Register Address */
-#define        AR5K_PHY_DESIRED_SIZE_ADC       0x000000ff      /* ADC desired size */
-#define        AR5K_PHY_DESIRED_SIZE_ADC_S     0
-#define        AR5K_PHY_DESIRED_SIZE_PGA       0x0000ff00      /* PGA desired size */
-#define        AR5K_PHY_DESIRED_SIZE_PGA_S     8
-#define        AR5K_PHY_DESIRED_SIZE_TOT       0x0ff00000      /* Total desired size */
-#define        AR5K_PHY_DESIRED_SIZE_TOT_S     20
-
-/*
- * PHY signal register
- * (for more infos read ANI patent)
- */
-#define        AR5K_PHY_SIG                    0x9858                  /* Register Address */
-#define        AR5K_PHY_SIG_FIRSTEP            0x0003f000      /* FIRSTEP */
-#define        AR5K_PHY_SIG_FIRSTEP_S          12
-#define        AR5K_PHY_SIG_FIRPWR             0x03fc0000      /* FIPWR */
-#define        AR5K_PHY_SIG_FIRPWR_S           18
-
-/*
- * PHY coarse agility control register
- * (for more infos read ANI patent)
- */
-#define        AR5K_PHY_AGCCOARSE              0x985c                  /* Register Address */
-#define        AR5K_PHY_AGCCOARSE_LO           0x00007f80      /* AGC Coarse low */
-#define        AR5K_PHY_AGCCOARSE_LO_S         7
-#define        AR5K_PHY_AGCCOARSE_HI           0x003f8000      /* AGC Coarse high */
-#define        AR5K_PHY_AGCCOARSE_HI_S         15
-
-/*
- * PHY agility control register
- */
-#define        AR5K_PHY_AGCCTL                 0x9860                  /* Register address */
-#define        AR5K_PHY_AGCCTL_CAL             0x00000001      /* Enable PHY calibration */
-#define        AR5K_PHY_AGCCTL_NF              0x00000002      /* Enable Noise Floor calibration */
-#define        AR5K_PHY_AGCCTL_NF_EN           0x00008000      /* Enable nf calibration to happen (?) */
-#define        AR5K_PHY_AGCCTL_NF_NOUPDATE     0x00020000      /* Don't update nf automaticaly */
-
-/*
- * PHY noise floor status register
- */
-#define AR5K_PHY_NF                    0x9864                  /* Register address */
-#define AR5K_PHY_NF_M                  0x000001ff      /* Noise floor mask */
-#define AR5K_PHY_NF_ACTIVE             0x00000100      /* Noise floor calibration still active */
-#define AR5K_PHY_NF_RVAL(_n)           (((_n) >> 19) & AR5K_PHY_NF_M)
-#define AR5K_PHY_NF_AVAL(_n)           (-((_n) ^ AR5K_PHY_NF_M) + 1)
-#define AR5K_PHY_NF_SVAL(_n)           (((_n) & AR5K_PHY_NF_M) | (1 << 9))
-#define        AR5K_PHY_NF_THRESH62            0x0007f000      /* Thresh62 -check ANI patent- (field) */
-#define        AR5K_PHY_NF_THRESH62_S          12
-#define        AR5K_PHY_NF_MINCCA_PWR          0x0ff80000      /* ??? */
-#define        AR5K_PHY_NF_MINCCA_PWR_S        19
-
-/*
- * PHY ADC saturation register [5110]
- */
-#define        AR5K_PHY_ADCSAT                 0x9868
-#define        AR5K_PHY_ADCSAT_ICNT            0x0001f800
-#define        AR5K_PHY_ADCSAT_ICNT_S          11
-#define        AR5K_PHY_ADCSAT_THR             0x000007e0
-#define        AR5K_PHY_ADCSAT_THR_S           5
-
-/*
- * PHY Weak ofdm signal detection threshold registers (ANI) [5212+]
- */
-
-/* High thresholds */
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR            0x9868
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT   0x0000001f
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT_S 0
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1         0x00fe0000
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1_S       17
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2         0x7f000000
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S       24
-
-/* Low thresholds */
-#define AR5K_PHY_WEAK_OFDM_LOW_THR             0x986c
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN  0x00000001
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT    0x00003f00
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S  8
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1          0x001fc000
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1_S                14
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2          0x0fe00000
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_S                21
-
-
-/*
- * PHY sleep registers [5112+]
- */
-#define AR5K_PHY_SCR                   0x9870
-
-#define AR5K_PHY_SLMT                  0x9874
-#define AR5K_PHY_SLMT_32MHZ            0x0000007f
-
-#define AR5K_PHY_SCAL                  0x9878
-#define AR5K_PHY_SCAL_32MHZ            0x0000000e
-#define        AR5K_PHY_SCAL_32MHZ_2417        0x0000000a
-#define        AR5K_PHY_SCAL_32MHZ_HB63        0x00000032
-
-/*
- * PHY PLL (Phase Locked Loop) control register
- */
-#define        AR5K_PHY_PLL                    0x987c
-#define        AR5K_PHY_PLL_20MHZ              0x00000013      /* For half rate (?) */
-/* 40MHz -> 5GHz band */
-#define        AR5K_PHY_PLL_40MHZ_5211         0x00000018
-#define        AR5K_PHY_PLL_40MHZ_5212         0x000000aa
-#define        AR5K_PHY_PLL_40MHZ_5413         0x00000004
-#define        AR5K_PHY_PLL_40MHZ              (ah->ah_version == AR5K_AR5211 ? \
-                                       AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212)
-/* 44MHz -> 2.4GHz band */
-#define        AR5K_PHY_PLL_44MHZ_5211         0x00000019
-#define        AR5K_PHY_PLL_44MHZ_5212         0x000000ab
-#define        AR5K_PHY_PLL_44MHZ              (ah->ah_version == AR5K_AR5211 ? \
-                                       AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212)
-
-#define AR5K_PHY_PLL_RF5111            0x00000000
-#define AR5K_PHY_PLL_RF5112            0x00000040
-#define        AR5K_PHY_PLL_HALF_RATE          0x00000100
-#define        AR5K_PHY_PLL_QUARTER_RATE       0x00000200
-
-/*
- * RF Buffer register
- *
- * It's obvious from the code that 0x989c is the buffer register but
- * for the other special registers that we write to after sending each
- * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
- * for now. It's interesting that they are also used for some other operations.
- */
-
-#define AR5K_RF_BUFFER                 0x989c
-#define AR5K_RF_BUFFER_CONTROL_0       0x98c0  /* Channel on 5110 */
-#define AR5K_RF_BUFFER_CONTROL_1       0x98c4  /* Bank 7 on 5112 */
-#define AR5K_RF_BUFFER_CONTROL_2       0x98cc  /* Bank 7 on 5111 */
-
-#define AR5K_RF_BUFFER_CONTROL_3       0x98d0  /* Bank 2 on 5112 */
-                                               /* Channel set on 5111 */
-                                               /* Used to read radio revision*/
-
-#define AR5K_RF_BUFFER_CONTROL_4       0x98d4  /* RF Stage register on 5110 */
-                                               /* Bank 0,1,2,6 on 5111 */
-                                               /* Bank 1 on 5112 */
-                                               /* Used during activation on 5111 */
-
-#define AR5K_RF_BUFFER_CONTROL_5       0x98d8  /* Bank 3 on 5111 */
-                                               /* Used during activation on 5111 */
-                                               /* Channel on 5112 */
-                                               /* Bank 6 on 5112 */
-
-#define AR5K_RF_BUFFER_CONTROL_6       0x98dc  /* Bank 3 on 5112 */
-
-/*
- * PHY RF stage register [5210]
- */
-#define AR5K_PHY_RFSTG                 0x98d4
-#define AR5K_PHY_RFSTG_DISABLE         0x00000021
-
-/*
- * BIN masks (?)
- */
-#define        AR5K_PHY_BIN_MASK_1     0x9900
-#define        AR5K_PHY_BIN_MASK_2     0x9904
-#define        AR5K_PHY_BIN_MASK_3     0x9908
-
-#define        AR5K_PHY_BIN_MASK_CTL           0x990c
-#define        AR5K_PHY_BIN_MASK_CTL_MASK_4    0x00003fff
-#define        AR5K_PHY_BIN_MASK_CTL_MASK_4_S  0
-#define        AR5K_PHY_BIN_MASK_CTL_RATE      0xff000000
-#define        AR5K_PHY_BIN_MASK_CTL_RATE_S    24
-
-/*
- * PHY Antenna control register
- */
-#define AR5K_PHY_ANT_CTL               0x9910                  /* Register Address */
-#define        AR5K_PHY_ANT_CTL_TXRX_EN        0x00000001      /* Enable TX/RX (?) */
-#define        AR5K_PHY_ANT_CTL_SECTORED_ANT   0x00000004      /* Sectored Antenna */
-#define        AR5K_PHY_ANT_CTL_HITUNE5        0x00000008      /* Hitune5 (?) */
-#define        AR5K_PHY_ANT_CTL_SWTABLE_IDLE   0x000003f0      /* Switch table idle (?) */
-#define        AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4
-
-/*
- * PHY receiver delay register [5111+]
- */
-#define        AR5K_PHY_RX_DELAY               0x9914                  /* Register Address */
-#define        AR5K_PHY_RX_DELAY_M             0x00003fff      /* Mask for RX activate to receive delay (/100ns) */
-
-/*
- * PHY max rx length register (?) [5111]
- */
-#define        AR5K_PHY_MAX_RX_LEN             0x991c
-
-/*
- * PHY timing register 4
- * I(nphase)/Q(adrature) calibration register [5111+]
- */
-#define        AR5K_PHY_IQ                     0x9920                  /* Register Address */
-#define        AR5K_PHY_IQ_CORR_Q_Q_COFF       0x0000001f      /* Mask for q correction info */
-#define        AR5K_PHY_IQ_CORR_Q_I_COFF       0x000007e0      /* Mask for i correction info */
-#define        AR5K_PHY_IQ_CORR_Q_I_COFF_S     5
-#define        AR5K_PHY_IQ_CORR_ENABLE         0x00000800      /* Enable i/q correction */
-#define        AR5K_PHY_IQ_CAL_NUM_LOG_MAX     0x0000f000      /* Mask for max number of samples in log scale */
-#define        AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S   12
-#define        AR5K_PHY_IQ_RUN                 0x00010000      /* Run i/q calibration */
-#define        AR5K_PHY_IQ_USE_PT_DF           0x00020000      /* Use pilot track df (?) */
-#define        AR5K_PHY_IQ_EARLY_TRIG_THR      0x00200000      /* Early trigger threshold (?) (field) */
-#define        AR5K_PHY_IQ_PILOT_MASK_EN       0x10000000      /* Enable pilot mask (?) */
-#define        AR5K_PHY_IQ_CHAN_MASK_EN        0x20000000      /* Enable channel mask (?) */
-#define        AR5K_PHY_IQ_SPUR_FILT_EN        0x40000000      /* Enable spur filter */
-#define        AR5K_PHY_IQ_SPUR_RSSI_EN        0x80000000      /* Enable spur rssi */
-
-/*
- * PHY timing register 5
- * OFDM Self-correlator Cyclic RSSI threshold params
- * (Check out bb_cycpwr_thr1 on ANI patent)
- */
-#define        AR5K_PHY_OFDM_SELFCORR                  0x9924                  /* Register Address */
-#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN    0x00000001      /* Enable cyclic RSSI thr 1 */
-#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1       0x000000fe      /* Mask for Cyclic RSSI threshold 1 */
-#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S     1
-#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3       0x00000100      /* Cyclic RSSI threshold 3 (field) (?) */
-#define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN    0x00008000      /* Enable 1A RSSI threshold (?) */
-#define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR       0x00010000      /* 1A RSSI threshold (field) (?) */
-#define        AR5K_PHY_OFDM_SELFCORR_LSCTHR_HIRSSI    0x00800000      /* Long sc threshold hi rssi (?) */
-
-/*
- * PHY-only warm reset register
- */
-#define        AR5K_PHY_WARM_RESET             0x9928
-
-/*
- * PHY-only control register
- */
-#define AR5K_PHY_CTL                   0x992c                  /* Register Address */
-#define        AR5K_PHY_CTL_RX_DRAIN_RATE      0x00000001      /* RX drain rate (?) */
-#define        AR5K_PHY_CTL_LATE_TX_SIG_SYM    0x00000002      /* Late tx signal symbol (?) */
-#define        AR5K_PHY_CTL_GEN_SCRAMBLER      0x00000004      /* Generate scrambler */
-#define        AR5K_PHY_CTL_TX_ANT_SEL         0x00000008      /* TX antenna select */
-#define        AR5K_PHY_CTL_TX_ANT_STATIC      0x00000010      /* Static TX antenna */
-#define        AR5K_PHY_CTL_RX_ANT_SEL         0x00000020      /* RX antenna select */
-#define        AR5K_PHY_CTL_RX_ANT_STATIC      0x00000040      /* Static RX antenna */
-#define        AR5K_PHY_CTL_LOW_FREQ_SLE_EN    0x00000080      /* Enable low freq sleep */
-
-/*
- * PHY PAPD probe register [5111+]
- */
-#define        AR5K_PHY_PAPD_PROBE             0x9930
-#define        AR5K_PHY_PAPD_PROBE_SH_HI_PAR   0x00000001
-#define        AR5K_PHY_PAPD_PROBE_PCDAC_BIAS  0x00000002
-#define        AR5K_PHY_PAPD_PROBE_COMP_GAIN   0x00000040
-#define        AR5K_PHY_PAPD_PROBE_TXPOWER     0x00007e00
-#define        AR5K_PHY_PAPD_PROBE_TXPOWER_S   9
-#define        AR5K_PHY_PAPD_PROBE_TX_NEXT     0x00008000
-#define        AR5K_PHY_PAPD_PROBE_PREDIST_EN  0x00010000
-#define        AR5K_PHY_PAPD_PROBE_TYPE        0x01800000      /* [5112+] */
-#define        AR5K_PHY_PAPD_PROBE_TYPE_S      23
-#define        AR5K_PHY_PAPD_PROBE_TYPE_OFDM   0
-#define        AR5K_PHY_PAPD_PROBE_TYPE_XR     1
-#define        AR5K_PHY_PAPD_PROBE_TYPE_CCK    2
-#define        AR5K_PHY_PAPD_PROBE_GAINF       0xfe000000
-#define        AR5K_PHY_PAPD_PROBE_GAINF_S     25
-#define        AR5K_PHY_PAPD_PROBE_INI_5111    0x00004883      /* [5212+] */
-#define        AR5K_PHY_PAPD_PROBE_INI_5112    0x00004882      /* [5212+] */
-
-/*
- * PHY TX rate power registers [5112+]
- */
-#define        AR5K_PHY_TXPOWER_RATE1                  0x9934
-#define        AR5K_PHY_TXPOWER_RATE2                  0x9938
-#define        AR5K_PHY_TXPOWER_RATE_MAX               0x993c
-#define        AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE    0x00000040
-#define        AR5K_PHY_TXPOWER_RATE3                  0xa234
-#define        AR5K_PHY_TXPOWER_RATE4                  0xa238
-
-/*
- * PHY frame control register [5111+]
- */
-#define        AR5K_PHY_FRAME_CTL_5210         0x9804
-#define        AR5K_PHY_FRAME_CTL_5211         0x9944
-#define        AR5K_PHY_FRAME_CTL              (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
-/*---[5111+]---*/
-#define        AR5K_PHY_FRAME_CTL_TX_CLIP      0x00000038      /* Mask for tx clip (?) */
-#define        AR5K_PHY_FRAME_CTL_TX_CLIP_S    3
-#define        AR5K_PHY_FRAME_CTL_PREP_CHINFO  0x00010000      /* Prepend chan info */
-#define        AR5K_PHY_FRAME_CTL_EMU          0x80000000
-#define        AR5K_PHY_FRAME_CTL_EMU_S        31
-/*---[5110/5111]---*/
-#define        AR5K_PHY_FRAME_CTL_TIMING_ERR   0x01000000      /* PHY timing error */
-#define        AR5K_PHY_FRAME_CTL_PARITY_ERR   0x02000000      /* Parity error */
-#define        AR5K_PHY_FRAME_CTL_ILLRATE_ERR  0x04000000      /* Illegal rate */
-#define        AR5K_PHY_FRAME_CTL_ILLLEN_ERR   0x08000000      /* Illegal length */
-#define        AR5K_PHY_FRAME_CTL_SERVICE_ERR  0x20000000
-#define        AR5K_PHY_FRAME_CTL_TXURN_ERR    0x40000000      /* TX underrun */
-#define AR5K_PHY_FRAME_CTL_INI         AR5K_PHY_FRAME_CTL_SERVICE_ERR | \
-                       AR5K_PHY_FRAME_CTL_TXURN_ERR | \
-                       AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \
-                       AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \
-                       AR5K_PHY_FRAME_CTL_PARITY_ERR | \
-                       AR5K_PHY_FRAME_CTL_TIMING_ERR
-
-/*
- * PHY Tx Power adjustment register [5212A+]
- */
-#define        AR5K_PHY_TX_PWR_ADJ                     0x994c
-#define        AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA      0x00000fc0
-#define        AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S    6
-#define        AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX     0x00fc0000
-#define        AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S   18
-
-/*
- * PHY radar detection register [5111+]
- */
-#define        AR5K_PHY_RADAR                  0x9954
-#define        AR5K_PHY_RADAR_ENABLE           0x00000001
-#define        AR5K_PHY_RADAR_DISABLE          0x00000000
-#define AR5K_PHY_RADAR_INBANDTHR       0x0000003e      /* Inband threshold
-                                                       5-bits, units unknown {0..31}
-                                                       (? MHz ?) */
-#define AR5K_PHY_RADAR_INBANDTHR_S     1
-
-#define AR5K_PHY_RADAR_PRSSI_THR       0x00000fc0      /* Pulse RSSI/SNR threshold
-                                                       6-bits, dBm range {0..63}
-                                                       in dBm units. */
-#define AR5K_PHY_RADAR_PRSSI_THR_S     6
-
-#define AR5K_PHY_RADAR_PHEIGHT_THR     0x0003f000      /* Pulse height threshold
-                                                       6-bits, dBm range {0..63}
-                                                       in dBm units. */
-#define AR5K_PHY_RADAR_PHEIGHT_THR_S   12
-
-#define AR5K_PHY_RADAR_RSSI_THR        0x00fc0000      /* Radar RSSI/SNR threshold.
-                                                       6-bits, dBm range {0..63}
-                                                       in dBm units. */
-#define AR5K_PHY_RADAR_RSSI_THR_S      18
-
-#define AR5K_PHY_RADAR_FIRPWR_THR      0x7f000000      /* Finite Impulse Response
-                                                       filter power out threshold.
-                                                       7-bits, standard power range
-                                                       {0..127} in 1/2 dBm units. */
-#define AR5K_PHY_RADAR_FIRPWR_THRS     24
-
-/*
- * PHY antenna switch table registers
- */
-#define AR5K_PHY_ANT_SWITCH_TABLE_0    0x9960
-#define AR5K_PHY_ANT_SWITCH_TABLE_1    0x9964
-
-/*
- * PHY Noise floor threshold
- */
-#define AR5K_PHY_NFTHRES               0x9968
-
-/*
- * Sigma Delta register (?) [5213]
- */
-#define AR5K_PHY_SIGMA_DELTA           0x996C
-#define AR5K_PHY_SIGMA_DELTA_ADC_SEL   0x00000003
-#define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0
-#define AR5K_PHY_SIGMA_DELTA_FILT2     0x000000f8
-#define AR5K_PHY_SIGMA_DELTA_FILT2_S   3
-#define AR5K_PHY_SIGMA_DELTA_FILT1     0x00001f00
-#define AR5K_PHY_SIGMA_DELTA_FILT1_S   8
-#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP  0x01ffe000
-#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S        13
-
-/*
- * RF restart register [5112+] (?)
- */
-#define AR5K_PHY_RESTART               0x9970          /* restart */
-#define AR5K_PHY_RESTART_DIV_GC                0x001c0000      /* Fast diversity gc_limit (?) */
-#define AR5K_PHY_RESTART_DIV_GC_S      18
-
-/*
- * RF Bus access request register (for synth-oly channel switching)
- */
-#define AR5K_PHY_RFBUS_REQ             0x997C
-#define AR5K_PHY_RFBUS_REQ_REQUEST     0x00000001
-
-/*
- * Spur mitigation masks (?)
- */
-#define AR5K_PHY_TIMING_7              0x9980
-#define AR5K_PHY_TIMING_8              0x9984
-#define AR5K_PHY_TIMING_8_PILOT_MASK_2         0x000fffff
-#define AR5K_PHY_TIMING_8_PILOT_MASK_2_S       0
-
-#define AR5K_PHY_BIN_MASK2_1           0x9988
-#define AR5K_PHY_BIN_MASK2_2           0x998c
-#define AR5K_PHY_BIN_MASK2_3           0x9990
-
-#define AR5K_PHY_BIN_MASK2_4           0x9994
-#define AR5K_PHY_BIN_MASK2_4_MASK_4    0x00003fff
-#define AR5K_PHY_BIN_MASK2_4_MASK_4_S  0
-
-#define AR5K_PHY_TIMING_9                      0x9998
-#define AR5K_PHY_TIMING_10                     0x999c
-#define AR5K_PHY_TIMING_10_PILOT_MASK_2                0x000fffff
-#define AR5K_PHY_TIMING_10_PILOT_MASK_2_S      0
-
-/*
- * Spur mitigation control
- */
-#define AR5K_PHY_TIMING_11                     0x99a0          /* Register address */
-#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE    0x000fffff      /* Spur delta phase */
-#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S  0
-#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD                0x3ff00000      /* Freq sigma delta */
-#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S      20
-#define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC     0x40000000      /* Spur filter in AGC detector */
-#define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000      /* Spur filter in OFDM self correlator */
-
-/*
- * Gain tables
- */
-#define        AR5K_BB_GAIN_BASE               0x9b00  /* BaseBand Amplifier Gain table base address */
-#define AR5K_BB_GAIN(_n)               (AR5K_BB_GAIN_BASE + ((_n) << 2))
-#define        AR5K_RF_GAIN_BASE               0x9a00  /* RF Amplrifier Gain table base address */
-#define AR5K_RF_GAIN(_n)               (AR5K_RF_GAIN_BASE + ((_n) << 2))
-
-/*
- * PHY timing IQ calibration result register [5111+]
- */
-#define        AR5K_PHY_IQRES_CAL_PWR_I        0x9c10  /* I (Inphase) power value */
-#define        AR5K_PHY_IQRES_CAL_PWR_Q        0x9c14  /* Q (Quadrature) power value */
-#define        AR5K_PHY_IQRES_CAL_CORR         0x9c18  /* I/Q Correlation */
-
-/*
- * PHY current RSSI register [5111+]
- */
-#define        AR5K_PHY_CURRENT_RSSI   0x9c1c
-
-/*
- * PHY RF Bus grant register
- */
-#define        AR5K_PHY_RFBUS_GRANT    0x9c20
-#define        AR5K_PHY_RFBUS_GRANT_OK 0x00000001
-
-/*
- * PHY ADC test register
- */
-#define        AR5K_PHY_ADC_TEST       0x9c24
-#define        AR5K_PHY_ADC_TEST_I     0x00000001
-#define        AR5K_PHY_ADC_TEST_Q     0x00000200
-
-/*
- * PHY DAC test register
- */
-#define        AR5K_PHY_DAC_TEST       0x9c28
-#define        AR5K_PHY_DAC_TEST_I     0x00000001
-#define        AR5K_PHY_DAC_TEST_Q     0x00000200
-
-/*
- * PHY PTAT register (?)
- */
-#define        AR5K_PHY_PTAT           0x9c2c
-
-/*
- * PHY Illegal TX rate register [5112+]
- */
-#define        AR5K_PHY_BAD_TX_RATE    0x9c30
-
-/*
- * PHY SPUR Power register [5112+]
- */
-#define        AR5K_PHY_SPUR_PWR       0x9c34                  /* Register Address */
-#define        AR5K_PHY_SPUR_PWR_I     0x00000001      /* SPUR Power estimate for I (field) */
-#define        AR5K_PHY_SPUR_PWR_Q     0x00000100      /* SPUR Power estimate for Q (field) */
-#define        AR5K_PHY_SPUR_PWR_FILT  0x00010000      /* Power with SPUR removed (field) */
-
-/*
- * PHY Channel status register [5112+] (?)
- */
-#define        AR5K_PHY_CHAN_STATUS            0x9c38
-#define        AR5K_PHY_CHAN_STATUS_BT_ACT     0x00000001
-#define        AR5K_PHY_CHAN_STATUS_RX_CLR_RAW 0x00000002
-#define        AR5K_PHY_CHAN_STATUS_RX_CLR_MAC 0x00000004
-#define        AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008
-
-/*
- * Heavy clip enable register
- */
-#define        AR5K_PHY_HEAVY_CLIP_ENABLE      0x99e0
-
-/*
- * PHY clock sleep registers [5112+]
- */
-#define AR5K_PHY_SCLOCK                        0x99f0
-#define AR5K_PHY_SCLOCK_32MHZ          0x0000000c
-#define AR5K_PHY_SDELAY                        0x99f4
-#define AR5K_PHY_SDELAY_32MHZ          0x000000ff
-#define AR5K_PHY_SPENDING              0x99f8
-
-
-/*
- * PHY PAPD I (power?) table (?)
- * (92! entries)
- */
-#define        AR5K_PHY_PAPD_I_BASE    0xa000
-#define        AR5K_PHY_PAPD_I(_n)     (AR5K_PHY_PAPD_I_BASE + ((_n) << 2))
-
-/*
- * PHY PCDAC TX power table
- */
-#define        AR5K_PHY_PCDAC_TXPOWER_BASE     0xa180
-#define        AR5K_PHY_PCDAC_TXPOWER(_n)      (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
-
-/*
- * PHY mode register [5111+]
- */
-#define        AR5K_PHY_MODE                   0x0a200                 /* Register Address */
-#define        AR5K_PHY_MODE_MOD               0x00000001      /* PHY Modulation bit */
-#define AR5K_PHY_MODE_MOD_OFDM         0
-#define AR5K_PHY_MODE_MOD_CCK          1
-#define AR5K_PHY_MODE_FREQ             0x00000002      /* Freq mode bit */
-#define        AR5K_PHY_MODE_FREQ_5GHZ         0
-#define        AR5K_PHY_MODE_FREQ_2GHZ         2
-#define AR5K_PHY_MODE_MOD_DYN          0x00000004      /* Enable Dynamic OFDM/CCK mode [5112+] */
-#define AR5K_PHY_MODE_RAD              0x00000008      /* [5212+] */
-#define AR5K_PHY_MODE_RAD_RF5111       0
-#define AR5K_PHY_MODE_RAD_RF5112       8
-#define AR5K_PHY_MODE_XR               0x00000010      /* Enable XR mode [5112+] */
-#define        AR5K_PHY_MODE_HALF_RATE         0x00000020      /* Enable Half rate (test) */
-#define        AR5K_PHY_MODE_QUARTER_RATE      0x00000040      /* Enable Quarter rat (test) */
-
-/*
- * PHY CCK transmit control register [5111+ (?)]
- */
-#define AR5K_PHY_CCKTXCTL              0xa204
-#define AR5K_PHY_CCKTXCTL_WORLD                0x00000000
-#define AR5K_PHY_CCKTXCTL_JAPAN                0x00000010
-#define        AR5K_PHY_CCKTXCTL_SCRAMBLER_DIS 0x00000001
-#define        AR5K_PHY_CCKTXCTK_DAC_SCALE     0x00000004
-
-/*
- * PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
- */
-#define AR5K_PHY_CCK_CROSSCORR                 0xa208
-#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR    0x0000000f
-#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S  0
-
-/* Same address is used for antenna diversity activation */
-#define        AR5K_PHY_FAST_ANT_DIV           0xa208
-#define        AR5K_PHY_FAST_ANT_DIV_EN        0x00002000
-
-/*
- * PHY 2GHz gain register [5111+]
- */
-#define        AR5K_PHY_GAIN_2GHZ                      0xa20c
-#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX          0x00fc0000
-#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S        18
-#define        AR5K_PHY_GAIN_2GHZ_INI_5111             0x6480416c
-
-#define        AR5K_PHY_CCK_RX_CTL_4                   0xa21c
-#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT    0x01f80000
-#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S  19
-
-#define        AR5K_PHY_DAG_CCK_CTL                    0xa228
-#define        AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR        0x00000200
-#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR           0x0001fc00
-#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S         10
-
-#define        AR5K_PHY_FAST_ADC       0xa24c
-
-#define        AR5K_PHY_BLUETOOTH      0xa254
-
-/*
- * Transmit Power Control register
- * [2413+]
- */
-#define        AR5K_PHY_TPC_RG1                0xa258
-#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN    0x0000c000
-#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S  14
-#define AR5K_PHY_TPC_RG1_PDGAIN_1      0x00030000
-#define AR5K_PHY_TPC_RG1_PDGAIN_1_S    16
-#define AR5K_PHY_TPC_RG1_PDGAIN_2      0x000c0000
-#define AR5K_PHY_TPC_RG1_PDGAIN_2_S    18
-#define AR5K_PHY_TPC_RG1_PDGAIN_3      0x00300000
-#define AR5K_PHY_TPC_RG1_PDGAIN_3_S    20
-
-#define        AR5K_PHY_TPC_RG5                        0xa26C
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP        0x0000000F
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S      0
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1     0x000003F0
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S   4
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2     0x0000FC00
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S   10
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3     0x003F0000
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S   16
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4     0x0FC00000
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S   22
-
-/*
- * PHY PDADC Tx power table
- */
-#define AR5K_PHY_PDADC_TXPOWER_BASE    0xa280
-#define        AR5K_PHY_PDADC_TXPOWER(_n)      (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
deleted file mode 100644 (file)
index 775fdf7..0000000
+++ /dev/null
@@ -1,1346 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
- * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-#define _ATH5K_RESET
-
-/*****************************\
-  Reset functions and helpers
-\*****************************/
-
-#include <linux/pci.h>                 /* To determine if a card is pci-e */
-#include <linux/bitops.h>      /* For get_bitmask_order */
-#include "ath5k.h"
-#include "reg.h"
-#include "base.h"
-#include "debug.h"
-
-/**
- * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
- *
- * @ah: the &struct ath5k_hw
- * @channel: the currently set channel upon reset
- *
- * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
- * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
- *
- * Since delta slope is floating point we split it on its exponent and
- * mantissa and provide these values on hw.
- *
- * For more infos i think this patent is related
- * http://www.freepatentsonline.com/7184495.html
- */
-static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
-       struct ieee80211_channel *channel)
-{
-       /* Get exponent and mantissa and set it */
-       u32 coef_scaled, coef_exp, coef_man,
-               ds_coef_exp, ds_coef_man, clock;
-
-       BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
-               !(channel->hw_value & CHANNEL_OFDM));
-
-       /* Get coefficient
-        * ALGO: coef = (5 * clock * carrier_freq) / 2)
-        * we scale coef by shifting clock value by 24 for
-        * better precision since we use integers */
-       /* TODO: Half/quarter rate */
-       clock =  ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO);
-
-       coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
-
-       /* Get exponent
-        * ALGO: coef_exp = 14 - highest set bit position */
-       coef_exp = get_bitmask_order(coef_scaled);
-
-       /* Doesn't make sense if it's zero*/
-       if (!coef_exp)
-               return -EINVAL;
-
-       /* Note: we've shifted coef_scaled by 24 */
-       coef_exp = 14 - (coef_exp - 24);
-
-
-       /* Get mantissa (significant digits)
-        * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
-       coef_man = coef_scaled +
-               (1 << (24 - coef_exp - 1));
-
-       /* Calculate delta slope coefficient exponent
-        * and mantissa (remove scaling) and set them on hw */
-       ds_coef_man = coef_man >> (24 - coef_exp);
-       ds_coef_exp = coef_exp - 16;
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
-               AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
-               AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
-
-       return 0;
-}
-
-
-/*
- * index into rates for control rates, we can set it up like this because
- * this is only used for AR5212 and we know it supports G mode
- */
-static const unsigned int control_rates[] =
-       { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
-
-/**
- * ath5k_hw_write_rate_duration - fill rate code to duration table
- *
- * @ah: the &struct ath5k_hw
- * @mode: one of enum ath5k_driver_mode
- *
- * Write the rate code to duration table upon hw reset. This is a helper for
- * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
- * the hardware, based on current mode, for each rate. The rates which are
- * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
- * different rate code so we write their value twice (one for long preample
- * and one for short).
- *
- * Note: Band doesn't matter here, if we set the values for OFDM it works
- * on both a and g modes. So all we have to do is set values for all g rates
- * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
- * quarter rate mode, we need to use another set of bitrates (that's why we
- * need the mode parameter) but we don't handle these proprietary modes yet.
- */
-static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
-       unsigned int mode)
-{
-       struct ath5k_softc *sc = ah->ah_sc;
-       struct ieee80211_rate *rate;
-       unsigned int i;
-
-       /* Write rate duration table */
-       for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
-               u32 reg;
-               u16 tx_time;
-
-               rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
-
-               /* Set ACK timeout */
-               reg = AR5K_RATE_DUR(rate->hw_value);
-
-               /* An ACK frame consists of 10 bytes. If you add the FCS,
-                * which ieee80211_generic_frame_duration() adds,
-                * its 14 bytes. Note we use the control rate and not the
-                * actual rate for this rate. See mac80211 tx.c
-                * ieee80211_duration() for a brief description of
-                * what rate we should choose to TX ACKs. */
-               tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
-                                                       sc->vif, 10, rate));
-
-               ath5k_hw_reg_write(ah, tx_time, reg);
-
-               if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
-                       continue;
-
-               /*
-                * We're not distinguishing short preamble here,
-                * This is true, all we'll get is a longer value here
-                * which is not necessarilly bad. We could use
-                * export ieee80211_frame_duration() but that needs to be
-                * fixed first to be properly used by mac802111 drivers:
-                *
-                *  - remove erp stuff and let the routine figure ofdm
-                *    erp rates
-                *  - remove passing argument ieee80211_local as
-                *    drivers don't have access to it
-                *  - move drivers using ieee80211_generic_frame_duration()
-                *    to this
-                */
-               ath5k_hw_reg_write(ah, tx_time,
-                       reg + (AR5K_SET_SHORT_PREAMBLE << 2));
-       }
-}
-
-/*
- * Reset chipset
- */
-static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
-{
-       int ret;
-       u32 mask = val ? val : ~0U;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Read-and-clear RX Descriptor Pointer*/
-       ath5k_hw_reg_read(ah, AR5K_RXDP);
-
-       /*
-        * Reset the device and wait until success
-        */
-       ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
-
-       /* Wait at least 128 PCI clocks */
-       udelay(15);
-
-       if (ah->ah_version == AR5K_AR5210) {
-               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
-                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
-               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
-                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
-       } else {
-               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
-               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
-       }
-
-       ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
-
-       /*
-        * Reset configuration register (for hw byte-swap). Note that this
-        * is only set for big endian. We do the necessary magic in
-        * AR5K_INIT_CFG.
-        */
-       if ((val & AR5K_RESET_CTL_PCU) == 0)
-               ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
-
-       return ret;
-}
-
-/*
- * Sleep control
- */
-int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
-               bool set_chip, u16 sleep_duration)
-{
-       unsigned int i;
-       u32 staid, data;
-
-       ATH5K_TRACE(ah->ah_sc);
-       staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
-
-       switch (mode) {
-       case AR5K_PM_AUTO:
-               staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
-               /* fallthrough */
-       case AR5K_PM_NETWORK_SLEEP:
-               if (set_chip)
-                       ath5k_hw_reg_write(ah,
-                               AR5K_SLEEP_CTL_SLE_ALLOW |
-                               sleep_duration,
-                               AR5K_SLEEP_CTL);
-
-               staid |= AR5K_STA_ID1_PWR_SV;
-               break;
-
-       case AR5K_PM_FULL_SLEEP:
-               if (set_chip)
-                       ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
-                               AR5K_SLEEP_CTL);
-
-               staid |= AR5K_STA_ID1_PWR_SV;
-               break;
-
-       case AR5K_PM_AWAKE:
-
-               staid &= ~AR5K_STA_ID1_PWR_SV;
-
-               if (!set_chip)
-                       goto commit;
-
-               /* Preserve sleep duration */
-               data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
-               if (data & 0xffc00000)
-                       data = 0;
-               else
-                       data = data & 0xfffcffff;
-
-               ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
-               udelay(15);
-
-               for (i = 50; i > 0; i--) {
-                       /* Check if the chip did wake up */
-                       if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
-                                       AR5K_PCICFG_SPWR_DN) == 0)
-                               break;
-
-                       /* Wait a bit and retry */
-                       udelay(200);
-                       ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
-               }
-
-               /* Fail if the chip didn't wake up */
-               if (i <= 0)
-                       return -EIO;
-
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-commit:
-       ah->ah_power_mode = mode;
-       ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
-
-       return 0;
-}
-
-/*
- * Bring up MAC + PHY Chips and program PLL
- * TODO: Half/Quarter rate support
- */
-int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
-{
-       struct pci_dev *pdev = ah->ah_sc->pdev;
-       u32 turbo, mode, clock, bus_flags;
-       int ret;
-
-       turbo = 0;
-       mode = 0;
-       clock = 0;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Wakeup the device */
-       ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
-               return ret;
-       }
-
-       if (ah->ah_version != AR5K_AR5210) {
-               /*
-                * Get channel mode flags
-                */
-
-               if (ah->ah_radio >= AR5K_RF5112) {
-                       mode = AR5K_PHY_MODE_RAD_RF5112;
-                       clock = AR5K_PHY_PLL_RF5112;
-               } else {
-                       mode = AR5K_PHY_MODE_RAD_RF5111;        /*Zero*/
-                       clock = AR5K_PHY_PLL_RF5111;            /*Zero*/
-               }
-
-               if (flags & CHANNEL_2GHZ) {
-                       mode |= AR5K_PHY_MODE_FREQ_2GHZ;
-                       clock |= AR5K_PHY_PLL_44MHZ;
-
-                       if (flags & CHANNEL_CCK) {
-                               mode |= AR5K_PHY_MODE_MOD_CCK;
-                       } else if (flags & CHANNEL_OFDM) {
-                               /* XXX Dynamic OFDM/CCK is not supported by the
-                                * AR5211 so we set MOD_OFDM for plain g (no
-                                * CCK headers) operation. We need to test
-                                * this, 5211 might support ofdm-only g after
-                                * all, there are also initial register values
-                                * in the code for g mode (see initvals.c). */
-                               if (ah->ah_version == AR5K_AR5211)
-                                       mode |= AR5K_PHY_MODE_MOD_OFDM;
-                               else
-                                       mode |= AR5K_PHY_MODE_MOD_DYN;
-                       } else {
-                               ATH5K_ERR(ah->ah_sc,
-                                       "invalid radio modulation mode\n");
-                               return -EINVAL;
-                       }
-               } else if (flags & CHANNEL_5GHZ) {
-                       mode |= AR5K_PHY_MODE_FREQ_5GHZ;
-
-                       if (ah->ah_radio == AR5K_RF5413)
-                               clock = AR5K_PHY_PLL_40MHZ_5413;
-                       else
-                               clock |= AR5K_PHY_PLL_40MHZ;
-
-                       if (flags & CHANNEL_OFDM)
-                               mode |= AR5K_PHY_MODE_MOD_OFDM;
-                       else {
-                               ATH5K_ERR(ah->ah_sc,
-                                       "invalid radio modulation mode\n");
-                               return -EINVAL;
-                       }
-               } else {
-                       ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
-                       return -EINVAL;
-               }
-
-               if (flags & CHANNEL_TURBO)
-                       turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
-       } else { /* Reset the device */
-
-               /* ...enable Atheros turbo mode if requested */
-               if (flags & CHANNEL_TURBO)
-                       ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
-                                       AR5K_PHY_TURBO);
-       }
-
-       /* reseting PCI on PCI-E cards results card to hang
-        * and always return 0xffff... so we ingore that flag
-        * for PCI-E cards */
-       bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
-
-       /* Reset chipset */
-       if (ah->ah_version == AR5K_AR5210) {
-               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
-                       AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
-                       AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
-                       mdelay(2);
-       } else {
-               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
-                       AR5K_RESET_CTL_BASEBAND | bus_flags);
-       }
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
-               return -EIO;
-       }
-
-       /* ...wakeup again!*/
-       ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
-               return ret;
-       }
-
-       /* ...final warm reset */
-       if (ath5k_hw_nic_reset(ah, 0)) {
-               ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
-               return -EIO;
-       }
-
-       if (ah->ah_version != AR5K_AR5210) {
-
-               /* ...update PLL if needed */
-               if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
-                       ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
-                       udelay(300);
-               }
-
-               /* ...set the PHY operating mode */
-               ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
-               ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
-       }
-
-       return 0;
-}
-
-/*
- * If there is an external 32KHz crystal available, use it
- * as ref. clock instead of 32/40MHz clock and baseband clocks
- * to save power during sleep or restore normal 32/40MHz
- * operation.
- *
- * XXX: When operating on 32KHz certain PHY registers (27 - 31,
- *     123 - 127) require delay on access.
- */
-static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 scal, spending, usec32;
-
-       /* Only set 32KHz settings if we have an external
-        * 32KHz crystal present */
-       if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
-       AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
-       enable) {
-
-               /* 1 usec/cycle */
-               AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
-               /* Set up tsf increment on each cycle */
-               AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
-
-               /* Set baseband sleep control registers
-                * and sleep control rate */
-               ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
-
-               if ((ah->ah_radio == AR5K_RF5112) ||
-               (ah->ah_radio == AR5K_RF5413) ||
-               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
-                       spending = 0x14;
-               else
-                       spending = 0x18;
-               ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
-
-               if ((ah->ah_radio == AR5K_RF5112) ||
-               (ah->ah_radio == AR5K_RF5413) ||
-               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
-                       ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
-                       ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
-                       ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
-                       ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
-                       AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
-               } else {
-                       ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
-                       ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
-                       ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
-                       ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
-                       AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
-               }
-
-               /* Enable sleep clock operation */
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_EN);
-
-       } else {
-
-               /* Disable sleep clock operation and
-                * restore default parameters */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_EN);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
-
-               ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
-               ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
-
-               if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
-                       scal = AR5K_PHY_SCAL_32MHZ_2417;
-               else if (ath5k_eeprom_is_hb63(ah))
-                       scal = AR5K_PHY_SCAL_32MHZ_HB63;
-               else
-                       scal = AR5K_PHY_SCAL_32MHZ;
-               ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
-
-               ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
-               ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
-
-               if ((ah->ah_radio == AR5K_RF5112) ||
-               (ah->ah_radio == AR5K_RF5413) ||
-               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
-                       spending = 0x14;
-               else
-                       spending = 0x18;
-               ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
-
-               if ((ah->ah_radio == AR5K_RF5112) ||
-               (ah->ah_radio == AR5K_RF5413))
-                       usec32 = 39;
-               else
-                       usec32 = 31;
-               AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
-       }
-       return;
-}
-
-static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
-                               struct ieee80211_channel *channel)
-{
-       u8 refclk_freq;
-
-       if ((ah->ah_radio == AR5K_RF5112) ||
-       (ah->ah_radio == AR5K_RF5413) ||
-       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
-               refclk_freq = 40;
-       else
-               refclk_freq = 32;
-
-       if ((channel->center_freq % refclk_freq != 0) &&
-       ((channel->center_freq % refclk_freq < 10) ||
-       (channel->center_freq % refclk_freq > 22)))
-               return true;
-       else
-               return false;
-}
-
-/* TODO: Half/Quarter rate */
-static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
-                               struct ieee80211_channel *channel)
-{
-       if (ah->ah_version == AR5K_AR5212 &&
-           ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
-
-               /* Setup ADC control */
-               ath5k_hw_reg_write(ah,
-                               (AR5K_REG_SM(2,
-                               AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
-                               AR5K_REG_SM(2,
-                               AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
-                               AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
-                               AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
-                               AR5K_PHY_ADC_CTL);
-
-
-
-               /* Disable barker RSSI threshold */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
-                               AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
-                       AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
-
-               /* Set the mute mask */
-               ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
-       }
-
-       /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */
-       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
-               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
-
-       /* Enable DCU double buffering */
-       if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
-               AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
-                               AR5K_TXCFG_DCU_DBL_BUF_DIS);
-
-       /* Set DAC/ADC delays */
-       if (ah->ah_version == AR5K_AR5212) {
-               u32 scal;
-               if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
-                       scal = AR5K_PHY_SCAL_32MHZ_2417;
-               else if (ath5k_eeprom_is_hb63(ah))
-                       scal = AR5K_PHY_SCAL_32MHZ_HB63;
-               else
-                       scal = AR5K_PHY_SCAL_32MHZ;
-               ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
-       }
-
-       /* Set fast ADC */
-       if ((ah->ah_radio == AR5K_RF5413) ||
-       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
-               u32 fast_adc = true;
-
-               if (channel->center_freq == 2462 ||
-               channel->center_freq == 2467)
-                       fast_adc = 0;
-
-               /* Only update if needed */
-               if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
-                               ath5k_hw_reg_write(ah, fast_adc,
-                                               AR5K_PHY_FAST_ADC);
-       }
-
-       /* Fix for first revision of the RF5112 RF chipset */
-       if (ah->ah_radio == AR5K_RF5112 &&
-                       ah->ah_radio_5ghz_revision <
-                       AR5K_SREV_RAD_5112A) {
-               u32 data;
-               ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
-                               AR5K_PHY_CCKTXCTL);
-               if (channel->hw_value & CHANNEL_5GHZ)
-                       data = 0xffb81020;
-               else
-                       data = 0xffb80d20;
-               ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
-       }
-
-       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
-               u32 usec_reg;
-               /* 5311 has different tx/rx latency masks
-                * from 5211, since we deal 5311 the same
-                * as 5211 when setting initvals, shift
-                * values here to their proper locations */
-               usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
-               ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
-                               AR5K_USEC_32 |
-                               AR5K_USEC_TX_LATENCY_5211 |
-                               AR5K_REG_SM(29,
-                               AR5K_USEC_RX_LATENCY_5210)),
-                               AR5K_USEC_5211);
-               /* Clear QCU/DCU clock gating register */
-               ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
-               /* Set DAC/ADC delays */
-               ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
-               /* Enable PCU FIFO corruption ECO */
-               AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
-                                       AR5K_DIAG_SW_ECO_ENABLE);
-       }
-}
-
-static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       s16 cck_ofdm_pwr_delta;
-
-       /* Adjust power delta for channel 14 */
-       if (channel->center_freq == 2484)
-               cck_ofdm_pwr_delta =
-                       ((ee->ee_cck_ofdm_power_delta -
-                       ee->ee_scaled_cck_delta) * 2) / 10;
-       else
-               cck_ofdm_pwr_delta =
-                       (ee->ee_cck_ofdm_power_delta * 2) / 10;
-
-       /* Set CCK to OFDM power delta on tx power
-        * adjustment register */
-       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
-               if (channel->hw_value == CHANNEL_G)
-                       ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
-                               AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
-                       AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
-                               AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
-                               AR5K_PHY_TX_PWR_ADJ);
-               else
-                       ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
-       } else {
-               /* For older revs we scale power on sw during tx power
-                * setup */
-               ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
-               ah->ah_txpower.txp_cck_ofdm_gainf_delta =
-                                               ee->ee_cck_ofdm_gain_delta;
-       }
-
-       /* Set antenna idle switch table */
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
-                       AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
-                       (ah->ah_antenna[ee_mode][0] |
-                       AR5K_PHY_ANT_CTL_TXRX_EN));
-
-       /* Set antenna switch table */
-       ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
-               AR5K_PHY_ANT_SWITCH_TABLE_0);
-       ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
-               AR5K_PHY_ANT_SWITCH_TABLE_1);
-
-       /* Noise floor threshold */
-       ath5k_hw_reg_write(ah,
-               AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
-               AR5K_PHY_NFTHRES);
-
-       if ((channel->hw_value & CHANNEL_TURBO) &&
-       (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
-               /* Switch settling time (Turbo) */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
-                               AR5K_PHY_SETTLING_SWITCH,
-                               ee->ee_switch_settling_turbo[ee_mode]);
-
-               /* Tx/Rx attenuation (Turbo) */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
-                               AR5K_PHY_GAIN_TXRX_ATTEN,
-                               ee->ee_atn_tx_rx_turbo[ee_mode]);
-
-               /* ADC/PGA desired size (Turbo) */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
-                               AR5K_PHY_DESIRED_SIZE_ADC,
-                               ee->ee_adc_desired_size_turbo[ee_mode]);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
-                               AR5K_PHY_DESIRED_SIZE_PGA,
-                               ee->ee_pga_desired_size_turbo[ee_mode]);
-
-               /* Tx/Rx margin (Turbo) */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
-                               AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
-                               ee->ee_margin_tx_rx_turbo[ee_mode]);
-
-       } else {
-               /* Switch settling time */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
-                               AR5K_PHY_SETTLING_SWITCH,
-                               ee->ee_switch_settling[ee_mode]);
-
-               /* Tx/Rx attenuation */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
-                               AR5K_PHY_GAIN_TXRX_ATTEN,
-                               ee->ee_atn_tx_rx[ee_mode]);
-
-               /* ADC/PGA desired size */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
-                               AR5K_PHY_DESIRED_SIZE_ADC,
-                               ee->ee_adc_desired_size[ee_mode]);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
-                               AR5K_PHY_DESIRED_SIZE_PGA,
-                               ee->ee_pga_desired_size[ee_mode]);
-
-               /* Tx/Rx margin */
-               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
-                       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
-                               AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
-                               ee->ee_margin_tx_rx[ee_mode]);
-       }
-
-       /* XPA delays */
-       ath5k_hw_reg_write(ah,
-               (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
-               (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
-               (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
-               (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
-
-       /* XLNA delay */
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
-                       AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
-                       ee->ee_tx_end2xlna_enable[ee_mode]);
-
-       /* Thresh64 (ANI) */
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
-                       AR5K_PHY_NF_THRESH62,
-                       ee->ee_thr_62[ee_mode]);
-
-
-       /* False detect backoff for channels
-        * that have spur noise. Write the new
-        * cyclic power RSSI threshold. */
-       if (ath5k_hw_chan_has_spur_noise(ah, channel))
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
-                               AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
-                               AR5K_INIT_CYCRSSI_THR1 +
-                               ee->ee_false_detect[ee_mode]);
-       else
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
-                               AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
-                               AR5K_INIT_CYCRSSI_THR1);
-
-       /* I/Q correction
-        * TODO: Per channel i/q infos ? */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
-               AR5K_PHY_IQ_CORR_ENABLE |
-               (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
-               ee->ee_q_cal[ee_mode]);
-
-       /* Heavy clipping -disable for now */
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
-               ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
-
-       return;
-}
-
-/*
- * Main reset function
- */
-int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
-       struct ieee80211_channel *channel, bool change_channel)
-{
-       u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
-       u32 phy_tst1;
-       u8 mode, freq, ee_mode, ant[2];
-       int i, ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       s_ant = 0;
-       ee_mode = 0;
-       staid1_flags = 0;
-       tsf_up = 0;
-       tsf_lo = 0;
-       freq = 0;
-       mode = 0;
-
-       /*
-        * Save some registers before a reset
-        */
-       /*DCU/Antenna selection not available on 5210*/
-       if (ah->ah_version != AR5K_AR5210) {
-
-               switch (channel->hw_value & CHANNEL_MODES) {
-               case CHANNEL_A:
-                       mode = AR5K_MODE_11A;
-                       freq = AR5K_INI_RFGAIN_5GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11A;
-                       break;
-               case CHANNEL_G:
-                       mode = AR5K_MODE_11G;
-                       freq = AR5K_INI_RFGAIN_2GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11G;
-                       break;
-               case CHANNEL_B:
-                       mode = AR5K_MODE_11B;
-                       freq = AR5K_INI_RFGAIN_2GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11B;
-                       break;
-               case CHANNEL_T:
-                       mode = AR5K_MODE_11A_TURBO;
-                       freq = AR5K_INI_RFGAIN_5GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11A;
-                       break;
-               case CHANNEL_TG:
-                       if (ah->ah_version == AR5K_AR5211) {
-                               ATH5K_ERR(ah->ah_sc,
-                                       "TurboG mode not available on 5211");
-                               return -EINVAL;
-                       }
-                       mode = AR5K_MODE_11G_TURBO;
-                       freq = AR5K_INI_RFGAIN_2GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11G;
-                       break;
-               case CHANNEL_XR:
-                       if (ah->ah_version == AR5K_AR5211) {
-                               ATH5K_ERR(ah->ah_sc,
-                                       "XR mode not available on 5211");
-                               return -EINVAL;
-                       }
-                       mode = AR5K_MODE_XR;
-                       freq = AR5K_INI_RFGAIN_5GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11A;
-                       break;
-               default:
-                       ATH5K_ERR(ah->ah_sc,
-                               "invalid channel: %d\n", channel->center_freq);
-                       return -EINVAL;
-               }
-
-               if (change_channel) {
-                       /*
-                        * Save frame sequence count
-                        * For revs. after Oahu, only save
-                        * seq num for DCU 0 (Global seq num)
-                        */
-                       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
-
-                               for (i = 0; i < 10; i++)
-                                       s_seq[i] = ath5k_hw_reg_read(ah,
-                                               AR5K_QUEUE_DCU_SEQNUM(i));
-
-                       } else {
-                               s_seq[0] = ath5k_hw_reg_read(ah,
-                                               AR5K_QUEUE_DCU_SEQNUM(0));
-                       }
-
-                       /* TSF accelerates on AR5211 durring reset
-                        * As a workaround save it here and restore
-                        * it later so that it's back in time after
-                        * reset. This way it'll get re-synced on the
-                        * next beacon without breaking ad-hoc.
-                        *
-                        * On AR5212 TSF is almost preserved across a
-                        * reset so it stays back in time anyway and
-                        * we don't have to save/restore it.
-                        *
-                        * XXX: Since this breaks power saving we have
-                        * to disable power saving until we receive the
-                        * next beacon, so we can resync beacon timers */
-                       if (ah->ah_version == AR5K_AR5211) {
-                               tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
-                               tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
-                       }
-               }
-
-               /* Save default antenna */
-               s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
-
-               if (ah->ah_version == AR5K_AR5212) {
-                       /* Restore normal 32/40MHz clock operation
-                        * to avoid register access delay on certain
-                        * PHY registers */
-                       ath5k_hw_set_sleep_clock(ah, false);
-
-                       /* Since we are going to write rf buffer
-                        * check if we have any pending gain_F
-                        * optimization settings */
-                       if (change_channel && ah->ah_rf_banks != NULL)
-                               ath5k_hw_gainf_calibrate(ah);
-               }
-       }
-
-       /*GPIOs*/
-       s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
-                                       AR5K_PCICFG_LEDSTATE;
-       s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
-       s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
-
-       /* AR5K_STA_ID1 flags, only preserve antenna
-        * settings and ack/cts rate mode */
-       staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
-                       (AR5K_STA_ID1_DEFAULT_ANTENNA |
-                       AR5K_STA_ID1_DESC_ANTENNA |
-                       AR5K_STA_ID1_RTS_DEF_ANTENNA |
-                       AR5K_STA_ID1_ACKCTS_6MB |
-                       AR5K_STA_ID1_BASE_RATE_11B |
-                       AR5K_STA_ID1_SELFGEN_DEF_ANT);
-
-       /* Wakeup the device */
-       ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
-       if (ret)
-               return ret;
-
-       /*
-        * Initialize operating mode
-        */
-       ah->ah_op_mode = op_mode;
-
-       /* PHY access enable */
-       if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
-               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
-       else
-               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
-                                                       AR5K_PHY(0));
-
-       /* Write initial settings */
-       ret = ath5k_hw_write_initvals(ah, mode, change_channel);
-       if (ret)
-               return ret;
-
-       /*
-        * 5211/5212 Specific
-        */
-       if (ah->ah_version != AR5K_AR5210) {
-
-               /*
-                * Write initial RF gain settings
-                * This should work for both 5111/5112
-                */
-               ret = ath5k_hw_rfgain_init(ah, freq);
-               if (ret)
-                       return ret;
-
-               mdelay(1);
-
-               /*
-                * Tweak initval settings for revised
-                * chipsets and add some more config
-                * bits
-                */
-               ath5k_hw_tweak_initval_settings(ah, channel);
-
-               /*
-                * Set TX power (FIXME)
-                */
-               ret = ath5k_hw_txpower(ah, channel, ee_mode,
-                                       AR5K_TUNE_DEFAULT_TXPOWER);
-               if (ret)
-                       return ret;
-
-               /* Write rate duration table only on AR5212 and if
-                * virtual interface has already been brought up
-                * XXX: rethink this after new mode changes to
-                * mac80211 are integrated */
-               if (ah->ah_version == AR5K_AR5212 &&
-                       ah->ah_sc->vif != NULL)
-                       ath5k_hw_write_rate_duration(ah, mode);
-
-               /*
-                * Write RF buffer
-                */
-               ret = ath5k_hw_rfregs_init(ah, channel, mode);
-               if (ret)
-                       return ret;
-
-
-               /* Write OFDM timings on 5212*/
-               if (ah->ah_version == AR5K_AR5212 &&
-                       channel->hw_value & CHANNEL_OFDM) {
-                       ret = ath5k_hw_write_ofdm_timings(ah, channel);
-                       if (ret)
-                               return ret;
-               }
-
-               /*Enable/disable 802.11b mode on 5111
-               (enable 2111 frequency converter + CCK)*/
-               if (ah->ah_radio == AR5K_RF5111) {
-                       if (mode == AR5K_MODE_11B)
-                               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
-                                   AR5K_TXCFG_B_MODE);
-                       else
-                               AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
-                                   AR5K_TXCFG_B_MODE);
-               }
-
-               /*
-                * In case a fixed antenna was set as default
-                * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
-                * registers.
-                */
-               if (s_ant != 0) {
-                       if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
-                               ant[0] = ant[1] = AR5K_ANT_FIXED_A;
-                       else    /* 2 - Aux */
-                               ant[0] = ant[1] = AR5K_ANT_FIXED_B;
-               } else {
-                       ant[0] = AR5K_ANT_FIXED_A;
-                       ant[1] = AR5K_ANT_FIXED_B;
-               }
-
-               /* Commit values from EEPROM */
-               ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode);
-
-       } else {
-               /*
-                * For 5210 we do all initialization using
-                * initvals, so we don't have to modify
-                * any settings (5210 also only supports
-                * a/aturbo modes)
-                */
-               mdelay(1);
-               /* Disable phy and wait */
-               ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
-               mdelay(1);
-       }
-
-       /*
-        * Restore saved values
-        */
-
-       /*DCU/Antenna selection not available on 5210*/
-       if (ah->ah_version != AR5K_AR5210) {
-
-               if (change_channel) {
-                       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
-                               for (i = 0; i < 10; i++)
-                                       ath5k_hw_reg_write(ah, s_seq[i],
-                                               AR5K_QUEUE_DCU_SEQNUM(i));
-                       } else {
-                               ath5k_hw_reg_write(ah, s_seq[0],
-                                       AR5K_QUEUE_DCU_SEQNUM(0));
-                       }
-
-
-                       if (ah->ah_version == AR5K_AR5211) {
-                               ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
-                               ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
-                       }
-               }
-
-               ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
-       }
-
-       /* Ledstate */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
-
-       /* Gpio settings */
-       ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
-       ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
-
-       /* Restore sta_id flags and preserve our mac address*/
-       ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
-                                               AR5K_STA_ID0);
-       ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
-                                               AR5K_STA_ID1);
-
-
-       /*
-        * Configure PCU
-        */
-
-       /* Restore bssid and bssid mask */
-       /* XXX: add ah->aid once mac80211 gives this to us */
-       ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
-
-       /* Set PCU config */
-       ath5k_hw_set_opmode(ah);
-
-       /* Clear any pending interrupts
-        * PISR/SISR Not available on 5210 */
-       if (ah->ah_version != AR5K_AR5210)
-               ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
-
-       /* Set RSSI/BRSSI thresholds
-        *
-        * Note: If we decide to set this value
-        * dynamicaly, have in mind that when AR5K_RSSI_THR
-        * register is read it might return 0x40 if we haven't
-        * wrote anything to it plus BMISS RSSI threshold is zeroed.
-        * So doing a save/restore procedure here isn't the right
-        * choice. Instead store it on ath5k_hw */
-       ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
-                               AR5K_TUNE_BMISS_THRES <<
-                               AR5K_RSSI_THR_BMISS_S),
-                               AR5K_RSSI_THR);
-
-       /* MIC QoS support */
-       if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
-               ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
-               ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
-       }
-
-       /* QoS NOACK Policy */
-       if (ah->ah_version == AR5K_AR5212) {
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
-                       AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET)  |
-                       AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
-                       AR5K_QOS_NOACK);
-       }
-
-
-       /*
-        * Configure PHY
-        */
-
-       /* Set channel on PHY */
-       ret = ath5k_hw_channel(ah, channel);
-       if (ret)
-               return ret;
-
-       /*
-        * Enable the PHY and wait until completion
-        * This includes BaseBand and Synthesizer
-        * activation.
-        */
-       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
-
-       /*
-        * On 5211+ read activation -> rx delay
-        * and use it.
-        *
-        * TODO: Half/quarter rate support
-        */
-       if (ah->ah_version != AR5K_AR5210) {
-               u32 delay;
-               delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
-                       AR5K_PHY_RX_DELAY_M;
-               delay = (channel->hw_value & CHANNEL_CCK) ?
-                       ((delay << 2) / 22) : (delay / 10);
-
-               udelay(100 + (2 * delay));
-       } else {
-               mdelay(1);
-       }
-
-       /*
-        * Perform ADC test to see if baseband is ready
-        * Set tx hold and check adc test register
-        */
-       phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
-       ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
-       for (i = 0; i <= 20; i++) {
-               if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
-                       break;
-               udelay(200);
-       }
-       ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
-
-       /*
-        * Start automatic gain control calibration
-        *
-        * During AGC calibration RX path is re-routed to
-        * a power detector so we don't receive anything.
-        *
-        * This method is used to calibrate some static offsets
-        * used together with on-the fly I/Q calibration (the
-        * one performed via ath5k_hw_phy_calibrate), that doesn't
-        * interrupt rx path.
-        *
-        * While rx path is re-routed to the power detector we also
-        * start a noise floor calibration, to measure the
-        * card's noise floor (the noise we measure when we are not
-        * transmiting or receiving anything).
-        *
-        * If we are in a noisy environment AGC calibration may time
-        * out and/or noise floor calibration might timeout.
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
-                               AR5K_PHY_AGCCTL_CAL);
-
-       /* At the same time start I/Q calibration for QAM constellation
-        * -no need for CCK- */
-       ah->ah_calibration = false;
-       if (!(mode == AR5K_MODE_11B)) {
-               ah->ah_calibration = true;
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
-                               AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
-                               AR5K_PHY_IQ_RUN);
-       }
-
-       /* Wait for gain calibration to finish (we check for I/Q calibration
-        * during ath5k_phy_calibrate) */
-       if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
-                       AR5K_PHY_AGCCTL_CAL, 0, false)) {
-               ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
-                       channel->center_freq);
-       }
-
-       /*
-        * If we run NF calibration before AGC, it always times out.
-        * Binary HAL starts NF and AGC calibration at the same time
-        * and only waits for AGC to finish. Also if AGC or NF cal.
-        * times out, reset doesn't fail on binary HAL. I believe
-        * that's wrong because since rx path is routed to a detector,
-        * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
-        * enables noise floor calibration after offset calibration and if noise
-        * floor calibration fails, reset fails. I believe that's
-        * a better approach, we just need to find a polling interval
-        * that suits best, even if reset continues we need to make
-        * sure that rx path is ready.
-        */
-       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-
-
-       /*
-        * Configure QCUs/DCUs
-        */
-
-       /* TODO: HW Compression support for data queues */
-       /* TODO: Burst prefetch for data queues */
-
-       /*
-        * Reset queues and start beacon timers at the end of the reset routine
-        * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
-        * Note: If we want we can assign multiple qcus on one dcu.
-        */
-       for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
-               ret = ath5k_hw_reset_tx_queue(ah, i);
-               if (ret) {
-                       ATH5K_ERR(ah->ah_sc,
-                               "failed to reset TX queue #%d\n", i);
-                       return ret;
-               }
-       }
-
-
-       /*
-        * Configure DMA/Interrupts
-        */
-
-       /*
-        * Set Rx/Tx DMA Configuration
-        *
-        * Set standard DMA size (128). Note that
-        * a DMA size of 512 causes rx overruns and tx errors
-        * on pci-e cards (tested on 5424 but since rx overruns
-        * also occur on 5416/5418 with madwifi we set 128
-        * for all PCI-E cards to be safe).
-        *
-        * XXX: need to check 5210 for this
-        * TODO: Check out tx triger level, it's always 64 on dumps but I
-        * guess we can tweak it and see how it goes ;-)
-        */
-       if (ah->ah_version != AR5K_AR5210) {
-               AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
-                       AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
-               AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
-                       AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
-       }
-
-       /* Pre-enable interrupts on 5211/5212*/
-       if (ah->ah_version != AR5K_AR5210)
-               ath5k_hw_set_imr(ah, ah->ah_imr);
-
-       /*
-        * Setup RFKill interrupt if rfkill flag is set on eeprom.
-        * TODO: Use gpio pin and polarity infos from eeprom
-        * TODO: Handle this in ath5k_intr because it'll result
-        *       a nasty interrupt storm.
-        */
-#if 0
-       if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
-               ath5k_hw_set_gpio_input(ah, 0);
-               ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
-               if (ah->ah_gpio[0] == 0)
-                       ath5k_hw_set_gpio_intr(ah, 0, 1);
-               else
-                       ath5k_hw_set_gpio_intr(ah, 0, 0);
-       }
-#endif
-
-       /* Enable 32KHz clock function for AR5212+ chips
-        * Set clocks to 32KHz operation and use an
-        * external 32KHz crystal when sleeping if one
-        * exists */
-       if (ah->ah_version == AR5K_AR5212)
-                       ath5k_hw_set_sleep_clock(ah, true);
-
-       /*
-        * Disable beacons and reset the register
-        */
-       AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
-                       AR5K_BEACON_RESET_TSF);
-
-       return 0;
-}
-
-#undef _ATH5K_RESET
diff --git a/drivers/net/wireless/ath5k/rfbuffer.h b/drivers/net/wireless/ath5k/rfbuffer.h
deleted file mode 100644 (file)
index e50baff..0000000
+++ /dev/null
@@ -1,1181 +0,0 @@
-/*
- * RF Buffer handling functions
- *
- * Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-
-/*
- * There are some special registers on the RF chip
- * that control various operation settings related mostly to
- * the analog parts (channel, gain adjustment etc).
- *
- * We don't write on those registers directly but
- * we send a data packet on the chip, using a special register,
- * that holds all the settings we need. After we 've sent the
- * data packet, we write on another special register to notify hw
- * to apply the settings. This is done so that control registers
- * can be dynamicaly programmed during operation and the settings
- * are applied faster on the hw.
- *
- * We call each data packet an "RF Bank" and all the data we write
- * (all RF Banks) "RF Buffer". This file holds initial RF Buffer
- * data for the different RF chips, and various info to match RF
- * Buffer offsets with specific RF registers so that we can access
- * them. We tweak these settings on rfregs_init function.
- *
- * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer
- * registers and control registers):
- *
- * http://www.google.com/patents?id=qNURAAAAEBAJ
- */
-
-
-/*
- * Struct to hold default mode specific RF
- * register values (RF Banks)
- */
-struct ath5k_ini_rfbuffer {
-       u8      rfb_bank;               /* RF Bank number */
-       u16     rfb_ctrl_register;      /* RF Buffer control register */
-       u32     rfb_mode_data[5];       /* RF Buffer data for each mode */
-};
-
-/*
- * Struct to hold RF Buffer field
- * infos used to access certain RF
- * analog registers
- */
-struct ath5k_rfb_field {
-       u8      len;    /* Field length */
-       u16     pos;    /* Offset on the raw packet */
-       u8      col;    /* Column -used for shifting */
-};
-
-/*
- * RF analog register definition
- */
-struct ath5k_rf_reg {
-       u8                      bank;   /* RF Buffer Bank number */
-       u8                      index;  /* Register's index on rf_regs_idx */
-       struct ath5k_rfb_field  field;  /* RF Buffer field for this register */
-};
-
-/* Map RF registers to indexes
- * We do this to handle common bits and make our
- * life easier by using an index for each register
- * instead of a full rfb_field */
-enum ath5k_rf_regs_idx {
-       /* BANK 6 */
-       AR5K_RF_OB_2GHZ = 0,
-       AR5K_RF_OB_5GHZ,
-       AR5K_RF_DB_2GHZ,
-       AR5K_RF_DB_5GHZ,
-       AR5K_RF_FIXED_BIAS_A,
-       AR5K_RF_FIXED_BIAS_B,
-       AR5K_RF_PWD_XPD,
-       AR5K_RF_XPD_SEL,
-       AR5K_RF_XPD_GAIN,
-       AR5K_RF_PD_GAIN_LO,
-       AR5K_RF_PD_GAIN_HI,
-       AR5K_RF_HIGH_VC_CP,
-       AR5K_RF_MID_VC_CP,
-       AR5K_RF_LOW_VC_CP,
-       AR5K_RF_PUSH_UP,
-       AR5K_RF_PAD2GND,
-       AR5K_RF_XB2_LVL,
-       AR5K_RF_XB5_LVL,
-       AR5K_RF_PWD_ICLOBUF_2G,
-       AR5K_RF_PWD_84,
-       AR5K_RF_PWD_90,
-       AR5K_RF_PWD_130,
-       AR5K_RF_PWD_131,
-       AR5K_RF_PWD_132,
-       AR5K_RF_PWD_136,
-       AR5K_RF_PWD_137,
-       AR5K_RF_PWD_138,
-       AR5K_RF_PWD_166,
-       AR5K_RF_PWD_167,
-       AR5K_RF_DERBY_CHAN_SEL_MODE,
-       /* BANK 7 */
-       AR5K_RF_GAIN_I,
-       AR5K_RF_PLO_SEL,
-       AR5K_RF_RFGAIN_SEL,
-       AR5K_RF_RFGAIN_STEP,
-       AR5K_RF_WAIT_S,
-       AR5K_RF_WAIT_I,
-       AR5K_RF_MAX_TIME,
-       AR5K_RF_MIXVGA_OVR,
-       AR5K_RF_MIXGAIN_OVR,
-       AR5K_RF_MIXGAIN_STEP,
-       AR5K_RF_PD_DELAY_A,
-       AR5K_RF_PD_DELAY_B,
-       AR5K_RF_PD_DELAY_XR,
-       AR5K_RF_PD_PERIOD_A,
-       AR5K_RF_PD_PERIOD_B,
-       AR5K_RF_PD_PERIOD_XR,
-};
-
-
-/*******************\
-* RF5111 (Sombrero) *
-\*******************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF5111_OB_2GHZ             { 3, 119, 0 }
-#define        AR5K_RF5111_DB_2GHZ             { 3, 122, 0 }
-
-#define        AR5K_RF5111_OB_5GHZ             { 3, 104, 0 }
-#define        AR5K_RF5111_DB_5GHZ             { 3, 107, 0 }
-
-#define        AR5K_RF5111_PWD_XPD             { 1, 95,  0 }
-#define        AR5K_RF5111_XPD_GAIN            { 4, 96,  0 }
-
-/* Access to PWD registers */
-#define AR5K_RF5111_PWD(_n)            { 1, (135 - _n), 3 }
-
-/* BANK 7                              len  pos col */
-#define        AR5K_RF5111_GAIN_I              { 6, 29,  0 }
-#define        AR5K_RF5111_PLO_SEL             { 1, 4,   0 }
-#define        AR5K_RF5111_RFGAIN_SEL          { 1, 36,  0 }
-#define AR5K_RF5111_RFGAIN_STEP                { 6, 37,  0 }
-/* Only on AR5212 BaseBand and up */
-#define        AR5K_RF5111_WAIT_S              { 5, 19,  0 }
-#define        AR5K_RF5111_WAIT_I              { 5, 24,  0 }
-#define        AR5K_RF5111_MAX_TIME            { 2, 49,  0 }
-
-static const struct ath5k_rf_reg rf_regs_5111[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5111_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5111_DB_2GHZ},
-       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5111_OB_5GHZ},
-       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5111_DB_5GHZ},
-       {6, AR5K_RF_PWD_XPD,            AR5K_RF5111_PWD_XPD},
-       {6, AR5K_RF_XPD_GAIN,           AR5K_RF5111_XPD_GAIN},
-       {6, AR5K_RF_PWD_84,             AR5K_RF5111_PWD(84)},
-       {6, AR5K_RF_PWD_90,             AR5K_RF5111_PWD(90)},
-       {7, AR5K_RF_GAIN_I,             AR5K_RF5111_GAIN_I},
-       {7, AR5K_RF_PLO_SEL,            AR5K_RF5111_PLO_SEL},
-       {7, AR5K_RF_RFGAIN_SEL,         AR5K_RF5111_RFGAIN_SEL},
-       {7, AR5K_RF_RFGAIN_STEP,        AR5K_RF5111_RFGAIN_STEP},
-       {7, AR5K_RF_WAIT_S,             AR5K_RF5111_WAIT_S},
-       {7, AR5K_RF_WAIT_I,             AR5K_RF5111_WAIT_I},
-       {7, AR5K_RF_MAX_TIME,           AR5K_RF5111_MAX_TIME}
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_5111[] = {
-       { 0, 0x989c,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
-       { 0, 0x989c,
-           { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
-       { 0, 0x98d4,
-           { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
-       { 1, 0x98d4,
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d4,
-           { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
-       { 3, 0x98d8,
-           { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
-       { 6, 0x989c,
-           { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
-       { 6, 0x989c,
-           { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
-       { 6, 0x989c,
-           { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
-       { 6, 0x989c,
-           { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
-       { 6, 0x989c,
-           { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
-       { 6, 0x98d4,
-           { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
-       { 7, 0x989c,
-           { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
-       { 7, 0x989c,
-           { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
-       { 7, 0x989c,
-           { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
-       { 7, 0x989c,
-           { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
-       { 7, 0x989c,
-           { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
-       { 7, 0x989c,
-           { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
-       { 7, 0x989c,
-           { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
-};
-
-
-
-/***********************\
-* RF5112/RF2112 (Derby) *
-\***********************/
-
-/* BANK 7 (Common)                     len  pos col */
-#define        AR5K_RF5112X_GAIN_I             { 6, 14,  0 }
-#define        AR5K_RF5112X_MIXVGA_OVR         { 1, 36,  0 }
-#define        AR5K_RF5112X_MIXGAIN_OVR        { 2, 37,  0 }
-#define AR5K_RF5112X_MIXGAIN_STEP      { 4, 32,  0 }
-#define        AR5K_RF5112X_PD_DELAY_A         { 4, 58,  0 }
-#define        AR5K_RF5112X_PD_DELAY_B         { 4, 62,  0 }
-#define        AR5K_RF5112X_PD_DELAY_XR        { 4, 66,  0 }
-#define        AR5K_RF5112X_PD_PERIOD_A        { 4, 70,  0 }
-#define        AR5K_RF5112X_PD_PERIOD_B        { 4, 74,  0 }
-#define        AR5K_RF5112X_PD_PERIOD_XR       { 4, 78,  0 }
-
-/* RFX112 (Derby 1) */
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF5112_OB_2GHZ             { 3, 269, 0 }
-#define        AR5K_RF5112_DB_2GHZ             { 3, 272, 0 }
-
-#define        AR5K_RF5112_OB_5GHZ             { 3, 261, 0 }
-#define        AR5K_RF5112_DB_5GHZ             { 3, 264, 0 }
-
-#define        AR5K_RF5112_FIXED_BIAS_A        { 1, 260, 0 }
-#define        AR5K_RF5112_FIXED_BIAS_B        { 1, 259, 0 }
-
-#define        AR5K_RF5112_XPD_SEL             { 1, 284, 0 }
-#define        AR5K_RF5112_XPD_GAIN            { 2, 252, 0 }
-
-/* Access to PWD registers */
-#define AR5K_RF5112_PWD(_n)            { 1, (302 - _n), 3 }
-
-static const struct ath5k_rf_reg rf_regs_5112[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5112_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5112_DB_2GHZ},
-       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5112_OB_5GHZ},
-       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5112_DB_5GHZ},
-       {6, AR5K_RF_FIXED_BIAS_A,       AR5K_RF5112_FIXED_BIAS_A},
-       {6, AR5K_RF_FIXED_BIAS_B,       AR5K_RF5112_FIXED_BIAS_B},
-       {6, AR5K_RF_XPD_SEL,            AR5K_RF5112_XPD_SEL},
-       {6, AR5K_RF_XPD_GAIN,           AR5K_RF5112_XPD_GAIN},
-       {6, AR5K_RF_PWD_130,            AR5K_RF5112_PWD(130)},
-       {6, AR5K_RF_PWD_131,            AR5K_RF5112_PWD(131)},
-       {6, AR5K_RF_PWD_132,            AR5K_RF5112_PWD(132)},
-       {6, AR5K_RF_PWD_136,            AR5K_RF5112_PWD(136)},
-       {6, AR5K_RF_PWD_137,            AR5K_RF5112_PWD(137)},
-       {6, AR5K_RF_PWD_138,            AR5K_RF5112_PWD(138)},
-       {7, AR5K_RF_GAIN_I,             AR5K_RF5112X_GAIN_I},
-       {7, AR5K_RF_MIXVGA_OVR,         AR5K_RF5112X_MIXVGA_OVR},
-       {7, AR5K_RF_MIXGAIN_OVR,        AR5K_RF5112X_MIXGAIN_OVR},
-       {7, AR5K_RF_MIXGAIN_STEP,       AR5K_RF5112X_MIXGAIN_STEP},
-       {7, AR5K_RF_PD_DELAY_A,         AR5K_RF5112X_PD_DELAY_A},
-       {7, AR5K_RF_PD_DELAY_B,         AR5K_RF5112X_PD_DELAY_B},
-       {7, AR5K_RF_PD_DELAY_XR,        AR5K_RF5112X_PD_DELAY_XR},
-       {7, AR5K_RF_PD_PERIOD_A,        AR5K_RF5112X_PD_PERIOD_A},
-       {7, AR5K_RF_PD_PERIOD_B,        AR5K_RF5112X_PD_PERIOD_B},
-       {7, AR5K_RF_PD_PERIOD_XR,       AR5K_RF5112X_PD_PERIOD_XR},
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_5112[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
-       { 3, 0x98dc,
-           { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
-       { 6, 0x989c,
-           { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
-       { 6, 0x989c,
-           { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
-       { 6, 0x989c,
-           { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
-       { 6, 0x989c,
-           { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
-       { 6, 0x989c,
-           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
-       { 6, 0x989c,
-           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
-       { 6, 0x989c,
-           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
-       { 6, 0x989c,
-           { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
-       { 6, 0x989c,
-           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
-       { 6, 0x989c,
-           { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
-       { 6, 0x989c,
-           { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
-       { 6, 0x989c,
-           { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
-       { 6, 0x989c,
-           { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
-       { 6, 0x989c,
-           { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
-       { 6, 0x989c,
-           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
-       { 6, 0x989c,
-           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
-       { 6, 0x989c,
-           { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
-       { 6, 0x989c,
-           { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
-       { 6, 0x989c,
-           { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
-       { 6, 0x989c,
-           { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
-       { 6, 0x989c,
-           { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
-       { 6, 0x989c,
-           { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
-       { 6, 0x989c,
-           { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
-       { 6, 0x989c,
-           { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
-       { 6, 0x989c,
-           { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
-       { 6, 0x989c,
-           { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
-       { 6, 0x989c,
-           { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
-       { 6, 0x989c,
-           { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
-       { 6, 0x989c,
-           { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
-       { 6, 0x98d0,
-           { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
-       { 7, 0x989c,
-           { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
-       { 7, 0x989c,
-           { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
-       { 7, 0x989c,
-           { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
-       { 7, 0x989c,
-           { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
-       { 7, 0x989c,
-           { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
-       { 7, 0x989c,
-           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
-       { 7, 0x989c,
-           { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
-       { 7, 0x989c,
-           { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
-       { 7, 0x989c,
-           { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
-       { 7, 0x989c,
-           { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
-       { 7, 0x989c,
-           { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
-       { 7, 0x989c,
-           { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
-       { 7, 0x98c4,
-           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-/* RFX112A (Derby 2) */
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF5112A_OB_2GHZ            { 3, 287, 0 }
-#define        AR5K_RF5112A_DB_2GHZ            { 3, 290, 0 }
-
-#define        AR5K_RF5112A_OB_5GHZ            { 3, 279, 0 }
-#define        AR5K_RF5112A_DB_5GHZ            { 3, 282, 0 }
-
-#define        AR5K_RF5112A_FIXED_BIAS_A       { 1, 278, 0 }
-#define        AR5K_RF5112A_FIXED_BIAS_B       { 1, 277, 0 }
-
-#define        AR5K_RF5112A_XPD_SEL            { 1, 302, 0 }
-#define        AR5K_RF5112A_PDGAINLO           { 2, 270, 0 }
-#define        AR5K_RF5112A_PDGAINHI           { 2, 257, 0 }
-
-/* Access to PWD registers */
-#define AR5K_RF5112A_PWD(_n)           { 1, (306 - _n), 3 }
-
-/* Voltage regulators */
-#define        AR5K_RF5112A_HIGH_VC_CP         { 2, 90,  2 }
-#define        AR5K_RF5112A_MID_VC_CP          { 2, 92,  2 }
-#define        AR5K_RF5112A_LOW_VC_CP          { 2, 94,  2 }
-#define        AR5K_RF5112A_PUSH_UP            { 1, 254,  2 }
-
-/* Power consumption */
-#define        AR5K_RF5112A_PAD2GND            { 1, 281, 1 }
-#define        AR5K_RF5112A_XB2_LVL            { 2, 1,   3 }
-#define        AR5K_RF5112A_XB5_LVL            { 2, 3,   3 }
-
-static const struct ath5k_rf_reg rf_regs_5112a[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5112A_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5112A_DB_2GHZ},
-       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5112A_OB_5GHZ},
-       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5112A_DB_5GHZ},
-       {6, AR5K_RF_FIXED_BIAS_A,       AR5K_RF5112A_FIXED_BIAS_A},
-       {6, AR5K_RF_FIXED_BIAS_B,       AR5K_RF5112A_FIXED_BIAS_B},
-       {6, AR5K_RF_XPD_SEL,            AR5K_RF5112A_XPD_SEL},
-       {6, AR5K_RF_PD_GAIN_LO,         AR5K_RF5112A_PDGAINLO},
-       {6, AR5K_RF_PD_GAIN_HI,         AR5K_RF5112A_PDGAINHI},
-       {6, AR5K_RF_PWD_130,            AR5K_RF5112A_PWD(130)},
-       {6, AR5K_RF_PWD_131,            AR5K_RF5112A_PWD(131)},
-       {6, AR5K_RF_PWD_132,            AR5K_RF5112A_PWD(132)},
-       {6, AR5K_RF_PWD_136,            AR5K_RF5112A_PWD(136)},
-       {6, AR5K_RF_PWD_137,            AR5K_RF5112A_PWD(137)},
-       {6, AR5K_RF_PWD_138,            AR5K_RF5112A_PWD(138)},
-       {6, AR5K_RF_PWD_166,            AR5K_RF5112A_PWD(166)},
-       {6, AR5K_RF_PWD_167,            AR5K_RF5112A_PWD(167)},
-       {6, AR5K_RF_HIGH_VC_CP,         AR5K_RF5112A_HIGH_VC_CP},
-       {6, AR5K_RF_MID_VC_CP,          AR5K_RF5112A_MID_VC_CP},
-       {6, AR5K_RF_LOW_VC_CP,          AR5K_RF5112A_LOW_VC_CP},
-       {6, AR5K_RF_PUSH_UP,            AR5K_RF5112A_PUSH_UP},
-       {6, AR5K_RF_PAD2GND,            AR5K_RF5112A_PAD2GND},
-       {6, AR5K_RF_XB2_LVL,            AR5K_RF5112A_XB2_LVL},
-       {6, AR5K_RF_XB5_LVL,            AR5K_RF5112A_XB5_LVL},
-       {7, AR5K_RF_GAIN_I,             AR5K_RF5112X_GAIN_I},
-       {7, AR5K_RF_MIXVGA_OVR,         AR5K_RF5112X_MIXVGA_OVR},
-       {7, AR5K_RF_MIXGAIN_OVR,        AR5K_RF5112X_MIXGAIN_OVR},
-       {7, AR5K_RF_MIXGAIN_STEP,       AR5K_RF5112X_MIXGAIN_STEP},
-       {7, AR5K_RF_PD_DELAY_A,         AR5K_RF5112X_PD_DELAY_A},
-       {7, AR5K_RF_PD_DELAY_B,         AR5K_RF5112X_PD_DELAY_B},
-       {7, AR5K_RF_PD_DELAY_XR,        AR5K_RF5112X_PD_DELAY_XR},
-       {7, AR5K_RF_PD_PERIOD_A,        AR5K_RF5112X_PD_PERIOD_A},
-       {7, AR5K_RF_PD_PERIOD_B,        AR5K_RF5112X_PD_PERIOD_B},
-       {7, AR5K_RF_PD_PERIOD_XR,       AR5K_RF5112X_PD_PERIOD_XR},
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
-       { 6, 0x989c,
-           { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
-       { 6, 0x989c,
-           { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
-       { 6, 0x989c,
-           { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
-       { 6, 0x989c,
-           { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
-       { 6, 0x989c,
-           { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
-       { 6, 0x989c,
-           { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
-       { 6, 0x989c,
-           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
-       { 6, 0x989c,
-           { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
-       { 6, 0x989c,
-           { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
-       { 6, 0x989c,
-           { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
-       { 6, 0x989c,
-           { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
-       { 6, 0x989c,
-           { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
-       { 6, 0x989c,
-           { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
-       { 6, 0x989c,
-           { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
-       { 6, 0x989c,
-           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
-       { 6, 0x989c,
-           { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
-       { 6, 0x989c,
-           { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
-       { 6, 0x989c,
-           { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
-       { 6, 0x989c,
-           { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
-       { 6, 0x989c,
-           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
-       { 6, 0x989c,
-           { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
-       { 6, 0x989c,
-           { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
-       { 6, 0x989c,
-           { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
-       { 6, 0x989c,
-           { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
-       { 6, 0x98d8,
-           { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
-       { 7, 0x989c,
-           { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
-       { 7, 0x989c,
-           { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
-       { 7, 0x989c,
-           { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
-       { 7, 0x989c,
-           { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
-       { 7, 0x989c,
-           { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
-       { 7, 0x989c,
-           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
-       { 7, 0x989c,
-           { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
-       { 7, 0x989c,
-           { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
-       { 7, 0x989c,
-           { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
-       { 7, 0x989c,
-           { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
-       { 7, 0x989c,
-           { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
-       { 7, 0x989c,
-           { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
-       { 7, 0x98c4,
-           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-
-
-/******************\
-* RF2413 (Griffin) *
-\******************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF2413_OB_2GHZ             { 3, 168, 0 }
-#define        AR5K_RF2413_DB_2GHZ             { 3, 165, 0 }
-
-static const struct ath5k_rf_reg rf_regs_2413[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2413_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2413_DB_2GHZ},
-};
-
-/* Default mode specific settings
- * XXX: a/aTurbo ???
- */
-static const struct ath5k_ini_rfbuffer rfb_2413[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
-       { 6, 0x989c,
-           { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
-       { 6, 0x989c,
-           { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
-       { 6, 0x989c,
-           { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
-       { 6, 0x989c,
-           { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
-       { 6, 0x989c,
-           { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
-       { 6, 0x989c,
-           { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
-       { 6, 0x989c,
-           { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
-       { 6, 0x989c,
-           { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
-       { 6, 0x989c,
-           { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
-       { 6, 0x989c,
-           { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
-       { 6, 0x989c,
-           { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
-       { 6, 0x989c,
-           { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
-       { 6, 0x98d8,
-           { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-
-
-/***************************\
-* RF2315/RF2316 (Cobra SoC) *
-\***************************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF2316_OB_2GHZ             { 3, 178, 0 }
-#define        AR5K_RF2316_DB_2GHZ             { 3, 175, 0 }
-
-static const struct ath5k_rf_reg rf_regs_2316[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2316_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2316_DB_2GHZ},
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_2316[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
-       { 6, 0x989c,
-           { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
-       { 6, 0x989c,
-           { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
-       { 6, 0x989c,
-           { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
-       { 6, 0x989c,
-           { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
-       { 6, 0x989c,
-           { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
-       { 6, 0x989c,
-           { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
-       { 6, 0x989c,
-           { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
-       { 6, 0x989c,
-           { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
-       { 6, 0x989c,
-           { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
-       { 6, 0x989c,
-           { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
-       { 6, 0x989c,
-           { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
-       { 6, 0x989c,
-           { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
-       { 6, 0x989c,
-           { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
-       { 6, 0x989c,
-           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
-       { 6, 0x989c,
-           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
-       { 6, 0x989c,
-           { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
-       { 6, 0x989c,
-           { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
-       { 6, 0x98c0,
-           { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-
-
-/******************************\
-* RF5413/RF5424 (Eagle/Condor) *
-\******************************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF5413_OB_2GHZ             { 3, 241, 0 }
-#define        AR5K_RF5413_DB_2GHZ             { 3, 238, 0 }
-
-#define        AR5K_RF5413_OB_5GHZ             { 3, 247, 0 }
-#define        AR5K_RF5413_DB_5GHZ             { 3, 244, 0 }
-
-#define        AR5K_RF5413_PWD_ICLOBUF2G       { 3, 131, 3 }
-#define        AR5K_RF5413_DERBY_CHAN_SEL_MODE { 1, 291, 2 }
-
-static const struct ath5k_rf_reg rf_regs_5413[] = {
-       {6, AR5K_RF_OB_2GHZ,             AR5K_RF5413_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,             AR5K_RF5413_DB_2GHZ},
-       {6, AR5K_RF_OB_5GHZ,             AR5K_RF5413_OB_5GHZ},
-       {6, AR5K_RF_DB_5GHZ,             AR5K_RF5413_DB_5GHZ},
-       {6, AR5K_RF_PWD_ICLOBUF_2G,      AR5K_RF5413_PWD_ICLOBUF2G},
-       {6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE},
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_5413[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
-       { 3, 0x98dc,
-           { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
-       { 6, 0x989c,
-           { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
-       { 6, 0x989c,
-           { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
-       { 6, 0x989c,
-           { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
-       { 6, 0x989c,
-           { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
-       { 6, 0x989c,
-           { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
-       { 6, 0x989c,
-           { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
-       { 6, 0x989c,
-           { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
-       { 6, 0x989c,
-           { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
-       { 6, 0x989c,
-           { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
-       { 6, 0x989c,
-           { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
-       { 6, 0x989c,
-           { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
-       { 6, 0x989c,
-           { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
-       { 6, 0x989c,
-           { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
-       { 6, 0x989c,
-           { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
-       { 6, 0x989c,
-           { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
-       { 6, 0x989c,
-           { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
-       { 6, 0x989c,
-           { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
-       { 6, 0x989c,
-           { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
-       { 6, 0x989c,
-           { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
-       { 6, 0x989c,
-           { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
-       { 6, 0x989c,
-           { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
-       { 6, 0x98c8,
-           { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-
-
-/***************************\
-* RF2425/RF2417 (Swan/Nala) *
-* AR2317 (Spider SoC)       *
-\***************************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF2425_OB_2GHZ             { 3, 193, 0 }
-#define        AR5K_RF2425_DB_2GHZ             { 3, 190, 0 }
-
-static const struct ath5k_rf_reg rf_regs_2425[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2425_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2425_DB_2GHZ},
-};
-
-/* Default mode specific settings
- * XXX: a/aTurbo ?
- */
-static const struct ath5k_ini_rfbuffer rfb_2425[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
-       { 6, 0x989c,
-           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
-       { 6, 0x989c,
-           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
-       { 6, 0x989c,
-           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
-       { 6, 0x989c,
-           { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
-       { 6, 0x989c,
-           { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
-       { 6, 0x989c,
-           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
-       { 6, 0x989c,
-           { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
-       { 6, 0x989c,
-           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
-       { 6, 0x989c,
-           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
-       { 6, 0x989c,
-           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
-       { 6, 0x989c,
-           { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
-       { 6, 0x98c4,
-           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-/*
- * TODO: Handle the few differences with swan during
- * bank modification and get rid of this
- */
-static const struct ath5k_ini_rfbuffer rfb_2317[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
-       { 6, 0x989c,
-           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
-       { 6, 0x989c,
-           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
-       { 6, 0x989c,
-           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
-       { 6, 0x989c,
-           { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
-       { 6, 0x989c,
-           { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
-       { 6, 0x989c,
-           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
-       { 6, 0x989c,
-           { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
-       { 6, 0x989c,
-           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
-       { 6, 0x989c,
-           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
-       { 6, 0x989c,
-           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
-       { 6, 0x989c,
-           { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
-       { 6, 0x98c4,
-           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-/*
- * TODO: Handle the few differences with swan during
- * bank modification and get rid of this
- * XXX: a/aTurbo ?
- */
-static const struct ath5k_ini_rfbuffer rfb_2417[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
-       { 6, 0x989c,
-           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
-       { 6, 0x989c,
-           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
-       { 6, 0x989c,
-           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
-       { 6, 0x989c,
-           { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
-       { 6, 0x989c,
-           { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
-       { 6, 0x989c,
-           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
-       { 6, 0x989c,
-           { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
-       { 6, 0x989c,
-           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
-       { 6, 0x989c,
-           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
-       { 6, 0x989c,
-           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
-       { 6, 0x989c,
-           { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
-       { 6, 0x98c4,
-           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
diff --git a/drivers/net/wireless/ath5k/rfgain.h b/drivers/net/wireless/ath5k/rfgain.h
deleted file mode 100644 (file)
index 1354d8c..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * RF Gain optimization
- *
- * Copyright (c) 2004-2009 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*
- * Mode-specific RF Gain table (64bytes) for RF5111/5112
- * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
- * RF Gain values are included in AR5K_AR5210_INI)
- */
-struct ath5k_ini_rfgain {
-       u16     rfg_register;   /* RF Gain register address */
-       u32     rfg_value[2];   /* [freq (see below)] */
-};
-
-/* Initial RF Gain settings for RF5111 */
-static const struct ath5k_ini_rfgain rfgain_5111[] = {
-       /*                            5Ghz      2Ghz    */
-       { AR5K_RF_GAIN(0),      { 0x000001a9, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x000001e9, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000029, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x00000069, 0x00000150 } },
-       { AR5K_RF_GAIN(4),      { 0x00000199, 0x00000190 } },
-       { AR5K_RF_GAIN(5),      { 0x000001d9, 0x000001d0 } },
-       { AR5K_RF_GAIN(6),      { 0x00000019, 0x00000010 } },
-       { AR5K_RF_GAIN(7),      { 0x00000059, 0x00000044 } },
-       { AR5K_RF_GAIN(8),      { 0x00000099, 0x00000084 } },
-       { AR5K_RF_GAIN(9),      { 0x000001a5, 0x00000148 } },
-       { AR5K_RF_GAIN(10),     { 0x000001e5, 0x00000188 } },
-       { AR5K_RF_GAIN(11),     { 0x00000025, 0x000001c8 } },
-       { AR5K_RF_GAIN(12),     { 0x000001c8, 0x00000014 } },
-       { AR5K_RF_GAIN(13),     { 0x00000008, 0x00000042 } },
-       { AR5K_RF_GAIN(14),     { 0x00000048, 0x00000082 } },
-       { AR5K_RF_GAIN(15),     { 0x00000088, 0x00000178 } },
-       { AR5K_RF_GAIN(16),     { 0x00000198, 0x000001b8 } },
-       { AR5K_RF_GAIN(17),     { 0x000001d8, 0x000001f8 } },
-       { AR5K_RF_GAIN(18),     { 0x00000018, 0x00000012 } },
-       { AR5K_RF_GAIN(19),     { 0x00000058, 0x00000052 } },
-       { AR5K_RF_GAIN(20),     { 0x00000098, 0x00000092 } },
-       { AR5K_RF_GAIN(21),     { 0x000001a4, 0x0000017c } },
-       { AR5K_RF_GAIN(22),     { 0x000001e4, 0x000001bc } },
-       { AR5K_RF_GAIN(23),     { 0x00000024, 0x000001fc } },
-       { AR5K_RF_GAIN(24),     { 0x00000064, 0x0000000a } },
-       { AR5K_RF_GAIN(25),     { 0x000000a4, 0x0000004a } },
-       { AR5K_RF_GAIN(26),     { 0x000000e4, 0x0000008a } },
-       { AR5K_RF_GAIN(27),     { 0x0000010a, 0x0000015a } },
-       { AR5K_RF_GAIN(28),     { 0x0000014a, 0x0000019a } },
-       { AR5K_RF_GAIN(29),     { 0x0000018a, 0x000001da } },
-       { AR5K_RF_GAIN(30),     { 0x000001ca, 0x0000000e } },
-       { AR5K_RF_GAIN(31),     { 0x0000000a, 0x0000004e } },
-       { AR5K_RF_GAIN(32),     { 0x0000004a, 0x0000008e } },
-       { AR5K_RF_GAIN(33),     { 0x0000008a, 0x0000015e } },
-       { AR5K_RF_GAIN(34),     { 0x000001ba, 0x0000019e } },
-       { AR5K_RF_GAIN(35),     { 0x000001fa, 0x000001de } },
-       { AR5K_RF_GAIN(36),     { 0x0000003a, 0x00000009 } },
-       { AR5K_RF_GAIN(37),     { 0x0000007a, 0x00000049 } },
-       { AR5K_RF_GAIN(38),     { 0x00000186, 0x00000089 } },
-       { AR5K_RF_GAIN(39),     { 0x000001c6, 0x00000179 } },
-       { AR5K_RF_GAIN(40),     { 0x00000006, 0x000001b9 } },
-       { AR5K_RF_GAIN(41),     { 0x00000046, 0x000001f9 } },
-       { AR5K_RF_GAIN(42),     { 0x00000086, 0x00000039 } },
-       { AR5K_RF_GAIN(43),     { 0x000000c6, 0x00000079 } },
-       { AR5K_RF_GAIN(44),     { 0x000000c6, 0x000000b9 } },
-       { AR5K_RF_GAIN(45),     { 0x000000c6, 0x000001bd } },
-       { AR5K_RF_GAIN(46),     { 0x000000c6, 0x000001fd } },
-       { AR5K_RF_GAIN(47),     { 0x000000c6, 0x0000003d } },
-       { AR5K_RF_GAIN(48),     { 0x000000c6, 0x0000007d } },
-       { AR5K_RF_GAIN(49),     { 0x000000c6, 0x000000bd } },
-       { AR5K_RF_GAIN(50),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(51),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(52),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(53),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(54),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(55),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(56),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(57),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(58),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(59),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(60),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(61),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(62),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(63),     { 0x000000c6, 0x000000fd } },
-};
-
-/* Initial RF Gain settings for RF5112 */
-static const struct ath5k_ini_rfgain rfgain_5112[] = {
-       /*                            5Ghz      2Ghz    */
-       { AR5K_RF_GAIN(0),      { 0x00000007, 0x00000007 } },
-       { AR5K_RF_GAIN(1),      { 0x00000047, 0x00000047 } },
-       { AR5K_RF_GAIN(2),      { 0x00000087, 0x00000087 } },
-       { AR5K_RF_GAIN(3),      { 0x000001a0, 0x000001a0 } },
-       { AR5K_RF_GAIN(4),      { 0x000001e0, 0x000001e0 } },
-       { AR5K_RF_GAIN(5),      { 0x00000020, 0x00000020 } },
-       { AR5K_RF_GAIN(6),      { 0x00000060, 0x00000060 } },
-       { AR5K_RF_GAIN(7),      { 0x000001a1, 0x000001a1 } },
-       { AR5K_RF_GAIN(8),      { 0x000001e1, 0x000001e1 } },
-       { AR5K_RF_GAIN(9),      { 0x00000021, 0x00000021 } },
-       { AR5K_RF_GAIN(10),     { 0x00000061, 0x00000061 } },
-       { AR5K_RF_GAIN(11),     { 0x00000162, 0x00000162 } },
-       { AR5K_RF_GAIN(12),     { 0x000001a2, 0x000001a2 } },
-       { AR5K_RF_GAIN(13),     { 0x000001e2, 0x000001e2 } },
-       { AR5K_RF_GAIN(14),     { 0x00000022, 0x00000022 } },
-       { AR5K_RF_GAIN(15),     { 0x00000062, 0x00000062 } },
-       { AR5K_RF_GAIN(16),     { 0x00000163, 0x00000163 } },
-       { AR5K_RF_GAIN(17),     { 0x000001a3, 0x000001a3 } },
-       { AR5K_RF_GAIN(18),     { 0x000001e3, 0x000001e3 } },
-       { AR5K_RF_GAIN(19),     { 0x00000023, 0x00000023 } },
-       { AR5K_RF_GAIN(20),     { 0x00000063, 0x00000063 } },
-       { AR5K_RF_GAIN(21),     { 0x00000184, 0x00000184 } },
-       { AR5K_RF_GAIN(22),     { 0x000001c4, 0x000001c4 } },
-       { AR5K_RF_GAIN(23),     { 0x00000004, 0x00000004 } },
-       { AR5K_RF_GAIN(24),     { 0x000001ea, 0x0000000b } },
-       { AR5K_RF_GAIN(25),     { 0x0000002a, 0x0000004b } },
-       { AR5K_RF_GAIN(26),     { 0x0000006a, 0x0000008b } },
-       { AR5K_RF_GAIN(27),     { 0x000000aa, 0x000001ac } },
-       { AR5K_RF_GAIN(28),     { 0x000001ab, 0x000001ec } },
-       { AR5K_RF_GAIN(29),     { 0x000001eb, 0x0000002c } },
-       { AR5K_RF_GAIN(30),     { 0x0000002b, 0x00000012 } },
-       { AR5K_RF_GAIN(31),     { 0x0000006b, 0x00000052 } },
-       { AR5K_RF_GAIN(32),     { 0x000000ab, 0x00000092 } },
-       { AR5K_RF_GAIN(33),     { 0x000001ac, 0x00000193 } },
-       { AR5K_RF_GAIN(34),     { 0x000001ec, 0x000001d3 } },
-       { AR5K_RF_GAIN(35),     { 0x0000002c, 0x00000013 } },
-       { AR5K_RF_GAIN(36),     { 0x0000003a, 0x00000053 } },
-       { AR5K_RF_GAIN(37),     { 0x0000007a, 0x00000093 } },
-       { AR5K_RF_GAIN(38),     { 0x000000ba, 0x00000194 } },
-       { AR5K_RF_GAIN(39),     { 0x000001bb, 0x000001d4 } },
-       { AR5K_RF_GAIN(40),     { 0x000001fb, 0x00000014 } },
-       { AR5K_RF_GAIN(41),     { 0x0000003b, 0x0000003a } },
-       { AR5K_RF_GAIN(42),     { 0x0000007b, 0x0000007a } },
-       { AR5K_RF_GAIN(43),     { 0x000000bb, 0x000000ba } },
-       { AR5K_RF_GAIN(44),     { 0x000001bc, 0x000001bb } },
-       { AR5K_RF_GAIN(45),     { 0x000001fc, 0x000001fb } },
-       { AR5K_RF_GAIN(46),     { 0x0000003c, 0x0000003b } },
-       { AR5K_RF_GAIN(47),     { 0x0000007c, 0x0000007b } },
-       { AR5K_RF_GAIN(48),     { 0x000000bc, 0x000000bb } },
-       { AR5K_RF_GAIN(49),     { 0x000000fc, 0x000001bc } },
-       { AR5K_RF_GAIN(50),     { 0x000000fc, 0x000001fc } },
-       { AR5K_RF_GAIN(51),     { 0x000000fc, 0x0000003c } },
-       { AR5K_RF_GAIN(52),     { 0x000000fc, 0x0000007c } },
-       { AR5K_RF_GAIN(53),     { 0x000000fc, 0x000000bc } },
-       { AR5K_RF_GAIN(54),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(55),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(56),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(57),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(58),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(59),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(60),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(61),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(62),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(63),     { 0x000000fc, 0x000000fc } },
-};
-
-/* Initial RF Gain settings for RF2413 */
-static const struct ath5k_ini_rfgain rfgain_2413[] = {
-       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x00000000, 0x00000181 } },
-       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000001c1 } },
-       { AR5K_RF_GAIN(5),      { 0x00000000, 0x00000001 } },
-       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000041 } },
-       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000081 } },
-       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000168 } },
-       { AR5K_RF_GAIN(9),      { 0x00000000, 0x000001a8 } },
-       { AR5K_RF_GAIN(10),     { 0x00000000, 0x000001e8 } },
-       { AR5K_RF_GAIN(11),     { 0x00000000, 0x00000028 } },
-       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000068 } },
-       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000189 } },
-       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000001c9 } },
-       { AR5K_RF_GAIN(15),     { 0x00000000, 0x00000009 } },
-       { AR5K_RF_GAIN(16),     { 0x00000000, 0x00000049 } },
-       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000089 } },
-       { AR5K_RF_GAIN(18),     { 0x00000000, 0x00000190 } },
-       { AR5K_RF_GAIN(19),     { 0x00000000, 0x000001d0 } },
-       { AR5K_RF_GAIN(20),     { 0x00000000, 0x00000010 } },
-       { AR5K_RF_GAIN(21),     { 0x00000000, 0x00000050 } },
-       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000090 } },
-       { AR5K_RF_GAIN(23),     { 0x00000000, 0x00000191 } },
-       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000001d1 } },
-       { AR5K_RF_GAIN(25),     { 0x00000000, 0x00000011 } },
-       { AR5K_RF_GAIN(26),     { 0x00000000, 0x00000051 } },
-       { AR5K_RF_GAIN(27),     { 0x00000000, 0x00000091 } },
-       { AR5K_RF_GAIN(28),     { 0x00000000, 0x00000178 } },
-       { AR5K_RF_GAIN(29),     { 0x00000000, 0x000001b8 } },
-       { AR5K_RF_GAIN(30),     { 0x00000000, 0x000001f8 } },
-       { AR5K_RF_GAIN(31),     { 0x00000000, 0x00000038 } },
-       { AR5K_RF_GAIN(32),     { 0x00000000, 0x00000078 } },
-       { AR5K_RF_GAIN(33),     { 0x00000000, 0x00000199 } },
-       { AR5K_RF_GAIN(34),     { 0x00000000, 0x000001d9 } },
-       { AR5K_RF_GAIN(35),     { 0x00000000, 0x00000019 } },
-       { AR5K_RF_GAIN(36),     { 0x00000000, 0x00000059 } },
-       { AR5K_RF_GAIN(37),     { 0x00000000, 0x00000099 } },
-       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000d9 } },
-       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f9 } },
-};
-
-/* Initial RF Gain settings for AR2316 */
-static const struct ath5k_ini_rfgain rfgain_2316[] = {
-       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x00000000, 0x000000c0 } },
-       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000000e0 } },
-       { AR5K_RF_GAIN(5),      { 0x00000000, 0x000000e0 } },
-       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000128 } },
-       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000128 } },
-       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000128 } },
-       { AR5K_RF_GAIN(9),      { 0x00000000, 0x00000168 } },
-       { AR5K_RF_GAIN(10),     { 0x00000000, 0x000001a8 } },
-       { AR5K_RF_GAIN(11),     { 0x00000000, 0x000001e8 } },
-       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000028 } },
-       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000068 } },
-       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000000a8 } },
-       { AR5K_RF_GAIN(15),     { 0x00000000, 0x000000e8 } },
-       { AR5K_RF_GAIN(16),     { 0x00000000, 0x000000e8 } },
-       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000130 } },
-       { AR5K_RF_GAIN(18),     { 0x00000000, 0x00000130 } },
-       { AR5K_RF_GAIN(19),     { 0x00000000, 0x00000170 } },
-       { AR5K_RF_GAIN(20),     { 0x00000000, 0x000001b0 } },
-       { AR5K_RF_GAIN(21),     { 0x00000000, 0x000001f0 } },
-       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000030 } },
-       { AR5K_RF_GAIN(23),     { 0x00000000, 0x00000070 } },
-       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000000b0 } },
-       { AR5K_RF_GAIN(25),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(26),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(27),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(28),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(29),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(30),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(31),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(32),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(33),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(34),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(35),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(36),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(37),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f0 } },
-};
-
-
-/* Initial RF Gain settings for RF5413 */
-static const struct ath5k_ini_rfgain rfgain_5413[] = {
-       /*                            5Ghz      2Ghz    */
-       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x00000040, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000080, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x000001a1, 0x00000161 } },
-       { AR5K_RF_GAIN(4),      { 0x000001e1, 0x000001a1 } },
-       { AR5K_RF_GAIN(5),      { 0x00000021, 0x000001e1 } },
-       { AR5K_RF_GAIN(6),      { 0x00000061, 0x00000021 } },
-       { AR5K_RF_GAIN(7),      { 0x00000188, 0x00000061 } },
-       { AR5K_RF_GAIN(8),      { 0x000001c8, 0x00000188 } },
-       { AR5K_RF_GAIN(9),      { 0x00000008, 0x000001c8 } },
-       { AR5K_RF_GAIN(10),     { 0x00000048, 0x00000008 } },
-       { AR5K_RF_GAIN(11),     { 0x00000088, 0x00000048 } },
-       { AR5K_RF_GAIN(12),     { 0x000001a9, 0x00000088 } },
-       { AR5K_RF_GAIN(13),     { 0x000001e9, 0x00000169 } },
-       { AR5K_RF_GAIN(14),     { 0x00000029, 0x000001a9 } },
-       { AR5K_RF_GAIN(15),     { 0x00000069, 0x000001e9 } },
-       { AR5K_RF_GAIN(16),     { 0x000001d0, 0x00000029 } },
-       { AR5K_RF_GAIN(17),     { 0x00000010, 0x00000069 } },
-       { AR5K_RF_GAIN(18),     { 0x00000050, 0x00000190 } },
-       { AR5K_RF_GAIN(19),     { 0x00000090, 0x000001d0 } },
-       { AR5K_RF_GAIN(20),     { 0x000001b1, 0x00000010 } },
-       { AR5K_RF_GAIN(21),     { 0x000001f1, 0x00000050 } },
-       { AR5K_RF_GAIN(22),     { 0x00000031, 0x00000090 } },
-       { AR5K_RF_GAIN(23),     { 0x00000071, 0x00000171 } },
-       { AR5K_RF_GAIN(24),     { 0x000001b8, 0x000001b1 } },
-       { AR5K_RF_GAIN(25),     { 0x000001f8, 0x000001f1 } },
-       { AR5K_RF_GAIN(26),     { 0x00000038, 0x00000031 } },
-       { AR5K_RF_GAIN(27),     { 0x00000078, 0x00000071 } },
-       { AR5K_RF_GAIN(28),     { 0x00000199, 0x00000198 } },
-       { AR5K_RF_GAIN(29),     { 0x000001d9, 0x000001d8 } },
-       { AR5K_RF_GAIN(30),     { 0x00000019, 0x00000018 } },
-       { AR5K_RF_GAIN(31),     { 0x00000059, 0x00000058 } },
-       { AR5K_RF_GAIN(32),     { 0x00000099, 0x00000098 } },
-       { AR5K_RF_GAIN(33),     { 0x000000d9, 0x00000179 } },
-       { AR5K_RF_GAIN(34),     { 0x000000f9, 0x000001b9 } },
-       { AR5K_RF_GAIN(35),     { 0x000000f9, 0x000001f9 } },
-       { AR5K_RF_GAIN(36),     { 0x000000f9, 0x00000039 } },
-       { AR5K_RF_GAIN(37),     { 0x000000f9, 0x00000079 } },
-       { AR5K_RF_GAIN(38),     { 0x000000f9, 0x000000b9 } },
-       { AR5K_RF_GAIN(39),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(40),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(41),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(42),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(43),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(44),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(45),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(46),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(47),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(48),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(49),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(50),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(51),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(52),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(53),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(54),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(55),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(56),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(57),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(58),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(59),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(60),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(61),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(62),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(63),     { 0x000000f9, 0x000000f9 } },
-};
-
-
-/* Initial RF Gain settings for RF2425 */
-static const struct ath5k_ini_rfgain rfgain_2425[] = {
-       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x00000000, 0x00000181 } },
-       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000001c1 } },
-       { AR5K_RF_GAIN(5),      { 0x00000000, 0x00000001 } },
-       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000041 } },
-       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000081 } },
-       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000188 } },
-       { AR5K_RF_GAIN(9),      { 0x00000000, 0x000001c8 } },
-       { AR5K_RF_GAIN(10),     { 0x00000000, 0x00000008 } },
-       { AR5K_RF_GAIN(11),     { 0x00000000, 0x00000048 } },
-       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000088 } },
-       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000189 } },
-       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000001c9 } },
-       { AR5K_RF_GAIN(15),     { 0x00000000, 0x00000009 } },
-       { AR5K_RF_GAIN(16),     { 0x00000000, 0x00000049 } },
-       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000089 } },
-       { AR5K_RF_GAIN(18),     { 0x00000000, 0x000001b0 } },
-       { AR5K_RF_GAIN(19),     { 0x00000000, 0x000001f0 } },
-       { AR5K_RF_GAIN(20),     { 0x00000000, 0x00000030 } },
-       { AR5K_RF_GAIN(21),     { 0x00000000, 0x00000070 } },
-       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000171 } },
-       { AR5K_RF_GAIN(23),     { 0x00000000, 0x000001b1 } },
-       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000001f1 } },
-       { AR5K_RF_GAIN(25),     { 0x00000000, 0x00000031 } },
-       { AR5K_RF_GAIN(26),     { 0x00000000, 0x00000071 } },
-       { AR5K_RF_GAIN(27),     { 0x00000000, 0x000001b8 } },
-       { AR5K_RF_GAIN(28),     { 0x00000000, 0x000001f8 } },
-       { AR5K_RF_GAIN(29),     { 0x00000000, 0x00000038 } },
-       { AR5K_RF_GAIN(30),     { 0x00000000, 0x00000078 } },
-       { AR5K_RF_GAIN(31),     { 0x00000000, 0x000000b8 } },
-       { AR5K_RF_GAIN(32),     { 0x00000000, 0x000001b9 } },
-       { AR5K_RF_GAIN(33),     { 0x00000000, 0x000001f9 } },
-       { AR5K_RF_GAIN(34),     { 0x00000000, 0x00000039 } },
-       { AR5K_RF_GAIN(35),     { 0x00000000, 0x00000079 } },
-       { AR5K_RF_GAIN(36),     { 0x00000000, 0x000000b9 } },
-       { AR5K_RF_GAIN(37),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f9 } },
-};
-
-#define AR5K_GAIN_CRN_FIX_BITS_5111            4
-#define AR5K_GAIN_CRN_FIX_BITS_5112            7
-#define AR5K_GAIN_CRN_MAX_FIX_BITS             AR5K_GAIN_CRN_FIX_BITS_5112
-#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN         15
-#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN         20
-#define AR5K_GAIN_CCK_PROBE_CORR               5
-#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA          15
-#define AR5K_GAIN_STEP_COUNT                   10
-
-/* Check if our current measurement is inside our
- * current variable attenuation window */
-#define AR5K_GAIN_CHECK_ADJUST(_g)             \
-       ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
-
-struct ath5k_gain_opt_step {
-       s8                              gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
-       s8                              gos_gain;
-};
-
-struct ath5k_gain_opt {
-       u8                              go_default;
-       u8                              go_steps_count;
-       const struct ath5k_gain_opt_step        go_step[AR5K_GAIN_STEP_COUNT];
-};
-
-/*
- * Parameters on gos_param:
- * 1) Tx clip PHY register
- * 2) PWD 90 RF register
- * 3) PWD 84 RF register
- * 4) RFGainSel RF register
- */
-static const struct ath5k_gain_opt rfgain_opt_5111 = {
-       4,
-       9,
-       {
-               { { 4, 1, 1, 1 }, 6 },
-               { { 4, 0, 1, 1 }, 4 },
-               { { 3, 1, 1, 1 }, 3 },
-               { { 4, 0, 0, 1 }, 1 },
-               { { 4, 1, 1, 0 }, 0 },
-               { { 4, 0, 1, 0 }, -2 },
-               { { 3, 1, 1, 0 }, -3 },
-               { { 4, 0, 0, 0 }, -4 },
-               { { 2, 1, 1, 0 }, -6 }
-       }
-};
-
-/*
- * Parameters on gos_param:
- * 1) Mixgain ovr RF register
- * 2) PWD 138 RF register
- * 3) PWD 137 RF register
- * 4) PWD 136 RF register
- * 5) PWD 132 RF register
- * 6) PWD 131 RF register
- * 7) PWD 130 RF register
- */
-static const struct ath5k_gain_opt rfgain_opt_5112 = {
-       1,
-       8,
-       {
-               { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
-               { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
-               { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
-               { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
-               { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
-               { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
-               { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
-               { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
-       }
-};
-
diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig
deleted file mode 100644 (file)
index 0ed1ac3..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-config ATH9K
-       tristate "Atheros 802.11n wireless cards support"
-       depends on PCI && MAC80211 && WLAN_80211
-       depends on RFKILL || RFKILL=n
-       select ATH_COMMON
-       select MAC80211_LEDS
-       select LEDS_CLASS
-       select NEW_LEDS
-       ---help---
-         This module adds support for wireless adapters based on
-         Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
-
-         If you choose to build a module, it'll be called ath9k.
-
-config ATH9K_DEBUG
-       bool "Atheros ath9k debugging"
-       depends on ATH9K
-       ---help---
-         Say Y, if you need ath9k to display debug messages.
-         Pass the debug mask as a module parameter:
-
-         modprobe ath9k debug=0x00002000
-
-         Look in ath9k/core.h for possible debug masks
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile
deleted file mode 100644 (file)
index 783bc39..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-ath9k-y +=     hw.o \
-               eeprom.o \
-               mac.o \
-               calib.o \
-               ani.o \
-               phy.o \
-               beacon.o \
-               main.o \
-               recv.o \
-               xmit.o \
-               virtual.o \
-               rc.o
-
-ath9k-$(CONFIG_PCI) += pci.o
-ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
-ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
-
-obj-$(CONFIG_ATH9K) += ath9k.o
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath9k/ahb.c
deleted file mode 100644 (file)
index 0e65c51..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
- * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
- *
- * 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 <linux/nl80211.h>
-#include <linux/platform_device.h>
-#include <linux/ath9k_platform.h>
-#include "ath9k.h"
-
-/* return bus cachesize in 4B word units */
-static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz)
-{
-       *csz = L1_CACHE_BYTES >> 2;
-}
-
-static void ath_ahb_cleanup(struct ath_softc *sc)
-{
-       iounmap(sc->mem);
-}
-
-static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
-{
-       struct ath_softc *sc = ah->ah_sc;
-       struct platform_device *pdev = to_platform_device(sc->dev);
-       struct ath9k_platform_data *pdata;
-
-       pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
-       if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "%s: flash read failed, offset %08x is out of range\n",
-                               __func__, off);
-               return false;
-       }
-
-       *data = pdata->eeprom_data[off];
-       return true;
-}
-
-static struct ath_bus_ops ath_ahb_bus_ops  = {
-       .read_cachesize = ath_ahb_read_cachesize,
-       .cleanup = ath_ahb_cleanup,
-
-       .eeprom_read = ath_ahb_eeprom_read,
-};
-
-static int ath_ahb_probe(struct platform_device *pdev)
-{
-       void __iomem *mem;
-       struct ath_wiphy *aphy;
-       struct ath_softc *sc;
-       struct ieee80211_hw *hw;
-       struct resource *res;
-       int irq;
-       int ret = 0;
-       struct ath_hw *ah;
-
-       if (!pdev->dev.platform_data) {
-               dev_err(&pdev->dev, "no platform data specified\n");
-               ret = -EINVAL;
-               goto err_out;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "no memory resource found\n");
-               ret = -ENXIO;
-               goto err_out;
-       }
-
-       mem = ioremap_nocache(res->start, res->end - res->start + 1);
-       if (mem == NULL) {
-               dev_err(&pdev->dev, "ioremap failed\n");
-               ret = -ENOMEM;
-               goto err_out;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "no IRQ resource found\n");
-               ret = -ENXIO;
-               goto err_iounmap;
-       }
-
-       irq = res->start;
-
-       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
-                               sizeof(struct ath_softc), &ath9k_ops);
-       if (hw == NULL) {
-               dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
-               ret = -ENOMEM;
-               goto err_iounmap;
-       }
-
-       SET_IEEE80211_DEV(hw, &pdev->dev);
-       platform_set_drvdata(pdev, hw);
-
-       aphy = hw->priv;
-       sc = (struct ath_softc *) (aphy + 1);
-       aphy->sc = sc;
-       aphy->hw = hw;
-       sc->pri_wiphy = aphy;
-       sc->hw = hw;
-       sc->dev = &pdev->dev;
-       sc->mem = mem;
-       sc->bus_ops = &ath_ahb_bus_ops;
-       sc->irq = irq;
-
-       ret = ath_attach(AR5416_AR9100_DEVID, sc);
-       if (ret != 0) {
-               dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
-               ret = -ENODEV;
-               goto err_free_hw;
-       }
-
-       ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
-       if (ret) {
-               dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret);
-               ret = -EIO;
-               goto err_detach;
-       }
-
-       ah = sc->sc_ah;
-       printk(KERN_INFO
-              "%s: Atheros AR%s MAC/BB Rev:%x, "
-              "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
-              wiphy_name(hw->wiphy),
-              ath_mac_bb_name(ah->hw_version.macVersion),
-              ah->hw_version.macRev,
-              ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
-              ah->hw_version.phyRev,
-              (unsigned long)mem, irq);
-
-       return 0;
-
- err_detach:
-       ath_detach(sc);
- err_free_hw:
-       ieee80211_free_hw(hw);
-       platform_set_drvdata(pdev, NULL);
- err_iounmap:
-       iounmap(mem);
- err_out:
-       return ret;
-}
-
-static int ath_ahb_remove(struct platform_device *pdev)
-{
-       struct ieee80211_hw *hw = platform_get_drvdata(pdev);
-
-       if (hw) {
-               struct ath_wiphy *aphy = hw->priv;
-               struct ath_softc *sc = aphy->sc;
-
-               ath_cleanup(sc);
-               platform_set_drvdata(pdev, NULL);
-       }
-
-       return 0;
-}
-
-static struct platform_driver ath_ahb_driver = {
-       .probe      = ath_ahb_probe,
-       .remove     = ath_ahb_remove,
-       .driver         = {
-               .name   = "ath9k",
-               .owner  = THIS_MODULE,
-       },
-};
-
-int ath_ahb_init(void)
-{
-       return platform_driver_register(&ath_ahb_driver);
-}
-
-void ath_ahb_exit(void)
-{
-       platform_driver_unregister(&ath_ahb_driver);
-}
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c
deleted file mode 100644 (file)
index 1aeafb5..0000000
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
-                                       struct ath9k_channel *chan)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
-               if (ah->ani[i].c &&
-                   ah->ani[i].c->channel == chan->channel)
-                       return i;
-               if (ah->ani[i].c == NULL) {
-                       ah->ani[i].c = chan;
-                       return i;
-               }
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "No more channel states left. Using channel 0\n");
-
-       return 0;
-}
-
-static bool ath9k_hw_ani_control(struct ath_hw *ah,
-                                enum ath9k_ani_cmd cmd, int param)
-{
-       struct ar5416AniState *aniState = ah->curani;
-
-       switch (cmd & ah->ani_function) {
-       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "level out of range (%u > %u)\n",
-                               level,
-                               (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
-                       return false;
-               }
-
-               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
-                             AR_PHY_DESIRED_SZ_TOT_DES,
-                             ah->totalSizeDesired[level]);
-               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-                             AR_PHY_AGC_CTL1_COARSE_LOW,
-                             ah->coarse_low[level]);
-               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-                             AR_PHY_AGC_CTL1_COARSE_HIGH,
-                             ah->coarse_high[level]);
-               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-                             AR_PHY_FIND_SIG_FIRPWR,
-                             ah->firpwr[level]);
-
-               if (level > aniState->noiseImmunityLevel)
-                       ah->stats.ast_ani_niup++;
-               else if (level < aniState->noiseImmunityLevel)
-                       ah->stats.ast_ani_nidown++;
-               aniState->noiseImmunityLevel = level;
-               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 };
-               u32 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)
-                               ah->stats.ast_ani_ofdmon++;
-                       else
-                               ah->stats.ast_ani_ofdmoff++;
-                       aniState->ofdmWeakSigDetectOff = !on;
-               }
-               break;
-       }
-       case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
-               const int weakSigThrCck[] = { 8, 6 };
-               u32 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)
-                               ah->stats.ast_ani_cckhigh++;
-                       else
-                               ah->stats.ast_ani_ccklow++;
-                       aniState->cckWeakSigThreshold = high;
-               }
-               break;
-       }
-       case ATH9K_ANI_FIRSTEP_LEVEL:{
-               const int firstep[] = { 0, 4, 8 };
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(firstep)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "level out of range (%u > %u)\n",
-                               level,
-                               (unsigned) ARRAY_SIZE(firstep));
-                       return false;
-               }
-               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-                             AR_PHY_FIND_SIG_FIRSTEP,
-                             firstep[level]);
-               if (level > aniState->firstepLevel)
-                       ah->stats.ast_ani_stepup++;
-               else if (level < aniState->firstepLevel)
-                       ah->stats.ast_ani_stepdown++;
-               aniState->firstepLevel = level;
-               break;
-       }
-       case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
-               const int cycpwrThr1[] =
-                       { 2, 4, 6, 8, 10, 12, 14, 16 };
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(cycpwrThr1)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "level out of range (%u > %u)\n",
-                               level,
-                               (unsigned)
-                               ARRAY_SIZE(cycpwrThr1));
-                       return false;
-               }
-               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
-                             AR_PHY_TIMING5_CYCPWR_THR1,
-                             cycpwrThr1[level]);
-               if (level > aniState->spurImmunityLevel)
-                       ah->stats.ast_ani_spurup++;
-               else if (level < aniState->spurImmunityLevel)
-                       ah->stats.ast_ani_spurdown++;
-               aniState->spurImmunityLevel = level;
-               break;
-       }
-       case ATH9K_ANI_PRESENT:
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "invalid cmd %u\n", cmd);
-               return false;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "ANI parameters:\n");
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
-               "ofdmWeakSigDetectOff=%d\n",
-               aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
-               !aniState->ofdmWeakSigDetectOff);
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "cckWeakSigThreshold=%d, "
-               "firstepLevel=%d, listenTime=%d\n",
-               aniState->cckWeakSigThreshold, aniState->firstepLevel,
-               aniState->listenTime);
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
-               aniState->cycleCount, aniState->ofdmPhyErrCount,
-               aniState->cckPhyErrCount);
-
-       return true;
-}
-
-static void ath9k_hw_update_mibstats(struct ath_hw *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_hw *ah)
-{
-       struct ar5416AniState *aniState;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = ah->curani;
-
-       aniState->listenTime = 0;
-       if (ah->has_hw_phycounters) {
-               if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
-                       aniState->ofdmPhyErrBase = 0;
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "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;
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "CCK Trigger is too high for hw counters\n");
-               } else {
-                       aniState->cckPhyErrBase =
-                               AR_PHY_COUNTMAX - aniState->cckTrigHigh;
-               }
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Writing ofdmbase=%u   cckbase=%u\n",
-                       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, &ah->ah_mibStats);
-       }
-       aniState->ofdmPhyErrCount = 0;
-       aniState->cckPhyErrCount = 0;
-}
-
-static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-       struct ar5416AniState *aniState;
-       int32_t rssi;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = 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->opmode == NL80211_IFTYPE_AP) {
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-               }
-               return;
-       }
-       rssi = BEACON_RSSI(ah);
-       if (rssi > aniState->rssiThrHigh) {
-               if (!aniState->ofdmWeakSigDetectOff) {
-                       if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                        false)) {
-                               ath9k_hw_ani_control(ah,
-                                       ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
-                               return;
-                       }
-               }
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-                       return;
-               }
-       } else if (rssi > aniState->rssiThrLow) {
-               if (aniState->ofdmWeakSigDetectOff)
-                       ath9k_hw_ani_control(ah,
-                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    true);
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-               return;
-       } else {
-               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
-                       if (!aniState->ofdmWeakSigDetectOff)
-                               ath9k_hw_ani_control(ah,
-                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    false);
-                       if (aniState->firstepLevel > 0)
-                               ath9k_hw_ani_control(ah,
-                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
-                       return;
-               }
-       }
-}
-
-static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-       struct ar5416AniState *aniState;
-       int32_t rssi;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = 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->opmode == NL80211_IFTYPE_AP) {
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-               }
-               return;
-       }
-       rssi = BEACON_RSSI(ah);
-       if (rssi > aniState->rssiThrLow) {
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-       } else {
-               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
-                       if (aniState->firstepLevel > 0)
-                               ath9k_hw_ani_control(ah,
-                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
-               }
-       }
-}
-
-static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
-{
-       struct ar5416AniState *aniState;
-       int32_t rssi;
-
-       aniState = ah->curani;
-
-       if (ah->opmode == NL80211_IFTYPE_AP) {
-               if (aniState->firstepLevel > 0) {
-                       if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                                aniState->firstepLevel - 1))
-                               return;
-               }
-       } else {
-               rssi = BEACON_RSSI(ah);
-               if (rssi > aniState->rssiThrHigh) {
-                       /* XXX: Handle me */
-               } else if (rssi > aniState->rssiThrLow) {
-                       if (aniState->ofdmWeakSigDetectOff) {
-                               if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                        true) == true)
-                                       return;
-                       }
-                       if (aniState->firstepLevel > 0) {
-                               if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_FIRSTEP_LEVEL,
-                                        aniState->firstepLevel - 1) == true)
-                                       return;
-                       }
-               } else {
-                       if (aniState->firstepLevel > 0) {
-                               if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_FIRSTEP_LEVEL,
-                                        aniState->firstepLevel - 1) == 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) {
-               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_hw *ah)
-{
-       struct ar5416AniState *aniState;
-       u32 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 = ah->curani;
-       if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
-
-               listenTime = 0;
-               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_hw *ah)
-{
-       struct ar5416AniState *aniState;
-       struct ath9k_channel *chan = ah->curchan;
-       int index;
-
-       if (!DO_ANI(ah))
-               return;
-
-       index = ath9k_hw_get_ani_channel_idx(ah, chan);
-       aniState = &ah->ani[index];
-       ah->curani = aniState;
-
-       if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
-           && ah->opmode != NL80211_IFTYPE_ADHOC) {
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Reset ANI state opmode %u\n", ah->opmode);
-               ah->stats.ast_ani_reset++;
-
-               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    !ATH9K_ANI_USE_OFDM_WEAK_SIG);
-               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->opmode == NL80211_IFTYPE_AP) {
-                       ah->curani->ofdmTrigHigh =
-                               ah->config.ofdm_trig_high;
-                       ah->curani->ofdmTrigLow =
-                               ah->config.ofdm_trig_low;
-                       ah->curani->cckTrigHigh =
-                               ah->config.cck_trig_high;
-                       ah->curani->cckTrigLow =
-                               ah->config.cck_trig_low;
-               }
-               ath9k_ani_restart(ah);
-               return;
-       }
-
-       if (aniState->noiseImmunityLevel != 0)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
-                                    aniState->noiseImmunityLevel);
-       if (aniState->spurImmunityLevel != 0)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
-                                    aniState->spurImmunityLevel);
-       if (aniState->ofdmWeakSigDetectOff)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    !aniState->ofdmWeakSigDetectOff);
-       if (aniState->cckWeakSigThreshold)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
-                                    aniState->cckWeakSigThreshold);
-       if (aniState->firstepLevel != 0)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                    aniState->firstepLevel);
-       if (ah->has_hw_phycounters) {
-               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);
-       }
-}
-
-void ath9k_hw_ani_monitor(struct ath_hw *ah,
-                         const struct ath9k_node_stats *stats,
-                         struct ath9k_channel *chan)
-{
-       struct ar5416AniState *aniState;
-       int32_t listenTime;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = ah->curani;
-       ah->stats.ast_nodestats = *stats;
-
-       listenTime = ath9k_hw_ani_get_listen_time(ah);
-       if (listenTime < 0) {
-               ah->stats.ast_ani_lneg++;
-               ath9k_ani_restart(ah);
-               return;
-       }
-
-       aniState->listenTime += listenTime;
-
-       if (ah->has_hw_phycounters) {
-               u32 phyCnt1, phyCnt2;
-               u32 ofdmPhyErrCnt, cckPhyErrCnt;
-
-               ath9k_hw_update_mibstats(ah, &ah->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) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                       "phyCnt1 0x%x, resetting "
-                                       "counter value to 0x%x\n",
-                                       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) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                       "phyCnt2 0x%x, resetting "
-                                       "counter value to 0x%x\n",
-                                       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;
-               ah->stats.ast_ani_ofdmerrs +=
-                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
-               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
-
-               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
-               ah->stats.ast_ani_cckerrs +=
-                       cckPhyErrCnt - aniState->cckPhyErrCount;
-               aniState->cckPhyErrCount = cckPhyErrCnt;
-       }
-
-       if (aniState->listenTime > 5 * 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 > 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);
-               }
-       }
-}
-
-bool ath9k_hw_phycounters(struct ath_hw *ah)
-{
-       return ah->has_hw_phycounters ? true : false;
-}
-
-void ath9k_enable_mib_counters(struct ath_hw *ah)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
-
-       ath9k_hw_update_mibstats(ah, &ah->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);
-}
-
-/* Freeze the MIB counters, get the stats and then clear them */
-void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
-       REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
-       ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-       REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
-       REG_WRITE(ah, AR_FILT_OFDM, 0);
-       REG_WRITE(ah, AR_FILT_CCK, 0);
-}
-
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
-                                 u32 *rxc_pcnt,
-                                 u32 *rxf_pcnt,
-                                 u32 *txf_pcnt)
-{
-       static u32 cycles, rx_clear, rx_frame, tx_frame;
-       u32 good = 1;
-
-       u32 rc = REG_READ(ah, AR_RCCNT);
-       u32 rf = REG_READ(ah, AR_RFCNT);
-       u32 tf = REG_READ(ah, AR_TFCNT);
-       u32 cc = REG_READ(ah, AR_CCCNT);
-
-       if (cycles == 0 || cycles > cc) {
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "cycle counter wrap. ExtBusy = 0\n");
-               good = 0;
-       } else {
-               u32 cc_d = cc - cycles;
-               u32 rc_d = rc - rx_clear;
-               u32 rf_d = rf - rx_frame;
-               u32 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_hw *ah,
-                          const struct ath9k_node_stats *stats)
-{
-       u32 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, &ah->ah_mibStats);
-       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 = ah->curani;
-               u32 ofdmPhyErrCnt, cckPhyErrCnt;
-
-               /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
-               ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
-               ah->stats.ast_ani_ofdmerrs +=
-                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
-               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
-
-               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
-               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_hw *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++) {
-               ah->totalSizeDesired[i] = totalSizeDesired[i];
-               ah->coarse_high[i] = coarseHigh[i];
-               ah->coarse_low[i] = coarseLow[i];
-               ah->firpwr[i] = firpwr[i];
-       }
-}
-
-void ath9k_hw_ani_attach(struct ath_hw *ah)
-{
-       int i;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
-
-       ah->has_hw_phycounters = 1;
-
-       memset(ah->ani, 0, sizeof(ah->ani));
-       for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
-               ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
-               ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
-               ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
-               ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
-               ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
-               ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
-               ah->ani[i].ofdmWeakSigDetectOff =
-                       !ATH9K_ANI_USE_OFDM_WEAK_SIG;
-               ah->ani[i].cckWeakSigThreshold =
-                       ATH9K_ANI_CCK_WEAK_SIG_THR;
-               ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
-               ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-               if (ah->has_hw_phycounters) {
-                       ah->ani[i].ofdmPhyErrBase =
-                               AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
-                       ah->ani[i].cckPhyErrBase =
-                               AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
-               }
-       }
-       if (ah->has_hw_phycounters) {
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Setting OfdmErrBase = 0x%08x\n",
-                       ah->ani[0].ofdmPhyErrBase);
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
-                       ah->ani[0].cckPhyErrBase);
-
-               REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
-               REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
-               ath9k_enable_mib_counters(ah);
-       }
-       ah->aniperiod = ATH9K_ANI_PERIOD;
-       if (ah->config.enable_ani)
-               ah->proc_phyerr |= HAL_PROCESS_ANI;
-}
-
-void ath9k_hw_ani_detach(struct ath_hw *ah)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
-
-       if (ah->has_hw_phycounters) {
-               ath9k_hw_disable_mib_counters(ah);
-               REG_WRITE(ah, AR_PHY_ERR_1, 0);
-               REG_WRITE(ah, AR_PHY_ERR_2, 0);
-       }
-}
diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath9k/ani.h
deleted file mode 100644 (file)
index 08b4e7e..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 ANI_H
-#define ANI_H
-
-#define HAL_PROCESS_ANI           0x00000001
-#define ATH9K_RSSI_EP_MULTIPLIER  (1<<7)
-
-#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
-
-#define HAL_EP_RND(x, mul)                                             \
-       ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
-#define BEACON_RSSI(ahp)                                       \
-       HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi,        \
-                  ATH9K_RSSI_EP_MULTIPLIER)
-
-#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       true
-#define ATH9K_ANI_CCK_WEAK_SIG_THR        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 HAL_NOISE_IMMUNE_MAX              4
-#define HAL_SPUR_IMMUNE_MAX               7
-#define HAL_FIRST_STEP_MAX                2
-
-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
-};
-
-struct ath9k_mib_stats {
-       u32 ackrcv_bad;
-       u32 rts_bad;
-       u32 rts_good;
-       u32 fcs_bad;
-       u32 beacons;
-};
-
-struct ath9k_node_stats {
-       u32 ns_avgbrssi;
-       u32 ns_avgrssi;
-       u32 ns_avgtxrssi;
-       u32 ns_avgtxrate;
-};
-
-struct ar5416AniState {
-       struct ath9k_channel *c;
-       u8 noiseImmunityLevel;
-       u8 spurImmunityLevel;
-       u8 firstepLevel;
-       u8 ofdmWeakSigDetectOff;
-       u8 cckWeakSigThreshold;
-       u32 listenTime;
-       u32 ofdmTrigHigh;
-       u32 ofdmTrigLow;
-       int32_t cckTrigHigh;
-       int32_t cckTrigLow;
-       int32_t rssiThrLow;
-       int32_t rssiThrHigh;
-       u32 noiseFloor;
-       u32 txFrameCount;
-       u32 rxFrameCount;
-       u32 cycleCount;
-       u32 ofdmPhyErrCount;
-       u32 cckPhyErrCount;
-       u32 ofdmPhyErrBase;
-       u32 cckPhyErrBase;
-       int16_t pktRssi[2];
-       int16_t ofdmErrRssi[2];
-       int16_t cckErrRssi[2];
-};
-
-struct ar5416Stats {
-       u32 ast_ani_niup;
-       u32 ast_ani_nidown;
-       u32 ast_ani_spurup;
-       u32 ast_ani_spurdown;
-       u32 ast_ani_ofdmon;
-       u32 ast_ani_ofdmoff;
-       u32 ast_ani_cckhigh;
-       u32 ast_ani_ccklow;
-       u32 ast_ani_stepup;
-       u32 ast_ani_stepdown;
-       u32 ast_ani_ofdmerrs;
-       u32 ast_ani_cckerrs;
-       u32 ast_ani_reset;
-       u32 ast_ani_lzero;
-       u32 ast_ani_lneg;
-       struct ath9k_mib_stats ast_mibstats;
-       struct ath9k_node_stats ast_nodestats;
-};
-#define ah_mibStats stats.ast_mibstats
-
-void ath9k_ani_reset(struct ath_hw *ah);
-void ath9k_hw_ani_monitor(struct ath_hw *ah,
-                         const struct ath9k_node_stats *stats,
-                         struct ath9k_channel *chan);
-bool ath9k_hw_phycounters(struct ath_hw *ah);
-void ath9k_enable_mib_counters(struct ath_hw *ah);
-void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
-                                 u32 *rxf_pcnt, u32 *txf_pcnt);
-void ath9k_hw_procmibevent(struct ath_hw *ah,
-                          const struct ath9k_node_stats *stats);
-void ath9k_hw_ani_setup(struct ath_hw *ah);
-void ath9k_hw_ani_attach(struct ath_hw *ah);
-void ath9k_hw_ani_detach(struct ath_hw *ah);
-
-#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
deleted file mode 100644 (file)
index c92d46f..0000000
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 ATH9K_H
-#define ATH9K_H
-
-#include <linux/etherdevice.h>
-#include <linux/device.h>
-#include <net/mac80211.h>
-#include <linux/leds.h>
-#include <linux/rfkill.h>
-
-#include "hw.h"
-#include "rc.h"
-#include "debug.h"
-
-struct ath_node;
-
-/* 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 ASSERT(exp) BUG_ON(!(exp))
-
-#define TSF_TO_TU(_h,_l) \
-       ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
-
-#define        ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
-
-static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-struct ath_config {
-       u32 ath_aggr_prot;
-       u16 txpowlimit;
-       u8 cabqReadytime;
-};
-
-/*************************/
-/* Descriptor Management */
-/*************************/
-
-#define ATH_TXBUF_RESET(_bf) do {                              \
-               (_bf)->bf_stale = false;                        \
-               (_bf)->bf_lastbf = NULL;                        \
-               (_bf)->bf_next = NULL;                          \
-               memset(&((_bf)->bf_state), 0,                   \
-                      sizeof(struct ath_buf_state));           \
-       } while (0)
-
-#define ATH_RXBUF_RESET(_bf) do {              \
-               (_bf)->bf_stale = false;        \
-       } while (0)
-
-/**
- * enum buffer_type - Buffer type flags
- *
- * @BUF_HT: Send this buffer using HT capabilities
- * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
- * @BUF_AGGR: Indicates whether the buffer can be aggregated
- *     (used in aggregation scheduling)
- * @BUF_RETRY: Indicates whether the buffer is retried
- * @BUF_XRETRY: To denote excessive retries of the buffer
- */
-enum buffer_type {
-       BUF_HT                  = BIT(1),
-       BUF_AMPDU               = BIT(2),
-       BUF_AGGR                = BIT(3),
-       BUF_RETRY               = BIT(4),
-       BUF_XRETRY              = BIT(5),
-};
-
-struct ath_buf_state {
-       int bfs_nframes;
-       u16 bfs_al;
-       u16 bfs_frmlen;
-       int bfs_seqno;
-       int bfs_tidno;
-       int bfs_retries;
-       u8 bf_type;
-       u32 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_keyix                bf_state.bfs_keyix
-#define bf_keytype             bf_state.bfs_keytype
-#define bf_isht(bf)            (bf->bf_state.bf_type & BUF_HT)
-#define bf_isampdu(bf)         (bf->bf_state.bf_type & BUF_AMPDU)
-#define bf_isaggr(bf)          (bf->bf_state.bf_type & BUF_AGGR)
-#define bf_isretried(bf)       (bf->bf_state.bf_type & BUF_RETRY)
-#define bf_isxretried(bf)      (bf->bf_state.bf_type & BUF_XRETRY)
-
-struct ath_buf {
-       struct list_head list;
-       struct ath_buf *bf_lastbf;      /* last buf of this unit (a frame or
-                                          an aggregate) */
-       struct ath_buf *bf_next;        /* next subframe in the aggregate */
-       struct sk_buff *bf_mpdu;        /* enclosing frame structure */
-       struct ath_desc *bf_desc;       /* virtual addr of desc */
-       dma_addr_t bf_daddr;            /* physical addr of desc */
-       dma_addr_t bf_buf_addr;         /* physical addr of data buffer */
-       bool bf_stale;
-       u16 bf_flags;
-       struct ath_buf_state bf_state;
-       dma_addr_t bf_dmacontext;
-};
-
-struct ath_descdma {
-       struct ath_desc *dd_desc;
-       dma_addr_t dd_desc_paddr;
-       u32 dd_desc_len;
-       struct ath_buf *dd_bufptr;
-};
-
-int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
-                     struct list_head *head, const char *name,
-                     int nbuf, int ndesc);
-void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
-                        struct list_head *head);
-
-/***********/
-/* RX / TX */
-/***********/
-
-#define ATH_MAX_ANTENNA         3
-#define ATH_RXBUF               512
-#define WME_NUM_TID             16
-#define ATH_TXBUF               512
-#define ATH_TXMAXTRY            13
-#define ATH_11N_TXMAXTRY        10
-#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)
-
-#define WME_AC_BE   0
-#define WME_AC_BK   1
-#define WME_AC_VI   2
-#define WME_AC_VO   3
-#define WME_NUM_AC  4
-
-#define ADDBA_EXCHANGE_ATTEMPTS    10
-#define ATH_AGGR_DELIM_SZ          4
-#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 ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
-#define ATH_AMPDU_LIMIT_DEFAULT    ATH_AMPDU_LIMIT_MAX
-
-#define IEEE80211_SEQ_SEQ_SHIFT    4
-#define IEEE80211_SEQ_MAX          4096
-#define IEEE80211_MIN_AMPDU_BUF    0x8
-#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
-#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))
-
-/* 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)->tid[(_tidno)])
-
-enum ATH_AGGR_STATUS {
-       ATH_AGGR_DONE,
-       ATH_AGGR_BAW_CLOSED,
-       ATH_AGGR_LIMITED,
-};
-
-struct ath_txq {
-       u32 axq_qnum;
-       u32 *axq_link;
-       struct list_head axq_q;
-       spinlock_t axq_lock;
-       u32 axq_depth;
-       u8 axq_aggr_depth;
-       u32 axq_totalqueued;
-       bool stopped;
-       struct ath_buf *axq_linkbuf;
-
-       /* first desc of the last descriptor that contains CTS */
-       struct ath_desc *axq_lastdsWithCTS;
-
-       /* final desc of the gating desc that determines whether
-          lastdsWithCTS has been DMA'ed or not */
-       struct ath_desc *axq_gatingds;
-
-       struct list_head axq_acq;
-};
-
-#define AGGR_CLEANUP         BIT(1)
-#define AGGR_ADDBA_COMPLETE  BIT(2)
-#define AGGR_ADDBA_PROGRESS  BIT(3)
-
-struct ath_atx_tid {
-       struct list_head list;
-       struct list_head buf_q;
-       struct ath_node *an;
-       struct ath_atx_ac *ac;
-       struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
-       u16 seq_start;
-       u16 seq_next;
-       u16 baw_size;
-       int tidno;
-       int baw_head;   /* first un-acked tx buffer */
-       int baw_tail;   /* next unused tx buffer slot */
-       int sched;
-       int paused;
-       u8 state;
-       int addba_exchangeattempts;
-};
-
-struct ath_atx_ac {
-       int sched;
-       int qnum;
-       struct list_head list;
-       struct list_head tid_q;
-};
-
-struct ath_tx_control {
-       struct ath_txq *txq;
-       int if_id;
-       enum ath9k_internal_frame_type frame_type;
-};
-
-#define ATH_TX_ERROR        0x01
-#define ATH_TX_XRETRY       0x02
-#define ATH_TX_BAR          0x04
-
-struct ath_node {
-       struct ath_softc *an_sc;
-       struct ath_atx_tid tid[WME_NUM_TID];
-       struct ath_atx_ac ac[WME_NUM_AC];
-       u16 maxampdu;
-       u8 mpdudensity;
-};
-
-struct ath_tx {
-       u16 seq_no;
-       u32 txqsetup;
-       int hwq_map[ATH9K_WME_AC_VO+1];
-       spinlock_t txbuflock;
-       struct list_head txbuf;
-       struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
-       struct ath_descdma txdma;
-};
-
-struct ath_rx {
-       u8 defant;
-       u8 rxotherant;
-       u32 *rxlink;
-       int bufsize;
-       unsigned int rxfilter;
-       spinlock_t rxflushlock;
-       spinlock_t rxbuflock;
-       struct list_head rxbuf;
-       struct ath_descdma rxdma;
-};
-
-int ath_startrecv(struct ath_softc *sc);
-bool ath_stoprecv(struct ath_softc *sc);
-void ath_flushrecv(struct ath_softc *sc);
-u32 ath_calcrxfilter(struct ath_softc *sc);
-int ath_rx_init(struct ath_softc *sc, int nbufs);
-void ath_rx_cleanup(struct ath_softc *sc);
-int ath_rx_tasklet(struct ath_softc *sc, int flush);
-struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
-void ath_draintxq(struct ath_softc *sc,
-                    struct ath_txq *txq, bool retry_tx);
-void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
-void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_init(struct ath_softc *sc, int nbufs);
-void ath_tx_cleanup(struct ath_softc *sc);
-struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
-int ath_txq_update(struct ath_softc *sc, int qnum,
-                  struct ath9k_tx_queue_info *q);
-int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
-                struct ath_tx_control *txctl);
-void ath_tx_tasklet(struct ath_softc *sc);
-void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
-                     u16 tid, u16 *ssn);
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-
-/********/
-/* VIFs */
-/********/
-
-struct ath_vif {
-       int av_bslot;
-       __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
-       enum nl80211_iftype av_opmode;
-       struct ath_buf *av_bcbuf;
-       struct ath_tx_control av_btxctl;
-       u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
-};
-
-/*******************/
-/* 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
-#define ATH_DEFAULT_BINTVAL            100 /* TU */
-#define ATH_DEFAULT_BMISS_LIMIT        10
-#define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
-
-struct ath_beacon_config {
-       u16 beacon_interval;
-       u16 listen_interval;
-       u16 dtim_period;
-       u16 bmiss_timeout;
-       u8 dtim_count;
-};
-
-struct ath_beacon {
-       enum {
-               OK,             /* no change needed */
-               UPDATE,         /* update pending */
-               COMMIT          /* beacon sent, commit change */
-       } updateslot;           /* slot time update fsm */
-
-       u32 beaconq;
-       u32 bmisscnt;
-       u32 ast_be_xmit;
-       u64 bc_tstamp;
-       struct ieee80211_vif *bslot[ATH_BCBUF];
-       struct ath_wiphy *bslot_aphy[ATH_BCBUF];
-       int slottime;
-       int slotupdate;
-       struct ath9k_tx_queue_info beacon_qi;
-       struct ath_descdma bdma;
-       struct ath_txq *cabq;
-       struct list_head bbuf;
-};
-
-void ath_beacon_tasklet(unsigned long data);
-void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
-int ath_beaconq_setup(struct ath_hw *ah);
-int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
-void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
-
-/*******/
-/* ANI */
-/*******/
-
-#define ATH_STA_SHORT_CALINTERVAL 1000    /* 1 second */
-#define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
-#define ATH_ANI_POLLINTERVAL      100     /* 100 ms */
-#define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
-#define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
-
-struct ath_ani {
-       bool caldone;
-       int16_t noise_floor;
-       unsigned int longcal_timer;
-       unsigned int shortcal_timer;
-       unsigned int resetcal_timer;
-       unsigned int checkani_timer;
-       struct timer_list timer;
-};
-
-/********************/
-/*   LED Control    */
-/********************/
-
-#define ATH_LED_PIN    1
-#define ATH_LED_ON_DURATION_IDLE       350     /* in msecs */
-#define ATH_LED_OFF_DURATION_IDLE      250     /* in msecs */
-
-enum ath_led_type {
-       ATH_LED_RADIO,
-       ATH_LED_ASSOC,
-       ATH_LED_TX,
-       ATH_LED_RX
-};
-
-struct ath_led {
-       struct ath_softc *sc;
-       struct led_classdev led_cdev;
-       enum ath_led_type led_type;
-       char name[32];
-       bool registered;
-};
-
-/* Rfkill */
-#define ATH_RFKILL_POLL_INTERVAL       2000 /* msecs */
-
-struct ath_rfkill {
-       struct rfkill *rfkill;
-       struct delayed_work rfkill_poll;
-       char rfkill_name[32];
-};
-
-/********************/
-/* 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 */
-
-/*
- * 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_TXPOWER_MAX         100     /* .5 dBm units */
-#define ATH_RSSI_DUMMY_MARKER   0x127
-#define ATH_RATE_DUMMY_MARKER   0
-
-#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_FULL_RESET        BIT(4)
-#define SC_OP_PREAMBLE_SHORT    BIT(5)
-#define SC_OP_PROTECT_ENABLE    BIT(6)
-#define SC_OP_RXFLUSH           BIT(7)
-#define SC_OP_LED_ASSOCIATED    BIT(8)
-#define SC_OP_RFKILL_REGISTERED BIT(9)
-#define SC_OP_RFKILL_SW_BLOCKED BIT(10)
-#define SC_OP_RFKILL_HW_BLOCKED BIT(11)
-#define SC_OP_WAIT_FOR_BEACON   BIT(12)
-#define SC_OP_LED_ON            BIT(13)
-#define SC_OP_SCANNING          BIT(14)
-#define SC_OP_TSF_RESET         BIT(15)
-
-struct ath_bus_ops {
-       void            (*read_cachesize)(struct ath_softc *sc, int *csz);
-       void            (*cleanup)(struct ath_softc *sc);
-       bool            (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
-};
-
-struct ath_wiphy;
-
-struct ath_softc {
-       struct ieee80211_hw *hw;
-       struct device *dev;
-
-       spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
-       struct ath_wiphy *pri_wiphy;
-       struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
-                                      * have NULL entries */
-       int num_sec_wiphy; /* number of sec_wiphy pointers in the array */
-       int chan_idx;
-       int chan_is_ht;
-       struct ath_wiphy *next_wiphy;
-       struct work_struct chan_work;
-       int wiphy_select_failures;
-       unsigned long wiphy_select_first_fail;
-       struct delayed_work wiphy_work;
-       unsigned long wiphy_scheduler_int;
-       int wiphy_scheduler_index;
-
-       struct tasklet_struct intr_tq;
-       struct tasklet_struct bcon_tasklet;
-       struct ath_hw *sc_ah;
-       void __iomem *mem;
-       int irq;
-       spinlock_t sc_resetlock;
-       spinlock_t sc_serial_rw;
-       struct mutex mutex;
-
-       u8 curbssid[ETH_ALEN];
-       u8 bssidmask[ETH_ALEN];
-       u32 intrstatus;
-       u32 sc_flags; /* SC_OP_* */
-       u16 curtxpow;
-       u16 curaid;
-       u16 cachelsz;
-       u8 nbcnvifs;
-       u16 nvifs;
-       u8 tx_chainmask;
-       u8 rx_chainmask;
-       u32 keymax;
-       DECLARE_BITMAP(keymap, ATH_KEYMAX);
-       u8 splitmic;
-       atomic_t ps_usecount;
-       enum ath9k_int imask;
-       enum ath9k_ht_extprotspacing ht_extprotspacing;
-       enum ath9k_ht_macmode tx_chan_width;
-
-       struct ath_config config;
-       struct ath_rx rx;
-       struct ath_tx tx;
-       struct ath_beacon beacon;
-       struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
-       struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
-       struct ath_rate_table *cur_rate_table;
-       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
-
-       struct ath_led radio_led;
-       struct ath_led assoc_led;
-       struct ath_led tx_led;
-       struct ath_led rx_led;
-       struct delayed_work ath_led_blink_work;
-       int led_on_duration;
-       int led_off_duration;
-       int led_on_cnt;
-       int led_off_cnt;
-
-       struct ath_rfkill rf_kill;
-       struct ath_ani ani;
-       struct ath9k_node_stats nodestats;
-#ifdef CONFIG_ATH9K_DEBUG
-       struct ath9k_debug debug;
-#endif
-       struct ath_bus_ops *bus_ops;
-};
-
-struct ath_wiphy {
-       struct ath_softc *sc; /* shared for all virtual wiphys */
-       struct ieee80211_hw *hw;
-       enum ath_wiphy_state {
-               ATH_WIPHY_INACTIVE,
-               ATH_WIPHY_ACTIVE,
-               ATH_WIPHY_PAUSING,
-               ATH_WIPHY_PAUSED,
-               ATH_WIPHY_SCAN,
-       } state;
-       int chan_idx;
-       int chan_is_ht;
-};
-
-int ath_reset(struct ath_softc *sc, bool retry_tx);
-int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
-int ath_cabq_update(struct ath_softc *);
-
-static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
-{
-       sc->bus_ops->read_cachesize(sc, csz);
-}
-
-static inline void ath_bus_cleanup(struct ath_softc *sc)
-{
-       sc->bus_ops->cleanup(sc);
-}
-
-extern struct ieee80211_ops ath9k_ops;
-
-irqreturn_t ath_isr(int irq, void *dev);
-void ath_cleanup(struct ath_softc *sc);
-int ath_attach(u16 devid, struct ath_softc *sc);
-void ath_detach(struct ath_softc *sc);
-const char *ath_mac_bb_name(u32 mac_bb_version);
-const char *ath_rf_name(u16 rf_version);
-void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
-void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
-                          struct ath9k_channel *ichan);
-void ath_update_chainmask(struct ath_softc *sc, int is_ht);
-int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
-                   struct ath9k_channel *hchan);
-void ath_radio_enable(struct ath_softc *sc);
-void ath_radio_disable(struct ath_softc *sc);
-
-#ifdef CONFIG_PCI
-int ath_pci_init(void);
-void ath_pci_exit(void);
-#else
-static inline int ath_pci_init(void) { return 0; };
-static inline void ath_pci_exit(void) {};
-#endif
-
-#ifdef CONFIG_ATHEROS_AR71XX
-int ath_ahb_init(void);
-void ath_ahb_exit(void);
-#else
-static inline int ath_ahb_init(void) { return 0; };
-static inline void ath_ahb_exit(void) {};
-#endif
-
-static inline void ath9k_ps_wakeup(struct ath_softc *sc)
-{
-       if (atomic_inc_return(&sc->ps_usecount) == 1)
-               if (sc->sc_ah->power_mode !=  ATH9K_PM_AWAKE) {
-                       sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
-                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
-               }
-}
-
-static inline void ath9k_ps_restore(struct ath_softc *sc)
-{
-       if (atomic_dec_and_test(&sc->ps_usecount))
-               if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
-                   !(sc->sc_flags & SC_OP_WAIT_FOR_BEACON))
-                       ath9k_hw_setpower(sc->sc_ah,
-                                         sc->sc_ah->restore_mode);
-}
-
-
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
-int ath9k_wiphy_add(struct ath_softc *sc);
-int ath9k_wiphy_del(struct ath_wiphy *aphy);
-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
-int ath9k_wiphy_pause(struct ath_wiphy *aphy);
-int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
-int ath9k_wiphy_select(struct ath_wiphy *aphy);
-void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int);
-void ath9k_wiphy_chan_work(struct work_struct *work);
-bool ath9k_wiphy_started(struct ath_softc *sc);
-void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
-                                 struct ath_wiphy *selected);
-bool ath9k_wiphy_scanning(struct ath_softc *sc);
-void ath9k_wiphy_work(struct work_struct *work);
-
-/*
- * 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.
- */
-
-static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
-{
-       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
-               unsigned long flags;
-               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
-               iowrite32(val, ah->ah_sc->mem + reg_offset);
-               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
-       } else
-               iowrite32(val, ah->ah_sc->mem + reg_offset);
-}
-
-static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
-{
-       u32 val;
-       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
-               unsigned long flags;
-               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
-               val = ioread32(ah->ah_sc->mem + reg_offset);
-               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
-       } else
-               val = ioread32(ah->ah_sc->mem + reg_offset);
-       return val;
-}
-
-#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
deleted file mode 100644 (file)
index eb4759f..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-#define FUDGE 2
-
-/*
- *  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 ath_beaconq_config(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath9k_tx_queue_info qi;
-
-       ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
-       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
-               /* 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->beacon.beacon_qi.tqi_aifs;
-               qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
-               qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
-       }
-
-       if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to update h/w beacon queue parameters\n");
-               return 0;
-       } else {
-               ath9k_hw_resettxqueue(ah, sc->beacon.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 ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
-                            struct ath_buf *bf)
-{
-       struct sk_buff *skb = bf->bf_mpdu;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_desc *ds;
-       struct ath9k_11n_rate_series series[4];
-       struct ath_rate_table *rt;
-       int flags, antenna, ctsrate = 0, ctsduration = 0;
-       u8 rate;
-
-       ds = bf->bf_desc;
-       flags = ATH9K_TXDESC_NOACK;
-
-       if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
-            (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
-           (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 beacon.
-                * Should only switch every beacon period, not for every SWBA
-                * XXX assumes two antennae
-                */
-               antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
-       }
-
-       ds->ds_data = bf->bf_buf_addr;
-
-       rt = sc->cur_rate_table;
-       rate = rt->info[0].ratecode;
-       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
-               rate |= rt->info[0].short_preamble;
-
-       ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
-                              ATH9K_PKT_TYPE_BEACON,
-                              MAX_RATE_POWER,
-                              ATH9K_TXKEYIX_INVALID,
-                              ATH9K_KEY_TYPE_CLEAR,
-                              flags);
-
-       /* NB: beacon's BufLen must be a multiple of 4 bytes */
-       ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
-                           true, true, ds);
-
-       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
-       series[0].Tries = 1;
-       series[0].Rate = rate;
-       series[0].ChSel = 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);
-}
-
-static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
-                                          struct ieee80211_vif *vif)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_buf *bf;
-       struct ath_vif *avp;
-       struct sk_buff *skb;
-       struct ath_txq *cabq;
-       struct ieee80211_tx_info *info;
-       int cabq_depth;
-
-       if (aphy->state != ATH_WIPHY_ACTIVE)
-               return NULL;
-
-       avp = (void *)vif->drv_priv;
-       cabq = sc->beacon.cabq;
-
-       if (avp->av_bcbuf == NULL)
-               return NULL;
-
-       /* Release the old beacon first */
-
-       bf = avp->av_bcbuf;
-       skb = bf->bf_mpdu;
-       if (skb) {
-               dma_unmap_single(sc->dev, bf->bf_dmacontext,
-                                skb->len, DMA_TO_DEVICE);
-               dev_kfree_skb_any(skb);
-       }
-
-       /* Get a new beacon from mac80211 */
-
-       skb = ieee80211_beacon_get(hw, vif);
-       bf->bf_mpdu = skb;
-       if (skb == NULL)
-               return NULL;
-       ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
-               avp->tsf_adjust;
-
-       info = IEEE80211_SKB_CB(skb);
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               /*
-                * TODO: make sure the seq# gets assigned properly (vs. other
-                * TX frames)
-                */
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-               sc->tx.seq_no += 0x10;
-               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-       }
-
-       bf->bf_buf_addr = bf->bf_dmacontext =
-               dma_map_single(sc->dev, skb->data,
-                              skb->len, DMA_TO_DEVICE);
-       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
-               dev_kfree_skb_any(skb);
-               bf->bf_mpdu = NULL;
-               DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n");
-               return NULL;
-       }
-
-       skb = ieee80211_get_buffered_bc(hw, vif);
-
-       /*
-        * if the CABQ traffic from previous DTIM is pending and the current
-        *  beacon is also a DTIM.
-        *  1) if there is only one vif let the cab traffic continue.
-        *  2) if there are more than one vif and we are using staggered
-        *     beacons, then drain the cabq by dropping all the frames in
-        *     the cabq so that the current vifs cab traffic can be scheduled.
-        */
-       spin_lock_bh(&cabq->axq_lock);
-       cabq_depth = cabq->axq_depth;
-       spin_unlock_bh(&cabq->axq_lock);
-
-       if (skb && cabq_depth) {
-               if (sc->nvifs > 1) {
-                       DPRINTF(sc, ATH_DBG_BEACON,
-                               "Flushing previous cabq traffic\n");
-                       ath_draintxq(sc, cabq, false);
-               }
-       }
-
-       ath_beacon_setup(sc, avp, bf);
-
-       while (skb) {
-               ath_tx_cabq(hw, skb);
-               skb = ieee80211_get_buffered_bc(hw, vif);
-       }
-
-       return bf;
-}
-
-/*
- * Startup beacon transmission for adhoc mode when they are sent entirely
- * by the hardware using the self-linked descriptor + veol trick.
-*/
-static void ath_beacon_start_adhoc(struct ath_softc *sc,
-                                  struct ieee80211_vif *vif)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf;
-       struct ath_vif *avp;
-       struct sk_buff *skb;
-
-       avp = (void *)vif->drv_priv;
-
-       if (avp->av_bcbuf == NULL)
-               return;
-
-       bf = avp->av_bcbuf;
-       skb = bf->bf_mpdu;
-
-       ath_beacon_setup(sc, avp, bf);
-
-       /* NB: caller is known to have already stopped tx dma */
-       ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
-       ath9k_hw_txstart(ah, sc->beacon.beaconq);
-       DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
-               sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
-}
-
-int ath_beaconq_setup(struct ath_hw *ah)
-{
-       struct ath9k_tx_queue_info qi;
-
-       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 ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
-{
-       struct ath_softc *sc = aphy->sc;
-       struct ath_vif *avp;
-       struct ath_buf *bf;
-       struct sk_buff *skb;
-       __le64 tstamp;
-
-       avp = (void *)vif->drv_priv;
-
-       /* Allocate a beacon descriptor if we haven't done so. */
-       if (!avp->av_bcbuf) {
-               /* Allocate beacon state for hostap/ibss.  We know
-                * a buffer is available. */
-               avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
-                                                struct ath_buf, list);
-               list_del(&avp->av_bcbuf->list);
-
-               if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
-                   !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
-                       int slot;
-                       /*
-                        * Assign the vif to a beacon xmit slot. As
-                        * above, this cannot fail to find one.
-                        */
-                       avp->av_bslot = 0;
-                       for (slot = 0; slot < ATH_BCBUF; slot++)
-                               if (sc->beacon.bslot[slot] == NULL) {
-                                       /*
-                                        * XXX hack, space out slots to better
-                                        * deal with misses
-                                        */
-                                       if (slot+1 < ATH_BCBUF &&
-                                           sc->beacon.bslot[slot+1] == NULL) {
-                                               avp->av_bslot = slot+1;
-                                               break;
-                                       }
-                                       avp->av_bslot = slot;
-                                       /* NB: keep looking for a double slot */
-                               }
-                       BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
-                       sc->beacon.bslot[avp->av_bslot] = vif;
-                       sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
-                       sc->nbcnvifs++;
-               }
-       }
-
-       /* release the previous beacon frame, if it already exists. */
-       bf = avp->av_bcbuf;
-       if (bf->bf_mpdu != NULL) {
-               skb = bf->bf_mpdu;
-               dma_unmap_single(sc->dev, bf->bf_dmacontext,
-                                skb->len, DMA_TO_DEVICE);
-               dev_kfree_skb_any(skb);
-               bf->bf_mpdu = NULL;
-       }
-
-       /* NB: the beacon data buffer must be 32-bit aligned. */
-       skb = ieee80211_beacon_get(sc->hw, vif);
-       if (skb == NULL) {
-               DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
-               return -ENOMEM;
-       }
-
-       tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
-       sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
-       /* Calculate a TSF adjustment factor required for staggered beacons. */
-       if (avp->av_bslot > 0) {
-               u64 tsfadjust;
-               int intval;
-
-               intval = sc->hw->conf.beacon_int ?
-                       sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
-
-               /*
-                * Calculate the TSF offset for this beacon slot, i.e., the
-                * number of usecs that need to be added to the timestamp field
-                * in Beacon and Probe Response frames. Beacon slot 0 is
-                * processed at the correct offset, so it does not require TSF
-                * adjustment. Other slots are adjusted to get the timestamp
-                * close to the TBTT for the BSS.
-                */
-               tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
-               avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
-
-               DPRINTF(sc, ATH_DBG_BEACON,
-                       "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
-                       avp->av_bslot, intval, (unsigned long long)tsfadjust);
-
-               ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
-                       avp->tsf_adjust;
-       } else
-               avp->tsf_adjust = cpu_to_le64(0);
-
-       bf->bf_mpdu = skb;
-       bf->bf_buf_addr = bf->bf_dmacontext =
-               dma_map_single(sc->dev, skb->data,
-                              skb->len, DMA_TO_DEVICE);
-       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
-               dev_kfree_skb_any(skb);
-               bf->bf_mpdu = NULL;
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "dma_mapping_error on beacon alloc\n");
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
-{
-       if (avp->av_bcbuf != NULL) {
-               struct ath_buf *bf;
-
-               if (avp->av_bslot != -1) {
-                       sc->beacon.bslot[avp->av_bslot] = NULL;
-                       sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
-                       sc->nbcnvifs--;
-               }
-
-               bf = avp->av_bcbuf;
-               if (bf->bf_mpdu != NULL) {
-                       struct sk_buff *skb = bf->bf_mpdu;
-                       dma_unmap_single(sc->dev, bf->bf_dmacontext,
-                                        skb->len, DMA_TO_DEVICE);
-                       dev_kfree_skb_any(skb);
-                       bf->bf_mpdu = NULL;
-               }
-               list_add_tail(&bf->list, &sc->beacon.bbuf);
-
-               avp->av_bcbuf = NULL;
-       }
-}
-
-void ath_beacon_tasklet(unsigned long data)
-{
-       struct ath_softc *sc = (struct ath_softc *)data;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf = NULL;
-       struct ieee80211_vif *vif;
-       struct ath_wiphy *aphy;
-       int slot;
-       u32 bfaddr, bc = 0, tsftu;
-       u64 tsf;
-       u16 intval;
-
-       /*
-        * Check if the previous beacon has gone out.  If
-        * not don't try to post another, skip this period
-        * and wait for the next.  Missed beacons indicate
-        * a problem and should not occur.  If we miss too
-        * many consecutive beacons reset the device.
-        */
-       if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
-               sc->beacon.bmisscnt++;
-
-               if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
-                       DPRINTF(sc, ATH_DBG_BEACON,
-                               "missed %u consecutive beacons\n",
-                               sc->beacon.bmisscnt);
-               } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
-                       DPRINTF(sc, ATH_DBG_BEACON,
-                               "beacon is officially stuck\n");
-                       ath_reset(sc, false);
-               }
-
-               return;
-       }
-
-       if (sc->beacon.bmisscnt != 0) {
-               DPRINTF(sc, ATH_DBG_BEACON,
-                       "resume beacon xmit after %u misses\n",
-                       sc->beacon.bmisscnt);
-               sc->beacon.bmisscnt = 0;
-       }
-
-       /*
-        * Generate beacon frames. we are sending frames
-        * staggered so calculate the slot for this frame based
-        * on the tsf to safeguard against missing an swba.
-        */
-
-       intval = sc->hw->conf.beacon_int ?
-               sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
-
-       tsf = ath9k_hw_gettsf64(ah);
-       tsftu = TSF_TO_TU(tsf>>32, tsf);
-       slot = ((tsftu % intval) * ATH_BCBUF) / intval;
-       /*
-        * Reverse the slot order to get slot 0 on the TBTT offset that does
-        * not require TSF adjustment and other slots adding
-        * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
-        * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
-        * and slot 0 is at correct offset to TBTT.
-        */
-       slot = ATH_BCBUF - slot - 1;
-       vif = sc->beacon.bslot[slot];
-       aphy = sc->beacon.bslot_aphy[slot];
-
-       DPRINTF(sc, ATH_DBG_BEACON,
-               "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
-               slot, tsf, tsftu, intval, vif);
-
-       bfaddr = 0;
-       if (vif) {
-               bf = ath_beacon_generate(aphy->hw, vif);
-               if (bf != NULL) {
-                       bfaddr = bf->bf_daddr;
-                       bc = 1;
-               }
-       }
-
-       /*
-        * Handle slot time change when a non-ERP station joins/leaves
-        * an 11g network.  The 802.11 layer notifies us via callback,
-        * we mark updateslot, then wait one beacon before effecting
-        * the change.  This gives associated stations at least one
-        * beacon interval to note the state change.
-        *
-        * NB: The slot time change state machine is clocked according
-        *     to whether we are bursting or staggering beacons.  We
-        *     recognize the request to update and record the current
-        *     slot then don't transition until that slot is reached
-        *     again.  If we miss a beacon for that slot then we'll be
-        *     slow to transition but we'll be sure at least one beacon
-        *     interval has passed.  When bursting slot is always left
-        *     set to ATH_BCBUF so this check is a noop.
-        */
-       if (sc->beacon.updateslot == UPDATE) {
-               sc->beacon.updateslot = COMMIT; /* commit next beacon */
-               sc->beacon.slotupdate = slot;
-       } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
-               ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
-               sc->beacon.updateslot = OK;
-       }
-       if (bfaddr != 0) {
-               /*
-                * Stop any current dma and put the new frame(s) 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->beacon.beaconq)) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "beacon queue %u did not stop?\n", sc->beacon.beaconq);
-               }
-
-               /* NB: cabq traffic should already be queued and primed */
-               ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
-               ath9k_hw_txstart(ah, sc->beacon.beaconq);
-
-               sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
-       }
-}
-
-/*
- * 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.
- */
-static void ath_beacon_config_ap(struct ath_softc *sc,
-                                struct ath_beacon_config *conf,
-                                struct ath_vif *avp)
-{
-       u32 nexttbtt, intval;
-
-       /* Configure the timers only when the TSF has to be reset */
-
-       if (!(sc->sc_flags & SC_OP_TSF_RESET))
-               return;
-
-       /* NB: the beacon interval is kept internally in TU's */
-       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
-       intval /= ATH_BCBUF;    /* for staggered beacons */
-       nexttbtt = intval;
-       intval |= ATH9K_BEACON_RESET_TSF;
-
-       /*
-        * In AP mode we enable the beacon timers and SWBA interrupts to
-        * prepare beacon frames.
-        */
-       intval |= ATH9K_BEACON_ENA;
-       sc->imask |= ATH9K_INT_SWBA;
-       ath_beaconq_config(sc);
-
-       /* Set the computed AP beacon timers */
-
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
-       ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
-       sc->beacon.bmisscnt = 0;
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-
-       /* Clear the reset TSF flag, so that subsequent beacon updation
-          will not reset the HW TSF. */
-
-       sc->sc_flags &= ~SC_OP_TSF_RESET;
-}
-
-/*
- * This sets up the beacon timers according to the timestamp of the last
- * received beacon and the current TSF, configures PCF and DTIM
- * handling, programs the sleep registers so the hardware will wakeup in
- * time to receive beacons, and configures the beacon miss handling so
- * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
- * we've associated with.
- */
-static void ath_beacon_config_sta(struct ath_softc *sc,
-                                 struct ath_beacon_config *conf,
-                                 struct ath_vif *avp)
-{
-       struct ath9k_beacon_state bs;
-       int dtimperiod, dtimcount, sleepduration;
-       int cfpperiod, cfpcount;
-       u32 nexttbtt = 0, intval, tsftu;
-       u64 tsf;
-
-       memset(&bs, 0, sizeof(bs));
-       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
-
-       /*
-        * 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;
-
-       /*
-        * Pull nexttbtt forward to reflect the current
-        * TSF and calculate dtim+cfp state for the result.
-        */
-       tsf = ath9k_hw_gettsf64(sc->sc_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);
-
-       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;
-               else if (bs.bs_bmissthreshold <= 0)
-                       bs.bs_bmissthreshold = 1;
-       }
-
-       /*
-        * Calculate sleep duration. The configuration is given in ms.
-        * We ensure 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;
-
-       /* TSF out of range threshold fixed at 1 second */
-       bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
-
-       DPRINTF(sc, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
-       DPRINTF(sc, ATH_DBG_BEACON,
-               "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
-               bs.bs_bmissthreshold, bs.bs_sleepduration,
-               bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
-
-       /* Set the computed STA beacon timers */
-
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
-       ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs);
-       sc->imask |= ATH9K_INT_BMISS;
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-}
-
-static void ath_beacon_config_adhoc(struct ath_softc *sc,
-                                   struct ath_beacon_config *conf,
-                                   struct ath_vif *avp,
-                                   struct ieee80211_vif *vif)
-{
-       u64 tsf;
-       u32 tsftu, intval, nexttbtt;
-
-       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
-
-       /* Pull nexttbtt forward to reflect the current TSF */
-
-       nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
-       if (nexttbtt == 0)
-                nexttbtt = intval;
-        else if (intval)
-                nexttbtt = roundup(nexttbtt, intval);
-
-       tsf = ath9k_hw_gettsf64(sc->sc_ah);
-       tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
-       do {
-               nexttbtt += intval;
-       } while (nexttbtt < tsftu);
-
-       DPRINTF(sc, ATH_DBG_BEACON,
-               "IBSS nexttbtt %u intval %u (%u)\n",
-               nexttbtt, intval, 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 (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
-               sc->imask |= ATH9K_INT_SWBA;
-
-       ath_beaconq_config(sc);
-
-       /* Set the computed ADHOC beacon timers */
-
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
-       ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
-       sc->beacon.bmisscnt = 0;
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
-               ath_beacon_start_adhoc(sc, vif);
-}
-
-void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
-{
-       struct ath_beacon_config conf;
-
-       /* Setup the beacon configuration parameters */
-
-       memset(&conf, 0, sizeof(struct ath_beacon_config));
-       conf.beacon_interval = sc->hw->conf.beacon_int ?
-               sc->hw->conf.beacon_int : 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;
-
-       if (vif) {
-               struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
-
-               switch(avp->av_opmode) {
-               case NL80211_IFTYPE_AP:
-                       ath_beacon_config_ap(sc, &conf, avp);
-                       break;
-               case NL80211_IFTYPE_ADHOC:
-               case NL80211_IFTYPE_MESH_POINT:
-                       ath_beacon_config_adhoc(sc, &conf, avp, vif);
-                       break;
-               case NL80211_IFTYPE_STATION:
-                       ath_beacon_config_sta(sc, &conf, avp);
-                       break;
-               default:
-                       DPRINTF(sc, ATH_DBG_CONFIG,
-                               "Unsupported beaconing mode\n");
-                       return;
-               }
-
-               sc->sc_flags |= SC_OP_BEACONS;
-       }
-}
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c
deleted file mode 100644 (file)
index e2d62e9..0000000
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-/* 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 */
-
-static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
-{
-       if (nf > ATH9K_NF_TOO_LOW) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "noise floor value detected (%d) is "
-                       "lower than what we think is a "
-                       "reasonable value (%d)\n",
-                       nf, ATH9K_NF_TOO_LOW);
-               return false;
-       }
-       return 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);
-               }
-       }
-       return;
-}
-
-static void ath9k_hw_do_getnf(struct ath_hw *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);
-       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-               "NF calibrated [ctl] [chain 0] is %d\n", nf);
-       nfarray[0] = nf;
-
-       if (!AR_SREV_9285(ah)) {
-               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);
-               DPRINTF(ah->ah_sc, ATH_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);
-                       DPRINTF(ah->ah_sc, ATH_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);
-       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-               "NF calibrated [ext] [chain 0] is %d\n", nf);
-       nfarray[3] = nf;
-
-       if (!AR_SREV_9285(ah)) {
-               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);
-               DPRINTF(ah->ah_sc, ATH_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);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "NF calibrated [ext] [chain 2] is %d\n", nf);
-                       nfarray[5] = nf;
-               }
-       }
-}
-
-static bool getNoiseFloorThresh(struct ath_hw *ah,
-                               enum ieee80211_band band,
-                               int16_t *nft)
-{
-       switch (band) {
-       case IEEE80211_BAND_5GHZ:
-               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
-               break;
-       case IEEE80211_BAND_2GHZ:
-               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
-               break;
-       default:
-               BUG_ON(1);
-               return false;
-       }
-
-       return true;
-}
-
-static void ath9k_hw_setup_calibration(struct ath_hw *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);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "starting IQ Mismatch Calibration\n");
-               break;
-       case ADC_GAIN_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "starting ADC Gain Calibration\n");
-               break;
-       case ADC_DC_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "starting ADC DC Calibration\n");
-               break;
-       case ADC_DC_INIT_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "starting Init ADC DC Calibration\n");
-               break;
-       }
-
-       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
-                   AR_PHY_TIMING_CTRL4_DO_CAL);
-}
-
-static void ath9k_hw_reset_calibration(struct ath_hw *ah,
-                                      struct hal_cal_list *currCal)
-{
-       int i;
-
-       ath9k_hw_setup_calibration(ah, currCal);
-
-       currCal->calState = CAL_RUNNING;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->meas0.sign[i] = 0;
-               ah->meas1.sign[i] = 0;
-               ah->meas2.sign[i] = 0;
-               ah->meas3.sign[i] = 0;
-       }
-
-       ah->cal_samples = 0;
-}
-
-static void ath9k_hw_per_calibration(struct ath_hw *ah,
-                                    struct ath9k_channel *ichan,
-                                    u8 rxchainmask,
-                                    struct hal_cal_list *currCal,
-                                    bool *isCalDone)
-{
-       *isCalDone = 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);
-                       ah->cal_samples++;
-
-                       if (ah->cal_samples >= 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 = true;
-                       } else {
-                               ath9k_hw_setup_calibration(ah, currCal);
-                       }
-               }
-       } else if (!(ichan->CalValid & currCal->calData->calType)) {
-               ath9k_hw_reset_calibration(ah, currCal);
-       }
-}
-
-/* Assumes you are talking about the currently configured channel */
-static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
-                                    enum hal_cal_types calType)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       switch (calType & ah->supp_cals) {
-       case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
-               return true;
-       case ADC_GAIN_CAL:
-       case ADC_DC_CAL:
-               if (conf->channel->band == IEEE80211_BAND_5GHZ &&
-                 conf_is_ht20(conf))
-                       return true;
-               break;
-       }
-       return false;
-}
-
-static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalPowerMeasI[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalPowerMeasQ[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalIqCorrMeas[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
-                       ah->cal_samples, i, ah->totalPowerMeasI[i],
-                       ah->totalPowerMeasQ[i],
-                       ah->totalIqCorrMeas[i]);
-       }
-}
-
-static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalAdcIOddPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalAdcIEvenPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalAdcQOddPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ah->totalAdcQEvenPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-                       "oddq=0x%08x; evenq=0x%08x;\n",
-                       ah->cal_samples, i,
-                       ah->totalAdcIOddPhase[i],
-                       ah->totalAdcIEvenPhase[i],
-                       ah->totalAdcQOddPhase[i],
-                       ah->totalAdcQEvenPhase[i]);
-       }
-}
-
-static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalAdcDcOffsetIOddPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalAdcDcOffsetIEvenPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalAdcDcOffsetQOddPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ah->totalAdcDcOffsetQEvenPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-                       "oddq=0x%08x; evenq=0x%08x;\n",
-                       ah->cal_samples, i,
-                       ah->totalAdcDcOffsetIOddPhase[i],
-                       ah->totalAdcDcOffsetIEvenPhase[i],
-                       ah->totalAdcDcOffsetQOddPhase[i],
-                       ah->totalAdcDcOffsetQEvenPhase[i]);
-       }
-}
-
-static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
-{
-       u32 powerMeasQ, powerMeasI, iqCorrMeas;
-       u32 qCoffDenom, iCoffDenom;
-       int32_t qCoff, iCoff;
-       int iqCorrNeg, i;
-
-       for (i = 0; i < numChains; i++) {
-               powerMeasI = ah->totalPowerMeasI[i];
-               powerMeasQ = ah->totalPowerMeasQ[i];
-               iqCorrMeas = ah->totalIqCorrMeas[i];
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Starting IQ Cal and Correction for Chain %d\n",
-                       i);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Orignal: Chn %diq_corr_meas = 0x%08x\n",
-                       i, ah->totalIqCorrMeas[i]);
-
-               iqCorrNeg = 0;
-
-               if (iqCorrMeas > 0x80000000) {
-                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
-                       iqCorrNeg = 1;
-               }
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
-               DPRINTF(ah->ah_sc, ATH_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;
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "Chn %d iCoff = 0x%08x\n", i, iCoff);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "Chn %d qCoff = 0x%08x\n", i, qCoff);
-
-                       iCoff = iCoff & 0x3f;
-                       DPRINTF(ah->ah_sc, ATH_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;
-
-                       DPRINTF(ah->ah_sc, ATH_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);
-                       DPRINTF(ah->ah_sc, ATH_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_hw *ah, u8 numChains)
-{
-       u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
-       u32 qGainMismatch, iGainMismatch, val, i;
-
-       for (i = 0; i < numChains; i++) {
-               iOddMeasOffset = ah->totalAdcIOddPhase[i];
-               iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
-               qOddMeasOffset = ah->totalAdcQOddPhase[i];
-               qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Starting ADC Gain Cal for Chain %d\n", i);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
-                       iOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_even_i = 0x%08x\n", i,
-                       iEvenMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
-                       qOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_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;
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "Chn %d gain_mismatch_i = 0x%08x\n", i,
-                               iGainMismatch);
-                       DPRINTF(ah->ah_sc, ATH_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);
-
-                       DPRINTF(ah->ah_sc, ATH_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_hw *ah, u8 numChains)
-{
-       u32 iOddMeasOffset, iEvenMeasOffset, val, i;
-       int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
-       const struct hal_percal_data *calData =
-               ah->cal_list_curr->calData;
-       u32 numSamples =
-               (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
-
-       for (i = 0; i < numChains; i++) {
-               iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
-               iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
-               qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
-               qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Starting ADC DC Offset Cal for Chain %d\n", i);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_odd_i = %d\n", i,
-                       iOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_even_i = %d\n", i,
-                       iEvenMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_odd_q = %d\n", i,
-                       qOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_even_q = %d\n", i,
-                       qEvenMeasOffset);
-
-               iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
-                              numSamples) & 0x1ff;
-               qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
-                              numSamples) & 0x1ff;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
-                       iDcMismatch);
-               DPRINTF(ah->ah_sc, ATH_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);
-
-               DPRINTF(ah->ah_sc, ATH_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);
-}
-
-/* This is done for the currently configured channel */
-bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-       struct hal_cal_list *currCal = ah->cal_list_curr;
-
-       if (!ah->curchan)
-               return true;
-
-       if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
-               return true;
-
-       if (currCal == NULL)
-               return true;
-
-       if (currCal->calState != CAL_DONE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Calibration state incorrect, %d\n",
-                       currCal->calState);
-               return true;
-       }
-
-       if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
-               return true;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-               "Resetting Cal %d state for channel %u\n",
-               currCal->calData->calType, conf->channel->center_freq);
-
-       ah->curchan->CalValid &= ~currCal->calData->calType;
-       currCal->calState = CAL_WAITING;
-
-       return false;
-}
-
-void ath9k_hw_start_nfcal(struct ath_hw *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);
-}
-
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       struct ath9k_nfcal_hist *h;
-       int i, j;
-       int32_t val;
-       const u32 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
-       };
-       u8 chainmask;
-
-       if (AR_SREV_9285(ah))
-               chainmask = 0x9;
-       else if (AR_SREV_9280(ah))
-               chainmask = 0x1B;
-       else
-               chainmask = 0x3F;
-
-       h = ah->nfCalHist;
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               if (chainmask & (1 << i)) {
-                       val = REG_READ(ah, ar5416_cca_regs[i]);
-                       val &= 0xFFFFFE00;
-                       val |= (((u32) (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;
-               udelay(10);
-       }
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               if (chainmask & (1 << i)) {
-                       val = REG_READ(ah, ar5416_cca_regs[i]);
-                       val &= 0xFFFFFE00;
-                       val |= (((u32) (-50) << 1) & 0x1ff);
-                       REG_WRITE(ah, ar5416_cca_regs[i], val);
-               }
-       }
-}
-
-int16_t ath9k_hw_getnf(struct ath_hw *ah,
-                      struct ath9k_channel *chan)
-{
-       int16_t nf, nfThresh;
-       int16_t nfarray[NUM_NF_READINGS] = { 0 };
-       struct ath9k_nfcal_hist *h;
-       struct ieee80211_channel *c = chan->chan;
-
-       chan->channelFlags &= (~CHANNEL_CW_INT);
-       if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "NF did not complete in calibration window\n");
-               nf = 0;
-               chan->rawNoiseFloor = nf;
-               return chan->rawNoiseFloor;
-       } else {
-               ath9k_hw_do_getnf(ah, nfarray);
-               nf = nfarray[0];
-               if (getNoiseFloorThresh(ah, c->band, &nfThresh)
-                   && nf > nfThresh) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "noise floor failed detected; "
-                               "detected %d, threshold %d\n",
-                               nf, nfThresh);
-                       chan->channelFlags |= CHANNEL_CW_INT;
-               }
-       }
-
-       h = ah->nfCalHist;
-
-       ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
-       chan->rawNoiseFloor = h[0].privNF;
-
-       return chan->rawNoiseFloor;
-}
-
-void ath9k_init_nfcal_hist_buffer(struct ath_hw *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;
-               }
-       }
-}
-
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       s16 nf;
-
-       if (chan->rawNoiseFloor == 0)
-               nf = -96;
-       else
-               nf = chan->rawNoiseFloor;
-
-       if (!ath9k_hw_nf_in_range(ah, nf))
-               nf = ATH_DEFAULT_NOISE_FLOOR;
-
-       return nf;
-}
-
-static void ath9k_olc_temp_compensation(struct ath_hw *ah)
-{
-       u32 rddata, i;
-       int delta, currPDADC, regval;
-
-       rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
-
-       currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
-
-       if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
-               delta = (currPDADC - ah->initPDADC + 4) / 8;
-       else
-               delta = (currPDADC - ah->initPDADC + 5) / 10;
-
-       if (delta != ah->PDADCdelta) {
-               ah->PDADCdelta = delta;
-               for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
-                       regval = ah->originalGain[i] - delta;
-                       if (regval < 0)
-                               regval = 0;
-
-                       REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
-                                       AR_PHY_TX_GAIN, regval);
-               }
-       }
-}
-
-static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
-{
-
-       u32 regVal;
-       int i, offset, offs_6_1, offs_0;
-       u32 ccomp_org, reg_field;
-       u32 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));
-               udelay(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);
-       udelay(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);
-               udelay(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);
-       udelay(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);
-
-}
-
-bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-                       u8 rxchainmask, bool longcal,
-                       bool *isCalDone)
-{
-       struct hal_cal_list *currCal = ah->cal_list_curr;
-
-       *isCalDone = true;
-
-       if (currCal &&
-           (currCal->calState == CAL_RUNNING ||
-            currCal->calState == CAL_WAITING)) {
-               ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
-                                        isCalDone);
-               if (*isCalDone) {
-                       ah->cal_list_curr = currCal = currCal->calNext;
-
-                       if (currCal->calState == CAL_WAITING) {
-                               *isCalDone = false;
-                               ath9k_hw_reset_calibration(ah, currCal);
-                       }
-               }
-       }
-
-       if (longcal) {
-               if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
-                       ath9k_hw_9285_pa_cal(ah);
-
-               if (OLC_FOR_AR9280_20_LATER)
-                       ath9k_olc_temp_compensation(ah);
-               ath9k_hw_getnf(ah, chan);
-               ath9k_hw_loadnf(ah, ah->curchan);
-               ath9k_hw_start_nfcal(ah);
-
-               if (chan->channelFlags & CHANNEL_CW_INT)
-                       chan->channelFlags &= ~CHANNEL_CW_INT;
-       }
-
-       return true;
-}
-
-static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       if (chan->channelFlags & CHANNEL_HT20) {
-               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
-               REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
-               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                           AR_PHY_AGC_CONTROL_FLTR_CAL);
-               REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
-               REG_SET_BIT(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, AH_WAIT_TIMEOUT)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset "
-                               "calibration failed to complete in "
-                               "1ms; noisy ??\n");
-                       return false;
-               }
-               REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
-               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
-               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       }
-       REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-       REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
-       REG_SET_BIT(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, AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration "
-                               "failed to complete in 1ms; noisy ??\n");
-               return false;
-       }
-
-       REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-       REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-
-       return true;
-}
-
-bool ath9k_hw_init_cal(struct ath_hw *ah,
-                      struct ath9k_channel *chan)
-{
-       if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
-               if (!ar9285_clc(ah, chan))
-                       return false;
-       } else if (AR_SREV_9280_10_OR_LATER(ah)) {
-               REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-
-               /* Kick off the cal */
-               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,
-                                       AH_WAIT_TIMEOUT)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "offset calibration failed to complete in 1ms; "
-                               "noisy environment?\n");
-                       return false;
-               }
-
-               REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       }
-
-       /* Calibrate the AGC */
-       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, AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "offset calibration failed to complete in 1ms; "
-                       "noisy environment?\n");
-               return false;
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-       }
-
-       /* Do PA Calibration */
-       if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
-               ath9k_hw_9285_pa_cal(ah);
-
-       /* Do NF Calibration */
-       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-                       REG_READ(ah, AR_PHY_AGC_CONTROL) |
-                       AR_PHY_AGC_CONTROL_NF);
-
-       ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
-
-       if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
-               if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
-                       INIT_CAL(&ah->adcgain_caldata);
-                       INSERT_CAL(ah, &ah->adcgain_caldata);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                       "enabling ADC Gain Calibration.\n");
-               }
-               if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
-                       INIT_CAL(&ah->adcdc_caldata);
-                       INSERT_CAL(ah, &ah->adcdc_caldata);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                       "enabling ADC DC Calibration.\n");
-               }
-               if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
-                       INIT_CAL(&ah->iq_caldata);
-                       INSERT_CAL(ah, &ah->iq_caldata);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                       "enabling IQ Calibration.\n");
-               }
-
-               ah->cal_list_curr = ah->cal_list;
-
-               if (ah->cal_list_curr)
-                       ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
-       }
-
-       chan->CalValid = 0;
-
-       return 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
-};
diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath9k/calib.h
deleted file mode 100644 (file)
index 1c74bd5..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 CALIB_H
-#define CALIB_H
-
-extern const struct hal_percal_data iq_cal_multi_sample;
-extern const struct hal_percal_data iq_cal_single_sample;
-extern const struct hal_percal_data adc_gain_cal_multi_sample;
-extern const struct hal_percal_data adc_gain_cal_single_sample;
-extern const struct hal_percal_data adc_dc_cal_multi_sample;
-extern const struct hal_percal_data adc_dc_cal_single_sample;
-extern const struct hal_percal_data adc_init_dc_cal;
-
-#define AR_PHY_CCA_MAX_GOOD_VALUE                      -85
-#define AR_PHY_CCA_MAX_HIGH_VALUE                      -62
-#define AR_PHY_CCA_MIN_BAD_VALUE                       -140
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
-
-#define NUM_NF_READINGS       6
-#define ATH9K_NF_CAL_HIST_MAX 5
-
-struct ar5416IniArray {
-       u32 *ia_array;
-       u32 ia_rows;
-       u32 ia_columns;
-};
-
-#define INIT_INI_ARRAY(iniarray, array, rows, columns) do {    \
-               (iniarray)->ia_array = (u32 *)(array);          \
-               (iniarray)->ia_rows = (rows);                   \
-               (iniarray)->ia_columns = (columns);             \
-       } 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)->cal_list_last == NULL) {                    \
-                       (_ahp)->cal_list =                              \
-                               (_ahp)->cal_list_last = (_perCal);      \
-                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
-               } else {                                                \
-                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
-                       (_ahp)->cal_list_last = (_perCal);              \
-                       (_perCal)->calNext = (_ahp)->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;
-       u32 calNumSamples;
-       u32 calCountMax;
-       void (*calCollect) (struct ath_hw *);
-       void (*calPostProc) (struct ath_hw *, u8);
-};
-
-struct hal_cal_list {
-       const struct hal_percal_data *calData;
-       enum hal_cal_state calState;
-       struct hal_cal_list *calNext;
-};
-
-struct ath9k_nfcal_hist {
-       int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
-       u8 currIndex;
-       int16_t privNF;
-       u8 invalidNFcount;
-};
-
-bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
-void ath9k_hw_start_nfcal(struct ath_hw *ah);
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
-int16_t ath9k_hw_getnf(struct ath_hw *ah,
-                      struct ath9k_channel *chan);
-void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
-bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-                       u8 rxchainmask, bool longcal,
-                       bool *isCalDone);
-bool ath9k_hw_init_cal(struct ath_hw *ah,
-                      struct ath9k_channel *chan);
-
-#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c
deleted file mode 100644 (file)
index 97df20c..0000000
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 <asm/unaligned.h>
-
-#include "ath9k.h"
-
-static unsigned int ath9k_debug = DBG_DEFAULT;
-module_param_named(debug, ath9k_debug, uint, 0);
-
-static struct dentry *ath9k_debugfs_root;
-
-void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
-{
-       if (!sc)
-               return;
-
-       if (sc->debug.debug_mask & dbg_mask) {
-               va_list args;
-
-               va_start(args, fmt);
-               printk(KERN_DEBUG "ath9k: ");
-               vprintk(fmt, args);
-               va_end(args);
-       }
-}
-
-static int ath9k_debugfs_open(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-static ssize_t read_file_dma(struct file *file, char __user *user_buf,
-                            size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       struct ath_hw *ah = sc->sc_ah;
-       char buf[1024];
-       unsigned int len = 0;
-       u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
-       int i, qcuOffset = 0, dcuOffset = 0;
-       u32 *qcuBase = &val[0], *dcuBase = &val[4];
-
-       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)));
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "Raw DMA Debug values:\n");
-
-       for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
-               if (i % 4 == 0)
-                       len += snprintf(buf + len, sizeof(buf) - len, "\n");
-
-               val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
-               len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ",
-                               i, val[i]);
-       }
-
-       len += snprintf(buf + len, sizeof(buf) - len, "\n\n");
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "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++;
-               }
-
-               len += snprintf(buf + len, sizeof(buf) - len,
-                       "%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);
-       }
-
-       len += snprintf(buf + len, sizeof(buf) - len, "\n");
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
-               (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "qcu_complete state: %2x    dcu_complete state:     %2x\n",
-               (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "dcu_arb state:      %2x    dcu_fp state:           %2x\n",
-               (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
-               (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
-               (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
-               (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
-
-       len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n",
-                       REG_READ(ah, AR_OBS_BUS_1));
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "AR_CR: 0x%x \n", REG_READ(ah, AR_CR));
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_dma = {
-       .read = read_file_dma,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
-
-void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
-{
-       if (status)
-               sc->debug.stats.istats.total++;
-       if (status & ATH9K_INT_RX)
-               sc->debug.stats.istats.rxok++;
-       if (status & ATH9K_INT_RXEOL)
-               sc->debug.stats.istats.rxeol++;
-       if (status & ATH9K_INT_RXORN)
-               sc->debug.stats.istats.rxorn++;
-       if (status & ATH9K_INT_TX)
-               sc->debug.stats.istats.txok++;
-       if (status & ATH9K_INT_TXURN)
-               sc->debug.stats.istats.txurn++;
-       if (status & ATH9K_INT_MIB)
-               sc->debug.stats.istats.mib++;
-       if (status & ATH9K_INT_RXPHY)
-               sc->debug.stats.istats.rxphyerr++;
-       if (status & ATH9K_INT_RXKCM)
-               sc->debug.stats.istats.rx_keycache_miss++;
-       if (status & ATH9K_INT_SWBA)
-               sc->debug.stats.istats.swba++;
-       if (status & ATH9K_INT_BMISS)
-               sc->debug.stats.istats.bmiss++;
-       if (status & ATH9K_INT_BNR)
-               sc->debug.stats.istats.bnr++;
-       if (status & ATH9K_INT_CST)
-               sc->debug.stats.istats.cst++;
-       if (status & ATH9K_INT_GTT)
-               sc->debug.stats.istats.gtt++;
-       if (status & ATH9K_INT_TIM)
-               sc->debug.stats.istats.tim++;
-       if (status & ATH9K_INT_CABEND)
-               sc->debug.stats.istats.cabend++;
-       if (status & ATH9K_INT_DTIMSYNC)
-               sc->debug.stats.istats.dtimsync++;
-       if (status & ATH9K_INT_DTIM)
-               sc->debug.stats.istats.dtim++;
-}
-
-static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[512];
-       unsigned int len = 0;
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_interrupt = {
-       .read = read_file_interrupt,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
-static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb)
-{
-       struct ath_tx_info_priv *tx_info_priv = NULL;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_rate *rates = tx_info->status.rates;
-       int final_ts_idx, idx;
-
-       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       final_ts_idx = tx_info_priv->tx.ts_rateindex;
-       idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
-
-       sc->debug.stats.n_rcstats[idx].success++;
-}
-
-static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
-{
-       struct ath_tx_info_priv *tx_info_priv = NULL;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_rate *rates = tx_info->status.rates;
-       int final_ts_idx, idx;
-
-       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       final_ts_idx = tx_info_priv->tx.ts_rateindex;
-       idx = rates[final_ts_idx].idx;
-
-       sc->debug.stats.legacy_rcstats[idx].success++;
-}
-
-void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
-{
-       if (conf_is_ht(&sc->hw->conf))
-               ath_debug_stat_11n_rc(sc, skb);
-       else
-               ath_debug_stat_legacy_rc(sc, skb);
-}
-
-/* FIXME: legacy rates, later on .. */
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                           int xretries, int retries, u8 per)
-{
-       if (conf_is_ht(&sc->hw->conf)) {
-               int idx = sc->cur_rate_table->info[rix].dot11rate;
-
-               sc->debug.stats.n_rcstats[idx].xretries += xretries;
-               sc->debug.stats.n_rcstats[idx].retries += retries;
-               sc->debug.stats.n_rcstats[idx].per = per;
-       }
-}
-
-static ssize_t ath_read_file_stat_11n_rc(struct file *file,
-                                        char __user *user_buf,
-                                        size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[1024];
-       unsigned int len = 0;
-       int i = 0;
-
-       len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success",
-                      "Retries", "XRetries", "PER");
-
-       for (i = 0; i <= 15; i++) {
-               len += snprintf(buf + len, sizeof(buf) - len,
-                               "%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
-                               sc->debug.stats.n_rcstats[i].success,
-                               sc->debug.stats.n_rcstats[i].retries,
-                               sc->debug.stats.n_rcstats[i].xretries,
-                               sc->debug.stats.n_rcstats[i].per);
-       }
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath_read_file_stat_legacy_rc(struct file *file,
-                                           char __user *user_buf,
-                                           size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[512];
-       unsigned int len = 0;
-       int i = 0;
-
-       len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success");
-
-       for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
-               len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n",
-                               sc->cur_rate_table->info[i].ratekbps / 1000,
-                               sc->debug.stats.legacy_rcstats[i].success);
-       }
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
-                               size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-
-       if (sc->cur_rate_table == NULL)
-               return 0;
-
-       if (conf_is_ht(&sc->hw->conf))
-               return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
-       else
-               return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
-}
-
-static const struct file_operations fops_rcstat = {
-       .read = read_file_rcstat,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
-static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
-{
-       switch (state) {
-       case ATH_WIPHY_INACTIVE:
-               return "INACTIVE";
-       case ATH_WIPHY_ACTIVE:
-               return "ACTIVE";
-       case ATH_WIPHY_PAUSING:
-               return "PAUSING";
-       case ATH_WIPHY_PAUSED:
-               return "PAUSED";
-       case ATH_WIPHY_SCAN:
-               return "SCAN";
-       }
-       return "?";
-}
-
-static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
-                              size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[512];
-       unsigned int len = 0;
-       int i;
-       u8 addr[ETH_ALEN];
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "primary: %s (%s chan=%d ht=%d)\n",
-                       wiphy_name(sc->pri_wiphy->hw->wiphy),
-                       ath_wiphy_state_str(sc->pri_wiphy->state),
-                       sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-               if (aphy == NULL)
-                       continue;
-               len += snprintf(buf + len, sizeof(buf) - len,
-                               "secondary: %s (%s chan=%d ht=%d)\n",
-                               wiphy_name(aphy->hw->wiphy),
-                               ath_wiphy_state_str(aphy->state),
-                               aphy->chan_idx, aphy->chan_is_ht);
-       }
-
-       put_unaligned_le32(REG_READ(sc->sc_ah, AR_STA_ID0), addr);
-       put_unaligned_le16(REG_READ(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "addr: %pM\n", addr);
-       put_unaligned_le32(REG_READ(sc->sc_ah, AR_BSSMSKL), addr);
-       put_unaligned_le16(REG_READ(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "addrmask: %pM\n", addr);
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name)
-{
-       int i;
-       if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0)
-               return sc->pri_wiphy;
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-               if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0)
-                       return aphy;
-       }
-       return NULL;
-}
-
-static int del_wiphy(struct ath_softc *sc, const char *name)
-{
-       struct ath_wiphy *aphy = get_wiphy(sc, name);
-       if (!aphy)
-               return -ENOENT;
-       return ath9k_wiphy_del(aphy);
-}
-
-static int pause_wiphy(struct ath_softc *sc, const char *name)
-{
-       struct ath_wiphy *aphy = get_wiphy(sc, name);
-       if (!aphy)
-               return -ENOENT;
-       return ath9k_wiphy_pause(aphy);
-}
-
-static int unpause_wiphy(struct ath_softc *sc, const char *name)
-{
-       struct ath_wiphy *aphy = get_wiphy(sc, name);
-       if (!aphy)
-               return -ENOENT;
-       return ath9k_wiphy_unpause(aphy);
-}
-
-static int select_wiphy(struct ath_softc *sc, const char *name)
-{
-       struct ath_wiphy *aphy = get_wiphy(sc, name);
-       if (!aphy)
-               return -ENOENT;
-       return ath9k_wiphy_select(aphy);
-}
-
-static int schedule_wiphy(struct ath_softc *sc, const char *msec)
-{
-       ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0));
-       return 0;
-}
-
-static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf,
-                               size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[50];
-       size_t len;
-
-       len = min(count, sizeof(buf) - 1);
-       if (copy_from_user(buf, user_buf, len))
-               return -EFAULT;
-       buf[len] = '\0';
-       if (len > 0 && buf[len - 1] == '\n')
-               buf[len - 1] = '\0';
-
-       if (strncmp(buf, "add", 3) == 0) {
-               int res = ath9k_wiphy_add(sc);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "del=", 4) == 0) {
-               int res = del_wiphy(sc, buf + 4);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "pause=", 6) == 0) {
-               int res = pause_wiphy(sc, buf + 6);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "unpause=", 8) == 0) {
-               int res = unpause_wiphy(sc, buf + 8);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "select=", 7) == 0) {
-               int res = select_wiphy(sc, buf + 7);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "schedule=", 9) == 0) {
-               int res = schedule_wiphy(sc, buf + 9);
-               if (res < 0)
-                       return res;
-       } else
-               return -EOPNOTSUPP;
-
-       return count;
-}
-
-static const struct file_operations fops_wiphy = {
-       .read = read_file_wiphy,
-       .write = write_file_wiphy,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
-
-int ath9k_init_debug(struct ath_softc *sc)
-{
-       sc->debug.debug_mask = ath9k_debug;
-
-       if (!ath9k_debugfs_root)
-               return -ENOENT;
-
-       sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
-                                                     ath9k_debugfs_root);
-       if (!sc->debug.debugfs_phy)
-               goto err;
-
-       sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
-                                      sc->debug.debugfs_phy, sc, &fops_dma);
-       if (!sc->debug.debugfs_dma)
-               goto err;
-
-       sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
-                                                    S_IRUGO,
-                                                    sc->debug.debugfs_phy,
-                                                    sc, &fops_interrupt);
-       if (!sc->debug.debugfs_interrupt)
-               goto err;
-
-       sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
-                                                 S_IRUGO,
-                                                 sc->debug.debugfs_phy,
-                                                 sc, &fops_rcstat);
-       if (!sc->debug.debugfs_rcstat)
-               goto err;
-
-       sc->debug.debugfs_wiphy = debugfs_create_file(
-               "wiphy", S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc,
-               &fops_wiphy);
-       if (!sc->debug.debugfs_wiphy)
-               goto err;
-
-       return 0;
-err:
-       ath9k_exit_debug(sc);
-       return -ENOMEM;
-}
-
-void ath9k_exit_debug(struct ath_softc *sc)
-{
-       debugfs_remove(sc->debug.debugfs_wiphy);
-       debugfs_remove(sc->debug.debugfs_rcstat);
-       debugfs_remove(sc->debug.debugfs_interrupt);
-       debugfs_remove(sc->debug.debugfs_dma);
-       debugfs_remove(sc->debug.debugfs_phy);
-}
-
-int ath9k_debug_create_root(void)
-{
-       ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
-       if (!ath9k_debugfs_root)
-               return -ENOENT;
-
-       return 0;
-}
-
-void ath9k_debug_remove_root(void)
-{
-       debugfs_remove(ath9k_debugfs_root);
-       ath9k_debugfs_root = NULL;
-}
diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath9k/debug.h
deleted file mode 100644 (file)
index 23298b9..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 DEBUG_H
-#define DEBUG_H
-
-enum ATH_DEBUG {
-       ATH_DBG_RESET           = 0x00000001,
-       ATH_DBG_QUEUE           = 0x00000002,
-       ATH_DBG_EEPROM          = 0x00000004,
-       ATH_DBG_CALIBRATE       = 0x00000008,
-       ATH_DBG_INTERRUPT       = 0x00000010,
-       ATH_DBG_REGULATORY      = 0x00000020,
-       ATH_DBG_ANI             = 0x00000040,
-       ATH_DBG_XMIT            = 0x00000080,
-       ATH_DBG_BEACON          = 0x00000100,
-       ATH_DBG_CONFIG          = 0x00000200,
-       ATH_DBG_FATAL           = 0x00000400,
-       ATH_DBG_ANY             = 0xffffffff
-};
-
-#define DBG_DEFAULT (ATH_DBG_FATAL)
-
-#ifdef CONFIG_ATH9K_DEBUG
-
-/**
- * struct ath_interrupt_stats - Contains statistics about interrupts
- * @total: Total no. of interrupts generated so far
- * @rxok: RX with no errors
- * @rxeol: RX with no more RXDESC available
- * @rxorn: RX FIFO overrun
- * @txok: TX completed at the requested rate
- * @txurn: TX FIFO underrun
- * @mib: MIB regs reaching its threshold
- * @rxphyerr: RX with phy errors
- * @rx_keycache_miss: RX with key cache misses
- * @swba: Software Beacon Alert
- * @bmiss: Beacon Miss
- * @bnr: Beacon Not Ready
- * @cst: Carrier Sense TImeout
- * @gtt: Global TX Timeout
- * @tim: RX beacon TIM occurrence
- * @cabend: RX End of CAB traffic
- * @dtimsync: DTIM sync lossage
- * @dtim: RX Beacon with DTIM
- */
-struct ath_interrupt_stats {
-       u32 total;
-       u32 rxok;
-       u32 rxeol;
-       u32 rxorn;
-       u32 txok;
-       u32 txeol;
-       u32 txurn;
-       u32 mib;
-       u32 rxphyerr;
-       u32 rx_keycache_miss;
-       u32 swba;
-       u32 bmiss;
-       u32 bnr;
-       u32 cst;
-       u32 gtt;
-       u32 tim;
-       u32 cabend;
-       u32 dtimsync;
-       u32 dtim;
-};
-
-struct ath_legacy_rc_stats {
-       u32 success;
-};
-
-struct ath_11n_rc_stats {
-       u32 success;
-       u32 retries;
-       u32 xretries;
-       u8 per;
-};
-
-struct ath_stats {
-       struct ath_interrupt_stats istats;
-       struct ath_legacy_rc_stats legacy_rcstats[12];  /* max(11a,11b,11g) */
-       struct ath_11n_rc_stats n_rcstats[16];          /* 0..15 MCS rates */
-};
-
-struct ath9k_debug {
-       int debug_mask;
-       struct dentry *debugfs_phy;
-       struct dentry *debugfs_dma;
-       struct dentry *debugfs_interrupt;
-       struct dentry *debugfs_rcstat;
-       struct dentry *debugfs_wiphy;
-       struct ath_stats stats;
-};
-
-void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
-int ath9k_init_debug(struct ath_softc *sc);
-void ath9k_exit_debug(struct ath_softc *sc);
-int ath9k_debug_create_root(void);
-void ath9k_debug_remove_root(void);
-void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                           int xretries, int retries, u8 per);
-
-#else
-
-static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
-                          const char *fmt, ...)
-{
-}
-
-static inline int ath9k_init_debug(struct ath_softc *sc)
-{
-       return 0;
-}
-
-static inline void ath9k_exit_debug(struct ath_softc *sc)
-{
-}
-
-static inline int ath9k_debug_create_root(void)
-{
-       return 0;
-}
-
-static inline void ath9k_debug_remove_root(void)
-{
-}
-
-static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
-                                           enum ath9k_int status)
-{
-}
-
-static inline void ath_debug_stat_rc(struct ath_softc *sc,
-                                    struct sk_buff *skb)
-{
-}
-
-static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                                         int xretries, int retries, u8 per)
-{
-}
-
-#endif /* CONFIG_ATH9K_DEBUG */
-
-#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
deleted file mode 100644 (file)
index 44fee5a..0000000
+++ /dev/null
@@ -1,2813 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
-                                     u32 reg, u32 mask,
-                                     u32 shift, u32 val)
-{
-       u32 regVal;
-
-       regVal = REG_READ(ah, reg) & ~mask;
-       regVal |= (val << shift) & mask;
-
-       REG_WRITE(ah, reg, regVal);
-
-       if (ah->config.analog_shiftreg)
-               udelay(100);
-
-       return;
-}
-
-static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
-{
-
-       if (fbin == AR5416_BCHAN_UNUSED)
-               return fbin;
-
-       return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
-}
-
-static inline int16_t ath9k_hw_interpolate(u16 target,
-                                          u16 srcLeft, u16 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 bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
-                                                 u16 listSize, u16 *indexL,
-                                                 u16 *indexR)
-{
-       u16 i;
-
-       if (target <= pList[0]) {
-               *indexL = *indexR = 0;
-               return true;
-       }
-       if (target >= pList[listSize - 1]) {
-               *indexL = *indexR = (u16) (listSize - 1);
-               return true;
-       }
-
-       for (i = 0; i < listSize - 1; i++) {
-               if (pList[i] == target) {
-                       *indexL = *indexR = i;
-                       return true;
-               }
-               if (target < pList[i + 1]) {
-                       *indexL = i;
-                       *indexR = (u16) (i + 1);
-                       return false;
-               }
-       }
-       return false;
-}
-
-static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
-{
-       struct ath_softc *sc = ah->ah_sc;
-
-       return sc->bus_ops->eeprom_read(ah, off, data);
-}
-
-static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
-                                          u8 *pVpdList, u16 numIntercepts,
-                                          u8 *pRetVpdList)
-{
-       u16 i, k;
-       u8 currPwr = pwrMin;
-       u16 idxL = 0, idxR = 0;
-
-       for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
-               ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
-                                              numIntercepts, &(idxL),
-                                              &(idxR));
-               if (idxR < 1)
-                       idxR = 1;
-               if (idxL == numIntercepts - 1)
-                       idxL = (u16) (numIntercepts - 2);
-               if (pPwrList[idxL] == pPwrList[idxR])
-                       k = pVpdList[idxL];
-               else
-                       k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
-                                  (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
-                                 (pPwrList[idxR] - pPwrList[idxL]));
-               pRetVpdList[i] = (u8) k;
-               currPwr += 2;
-       }
-
-       return true;
-}
-
-static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
-                                     struct ath9k_channel *chan,
-                                     struct cal_target_power_leg *powInfo,
-                                     u16 numChannels,
-                                     struct cal_target_power_leg *pNewPower,
-                                     u16 numRates, bool isExtTarget)
-{
-       struct chan_centers centers;
-       u16 clo, chi;
-       int i;
-       int matchIndex = -1, lowIndex = -1;
-       u16 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] =
-                               (u8)ath9k_hw_interpolate(freq, clo, chi,
-                                               powInfo[lowIndex].tPow2x[i],
-                                               powInfo[lowIndex + 1].tPow2x[i]);
-               }
-       }
-}
-
-static void ath9k_get_txgain_index(struct ath_hw *ah,
-               struct ath9k_channel *chan,
-               struct calDataPerFreqOpLoop *rawDatasetOpLoop,
-               u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
-{
-       u8 pcdac, i = 0;
-       u16 idxL = 0, idxR = 0, numPiers;
-       bool match;
-       struct chan_centers centers;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-       for (numPiers = 0; numPiers < availPiers; numPiers++)
-               if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
-                       break;
-
-       match = ath9k_hw_get_lower_upper_index(
-                       (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
-                       calChans, numPiers, &idxL, &idxR);
-       if (match) {
-               pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
-               *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
-       } else {
-               pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
-               *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
-                               rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
-       }
-
-       while (pcdac > ah->originalGain[i] &&
-                       i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
-               i++;
-
-       *pcdacIdx = i;
-       return;
-}
-
-static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
-                               u32 initTxGain,
-                               int txPower,
-                               u8 *pPDADCValues)
-{
-       u32 i;
-       u32 offset;
-
-       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
-                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
-       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
-                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
-
-       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
-                       AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
-
-       offset = txPower;
-       for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
-               if (i < offset)
-                       pPDADCValues[i] = 0x0;
-               else
-                       pPDADCValues[i] = 0xFF;
-}
-
-
-
-
-static void ath9k_hw_get_target_powers(struct ath_hw *ah,
-                                      struct ath9k_channel *chan,
-                                      struct cal_target_power_ht *powInfo,
-                                      u16 numChannels,
-                                      struct cal_target_power_ht *pNewPower,
-                                      u16 numRates, bool isHt40Target)
-{
-       struct chan_centers centers;
-       u16 clo, chi;
-       int i;
-       int matchIndex = -1, lowIndex = -1;
-       u16 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] = (u8)ath9k_hw_interpolate(freq,
-                                               clo, chi,
-                                               powInfo[lowIndex].tPow2x[i],
-                                               powInfo[lowIndex + 1].tPow2x[i]);
-               }
-       }
-}
-
-static u16 ath9k_hw_get_max_edge_power(u16 freq,
-                                      struct cal_ctl_edges *pRdEdgesPower,
-                                      bool is2GHz, int num_band_edges)
-{
-       u16 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;
-}
-
-/****************************************/
-/* EEPROM Operations for 4K sized cards */
-/****************************************/
-
-static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
-{
-       return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
-}
-
-static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
-{
-       return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
-}
-
-static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
-{
-#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
-       u16 *eep_data = (u16 *)&ah->eeprom.map4k;
-       int addr, eep_start_loc = 0;
-
-       eep_start_loc = 64;
-
-       if (!ath9k_hw_use_flash(ah)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "Reading from EEPROM, not flash\n");
-       }
-
-       for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
-               if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                              "Unable to read eeprom region \n");
-                       return false;
-               }
-               eep_data++;
-       }
-
-       return true;
-#undef SIZE_EEPROM_4K
-}
-
-static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
-{
-#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
-       struct ar5416_eeprom_4k *eep =
-               (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
-       u16 *eepdata, temp, magic, magic2;
-       u32 sum = 0, el;
-       bool need_swap = false;
-       int i, addr;
-
-
-       if (!ath9k_hw_use_flash(ah)) {
-               if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
-                                        &magic)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Reading Magic # failed\n");
-                       return false;
-               }
-
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "Read Magic = 0x%04X\n", magic);
-
-               if (magic != AR5416_EEPROM_MAGIC) {
-                       magic2 = swab16(magic);
-
-                       if (magic2 == AR5416_EEPROM_MAGIC) {
-                               need_swap = true;
-                               eepdata = (u16 *) (&ah->eeprom);
-
-                               for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
-                                       temp = swab16(*eepdata);
-                                       *eepdata = temp;
-                                       eepdata++;
-                               }
-                       } else {
-                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                                       "Invalid EEPROM Magic. "
-                                       "endianness mismatch.\n");
-                               return -EINVAL;
-                       }
-               }
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-               need_swap ? "True" : "False");
-
-       if (need_swap)
-               el = swab16(ah->eeprom.map4k.baseEepHeader.length);
-       else
-               el = ah->eeprom.map4k.baseEepHeader.length;
-
-       if (el > sizeof(struct ar5416_eeprom_4k))
-               el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
-       else
-               el = el / sizeof(u16);
-
-       eepdata = (u16 *)(&ah->eeprom);
-
-       for (i = 0; i < el; i++)
-               sum ^= *eepdata++;
-
-       if (need_swap) {
-               u32 integer;
-               u16 word;
-
-               DPRINTF(ah->ah_sc, ATH_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 || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
-           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-                       sum, ah->eep_ops->get_eeprom_ver(ah));
-               return -EINVAL;
-       }
-
-       return 0;
-#undef EEPROM_4K_SIZE
-}
-
-static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
-                                 enum eeprom_param param)
-{
-       struct ar5416_eeprom_4k *eep = &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->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;
-       case EEP_FRAC_N_5G:
-               return 0;
-       default:
-               return 0;
-       }
-}
-
-static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
-                               struct ath9k_channel *chan,
-                               struct cal_data_per_freq_4k *pRawDataSet,
-                               u8 *bChans, u16 availPiers,
-                               u16 tPdGainOverlap, int16_t *pMinCalPower,
-                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
-                               u16 numXpdGains)
-{
-#define TMP_VAL_VPD_TABLE \
-       ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
-       int i, j, k;
-       int16_t ss;
-       u16 idxL = 0, idxR = 0, numPiers;
-       static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
-       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
-       u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
-       u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
-       int16_t vpdStep;
-       int16_t tmpVal;
-       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
-       bool 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(
-                                       (u8)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];
-                       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]);
-
-
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                               pPwrL, pVpdL,
-                                               AR5416_EEP4K_PD_GAIN_ICEPTS,
-                                               vpdTableL[i]);
-                       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] =
-                                       (u8)(ath9k_hw_interpolate((u16)
-                                            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] =
-                               (u16)(maxPwrT4[i] / 2);
-               else
-                       pPdGainBoundaries[i] =
-                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
-               pPdGainBoundaries[i] =
-                       min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
-               if ((i == 0) && !AR_SREV_5416_20_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++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
-                       ss++;
-               }
-
-               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
-               tgtIndex = (u8)(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++] = (u8)((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 bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 int16_t *pTxPowerIndexOffset)
-{
-       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-       struct cal_data_per_freq_4k *pRawDataset;
-       u8 *pCalBChans = NULL;
-       u16 pdGainOverlap_t2;
-       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
-       u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
-       u16 numPiers, i, j;
-       int16_t tMinCalPower;
-       u16 numXpdGain, xpdMask;
-       u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
-       u32 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 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
-                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
-       }
-
-       pCalBChans = pEepData->calFreqPier2G;
-       numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
-
-       numXpdGain = 0;
-
-       for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
-               if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
-                       if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
-                               break;
-                       xpdGainValues[numXpdGain] =
-                               (u16)(AR5416_EEP4K_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, 0);
-
-       for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
-               if (AR_SREV_5416_20_OR_LATER(ah) &&
-                   (ah->rxchainmask == 5 || 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_20_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);
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
-                                       i, regChainOffset, regOffset,
-                                       reg32);
-                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                       "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 true;
-}
-
-static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
-                                                struct ath9k_channel *chan,
-                                                int16_t *ratesArray,
-                                                u16 cfgCtl,
-                                                u16 AntennaReduction,
-                                                u16 twiceMaxRegulatoryPower,
-                                                u16 powerLimit)
-{
-       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-       static const u16 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}
-       };
-       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
-       u16 ctlModesFor11g[] =
-               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
-                 CTL_2GHT40
-               };
-       u16 numCtlModes, *pCtlMode, ctlMode, freq;
-       struct chan_centers centers;
-       int tx_chainmask;
-       u16 twiceMinEdgePower;
-
-       tx_chainmask = 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->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
-               maxRegAllowedPower -=
-                       (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
-       }
-
-       scaledPower = min(powerLimit, maxRegAllowedPower);
-       scaledPower = max((u16)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, false);
-       ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->calTargetPower2G,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerOfdm, 4, false);
-       ath9k_hw_get_target_powers(ah, chan,
-                       pEepData->calTargetPower2GHT20,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerHt20, 8, 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, true);
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPowerCck,
-                               AR5416_NUM_2G_CCK_TARGET_POWERS,
-                               &targetPowerCckExt, 4, true);
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPower2G,
-                               AR5416_NUM_2G_20_TARGET_POWERS,
-                               &targetPowerOfdmExt, 4, true);
-       }
-
-       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
-               bool 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 (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
-                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
-                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "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++) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                               "  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);
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                       "    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 = (u8)min(twiceMaxEdgePower, scaledPower);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "    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((u16)targetPowerCck.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11G:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
-                                       i++) {
-                               targetPowerOfdm.tPow2x[i] =
-                                       min((u16)targetPowerOfdm.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_2GHT20:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
-                                       i++) {
-                               targetPowerHt20.tPow2x[i] =
-                                       min((u16)targetPowerHt20.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11B_EXT:
-                       targetPowerCckExt.tPow2x[0] = min((u16)
-                                       targetPowerCckExt.tPow2x[0],
-                                       minCtlPower);
-                       break;
-               case CTL_11G_EXT:
-                       targetPowerOfdmExt.tPow2x[0] = min((u16)
-                                       targetPowerOfdmExt.tPow2x[0],
-                                       minCtlPower);
-                       break;
-               case CTL_2GHT40:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
-                                       i++) {
-                               targetPowerHt40.tPow2x[i] =
-                                       min((u16)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 true;
-}
-
-static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
-                                  struct ath9k_channel *chan,
-                                  u16 cfgCtl,
-                                  u8 twiceAntennaReduction,
-                                  u8 twiceMaxRegulatoryPower,
-                                  u8 powerLimit)
-{
-       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-       struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
-       int16_t ratesArray[Ar5416RateSize];
-       int16_t txPowerIndexOffset = 0;
-       u8 ht40PowerIncForPdadc = 2;
-       int i;
-
-       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)) {
-               DPRINTF(ah->ah_sc, ATH_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)) {
-               DPRINTF(ah->ah_sc, ATH_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->regulatory.max_power_level =
-                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
-       else
-               ah->regulatory.max_power_level = ratesArray[i];
-
-       return 0;
-}
-
-static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
-                                 struct ath9k_channel *chan)
-{
-       struct modal_eep_4k_header *pModal;
-       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-       u8 biaslevel;
-
-       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
-               return;
-
-       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
-               return;
-
-       pModal = &eep->modalHeader;
-
-       if (pModal->xpaBiasLvl != 0xff) {
-               biaslevel = pModal->xpaBiasLvl;
-               INI_RA(&ah->iniAddac, 7, 1) =
-                 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
-       }
-}
-
-static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
-                                struct modal_eep_4k_header *pModal,
-                                struct ar5416_eeprom_4k *eep,
-                                u8 txRxAttenLocal, int regChainOffset)
-{
-       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));
-}
-
-static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
-                                        struct ath9k_channel *chan)
-{
-       struct modal_eep_4k_header *pModal;
-       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-       u8 txRxAttenLocal;
-       u8 ob[5], db1[5], db2[5];
-       u8 ant_div_control1, ant_div_control2;
-       u32 regVal;
-
-       pModal = &eep->modalHeader;
-       txRxAttenLocal = 23;
-
-       REG_WRITE(ah, AR_PHY_SWITCH_COM,
-                 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
-
-       /* Single chain for 4K EEPROM*/
-       ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
-
-       /* 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) {
-               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);
-       }
-}
-
-static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
-                                             struct ath9k_channel *chan)
-{
-       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-       struct modal_eep_4k_header *pModal = &eep->modalHeader;
-
-       return pModal->antCtrlCommon & 0xFFFF;
-}
-
-static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
-                                        enum ieee80211_band freq_band)
-{
-       return 1;
-}
-
-static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
-{
-#define EEP_MAP4K_SPURCHAN \
-       (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
-
-       u16 spur_val = AR_NO_SPUR;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "Getting spur idx %d is2Ghz. %d val %x\n",
-               i, is2GHz, ah->config.spurchans[i][is2GHz]);
-
-       switch (ah->config.spurmode) {
-       case SPUR_DISABLE:
-               break;
-       case SPUR_ENABLE_IOCTL:
-               spur_val = ah->config.spurchans[i][is2GHz];
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Getting spur val from new loc. %d\n", spur_val);
-               break;
-       case SPUR_ENABLE_EEPROM:
-               spur_val = EEP_MAP4K_SPURCHAN;
-               break;
-       }
-
-       return spur_val;
-
-#undef EEP_MAP4K_SPURCHAN
-}
-
-static struct eeprom_ops eep_4k_ops = {
-       .check_eeprom           = ath9k_hw_4k_check_eeprom,
-       .get_eeprom             = ath9k_hw_4k_get_eeprom,
-       .fill_eeprom            = ath9k_hw_4k_fill_eeprom,
-       .get_eeprom_ver         = ath9k_hw_4k_get_eeprom_ver,
-       .get_eeprom_rev         = ath9k_hw_4k_get_eeprom_rev,
-       .get_num_ant_config     = ath9k_hw_4k_get_num_ant_config,
-       .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
-       .set_board_values       = ath9k_hw_4k_set_board_values,
-       .set_addac              = ath9k_hw_4k_set_addac,
-       .set_txpower            = ath9k_hw_4k_set_txpower,
-       .get_spur_channel       = ath9k_hw_4k_get_spur_channel
-};
-
-/************************************************/
-/* EEPROM Operations for non-4K (Default) cards */
-/************************************************/
-
-static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
-{
-       return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
-}
-
-static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
-{
-       return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
-}
-
-static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
-{
-#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
-       u16 *eep_data = (u16 *)&ah->eeprom.def;
-       int addr, ar5416_eep_start_loc = 0x100;
-
-       for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
-               if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
-                                        eep_data)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Unable to read eeprom region\n");
-                       return false;
-               }
-               eep_data++;
-       }
-       return true;
-#undef SIZE_EEPROM_DEF
-}
-
-static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
-{
-       struct ar5416_eeprom_def *eep =
-               (struct ar5416_eeprom_def *) &ah->eeprom.def;
-       u16 *eepdata, temp, magic, magic2;
-       u32 sum = 0, el;
-       bool need_swap = false;
-       int i, addr, size;
-
-       if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
-               return false;
-       }
-
-       if (!ath9k_hw_use_flash(ah)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "Read Magic = 0x%04X\n", magic);
-
-               if (magic != AR5416_EEPROM_MAGIC) {
-                       magic2 = swab16(magic);
-
-                       if (magic2 == AR5416_EEPROM_MAGIC) {
-                               size = sizeof(struct ar5416_eeprom_def);
-                               need_swap = true;
-                               eepdata = (u16 *) (&ah->eeprom);
-
-                               for (addr = 0; addr < size / sizeof(u16); addr++) {
-                                       temp = swab16(*eepdata);
-                                       *eepdata = temp;
-                                       eepdata++;
-                               }
-                       } else {
-                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                                       "Invalid EEPROM Magic. "
-                                       "Endianness mismatch.\n");
-                               return -EINVAL;
-                       }
-               }
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-               need_swap ? "True" : "False");
-
-       if (need_swap)
-               el = swab16(ah->eeprom.def.baseEepHeader.length);
-       else
-               el = ah->eeprom.def.baseEepHeader.length;
-
-       if (el > sizeof(struct ar5416_eeprom_def))
-               el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
-       else
-               el = el / sizeof(u16);
-
-       eepdata = (u16 *)(&ah->eeprom);
-
-       for (i = 0; i < el; i++)
-               sum ^= *eepdata++;
-
-       if (need_swap) {
-               u32 integer, j;
-               u16 word;
-
-               DPRINTF(ah->ah_sc, ATH_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 || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
-           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-                       sum, ah->eep_ops->get_eeprom_ver(ah));
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
-                                  enum eeprom_param param)
-{
-       struct ar5416_eeprom_def *eep = &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 AR5416_VER_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;
-       case EEP_OL_PWRCTRL:
-               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
-                       return pBase->openLoopPwrCntl ? true : false;
-               else
-                       return false;
-       case EEP_RC_CHAIN_MASK:
-               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
-                       return pBase->rcChainMask;
-               else
-                       return 0;
-       case EEP_DAC_HPWR_5G:
-               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
-                       return pBase->dacHiPwrMode_5G;
-               else
-                       return 0;
-       case EEP_FRAC_N_5G:
-               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
-                       return pBase->frac_n_5g;
-               else
-                       return 0;
-       default:
-               return 0;
-       }
-}
-
-static void ath9k_hw_def_set_gain(struct ath_hw *ah,
-                                 struct modal_eep_header *pModal,
-                                 struct ar5416_eeprom_def *eep,
-                                 u8 txRxAttenLocal, int regChainOffset, int i)
-{
-       if (AR5416_VER_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));
-       }
-}
-
-static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
-                                         struct ath9k_channel *chan)
-{
-       struct modal_eep_header *pModal;
-       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-       int i, regChainOffset;
-       u8 txRxAttenLocal;
-
-       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-       txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
-
-       REG_WRITE(ah, AR_PHY_SWITCH_COM,
-                 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               if (AR_SREV_9280(ah)) {
-                       if (i >= 2)
-                               break;
-               }
-
-               if (AR_SREV_5416_20_OR_LATER(ah) &&
-                   (ah->rxchainmask == 5 || 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_20_OR_LATER(ah))
-                       ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
-                                             regChainOffset, i);
-       }
-
-       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);
-               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 (AR5416_VER_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 (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
-               if (IS_CHAN_HT40(chan))
-                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
-                                     AR_PHY_SETTLING_SWITCH,
-                                     pModal->swSettleHt40);
-       }
-
-       if (AR_SREV_9280_20_OR_LATER(ah) &&
-           AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
-               REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
-                             AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
-                             pModal->miscBits);
-
-
-       if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
-               if (IS_CHAN_2GHZ(chan))
-                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
-                                       eep->baseEepHeader.dacLpMode);
-               else if (eep->baseEepHeader.dacHiPwrMode_5G)
-                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
-               else
-                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
-                                     eep->baseEepHeader.dacLpMode);
-
-               REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
-                             pModal->miscBits >> 2);
-
-               REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
-                             AR_PHY_TX_DESIRED_SCALE_CCK,
-                             eep->baseEepHeader.desiredScaleCCK);
-       }
-}
-
-static void ath9k_hw_def_set_addac(struct ath_hw *ah,
-                                  struct ath9k_channel *chan)
-{
-#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
-       struct modal_eep_header *pModal;
-       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-       u8 biaslevel;
-
-       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
-               return;
-
-       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
-               return;
-
-       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
-       if (pModal->xpaBiasLvl != 0xff) {
-               biaslevel = pModal->xpaBiasLvl;
-       } else {
-               u16 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(0) & 0xff;
-               biaslevel = (u8) (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 = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
-                       else
-                               break;
-                       freqCount++;
-               }
-       }
-
-       if (IS_CHAN_2GHZ(chan)) {
-               INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
-                                       7, 1) & (~0x18)) | biaslevel << 3;
-       } else {
-               INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
-                                       6, 1) & (~0xc0)) | biaslevel << 6;
-       }
-#undef XPA_LVL_FREQ
-}
-
-static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
-                               struct ath9k_channel *chan,
-                               struct cal_data_per_freq *pRawDataSet,
-                               u8 *bChans, u16 availPiers,
-                               u16 tPdGainOverlap, int16_t *pMinCalPower,
-                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
-                               u16 numXpdGains)
-{
-       int i, j, k;
-       int16_t ss;
-       u16 idxL = 0, idxR = 0, numPiers;
-       static u8 vpdTableL[AR5416_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableR[AR5416_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableI[AR5416_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
-       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
-       u8 minPwrT4[AR5416_NUM_PD_GAINS];
-       u8 maxPwrT4[AR5416_NUM_PD_GAINS];
-       int16_t vpdStep;
-       int16_t tmpVal;
-       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
-       bool 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((u8)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];
-                       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]);
-
-
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                               pPwrL, pVpdL,
-                                               AR5416_PD_GAIN_ICEPTS,
-                                               vpdTableL[i]);
-                       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] =
-                                       (u8)(ath9k_hw_interpolate((u16)
-                                            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] =
-                               (u16)(maxPwrT4[i] / 2);
-               else
-                       pPdGainBoundaries[i] =
-                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
-               pPdGainBoundaries[i] =
-                       min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
-               if ((i == 0) && !AR_SREV_5416_20_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++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
-                       ss++;
-               }
-
-               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
-               tgtIndex = (u8)(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++] = (u8)((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++;
-       }
-
-       return;
-}
-
-static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 int16_t *pTxPowerIndexOffset)
-{
-#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
-#define SM_PDGAIN_B(x, y) \
-               SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
-
-       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
-       struct cal_data_per_freq *pRawDataset;
-       u8 *pCalBChans = NULL;
-       u16 pdGainOverlap_t2;
-       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
-       u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
-       u16 numPiers, i, j;
-       int16_t tMinCalPower;
-       u16 numXpdGain, xpdMask;
-       u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
-       u32 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 = (u16)(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;
-       }
-
-       if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
-               pRawDataset = pEepData->calPierData2G[0];
-               ah->initPDADC = ((struct calDataPerFreqOpLoop *)
-                                pRawDataset)->vpdPdg[0][0];
-       }
-
-       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] =
-                               (u16)(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_20_OR_LATER(ah) &&
-                   (ah->rxchainmask == 5 || 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];
-
-
-                       if (OLC_FOR_AR9280_20_LATER) {
-                               u8 pcdacIdx;
-                               u8 txPower;
-
-                               ath9k_get_txgain_index(ah, chan,
-                               (struct calDataPerFreqOpLoop *)pRawDataset,
-                               pCalBChans, numPiers, &txPower, &pcdacIdx);
-                               ath9k_olc_get_pdadcs(ah, pcdacIdx,
-                                                    txPower/2, pdadcValues);
-                       } else {
-                               ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
-                                                       chan, pRawDataset,
-                                                       pCalBChans, numPiers,
-                                                       pdGainOverlap_t2,
-                                                       &tMinCalPower,
-                                                       gainBoundaries,
-                                                       pdadcValues,
-                                                       numXpdGain);
-                       }
-
-                       if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
-                               if (OLC_FOR_AR9280_20_LATER) {
-                                       REG_WRITE(ah,
-                                               AR_PHY_TPCRG5 + regChainOffset,
-                                               SM(0x6,
-                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
-                                               SM_PD_GAIN(1) | SM_PD_GAIN(2) |
-                                               SM_PD_GAIN(3) | SM_PD_GAIN(4));
-                               } else {
-                                       REG_WRITE(ah,
-                                               AR_PHY_TPCRG5 + regChainOffset,
-                                               SM(pdGainOverlap_t2,
-                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
-                                               SM_PDGAIN_B(0, 1) |
-                                               SM_PDGAIN_B(1, 2) |
-                                               SM_PDGAIN_B(2, 3) |
-                                               SM_PDGAIN_B(3, 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);
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
-                                       i, regChainOffset, regOffset,
-                                       reg32);
-                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                       "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 true;
-#undef SM_PD_GAIN
-#undef SM_PDGAIN_B
-}
-
-static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
-                                                 struct ath9k_channel *chan,
-                                                 int16_t *ratesArray,
-                                                 u16 cfgCtl,
-                                                 u16 AntennaReduction,
-                                                 u16 twiceMaxRegulatoryPower,
-                                                 u16 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 ar5416_eeprom_def *pEepData = &ah->eeprom.def;
-       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-       static const u16 tpScaleReductionTable[5] =
-               { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
-
-       int i;
-       int16_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}
-       };
-       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
-       u16 ctlModesFor11a[] =
-               { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
-       u16 ctlModesFor11g[] =
-               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
-                 CTL_2GHT40
-               };
-       u16 numCtlModes, *pCtlMode, ctlMode, freq;
-       struct chan_centers centers;
-       int tx_chainmask;
-       u16 twiceMinEdgePower;
-
-       tx_chainmask = 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((u8)twiceLargestAntenna,
-                                 pEepData->modalHeader
-                                 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
-
-       twiceLargestAntenna = (int16_t)min(AntennaReduction -
-                                          twiceLargestAntenna, 0);
-
-       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
-
-       if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
-               maxRegAllowedPower -=
-                       (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 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((u16)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, false);
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->calTargetPower2G,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerOfdm, 4, false);
-               ath9k_hw_get_target_powers(ah, chan,
-                       pEepData->calTargetPower2GHT20,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerHt20, 8, 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, true);
-                       ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPowerCck,
-                               AR5416_NUM_2G_CCK_TARGET_POWERS,
-                               &targetPowerCckExt, 4, true);
-                       ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPower2G,
-                               AR5416_NUM_2G_20_TARGET_POWERS,
-                               &targetPowerOfdmExt, 4, 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, false);
-               ath9k_hw_get_target_powers(ah, chan,
-                       pEepData->calTargetPower5GHT20,
-                       AR5416_NUM_5G_20_TARGET_POWERS,
-                       &targetPowerHt20, 8, 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, true);
-                       ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPower5G,
-                               AR5416_NUM_5G_20_TARGET_POWERS,
-                               &targetPowerOfdmExt, 4, true);
-               }
-       }
-
-       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
-               bool 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 (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
-                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
-                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "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++) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                               "  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);
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                       "    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);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "    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((u16)targetPowerCck.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11A:
-               case CTL_11G:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
-                               targetPowerOfdm.tPow2x[i] =
-                                       min((u16)targetPowerOfdm.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_5GHT20:
-               case CTL_2GHT20:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
-                               targetPowerHt20.tPow2x[i] =
-                                       min((u16)targetPowerHt20.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11B_EXT:
-                       targetPowerCckExt.tPow2x[0] = min((u16)
-                                       targetPowerCckExt.tPow2x[0],
-                                       minCtlPower);
-                       break;
-               case CTL_11A_EXT:
-               case CTL_11G_EXT:
-                       targetPowerOfdmExt.tPow2x[0] = min((u16)
-                                       targetPowerOfdmExt.tPow2x[0],
-                                       minCtlPower);
-                       break;
-               case CTL_5GHT40:
-               case CTL_2GHT40:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-                               targetPowerHt40.tPow2x[i] =
-                                       min((u16)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 true;
-}
-
-static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
-                                   struct ath9k_channel *chan,
-                                   u16 cfgCtl,
-                                   u8 twiceAntennaReduction,
-                                   u8 twiceMaxRegulatoryPower,
-                                   u8 powerLimit)
-{
-#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
-       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
-       struct modal_eep_header *pModal =
-               &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
-       int16_t ratesArray[Ar5416RateSize];
-       int16_t txPowerIndexOffset = 0;
-       u8 ht40PowerIncForPdadc = 2;
-       int i, cck_ofdm_delta = 0;
-
-       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)) {
-               DPRINTF(ah->ah_sc, ATH_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)) {
-               DPRINTF(ah->ah_sc, ATH_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)) {
-               if (OLC_FOR_AR9280_20_LATER) {
-                       cck_ofdm_delta = 2;
-                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
-                               ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
-                               | ATH9K_POW_SM(ratesArray[rateXr], 8)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
-                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
-                               ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
-               } else {
-                       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));
-               if (OLC_FOR_AR9280_20_LATER) {
-                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
-                               ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
-                               | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
-               } else {
-                       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->regulatory.max_power_level =
-                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
-       else
-               ah->regulatory.max_power_level = ratesArray[i];
-
-       switch(ar5416_get_ntxchains(ah->txchainmask)) {
-       case 1:
-               break;
-       case 2:
-               ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
-               break;
-       case 3:
-               ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "Invalid chainmask configuration\n");
-               break;
-       }
-
-       return 0;
-}
-
-static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
-                                         enum ieee80211_band freq_band)
-{
-       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-       struct modal_eep_header *pModal =
-               &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
-       struct base_eep_header *pBase = &eep->baseEepHeader;
-       u8 num_ant_config;
-
-       num_ant_config = 1;
-
-       if (pBase->version >= 0x0E0D)
-               if (pModal->useAnt1)
-                       num_ant_config += 1;
-
-       return num_ant_config;
-}
-
-static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
-                                              struct ath9k_channel *chan)
-{
-       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-       struct modal_eep_header *pModal =
-               &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
-       return pModal->antCtrlCommon & 0xFFFF;
-}
-
-static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
-{
-#define EEP_DEF_SPURCHAN \
-       (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
-
-       u16 spur_val = AR_NO_SPUR;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "Getting spur idx %d is2Ghz. %d val %x\n",
-               i, is2GHz, ah->config.spurchans[i][is2GHz]);
-
-       switch (ah->config.spurmode) {
-       case SPUR_DISABLE:
-               break;
-       case SPUR_ENABLE_IOCTL:
-               spur_val = ah->config.spurchans[i][is2GHz];
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Getting spur val from new loc. %d\n", spur_val);
-               break;
-       case SPUR_ENABLE_EEPROM:
-               spur_val = EEP_DEF_SPURCHAN;
-               break;
-       }
-
-       return spur_val;
-
-#undef EEP_DEF_SPURCHAN
-}
-
-static struct eeprom_ops eep_def_ops = {
-       .check_eeprom           = ath9k_hw_def_check_eeprom,
-       .get_eeprom             = ath9k_hw_def_get_eeprom,
-       .fill_eeprom            = ath9k_hw_def_fill_eeprom,
-       .get_eeprom_ver         = ath9k_hw_def_get_eeprom_ver,
-       .get_eeprom_rev         = ath9k_hw_def_get_eeprom_rev,
-       .get_num_ant_config     = ath9k_hw_def_get_num_ant_config,
-       .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
-       .set_board_values       = ath9k_hw_def_set_board_values,
-       .set_addac              = ath9k_hw_def_set_addac,
-       .set_txpower            = ath9k_hw_def_set_txpower,
-       .get_spur_channel       = ath9k_hw_def_get_spur_channel
-};
-
-int ath9k_hw_eeprom_attach(struct ath_hw *ah)
-{
-       int status;
-
-       if (AR_SREV_9285(ah)) {
-               ah->eep_map = EEP_MAP_4KBITS;
-               ah->eep_ops = &eep_4k_ops;
-       } else {
-               ah->eep_map = EEP_MAP_DEFAULT;
-               ah->eep_ops = &eep_def_ops;
-       }
-
-       if (!ah->eep_ops->fill_eeprom(ah))
-               return -EIO;
-
-       status = ah->eep_ops->check_eeprom(ah);
-
-       return status;
-}
diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath9k/eeprom.h
deleted file mode 100644 (file)
index 9a7715d..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 EEPROM_H
-#define EEPROM_H
-
-#include <net/wireless.h>
-
-#define AH_USE_EEPROM   0x1
-
-#ifdef __BIG_ENDIAN
-#define AR5416_EEPROM_MAGIC 0x5aa5
-#else
-#define AR5416_EEPROM_MAGIC 0xa55a
-#endif
-
-#define CTRY_DEBUG   0x1ff
-#define        CTRY_DEFAULT 0
-
-#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 AR5416_EEPROM_MAGIC_OFFSET  0x0
-#define AR5416_EEPROM_S             2
-#define AR5416_EEPROM_OFFSET        0x2000
-#define AR5416_EEPROM_MAX           0xae0
-
-#define AR5416_EEPROM_START_ADDR \
-       (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
-
-#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 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 INCREASE_MAXPOW_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
-#define INCREASE_MAXPOW_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
-
-/*
- * For AR9285 and later chipsets, the following bits are not being programmed
- * in EEPROM and so need to be enabled always.
- *
- * Bit 0: en_fcc_mid
- * Bit 1: en_jap_mid
- * Bit 2: en_fcc_dfs_ht40
- * Bit 3: en_jap_ht40
- * Bit 4: en_jap_dfs_ht40
- */
-#define AR9285_RDEXT_DEFAULT    0x1F
-
-#define AR_EEPROM_MAC(i)       (0x1d+(i))
-#define ATH9K_POW_SM(_r, _s)   (((_r) & 0x3f) << (_s))
-#define FREQ2FBIN(x, y)                ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
-#define ath9k_hw_use_flash(_ah)        (!(_ah->ah_flags & AH_USE_EEPROM))
-
-#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
-#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
-                                ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
-
-#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 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_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 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_EEP_MINOR_VER_20      0x14
-#define AR5416_EEP_MINOR_VER_22      0x16
-
-#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
-
-#define AR9280_TX_GAIN_TABLE_SIZE 22
-
-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,
-       EEP_OL_PWRCTRL,
-       EEP_RC_CHAIN_MASK,
-       EEP_DAC_HPWR_5G,
-       EEP_FRAC_N_5G
-};
-
-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
-};
-
-struct base_eep_header {
-       u16 length;
-       u16 checksum;
-       u16 version;
-       u8 opCapFlags;
-       u8 eepMisc;
-       u16 regDmn[2];
-       u8 macAddr[6];
-       u8 rxMask;
-       u8 txMask;
-       u16 rfSilent;
-       u16 blueToothOptions;
-       u16 deviceCap;
-       u32 binBuildNumber;
-       u8 deviceType;
-       u8 pwdclkind;
-       u8 futureBase_1[2];
-       u8 rxGainType;
-       u8 dacHiPwrMode_5G;
-       u8 openLoopPwrCntl;
-       u8 dacLpMode;
-       u8 txGainType;
-       u8 rcChainMask;
-       u8 desiredScaleCCK;
-       u8 power_table_offset;
-       u8 frac_n_5g;
-       u8 futureBase_3[21];
-} __packed;
-
-struct base_eep_header_4k {
-       u16 length;
-       u16 checksum;
-       u16 version;
-       u8 opCapFlags;
-       u8 eepMisc;
-       u16 regDmn[2];
-       u8 macAddr[6];
-       u8 rxMask;
-       u8 txMask;
-       u16 rfSilent;
-       u16 blueToothOptions;
-       u16 deviceCap;
-       u32 binBuildNumber;
-       u8 deviceType;
-       u8 txGainType;
-} __packed;
-
-
-struct spur_chan {
-       u16 spurChan;
-       u8 spurRangeLow;
-       u8 spurRangeHigh;
-} __packed;
-
-struct modal_eep_header {
-       u32 antCtrlChain[AR5416_MAX_CHAINS];
-       u32 antCtrlCommon;
-       u8 antennaGainCh[AR5416_MAX_CHAINS];
-       u8 switchSettling;
-       u8 txRxAttenCh[AR5416_MAX_CHAINS];
-       u8 rxTxMarginCh[AR5416_MAX_CHAINS];
-       u8 adcDesiredSize;
-       u8 pgaDesiredSize;
-       u8 xlnaGainCh[AR5416_MAX_CHAINS];
-       u8 txEndToXpaOff;
-       u8 txEndToRxOn;
-       u8 txFrameToXpaOn;
-       u8 thresh62;
-       u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
-       u8 xpdGain;
-       u8 xpd;
-       u8 iqCalICh[AR5416_MAX_CHAINS];
-       u8 iqCalQCh[AR5416_MAX_CHAINS];
-       u8 pdGainOverlap;
-       u8 ob;
-       u8 db;
-       u8 xpaBiasLvl;
-       u8 pwrDecreaseFor2Chain;
-       u8 pwrDecreaseFor3Chain;
-       u8 txFrameToDataStart;
-       u8 txFrameToPaOn;
-       u8 ht40PowerIncForPdadc;
-       u8 bswAtten[AR5416_MAX_CHAINS];
-       u8 bswMargin[AR5416_MAX_CHAINS];
-       u8 swSettleHt40;
-       u8 xatten2Db[AR5416_MAX_CHAINS];
-       u8 xatten2Margin[AR5416_MAX_CHAINS];
-       u8 ob_ch1;
-       u8 db_ch1;
-       u8 useAnt1:1,
-           force_xpaon:1,
-           local_bias:1,
-           femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
-       u8 miscBits;
-       u16 xpaBiasLvlFreq[3];
-       u8 futureModal[6];
-
-       struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-struct calDataPerFreqOpLoop {
-       u8 pwrPdg[2][5];
-       u8 vpdPdg[2][5];
-       u8 pcdac[2][5];
-       u8 empty[2][5];
-} __packed;
-
-struct modal_eep_4k_header {
-       u32  antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
-       u32  antCtrlCommon;
-       u8   antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   switchSettling;
-       u8   txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   adcDesiredSize;
-       u8   pgaDesiredSize;
-       u8   xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   txEndToXpaOff;
-       u8   txEndToRxOn;
-       u8   txFrameToXpaOn;
-       u8   thresh62;
-       u8   noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   xpdGain;
-       u8   xpd;
-       u8   iqCalICh[AR5416_EEP4K_MAX_CHAINS];
-       u8   iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   pdGainOverlap;
-       u8   ob_01;
-       u8   db1_01;
-       u8   xpaBiasLvl;
-       u8   txFrameToDataStart;
-       u8   txFrameToPaOn;
-       u8   ht40PowerIncForPdadc;
-       u8   bswAtten[AR5416_EEP4K_MAX_CHAINS];
-       u8   bswMargin[AR5416_EEP4K_MAX_CHAINS];
-       u8   swSettleHt40;
-       u8   xatten2Db[AR5416_EEP4K_MAX_CHAINS];
-       u8   xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
-       u8   db2_01;
-       u8   version;
-       u16  ob_234;
-       u16  db1_234;
-       u16  db2_234;
-       u8   futureModal[4];
-
-       struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-
-struct cal_data_per_freq {
-       u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-       u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_data_per_freq_4k {
-       u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
-       u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_target_power_leg {
-       u8 bChannel;
-       u8 tPow2x[4];
-} __packed;
-
-struct cal_target_power_ht {
-       u8 bChannel;
-       u8 tPow2x[8];
-} __packed;
-
-
-#ifdef __BIG_ENDIAN_BITFIELD
-struct cal_ctl_edges {
-       u8 bChannel;
-       u8 flag:2, tPower:6;
-} __packed;
-#else
-struct cal_ctl_edges {
-       u8 bChannel;
-       u8 tPower:6, flag:2;
-} __packed;
-#endif
-
-struct cal_ctl_data {
-       struct cal_ctl_edges
-       ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
-} __packed;
-
-struct cal_ctl_data_4k {
-       struct cal_ctl_edges
-       ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
-} __packed;
-
-struct ar5416_eeprom_def {
-       struct base_eep_header baseEepHeader;
-       u8 custData[64];
-       struct modal_eep_header modalHeader[2];
-       u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
-       u8 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];
-       u8 ctlIndex[AR5416_NUM_CTLS];
-       struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
-       u8 padding;
-} __packed;
-
-struct ar5416_eeprom_4k {
-       struct base_eep_header_4k baseEepHeader;
-       u8 custData[20];
-       struct modal_eep_4k_header modalHeader;
-       u8 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];
-       u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
-       struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
-       u8 padding;
-} __packed;
-
-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 {
-       u16 countryCode;
-       u16 regDmnEnum;
-       u16 regDmn5G;
-       u16 regDmn2G;
-       u8 isMultidomain;
-       u8 iso[3];
-};
-
-enum ath9k_eep_map {
-       EEP_MAP_DEFAULT = 0x0,
-       EEP_MAP_4KBITS,
-       EEP_MAP_MAX
-};
-
-struct eeprom_ops {
-       int (*check_eeprom)(struct ath_hw *hw);
-       u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
-       bool (*fill_eeprom)(struct ath_hw *hw);
-       int (*get_eeprom_ver)(struct ath_hw *hw);
-       int (*get_eeprom_rev)(struct ath_hw *hw);
-       u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
-       u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
-                                     struct ath9k_channel *chan);
-       void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
-       void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
-       int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
-                          u16 cfgCtl, u8 twiceAntennaReduction,
-                          u8 twiceMaxRegulatoryPower, u8 powerLimit);
-       u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
-};
-
-#define ar5416_get_ntxchains(_txchainmask)                     \
-       (((_txchainmask >> 2) & 1) +                            \
-        ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
-
-int ath9k_hw_eeprom_attach(struct ath_hw *ah);
-
-#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
deleted file mode 100644 (file)
index 24299e6..0000000
+++ /dev/null
@@ -1,3861 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 <linux/io.h>
-#include <asm/unaligned.h>
-
-#include "ath9k.h"
-#include "initvals.h"
-
-static int btcoex_enable;
-module_param(btcoex_enable, bool, 0);
-MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
-
-#define ATH9K_CLOCK_RATE_CCK           22
-#define ATH9K_CLOCK_RATE_5GHZ_OFDM     40
-#define ATH9K_CLOCK_RATE_2GHZ_OFDM     44
-
-static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-                             enum ath9k_ht_macmode macmode);
-static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
-                             struct ar5416_eeprom_def *pEepData,
-                             u32 reg, u32 value);
-static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-
-/********************/
-/* Helper Functions */
-/********************/
-
-static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       if (!ah->curchan) /* should really check for CCK instead */
-               return clks / ATH9K_CLOCK_RATE_CCK;
-       if (conf->channel->band == IEEE80211_BAND_2GHZ)
-               return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
-
-       return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
-}
-
-static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       if (conf_is_ht40(conf))
-               return ath9k_hw_mac_usec(ah, clks) / 2;
-       else
-               return ath9k_hw_mac_usec(ah, clks);
-}
-
-static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       if (!ah->curchan) /* should really check for CCK instead */
-               return usecs *ATH9K_CLOCK_RATE_CCK;
-       if (conf->channel->band == IEEE80211_BAND_2GHZ)
-               return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
-       return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
-}
-
-static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       if (conf_is_ht40(conf))
-               return ath9k_hw_mac_clks(ah, usecs) * 2;
-       else
-               return ath9k_hw_mac_clks(ah, usecs);
-}
-
-bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
-{
-       int i;
-
-       BUG_ON(timeout < AH_TIME_QUANTUM);
-
-       for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
-               if ((REG_READ(ah, reg) & mask) == val)
-                       return true;
-
-               udelay(AH_TIME_QUANTUM);
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-               "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
-               timeout, reg, REG_READ(ah, reg), mask, val);
-
-       return false;
-}
-
-u32 ath9k_hw_reverse_bits(u32 val, u32 n)
-{
-       u32 retval;
-       int i;
-
-       for (i = 0, retval = 0; i < n; i++) {
-               retval = (retval << 1) | (val & 1);
-               val >>= 1;
-       }
-       return retval;
-}
-
-bool ath9k_get_channel_edges(struct ath_hw *ah,
-                            u16 flags, u16 *low,
-                            u16 *high)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-       if (flags & CHANNEL_5GHZ) {
-               *low = pCap->low_5ghz_chan;
-               *high = pCap->high_5ghz_chan;
-               return true;
-       }
-       if ((flags & CHANNEL_2GHZ)) {
-               *low = pCap->low_2ghz_chan;
-               *high = pCap->high_2ghz_chan;
-               return true;
-       }
-       return false;
-}
-
-u16 ath9k_hw_computetxtime(struct ath_hw *ah,
-                          struct ath_rate_table *rates,
-                          u32 frameLen, u16 rateix,
-                          bool shortPreamble)
-{
-       u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
-       u32 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->curchan && IS_CHAN_QUARTER_RATE(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->curchan &&
-                          IS_CHAN_HALF_RATE(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:
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Unknown phy %u (rate ix %u)\n",
-                       rates->info[rateix].phy, rateix);
-               txTime = 0;
-               break;
-       }
-
-       return txTime;
-}
-
-void ath9k_hw_get_channel_centers(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 struct chan_centers *centers)
-{
-       int8_t extoff;
-
-       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 *
-                        ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
-                         HT40_CHANNEL_CENTER_SHIFT : 15));
-}
-
-/******************/
-/* Chip Revisions */
-/******************/
-
-static void ath9k_hw_read_revisions(struct ath_hw *ah)
-{
-       u32 val;
-
-       val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
-
-       if (val == 0xFF) {
-               val = REG_READ(ah, AR_SREV);
-               ah->hw_version.macVersion =
-                       (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
-               ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
-               ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
-       } else {
-               if (!AR_SREV_9100(ah))
-                       ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
-
-               ah->hw_version.macRev = val & AR_SREV_REVISION;
-
-               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
-                       ah->is_pciexpress = true;
-       }
-}
-
-static int ath9k_hw_get_radiorev(struct ath_hw *ah)
-{
-       u32 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_hw *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 bool ath9k_hw_chip_test(struct ath_hw *ah)
-{
-       u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
-       u32 regHold[2];
-       u32 patternData[4] = { 0x55555555,
-                              0xaaaaaaaa,
-                              0x66666666,
-                              0x99999999 };
-       int i, j;
-
-       for (i = 0; i < 2; i++) {
-               u32 addr = regAddr[i];
-               u32 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) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                                       "address test failed "
-                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
-                                       addr, wrData, rdData);
-                               return false;
-                       }
-               }
-               for (j = 0; j < 4; j++) {
-                       wrData = patternData[j];
-                       REG_WRITE(ah, addr, wrData);
-                       rdData = REG_READ(ah, addr);
-                       if (wrData != rdData) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                                       "address test failed "
-                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
-                                       addr, wrData, rdData);
-                               return false;
-                       }
-               }
-               REG_WRITE(ah, regAddr[i], regHold[i]);
-       }
-       udelay(100);
-
-       return true;
-}
-
-static const char *ath9k_hw_devname(u16 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 AR5416_AR9100_DEVID:
-               return "Atheros 9100";
-       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_hw *ah)
-{
-       int i;
-
-       ah->config.dma_beacon_response_time = 2;
-       ah->config.sw_beacon_response_time = 10;
-       ah->config.additional_swba_backoff = 0;
-       ah->config.ack_6mb = 0x0;
-       ah->config.cwm_ignore_extcca = 0;
-       ah->config.pcie_powersave_enable = 0;
-       ah->config.pcie_clock_req = 0;
-       ah->config.pcie_waen = 0;
-       ah->config.analog_shiftreg = 1;
-       ah->config.ht_enable = 1;
-       ah->config.ofdm_trig_low = 200;
-       ah->config.ofdm_trig_high = 500;
-       ah->config.cck_trig_high = 200;
-       ah->config.cck_trig_low = 100;
-       ah->config.enable_ani = 1;
-       ah->config.diversity_control = 0;
-       ah->config.antenna_switch_swap = 0;
-
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               ah->config.spurchans[i][0] = AR_NO_SPUR;
-               ah->config.spurchans[i][1] = AR_NO_SPUR;
-       }
-
-       ah->config.intr_mitigation = true;
-
-       /*
-        * 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).
-        */
-       if (num_possible_cpus() > 1)
-               ah->config.serialize_regmode = SER_REG_MODE_AUTO;
-}
-
-static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
-                                       int *status)
-{
-       struct ath_hw *ah;
-
-       ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
-       if (ah == NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Cannot allocate memory for state block\n");
-               *status = -ENOMEM;
-               return NULL;
-       }
-
-       ah->ah_sc = sc;
-       ah->hw_version.magic = AR5416_MAGIC;
-       ah->regulatory.country_code = CTRY_DEFAULT;
-       ah->hw_version.devid = devid;
-       ah->hw_version.subvendorid = 0;
-
-       ah->ah_flags = 0;
-       if ((devid == AR5416_AR9100_DEVID))
-               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
-       if (!AR_SREV_9100(ah))
-               ah->ah_flags = AH_USE_EEPROM;
-
-       ah->regulatory.power_limit = MAX_RATE_POWER;
-       ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
-       ah->atim_window = 0;
-       ah->diversity_control = ah->config.diversity_control;
-       ah->antenna_switch_swap =
-               ah->config.antenna_switch_swap;
-       ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
-       ah->beacon_interval = 100;
-       ah->enable_32kHz_clock = DONT_USE_32KHZ;
-       ah->slottime = (u32) -1;
-       ah->acktimeout = (u32) -1;
-       ah->ctstimeout = (u32) -1;
-       ah->globaltxtimeout = (u32) -1;
-
-       ah->gbeacon_rate = 0;
-
-       return ah;
-}
-
-static int ath9k_hw_rfattach(struct ath_hw *ah)
-{
-       bool rfStatus = false;
-       int ecode = 0;
-
-       rfStatus = ath9k_hw_init_rf(ah, &ecode);
-       if (!rfStatus) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "RF setup failed, status: %u\n", ecode);
-               return ecode;
-       }
-
-       return 0;
-}
-
-static int ath9k_hw_rf_claim(struct ath_hw *ah)
-{
-       u32 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:
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Radio Chip Rev 0x%02X not supported\n",
-                       val & AR_RADIO_SREV_MAJOR);
-               return -EOPNOTSUPP;
-       }
-
-       ah->hw_version.analog5GhzRev = val;
-
-       return 0;
-}
-
-static int ath9k_hw_init_macaddr(struct ath_hw *ah)
-{
-       u32 sum;
-       int i;
-       u16 eeval;
-
-       sum = 0;
-       for (i = 0; i < 3; i++) {
-               eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
-               sum += eeval;
-               ah->macaddr[2 * i] = eeval >> 8;
-               ah->macaddr[2 * i + 1] = eeval & 0xff;
-       }
-       if (sum == 0 || sum == 0xffff * 3)
-               return -EADDRNOTAVAIL;
-
-       return 0;
-}
-
-static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
-{
-       u32 rxgain_type;
-
-       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
-               rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
-
-               if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
-                       INIT_INI_ARRAY(&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(&ah->iniModesRxGain,
-                       ar9280Modes_backoff_23db_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_original_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
-       } else {
-               INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_original_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
-       }
-}
-
-static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
-{
-       u32 txgain_type;
-
-       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
-               txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
-               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9280Modes_high_power_tx_gain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9280Modes_original_tx_gain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
-       } else {
-               INIT_INI_ARRAY(&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_hw *ah)
-{
-       int ecode;
-
-       if (!ath9k_hw_chip_test(ah))
-               return -ENODEV;
-
-       ecode = ath9k_hw_rf_claim(ah);
-       if (ecode != 0)
-               return ecode;
-
-       ecode = ath9k_hw_eeprom_attach(ah);
-       if (ecode != 0)
-               return ecode;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_CONFIG, "Eeprom VER: %d, REV: %d\n",
-               ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah));
-
-       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_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
-                                        int *status)
-{
-       struct ath_hw *ah;
-       int ecode;
-       u32 i, j;
-
-       ah = ath9k_hw_newstate(devid, sc, status);
-       if (ah == NULL)
-               return NULL;
-
-       ath9k_hw_set_defaults(ah);
-
-       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
-               DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n");
-               ecode = -EIO;
-               goto bad;
-       }
-
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
-               DPRINTF(sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
-               ecode = -EIO;
-               goto bad;
-       }
-
-       if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
-               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
-                   (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
-                       ah->config.serialize_regmode =
-                               SER_REG_MODE_ON;
-               } else {
-                       ah->config.serialize_regmode =
-                               SER_REG_MODE_OFF;
-               }
-       }
-
-       DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
-               ah->config.serialize_regmode);
-
-       if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
-           (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
-           (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
-           (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Mac Chip Rev 0x%02x.%x is not supported by "
-                       "this driver\n", ah->hw_version.macVersion,
-                       ah->hw_version.macRev);
-               ecode = -EOPNOTSUPP;
-               goto bad;
-       }
-
-       if (AR_SREV_9100(ah)) {
-               ah->iq_caldata.calData = &iq_cal_multi_sample;
-               ah->supp_cals = IQ_MISMATCH_CAL;
-               ah->is_pciexpress = false;
-       }
-       ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
-
-       if (AR_SREV_9160_10_OR_LATER(ah)) {
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       ah->iq_caldata.calData = &iq_cal_single_sample;
-                       ah->adcgain_caldata.calData =
-                               &adc_gain_cal_single_sample;
-                       ah->adcdc_caldata.calData =
-                               &adc_dc_cal_single_sample;
-                       ah->adcdc_calinitdata.calData =
-                               &adc_init_dc_cal;
-               } else {
-                       ah->iq_caldata.calData = &iq_cal_multi_sample;
-                       ah->adcgain_caldata.calData =
-                               &adc_gain_cal_multi_sample;
-                       ah->adcdc_caldata.calData =
-                               &adc_dc_cal_multi_sample;
-                       ah->adcdc_calinitdata.calData =
-                               &adc_init_dc_cal;
-               }
-               ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
-       }
-
-       ah->ani_function = ATH9K_ANI_ALL;
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
-
-       if (AR_SREV_9285_12_OR_LATER(ah)) {
-
-               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
-                              ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
-                              ARRAY_SIZE(ar9285Common_9285_1_2), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_off_L1_9285_1_2,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
-               } else {
-                       INIT_INI_ARRAY(&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(&ah->iniModes, ar9285Modes_9285,
-                              ARRAY_SIZE(ar9285Modes_9285), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
-                              ARRAY_SIZE(ar9285Common_9285), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_off_L1_9285,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
-               } else {
-                       INIT_INI_ARRAY(&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(&ah->iniModes, ar9280Modes_9280_2,
-                              ARRAY_SIZE(ar9280Modes_9280_2), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
-                              ARRAY_SIZE(ar9280Common_9280_2), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                              ar9280PciePhy_clkreq_off_L1_9280,
-                              ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                              ar9280PciePhy_clkreq_always_on_L1_9280,
-                              ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
-               }
-               INIT_INI_ARRAY(&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(&ah->iniModes, ar9280Modes_9280,
-                              ARRAY_SIZE(ar9280Modes_9280), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
-                              ARRAY_SIZE(ar9280Common_9280), 2);
-       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
-                              ARRAY_SIZE(ar5416Modes_9160), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
-                              ARRAY_SIZE(ar5416Common_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
-                              ARRAY_SIZE(ar5416Bank0_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
-                              ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
-                              ARRAY_SIZE(ar5416Bank1_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
-                              ARRAY_SIZE(ar5416Bank2_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
-                              ARRAY_SIZE(ar5416Bank3_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
-                              ARRAY_SIZE(ar5416Bank6_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
-                              ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
-                              ARRAY_SIZE(ar5416Bank7_9160), 2);
-               if (AR_SREV_9160_11(ah)) {
-                       INIT_INI_ARRAY(&ah->iniAddac,
-                                      ar5416Addac_91601_1,
-                                      ARRAY_SIZE(ar5416Addac_91601_1), 2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
-                                      ARRAY_SIZE(ar5416Addac_9160), 2);
-               }
-       } else if (AR_SREV_9100_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
-                              ARRAY_SIZE(ar5416Modes_9100), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
-                              ARRAY_SIZE(ar5416Common_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
-                              ARRAY_SIZE(ar5416Bank0_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
-                              ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
-                              ARRAY_SIZE(ar5416Bank1_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
-                              ARRAY_SIZE(ar5416Bank2_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
-                              ARRAY_SIZE(ar5416Bank3_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
-                              ARRAY_SIZE(ar5416Bank6_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
-                              ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
-                              ARRAY_SIZE(ar5416Bank7_9100), 2);
-               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
-                              ARRAY_SIZE(ar5416Addac_9100), 2);
-       } else {
-               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
-                              ARRAY_SIZE(ar5416Modes), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
-                              ARRAY_SIZE(ar5416Common), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
-                              ARRAY_SIZE(ar5416Bank0), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
-                              ARRAY_SIZE(ar5416BB_RfGain), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
-                              ARRAY_SIZE(ar5416Bank1), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
-                              ARRAY_SIZE(ar5416Bank2), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
-                              ARRAY_SIZE(ar5416Bank3), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
-                              ARRAY_SIZE(ar5416Bank6), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
-                              ARRAY_SIZE(ar5416Bank6TPC), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
-                              ARRAY_SIZE(ar5416Bank7), 2);
-               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
-                              ARRAY_SIZE(ar5416Addac), 2);
-       }
-
-       if (ah->is_pciexpress)
-               ath9k_hw_configpcipowersave(ah, 0);
-       else
-               ath9k_hw_disablepcie(ah);
-
-       ecode = ath9k_hw_post_attach(ah);
-       if (ecode != 0)
-               goto bad;
-
-       if (AR_SREV_9285_12_OR_LATER(ah)) {
-               u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
-               /* txgain table */
-               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9285Modes_high_power_tx_gain_9285_1_2,
-                       ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9285Modes_original_tx_gain_9285_1_2,
-                       ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
-               }
-
-       }
-
-       /* 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);
-
-       ath9k_hw_fill_cap_info(ah);
-
-       if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
-           test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
-
-               /* EEPROM Fixup */
-               for (i = 0; i < ah->iniModes.ia_rows; i++) {
-                       u32 reg = INI_RA(&ah->iniModes, i, 0);
-
-                       for (j = 1; j < ah->iniModes.ia_columns; j++) {
-                               u32 val = INI_RA(&ah->iniModes, i, j);
-
-                               INI_RA(&ah->iniModes, i, j) =
-                                       ath9k_hw_ini_fixup(ah,
-                                                          &ah->eeprom.def,
-                                                          reg, val);
-                       }
-               }
-       }
-
-       ecode = ath9k_hw_init_macaddr(ah);
-       if (ecode != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Failed to initialize MAC address\n");
-               goto bad;
-       }
-
-       if (AR_SREV_9285(ah))
-               ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
-       else
-               ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
-
-       ath9k_init_nfcal_hist_buffer(ah);
-
-       return ah;
-bad:
-       if (ah)
-               ath9k_hw_detach(ah);
-       if (status)
-               *status = ecode;
-
-       return NULL;
-}
-
-static void ath9k_hw_init_bb(struct ath_hw *ah,
-                            struct ath9k_channel *chan)
-{
-       u32 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);
-
-       udelay(synthDelay + BASE_ACTIVATE_DELAY);
-}
-
-static void ath9k_hw_init_qos(struct ath_hw *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_hw *ah,
-                             struct ath9k_channel *chan)
-{
-       u32 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, AR_RTC_PLL_CONTROL, pll);
-
-       udelay(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_hw *ah)
-{
-       int rx_chainmask, tx_chainmask;
-
-       rx_chainmask = ah->rxchainmask;
-       tx_chainmask = ah->txchainmask;
-
-       switch (rx_chainmask) {
-       case 0x5:
-               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-                           AR_PHY_SWAP_ALT_CHAIN);
-       case 0x3:
-               if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
-                       REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
-                       REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
-                       break;
-               }
-       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_hw *ah,
-                                         enum nl80211_iftype opmode)
-{
-       ah->mask_reg = AR_IMR_TXERR |
-               AR_IMR_TXURN |
-               AR_IMR_RXERR |
-               AR_IMR_RXORN |
-               AR_IMR_BCNMISC;
-
-       if (ah->config.intr_mitigation)
-               ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
-       else
-               ah->mask_reg |= AR_IMR_RXOK;
-
-       ah->mask_reg |= AR_IMR_TXOK;
-
-       if (opmode == NL80211_IFTYPE_AP)
-               ah->mask_reg |= AR_IMR_MIB;
-
-       REG_WRITE(ah, AR_IMR, ah->mask_reg);
-       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 bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
-{
-       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us);
-               ah->acktimeout = (u32) -1;
-               return false;
-       } else {
-               REG_RMW_FIELD(ah, AR_TIME_OUT,
-                             AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
-               ah->acktimeout = us;
-               return true;
-       }
-}
-
-static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
-{
-       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us);
-               ah->ctstimeout = (u32) -1;
-               return false;
-       } else {
-               REG_RMW_FIELD(ah, AR_TIME_OUT,
-                             AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
-               ah->ctstimeout = us;
-               return true;
-       }
-}
-
-static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
-{
-       if (tu > 0xFFFF) {
-               DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
-                       "bad global tx timeout %u\n", tu);
-               ah->globaltxtimeout = (u32) -1;
-               return false;
-       } else {
-               REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
-               ah->globaltxtimeout = tu;
-               return true;
-       }
-}
-
-static void ath9k_hw_init_user_settings(struct ath_hw *ah)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
-               ah->misc_mode);
-
-       if (ah->misc_mode != 0)
-               REG_WRITE(ah, AR_PCU_MISC,
-                         REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
-       if (ah->slottime != (u32) -1)
-               ath9k_hw_setslottime(ah, ah->slottime);
-       if (ah->acktimeout != (u32) -1)
-               ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
-       if (ah->ctstimeout != (u32) -1)
-               ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
-       if (ah->globaltxtimeout != (u32) -1)
-               ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
-}
-
-const char *ath9k_hw_probe(u16 vendorid, u16 devid)
-{
-       return vendorid == ATHEROS_VENDOR_ID ?
-               ath9k_hw_devname(devid) : NULL;
-}
-
-void ath9k_hw_detach(struct ath_hw *ah)
-{
-       if (!AR_SREV_9100(ah))
-               ath9k_hw_ani_detach(ah);
-
-       ath9k_hw_rfdetach(ah);
-       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
-       kfree(ah);
-}
-
-struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
-{
-       struct ath_hw *ah = NULL;
-
-       switch (devid) {
-       case AR5416_DEVID_PCI:
-       case AR5416_DEVID_PCIE:
-       case AR5416_AR9100_DEVID:
-       case AR9160_DEVID_PCI:
-       case AR9280_DEVID_PCI:
-       case AR9280_DEVID_PCIE:
-       case AR9285_DEVID_PCIE:
-               ah = ath9k_hw_do_attach(devid, sc, error);
-               break;
-       default:
-               *error = -ENXIO;
-               break;
-       }
-
-       return ah;
-}
-
-/*******/
-/* INI */
-/*******/
-
-static void ath9k_hw_override_ini(struct ath_hw *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_20_OR_LATER(ah) ||
-           AR_SREV_9280_10_OR_LATER(ah))
-               return;
-
-       REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
-}
-
-static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
-                             struct ar5416_eeprom_def *pEepData,
-                             u32 reg, u32 value)
-{
-       struct base_eep_header *pBase = &(pEepData->baseEepHeader);
-
-       switch (ah->hw_version.devid) {
-       case AR9280_DEVID_PCI:
-               if (reg == 0x7894) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                               "ini VAL: %x  EEPROM: %x\n", value,
-                               (pBase->version & 0xff));
-
-                       if ((pBase->version & 0xff) > 0x0a) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                       "PWDCLKIND: %d\n",
-                                       pBase->pwdclkind);
-                               value &= ~AR_AN_TOP2_PWDCLKIND;
-                               value |= AR_AN_TOP2_PWDCLKIND &
-                                       (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
-                       } else {
-                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                       "PWDCLKIND Earlier Rev\n");
-                       }
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                               "final ini VAL: %x\n", value);
-               }
-               break;
-       }
-
-       return value;
-}
-
-static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
-                             struct ar5416_eeprom_def *pEepData,
-                             u32 reg, u32 value)
-{
-       if (ah->eep_map == EEP_MAP_4KBITS)
-               return value;
-       else
-               return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
-}
-
-static void ath9k_olc_init(struct ath_hw *ah)
-{
-       u32 i;
-
-       for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
-               ah->originalGain[i] =
-                       MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
-                                       AR_PHY_TX_GAIN);
-       ah->PDADCdelta = 0;
-}
-
-static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
-                             struct ath9k_channel *chan)
-{
-       u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
-
-       if (IS_CHAN_B(chan))
-               ctl |= CTL_11B;
-       else if (IS_CHAN_G(chan))
-               ctl |= CTL_11G;
-       else
-               ctl |= CTL_11A;
-
-       return ctl;
-}
-
-static int ath9k_hw_process_ini(struct ath_hw *ah,
-                               struct ath9k_channel *chan,
-                               enum ath9k_ht_macmode macmode)
-{
-       int i, regWrites = 0;
-       struct ieee80211_channel *channel = chan->chan;
-       u32 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:
-               return -EINVAL;
-       }
-
-       REG_WRITE(ah, AR_PHY(0), 0x00000007);
-       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
-       ah->eep_ops->set_addac(ah, chan);
-
-       if (AR_SREV_5416_22_OR_LATER(ah)) {
-               REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
-       } else {
-               struct ar5416IniArray temp;
-               u32 addacSize =
-                       sizeof(u32) * ah->iniAddac.ia_rows *
-                       ah->iniAddac.ia_columns;
-
-               memcpy(ah->addac5416_21,
-                      ah->iniAddac.ia_array, addacSize);
-
-               (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
-
-               temp.ia_array = ah->addac5416_21;
-               temp.ia_columns = ah->iniAddac.ia_columns;
-               temp.ia_rows = ah->iniAddac.ia_rows;
-               REG_WRITE_ARRAY(&temp, 1, regWrites);
-       }
-
-       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
-
-       for (i = 0; i < ah->iniModes.ia_rows; i++) {
-               u32 reg = INI_RA(&ah->iniModes, i, 0);
-               u32 val = INI_RA(&ah->iniModes, i, modesIndex);
-
-               REG_WRITE(ah, reg, val);
-
-               if (reg >= 0x7800 && reg < 0x78a0
-                   && ah->config.analog_shiftreg) {
-                       udelay(100);
-               }
-
-               DO_DELAY(regWrites);
-       }
-
-       if (AR_SREV_9280(ah))
-               REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
-
-       if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
-           AR_SREV_9285_12_OR_LATER(ah)))
-               REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
-
-       for (i = 0; i < ah->iniCommon.ia_rows; i++) {
-               u32 reg = INI_RA(&ah->iniCommon, i, 0);
-               u32 val = INI_RA(&ah->iniCommon, i, 1);
-
-               REG_WRITE(ah, reg, val);
-
-               if (reg >= 0x7800 && reg < 0x78a0
-                   && ah->config.analog_shiftreg) {
-                       udelay(100);
-               }
-
-               DO_DELAY(regWrites);
-       }
-
-       ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
-
-       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
-               REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
-                               regWrites);
-       }
-
-       ath9k_hw_override_ini(ah, chan);
-       ath9k_hw_set_regs(ah, chan, macmode);
-       ath9k_hw_init_chain_masks(ah);
-
-       if (OLC_FOR_AR9280_20_LATER)
-               ath9k_olc_init(ah);
-
-       status = ah->eep_ops->set_txpower(ah, chan,
-                                 ath9k_regd_get_ctl(&ah->regulatory, chan),
-                                 channel->max_antenna_gain * 2,
-                                 channel->max_power * 2,
-                                 min((u32) MAX_RATE_POWER,
-                                     (u32) ah->regulatory.power_limit));
-       if (status != 0) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Error initializing transmit power\n");
-               return -EIO;
-       }
-
-       if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "ar5416SetRfRegs failed\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-/****************************************/
-/* Reset and Channel Switching Routines */
-/****************************************/
-
-static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       u32 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_hw *ah)
-{
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
-}
-
-static inline void ath9k_hw_set_dma(struct ath_hw *ah)
-{
-       u32 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->tx_trig_level);
-
-       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_hw *ah, int opmode)
-{
-       u32 val;
-
-       val = REG_READ(ah, AR_STA_ID1);
-       val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
-       switch (opmode) {
-       case NL80211_IFTYPE_AP:
-               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 NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_MESH_POINT:
-               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 NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_MONITOR:
-               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
-               break;
-       }
-}
-
-static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
-                                                u32 coef_scaled,
-                                                u32 *coef_mantissa,
-                                                u32 *coef_exponent)
-{
-       u32 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_hw *ah,
-                                    struct ath9k_channel *chan)
-{
-       u32 coef_scaled, ds_coef_exp, ds_coef_man;
-       u32 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 bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
-{
-       u32 rst_flags;
-       u32 tmpReg;
-
-       if (AR_SREV_9100(ah)) {
-               u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
-               val &= ~AR_RTC_DERIVED_CLK_PERIOD;
-               val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
-               REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
-               (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
-       }
-
-       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, AR_RTC_RC, rst_flags);
-       udelay(50);
-
-       REG_WRITE(ah, AR_RTC_RC, 0);
-       if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                       "RTC stuck in MAC reset\n");
-               return false;
-       }
-
-       if (!AR_SREV_9100(ah))
-               REG_WRITE(ah, AR_RC, 0);
-
-       ath9k_hw_init_pll(ah, NULL);
-
-       if (AR_SREV_9100(ah))
-               udelay(50);
-
-       return true;
-}
-
-static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
-{
-       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
-                 AR_RTC_FORCE_WAKE_ON_INT);
-
-       REG_WRITE(ah, AR_RTC_RESET, 0);
-       udelay(2);
-       REG_WRITE(ah, AR_RTC_RESET, 1);
-
-       if (!ath9k_hw_wait(ah,
-                          AR_RTC_STATUS,
-                          AR_RTC_STATUS_M,
-                          AR_RTC_STATUS_ON,
-                          AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n");
-               return false;
-       }
-
-       ath9k_hw_read_revisions(ah);
-
-       return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
-}
-
-static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 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);
-               break;
-       case ATH9K_RESET_WARM:
-       case ATH9K_RESET_COLD:
-               return ath9k_hw_set_reset(ah, type);
-               break;
-       default:
-               return false;
-       }
-}
-
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-                             enum ath9k_ht_macmode macmode)
-{
-       u32 phymode;
-       u32 enableDacFifo = 0;
-
-       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 (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 bool ath9k_hw_chip_reset(struct ath_hw *ah,
-                               struct ath9k_channel *chan)
-{
-       if (OLC_FOR_AR9280_20_LATER) {
-               if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
-                       return false;
-       } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
-               return false;
-
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
-               return false;
-
-       ah->chip_fullsleep = false;
-       ath9k_hw_init_pll(ah, chan);
-       ath9k_hw_set_rfmode(ah, chan);
-
-       return true;
-}
-
-static bool ath9k_hw_channel_change(struct ath_hw *ah,
-                                   struct ath9k_channel *chan,
-                                   enum ath9k_ht_macmode macmode)
-{
-       struct ieee80211_channel *channel = chan->chan;
-       u32 synthDelay, qnum;
-
-       for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
-               if (ath9k_hw_numtxpending(ah, qnum)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                               "Transmit frames pending on queue %d\n", qnum);
-                       return 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, AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Could not kill baseband RX\n");
-               return false;
-       }
-
-       ath9k_hw_set_regs(ah, chan, macmode);
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Failed to set channel\n");
-                       return false;
-               }
-       } else {
-               if (!(ath9k_hw_set_channel(ah, chan))) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Failed to set channel\n");
-                       return false;
-               }
-       }
-
-       if (ah->eep_ops->set_txpower(ah, chan,
-                            ath9k_regd_get_ctl(&ah->regulatory, chan),
-                            channel->max_antenna_gain * 2,
-                            channel->max_power * 2,
-                            min((u32) MAX_RATE_POWER,
-                                (u32) ah->regulatory.power_limit)) != 0) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "Error initializing transmit power\n");
-               return 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;
-
-       udelay(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 = true;
-
-       return true;
-}
-
-static void ath9k_hw_9280_spur_mitigate(struct ath_hw *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;
-       bool is2GHz = IS_CHAN_2GHZ(chan);
-
-       memset(&mask_m, 0, sizeof(int8_t) * 123);
-       memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = centers.synth_center;
-
-       ah->config.spurmode = SPUR_ENABLE_EEPROM;
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               cur_bb_spur = ah->eep_ops->get_spur_channel(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_v = abs(cur_vit_mask - bin);
-
-                       if (tmp_v < 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_hw *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;
-       bool is2GHz = IS_CHAN_2GHZ(chan);
-
-       memset(&mask_m, 0, sizeof(int8_t) * 123);
-       memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               cur_bb_spur = ah->eep_ops->get_spur_channel(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_v = abs(cur_vit_mask - bin);
-
-                       if (tmp_v < 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);
-}
-
-int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
-                   bool bChannelChange)
-{
-       u32 saveLedState;
-       struct ath_softc *sc = ah->ah_sc;
-       struct ath9k_channel *curchan = ah->curchan;
-       u32 saveDefAntenna;
-       u32 macStaId1;
-       int i, rx_chainmask, r;
-
-       ah->extprotspacing = sc->ht_extprotspacing;
-       ah->txchainmask = sc->tx_chainmask;
-       ah->rxchainmask = sc->rx_chainmask;
-
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
-               return -EIO;
-
-       if (curchan)
-               ath9k_hw_getnf(ah, curchan);
-
-       if (bChannelChange &&
-           (ah->chip_fullsleep != true) &&
-           (ah->curchan != NULL) &&
-           (chan->channel != ah->curchan->channel) &&
-           ((chan->channelFlags & CHANNEL_ALL) ==
-            (ah->curchan->channelFlags & CHANNEL_ALL)) &&
-           (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
-                                  !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) {
-
-               if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
-                       ath9k_hw_loadnf(ah, ah->curchan);
-                       ath9k_hw_start_nfcal(ah);
-                       return 0;
-               }
-       }
-
-       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)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n");
-               return -EINVAL;
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
-
-       r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
-       if (r)
-               return r;
-
-       /* Setup MFP options for CCMP */
-       if (AR_SREV_9280_20_OR_LATER(ah)) {
-               /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
-                * frames when constructing CCMP AAD. */
-               REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
-                             0xc7ff);
-               ah->sw_mgmt_crypto = false;
-       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
-               /* Disable hardware crypto for management frames */
-               REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
-                           AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
-               REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
-                           AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
-               ah->sw_mgmt_crypto = true;
-       } else
-               ah->sw_mgmt_crypto = true;
-
-       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);
-
-       ah->eep_ops->set_board_values(ah, chan);
-
-       ath9k_hw_decrease_chain_power(ah, chan);
-
-       REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr));
-       REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4)
-                 | macStaId1
-                 | AR_STA_ID1_RTS_USE_DEF
-                 | (ah->config.
-                    ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
-                 | ah->sta_id1_defaults);
-       ath9k_hw_set_operating_mode(ah, ah->opmode);
-
-       REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
-       REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
-
-       REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
-
-       REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
-       REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
-                 ((sc->curaid & 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)))
-                       return -EIO;
-       } else {
-               if (!(ath9k_hw_set_channel(ah, chan)))
-                       return -EIO;
-       }
-
-       for (i = 0; i < AR_NUM_DCU; i++)
-               REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
-
-       ah->intr_txqs = 0;
-       for (i = 0; i < ah->caps.total_queues; i++)
-               ath9k_hw_resettxqueue(ah, i);
-
-       ath9k_hw_init_interrupt_masks(ah, ah->opmode);
-       ath9k_hw_init_qos(ah);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       if (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 (ah->config.intr_mitigation) {
-               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))
-               return -EIO;;
-
-       rx_chainmask = 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)) {
-               u32 mask;
-               mask = REG_READ(ah, AR_CFG);
-               if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                               "CFG Byte Swap Set 0x%x\n", mask);
-               } else {
-                       mask =
-                               INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
-                       REG_WRITE(ah, AR_CFG, mask);
-                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                               "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
-               }
-       } else {
-#ifdef __BIG_ENDIAN
-               REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
-#endif
-       }
-
-       return 0;
-}
-
-/************************/
-/* Key Cache Management */
-/************************/
-
-bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
-{
-       u32 keyType;
-
-       if (entry >= ah->caps.keycache_size) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "keychache entry %u out of range\n", entry);
-               return 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)) {
-               u16 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->curchan == NULL)
-               return true;
-
-       return true;
-}
-
-bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
-{
-       u32 macHi, macLo;
-
-       if (entry >= ah->caps.keycache_size) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "keychache entry %u out of range\n", entry);
-               return 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 true;
-}
-
-bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
-                                const struct ath9k_keyval *k,
-                                const u8 *mac)
-{
-       const struct ath9k_hw_capabilities *pCap = &ah->caps;
-       u32 key0, key1, key2, key3, key4;
-       u32 keyType;
-
-       if (entry >= pCap->keycache_size) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "keycache entry %u out of range\n", entry);
-               return 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)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                               "AES-CCM not supported by mac rev 0x%x\n",
-                               ah->hw_version.macRev);
-                       return 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) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                               "entry %u inappropriate for TKIP\n", entry);
-                       return false;
-               }
-               break;
-       case ATH9K_CIPHER_WEP:
-               if (k->kv_len < LEN_WEP40) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                               "WEP key length %u too small\n", k->kv_len);
-                       return false;
-               }
-               if (k->kv_len <= LEN_WEP40)
-                       keyType = AR_KEYTABLE_TYPE_40;
-               else if (k->kv_len <= 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:
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "cipher %u not supported\n", k->kv_type);
-               return false;
-       }
-
-       key0 = get_unaligned_le32(k->kv_val + 0);
-       key1 = get_unaligned_le16(k->kv_val + 4);
-       key2 = get_unaligned_le32(k->kv_val + 6);
-       key3 = get_unaligned_le16(k->kv_val + 10);
-       key4 = get_unaligned_le32(k->kv_val + 12);
-       if (k->kv_len <= LEN_WEP104)
-               key4 &= 0xff;
-
-       /*
-        * Note: Key cache registers access special memory area that requires
-        * two 32-bit writes to actually update the values in the internal
-        * memory. Consequently, the exact order and pairs used here must be
-        * maintained.
-        */
-
-       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
-               u16 micentry = entry + 64;
-
-               /*
-                * Write inverted key[47:0] first to avoid Michael MIC errors
-                * on frames that could be sent or received at the same time.
-                * The correct key will be written in the end once everything
-                * else is ready.
-                */
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
-
-               /* Write key[95:48] */
-               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
-               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
-
-               /* Write key[127:96] and key type */
-               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
-               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
-
-               /* Write MAC address for the entry */
-               (void) ath9k_hw_keysetmac(ah, entry, mac);
-
-               if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
-                       /*
-                        * TKIP uses two key cache entries:
-                        * Michael MIC TX/RX keys in the same key cache entry
-                        * (idx = main index + 64):
-                        * key0 [31:0] = RX key [31:0]
-                        * key1 [15:0] = TX key [31:16]
-                        * key1 [31:16] = reserved
-                        * key2 [31:0] = RX key [63:32]
-                        * key3 [15:0] = TX key [15:0]
-                        * key3 [31:16] = reserved
-                        * key4 [31:0] = TX key [63:32]
-                        */
-                       u32 mic0, mic1, mic2, mic3, mic4;
-
-                       mic0 = get_unaligned_le32(k->kv_mic + 0);
-                       mic2 = get_unaligned_le32(k->kv_mic + 4);
-                       mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
-                       mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
-                       mic4 = get_unaligned_le32(k->kv_txmic + 4);
-
-                       /* Write RX[31:0] and TX[31:16] */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
-
-                       /* Write RX[63:32] and TX[15:0] */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
-
-                       /* Write TX[63:32] and keyType(reserved) */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
-                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
-                                 AR_KEYTABLE_TYPE_CLR);
-
-               } else {
-                       /*
-                        * TKIP uses four key cache entries (two for group
-                        * keys):
-                        * Michael MIC TX/RX keys are in different key cache
-                        * entries (idx = main index + 64 for TX and
-                        * main index + 32 + 96 for RX):
-                        * key0 [31:0] = TX/RX MIC key [31:0]
-                        * key1 [31:0] = reserved
-                        * key2 [31:0] = TX/RX MIC key [63:32]
-                        * key3 [31:0] = reserved
-                        * key4 [31:0] = reserved
-                        *
-                        * Upper layer code will call this function separately
-                        * for TX and RX keys when these registers offsets are
-                        * used.
-                        */
-                       u32 mic0, mic2;
-
-                       mic0 = get_unaligned_le32(k->kv_mic + 0);
-                       mic2 = get_unaligned_le32(k->kv_mic + 4);
-
-                       /* Write MIC key[31:0] */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
-
-                       /* Write MIC key[63:32] */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
-
-                       /* Write TX[63:32] and keyType(reserved) */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
-                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
-                                 AR_KEYTABLE_TYPE_CLR);
-               }
-
-               /* MAC address registers are reserved for the MIC entry */
-               REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
-
-               /*
-                * Write the correct (un-inverted) key[47:0] last to enable
-                * TKIP now that all other registers are set with correct
-                * values.
-                */
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
-       } else {
-               /* Write key[47:0] */
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
-
-               /* Write key[95:48] */
-               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
-               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
-
-               /* Write key[127:96] and key type */
-               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
-               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
-
-               /* Write MAC address for the entry */
-               (void) ath9k_hw_keysetmac(ah, entry, mac);
-       }
-
-       return true;
-}
-
-bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
-{
-       if (entry < ah->caps.keycache_size) {
-               u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
-               if (val & AR_KEYTABLE_VALID)
-                       return true;
-       }
-       return false;
-}
-
-/******************************/
-/* Power Management (Chipset) */
-/******************************/
-
-static void ath9k_set_power_sleep(struct ath_hw *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, (AR_RTC_RESET),
-                           AR_RTC_RESET_EN);
-       }
-}
-
-static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
-{
-       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-       if (setChip) {
-               struct ath9k_hw_capabilities *pCap = &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 bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
-{
-       u32 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) != true) {
-                               return 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);
-               udelay(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;
-                       udelay(50);
-                       REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
-                                   AR_RTC_FORCE_WAKE_EN);
-               }
-               if (i == 0) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Failed to wakeup in %uus\n", POWER_UP_TIME / 20);
-                       return false;
-               }
-       }
-
-       REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-
-       return true;
-}
-
-bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
-{
-       int status = true, setChip = true;
-       static const char *modes[] = {
-               "AWAKE",
-               "FULL-SLEEP",
-               "NETWORK SLEEP",
-               "UNDEFINED"
-       };
-
-       DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n",
-               modes[ah->power_mode], modes[mode]);
-
-       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);
-               ah->chip_fullsleep = true;
-               break;
-       case ATH9K_PM_NETWORK_SLEEP:
-               ath9k_set_power_network_sleep(ah, setChip);
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Unknown power mode %u\n", mode);
-               return false;
-       }
-       ah->power_mode = mode;
-
-       return status;
-}
-
-/*
- * Helper for ASPM support.
- *
- * Disable PLL when in L0s as well as receiver clock when in L1.
- * This power saving option must be enabled through the SerDes.
- *
- * Programming the SerDes must go through the same 288 bit serial shift
- * register as the other analog registers.  Hence the 9 writes.
- */
-void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
-{
-       u8 i;
-
-       if (ah->is_pciexpress != true)
-               return;
-
-       /* Do not touch SerDes registers */
-       if (ah->config.pcie_powersave_enable == 2)
-               return;
-
-       /* Nothing to do on restore for 11N */
-       if (restore)
-               return;
-
-       if (AR_SREV_9280_20_OR_LATER(ah)) {
-               /*
-                * AR9280 2.0 or later chips use SerDes values from the
-                * initvals.h initialized depending on chipset during
-                * ath9k_hw_do_attach()
-                */
-               for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
-                       REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
-                                 INI_RA(&ah->iniPcieSerdes, i, 1));
-               }
-       } else if (AR_SREV_9280(ah) &&
-                  (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-
-               /* RX shut off when elecidle is asserted */
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
-
-               /* Shut off CLKREQ active in L1 */
-               if (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);
-
-               /* Load the new settings */
-               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-
-       } else {
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-
-               /* RX shut off when elecidle is asserted */
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
-
-               /*
-                * Ignore ah->ah_config.pcie_clock_req setting for
-                * pre-AR9280 11n
-                */
-               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);
-
-               /* Load the new settings */
-               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-       }
-
-       udelay(1000);
-
-       /* set bit 19 to allow forcing of pcie core into L1 state */
-       REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
-
-       /* Several PCIe massages to ensure proper behaviour */
-       if (ah->config.pcie_waen) {
-               REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
-       } else {
-               if (AR_SREV_9285(ah))
-                       REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
-               /*
-                * On AR9280 chips bit 22 of 0x4004 needs to be set to
-                * otherwise card may disappear.
-                */
-               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 */
-/**********************/
-
-bool ath9k_hw_intrpend(struct ath_hw *ah)
-{
-       u32 host_isr;
-
-       if (AR_SREV_9100(ah))
-               return true;
-
-       host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
-       if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
-               return true;
-
-       host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
-       if ((host_isr & AR_INTR_SYNC_DEFAULT)
-           && (host_isr != AR_INTR_SPURIOUS))
-               return true;
-
-       return false;
-}
-
-bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
-{
-       u32 isr = 0;
-       u32 mask2 = 0;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       u32 sync_cause = 0;
-       bool fatal_int = false;
-
-       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 false;
-       } else {
-               *masked = 0;
-               isr = REG_READ(ah, AR_ISR);
-       }
-
-       if (isr) {
-               if (isr & AR_ISR_BCNMISC) {
-                       u32 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;
-                       if (isr2 & AR_ISR_S2_TSFOOR)
-                               mask2 |= ATH9K_INT_TSFOOR;
-               }
-
-               isr = REG_READ(ah, AR_ISR_RAC);
-               if (isr == 0xffffffff) {
-                       *masked = 0;
-                       return false;
-               }
-
-               *masked = isr & ATH9K_INT_COMMON;
-
-               if (ah->config.intr_mitigation) {
-                       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)) {
-                       u32 s0_s, s1_s;
-
-                       *masked |= ATH9K_INT_TX;
-
-                       s0_s = REG_READ(ah, AR_ISR_S0_S);
-                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
-                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
-
-                       s1_s = REG_READ(ah, AR_ISR_S1_S);
-                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
-                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
-               }
-
-               if (isr & AR_ISR_RXORN) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                               "receive FIFO overrun interrupt\n");
-               }
-
-               if (!AR_SREV_9100(ah)) {
-                       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-                               u32 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 true;
-
-       if (sync_cause) {
-               fatal_int =
-                       (sync_cause &
-                        (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
-                       ? true : false;
-
-               if (fatal_int) {
-                       if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                       "received PCI FATAL interrupt\n");
-                       }
-                       if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                       "received PCI PERR interrupt\n");
-                       }
-               }
-               if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                               "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
-                       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) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                               "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
-               }
-
-               REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
-               (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
-       }
-
-       return true;
-}
-
-enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
-{
-       return ah->mask_reg;
-}
-
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
-{
-       u32 omask = ah->mask_reg;
-       u32 mask, mask2;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
-
-       if (omask & ATH9K_INT_GLOBAL) {
-               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "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 (ah->txok_interrupt_mask)
-                       mask |= AR_IMR_TXOK;
-               if (ah->txdesc_interrupt_mask)
-                       mask |= AR_IMR_TXDESC;
-               if (ah->txerr_interrupt_mask)
-                       mask |= AR_IMR_TXERR;
-               if (ah->txeol_interrupt_mask)
-                       mask |= AR_IMR_TXEOL;
-       }
-       if (ints & ATH9K_INT_RX) {
-               mask |= AR_IMR_RXERR;
-               if (ah->config.intr_mitigation)
-                       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_TSFOOR)
-                       mask2 |= AR_IMR_S2_TSFOOR;
-       }
-
-       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;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
-       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);
-       ah->mask_reg = 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) {
-               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "enable IER\n");
-               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);
-               }
-               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
-                        REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
-       }
-
-       return omask;
-}
-
-/*******************/
-/* Beacon Handling */
-/*******************/
-
-void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
-{
-       int flags = 0;
-
-       ah->beacon_interval = beacon_period;
-
-       switch (ah->opmode) {
-       case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_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 NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_MESH_POINT:
-               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 +
-                                    (ah->atim_window ? ah->
-                                     atim_window : 1)));
-               flags |= AR_NDP_TIMER_EN;
-       case NL80211_IFTYPE_AP:
-               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->config.
-                                    dma_beacon_response_time));
-               REG_WRITE(ah, AR_NEXT_SWBA,
-                         TU_TO_USEC(next_beacon -
-                                    ah->config.
-                                    sw_beacon_response_time));
-               flags |=
-                       AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_BEACON,
-                       "%s: unsupported opmode: %d\n",
-                       __func__, ah->opmode);
-               return;
-               break;
-       }
-
-       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_hw *ah,
-                                   const struct ath9k_beacon_state *bs)
-{
-       u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
-       struct ath9k_hw_capabilities *pCap = &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;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
-       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
-       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
-       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "DTIM period %d\n", 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);
-
-       /* TSF Out of Range Threshold */
-       REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
-}
-
-/*******************/
-/* HW Capabilities */
-/*******************/
-
-void ath9k_hw_fill_cap_info(struct ath_hw *ah)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       u16 capField = 0, eeval;
-
-       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
-       ah->regulatory.current_rd = eeval;
-
-       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
-       if (AR_SREV_9285_10_OR_LATER(ah))
-               eeval |= AR9285_RDEXT_DEFAULT;
-       ah->regulatory.current_rd_ext = eeval;
-
-       capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
-
-       if (ah->opmode != NL80211_IFTYPE_AP &&
-           ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
-               if (ah->regulatory.current_rd == 0x64 ||
-                   ah->regulatory.current_rd == 0x65)
-                       ah->regulatory.current_rd += 5;
-               else if (ah->regulatory.current_rd == 0x41)
-                       ah->regulatory.current_rd = 0x43;
-               DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-                       "regdomain mapped to 0x%x\n", ah->regulatory.current_rd);
-       }
-
-       eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
-       bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
-
-       if (eeval & AR5416_OPFLAGS_11A) {
-               set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
-               if (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->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 = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
-       if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
-           !(eeval & AR5416_OPFLAGS_11A))
-               pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
-       else
-               pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
-
-       if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
-               ah->misc_mode |= 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;
-
-       if (ah->config.ht_enable)
-               pCap->hw_caps |= ATH9K_HW_CAP_HT;
-       else
-               pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
-
-       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->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
-
-       if (AR_SREV_9285_10_OR_LATER(ah))
-               pCap->num_gpio_pins = AR9285_NUM_GPIO;
-       else 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_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->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
-       if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
-               ah->rfkill_gpio =
-                       MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
-               ah->rfkill_polarity =
-                       MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
-
-               pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
-       }
-#endif
-
-       if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) ||
-           (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
-           (ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
-           (ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
-           (ah->hw_version.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->regulatory.current_rd_ext & (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;
-
-       pCap->num_antcfg_5ghz =
-               ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
-       pCap->num_antcfg_2ghz =
-               ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
-
-       if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
-               pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
-               ah->btactive_gpio = 6;
-               ah->wlanactive_gpio = 5;
-       }
-}
-
-bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
-                           u32 capability, u32 *result)
-{
-       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 true;
-               default:
-                       return false;
-               }
-       case ATH9K_CAP_TKIP_MIC:
-               switch (capability) {
-               case 0:
-                       return true;
-               case 1:
-                       return (ah->sta_id1_defaults &
-                               AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
-                       false;
-               }
-       case ATH9K_CAP_TKIP_SPLIT:
-               return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
-                       false : true;
-       case ATH9K_CAP_DIVERSITY:
-               return (REG_READ(ah, AR_PHY_CCK_DETECT) &
-                       AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
-                       true : false;
-       case ATH9K_CAP_MCAST_KEYSRCH:
-               switch (capability) {
-               case 0:
-                       return true;
-               case 1:
-                       if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
-                               return false;
-                       } else {
-                               return (ah->sta_id1_defaults &
-                                       AR_STA_ID1_MCAST_KSRCH) ? true :
-                                       false;
-                       }
-               }
-               return false;
-       case ATH9K_CAP_TXPOW:
-               switch (capability) {
-               case 0:
-                       return 0;
-               case 1:
-                       *result = ah->regulatory.power_limit;
-                       return 0;
-               case 2:
-                       *result = ah->regulatory.max_power_level;
-                       return 0;
-               case 3:
-                       *result = ah->regulatory.tp_scale;
-                       return 0;
-               }
-               return false;
-       case ATH9K_CAP_DS:
-               return (AR_SREV_9280_20_OR_LATER(ah) &&
-                       (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1))
-                       ? false : true;
-       default:
-               return false;
-       }
-}
-
-bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
-                           u32 capability, u32 setting, int *status)
-{
-       u32 v;
-
-       switch (type) {
-       case ATH9K_CAP_TKIP_MIC:
-               if (setting)
-                       ah->sta_id1_defaults |=
-                               AR_STA_ID1_CRPT_MIC_ENABLE;
-               else
-                       ah->sta_id1_defaults &=
-                               ~AR_STA_ID1_CRPT_MIC_ENABLE;
-               return 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 true;
-       case ATH9K_CAP_MCAST_KEYSRCH:
-               if (setting)
-                       ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
-               else
-                       ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
-               return true;
-       default:
-               return false;
-       }
-}
-
-/****************************/
-/* GPIO / RFKILL / Antennae */
-/****************************/
-
-static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
-                                        u32 gpio, u32 type)
-{
-       int addr;
-       u32 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_hw *ah, u32 gpio)
-{
-       u32 gpio_shift;
-
-       ASSERT(gpio < 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));
-}
-
-u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
-{
-#define MS_REG_READ(x, y) \
-       (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
-
-       if (gpio >= ah->caps.num_gpio_pins)
-               return 0xffffffff;
-
-       if (AR_SREV_9285_10_OR_LATER(ah))
-               return MS_REG_READ(AR9285, gpio) != 0;
-       else if (AR_SREV_9280_10_OR_LATER(ah))
-               return MS_REG_READ(AR928X, gpio) != 0;
-       else
-               return MS_REG_READ(AR, gpio) != 0;
-}
-
-void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
-                        u32 ah_signal_type)
-{
-       u32 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_hw *ah, u32 gpio, u32 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_hw *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->rfkill_gpio);
-       REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
-}
-#endif
-
-u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
-{
-       return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
-}
-
-void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
-{
-       REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
-}
-
-bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
-                              enum ath9k_ant_setting settings,
-                              struct ath9k_channel *chan,
-                              u8 *tx_chainmask,
-                              u8 *rx_chainmask,
-                              u8 *antenna_cfgd)
-{
-       static u8 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 = true;
-                       break;
-               case ATH9K_ANT_FIXED_B:
-                       if (ah->caps.tx_chainmask >
-                           ATH9K_ANTENNA1_CHAINMASK) {
-                               *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-                       }
-                       *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-                       *antenna_cfgd = true;
-                       break;
-               case ATH9K_ANT_VARIABLE:
-                       *tx_chainmask = tx_chainmask_cfg;
-                       *rx_chainmask = rx_chainmask_cfg;
-                       *antenna_cfgd = true;
-                       break;
-               default:
-                       break;
-               }
-       } else {
-               ah->diversity_control = settings;
-       }
-
-       return true;
-}
-
-/*********************/
-/* General Operation */
-/*********************/
-
-u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
-{
-       u32 bits = REG_READ(ah, AR_RX_FILTER);
-       u32 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_hw *ah, u32 bits)
-{
-       u32 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);
-}
-
-bool ath9k_hw_phy_disable(struct ath_hw *ah)
-{
-       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
-}
-
-bool ath9k_hw_disable(struct ath_hw *ah)
-{
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
-               return false;
-
-       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
-}
-
-bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
-{
-       struct ath9k_channel *chan = ah->curchan;
-       struct ieee80211_channel *channel = chan->chan;
-
-       ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
-
-       if (ah->eep_ops->set_txpower(ah, chan,
-                            ath9k_regd_get_ctl(&ah->regulatory, chan),
-                            channel->max_antenna_gain * 2,
-                            channel->max_power * 2,
-                            min((u32) MAX_RATE_POWER,
-                                (u32) ah->regulatory.power_limit)) != 0)
-               return false;
-
-       return true;
-}
-
-void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
-{
-       memcpy(ah->macaddr, mac, ETH_ALEN);
-}
-
-void ath9k_hw_setopmode(struct ath_hw *ah)
-{
-       ath9k_hw_set_operating_mode(ah, ah->opmode);
-}
-
-void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
-{
-       REG_WRITE(ah, AR_MCAST_FIL0, filter0);
-       REG_WRITE(ah, AR_MCAST_FIL1, filter1);
-}
-
-void ath9k_hw_setbssidmask(struct ath_softc *sc)
-{
-       REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
-       REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
-}
-
-void ath9k_hw_write_associd(struct ath_softc *sc)
-{
-       REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
-       REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
-                 ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
-}
-
-u64 ath9k_hw_gettsf64(struct ath_hw *ah)
-{
-       u64 tsf;
-
-       tsf = REG_READ(ah, AR_TSF_U32);
-       tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
-
-       return tsf;
-}
-
-void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
-{
-       REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
-       REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
-}
-
-void ath9k_hw_reset_tsf(struct ath_hw *ah)
-{
-       int count;
-
-       count = 0;
-       while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
-               count++;
-               if (count > 10) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                               "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
-                       break;
-               }
-               udelay(10);
-       }
-       REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
-}
-
-bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
-{
-       if (setting)
-               ah->misc_mode |= AR_PCU_TX_ADD_TSF;
-       else
-               ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
-
-       return true;
-}
-
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
-{
-       if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us);
-               ah->slottime = (u32) -1;
-               return false;
-       } else {
-               REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
-               ah->slottime = us;
-               return true;
-       }
-}
-
-void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
-{
-       u32 macmode;
-
-       if (mode == ATH9K_HT_MACMODE_2040 &&
-           !ah->config.cwm_ignore_extcca)
-               macmode = AR_2040_JOINED_RX_CLEAR;
-       else
-               macmode = 0;
-
-       REG_WRITE(ah, AR_2040_MODE, macmode);
-}
-
-/***************************/
-/*  Bluetooth Coexistence  */
-/***************************/
-
-void ath9k_hw_btcoex_enable(struct ath_hw *ah)
-{
-       /* connect bt_active to baseband */
-       REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-                       (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
-                        AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
-
-       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-                       AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
-
-       /* Set input mux for bt_active to gpio pin */
-       REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
-                       AR_GPIO_INPUT_MUX1_BT_ACTIVE,
-                       ah->btactive_gpio);
-
-       /* Configure the desired gpio port for input */
-       ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
-
-       /* Configure the desired GPIO port for TX_FRAME output */
-       ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
-                           AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
-}
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
deleted file mode 100644 (file)
index 984ac7d..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 HW_H
-#define HW_H
-
-#include <linux/if_ether.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include "mac.h"
-#include "ani.h"
-#include "eeprom.h"
-#include "calib.h"
-#include "reg.h"
-#include "phy.h"
-
-#include "../ath/regd.h"
-
-#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 AR5416_MAGIC           0x19641014
-
-/* Register read/write primitives */
-#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
-#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_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 DO_DELAY(x) do {                       \
-               if ((++(x) % 64) == 0)          \
-                       udelay(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 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_TX_FRAME           3
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    5
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      6
-
-#define AR_GPIOD_MASK               0x00001FFF
-#define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
-
-#define BASE_ACTIVATE_DELAY         100
-#define RTC_PLL_SETTLE_DELAY        1000
-#define COEF_SCALE_S                24
-#define HT40_CHANNEL_CENTER_SHIFT   10
-
-#define ATH9K_ANTENNA0_CHAINMASK    0x1
-#define ATH9K_ANTENNA1_CHAINMASK    0x2
-
-#define ATH9K_NUM_DMA_DEBUG_REGS    8
-#define ATH9K_NUM_QUEUES            10
-
-#define MAX_RATE_POWER              63
-#define AH_WAIT_TIMEOUT             100000 /* (us) */
-#define AH_TIME_QUANTUM             10
-#define AR_KEYTABLE_SIZE            128
-#define POWER_UP_TIME               200000
-#define SPUR_RSSI_THRESH            40
-
-#define CAB_TIMEOUT_VAL             10
-#define BEACON_TIMEOUT_VAL          10
-#define MIN_BEACON_TIMEOUT_VAL      1
-#define SLEEP_SLOP                  3
-
-#define INIT_CONFIG_STATUS          0x00000000
-#define INIT_RSSI_THR               0x00000700
-#define INIT_BCON_CNTRL_REG         0x00000000
-
-#define TU_TO_USEC(_tu)             ((_tu) << 10)
-
-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_MIC_AESCCM                 = BIT(0),
-       ATH9K_HW_CAP_MIC_CKIP                   = BIT(1),
-       ATH9K_HW_CAP_MIC_TKIP                   = BIT(2),
-       ATH9K_HW_CAP_CIPHER_AESCCM              = BIT(3),
-       ATH9K_HW_CAP_CIPHER_CKIP                = BIT(4),
-       ATH9K_HW_CAP_CIPHER_TKIP                = BIT(5),
-       ATH9K_HW_CAP_VEOL                       = BIT(6),
-       ATH9K_HW_CAP_BSSIDMASK                  = BIT(7),
-       ATH9K_HW_CAP_MCAST_KEYSEARCH            = BIT(8),
-       ATH9K_HW_CAP_HT                         = BIT(9),
-       ATH9K_HW_CAP_GTT                        = BIT(10),
-       ATH9K_HW_CAP_FASTCC                     = BIT(11),
-       ATH9K_HW_CAP_RFSILENT                   = BIT(12),
-       ATH9K_HW_CAP_CST                        = BIT(13),
-       ATH9K_HW_CAP_ENHANCEDPM                 = BIT(14),
-       ATH9K_HW_CAP_AUTOSLEEP                  = BIT(15),
-       ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(16),
-       ATH9K_HW_CAP_BT_COEX                    = BIT(17)
-};
-
-enum ath9k_capability_type {
-       ATH9K_CAP_CIPHER = 0,
-       ATH9K_CAP_TKIP_MIC,
-       ATH9K_CAP_TKIP_SPLIT,
-       ATH9K_CAP_DIVERSITY,
-       ATH9K_CAP_TXPOW,
-       ATH9K_CAP_MCAST_KEYSRCH,
-       ATH9K_CAP_DS
-};
-
-struct ath9k_hw_capabilities {
-       u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
-       DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
-       u16 total_queues;
-       u16 keycache_size;
-       u16 low_5ghz_chan, high_5ghz_chan;
-       u16 low_2ghz_chan, high_2ghz_chan;
-       u16 rts_aggr_limit;
-       u8 tx_chainmask;
-       u8 rx_chainmask;
-       u16 tx_triglevel_max;
-       u16 reg_cap;
-       u8 num_gpio_pins;
-       u8 num_antcfg_2ghz;
-       u8 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;
-       u8 pcie_powersave_enable;
-       u8 pcie_clock_req;
-       u32 pcie_waen;
-       u8 analog_shiftreg;
-       u8 ht_enable;
-       u32 ofdm_trig_low;
-       u32 ofdm_trig_high;
-       u32 cck_trig_high;
-       u32 cck_trig_low;
-       u32 enable_ani;
-       u16 diversity_control;
-       u16 antenna_switch_swap;
-       int serialize_regmode;
-       bool 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;
-       u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
-};
-
-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_TSFOOR = 0x04000000,
-       ATH9K_INT_CST = 0x10000000,
-       ATH9K_INT_GTT = 0x20000000,
-       ATH9K_INT_FATAL = 0x40000000,
-       ATH9K_INT_GLOBAL = 0x80000000,
-       ATH9K_INT_BMISC = ATH9K_INT_TIM |
-               ATH9K_INT_DTIM |
-               ATH9K_INT_DTIMSYNC |
-               ATH9K_INT_TSFOOR |
-               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 = 0xffffffff
-};
-
-#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 {
-       struct ieee80211_channel *chan;
-       u16 channel;
-       u32 channelFlags;
-       u32 chanmode;
-       int32_t CalValid;
-       bool oneTimeCalsDone;
-       int8_t iCoff;
-       int8_t qCoff;
-       int16_t rawNoiseFloor;
-};
-
-#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)
-#define IS_CHAN_A_5MHZ_SPACED(_c)                      \
-       ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) &&  \
-        (((_c)->channel % 20) != 0) &&                 \
-        (((_c)->channel % 10) != 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)))
-
-enum ath9k_power_mode {
-       ATH9K_PM_AWAKE = 0,
-       ATH9K_PM_FULL_SLEEP,
-       ATH9K_PM_NETWORK_SLEEP,
-       ATH9K_PM_UNDEFINED
-};
-
-enum ath9k_ant_setting {
-       ATH9K_ANT_VARIABLE = 0,
-       ATH9K_ANT_FIXED_A,
-       ATH9K_ANT_FIXED_B
-};
-
-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,
-};
-
-struct ath9k_beacon_state {
-       u32 bs_nexttbtt;
-       u32 bs_nextdtim;
-       u32 bs_intval;
-#define ATH9K_BEACON_PERIOD       0x0000ffff
-#define ATH9K_BEACON_ENA          0x00800000
-#define ATH9K_BEACON_RESET_TSF    0x01000000
-#define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */
-       u32 bs_dtimperiod;
-       u16 bs_cfpperiod;
-       u16 bs_cfpmaxduration;
-       u32 bs_cfpnext;
-       u16 bs_timoffset;
-       u16 bs_bmissthreshold;
-       u32 bs_sleepduration;
-       u32 bs_tsfoor_threshold;
-};
-
-struct chan_centers {
-       u16 synth_center;
-       u16 ctl_center;
-       u16 ext_center;
-};
-
-enum {
-       ATH9K_RESET_POWER_ON,
-       ATH9K_RESET_WARM,
-       ATH9K_RESET_COLD,
-};
-
-struct ath9k_hw_version {
-       u32 magic;
-       u16 devid;
-       u16 subvendorid;
-       u32 macVersion;
-       u16 macRev;
-       u16 phyRev;
-       u16 analog5GhzRev;
-       u16 analog2GhzRev;
-};
-
-struct ath_hw {
-       struct ath_softc *ah_sc;
-       struct ath9k_hw_version hw_version;
-       struct ath9k_ops_config config;
-       struct ath9k_hw_capabilities caps;
-       struct ath_regulatory regulatory;
-       struct ath9k_channel channels[38];
-       struct ath9k_channel *curchan;
-
-       union {
-               struct ar5416_eeprom_def def;
-               struct ar5416_eeprom_4k map4k;
-       } eeprom;
-       const struct eeprom_ops *eep_ops;
-       enum ath9k_eep_map eep_map;
-
-       bool sw_mgmt_crypto;
-       bool is_pciexpress;
-       u8 macaddr[ETH_ALEN];
-       u16 tx_trig_level;
-       u16 rfsilent;
-       u32 rfkill_gpio;
-       u32 rfkill_polarity;
-       u32 btactive_gpio;
-       u32 wlanactive_gpio;
-       u32 ah_flags;
-
-       enum nl80211_iftype opmode;
-       enum ath9k_power_mode power_mode;
-       enum ath9k_power_mode restore_mode;
-
-       struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-       struct ar5416Stats stats;
-       struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
-
-       int16_t curchan_rad_index;
-       u32 mask_reg;
-       u32 txok_interrupt_mask;
-       u32 txerr_interrupt_mask;
-       u32 txdesc_interrupt_mask;
-       u32 txeol_interrupt_mask;
-       u32 txurn_interrupt_mask;
-       bool chip_fullsleep;
-       u32 atim_window;
-       u16 antenna_switch_swap;
-       enum ath9k_ant_setting diversity_control;
-
-       /* Calibration */
-       enum hal_cal_types supp_cals;
-       struct hal_cal_list iq_caldata;
-       struct hal_cal_list adcgain_caldata;
-       struct hal_cal_list adcdc_calinitdata;
-       struct hal_cal_list adcdc_caldata;
-       struct hal_cal_list *cal_list;
-       struct hal_cal_list *cal_list_last;
-       struct hal_cal_list *cal_list_curr;
-#define totalPowerMeasI meas0.unsign
-#define totalPowerMeasQ meas1.unsign
-#define totalIqCorrMeas meas2.sign
-#define totalAdcIOddPhase  meas0.unsign
-#define totalAdcIEvenPhase meas1.unsign
-#define totalAdcQOddPhase  meas2.unsign
-#define totalAdcQEvenPhase meas3.unsign
-#define totalAdcDcOffsetIOddPhase  meas0.sign
-#define totalAdcDcOffsetIEvenPhase meas1.sign
-#define totalAdcDcOffsetQOddPhase  meas2.sign
-#define totalAdcDcOffsetQEvenPhase meas3.sign
-       union {
-               u32 unsign[AR5416_MAX_CHAINS];
-               int32_t sign[AR5416_MAX_CHAINS];
-       } meas0;
-       union {
-               u32 unsign[AR5416_MAX_CHAINS];
-               int32_t sign[AR5416_MAX_CHAINS];
-       } meas1;
-       union {
-               u32 unsign[AR5416_MAX_CHAINS];
-               int32_t sign[AR5416_MAX_CHAINS];
-       } meas2;
-       union {
-               u32 unsign[AR5416_MAX_CHAINS];
-               int32_t sign[AR5416_MAX_CHAINS];
-       } meas3;
-       u16 cal_samples;
-
-       u32 sta_id1_defaults;
-       u32 misc_mode;
-       enum {
-               AUTO_32KHZ,
-               USE_32KHZ,
-               DONT_USE_32KHZ,
-       } enable_32kHz_clock;
-
-       /* RF */
-       u32 *analogBank0Data;
-       u32 *analogBank1Data;
-       u32 *analogBank2Data;
-       u32 *analogBank3Data;
-       u32 *analogBank6Data;
-       u32 *analogBank6TPCData;
-       u32 *analogBank7Data;
-       u32 *addac5416_21;
-       u32 *bank6Temp;
-
-       int16_t txpower_indexoffset;
-       u32 beacon_interval;
-       u32 slottime;
-       u32 acktimeout;
-       u32 ctstimeout;
-       u32 globaltxtimeout;
-       u8 gbeacon_rate;
-
-       /* ANI */
-       u32 proc_phyerr;
-       bool has_hw_phycounters;
-       u32 aniperiod;
-       struct ar5416AniState *curani;
-       struct ar5416AniState ani[255];
-       int totalSizeDesired[5];
-       int coarse_high[5];
-       int coarse_low[5];
-       int firpwr[5];
-       enum ath9k_ani_cmd ani_function;
-
-       u32 intr_txqs;
-       enum ath9k_ht_extprotspacing extprotspacing;
-       u8 txchainmask;
-       u8 rxchainmask;
-
-       u32 originalGain[22];
-       int initPDADC;
-       int PDADCdelta;
-
-       struct ar5416IniArray iniModes;
-       struct ar5416IniArray iniCommon;
-       struct ar5416IniArray iniBank0;
-       struct ar5416IniArray iniBB_RfGain;
-       struct ar5416IniArray iniBank1;
-       struct ar5416IniArray iniBank2;
-       struct ar5416IniArray iniBank3;
-       struct ar5416IniArray iniBank6;
-       struct ar5416IniArray iniBank6TPC;
-       struct ar5416IniArray iniBank7;
-       struct ar5416IniArray iniAddac;
-       struct ar5416IniArray iniPcieSerdes;
-       struct ar5416IniArray iniModesAdditional;
-       struct ar5416IniArray iniModesRxGain;
-       struct ar5416IniArray iniModesTxGain;
-};
-
-/* Attach, Detach, Reset */
-const char *ath9k_hw_probe(u16 vendorid, u16 devid);
-void ath9k_hw_detach(struct ath_hw *ah);
-struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
-void ath9k_hw_rfdetach(struct ath_hw *ah);
-int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
-                  bool bChannelChange);
-void ath9k_hw_fill_cap_info(struct ath_hw *ah);
-bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
-                           u32 capability, u32 *result);
-bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
-                           u32 capability, u32 setting, int *status);
-
-/* Key Cache Management */
-bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
-bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac);
-bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
-                                const struct ath9k_keyval *k,
-                                const u8 *mac);
-bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry);
-
-/* GPIO / RFKILL / Antennae */
-void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
-u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
-void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
-                        u32 ah_signal_type);
-void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-void ath9k_enable_rfkill(struct ath_hw *ah);
-#endif
-u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
-void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
-bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
-                              enum ath9k_ant_setting settings,
-                              struct ath9k_channel *chan,
-                              u8 *tx_chainmask, u8 *rx_chainmask,
-                              u8 *antenna_cfgd);
-
-/* General Operation */
-bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
-u32 ath9k_hw_reverse_bits(u32 val, u32 n);
-bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
-u16 ath9k_hw_computetxtime(struct ath_hw *ah, struct ath_rate_table *rates,
-                          u32 frameLen, u16 rateix, bool shortPreamble);
-void ath9k_hw_get_channel_centers(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 struct chan_centers *centers);
-u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
-void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
-bool ath9k_hw_phy_disable(struct ath_hw *ah);
-bool ath9k_hw_disable(struct ath_hw *ah);
-bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
-void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
-void ath9k_hw_setopmode(struct ath_hw *ah);
-void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
-void ath9k_hw_setbssidmask(struct ath_softc *sc);
-void ath9k_hw_write_associd(struct ath_softc *sc);
-u64 ath9k_hw_gettsf64(struct ath_hw *ah);
-void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
-void ath9k_hw_reset_tsf(struct ath_hw *ah);
-bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
-void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
-void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
-void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
-                                   const struct ath9k_beacon_state *bs);
-bool ath9k_hw_setpower(struct ath_hw *ah,
-                      enum ath9k_power_mode mode);
-void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
-
-/* Interrupt Handling */
-bool ath9k_hw_intrpend(struct ath_hw *ah);
-bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
-enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
-
-void ath9k_hw_btcoex_enable(struct ath_hw *ah);
-
-#endif
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h
deleted file mode 100644 (file)
index e2f0a34..0000000
+++ /dev/null
@@ -1,4848 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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.
- */
-
-static const u32 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, 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 u32 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 },
-    { 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 u32 ar5416Bank0[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 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 u32 ar5416Bank1[][2] = {
-    { 0x000098b0, 0x02108421 },
-    { 0x000098ec, 0x00000008 },
-};
-
-static const u32 ar5416Bank2[][2] = {
-    { 0x000098b0, 0x0e73ff17 },
-    { 0x000098e0, 0x00000420 },
-};
-
-static const u32 ar5416Bank3[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 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, 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 u32 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, 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 u32 ar5416Bank7[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static const u32 ar5416Addac[][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 },
-    {0x000098cc,  0x00000000 },
-};
-
-static const u32 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, 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 u32 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 },
-    { 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 u32 ar5416Bank0_9100[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 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 u32 ar5416Bank1_9100[][2] = {
-    { 0x000098b0, 0x02108421},
-    { 0x000098ec, 0x00000008},
-};
-
-static const u32 ar5416Bank2_9100[][2] = {
-    { 0x000098b0, 0x0e73ff17},
-    { 0x000098e0, 0x00000420},
-};
-
-static const u32 ar5416Bank3_9100[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 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, 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 u32 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, 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 u32 ar5416Bank7_9100[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static const u32 ar5416Addac_9100[][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 },
-};
-
-static const u32 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 u32 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 u32 ar5416Bank0_9160[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 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 u32 ar5416Bank1_9160[][2] = {
-    { 0x000098b0, 0x02108421 },
-    { 0x000098ec, 0x00000008 },
-};
-
-static const u32 ar5416Bank2_9160[][2] = {
-    { 0x000098b0, 0x0e73ff17 },
-    { 0x000098e0, 0x00000420 },
-};
-
-static const u32 ar5416Bank3_9160[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 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 u32 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 u32 ar5416Bank7_9160[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static u32 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 u32 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 u32 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 u32 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 u32 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 },
-    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
-    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
-    { 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 },
-    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
-    { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
-};
-
-static const u32 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 },
-    { 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 },
-    { 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 },
-    { 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 },
-    { 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 },
-    { 0x00007824, 0x00040000 },
-    { 0x00007828, 0xdb005012 },
-    { 0x0000782c, 0x04924914 },
-    { 0x00007830, 0x21084210 },
-    { 0x00007834, 0x6d801300 },
-    { 0x0000783c, 0x07e40000 },
-    { 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 u32 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 },
-};
-
-static const u32 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 u32 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 u32 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 u32 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, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 },
-    { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 },
-    { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 },
-    { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 },
-    { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
-    { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 },
-    { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
-    { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
-    { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 },
-    { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
-    { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
-    { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
-    { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 },
-    { 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
-    { 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
-    { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
-    { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
-    { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
-    { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
-    { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
-    { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce },
-};
-
-static const u32 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 },
-    { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
-    { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
-    { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
-    { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
-    { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
-    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
-};
-
-static const u32 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 u32 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 u_int32_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 u_int32_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 u_int32_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 u_int32_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 },
-};
-
-/* AR9285 v1_2 PCI Register Writes.  Created: 03/04/09 */
-static const u_int32_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, 0x03721620, 0x03721620, 0x037216a0 },
-    { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
-    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
-    { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
-    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 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, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
-    { 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, 0x00058084, 0x00058084, 0x00000000 },
-    { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
-    { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
-    { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
-    { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
-    { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
-    { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
-    { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
-    { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
-    { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
-    { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
-    { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
-    { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
-    { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
-    { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
-    { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
-    { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
-    { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
-    { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
-    { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
-    { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
-    { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
-    { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
-    { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
-    { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
-    { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
-    { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
-    { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 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, 0x00078b04, 0x00078b04, 0x00000000 },
-    { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
-    { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
-    { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
-    { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
-    { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
-    { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
-    { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
-    { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
-    { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
-    { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
-    { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
-    { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
-    { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
-    { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
-    { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
-    { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
-    { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
-    { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
-    { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
-    { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
-    { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
-    { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
-    { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
-    { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
-    { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
-    { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
-    { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
-    { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
-    { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
-    { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
-    { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
-    { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
-    { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
-    { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
-    { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
-    { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
-    { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
-    { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
-    { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
-    { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
-    { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
-    { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
-    { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
-    { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
-    { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
-    { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
-    { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
-    { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
-    { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
-    { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
-    { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
-    { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
-    { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
-    { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
-    { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
-    { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
-    { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
-    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
-    { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
-    { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
-    { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
-    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
-    { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
-    { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
-    { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
-    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
-    { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
-    { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
-    { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
-    { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
-    { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
-    { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
-    { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
-    { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
-    { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
-    { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
-    { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
-    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
-    { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
-    { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
-    { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
-    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
-    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
-    { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
-    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
-    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
-    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
-    { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
-    { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
-    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
-    { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
-    { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
-    { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
-    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
-    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
-    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
-    { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
-    { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
-    { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
-    { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
-    { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
-    { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
-    { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
-    { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
-    { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
-    { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
-    { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
-    { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
-    { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
-    { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
-    { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
-    { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
-    { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
-    { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
-    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
-    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
-    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
-    { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
-    { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
-    { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
-    { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
-    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
-    { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
-    { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
-    { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
-    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
-    { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
-    { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
-    { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
-    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
-    { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
-    { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
-    { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
-    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
-    { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
-    { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
-    { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
-    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
-    { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
-    { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
-    { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
-    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
-    { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
-    { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
-    { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
-    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
-};
-
-static const u_int32_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, 0x08f04810 },
-    { 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, 0x0000320a },
-    { 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, 0x2def0400 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099b4, 0x00000820 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000000 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099f0, 0x00000000 },
-    { 0x0000a208, 0x803e68c8 },
-    { 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 },
-    { 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 },
-    { 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 },
-    { 0x0000a3e4, 0x00000000 },
-    { 0x0000a3e8, 0x18c43433 },
-    { 0x0000a3ec, 0x00f70081 },
-    { 0x00007800, 0x00140000 },
-    { 0x00007804, 0x0e4548d8 },
-    { 0x00007808, 0x54214514 },
-    { 0x0000780c, 0x02025820 },
-    { 0x00007810, 0x71c0d388 },
-    { 0x00007814, 0x924934a8 },
-    { 0x0000781c, 0x00000000 },
-    { 0x00007824, 0x00d86fff },
-    { 0x00007828, 0x26d2491b },
-    { 0x0000782c, 0x6e36d97b },
-    { 0x00007830, 0xedb6d96e },
-    { 0x00007834, 0x71400087 },
-    { 0x0000783c, 0x0001fffe },
-    { 0x00007840, 0xffeb1a20 },
-    { 0x00007844, 0x000c0db6 },
-    { 0x00007848, 0x6db61b6f },
-    { 0x0000784c, 0x6d9b66db },
-    { 0x00007850, 0x6d8c6dba },
-    { 0x00007854, 0x00040000 },
-    { 0x00007858, 0xdb003012 },
-    { 0x0000785c, 0x04924914 },
-    { 0x00007860, 0x21084210 },
-    { 0x00007864, 0xf7d7ffde },
-    { 0x00007868, 0xc2034080 },
-    { 0x00007870, 0x10142c00 },
-};
-
-static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
-    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
-    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 },
-    { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
-    { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
-    { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
-    { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 },
-    { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 },
-    { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 },
-    { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 },
-    { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 },
-    { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
-    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
-    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
-    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
-    { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
-    { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
-    { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
-    { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
-    { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
-    { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
-};
-
-static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
-    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
-    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
-    { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
-    { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
-    { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
-    { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
-    { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
-    { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
-    { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
-    { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
-    { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
-    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
-    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
-    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
-    { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
-    { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
-    { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
-    { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
-    { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
-    { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
-    { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
-    { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
-    { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
-};
-
-static const u_int32_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 u_int32_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 },
-};
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c
deleted file mode 100644 (file)
index 8ae4ec2..0000000
+++ /dev/null
@@ -1,976 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
-                                       struct ath9k_tx_queue_info *qi)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-               "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
-               ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
-               ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
-               ah->txurn_interrupt_mask);
-
-       REG_WRITE(ah, AR_IMR_S0,
-                 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
-                 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
-       REG_WRITE(ah, AR_IMR_S1,
-                 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
-                 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
-       REG_RMW_FIELD(ah, AR_IMR_S2,
-                     AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask);
-}
-
-u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
-{
-       return REG_READ(ah, AR_QTXDP(q));
-}
-
-bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
-{
-       REG_WRITE(ah, AR_QTXDP(q), txdp);
-
-       return true;
-}
-
-bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q);
-
-       REG_WRITE(ah, AR_Q_TXE, 1 << q);
-
-       return true;
-}
-
-u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
-{
-       u32 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;
-}
-
-bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
-{
-       u32 txcfg, curLevel, newLevel;
-       enum ath9k_int omask;
-
-       if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
-               return false;
-
-       omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~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));
-
-       ath9k_hw_set_interrupts(ah, omask);
-
-       ah->tx_trig_level = newLevel;
-
-       return newLevel != curLevel;
-}
-
-bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
-{
-#define ATH9K_TX_STOP_DMA_TIMEOUT      4000    /* usec */
-#define ATH9K_TIME_QUANTUM             100     /* usec */
-
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_tx_queue_info *qi;
-       u32 tsfLow, j, wait;
-       u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
-                       "invalid queue: %u\n", q);
-               return false;
-       }
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
-                       "inactive queue: %u\n", q);
-               return false;
-       }
-
-       REG_WRITE(ah, AR_Q_TXD, 1 << q);
-
-       for (wait = wait_time; wait != 0; wait--) {
-               if (ath9k_hw_numtxpending(ah, q) == 0)
-                       break;
-               udelay(ATH9K_TIME_QUANTUM);
-       }
-
-       if (ath9k_hw_numtxpending(ah, q)) {
-               DPRINTF(ah->ah_sc, ATH_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;
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                               "TSF has moved while trying to set "
-                               "quiet time TSF: 0x%08x\n", tsfLow);
-               }
-
-               REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
-
-               udelay(200);
-               REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
-
-               wait = wait_time;
-               while (ath9k_hw_numtxpending(ah, q)) {
-                       if ((--wait) == 0) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                                       "Failed to stop TX DMA in 100 "
-                                       "msec after killing last frame\n");
-                               break;
-                       }
-                       udelay(ATH9K_TIME_QUANTUM);
-               }
-
-               REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
-       }
-
-       REG_WRITE(ah, AR_Q_TXD, 0);
-       return wait != 0;
-
-#undef ATH9K_TX_STOP_DMA_TIMEOUT
-#undef ATH9K_TIME_QUANTUM
-}
-
-bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                        u32 segLen, bool firstSeg,
-                        bool 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 true;
-}
-
-void ath9k_hw_cleartxdesc(struct ath_hw *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_hw *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)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
-       if (ads->ds_txstatus1 & AR_Filtered)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
-       if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus9 & AR_TxOpExceeded)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
-       if (ads->ds_txstatus1 & AR_TxTimerExpired)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
-
-       if (ads->ds_txstatus1 & AR_DescCfgErr)
-               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;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
-               ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
-               ath9k_hw_updatetxtriglevel(ah, 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 = 0;
-
-       return 0;
-}
-
-void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
-                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-                           u32 keyIx, enum ath9k_key_type keyType, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       txPower += ah->txpower_indexoffset;
-       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;
-       }
-}
-
-void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
-                                 struct ath_desc *lastds,
-                                 u32 durUpdateEn, u32 rtsctsRate,
-                                 u32 rtsctsDuration,
-                                 struct ath9k_11n_rate_series series[],
-                                 u32 nseries, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       struct ar5416_desc *last_ads = AR5416DESC(lastds);
-       u32 ds_ctl0;
-
-       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;
-}
-
-void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
-                               u32 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);
-}
-
-void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
-                                u32 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;
-}
-
-void ath9k_hw_set11n_aggr_last(struct ath_hw *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;
-}
-
-void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
-}
-
-void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
-                                  u32 burstDuration)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl2 &= ~AR_BurstDur;
-       ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
-}
-
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
-                                    u32 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_hw *ah, u32 *txqs)
-{
-       *txqs &= ah->intr_txqs;
-       ah->intr_txqs &= ~(*txqs);
-}
-
-bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
-                           const struct ath9k_tx_queue_info *qinfo)
-{
-       u32 cw;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_tx_queue_info *qi;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
-                       "invalid queue: %u\n", q);
-               return false;
-       }
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
-                       "inactive queue: %u\n", q);
-               return false;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
-
-       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((u32) qinfo->tqi_shretry, 15U);
-       else
-               qi->tqi_shretry = INIT_SH_RETRY;
-       if (qinfo->tqi_lgretry != 0)
-               qi->tqi_lgretry = min((u32) 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 true;
-}
-
-bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
-                           struct ath9k_tx_queue_info *qinfo)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_tx_queue_info *qi;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
-                       "invalid queue: %u\n", q);
-               return false;
-       }
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
-                       "inactive queue: %u\n", q);
-               return 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 true;
-}
-
-int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
-                         const struct ath9k_tx_queue_info *qinfo)
-{
-       struct ath9k_tx_queue_info *qi;
-       struct ath9k_hw_capabilities *pCap = &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 (ah->txq[q].tqi_type ==
-                           ATH9K_TX_QUEUE_INACTIVE)
-                               break;
-               if (q == pCap->total_queues) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "No available TX queue\n");
-                       return -1;
-               }
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid TX queue type: %u\n",
-                       type);
-               return -1;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "TX queue: %u already active\n", q);
-               return -1;
-       }
-       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;
-}
-
-bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_tx_queue_info *qi;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
-                       "invalid queue: %u\n", q);
-               return false;
-       }
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
-                       "inactive queue: %u\n", q);
-               return false;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
-
-       qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
-       ah->txok_interrupt_mask &= ~(1 << q);
-       ah->txerr_interrupt_mask &= ~(1 << q);
-       ah->txdesc_interrupt_mask &= ~(1 << q);
-       ah->txeol_interrupt_mask &= ~(1 << q);
-       ah->txurn_interrupt_mask &= ~(1 << q);
-       ath9k_hw_set_txq_interrupts(ah, qi);
-
-       return true;
-}
-
-bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_channel *chan = ah->curchan;
-       struct ath9k_tx_queue_info *qi;
-       u32 cwMin, chanCwMin, value;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
-                       "invalid queue: %u\n", q);
-               return false;
-       }
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
-                       "inactive queue: %u\n", q);
-               return true;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TX queue: %u\n", 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);
-       } 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->config.sw_beacon_response_time -
-                         ah->config.dma_beacon_response_time) -
-                        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)
-               ah->txok_interrupt_mask |= 1 << q;
-       else
-               ah->txok_interrupt_mask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
-               ah->txerr_interrupt_mask |= 1 << q;
-       else
-               ah->txerr_interrupt_mask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
-               ah->txdesc_interrupt_mask |= 1 << q;
-       else
-               ah->txdesc_interrupt_mask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
-               ah->txeol_interrupt_mask |= 1 << q;
-       else
-               ah->txeol_interrupt_mask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
-               ah->txurn_interrupt_mask |= 1 << q;
-       else
-               ah->txurn_interrupt_mask &= ~(1 << q);
-       ath9k_hw_set_txq_interrupts(ah, qi);
-
-       return true;
-}
-
-int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
-                       u32 pa, struct ath_desc *nds, u64 tsf)
-{
-       struct ar5416_desc ads;
-       struct ar5416_desc *adsp = AR5416DESC(ds);
-       u32 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 = phyerr;
-               } 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;
-}
-
-bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                         u32 size, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       struct ath9k_hw_capabilities *pCap = &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))
-               memset(&(ads->u), 0, sizeof(ads->u));
-
-       return true;
-}
-
-bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
-{
-       u32 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, AH_WAIT_TIMEOUT)) {
-                       REG_CLR_BIT(ah, AR_DIAG_SW,
-                                   (AR_DIAG_RX_DIS |
-                                    AR_DIAG_RX_ABORT));
-
-                       reg = REG_READ(ah, AR_OBS_BUS_1);
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "RX failed to go idle in 10 ms RXSM=0x%x\n", reg);
-
-                       return false;
-               }
-       } else {
-               REG_CLR_BIT(ah, AR_DIAG_SW,
-                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-       }
-
-       return true;
-}
-
-void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
-{
-       REG_WRITE(ah, AR_RXDP, rxdp);
-}
-
-void ath9k_hw_rxena(struct ath_hw *ah)
-{
-       REG_WRITE(ah, AR_CR, AR_CR_RXE);
-}
-
-void ath9k_hw_startpcureceive(struct ath_hw *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_hw *ah)
-{
-       REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
-
-       ath9k_hw_disable_mib_counters(ah);
-}
-
-bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
-{
-#define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
-#define AH_RX_TIME_QUANTUM     100     /* usec */
-
-       int i;
-
-       REG_WRITE(ah, AR_CR, AR_CR_RXD);
-
-       /* Wait for rx enable bit to go low */
-       for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
-               if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
-                       break;
-               udelay(AH_TIME_QUANTUM);
-       }
-
-       if (i == 0) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "DMA failed to stop in %d ms "
-                       "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
-                       AH_RX_STOP_DMA_TIMEOUT / 1000,
-                       REG_READ(ah, AR_CR),
-                       REG_READ(ah, AR_DIAG_SW));
-               return false;
-       } else {
-               return true;
-       }
-
-#undef AH_RX_TIME_QUANTUM
-#undef AH_RX_STOP_DMA_TIMEOUT
-}
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath9k/mac.h
deleted file mode 100644 (file)
index 1176bce..0000000
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 MAC_H
-#define MAC_H
-
-#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_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 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
-
-#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 ATH9K_SLOT_TIME_6 6
-#define ATH9K_SLOT_TIME_9 9
-#define ATH9K_SLOT_TIME_20 20
-
-#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
-
-#define MIN_TX_FIFO_THRESHOLD   0x1
-#define MAX_TX_FIFO_THRESHOLD   ((4096 / 64) - 1)
-#define INIT_TX_FIFO_THRESHOLD  MIN_TX_FIFO_THRESHOLD
-
-struct ath_tx_status {
-       u32 ts_tstamp;
-       u16 ts_seqnum;
-       u8 ts_status;
-       u8 ts_ratecode;
-       u8 ts_rateindex;
-       int8_t ts_rssi;
-       u8 ts_shortretry;
-       u8 ts_longretry;
-       u8 ts_virtcol;
-       u8 ts_antenna;
-       u8 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;
-       u8 pad[3];
-       u32 ba_low;
-       u32 ba_high;
-       u32 evm0;
-       u32 evm1;
-       u32 evm2;
-};
-
-struct ath_rx_status {
-       u32 rs_tstamp;
-       u16 rs_datalen;
-       u8 rs_status;
-       u8 rs_phyerr;
-       int8_t rs_rssi;
-       u8 rs_keyix;
-       u8 rs_rate;
-       u8 rs_antenna;
-       u8 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;
-       u8 rs_isaggr;
-       u8 rs_moreaggr;
-       u8 rs_num_delims;
-       u8 rs_flags;
-       u32 evm0;
-       u32 evm1;
-       u32 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  ((u8)-1)
-#define ATH9K_TXKEYIX_INVALID  ((u32)-1)
-
-struct ath_desc {
-       u32 ds_link;
-       u32 ds_data;
-       u32 ds_ctl0;
-       u32 ds_ctl1;
-       u32 ds_hw[20];
-       union {
-               struct ath_tx_status tx;
-               struct ath_rx_status rx;
-               void *stats;
-       } ds_us;
-       void *ds_vdata;
-} __packed;
-
-#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
-
-struct ar5416_desc {
-       u32 ds_link;
-       u32 ds_data;
-       u32 ds_ctl0;
-       u32 ds_ctl1;
-       union {
-               struct {
-                       u32 ctl2;
-                       u32 ctl3;
-                       u32 ctl4;
-                       u32 ctl5;
-                       u32 ctl6;
-                       u32 ctl7;
-                       u32 ctl8;
-                       u32 ctl9;
-                       u32 ctl10;
-                       u32 ctl11;
-                       u32 status0;
-                       u32 status1;
-                       u32 status2;
-                       u32 status3;
-                       u32 status4;
-                       u32 status5;
-                       u32 status6;
-                       u32 status7;
-                       u32 status8;
-                       u32 status9;
-               } tx;
-               struct {
-                       u32 status0;
-                       u32 status1;
-                       u32 status2;
-                       u32 status3;
-                       u32 status4;
-                       u32 status5;
-                       u32 status6;
-                       u32 status7;
-                       u32 status8;
-               } rx;
-       } u;
-} __packed;
-
-#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
-
-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 ((u32) -1)
-#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
-
-#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 {
-       u32 tqi_ver;
-       enum ath9k_tx_queue tqi_type;
-       enum ath9k_tx_queue_subtype tqi_subtype;
-       enum ath9k_tx_queue_flags tqi_qflags;
-       u32 tqi_priority;
-       u32 tqi_aifs;
-       u32 tqi_cwmin;
-       u32 tqi_cwmax;
-       u16 tqi_shretry;
-       u16 tqi_lgretry;
-       u32 tqi_cbrPeriod;
-       u32 tqi_cbrOverflowLimit;
-       u32 tqi_burstTime;
-       u32 tqi_readyTime;
-       u32 tqi_physCompBuf;
-       u32 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_PHYERR = 0x00000100,
-       ATH9K_RX_FILTER_MYBEACON = 0x00000200,
-       ATH9K_RX_FILTER_PSPOLL = 0x00004000,
-       ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
-       ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
-};
-
-#define ATH9K_RATESERIES_RTS_CTS  0x0001
-#define ATH9K_RATESERIES_2040     0x0002
-#define ATH9K_RATESERIES_HALFGI   0x0004
-
-struct ath9k_11n_rate_series {
-       u32 Tries;
-       u32 Rate;
-       u32 PktDuration;
-       u32 ChSel;
-       u32 RateFlags;
-};
-
-struct ath9k_keyval {
-       u8 kv_type;
-       u8 kv_pad;
-       u16 kv_len;
-       u8 kv_val[16]; /* TK */
-       u8 kv_mic[8]; /* Michael MIC key */
-       u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
-                        * supports both MIC keys in the same key cache entry;
-                        * in that case, kv_mic is the RX key) */
-};
-
-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
-};
-
-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 ath_hw;
-struct ath9k_channel;
-struct ath_rate_table;
-
-u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
-bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
-bool ath9k_hw_txstart(struct ath_hw *ah, u32 q);
-u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
-bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
-bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
-bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                        u32 segLen, bool firstSeg,
-                        bool lastSeg, const struct ath_desc *ds0);
-void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
-int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
-                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-                           u32 keyIx, enum ath9k_key_type keyType, u32 flags);
-void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
-                                 struct ath_desc *lastds,
-                                 u32 durUpdateEn, u32 rtsctsRate,
-                                 u32 rtsctsDuration,
-                                 struct ath9k_11n_rate_series series[],
-                                 u32 nseries, u32 flags);
-void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
-                               u32 aggrLen);
-void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
-                                u32 numDelims);
-void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
-                                  u32 burstDuration);
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
-                                    u32 vmf);
-void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
-bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
-                           const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
-                           struct ath9k_tx_queue_info *qinfo);
-int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
-                         const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
-bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
-int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
-                       u32 pa, struct ath_desc *nds, u64 tsf);
-bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                         u32 size, u32 flags);
-bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
-void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
-void ath9k_hw_rxena(struct ath_hw *ah);
-void ath9k_hw_startpcureceive(struct ath_hw *ah);
-void ath9k_hw_stoppcurecv(struct ath_hw *ah);
-bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
-
-#endif /* MAC_H */
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
deleted file mode 100644 (file)
index 8b6a7ea..0000000
+++ /dev/null
@@ -1,2890 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 <linux/nl80211.h>
-#include "ath9k.h"
-
-#define ATH_PCI_VERSION "0.1"
-
-static char *dev_info = "ath9k";
-
-MODULE_AUTHOR("Atheros Communications");
-MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
-MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
-MODULE_LICENSE("Dual BSD/GPL");
-
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
-
-/* We use the hw_value as an index into our private channel structure */
-
-#define CHAN2G(_freq, _idx)  { \
-       .center_freq = (_freq), \
-       .hw_value = (_idx), \
-       .max_power = 30, \
-}
-
-#define CHAN5G(_freq, _idx) { \
-       .band = IEEE80211_BAND_5GHZ, \
-       .center_freq = (_freq), \
-       .hw_value = (_idx), \
-       .max_power = 30, \
-}
-
-/* Some 2 GHz radios are actually tunable on 2312-2732
- * on 5 MHz steps, we support the channels which we know
- * we have calibration data for all cards though to make
- * this static */
-static struct ieee80211_channel ath9k_2ghz_chantable[] = {
-       CHAN2G(2412, 0), /* Channel 1 */
-       CHAN2G(2417, 1), /* Channel 2 */
-       CHAN2G(2422, 2), /* Channel 3 */
-       CHAN2G(2427, 3), /* Channel 4 */
-       CHAN2G(2432, 4), /* Channel 5 */
-       CHAN2G(2437, 5), /* Channel 6 */
-       CHAN2G(2442, 6), /* Channel 7 */
-       CHAN2G(2447, 7), /* Channel 8 */
-       CHAN2G(2452, 8), /* Channel 9 */
-       CHAN2G(2457, 9), /* Channel 10 */
-       CHAN2G(2462, 10), /* Channel 11 */
-       CHAN2G(2467, 11), /* Channel 12 */
-       CHAN2G(2472, 12), /* Channel 13 */
-       CHAN2G(2484, 13), /* Channel 14 */
-};
-
-/* Some 5 GHz radios are actually tunable on XXXX-YYYY
- * on 5 MHz steps, we support the channels which we know
- * we have calibration data for all cards though to make
- * this static */
-static struct ieee80211_channel ath9k_5ghz_chantable[] = {
-       /* _We_ call this UNII 1 */
-       CHAN5G(5180, 14), /* Channel 36 */
-       CHAN5G(5200, 15), /* Channel 40 */
-       CHAN5G(5220, 16), /* Channel 44 */
-       CHAN5G(5240, 17), /* Channel 48 */
-       /* _We_ call this UNII 2 */
-       CHAN5G(5260, 18), /* Channel 52 */
-       CHAN5G(5280, 19), /* Channel 56 */
-       CHAN5G(5300, 20), /* Channel 60 */
-       CHAN5G(5320, 21), /* Channel 64 */
-       /* _We_ call this "Middle band" */
-       CHAN5G(5500, 22), /* Channel 100 */
-       CHAN5G(5520, 23), /* Channel 104 */
-       CHAN5G(5540, 24), /* Channel 108 */
-       CHAN5G(5560, 25), /* Channel 112 */
-       CHAN5G(5580, 26), /* Channel 116 */
-       CHAN5G(5600, 27), /* Channel 120 */
-       CHAN5G(5620, 28), /* Channel 124 */
-       CHAN5G(5640, 29), /* Channel 128 */
-       CHAN5G(5660, 30), /* Channel 132 */
-       CHAN5G(5680, 31), /* Channel 136 */
-       CHAN5G(5700, 32), /* Channel 140 */
-       /* _We_ call this UNII 3 */
-       CHAN5G(5745, 33), /* Channel 149 */
-       CHAN5G(5765, 34), /* Channel 153 */
-       CHAN5G(5785, 35), /* Channel 157 */
-       CHAN5G(5805, 36), /* Channel 161 */
-       CHAN5G(5825, 37), /* Channel 165 */
-};
-
-static void ath_cache_conf_rate(struct ath_softc *sc,
-                               struct ieee80211_conf *conf)
-{
-       switch (conf->channel->band) {
-       case IEEE80211_BAND_2GHZ:
-               if (conf_is_ht20(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
-               else if (conf_is_ht40_minus(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
-               else if (conf_is_ht40_plus(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
-               else
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11G];
-               break;
-       case IEEE80211_BAND_5GHZ:
-               if (conf_is_ht20(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
-               else if (conf_is_ht40_minus(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
-               else if (conf_is_ht40_plus(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
-               else
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11A];
-               break;
-       default:
-               BUG_ON(1);
-               break;
-       }
-}
-
-static void ath_update_txpow(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       u32 txpow;
-
-       if (sc->curtxpow != sc->config.txpowlimit) {
-               ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
-               /* read back in case value is clamped */
-               ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
-               sc->curtxpow = txpow;
-       }
-}
-
-static u8 parse_mpdudensity(u8 mpdudensity)
-{
-       /*
-        * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
-        *   0 for no restriction
-        *   1 for 1/4 us
-        *   2 for 1/2 us
-        *   3 for 1 us
-        *   4 for 2 us
-        *   5 for 4 us
-        *   6 for 8 us
-        *   7 for 16 us
-        */
-       switch (mpdudensity) {
-       case 0:
-               return 0;
-       case 1:
-       case 2:
-       case 3:
-               /* Our lower layer calculations limit our precision to
-                  1 microsecond */
-               return 1;
-       case 4:
-               return 2;
-       case 5:
-               return 4;
-       case 6:
-               return 8;
-       case 7:
-               return 16;
-       default:
-               return 0;
-       }
-}
-
-static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
-{
-       struct ath_rate_table *rate_table = NULL;
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_rate *rate;
-       int i, maxrates;
-
-       switch (band) {
-       case IEEE80211_BAND_2GHZ:
-               rate_table = sc->hw_rate_table[ATH9K_MODE_11G];
-               break;
-       case IEEE80211_BAND_5GHZ:
-               rate_table = sc->hw_rate_table[ATH9K_MODE_11A];
-               break;
-       default:
-               break;
-       }
-
-       if (rate_table == NULL)
-               return;
-
-       sband = &sc->sbands[band];
-       rate = sc->rates[band];
-
-       if (rate_table->rate_cnt > ATH_RATE_MAX)
-               maxrates = ATH_RATE_MAX;
-       else
-               maxrates = rate_table->rate_cnt;
-
-       for (i = 0; i < maxrates; i++) {
-               rate[i].bitrate = rate_table->info[i].ratekbps / 100;
-               rate[i].hw_value = rate_table->info[i].ratecode;
-               if (rate_table->info[i].short_preamble) {
-                       rate[i].hw_value_short = rate_table->info[i].ratecode |
-                               rate_table->info[i].short_preamble;
-                       rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE;
-               }
-               sband->n_bitrates++;
-
-               DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n",
-                       rate[i].bitrate / 10, rate[i].hw_value);
-       }
-}
-
-/*
- * 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.
-*/
-int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
-                   struct ath9k_channel *hchan)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       bool fastcc = true, stopped;
-       struct ieee80211_channel *channel = hw->conf.channel;
-       int r;
-
-       if (sc->sc_flags & SC_OP_INVALID)
-               return -EIO;
-
-       ath9k_ps_wakeup(sc);
-
-       /*
-        * 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.
-        */
-       ath9k_hw_set_interrupts(ah, 0);
-       ath_drain_all_txq(sc, false);
-       stopped = ath_stoprecv(sc);
-
-       /* 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 = false;
-
-       DPRINTF(sc, ATH_DBG_CONFIG,
-               "(%u MHz) -> (%u MHz), chanwidth: %d\n",
-               sc->sc_ah->curchan->channel,
-               channel->center_freq, sc->tx_chan_width);
-
-       spin_lock_bh(&sc->sc_resetlock);
-
-       r = ath9k_hw_reset(ah, hchan, fastcc);
-       if (r) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset channel (%u Mhz) "
-                       "reset status %u\n",
-                       channel->center_freq, r);
-               spin_unlock_bh(&sc->sc_resetlock);
-               return r;
-       }
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       sc->sc_flags &= ~SC_OP_FULL_RESET;
-
-       if (ath_startrecv(sc) != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to restart recv logic\n");
-               return -EIO;
-       }
-
-       ath_cache_conf_rate(sc, &hw->conf);
-       ath_update_txpow(sc);
-       ath9k_hw_set_interrupts(ah, sc->imask);
-       ath9k_ps_restore(sc);
-       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 ath_ani_calibrate(unsigned long data)
-{
-       struct ath_softc *sc = (struct ath_softc *)data;
-       struct ath_hw *ah = sc->sc_ah;
-       bool longcal = false;
-       bool shortcal = false;
-       bool aniflag = false;
-       unsigned int timestamp = jiffies_to_msecs(jiffies);
-       u32 cal_interval, short_cal_interval;
-
-       short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
-               ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
-
-       /*
-       * don't calibrate when we're scanning.
-       * we are most likely not on our home channel.
-       */
-       if (sc->sc_flags & SC_OP_SCANNING)
-               goto set_timer;
-
-       /* Long calibration runs independently of short calibration. */
-       if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
-               longcal = true;
-               DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
-               sc->ani.longcal_timer = timestamp;
-       }
-
-       /* Short calibration applies only while caldone is false */
-       if (!sc->ani.caldone) {
-               if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) {
-                       shortcal = true;
-                       DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies);
-                       sc->ani.shortcal_timer = timestamp;
-                       sc->ani.resetcal_timer = timestamp;
-               }
-       } else {
-               if ((timestamp - sc->ani.resetcal_timer) >=
-                   ATH_RESTART_CALINTERVAL) {
-                       sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
-                       if (sc->ani.caldone)
-                               sc->ani.resetcal_timer = timestamp;
-               }
-       }
-
-       /* Verify whether we must check ANI */
-       if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
-               aniflag = true;
-               sc->ani.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->nodestats, ah->curchan);
-
-               /* Perform calibration if necessary */
-               if (longcal || shortcal) {
-                       bool iscaldone = false;
-
-                       if (ath9k_hw_calibrate(ah, ah->curchan,
-                                              sc->rx_chainmask, longcal,
-                                              &iscaldone)) {
-                               if (longcal)
-                                       sc->ani.noise_floor =
-                                               ath9k_hw_getchan_noise(ah,
-                                                              ah->curchan);
-
-                               DPRINTF(sc, ATH_DBG_ANI,
-                                       "calibrate chan %u/%x nf: %d\n",
-                                       ah->curchan->channel,
-                                       ah->curchan->channelFlags,
-                                       sc->ani.noise_floor);
-                       } else {
-                               DPRINTF(sc, ATH_DBG_ANY,
-                                       "calibrate chan %u/%x failed\n",
-                                       ah->curchan->channel,
-                                       ah->curchan->channelFlags);
-                       }
-                       sc->ani.caldone = iscaldone;
-               }
-       }
-
-set_timer:
-       /*
-       * 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->config.enable_ani)
-               cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
-       if (!sc->ani.caldone)
-               cal_interval = min(cal_interval, (u32)short_cal_interval);
-
-       mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
-}
-
-/*
- * Update tx/rx chainmask. For legacy association,
- * hard code chainmask to 1x1, for 11n association, use
- * the chainmask configuration, for bt coexistence, use
- * the chainmask configuration even in legacy mode.
- */
-void ath_update_chainmask(struct ath_softc *sc, int is_ht)
-{
-       if (is_ht ||
-           (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
-               sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
-               sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
-       } else {
-               sc->tx_chainmask = 1;
-               sc->rx_chainmask = 1;
-       }
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
-               sc->tx_chainmask, sc->rx_chainmask);
-}
-
-static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
-{
-       struct ath_node *an;
-
-       an = (struct ath_node *)sta->drv_priv;
-
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               ath_tx_node_init(sc, an);
-               an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
-                                    sta->ht_cap.ampdu_factor);
-               an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
-       }
-}
-
-static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
-{
-       struct ath_node *an = (struct ath_node *)sta->drv_priv;
-
-       if (sc->sc_flags & SC_OP_TXAGGR)
-               ath_tx_node_cleanup(sc, an);
-}
-
-static void ath9k_tasklet(unsigned long data)
-{
-       struct ath_softc *sc = (struct ath_softc *)data;
-       u32 status = sc->intrstatus;
-
-       if (status & ATH9K_INT_FATAL) {
-               ath_reset(sc, false);
-               return;
-       }
-
-       if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
-               spin_lock_bh(&sc->rx.rxflushlock);
-               ath_rx_tasklet(sc, 0);
-               spin_unlock_bh(&sc->rx.rxflushlock);
-       }
-
-       if (status & ATH9K_INT_TX)
-               ath_tx_tasklet(sc);
-
-       /* re-enable hardware interrupt */
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-}
-
-irqreturn_t ath_isr(int irq, void *dev)
-{
-#define SCHED_INTR (                           \
-               ATH9K_INT_FATAL |               \
-               ATH9K_INT_RXORN |               \
-               ATH9K_INT_RXEOL |               \
-               ATH9K_INT_RX |                  \
-               ATH9K_INT_TX |                  \
-               ATH9K_INT_BMISS |               \
-               ATH9K_INT_CST |                 \
-               ATH9K_INT_TSFOOR)
-
-       struct ath_softc *sc = dev;
-       struct ath_hw *ah = sc->sc_ah;
-       enum ath9k_int status;
-       bool sched = false;
-
-       /*
-        * The hardware is not ready/present, don't
-        * touch anything. Note this can happen early
-        * on if the IRQ is shared.
-        */
-       if (sc->sc_flags & SC_OP_INVALID)
-               return IRQ_NONE;
-
-       ath9k_ps_wakeup(sc);
-
-       /* shared irq, not for us */
-
-       if (!ath9k_hw_intrpend(ah)) {
-               ath9k_ps_restore(sc);
-               return IRQ_NONE;
-       }
-
-       /*
-        * 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.
-        */
-       ath9k_hw_getisr(ah, &status);   /* NB: clears ISR too */
-       status &= 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) {
-               ath9k_ps_restore(sc);
-               return IRQ_NONE;
-       }
-
-       /* Cache the status */
-       sc->intrstatus = status;
-
-       if (status & SCHED_INTR)
-               sched = true;
-
-       /*
-        * If a FATAL or RXORN interrupt is received, we have to reset the
-        * chip immediately.
-        */
-       if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN))
-               goto chip_reset;
-
-       if (status & ATH9K_INT_SWBA)
-               tasklet_schedule(&sc->bcon_tasklet);
-
-       if (status & ATH9K_INT_TXURN)
-               ath9k_hw_updatetxtriglevel(ah, true);
-
-       if (status & ATH9K_INT_MIB) {
-               /*
-                * Disable interrupts until we service the MIB
-                * interrupt; otherwise it will continue to
-                * fire.
-                */
-               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->nodestats);
-               ath9k_hw_set_interrupts(ah, sc->imask);
-       }
-
-       if (status & ATH9K_INT_TIM_TIMER) {
-               if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-                       /* Clear RxAbort bit so that we can
-                        * receive frames */
-                       ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
-                       ath9k_hw_setrxabort(ah, 0);
-                       sched = true;
-                       sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
-               }
-       }
-
-chip_reset:
-
-       ath9k_ps_restore(sc);
-       ath_debug_stat_interrupt(sc, status);
-
-       if (sched) {
-               /* turn off every interrupt except SWBA */
-               ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA));
-               tasklet_schedule(&sc->intr_tq);
-       }
-
-       return IRQ_HANDLED;
-
-#undef SCHED_INTR
-}
-
-static u32 ath_get_extchanmode(struct ath_softc *sc,
-                              struct ieee80211_channel *chan,
-                              enum nl80211_channel_type channel_type)
-{
-       u32 chanmode = 0;
-
-       switch (chan->band) {
-       case IEEE80211_BAND_2GHZ:
-               switch(channel_type) {
-               case NL80211_CHAN_NO_HT:
-               case NL80211_CHAN_HT20:
-                       chanmode = CHANNEL_G_HT20;
-                       break;
-               case NL80211_CHAN_HT40PLUS:
-                       chanmode = CHANNEL_G_HT40PLUS;
-                       break;
-               case NL80211_CHAN_HT40MINUS:
-                       chanmode = CHANNEL_G_HT40MINUS;
-                       break;
-               }
-               break;
-       case IEEE80211_BAND_5GHZ:
-               switch(channel_type) {
-               case NL80211_CHAN_NO_HT:
-               case NL80211_CHAN_HT20:
-                       chanmode = CHANNEL_A_HT20;
-                       break;
-               case NL80211_CHAN_HT40PLUS:
-                       chanmode = CHANNEL_A_HT40PLUS;
-                       break;
-               case NL80211_CHAN_HT40MINUS:
-                       chanmode = CHANNEL_A_HT40MINUS;
-                       break;
-               }
-               break;
-       default:
-               break;
-       }
-
-       return chanmode;
-}
-
-static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
-                          struct ath9k_keyval *hk, const u8 *addr,
-                          bool authenticator)
-{
-       const u8 *key_rxmic;
-       const u8 *key_txmic;
-
-       key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
-       key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
-
-       if (addr == NULL) {
-               /*
-                * Group key installation - only two key cache entries are used
-                * regardless of splitmic capability since group key is only
-                * used either for TX or RX.
-                */
-               if (authenticator) {
-                       memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
-                       memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
-               } else {
-                       memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
-                       memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
-               }
-               return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
-       }
-       if (!sc->splitmic) {
-               /* TX and RX keys share the same key cache entry. */
-               memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
-               memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
-               return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
-       }
-
-       /* Separate key cache entries for TX and RX */
-
-       /* TX key goes at first index, RX key at +32. */
-       memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
-       if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
-               /* TX MIC entry failed. No need to proceed further */
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Setting TX MIC Key Failed\n");
-               return 0;
-       }
-
-       memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
-       /* XXX delete tx key on failure? */
-       return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr);
-}
-
-static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
-{
-       int i;
-
-       for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
-               if (test_bit(i, sc->keymap) ||
-                   test_bit(i + 64, sc->keymap))
-                       continue; /* At least one part of TKIP key allocated */
-               if (sc->splitmic &&
-                   (test_bit(i + 32, sc->keymap) ||
-                    test_bit(i + 64 + 32, sc->keymap)))
-                       continue; /* At least one part of TKIP key allocated */
-
-               /* Found a free slot for a TKIP key */
-               return i;
-       }
-       return -1;
-}
-
-static int ath_reserve_key_cache_slot(struct ath_softc *sc)
-{
-       int i;
-
-       /* First, try to find slots that would not be available for TKIP. */
-       if (sc->splitmic) {
-               for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) {
-                       if (!test_bit(i, sc->keymap) &&
-                           (test_bit(i + 32, sc->keymap) ||
-                            test_bit(i + 64, sc->keymap) ||
-                            test_bit(i + 64 + 32, sc->keymap)))
-                               return i;
-                       if (!test_bit(i + 32, sc->keymap) &&
-                           (test_bit(i, sc->keymap) ||
-                            test_bit(i + 64, sc->keymap) ||
-                            test_bit(i + 64 + 32, sc->keymap)))
-                               return i + 32;
-                       if (!test_bit(i + 64, sc->keymap) &&
-                           (test_bit(i , sc->keymap) ||
-                            test_bit(i + 32, sc->keymap) ||
-                            test_bit(i + 64 + 32, sc->keymap)))
-                               return i + 64;
-                       if (!test_bit(i + 64 + 32, sc->keymap) &&
-                           (test_bit(i, sc->keymap) ||
-                            test_bit(i + 32, sc->keymap) ||
-                            test_bit(i + 64, sc->keymap)))
-                               return i + 64 + 32;
-               }
-       } else {
-               for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
-                       if (!test_bit(i, sc->keymap) &&
-                           test_bit(i + 64, sc->keymap))
-                               return i;
-                       if (test_bit(i, sc->keymap) &&
-                           !test_bit(i + 64, sc->keymap))
-                               return i + 64;
-               }
-       }
-
-       /* No partially used TKIP slots, pick any available slot */
-       for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) {
-               /* Do not allow slots that could be needed for TKIP group keys
-                * to be used. This limitation could be removed if we know that
-                * TKIP will not be used. */
-               if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
-                       continue;
-               if (sc->splitmic) {
-                       if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
-                               continue;
-                       if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
-                               continue;
-               }
-
-               if (!test_bit(i, sc->keymap))
-                       return i; /* Found a free slot for a key */
-       }
-
-       /* No free slot found */
-       return -1;
-}
-
-static int ath_key_config(struct ath_softc *sc,
-                         struct ieee80211_vif *vif,
-                         struct ieee80211_sta *sta,
-                         struct ieee80211_key_conf *key)
-{
-       struct ath9k_keyval hk;
-       const u8 *mac = NULL;
-       int ret = 0;
-       int idx;
-
-       memset(&hk, 0, sizeof(hk));
-
-       switch (key->alg) {
-       case ALG_WEP:
-               hk.kv_type = ATH9K_CIPHER_WEP;
-               break;
-       case ALG_TKIP:
-               hk.kv_type = ATH9K_CIPHER_TKIP;
-               break;
-       case ALG_CCMP:
-               hk.kv_type = ATH9K_CIPHER_AES_CCM;
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       hk.kv_len = key->keylen;
-       memcpy(hk.kv_val, key->key, key->keylen);
-
-       if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
-               /* For now, use the default keys for broadcast keys. This may
-                * need to change with virtual interfaces. */
-               idx = key->keyidx;
-       } else if (key->keyidx) {
-               if (WARN_ON(!sta))
-                       return -EOPNOTSUPP;
-               mac = sta->addr;
-
-               if (vif->type != NL80211_IFTYPE_AP) {
-                       /* Only keyidx 0 should be used with unicast key, but
-                        * allow this for client mode for now. */
-                       idx = key->keyidx;
-               } else
-                       return -EIO;
-       } else {
-               if (WARN_ON(!sta))
-                       return -EOPNOTSUPP;
-               mac = sta->addr;
-
-               if (key->alg == ALG_TKIP)
-                       idx = ath_reserve_key_cache_slot_tkip(sc);
-               else
-                       idx = ath_reserve_key_cache_slot(sc);
-               if (idx < 0)
-                       return -ENOSPC; /* no free key cache entries */
-       }
-
-       if (key->alg == ALG_TKIP)
-               ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac,
-                                     vif->type == NL80211_IFTYPE_AP);
-       else
-               ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac);
-
-       if (!ret)
-               return -EIO;
-
-       set_bit(idx, sc->keymap);
-       if (key->alg == ALG_TKIP) {
-               set_bit(idx + 64, sc->keymap);
-               if (sc->splitmic) {
-                       set_bit(idx + 32, sc->keymap);
-                       set_bit(idx + 64 + 32, sc->keymap);
-               }
-       }
-
-       return idx;
-}
-
-static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
-{
-       ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx);
-       if (key->hw_key_idx < IEEE80211_WEP_NKID)
-               return;
-
-       clear_bit(key->hw_key_idx, sc->keymap);
-       if (key->alg != ALG_TKIP)
-               return;
-
-       clear_bit(key->hw_key_idx + 64, sc->keymap);
-       if (sc->splitmic) {
-               clear_bit(key->hw_key_idx + 32, sc->keymap);
-               clear_bit(key->hw_key_idx + 64 + 32, sc->keymap);
-       }
-}
-
-static void setup_ht_cap(struct ath_softc *sc,
-                        struct ieee80211_sta_ht_cap *ht_info)
-{
-#define        ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3       /* 2 ^ 16 */
-#define        ATH9K_HT_CAP_MPDUDENSITY_8 0x6          /* 8 usec */
-
-       ht_info->ht_supported = true;
-       ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
-                      IEEE80211_HT_CAP_SM_PS |
-                      IEEE80211_HT_CAP_SGI_40 |
-                      IEEE80211_HT_CAP_DSSSCCK40;
-
-       ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
-       ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
-
-       /* set up supported mcs set */
-       memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
-
-       switch(sc->rx_chainmask) {
-       case 1:
-               ht_info->mcs.rx_mask[0] = 0xff;
-               break;
-       case 3:
-       case 5:
-       case 7:
-       default:
-               ht_info->mcs.rx_mask[0] = 0xff;
-               ht_info->mcs.rx_mask[1] = 0xff;
-               break;
-       }
-
-       ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
-}
-
-static void ath9k_bss_assoc_info(struct ath_softc *sc,
-                                struct ieee80211_vif *vif,
-                                struct ieee80211_bss_conf *bss_conf)
-{
-       struct ath_vif *avp = (void *)vif->drv_priv;
-
-       if (bss_conf->assoc) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
-                       bss_conf->aid, sc->curbssid);
-
-               /* New association, store aid */
-               if (avp->av_opmode == NL80211_IFTYPE_STATION) {
-                       sc->curaid = bss_conf->aid;
-                       ath9k_hw_write_associd(sc);
-               }
-
-               /* Configure the beacon */
-               ath_beacon_config(sc, vif);
-
-               /* Reset rssi stats */
-               sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
-               sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
-               sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
-               sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
-
-               /* Start ANI */
-               mod_timer(&sc->ani.timer,
-                         jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
-       } else {
-               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
-               sc->curaid = 0;
-       }
-}
-
-/********************************/
-/*      LED functions          */
-/********************************/
-
-static void ath_led_blink_work(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc,
-                                           ath_led_blink_work.work);
-
-       if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
-               return;
-
-       if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
-           (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
-               ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
-       else
-               ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
-                                 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
-
-       queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
-                          (sc->sc_flags & SC_OP_LED_ON) ?
-                          msecs_to_jiffies(sc->led_off_duration) :
-                          msecs_to_jiffies(sc->led_on_duration));
-
-       sc->led_on_duration = sc->led_on_cnt ?
-                       max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
-                       ATH_LED_ON_DURATION_IDLE;
-       sc->led_off_duration = sc->led_off_cnt ?
-                       max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
-                       ATH_LED_OFF_DURATION_IDLE;
-       sc->led_on_cnt = sc->led_off_cnt = 0;
-       if (sc->sc_flags & SC_OP_LED_ON)
-               sc->sc_flags &= ~SC_OP_LED_ON;
-       else
-               sc->sc_flags |= SC_OP_LED_ON;
-}
-
-static void ath_led_brightness(struct led_classdev *led_cdev,
-                              enum led_brightness brightness)
-{
-       struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
-       struct ath_softc *sc = led->sc;
-
-       switch (brightness) {
-       case LED_OFF:
-               if (led->led_type == ATH_LED_ASSOC ||
-                   led->led_type == ATH_LED_RADIO) {
-                       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
-                               (led->led_type == ATH_LED_RADIO));
-                       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-                       if (led->led_type == ATH_LED_RADIO)
-                               sc->sc_flags &= ~SC_OP_LED_ON;
-               } else {
-                       sc->led_off_cnt++;
-               }
-               break;
-       case LED_FULL:
-               if (led->led_type == ATH_LED_ASSOC) {
-                       sc->sc_flags |= SC_OP_LED_ASSOCIATED;
-                       queue_delayed_work(sc->hw->workqueue,
-                                          &sc->ath_led_blink_work, 0);
-               } else if (led->led_type == ATH_LED_RADIO) {
-                       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
-                       sc->sc_flags |= SC_OP_LED_ON;
-               } else {
-                       sc->led_on_cnt++;
-               }
-               break;
-       default:
-               break;
-       }
-}
-
-static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
-                           char *trigger)
-{
-       int ret;
-
-       led->sc = sc;
-       led->led_cdev.name = led->name;
-       led->led_cdev.default_trigger = trigger;
-       led->led_cdev.brightness_set = ath_led_brightness;
-
-       ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
-       if (ret)
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Failed to register led:%s", led->name);
-       else
-               led->registered = 1;
-       return ret;
-}
-
-static void ath_unregister_led(struct ath_led *led)
-{
-       if (led->registered) {
-               led_classdev_unregister(&led->led_cdev);
-               led->registered = 0;
-       }
-}
-
-static void ath_deinit_leds(struct ath_softc *sc)
-{
-       cancel_delayed_work_sync(&sc->ath_led_blink_work);
-       ath_unregister_led(&sc->assoc_led);
-       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-       ath_unregister_led(&sc->tx_led);
-       ath_unregister_led(&sc->rx_led);
-       ath_unregister_led(&sc->radio_led);
-       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-}
-
-static void ath_init_leds(struct ath_softc *sc)
-{
-       char *trigger;
-       int ret;
-
-       /* Configure gpio 1 for output */
-       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
-                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-       /* LED off, active low */
-       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-       INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
-
-       trigger = ieee80211_get_radio_led_name(sc->hw);
-       snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
-               "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->radio_led, trigger);
-       sc->radio_led.led_type = ATH_LED_RADIO;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_assoc_led_name(sc->hw);
-       snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
-               "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->assoc_led, trigger);
-       sc->assoc_led.led_type = ATH_LED_ASSOC;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_tx_led_name(sc->hw);
-       snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
-               "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->tx_led, trigger);
-       sc->tx_led.led_type = ATH_LED_TX;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_rx_led_name(sc->hw);
-       snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
-               "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->rx_led, trigger);
-       sc->rx_led.led_type = ATH_LED_RX;
-       if (ret)
-               goto fail;
-
-       return;
-
-fail:
-       ath_deinit_leds(sc);
-}
-
-void ath_radio_enable(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ieee80211_channel *channel = sc->hw->conf.channel;
-       int r;
-
-       ath9k_ps_wakeup(sc);
-       spin_lock_bh(&sc->sc_resetlock);
-
-       r = ath9k_hw_reset(ah, ah->curchan, false);
-
-       if (r) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset channel %u (%uMhz) ",
-                       "reset status %u\n",
-                       channel->center_freq, r);
-       }
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       ath_update_txpow(sc);
-       if (ath_startrecv(sc) != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to restart recv logic\n");
-               return;
-       }
-
-       if (sc->sc_flags & SC_OP_BEACONS)
-               ath_beacon_config(sc, NULL);    /* restart beacons */
-
-       /* Re-Enable  interrupts */
-       ath9k_hw_set_interrupts(ah, sc->imask);
-
-       /* Enable LED */
-       ath9k_hw_cfg_output(ah, ATH_LED_PIN,
-                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-       ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
-
-       ieee80211_wake_queues(sc->hw);
-       ath9k_ps_restore(sc);
-}
-
-void ath_radio_disable(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ieee80211_channel *channel = sc->hw->conf.channel;
-       int r;
-
-       ath9k_ps_wakeup(sc);
-       ieee80211_stop_queues(sc->hw);
-
-       /* Disable LED */
-       ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1);
-       ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN);
-
-       /* Disable interrupts */
-       ath9k_hw_set_interrupts(ah, 0);
-
-       ath_drain_all_txq(sc, false);   /* clear pending tx frames */
-       ath_stoprecv(sc);               /* turn off frame recv */
-       ath_flushrecv(sc);              /* flush recv queue */
-
-       spin_lock_bh(&sc->sc_resetlock);
-       r = ath9k_hw_reset(ah, ah->curchan, false);
-       if (r) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset channel %u (%uMhz) "
-                       "reset status %u\n",
-                       channel->center_freq, r);
-       }
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       ath9k_hw_phy_disable(ah);
-       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
-       ath9k_ps_restore(sc);
-}
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-
-/*******************/
-/*     Rfkill     */
-/*******************/
-
-static bool ath_is_rfkill_set(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-
-       return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
-                                 ah->rfkill_polarity;
-}
-
-/* h/w rfkill poll function */
-static void ath_rfkill_poll(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc,
-                                           rf_kill.rfkill_poll.work);
-       bool radio_on;
-
-       if (sc->sc_flags & SC_OP_INVALID)
-               return;
-
-       radio_on = !ath_is_rfkill_set(sc);
-
-       /*
-        * enable/disable radio only when there is a
-        * state change in RF switch
-        */
-       if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) {
-               enum rfkill_state state;
-
-               if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) {
-                       state = radio_on ? RFKILL_STATE_SOFT_BLOCKED
-                               : RFKILL_STATE_HARD_BLOCKED;
-               } else if (radio_on) {
-                       ath_radio_enable(sc);
-                       state = RFKILL_STATE_UNBLOCKED;
-               } else {
-                       ath_radio_disable(sc);
-                       state = RFKILL_STATE_HARD_BLOCKED;
-               }
-
-               if (state == RFKILL_STATE_HARD_BLOCKED)
-                       sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED;
-               else
-                       sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED;
-
-               rfkill_force_state(sc->rf_kill.rfkill, state);
-       }
-
-       queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll,
-                          msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL));
-}
-
-/* s/w rfkill handler */
-static int ath_sw_toggle_radio(void *data, enum rfkill_state state)
-{
-       struct ath_softc *sc = data;
-
-       switch (state) {
-       case RFKILL_STATE_SOFT_BLOCKED:
-               if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED |
-                   SC_OP_RFKILL_SW_BLOCKED)))
-                       ath_radio_disable(sc);
-               sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED;
-               return 0;
-       case RFKILL_STATE_UNBLOCKED:
-               if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) {
-                       sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED;
-                       if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) {
-                               DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the"
-                                       "radio as it is disabled by h/w\n");
-                               return -EPERM;
-                       }
-                       ath_radio_enable(sc);
-               }
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-/* Init s/w rfkill */
-static int ath_init_sw_rfkill(struct ath_softc *sc)
-{
-       sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy),
-                                            RFKILL_TYPE_WLAN);
-       if (!sc->rf_kill.rfkill) {
-               DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");
-               return -ENOMEM;
-       }
-
-       snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
-               "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
-       sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name;
-       sc->rf_kill.rfkill->data = sc;
-       sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio;
-       sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED;
-
-       return 0;
-}
-
-/* Deinitialize rfkill */
-static void ath_deinit_rfkill(struct ath_softc *sc)
-{
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-
-       if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
-               rfkill_unregister(sc->rf_kill.rfkill);
-               sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED;
-               sc->rf_kill.rfkill = NULL;
-       }
-}
-
-static int ath_start_rfkill_poll(struct ath_softc *sc)
-{
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               queue_delayed_work(sc->hw->workqueue,
-                                  &sc->rf_kill.rfkill_poll, 0);
-
-       if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
-               if (rfkill_register(sc->rf_kill.rfkill)) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Unable to register rfkill\n");
-                       rfkill_free(sc->rf_kill.rfkill);
-
-                       /* Deinitialize the device */
-                       ath_cleanup(sc);
-                       return -EIO;
-               } else {
-                       sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
-               }
-       }
-
-       return 0;
-}
-#endif /* CONFIG_RFKILL */
-
-void ath_cleanup(struct ath_softc *sc)
-{
-       ath_detach(sc);
-       free_irq(sc->irq, sc);
-       ath_bus_cleanup(sc);
-       kfree(sc->sec_wiphy);
-       ieee80211_free_hw(sc->hw);
-}
-
-void ath_detach(struct ath_softc *sc)
-{
-       struct ieee80211_hw *hw = sc->hw;
-       int i = 0;
-
-       ath9k_ps_wakeup(sc);
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       ath_deinit_rfkill(sc);
-#endif
-       ath_deinit_leds(sc);
-       cancel_work_sync(&sc->chan_work);
-       cancel_delayed_work_sync(&sc->wiphy_work);
-
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-               if (aphy == NULL)
-                       continue;
-               sc->sec_wiphy[i] = NULL;
-               ieee80211_unregister_hw(aphy->hw);
-               ieee80211_free_hw(aphy->hw);
-       }
-       ieee80211_unregister_hw(hw);
-       ath_rx_cleanup(sc);
-       ath_tx_cleanup(sc);
-
-       tasklet_kill(&sc->intr_tq);
-       tasklet_kill(&sc->bcon_tasklet);
-
-       if (!(sc->sc_flags & SC_OP_INVALID))
-               ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
-
-       /* cleanup tx queues */
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-
-       ath9k_hw_detach(sc->sc_ah);
-       ath9k_exit_debug(sc);
-       ath9k_ps_restore(sc);
-}
-
-static int ath9k_reg_notifier(struct wiphy *wiphy,
-                             struct regulatory_request *request)
-{
-       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_regulatory *reg = &sc->sc_ah->regulatory;
-
-       return ath_reg_notifier_apply(wiphy, request, reg);
-}
-
-static int ath_init(u16 devid, struct ath_softc *sc)
-{
-       struct ath_hw *ah = NULL;
-       int status;
-       int error = 0, i;
-       int csz = 0;
-
-       /* XXX: hardware will not be ready until ath_open() being called */
-       sc->sc_flags |= SC_OP_INVALID;
-
-       if (ath9k_init_debug(sc) < 0)
-               printk(KERN_ERR "Unable to create debugfs files\n");
-
-       spin_lock_init(&sc->wiphy_lock);
-       spin_lock_init(&sc->sc_resetlock);
-       spin_lock_init(&sc->sc_serial_rw);
-       mutex_init(&sc->mutex);
-       tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
-       tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
-                    (unsigned long)sc);
-
-       /*
-        * Cache line size is used to size and align various
-        * structures used to communicate with the hardware.
-        */
-       ath_read_cachesize(sc, &csz);
-       /* XXX assert csz is non-zero */
-       sc->cachelsz = csz << 2;        /* convert to bytes */
-
-       ah = ath9k_hw_attach(devid, sc, &status);
-       if (ah == NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to attach hardware; HAL status %d\n", status);
-               error = -ENXIO;
-               goto bad;
-       }
-       sc->sc_ah = ah;
-
-       /* Get the hardware key cache size. */
-       sc->keymax = ah->caps.keycache_size;
-       if (sc->keymax > ATH_KEYMAX) {
-               DPRINTF(sc, ATH_DBG_ANY,
-                       "Warning, using only %u entries in %u key cache\n",
-                       ATH_KEYMAX, sc->keymax);
-               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->keymax; i++)
-               ath9k_hw_keyreset(ah, (u16) i);
-
-       if (ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy,
-                         ath9k_reg_notifier))
-               goto bad;
-
-       /* default to MONITOR mode */
-       sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
-
-       /* Setup rate tables */
-
-       ath_rate_attach(sc);
-       ath_setup_rates(sc, IEEE80211_BAND_2GHZ);
-       ath_setup_rates(sc, IEEE80211_BAND_5GHZ);
-
-       /*
-        * 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.
-        */
-       sc->beacon.beaconq = ath_beaconq_setup(ah);
-       if (sc->beacon.beaconq == -1) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup a beacon xmit queue\n");
-               error = -EIO;
-               goto bad2;
-       }
-       sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
-       if (sc->beacon.cabq == NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup CAB xmit queue\n");
-               error = -EIO;
-               goto bad2;
-       }
-
-       sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
-       ath_cabq_update(sc);
-
-       for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
-               sc->tx.hwq_map[i] = -1;
-
-       /* Setup data queues */
-       /* NB: ensure BK queue is the lowest priority h/w queue */
-       if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup xmit queue for BK traffic\n");
-               error = -EIO;
-               goto bad2;
-       }
-
-       if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup xmit queue for BE traffic\n");
-               error = -EIO;
-               goto bad2;
-       }
-       if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup xmit queue for VI traffic\n");
-               error = -EIO;
-               goto bad2;
-       }
-       if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup xmit queue for VO traffic\n");
-               error = -EIO;
-               goto bad2;
-       }
-
-       /* Initializes the noise floor to a reasonable default value.
-        * Later on this will be updated during ANI processing. */
-
-       sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
-       setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc);
-
-       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.
-                */
-               ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC,
-                                      0, 1, NULL);
-       }
-
-       /*
-        * 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->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->config.txpowlimit = ATH_TXPOWER_MAX;
-
-       /* 11n Capabilities */
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-               sc->sc_flags |= SC_OP_TXAGGR;
-               sc->sc_flags |= SC_OP_RXAGGR;
-       }
-
-       sc->tx_chainmask = ah->caps.tx_chainmask;
-       sc->rx_chainmask = ah->caps.rx_chainmask;
-
-       ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
-       sc->rx.defant = ath9k_hw_getdefantenna(ah);
-
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-               memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
-
-       sc->beacon.slottime = ATH9K_SLOT_TIME_9;        /* default to short slot time */
-
-       /* initialize beacon slots */
-       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
-               sc->beacon.bslot[i] = NULL;
-               sc->beacon.bslot_aphy[i] = NULL;
-       }
-
-       /* setup channels and rates */
-
-       sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
-       sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
-               sc->rates[IEEE80211_BAND_2GHZ];
-       sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
-       sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
-               ARRAY_SIZE(ath9k_2ghz_chantable);
-
-       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
-               sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
-               sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
-                       sc->rates[IEEE80211_BAND_5GHZ];
-               sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
-               sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
-                       ARRAY_SIZE(ath9k_5ghz_chantable);
-       }
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
-               ath9k_hw_btcoex_enable(sc->sc_ah);
-
-       return 0;
-bad2:
-       /* cleanup tx queues */
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-bad:
-       if (ah)
-               ath9k_hw_detach(ah);
-       ath9k_exit_debug(sc);
-
-       return error;
-}
-
-void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
-{
-       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-               IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-               IEEE80211_HW_SIGNAL_DBM |
-               IEEE80211_HW_AMPDU_AGGREGATION |
-               IEEE80211_HW_SUPPORTS_PS |
-               IEEE80211_HW_PS_NULLFUNC_STACK |
-               IEEE80211_HW_SPECTRUM_MGMT;
-
-       if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
-               hw->flags |= IEEE80211_HW_MFP_CAPABLE;
-
-       hw->wiphy->interface_modes =
-               BIT(NL80211_IFTYPE_AP) |
-               BIT(NL80211_IFTYPE_STATION) |
-               BIT(NL80211_IFTYPE_ADHOC) |
-               BIT(NL80211_IFTYPE_MESH_POINT);
-
-       hw->queues = 4;
-       hw->max_rates = 4;
-       hw->channel_change_time = 5000;
-       hw->max_listen_interval = 10;
-       hw->max_rate_tries = ATH_11N_TXMAXTRY;
-       hw->sta_data_size = sizeof(struct ath_node);
-       hw->vif_data_size = sizeof(struct ath_vif);
-
-       hw->rate_control_algorithm = "ath9k_rate_control";
-
-       hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
-               &sc->sbands[IEEE80211_BAND_2GHZ];
-       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
-               hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
-                       &sc->sbands[IEEE80211_BAND_5GHZ];
-}
-
-int ath_attach(u16 devid, struct ath_softc *sc)
-{
-       struct ieee80211_hw *hw = sc->hw;
-       int error = 0, i;
-       struct ath_regulatory *reg;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
-
-       error = ath_init(devid, sc);
-       if (error != 0)
-               return error;
-
-       reg = &sc->sc_ah->regulatory;
-
-       /* get mac address from hardware and set in mac80211 */
-
-       SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
-
-       ath_set_hw_capab(sc, hw);
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-               setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
-               if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
-                       setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
-       }
-
-       /* initialize tx/rx engine */
-       error = ath_tx_init(sc, ATH_TXBUF);
-       if (error != 0)
-               goto error_attach;
-
-       error = ath_rx_init(sc, ATH_RXBUF);
-       if (error != 0)
-               goto error_attach;
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       /* Initialze h/w Rfkill */
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
-
-       /* Initialize s/w rfkill */
-       error = ath_init_sw_rfkill(sc);
-       if (error)
-               goto error_attach;
-#endif
-
-       INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
-       INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
-       sc->wiphy_scheduler_int = msecs_to_jiffies(500);
-
-       error = ieee80211_register_hw(hw);
-
-       if (!ath_is_world_regd(reg)) {
-               error = regulatory_hint(hw->wiphy, reg->alpha2);
-               if (error)
-                       goto error_attach;
-       }
-
-       /* Initialize LED control */
-       ath_init_leds(sc);
-
-
-       return 0;
-
-error_attach:
-       /* cleanup tx queues */
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-
-       ath9k_hw_detach(sc->sc_ah);
-       ath9k_exit_debug(sc);
-
-       return error;
-}
-
-int ath_reset(struct ath_softc *sc, bool retry_tx)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ieee80211_hw *hw = sc->hw;
-       int r;
-
-       ath9k_hw_set_interrupts(ah, 0);
-       ath_drain_all_txq(sc, retry_tx);
-       ath_stoprecv(sc);
-       ath_flushrecv(sc);
-
-       spin_lock_bh(&sc->sc_resetlock);
-       r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
-       if (r)
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset hardware; reset status %u\n", r);
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       if (ath_startrecv(sc) != 0)
-               DPRINTF(sc, ATH_DBG_FATAL, "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.
-        */
-       ath_cache_conf_rate(sc, &hw->conf);
-
-       ath_update_txpow(sc);
-
-       if (sc->sc_flags & SC_OP_BEACONS)
-               ath_beacon_config(sc, NULL);    /* restart beacons */
-
-       ath9k_hw_set_interrupts(ah, sc->imask);
-
-       if (retry_tx) {
-               int i;
-               for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-                       if (ATH_TXQ_SETUP(sc, i)) {
-                               spin_lock_bh(&sc->tx.txq[i].axq_lock);
-                               ath_txq_schedule(sc, &sc->tx.txq[i]);
-                               spin_unlock_bh(&sc->tx.txq[i].axq_lock);
-                       }
-               }
-       }
-
-       return r;
-}
-
-/*
- *  This function will allocate both the DMA descriptor structure, and the
- *  buffers it contains.  These are used to contain the descriptors used
- *  by the system.
-*/
-int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
-                     struct list_head *head, const char *name,
-                     int nbuf, int ndesc)
-{
-#define        DS2PHYS(_dd, _ds)                                               \
-       ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
-#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
-#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
-
-       struct ath_desc *ds;
-       struct ath_buf *bf;
-       int i, bsize, error;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
-               name, nbuf, ndesc);
-
-       INIT_LIST_HEAD(head);
-       /* ath_desc must be a multiple of DWORDs */
-       if ((sizeof(struct ath_desc) % 4) != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n");
-               ASSERT((sizeof(struct ath_desc) % 4) == 0);
-               error = -ENOMEM;
-               goto fail;
-       }
-
-       dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
-
-       /*
-        * Need additional DMA memory because we can't use
-        * descriptors that cross the 4K page boundary. Assume
-        * one skipped descriptor per 4K page.
-        */
-       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
-               u32 ndesc_skipped =
-                       ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
-               u32 dma_len;
-
-               while (ndesc_skipped) {
-                       dma_len = ndesc_skipped * sizeof(struct ath_desc);
-                       dd->dd_desc_len += dma_len;
-
-                       ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
-               };
-       }
-
-       /* allocate descriptors */
-       dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
-                                        &dd->dd_desc_paddr, GFP_KERNEL);
-       if (dd->dd_desc == NULL) {
-               error = -ENOMEM;
-               goto fail;
-       }
-       ds = dd->dd_desc;
-       DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
-               name, ds, (u32) dd->dd_desc_len,
-               ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
-
-       /* allocate buffers */
-       bsize = sizeof(struct ath_buf) * nbuf;
-       bf = kzalloc(bsize, GFP_KERNEL);
-       if (bf == NULL) {
-               error = -ENOMEM;
-               goto fail2;
-       }
-       dd->dd_bufptr = bf;
-
-       for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
-               bf->bf_desc = ds;
-               bf->bf_daddr = DS2PHYS(dd, ds);
-
-               if (!(sc->sc_ah->caps.hw_caps &
-                     ATH9K_HW_CAP_4KB_SPLITTRANS)) {
-                       /*
-                        * Skip descriptor addresses which can cause 4KB
-                        * boundary crossing (addr + length) with a 32 dword
-                        * descriptor fetch.
-                        */
-                       while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
-                               ASSERT((caddr_t) bf->bf_desc <
-                                      ((caddr_t) dd->dd_desc +
-                                       dd->dd_desc_len));
-
-                               ds += ndesc;
-                               bf->bf_desc = ds;
-                               bf->bf_daddr = DS2PHYS(dd, ds);
-                       }
-               }
-               list_add_tail(&bf->list, head);
-       }
-       return 0;
-fail2:
-       dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
-                         dd->dd_desc_paddr);
-fail:
-       memset(dd, 0, sizeof(*dd));
-       return error;
-#undef ATH_DESC_4KB_BOUND_CHECK
-#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
-#undef DS2PHYS
-}
-
-void ath_descdma_cleanup(struct ath_softc *sc,
-                        struct ath_descdma *dd,
-                        struct list_head *head)
-{
-       dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
-                         dd->dd_desc_paddr);
-
-       INIT_LIST_HEAD(head);
-       kfree(dd->dd_bufptr);
-       memset(dd, 0, sizeof(*dd));
-}
-
-int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
-{
-       int qnum;
-
-       switch (queue) {
-       case 0:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO];
-               break;
-       case 1:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI];
-               break;
-       case 2:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
-               break;
-       case 3:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK];
-               break;
-       default:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
-               break;
-       }
-
-       return qnum;
-}
-
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
-{
-       int qnum;
-
-       switch (queue) {
-       case ATH9K_WME_AC_VO:
-               qnum = 0;
-               break;
-       case ATH9K_WME_AC_VI:
-               qnum = 1;
-               break;
-       case ATH9K_WME_AC_BE:
-               qnum = 2;
-               break;
-       case ATH9K_WME_AC_BK:
-               qnum = 3;
-               break;
-       default:
-               qnum = -1;
-               break;
-       }
-
-       return qnum;
-}
-
-/* XXX: Remove me once we don't depend on ath9k_channel for all
- * this redundant data */
-void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
-                          struct ath9k_channel *ichan)
-{
-       struct ieee80211_channel *chan = hw->conf.channel;
-       struct ieee80211_conf *conf = &hw->conf;
-
-       ichan->channel = chan->center_freq;
-       ichan->chan = chan;
-
-       if (chan->band == IEEE80211_BAND_2GHZ) {
-               ichan->chanmode = CHANNEL_G;
-               ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
-       } else {
-               ichan->chanmode = CHANNEL_A;
-               ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
-       }
-
-       sc->tx_chan_width = ATH9K_HT_MACMODE_20;
-
-       if (conf_is_ht(conf)) {
-               if (conf_is_ht40(conf))
-                       sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
-
-               ichan->chanmode = ath_get_extchanmode(sc, chan,
-                                           conf->channel_type);
-       }
-}
-
-/**********************/
-/* mac80211 callbacks */
-/**********************/
-
-static int ath9k_start(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ieee80211_channel *curchan = hw->conf.channel;
-       struct ath9k_channel *init_channel;
-       int r, pos;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
-               "initial channel: %d MHz\n", curchan->center_freq);
-
-       mutex_lock(&sc->mutex);
-
-       if (ath9k_wiphy_started(sc)) {
-               if (sc->chan_idx == curchan->hw_value) {
-                       /*
-                        * Already on the operational channel, the new wiphy
-                        * can be marked active.
-                        */
-                       aphy->state = ATH_WIPHY_ACTIVE;
-                       ieee80211_wake_queues(hw);
-               } else {
-                       /*
-                        * Another wiphy is on another channel, start the new
-                        * wiphy in paused state.
-                        */
-                       aphy->state = ATH_WIPHY_PAUSED;
-                       ieee80211_stop_queues(hw);
-               }
-               mutex_unlock(&sc->mutex);
-               return 0;
-       }
-       aphy->state = ATH_WIPHY_ACTIVE;
-
-       /* setup initial channel */
-
-       pos = curchan->hw_value;
-
-       sc->chan_idx = pos;
-       init_channel = &sc->sc_ah->channels[pos];
-       ath9k_update_ichannel(sc, hw, init_channel);
-
-       /* 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.
-        */
-       spin_lock_bh(&sc->sc_resetlock);
-       r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
-       if (r) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset hardware; reset status %u "
-                       "(freq %u MHz)\n", r,
-                       curchan->center_freq);
-               spin_unlock_bh(&sc->sc_resetlock);
-               goto mutex_unlock;
-       }
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       /*
-        * This is needed only to setup initial state
-        * but it's best done after a reset.
-        */
-       ath_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 (ath_startrecv(sc) != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n");
-               r = -EIO;
-               goto mutex_unlock;
-       }
-
-       /* Setup our intr mask. */
-       sc->imask = ATH9K_INT_RX | ATH9K_INT_TX
-               | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
-               | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
-               sc->imask |= ATH9K_INT_GTT;
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
-               sc->imask |= ATH9K_INT_CST;
-
-       ath_cache_conf_rate(sc, &hw->conf);
-
-       sc->sc_flags &= ~SC_OP_INVALID;
-
-       /* Disable BMISS interrupt when we're not associated */
-       sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-
-       ieee80211_wake_queues(hw);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       r = ath_start_rfkill_poll(sc);
-#endif
-
-mutex_unlock:
-       mutex_unlock(&sc->mutex);
-
-       return r;
-}
-
-static int ath9k_tx(struct ieee80211_hw *hw,
-                   struct sk_buff *skb)
-{
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_tx_control txctl;
-       int hdrlen, padsize;
-
-       if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
-               printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state "
-                      "%d\n", wiphy_name(hw->wiphy), aphy->state);
-               goto exit;
-       }
-
-       memset(&txctl, 0, sizeof(struct ath_tx_control));
-
-       /*
-        * As a temporary workaround, assign seq# here; this will likely need
-        * to be cleaned up to work better with Beacon transmission and virtual
-        * BSSes.
-        */
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-                       sc->tx.seq_no += 0x10;
-               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-       }
-
-       /* Add the padding after the header if this is not already done */
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       if (hdrlen & 3) {
-               padsize = hdrlen % 4;
-               if (skb_headroom(skb) < padsize)
-                       return -1;
-               skb_push(skb, padsize);
-               memmove(skb->data, skb->data + padsize, hdrlen);
-       }
-
-       /* Check if a tx queue is available */
-
-       txctl.txq = ath_test_get_txq(sc, skb);
-       if (!txctl.txq)
-               goto exit;
-
-       DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
-
-       if (ath_tx_start(hw, skb, &txctl) != 0) {
-               DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n");
-               goto exit;
-       }
-
-       return 0;
-exit:
-       dev_kfree_skb_any(skb);
-       return 0;
-}
-
-static void ath9k_stop(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       aphy->state = ATH_WIPHY_INACTIVE;
-
-       if (sc->sc_flags & SC_OP_INVALID) {
-               DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
-               return;
-       }
-
-       mutex_lock(&sc->mutex);
-
-       ieee80211_stop_queues(hw);
-
-       if (ath9k_wiphy_started(sc)) {
-               mutex_unlock(&sc->mutex);
-               return; /* another wiphy still in use */
-       }
-
-       /* make sure h/w will not generate any interrupt
-        * before setting the invalid flag. */
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
-
-       if (!(sc->sc_flags & SC_OP_INVALID)) {
-               ath_drain_all_txq(sc, false);
-               ath_stoprecv(sc);
-               ath9k_hw_phy_disable(sc->sc_ah);
-       } else
-               sc->rx.rxlink = NULL;
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-#endif
-       /* disable HAL and put h/w to sleep */
-       ath9k_hw_disable(sc->sc_ah);
-       ath9k_hw_configpcipowersave(sc->sc_ah, 1);
-
-       sc->sc_flags |= SC_OP_INVALID;
-
-       mutex_unlock(&sc->mutex);
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n");
-}
-
-static int ath9k_add_interface(struct ieee80211_hw *hw,
-                              struct ieee80211_if_init_conf *conf)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_vif *avp = (void *)conf->vif->drv_priv;
-       enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
-       int ret = 0;
-
-       mutex_lock(&sc->mutex);
-
-       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
-           sc->nvifs > 0) {
-               ret = -ENOBUFS;
-               goto out;
-       }
-
-       switch (conf->type) {
-       case NL80211_IFTYPE_STATION:
-               ic_opmode = NL80211_IFTYPE_STATION;
-               break;
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_MESH_POINT:
-               if (sc->nbcnvifs >= ATH_BCBUF) {
-                       ret = -ENOBUFS;
-                       goto out;
-               }
-               ic_opmode = conf->type;
-               break;
-       default:
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Interface type %d not yet supported\n", conf->type);
-               ret = -EOPNOTSUPP;
-               goto out;
-       }
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode);
-
-       /* Set the VIF opmode */
-       avp->av_opmode = ic_opmode;
-       avp->av_bslot = -1;
-
-       sc->nvifs++;
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-               ath9k_set_bssid_mask(hw);
-
-       if (sc->nvifs > 1)
-               goto out; /* skip global settings for secondary vif */
-
-       if (ic_opmode == NL80211_IFTYPE_AP) {
-               ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
-               sc->sc_flags |= SC_OP_TSF_RESET;
-       }
-
-       /* Set the device opmode */
-       sc->sc_ah->opmode = ic_opmode;
-
-       /*
-        * Enable MIB interrupts when there are hardware phy counters.
-        * Note we only do this (at the moment) for station mode.
-        */
-       if ((conf->type == NL80211_IFTYPE_STATION) ||
-           (conf->type == NL80211_IFTYPE_ADHOC) ||
-           (conf->type == NL80211_IFTYPE_MESH_POINT)) {
-               if (ath9k_hw_phycounters(sc->sc_ah))
-                       sc->imask |= ATH9K_INT_MIB;
-               sc->imask |= ATH9K_INT_TSFOOR;
-       }
-
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-
-       if (conf->type == NL80211_IFTYPE_AP) {
-               /* TODO: is this a suitable place to start ANI for AP mode? */
-               /* Start ANI */
-               mod_timer(&sc->ani.timer,
-                         jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
-       }
-
-out:
-       mutex_unlock(&sc->mutex);
-       return ret;
-}
-
-static void ath9k_remove_interface(struct ieee80211_hw *hw,
-                                  struct ieee80211_if_init_conf *conf)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_vif *avp = (void *)conf->vif->drv_priv;
-       int i;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
-
-       mutex_lock(&sc->mutex);
-
-       /* Stop ANI */
-       del_timer_sync(&sc->ani.timer);
-
-       /* Reclaim beacon resources */
-       if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
-               ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-               ath_beacon_return(sc, avp);
-       }
-
-       sc->sc_flags &= ~SC_OP_BEACONS;
-
-       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
-               if (sc->beacon.bslot[i] == conf->vif) {
-                       printk(KERN_DEBUG "%s: vif had allocated beacon "
-                              "slot\n", __func__);
-                       sc->beacon.bslot[i] = NULL;
-                       sc->beacon.bslot_aphy[i] = NULL;
-               }
-       }
-
-       sc->nvifs--;
-
-       mutex_unlock(&sc->mutex);
-}
-
-static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ieee80211_conf *conf = &hw->conf;
-       struct ath_hw *ah = sc->sc_ah;
-
-       mutex_lock(&sc->mutex);
-
-       if (changed & IEEE80211_CONF_CHANGE_PS) {
-               if (conf->flags & IEEE80211_CONF_PS) {
-                       if (!(ah->caps.hw_caps &
-                             ATH9K_HW_CAP_AUTOSLEEP)) {
-                               if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
-                                       sc->imask |= ATH9K_INT_TIM_TIMER;
-                                       ath9k_hw_set_interrupts(sc->sc_ah,
-                                                       sc->imask);
-                               }
-                               ath9k_hw_setrxabort(sc->sc_ah, 1);
-                       }
-                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
-               } else {
-                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
-                       if (!(ah->caps.hw_caps &
-                             ATH9K_HW_CAP_AUTOSLEEP)) {
-                               ath9k_hw_setrxabort(sc->sc_ah, 0);
-                               sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
-                               if (sc->imask & ATH9K_INT_TIM_TIMER) {
-                                       sc->imask &= ~ATH9K_INT_TIM_TIMER;
-                                       ath9k_hw_set_interrupts(sc->sc_ah,
-                                                       sc->imask);
-                               }
-                       }
-               }
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               struct ieee80211_channel *curchan = hw->conf.channel;
-               int pos = curchan->hw_value;
-
-               aphy->chan_idx = pos;
-               aphy->chan_is_ht = conf_is_ht(conf);
-
-               if (aphy->state == ATH_WIPHY_SCAN ||
-                   aphy->state == ATH_WIPHY_ACTIVE)
-                       ath9k_wiphy_pause_all_forced(sc, aphy);
-               else {
-                       /*
-                        * Do not change operational channel based on a paused
-                        * wiphy changes.
-                        */
-                       goto skip_chan_change;
-               }
-
-               DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
-                       curchan->center_freq);
-
-               /* XXX: remove me eventualy */
-               ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
-
-               ath_update_chainmask(sc, conf_is_ht(conf));
-
-               if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
-                       DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
-                       mutex_unlock(&sc->mutex);
-                       return -EINVAL;
-               }
-       }
-
-skip_chan_change:
-       if (changed & IEEE80211_CONF_CHANGE_POWER)
-               sc->config.txpowlimit = 2 * conf->power_level;
-
-       /*
-        * The HW TSF has to be reset when the beacon interval changes.
-        * We set the flag here, and ath_beacon_config_ap() would take this
-        * into account when it gets called through the subsequent
-        * config_interface() call - with IFCC_BEACON in the changed field.
-        */
-
-       if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
-               sc->sc_flags |= SC_OP_TSF_RESET;
-
-       mutex_unlock(&sc->mutex);
-
-       return 0;
-}
-
-static int ath9k_config_interface(struct ieee80211_hw *hw,
-                                 struct ieee80211_vif *vif,
-                                 struct ieee80211_if_conf *conf)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_vif *avp = (void *)vif->drv_priv;
-       u32 rfilt = 0;
-       int error, i;
-
-       mutex_lock(&sc->mutex);
-
-       /* TODO: Need to decide which hw opmode to use for multi-interface
-        * cases */
-       if (vif->type == NL80211_IFTYPE_AP &&
-           ah->opmode != NL80211_IFTYPE_AP) {
-               ah->opmode = NL80211_IFTYPE_STATION;
-               ath9k_hw_setopmode(ah);
-               memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
-               sc->curaid = 0;
-               ath9k_hw_write_associd(sc);
-               /* Request full reset to get hw opmode changed properly */
-               sc->sc_flags |= SC_OP_FULL_RESET;
-       }
-
-       if ((conf->changed & IEEE80211_IFCC_BSSID) &&
-           !is_zero_ether_addr(conf->bssid)) {
-               switch (vif->type) {
-               case NL80211_IFTYPE_STATION:
-               case NL80211_IFTYPE_ADHOC:
-               case NL80211_IFTYPE_MESH_POINT:
-                       /* Set BSSID */
-                       memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
-                       memcpy(avp->bssid, conf->bssid, ETH_ALEN);
-                       sc->curaid = 0;
-                       ath9k_hw_write_associd(sc);
-
-                       /* Set aggregation protection mode parameters */
-                       sc->config.ath_aggr_prot = 0;
-
-                       DPRINTF(sc, ATH_DBG_CONFIG,
-                               "RX filter 0x%x bssid %pM aid 0x%x\n",
-                               rfilt, sc->curbssid, sc->curaid);
-
-                       /* need to reconfigure the beacon */
-                       sc->sc_flags &= ~SC_OP_BEACONS ;
-
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       if ((vif->type == NL80211_IFTYPE_ADHOC) ||
-           (vif->type == NL80211_IFTYPE_AP) ||
-           (vif->type == NL80211_IFTYPE_MESH_POINT)) {
-               if ((conf->changed & IEEE80211_IFCC_BEACON) ||
-                   (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
-                    conf->enable_beacon)) {
-                       /*
-                        * Allocate and setup the beacon frame.
-                        *
-                        * Stop any previous beacon DMA.  This may be
-                        * necessary, for example, when an ibss merge
-                        * causes reconfiguration; we may be called
-                        * with beacon transmission active.
-                        */
-                       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-
-                       error = ath_beacon_alloc(aphy, vif);
-                       if (error != 0) {
-                               mutex_unlock(&sc->mutex);
-                               return error;
-                       }
-
-                       ath_beacon_config(sc, vif);
-               }
-       }
-
-       /* Check for WLAN_CAPABILITY_PRIVACY ? */
-       if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
-               for (i = 0; i < IEEE80211_WEP_NKID; i++)
-                       if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
-                               ath9k_hw_keysetmac(sc->sc_ah,
-                                                  (u16)i,
-                                                  sc->curbssid);
-       }
-
-       /* Only legacy IBSS for now */
-       if (vif->type == NL80211_IFTYPE_ADHOC)
-               ath_update_chainmask(sc, 0);
-
-       mutex_unlock(&sc->mutex);
-
-       return 0;
-}
-
-#define SUPPORTED_FILTERS                      \
-       (FIF_PROMISC_IN_BSS |                   \
-       FIF_ALLMULTI |                          \
-       FIF_CONTROL |                           \
-       FIF_OTHER_BSS |                         \
-       FIF_BCN_PRBRESP_PROMISC |               \
-       FIF_FCSFAIL)
-
-/* FIXME: sc->sc_full_reset ? */
-static void ath9k_configure_filter(struct ieee80211_hw *hw,
-                                  unsigned int changed_flags,
-                                  unsigned int *total_flags,
-                                  int mc_count,
-                                  struct dev_mc_list *mclist)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       u32 rfilt;
-
-       changed_flags &= SUPPORTED_FILTERS;
-       *total_flags &= SUPPORTED_FILTERS;
-
-       sc->rx.rxfilter = *total_flags;
-       rfilt = ath_calcrxfilter(sc);
-       ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
-}
-
-static void ath9k_sta_notify(struct ieee80211_hw *hw,
-                            struct ieee80211_vif *vif,
-                            enum sta_notify_cmd cmd,
-                            struct ieee80211_sta *sta)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       switch (cmd) {
-       case STA_NOTIFY_ADD:
-               ath_node_attach(sc, sta);
-               break;
-       case STA_NOTIFY_REMOVE:
-               ath_node_detach(sc, sta);
-               break;
-       default:
-               break;
-       }
-}
-
-static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
-                        const struct ieee80211_tx_queue_params *params)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath9k_tx_queue_info qi;
-       int ret = 0, qnum;
-
-       if (queue >= WME_NUM_AC)
-               return 0;
-
-       mutex_lock(&sc->mutex);
-
-       memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
-
-       qi.tqi_aifs = params->aifs;
-       qi.tqi_cwmin = params->cw_min;
-       qi.tqi_cwmax = params->cw_max;
-       qi.tqi_burstTime = params->txop;
-       qnum = ath_get_hal_qnum(queue, sc);
-
-       DPRINTF(sc, ATH_DBG_CONFIG,
-               "Configure tx [queue/halq] [%d/%d],  "
-               "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
-               queue, qnum, params->aifs, params->cw_min,
-               params->cw_max, params->txop);
-
-       ret = ath_txq_update(sc, qnum, &qi);
-       if (ret)
-               DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n");
-
-       mutex_unlock(&sc->mutex);
-
-       return ret;
-}
-
-static int ath9k_set_key(struct ieee80211_hw *hw,
-                        enum set_key_cmd cmd,
-                        struct ieee80211_vif *vif,
-                        struct ieee80211_sta *sta,
-                        struct ieee80211_key_conf *key)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       int ret = 0;
-
-       if (modparam_nohwcrypt)
-               return -ENOSPC;
-
-       mutex_lock(&sc->mutex);
-       ath9k_ps_wakeup(sc);
-       DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n");
-
-       switch (cmd) {
-       case SET_KEY:
-               ret = ath_key_config(sc, vif, sta, key);
-               if (ret >= 0) {
-                       key->hw_key_idx = ret;
-                       /* push IV and Michael MIC generation to stack */
-                       key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-                       if (key->alg == ALG_TKIP)
-                               key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-                       if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
-                               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
-                       ret = 0;
-               }
-               break;
-       case DISABLE_KEY:
-               ath_key_delete(sc, key);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       ath9k_ps_restore(sc);
-       mutex_unlock(&sc->mutex);
-
-       return ret;
-}
-
-static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
-                                  struct ieee80211_vif *vif,
-                                  struct ieee80211_bss_conf *bss_conf,
-                                  u32 changed)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-
-       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
-                       bss_conf->use_short_preamble);
-               if (bss_conf->use_short_preamble)
-                       sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
-               else
-                       sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
-       }
-
-       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
-                       bss_conf->use_cts_prot);
-               if (bss_conf->use_cts_prot &&
-                   hw->conf.channel->band != IEEE80211_BAND_5GHZ)
-                       sc->sc_flags |= SC_OP_PROTECT_ENABLE;
-               else
-                       sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
-       }
-
-       if (changed & BSS_CHANGED_ASSOC) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
-                       bss_conf->assoc);
-               ath9k_bss_assoc_info(sc, vif, bss_conf);
-       }
-
-       mutex_unlock(&sc->mutex);
-}
-
-static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
-{
-       u64 tsf;
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-       tsf = ath9k_hw_gettsf64(sc->sc_ah);
-       mutex_unlock(&sc->mutex);
-
-       return tsf;
-}
-
-static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-       ath9k_hw_settsf64(sc->sc_ah, tsf);
-       mutex_unlock(&sc->mutex);
-}
-
-static void ath9k_reset_tsf(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-       ath9k_hw_reset_tsf(sc->sc_ah);
-       mutex_unlock(&sc->mutex);
-}
-
-static int ath9k_ampdu_action(struct ieee80211_hw *hw,
-                             enum ieee80211_ampdu_mlme_action action,
-                             struct ieee80211_sta *sta,
-                             u16 tid, u16 *ssn)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       int ret = 0;
-
-       switch (action) {
-       case IEEE80211_AMPDU_RX_START:
-               if (!(sc->sc_flags & SC_OP_RXAGGR))
-                       ret = -ENOTSUPP;
-               break;
-       case IEEE80211_AMPDU_RX_STOP:
-               break;
-       case IEEE80211_AMPDU_TX_START:
-               ret = ath_tx_aggr_start(sc, sta, tid, ssn);
-               if (ret < 0)
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Unable to start TX aggregation\n");
-               else
-                       ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
-               break;
-       case IEEE80211_AMPDU_TX_STOP:
-               ret = ath_tx_aggr_stop(sc, sta, tid);
-               if (ret < 0)
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Unable to stop TX aggregation\n");
-
-               ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
-               break;
-       case IEEE80211_AMPDU_TX_OPERATIONAL:
-               ath_tx_aggr_resume(sc, sta, tid);
-               break;
-       default:
-               DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n");
-       }
-
-       return ret;
-}
-
-static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       if (ath9k_wiphy_scanning(sc)) {
-               printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
-                      "same time\n");
-               /*
-                * Do not allow the concurrent scanning state for now. This
-                * could be improved with scanning control moved into ath9k.
-                */
-               return;
-       }
-
-       aphy->state = ATH_WIPHY_SCAN;
-       ath9k_wiphy_pause_all_forced(sc, aphy);
-
-       mutex_lock(&sc->mutex);
-       sc->sc_flags |= SC_OP_SCANNING;
-       mutex_unlock(&sc->mutex);
-}
-
-static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-       aphy->state = ATH_WIPHY_ACTIVE;
-       sc->sc_flags &= ~SC_OP_SCANNING;
-       mutex_unlock(&sc->mutex);
-}
-
-struct ieee80211_ops ath9k_ops = {
-       .tx                 = ath9k_tx,
-       .start              = ath9k_start,
-       .stop               = ath9k_stop,
-       .add_interface      = ath9k_add_interface,
-       .remove_interface   = ath9k_remove_interface,
-       .config             = ath9k_config,
-       .config_interface   = ath9k_config_interface,
-       .configure_filter   = ath9k_configure_filter,
-       .sta_notify         = ath9k_sta_notify,
-       .conf_tx            = ath9k_conf_tx,
-       .bss_info_changed   = ath9k_bss_info_changed,
-       .set_key            = ath9k_set_key,
-       .get_tsf            = ath9k_get_tsf,
-       .set_tsf            = ath9k_set_tsf,
-       .reset_tsf          = ath9k_reset_tsf,
-       .ampdu_action       = ath9k_ampdu_action,
-       .sw_scan_start      = ath9k_sw_scan_start,
-       .sw_scan_complete   = ath9k_sw_scan_complete,
-};
-
-static struct {
-       u32 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 {
-       u16 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.
- */
-const char *
-ath_mac_bb_name(u32 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.
- */
-const char *
-ath_rf_name(u16 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 int __init ath9k_init(void)
-{
-       int error;
-
-       /* Register rate control algorithm */
-       error = ath_rate_control_register();
-       if (error != 0) {
-               printk(KERN_ERR
-                       "ath9k: Unable to register rate control "
-                       "algorithm: %d\n",
-                       error);
-               goto err_out;
-       }
-
-       error = ath9k_debug_create_root();
-       if (error) {
-               printk(KERN_ERR
-                       "ath9k: Unable to create debugfs root: %d\n",
-                       error);
-               goto err_rate_unregister;
-       }
-
-       error = ath_pci_init();
-       if (error < 0) {
-               printk(KERN_ERR
-                       "ath9k: No PCI devices found, driver not installed.\n");
-               error = -ENODEV;
-               goto err_remove_root;
-       }
-
-       error = ath_ahb_init();
-       if (error < 0) {
-               error = -ENODEV;
-               goto err_pci_exit;
-       }
-
-       return 0;
-
- err_pci_exit:
-       ath_pci_exit();
-
- err_remove_root:
-       ath9k_debug_remove_root();
- err_rate_unregister:
-       ath_rate_control_unregister();
- err_out:
-       return error;
-}
-module_init(ath9k_init);
-
-static void __exit ath9k_exit(void)
-{
-       ath_ahb_exit();
-       ath_pci_exit();
-       ath9k_debug_remove_root();
-       ath_rate_control_unregister();
-       printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
-}
-module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
deleted file mode 100644 (file)
index 6dbc585..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 <linux/nl80211.h>
-#include <linux/pci.h>
-#include "ath9k.h"
-
-static struct pci_device_id ath_pci_id_table[] __devinitdata = {
-       { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
-       { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
-       { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
-       { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
-       { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
-       { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
-       { 0 }
-};
-
-/* return bus cachesize in 4B word units */
-static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
-{
-       u8 u8tmp;
-
-       pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
-                            (u8 *)&u8tmp);
-       *csz = (int)u8tmp;
-
-       /*
-        * This check was put in to avoid "unplesant" consequences if
-        * the bootrom has not fully initialized all PCI devices.
-        * Sometimes the cache line size register is not set
-        */
-
-       if (*csz == 0)
-               *csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
-}
-
-static void ath_pci_cleanup(struct ath_softc *sc)
-{
-       struct pci_dev *pdev = to_pci_dev(sc->dev);
-
-       pci_iounmap(pdev, sc->mem);
-       pci_disable_device(pdev);
-       pci_release_region(pdev, 0);
-}
-
-static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *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,
-                          AH_WAIT_TIMEOUT)) {
-               return false;
-       }
-
-       *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
-                  AR_EEPROM_STATUS_DATA_VAL);
-
-       return true;
-}
-
-static struct ath_bus_ops ath_pci_bus_ops = {
-       .read_cachesize = ath_pci_read_cachesize,
-       .cleanup = ath_pci_cleanup,
-       .eeprom_read = ath_pci_eeprom_read,
-};
-
-static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-       void __iomem *mem;
-       struct ath_wiphy *aphy;
-       struct ath_softc *sc;
-       struct ieee80211_hw *hw;
-       u8 csz;
-       int ret = 0;
-       struct ath_hw *ah;
-
-       if (pci_enable_device(pdev))
-               return -EIO;
-
-       ret =  pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-
-       if (ret) {
-               printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
-               goto bad;
-       }
-
-       ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
-
-       if (ret) {
-               printk(KERN_ERR "ath9k: 32-bit DMA consistent "
-                       "DMA enable failed\n");
-               goto bad;
-       }
-
-       /*
-        * Cache line size is used to size and align various
-        * structures used to communicate with the hardware.
-        */
-       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
-       if (csz == 0) {
-               /*
-                * Linux 2.4.18 (at least) writes the cache line size
-                * register as a 16-bit wide register which is wrong.
-                * We must have this setup properly for rx buffer
-                * DMA to work so force a reasonable value here if it
-                * comes up zero.
-                */
-               csz = L1_CACHE_BYTES / sizeof(u32);
-               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
-       }
-       /*
-        * The default setting of latency timer yields poor results,
-        * set it to the value used by other systems. It may be worth
-        * tweaking this setting more.
-        */
-       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
-       pci_set_master(pdev);
-
-       ret = pci_request_region(pdev, 0, "ath9k");
-       if (ret) {
-               dev_err(&pdev->dev, "PCI memory region reserve error\n");
-               ret = -ENODEV;
-               goto bad;
-       }
-
-       mem = pci_iomap(pdev, 0, 0);
-       if (!mem) {
-               printk(KERN_ERR "PCI memory map error\n") ;
-               ret = -EIO;
-               goto bad1;
-       }
-
-       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
-                               sizeof(struct ath_softc), &ath9k_ops);
-       if (hw == NULL) {
-               printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
-               goto bad2;
-       }
-
-       SET_IEEE80211_DEV(hw, &pdev->dev);
-       pci_set_drvdata(pdev, hw);
-
-       aphy = hw->priv;
-       sc = (struct ath_softc *) (aphy + 1);
-       aphy->sc = sc;
-       aphy->hw = hw;
-       sc->pri_wiphy = aphy;
-       sc->hw = hw;
-       sc->dev = &pdev->dev;
-       sc->mem = mem;
-       sc->bus_ops = &ath_pci_bus_ops;
-
-       if (ath_attach(id->device, sc) != 0) {
-               ret = -ENODEV;
-               goto bad3;
-       }
-
-       /* setup interrupt service routine */
-
-       if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
-               printk(KERN_ERR "%s: request_irq failed\n",
-                       wiphy_name(hw->wiphy));
-               ret = -EIO;
-               goto bad4;
-       }
-
-       sc->irq = pdev->irq;
-
-       ah = sc->sc_ah;
-       printk(KERN_INFO
-              "%s: Atheros AR%s MAC/BB Rev:%x "
-              "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
-              wiphy_name(hw->wiphy),
-              ath_mac_bb_name(ah->hw_version.macVersion),
-              ah->hw_version.macRev,
-              ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
-              ah->hw_version.phyRev,
-              (unsigned long)mem, pdev->irq);
-
-       return 0;
-bad4:
-       ath_detach(sc);
-bad3:
-       ieee80211_free_hw(hw);
-bad2:
-       pci_iounmap(pdev, mem);
-bad1:
-       pci_release_region(pdev, 0);
-bad:
-       pci_disable_device(pdev);
-       return ret;
-}
-
-static void ath_pci_remove(struct pci_dev *pdev)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       ath_cleanup(sc);
-}
-
-#ifdef CONFIG_PM
-
-static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-#endif
-
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       return 0;
-}
-
-static int ath_pci_resume(struct pci_dev *pdev)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       int err;
-
-       err = pci_enable_device(pdev);
-       if (err)
-               return err;
-       pci_restore_state(pdev);
-
-       /* Enable LED */
-       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
-                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       /*
-        * check the h/w rfkill state on resume
-        * and start the rfkill poll timer
-        */
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               queue_delayed_work(sc->hw->workqueue,
-                                  &sc->rf_kill.rfkill_poll, 0);
-#endif
-
-       return 0;
-}
-
-#endif /* CONFIG_PM */
-
-MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
-
-static struct pci_driver ath_pci_driver = {
-       .name       = "ath9k",
-       .id_table   = ath_pci_id_table,
-       .probe      = ath_pci_probe,
-       .remove     = ath_pci_remove,
-#ifdef CONFIG_PM
-       .suspend    = ath_pci_suspend,
-       .resume     = ath_pci_resume,
-#endif /* CONFIG_PM */
-};
-
-int ath_pci_init(void)
-{
-       return pci_register_driver(&ath_pci_driver);
-}
-
-void ath_pci_exit(void)
-{
-       pci_unregister_driver(&ath_pci_driver);
-}
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c
deleted file mode 100644 (file)
index 5ec9ce9..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-void
-ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
-                   int regWrites)
-{
-       REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
-}
-
-bool
-ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       u32 channelSel = 0;
-       u32 bModeSynth = 0;
-       u32 aModeRefSel = 0;
-       u32 reg32 = 0;
-       u16 freq;
-       struct chan_centers centers;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = centers.synth_center;
-
-       if (freq < 4800) {
-               u32 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 {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Invalid channel %u MHz\n", freq);
-                       return 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 {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Invalid channel %u MHz\n", freq);
-               return false;
-       }
-
-       reg32 =
-           (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
-           (1 << 5) | 0x1;
-
-       REG_WRITE(ah, AR_PHY(0x37), reg32);
-
-       ah->curchan = chan;
-       ah->curchan_rad_index = -1;
-
-       return true;
-}
-
-bool
-ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
-                           struct ath9k_channel *chan)
-{
-       u16 bMode, fracMode, aModeRefSel = 0;
-       u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
-       struct chan_centers centers;
-       u32 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) {
-               u32 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;
-
-               switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
-               case 0:
-                       if ((freq % 20) == 0) {
-                               aModeRefSel = 3;
-                       } else if ((freq % 10) == 0) {
-                               aModeRefSel = 2;
-                       }
-                       if (aModeRefSel)
-                               break;
-               case 1:
-               default:
-                       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->curchan = chan;
-       ah->curchan_rad_index = -1;
-
-       return true;
-}
-
-static void
-ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
-                          u32 numBits, u32 firstBit,
-                          u32 column)
-{
-       u32 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++;
-       }
-}
-
-bool
-ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-                    u16 modesIndex)
-{
-       u32 eepMinorRev;
-       u32 ob5GHz = 0, db5GHz = 0;
-       u32 ob2GHz = 0, db2GHz = 0;
-       int regWrites = 0;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               return true;
-
-       eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
-
-       RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
-
-       RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
-
-       RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
-
-       RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
-                     modesIndex);
-       {
-               int i;
-               for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
-                       ah->analogBank6Data[i] =
-                           INI_RA(&ah->iniBank6TPC, i, modesIndex);
-               }
-       }
-
-       if (eepMinorRev >= 2) {
-               if (IS_CHAN_2GHZ(chan)) {
-                       ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
-                       db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  ob2GHz, 3, 197, 0);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  db2GHz, 3, 194, 0);
-               } else {
-                       ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
-                       db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  ob5GHz, 3, 203, 0);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  db5GHz, 3, 200, 0);
-               }
-       }
-
-       RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
-
-       REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
-                          regWrites);
-
-       return true;
-}
-
-void
-ath9k_hw_rfdetach(struct ath_hw *ah)
-{
-       if (ah->analogBank0Data != NULL) {
-               kfree(ah->analogBank0Data);
-               ah->analogBank0Data = NULL;
-       }
-       if (ah->analogBank1Data != NULL) {
-               kfree(ah->analogBank1Data);
-               ah->analogBank1Data = NULL;
-       }
-       if (ah->analogBank2Data != NULL) {
-               kfree(ah->analogBank2Data);
-               ah->analogBank2Data = NULL;
-       }
-       if (ah->analogBank3Data != NULL) {
-               kfree(ah->analogBank3Data);
-               ah->analogBank3Data = NULL;
-       }
-       if (ah->analogBank6Data != NULL) {
-               kfree(ah->analogBank6Data);
-               ah->analogBank6Data = NULL;
-       }
-       if (ah->analogBank6TPCData != NULL) {
-               kfree(ah->analogBank6TPCData);
-               ah->analogBank6TPCData = NULL;
-       }
-       if (ah->analogBank7Data != NULL) {
-               kfree(ah->analogBank7Data);
-               ah->analogBank7Data = NULL;
-       }
-       if (ah->addac5416_21 != NULL) {
-               kfree(ah->addac5416_21);
-               ah->addac5416_21 = NULL;
-       }
-       if (ah->bank6Temp != NULL) {
-               kfree(ah->bank6Temp);
-               ah->bank6Temp = NULL;
-       }
-}
-
-bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
-{
-       if (!AR_SREV_9280_10_OR_LATER(ah)) {
-               ah->analogBank0Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank0.ia_rows), GFP_KERNEL);
-               ah->analogBank1Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank1.ia_rows), GFP_KERNEL);
-               ah->analogBank2Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank2.ia_rows), GFP_KERNEL);
-               ah->analogBank3Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank3.ia_rows), GFP_KERNEL);
-               ah->analogBank6Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank6.ia_rows), GFP_KERNEL);
-               ah->analogBank6TPCData =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank6TPC.ia_rows), GFP_KERNEL);
-               ah->analogBank7Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank7.ia_rows), GFP_KERNEL);
-
-               if (ah->analogBank0Data == NULL
-                   || ah->analogBank1Data == NULL
-                   || ah->analogBank2Data == NULL
-                   || ah->analogBank3Data == NULL
-                   || ah->analogBank6Data == NULL
-                   || ah->analogBank6TPCData == NULL
-                   || ah->analogBank7Data == NULL) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Cannot allocate RF banks\n");
-                       *status = -ENOMEM;
-                       return false;
-               }
-
-               ah->addac5416_21 =
-                   kzalloc((sizeof(u32) *
-                            ah->iniAddac.ia_rows *
-                            ah->iniAddac.ia_columns), GFP_KERNEL);
-               if (ah->addac5416_21 == NULL) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Cannot allocate addac5416_21\n");
-                       *status = -ENOMEM;
-                       return false;
-               }
-
-               ah->bank6Temp =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank6.ia_rows), GFP_KERNEL);
-               if (ah->bank6Temp == NULL) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Cannot allocate bank6Temp\n");
-                       *status = -ENOMEM;
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-void
-ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       int i, regWrites = 0;
-       u32 bank6SelMask;
-       u32 *bank6Temp = ah->bank6Temp;
-
-       switch (ah->diversity_control) {
-       case ATH9K_ANT_FIXED_A:
-               bank6SelMask =
-                   (ah->
-                    antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
-                   REDUCE_CHAIN_1;
-               break;
-       case ATH9K_ANT_FIXED_B:
-               bank6SelMask =
-                   (ah->
-                    antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
-                   REDUCE_CHAIN_0;
-               break;
-       case ATH9K_ANT_VARIABLE:
-               return;
-               break;
-       default:
-               return;
-               break;
-       }
-
-       for (i = 0; i < ah->iniBank6.ia_rows; i++)
-               bank6Temp[i] = 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(&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
-}
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
deleted file mode 100644 (file)
index 296d0e9..0000000
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 PHY_H
-#define PHY_H
-
-bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
-                                struct ath9k_channel
-                                *chan);
-bool ath9k_hw_set_channel(struct ath_hw *ah,
-                         struct ath9k_channel *chan);
-void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
-                        u32 freqIndex, int regWrites);
-bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
-                         struct ath9k_channel *chan,
-                         u16 modesIndex);
-void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
-                                  struct ath9k_channel *chan);
-bool ath9k_hw_init_rf(struct ath_hw *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_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
-#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
-
-#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_TPCRG1_PD_CAL_ENABLE   0x00400000
-#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
-
-#define AR_PHY_TX_PWRCTRL4       0xa264
-#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
-#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
-#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
-#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
-
-#define AR_PHY_TX_PWRCTRL6_0     0xa270
-#define AR_PHY_TX_PWRCTRL6_1     0xb270
-#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
-#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
-
-#define AR_PHY_TX_PWRCTRL7       0xa274
-#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
-#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
-
-#define AR_PHY_TX_PWRCTRL9       0xa27C
-#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
-#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
-
-#define AR_PHY_TX_GAIN_TBL1      0xa300
-#define AR_PHY_TX_GAIN                     0x0007F000
-#define AR_PHY_TX_GAIN_S                   12
-
-#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
-
-/* Carrier leak calibration control, do it after AGC calibration */
-#define AR_PHY_CL_CAL_CTL       0xA358
-#define AR_PHY_CL_CAL_ENABLE    0x00000002
-#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
-
-#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]); \
-                       DO_DELAY(regWr);                                \
-               }                                                       \
-       } while (0)
-
-#define ATH9K_IS_MIC_ENABLED(ah)                                       \
-       ((ah)->sta_id1_defaults & 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);;     \
-       } while (0)
-
-#endif
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
deleted file mode 100644 (file)
index a13668b..0000000
+++ /dev/null
@@ -1,1752 +0,0 @@
-/*
- * Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2004-2009 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 "ath9k.h"
-
-static struct ath_rate_table ar5416_11na_ratetable = {
-       42,
-       {
-               { 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.5 Mb */
-                       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, /* 150 Mb */
-                       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,
-       {
-               { 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,
-       {
-               { 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,
-       {
-               { 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,
-       {
-               { 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 inline int8_t median(int8_t a, int8_t b, int8_t c)
-{
-       if (a >= b) {
-               if (b >= c)
-                       return b;
-               else if (a > c)
-                       return c;
-               else
-                       return a;
-       } else {
-               if (a >= c)
-                       return a;
-               else if (b >= c)
-                       return c;
-               else
-                       return b;
-       }
-}
-
-static void ath_rc_sort_validrates(struct ath_rate_table *rate_table,
-                                  struct ath_rate_priv *ath_rc_priv)
-{
-       u8 i, j, idx, idx_next;
-
-       for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
-               for (j = 0; j <= i-1; j++) {
-                       idx = ath_rc_priv->valid_rate_index[j];
-                       idx_next = ath_rc_priv->valid_rate_index[j+1];
-
-                       if (rate_table->info[idx].ratekbps >
-                               rate_table->info[idx_next].ratekbps) {
-                               ath_rc_priv->valid_rate_index[j] = idx_next;
-                               ath_rc_priv->valid_rate_index[j+1] = idx;
-                       }
-               }
-       }
-}
-
-static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
-{
-       u8 i;
-
-       for (i = 0; i < ath_rc_priv->rate_table_size; i++)
-               ath_rc_priv->valid_rate_index[i] = 0;
-}
-
-static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
-                                          u8 index, int valid_tx_rate)
-{
-       ASSERT(index <= ath_rc_priv->rate_table_size);
-       ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
-}
-
-static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
-                                       u8 index)
-{
-       ASSERT(index <= ath_rc_priv->rate_table_size);
-       return ath_rc_priv->valid_rate_index[index];
-}
-
-static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
-                                             struct ath_rate_priv *ath_rc_priv,
-                                             u8 cur_valid_txrate,
-                                             u8 *next_idx)
-{
-       u8 i;
-
-       for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) {
-               if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
-                       *next_idx = ath_rc_priv->valid_rate_index[i+1];
-                       return 1;
-               }
-       }
-
-       /* No more valid rates */
-       *next_idx = 0;
-
-       return 0;
-}
-
-/* Return true only for single stream */
-
-static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
-{
-       if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
-               return 0;
-       if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
-               return 0;
-       if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
-               return 0;
-       if (!ignore_cw && WLAN_RC_PHY_HT(phy))
-               if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
-                       return 0;
-               if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
-                       return 0;
-       return 1;
-}
-
-static inline int
-ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
-                                struct ath_rate_priv *ath_rc_priv,
-                                u8 cur_valid_txrate, u8 *next_idx)
-{
-       int8_t i;
-
-       for (i = 1; i < ath_rc_priv->max_valid_rate ; i++) {
-               if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
-                       *next_idx = ath_rc_priv->valid_rate_index[i-1];
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
-                                struct ath_rate_table *rate_table,
-                                u32 capflag)
-{
-       u8 i, hi = 0;
-       u32 valid;
-
-       for (i = 0; i < rate_table->rate_cnt; i++) {
-               valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
-                        rate_table->info[i].valid_single_stream :
-                        rate_table->info[i].valid);
-               if (valid == 1) {
-                       u32 phy = rate_table->info[i].phy;
-                       u8 valid_rate_count = 0;
-
-                       if (!ath_rc_valid_phyrate(phy, capflag, 0))
-                               continue;
-
-                       valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
-
-                       ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
-                       ath_rc_priv->valid_phy_ratecnt[phy] += 1;
-                       ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
-                       hi = A_MAX(hi, i);
-               }
-       }
-
-       return hi;
-}
-
-static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
-                               struct ath_rate_table *rate_table,
-                               struct ath_rateset *rateset,
-                               u32 capflag)
-{
-       u8 i, j, hi = 0;
-
-       /* Use intersection of working rates and valid rates */
-       for (i = 0; i < rateset->rs_nrates; i++) {
-               for (j = 0; j < rate_table->rate_cnt; j++) {
-                       u32 phy = rate_table->info[j].phy;
-                       u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
-                                    rate_table->info[j].valid_single_stream :
-                                    rate_table->info[j].valid);
-                       u8 rate = rateset->rs_rates[i];
-                       u8 dot11rate = rate_table->info[j].dot11rate;
-
-                       /* We allow a rate only if its valid and the
-                        * capflag matches one of the validity
-                        * (VALID/VALID_20/VALID_40) flags */
-
-                       if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
-                           ((valid & WLAN_RC_CAP_MODE(capflag)) ==
-                            WLAN_RC_CAP_MODE(capflag)) &&
-                           !WLAN_RC_PHY_HT(phy)) {
-                               u8 valid_rate_count = 0;
-
-                               if (!ath_rc_valid_phyrate(phy, capflag, 0))
-                                       continue;
-
-                               valid_rate_count =
-                                       ath_rc_priv->valid_phy_ratecnt[phy];
-
-                               ath_rc_priv->valid_phy_rateidx[phy]
-                                       [valid_rate_count] = j;
-                               ath_rc_priv->valid_phy_ratecnt[phy] += 1;
-                               ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
-                               hi = A_MAX(hi, j);
-                       }
-               }
-       }
-
-       return hi;
-}
-
-static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
-                                 struct ath_rate_table *rate_table,
-                                 u8 *mcs_set, u32 capflag)
-{
-       struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
-
-       u8 i, j, hi = 0;
-
-       /* Use intersection of working rates and valid rates */
-       for (i = 0; i < rateset->rs_nrates; i++) {
-               for (j = 0; j < rate_table->rate_cnt; j++) {
-                       u32 phy = rate_table->info[j].phy;
-                       u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
-                                    rate_table->info[j].valid_single_stream :
-                                    rate_table->info[j].valid);
-                       u8 rate = rateset->rs_rates[i];
-                       u8 dot11rate = rate_table->info[j].dot11rate;
-
-                       if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
-                           !WLAN_RC_PHY_HT(phy) ||
-                           !WLAN_RC_PHY_HT_VALID(valid, capflag))
-                               continue;
-
-                       if (!ath_rc_valid_phyrate(phy, capflag, 0))
-                               continue;
-
-                       ath_rc_priv->valid_phy_rateidx[phy]
-                               [ath_rc_priv->valid_phy_ratecnt[phy]] = j;
-                       ath_rc_priv->valid_phy_ratecnt[phy] += 1;
-                       ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
-                       hi = A_MAX(hi, j);
-               }
-       }
-
-       return hi;
-}
-
-static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
-                            struct ath_rate_priv *ath_rc_priv,
-                            struct ath_rate_table *rate_table,
-                            int *is_probing)
-{
-       u32 dt, best_thruput, this_thruput, now_msec;
-       u8 rate, next_rate, best_rate, maxindex, minindex;
-       int8_t  rssi_last, rssi_reduce = 0, index = 0;
-
-       *is_probing = 0;
-
-       rssi_last = median(ath_rc_priv->rssi_last,
-                          ath_rc_priv->rssi_last_prev,
-                          ath_rc_priv->rssi_last_prev2);
-
-       /*
-        * Age (reduce) last ack rssi based on how old it is.
-        * The bizarre numbers are so the delta is 160msec,
-        * meaning we divide by 16.
-        *   0msec   <= dt <= 25msec:   don't derate
-        *   25msec  <= dt <= 185msec:  derate linearly from 0 to 10dB
-        *   185msec <= dt:             derate by 10dB
-        */
-
-       now_msec = jiffies_to_msecs(jiffies);
-       dt = now_msec - ath_rc_priv->rssi_time;
-
-       if (dt >= 185)
-               rssi_reduce = 10;
-       else if (dt >= 25)
-               rssi_reduce = (u8)((dt - 25) >> 4);
-
-       /* Now reduce rssi_last by rssi_reduce */
-       if (rssi_last < rssi_reduce)
-               rssi_last = 0;
-       else
-               rssi_last -= rssi_reduce;
-
-       /*
-        * Now look up the rate in the rssi table and return it.
-        * If no rates match then we return 0 (lowest rate)
-        */
-
-       best_thruput = 0;
-       maxindex = ath_rc_priv->max_valid_rate-1;
-
-       minindex = 0;
-       best_rate = minindex;
-
-       /*
-        * Try the higher rate first. It will reduce memory moving time
-        * if we have very good channel characteristics.
-        */
-       for (index = maxindex; index >= minindex ; index--) {
-               u8 per_thres;
-
-               rate = ath_rc_priv->valid_rate_index[index];
-               if (rate > ath_rc_priv->rate_max_phy)
-                       continue;
-
-               /*
-                * For TCP the average collision rate is around 11%,
-                * so we ignore PERs less than this.  This is to
-                * prevent the rate we are currently using (whose
-                * PER might be in the 10-15 range because of TCP
-                * collisions) looking worse than the next lower
-                * rate whose PER has decayed close to 0.  If we
-                * used to next lower rate, its PER would grow to
-                * 10-15 and we would be worse off then staying
-                * at the current rate.
-                */
-               per_thres = ath_rc_priv->state[rate].per;
-               if (per_thres < 12)
-                       per_thres = 12;
-
-               this_thruput = rate_table->info[rate].user_ratekbps *
-                       (100 - per_thres);
-
-               if (best_thruput <= this_thruput) {
-                       best_thruput = this_thruput;
-                       best_rate    = rate;
-               }
-       }
-
-       rate = best_rate;
-       ath_rc_priv->rssi_last_lookup = rssi_last;
-
-       /*
-        * Must check the actual rate (ratekbps) to account for
-        * non-monoticity of 11g's rate table
-        */
-
-       if (rate >= ath_rc_priv->rate_max_phy) {
-               rate = ath_rc_priv->rate_max_phy;
-
-               /* Probe the next allowed phy state */
-               if (ath_rc_get_nextvalid_txrate(rate_table,
-                                       ath_rc_priv, rate, &next_rate) &&
-                   (now_msec - ath_rc_priv->probe_time >
-                    rate_table->probe_interval) &&
-                   (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
-                       rate = next_rate;
-                       ath_rc_priv->probe_rate = rate;
-                       ath_rc_priv->probe_time = now_msec;
-                       ath_rc_priv->hw_maxretry_pktcnt = 0;
-                       *is_probing = 1;
-               }
-       }
-
-       if (rate > (ath_rc_priv->rate_table_size - 1))
-               rate = ath_rc_priv->rate_table_size - 1;
-
-       ASSERT((rate_table->info[rate].valid &&
-               (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) ||
-              (rate_table->info[rate].valid_single_stream &&
-               !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)));
-
-       return rate;
-}
-
-static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
-                                  struct ieee80211_tx_rate *rate,
-                                  struct ieee80211_tx_rate_control *txrc,
-                                  u8 tries, u8 rix, int rtsctsenable)
-{
-       rate->count = tries;
-       rate->idx = rix;
-
-       if (txrc->short_preamble)
-               rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
-       if (txrc->rts || rtsctsenable)
-               rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
-       if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
-               rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
-       if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
-               rate->flags |= IEEE80211_TX_RC_SHORT_GI;
-       if (WLAN_RC_PHY_HT(rate_table->info[rix].phy))
-               rate->flags |= IEEE80211_TX_RC_MCS;
-}
-
-static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
-                                  struct ath_rate_table *rate_table,
-                                  struct ieee80211_tx_info *tx_info)
-{
-       struct ieee80211_tx_rate *rates = tx_info->control.rates;
-       int i = 0, rix = 0, cix, enable_g_protection = 0;
-
-       /* get the cix for the lowest valid rix */
-       for (i = 3; i >= 0; i--) {
-               if (rates[i].count && (rates[i].idx >= 0)) {
-                       rix = rates[i].idx;
-                       break;
-               }
-       }
-       cix = rate_table->info[rix].ctrl_rate;
-
-       /* All protection frames are transmited at 2Mb/s for 802.11g,
-        * otherwise we transmit them at 1Mb/s */
-       if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
-           !conf_is_ht(&sc->hw->conf))
-               enable_g_protection = 1;
-
-       /*
-        * If 802.11g protection is enabled, determine whether to use RTS/CTS or
-        * just CTS.  Note that this is only done for OFDM/HT unicast frames.
-        */
-       if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
-           !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-           (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
-            WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
-               rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
-               cix = rate_table->info[enable_g_protection].ctrl_rate;
-       }
-
-       tx_info->control.rts_cts_rate_idx = cix;
-}
-
-static u8 ath_rc_rate_getidx(struct ath_softc *sc,
-                            struct ath_rate_priv *ath_rc_priv,
-                            struct ath_rate_table *rate_table,
-                            u8 rix, u16 stepdown,
-                            u16 min_rate)
-{
-       u32 j;
-       u8 nextindex;
-
-       if (min_rate) {
-               for (j = RATE_TABLE_SIZE; j > 0; j--) {
-                       if (ath_rc_get_nextlowervalid_txrate(rate_table,
-                                               ath_rc_priv, rix, &nextindex))
-                               rix = nextindex;
-                       else
-                               break;
-               }
-       } else {
-               for (j = stepdown; j > 0; j--) {
-                       if (ath_rc_get_nextlowervalid_txrate(rate_table,
-                                               ath_rc_priv, rix, &nextindex))
-                               rix = nextindex;
-                       else
-                               break;
-               }
-       }
-       return rix;
-}
-
-static void ath_rc_ratefind(struct ath_softc *sc,
-                           struct ath_rate_priv *ath_rc_priv,
-                           struct ieee80211_tx_rate_control *txrc)
-{
-       struct ath_rate_table *rate_table;
-       struct sk_buff *skb = txrc->skb;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_rate *rates = tx_info->control.rates;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       __le16 fc = hdr->frame_control;
-       u8 try_per_rate = 0, i = 0, rix, nrix;
-       int is_probe = 0;
-
-       rate_table = sc->cur_rate_table;
-       rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
-       nrix = rix;
-
-       if (is_probe) {
-               /* set one try for probe rates. For the
-                * probes don't enable rts */
-               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
-                                      1, nrix, 0);
-
-               try_per_rate = (ATH_11N_TXMAXTRY/4);
-               /* Get the next tried/allowed rate. No RTS for the next series
-                * after the probe rate
-                */
-               nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
-                                         rate_table, nrix, 1, 0);
-               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
-                                      try_per_rate, nrix, 0);
-
-               tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
-       } else {
-               try_per_rate = (ATH_11N_TXMAXTRY/4);
-               /* Set the choosen rate. No RTS for first series entry. */
-               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
-                                      try_per_rate, nrix, 0);
-       }
-
-       /* Fill in the other rates for multirate retry */
-       for ( ; i < 4; i++) {
-               u8 try_num;
-               u8 min_rate;
-
-               try_num = ((i + 1) == 4) ?
-                       ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
-               min_rate = (((i + 1) == 4) && 0);
-
-               nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
-                                         rate_table, nrix, 1, min_rate);
-               /* All other rates in the series have RTS enabled */
-               ath_rc_rate_set_series(rate_table, &rates[i], txrc,
-                                      try_num, nrix, 1);
-       }
-
-       /*
-        * NB:Change rate series to enable aggregation when operating
-        * at lower MCS rates. When first rate in series is MCS2
-        * in HT40 @ 2.4GHz, series should look like:
-        *
-        * {MCS2, MCS1, MCS0, MCS0}.
-        *
-        * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should
-        * look like:
-        *
-        * {MCS3, MCS2, MCS1, MCS1}
-        *
-        * So, set fourth rate in series to be same as third one for
-        * above conditions.
-        */
-       if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
-           (conf_is_ht(&sc->hw->conf))) {
-               u8 dot11rate = rate_table->info[rix].dot11rate;
-               u8 phy = rate_table->info[rix].phy;
-               if (i == 4 &&
-                   ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
-                    (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
-                       rates[3].idx = rates[2].idx;
-                       rates[3].flags = rates[2].flags;
-               }
-       }
-
-       /*
-        * Force hardware to use computed duration for next
-        * fragment by disabling multi-rate retry, which
-        * updates duration based on the multi-rate duration table.
-        *
-        * FIXME: Fix duration
-        */
-       if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-           (ieee80211_has_morefrags(fc) ||
-            (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
-               rates[1].count = rates[2].count = rates[3].count = 0;
-               rates[1].idx = rates[2].idx = rates[3].idx = 0;
-               rates[0].count = ATH_TXMAXTRY;
-       }
-
-       /* Setup RTS/CTS */
-       ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
-}
-
-static bool ath_rc_update_per(struct ath_softc *sc,
-                             struct ath_rate_table *rate_table,
-                             struct ath_rate_priv *ath_rc_priv,
-                             struct ath_tx_info_priv *tx_info_priv,
-                             int tx_rate, int xretries, int retries,
-                             u32 now_msec)
-{
-       bool state_change = false;
-       int count;
-       u8 last_per;
-       static u32 nretry_to_per_lookup[10] = {
-               100 * 0 / 1,
-               100 * 1 / 4,
-               100 * 1 / 2,
-               100 * 3 / 4,
-               100 * 4 / 5,
-               100 * 5 / 6,
-               100 * 6 / 7,
-               100 * 7 / 8,
-               100 * 8 / 9,
-               100 * 9 / 10
-       };
-
-       last_per = ath_rc_priv->state[tx_rate].per;
-
-       if (xretries) {
-               if (xretries == 1) {
-                       ath_rc_priv->state[tx_rate].per += 30;
-                       if (ath_rc_priv->state[tx_rate].per > 100)
-                               ath_rc_priv->state[tx_rate].per = 100;
-               } else {
-                       /* xretries == 2 */
-                       count = ARRAY_SIZE(nretry_to_per_lookup);
-                       if (retries >= count)
-                               retries = count - 1;
-
-                       /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
-                       ath_rc_priv->state[tx_rate].per =
-                               (u8)(last_per - (last_per >> 3) + (100 >> 3));
-               }
-
-               /* xretries == 1 or 2 */
-
-               if (ath_rc_priv->probe_rate == tx_rate)
-                       ath_rc_priv->probe_rate = 0;
-
-       } else { /* xretries == 0 */
-               count = ARRAY_SIZE(nretry_to_per_lookup);
-               if (retries >= count)
-                       retries = count - 1;
-
-               if (tx_info_priv->n_bad_frames) {
-                       /* new_PER = 7/8*old_PER + 1/8*(currentPER)
-                        * Assuming that n_frames is not 0.  The current PER
-                        * from the retries is 100 * retries / (retries+1),
-                        * since the first retries attempts failed, and the
-                        * next one worked.  For the one that worked,
-                        * n_bad_frames subframes out of n_frames wored,
-                        * so the PER for that part is
-                        * 100 * n_bad_frames / n_frames, and it contributes
-                        * 100 * n_bad_frames / (n_frames * (retries+1)) to
-                        * the above PER.  The expression below is a
-                        * simplified version of the sum of these two terms.
-                        */
-                       if (tx_info_priv->n_frames > 0) {
-                               int n_frames, n_bad_frames;
-                               u8 cur_per, new_per;
-
-                               n_bad_frames = retries * tx_info_priv->n_frames +
-                                       tx_info_priv->n_bad_frames;
-                               n_frames = tx_info_priv->n_frames * (retries + 1);
-                               cur_per = (100 * n_bad_frames / n_frames) >> 3;
-                               new_per = (u8)(last_per - (last_per >> 3) + cur_per);
-                               ath_rc_priv->state[tx_rate].per = new_per;
-                       }
-               } else {
-                       ath_rc_priv->state[tx_rate].per =
-                               (u8)(last_per - (last_per >> 3) +
-                                    (nretry_to_per_lookup[retries] >> 3));
-               }
-
-               ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
-               ath_rc_priv->rssi_last_prev  = ath_rc_priv->rssi_last;
-               ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi;
-               ath_rc_priv->rssi_time = now_msec;
-
-               /*
-                * If we got at most one retry then increase the max rate if
-                * this was a probe.  Otherwise, ignore the probe.
-                */
-               if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
-                       if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
-                               tx_info_priv->n_frames) {
-                               /*
-                                * Since we probed with just a single attempt,
-                                * any retries means the probe failed.  Also,
-                                * if the attempt worked, but more than half
-                                * the subframes were bad then also consider
-                                * the probe a failure.
-                                */
-                               ath_rc_priv->probe_rate = 0;
-                       } else {
-                               u8 probe_rate = 0;
-
-                               ath_rc_priv->rate_max_phy =
-                                       ath_rc_priv->probe_rate;
-                               probe_rate = ath_rc_priv->probe_rate;
-
-                               if (ath_rc_priv->state[probe_rate].per > 30)
-                                       ath_rc_priv->state[probe_rate].per = 20;
-
-                               ath_rc_priv->probe_rate = 0;
-
-                               /*
-                                * Since this probe succeeded, we allow the next
-                                * probe twice as soon.  This allows the maxRate
-                                * to move up faster if the probes are
-                                * succesful.
-                                */
-                               ath_rc_priv->probe_time =
-                                       now_msec - rate_table->probe_interval / 2;
-                       }
-               }
-
-               if (retries > 0) {
-                       /*
-                        * Don't update anything.  We don't know if
-                        * this was because of collisions or poor signal.
-                        *
-                        * Later: if rssi_ack is close to
-                        * ath_rc_priv->state[txRate].rssi_thres and we see lots
-                        * of retries, then we could increase
-                        * ath_rc_priv->state[txRate].rssi_thres.
-                        */
-                       ath_rc_priv->hw_maxretry_pktcnt = 0;
-               } else {
-                       int32_t rssi_ackAvg;
-                       int8_t rssi_thres;
-                       int8_t rssi_ack_vmin;
-
-                       /*
-                        * It worked with no retries. First ignore bogus (small)
-                        * rssi_ack values.
-                        */
-                       if (tx_rate == ath_rc_priv->rate_max_phy &&
-                           ath_rc_priv->hw_maxretry_pktcnt < 255) {
-                               ath_rc_priv->hw_maxretry_pktcnt++;
-                       }
-
-                       if (tx_info_priv->tx.ts_rssi <
-                           rate_table->info[tx_rate].rssi_ack_validmin)
-                               goto exit;
-
-                       /* Average the rssi */
-                       if (tx_rate != ath_rc_priv->rssi_sum_rate) {
-                               ath_rc_priv->rssi_sum_rate = tx_rate;
-                               ath_rc_priv->rssi_sum =
-                                       ath_rc_priv->rssi_sum_cnt = 0;
-                       }
-
-                       ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
-                       ath_rc_priv->rssi_sum_cnt++;
-
-                       if (ath_rc_priv->rssi_sum_cnt < 4)
-                               goto exit;
-
-                       rssi_ackAvg =
-                               (ath_rc_priv->rssi_sum + 2) / 4;
-                       rssi_thres =
-                               ath_rc_priv->state[tx_rate].rssi_thres;
-                       rssi_ack_vmin =
-                               rate_table->info[tx_rate].rssi_ack_validmin;
-
-                       ath_rc_priv->rssi_sum =
-                               ath_rc_priv->rssi_sum_cnt = 0;
-
-                       /* Now reduce the current rssi threshold */
-                       if ((rssi_ackAvg < rssi_thres + 2) &&
-                           (rssi_thres > rssi_ack_vmin)) {
-                               ath_rc_priv->state[tx_rate].rssi_thres--;
-                       }
-
-                       state_change = true;
-               }
-       }
-exit:
-       return state_change;
-}
-
-/* Update PER, RSSI and whatever else that the code thinks it is doing.
-   If you can make sense of all this, you really need to go out more. */
-
-static void ath_rc_update_ht(struct ath_softc *sc,
-                            struct ath_rate_priv *ath_rc_priv,
-                            struct ath_tx_info_priv *tx_info_priv,
-                            int tx_rate, int xretries, int retries)
-{
-#define CHK_RSSI(rate)                                 \
-       ((ath_rc_priv->state[(rate)].rssi_thres +       \
-         rate_table->info[(rate)].rssi_ack_deltamin) > \
-        ath_rc_priv->state[(rate)+1].rssi_thres)
-
-       u32 now_msec = jiffies_to_msecs(jiffies);
-       int rate;
-       u8 last_per;
-       bool state_change = false;
-       struct ath_rate_table *rate_table = sc->cur_rate_table;
-       int size = ath_rc_priv->rate_table_size;
-
-       if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
-               return;
-
-       /* To compensate for some imbalance between ctrl and ext. channel */
-
-       if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
-               tx_info_priv->tx.ts_rssi =
-                       tx_info_priv->tx.ts_rssi < 3 ? 0 :
-                       tx_info_priv->tx.ts_rssi - 3;
-
-       last_per = ath_rc_priv->state[tx_rate].per;
-
-       /* Update PER first */
-       state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
-                                        tx_info_priv, tx_rate, xretries,
-                                        retries, now_msec);
-
-       /*
-        * If this rate looks bad (high PER) then stop using it for
-        * a while (except if we are probing).
-        */
-       if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
-           rate_table->info[tx_rate].ratekbps <=
-           rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
-               ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
-                                (u8)tx_rate, &ath_rc_priv->rate_max_phy);
-
-               /* Don't probe for a little while. */
-               ath_rc_priv->probe_time = now_msec;
-       }
-
-       if (state_change) {
-               /*
-                * Make sure the rates above this have higher rssi thresholds.
-                * (Note:  Monotonicity is kept within the OFDM rates and
-                *         within the CCK rates. However, no adjustment is
-                *         made to keep the rssi thresholds monotonically
-                *         increasing between the CCK and OFDM rates.)
-                */
-               for (rate = tx_rate; rate < size - 1; rate++) {
-                       if (rate_table->info[rate+1].phy !=
-                           rate_table->info[tx_rate].phy)
-                               break;
-
-                       if (CHK_RSSI(rate)) {
-                               ath_rc_priv->state[rate+1].rssi_thres =
-                                       ath_rc_priv->state[rate].rssi_thres +
-                                       rate_table->info[rate].rssi_ack_deltamin;
-                       }
-               }
-
-               /* Make sure the rates below this have lower rssi thresholds. */
-               for (rate = tx_rate - 1; rate >= 0; rate--) {
-                       if (rate_table->info[rate].phy !=
-                           rate_table->info[tx_rate].phy)
-                               break;
-
-                       if (CHK_RSSI(rate)) {
-                               if (ath_rc_priv->state[rate+1].rssi_thres <
-                                   rate_table->info[rate].rssi_ack_deltamin)
-                                       ath_rc_priv->state[rate].rssi_thres = 0;
-                               else {
-                                       ath_rc_priv->state[rate].rssi_thres =
-                                       ath_rc_priv->state[rate+1].rssi_thres -
-                                       rate_table->info[rate].rssi_ack_deltamin;
-                               }
-
-                               if (ath_rc_priv->state[rate].rssi_thres <
-                                   rate_table->info[rate].rssi_ack_validmin) {
-                                       ath_rc_priv->state[rate].rssi_thres =
-                                       rate_table->info[rate].rssi_ack_validmin;
-                               }
-                       }
-               }
-       }
-
-       /* Make sure the rates below this have lower PER */
-       /* Monotonicity is kept only for rates below the current rate. */
-       if (ath_rc_priv->state[tx_rate].per < last_per) {
-               for (rate = tx_rate - 1; rate >= 0; rate--) {
-                       if (rate_table->info[rate].phy !=
-                           rate_table->info[tx_rate].phy)
-                               break;
-
-                       if (ath_rc_priv->state[rate].per >
-                           ath_rc_priv->state[rate+1].per) {
-                               ath_rc_priv->state[rate].per =
-                                       ath_rc_priv->state[rate+1].per;
-                       }
-               }
-       }
-
-       /* Maintain monotonicity for rates above the current rate */
-       for (rate = tx_rate; rate < size - 1; rate++) {
-               if (ath_rc_priv->state[rate+1].per <
-                   ath_rc_priv->state[rate].per)
-                       ath_rc_priv->state[rate+1].per =
-                               ath_rc_priv->state[rate].per;
-       }
-
-       /* Every so often, we reduce the thresholds and
-        * PER (different for CCK and OFDM). */
-       if (now_msec - ath_rc_priv->rssi_down_time >=
-           rate_table->rssi_reduce_interval) {
-
-               for (rate = 0; rate < size; rate++) {
-                       if (ath_rc_priv->state[rate].rssi_thres >
-                           rate_table->info[rate].rssi_ack_validmin)
-                               ath_rc_priv->state[rate].rssi_thres -= 1;
-               }
-               ath_rc_priv->rssi_down_time = now_msec;
-       }
-
-       /* Every so often, we reduce the thresholds
-        * and PER (different for CCK and OFDM). */
-       if (now_msec - ath_rc_priv->per_down_time >=
-           rate_table->rssi_reduce_interval) {
-               for (rate = 0; rate < size; rate++) {
-                       ath_rc_priv->state[rate].per =
-                               7 * ath_rc_priv->state[rate].per / 8;
-               }
-
-               ath_rc_priv->per_down_time = now_msec;
-       }
-
-       ath_debug_stat_retries(sc, tx_rate, xretries, retries,
-                              ath_rc_priv->state[tx_rate].per);
-
-#undef CHK_RSSI
-}
-
-static int ath_rc_get_rateindex(struct ath_rate_table *rate_table,
-                               struct ieee80211_tx_rate *rate)
-{
-       int rix;
-
-       if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
-           (rate->flags & IEEE80211_TX_RC_SHORT_GI))
-               rix = rate_table->info[rate->idx].ht_index;
-       else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
-               rix = rate_table->info[rate->idx].sgi_index;
-       else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-               rix = rate_table->info[rate->idx].cw40index;
-       else
-               rix = rate_table->info[rate->idx].base_index;
-
-       return rix;
-}
-
-static void ath_rc_tx_status(struct ath_softc *sc,
-                            struct ath_rate_priv *ath_rc_priv,
-                            struct ieee80211_tx_info *tx_info,
-                            int final_ts_idx, int xretries, int long_retry)
-{
-       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       struct ath_rate_table *rate_table;
-       struct ieee80211_tx_rate *rates = tx_info->status.rates;
-       u8 flags;
-       u32 i = 0, rix;
-
-       rate_table = sc->cur_rate_table;
-
-       /*
-        * If the first rate is not the final index, there
-        * are intermediate rate failures to be processed.
-        */
-       if (final_ts_idx != 0) {
-               /* Process intermediate rates that failed.*/
-               for (i = 0; i < final_ts_idx ; i++) {
-                       if (rates[i].count != 0 && (rates[i].idx >= 0)) {
-                               flags = rates[i].flags;
-
-                               /* If HT40 and we have switched mode from
-                                * 40 to 20 => don't update */
-
-                               if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
-                                   !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
-                                       return;
-
-                               rix = ath_rc_get_rateindex(rate_table, &rates[i]);
-                               ath_rc_update_ht(sc, ath_rc_priv,
-                                               tx_info_priv, rix,
-                                               xretries ? 1 : 2,
-                                               rates[i].count);
-                       }
-               }
-       } else {
-               /*
-                * Handle the special case of MIMO PS burst, where the second
-                * aggregate is sent out with only one rate and one try.
-                * Treating it as an excessive retry penalizes the rate
-                * inordinately.
-                */
-               if (rates[0].count == 1 && xretries == 1)
-                       xretries = 2;
-       }
-
-       flags = rates[i].flags;
-
-       /* If HT40 and we have switched mode from 40 to 20 => don't update */
-       if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
-           !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
-               return;
-
-       rix = ath_rc_get_rateindex(rate_table, &rates[i]);
-       ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
-                        xretries, long_retry);
-}
-
-static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
-                                                   enum ieee80211_band band,
-                                                   bool is_ht, bool is_cw_40)
-{
-       int mode = 0;
-
-       switch(band) {
-       case IEEE80211_BAND_2GHZ:
-               mode = ATH9K_MODE_11G;
-               if (is_ht)
-                       mode = ATH9K_MODE_11NG_HT20;
-               if (is_cw_40)
-                       mode = ATH9K_MODE_11NG_HT40PLUS;
-               break;
-       case IEEE80211_BAND_5GHZ:
-               mode = ATH9K_MODE_11A;
-               if (is_ht)
-                       mode = ATH9K_MODE_11NA_HT20;
-               if (is_cw_40)
-                       mode = ATH9K_MODE_11NA_HT40PLUS;
-               break;
-       default:
-               DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n");
-               return NULL;
-       }
-
-       BUG_ON(mode >= ATH9K_MODE_MAX);
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode);
-       return sc->hw_rate_table[mode];
-}
-
-static void ath_rc_init(struct ath_softc *sc,
-                       struct ath_rate_priv *ath_rc_priv,
-                       struct ieee80211_supported_band *sband,
-                       struct ieee80211_sta *sta,
-                       struct ath_rate_table *rate_table)
-{
-       struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
-       u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
-       u8 i, j, k, hi = 0, hthi = 0;
-
-       if (!rate_table) {
-               DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
-               return;
-       }
-
-       /* Initial rate table size. Will change depending
-        * on the working rate set */
-       ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
-
-       /* Initialize thresholds according to the global rate table */
-       for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
-               ath_rc_priv->state[i].rssi_thres =
-                       rate_table->info[i].rssi_ack_validmin;
-               ath_rc_priv->state[i].per = 0;
-       }
-
-       /* Determine the valid rates */
-       ath_rc_init_valid_txmask(ath_rc_priv);
-
-       for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
-               for (j = 0; j < MAX_TX_RATE_PHY; j++)
-                       ath_rc_priv->valid_phy_rateidx[i][j] = 0;
-               ath_rc_priv->valid_phy_ratecnt[i] = 0;
-       }
-
-       if (!rateset->rs_nrates) {
-               /* No working rate, just initialize valid rates */
-               hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
-                                           ath_rc_priv->ht_cap);
-       } else {
-               /* Use intersection of working rates and valid rates */
-               hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
-                                          rateset, ath_rc_priv->ht_cap);
-               if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
-                       hthi = ath_rc_setvalid_htrates(ath_rc_priv,
-                                                      rate_table,
-                                                      ht_mcs,
-                                                      ath_rc_priv->ht_cap);
-               }
-               hi = A_MAX(hi, hthi);
-       }
-
-       ath_rc_priv->rate_table_size = hi + 1;
-       ath_rc_priv->rate_max_phy = 0;
-       ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
-
-       for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
-               for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
-                       ath_rc_priv->valid_rate_index[k++] =
-                               ath_rc_priv->valid_phy_rateidx[i][j];
-               }
-
-               if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1)
-                   || !ath_rc_priv->valid_phy_ratecnt[i])
-                       continue;
-
-               ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
-       }
-       ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
-       ASSERT(k <= RATE_TABLE_SIZE);
-
-       ath_rc_priv->max_valid_rate = k;
-       ath_rc_sort_validrates(rate_table, ath_rc_priv);
-       ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
-       sc->cur_rate_table = rate_table;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n",
-               ath_rc_priv->ht_cap);
-}
-
-static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
-                              bool is_cw40, bool is_sgi40)
-{
-       u8 caps = 0;
-
-       if (sta->ht_cap.ht_supported) {
-               caps = WLAN_RC_HT_FLAG;
-               if (sc->sc_ah->caps.tx_chainmask != 1 &&
-                   ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
-                       if (sta->ht_cap.mcs.rx_mask[1])
-                               caps |= WLAN_RC_DS_FLAG;
-               }
-               if (is_cw40)
-                       caps |= WLAN_RC_40_FLAG;
-               if (is_sgi40)
-                       caps |= WLAN_RC_SGI_FLAG;
-       }
-
-       return caps;
-}
-
-/***********************************/
-/* mac80211 Rate Control callbacks */
-/***********************************/
-
-static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
-                         struct ieee80211_sta *sta, void *priv_sta,
-                         struct sk_buff *skb)
-{
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *ath_rc_priv = priv_sta;
-       struct ath_tx_info_priv *tx_info_priv = NULL;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr;
-       int final_ts_idx, tx_status = 0, is_underrun = 0;
-       __le16 fc;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       final_ts_idx = tx_info_priv->tx.ts_rateindex;
-
-       if (!priv_sta || !ieee80211_is_data(fc) ||
-           !tx_info_priv->update_rc)
-               goto exit;
-
-       if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
-               goto exit;
-
-       /*
-        * If underrun error is seen assume it as an excessive retry only
-        * if prefetch trigger level have reached the max (0x3f for 5416)
-        * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
-        * times. This affects how ratectrl updates PER for the failed rate.
-        */
-       if (tx_info_priv->tx.ts_flags &
-           (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
-           ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
-               tx_status = 1;
-               is_underrun = 1;
-       }
-
-       if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) ||
-           (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
-               tx_status = 1;
-
-       ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
-                        (is_underrun) ? ATH_11N_TXMAXTRY :
-                        tx_info_priv->tx.ts_longretry);
-
-       /* Check if aggregation has to be enabled for this tid */
-       if (conf_is_ht(&sc->hw->conf) &&
-           !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
-               if (ieee80211_is_data_qos(fc)) {
-                       u8 *qc, tid;
-                       struct ath_node *an;
-
-                       qc = ieee80211_get_qos_ctl(hdr);
-                       tid = qc[0] & 0xf;
-                       an = (struct ath_node *)sta->drv_priv;
-
-                       if(ath_tx_aggr_check(sc, an, tid))
-                               ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid);
-               }
-       }
-
-       ath_debug_stat_rc(sc, skb);
-exit:
-       kfree(tx_info_priv);
-}
-
-static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
-                        struct ieee80211_tx_rate_control *txrc)
-{
-       struct ieee80211_supported_band *sband = txrc->sband;
-       struct sk_buff *skb = txrc->skb;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *ath_rc_priv = priv_sta;
-       __le16 fc = hdr->frame_control;
-
-       /* lowest rate for management and multicast/broadcast frames */
-       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
-           !sta) {
-               tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
-               tx_info->control.rates[0].count =
-                       is_multicast_ether_addr(hdr->addr1) ? 1 : ATH_MGT_TXMAXTRY;
-               return;
-       }
-
-       /* Find tx rate for unicast frames */
-       ath_rc_ratefind(sc, ath_rc_priv, txrc);
-}
-
-static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
-                          struct ieee80211_sta *sta, void *priv_sta)
-{
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *ath_rc_priv = priv_sta;
-       struct ath_rate_table *rate_table = NULL;
-       bool is_cw40, is_sgi40;
-       int i, j = 0;
-
-       for (i = 0; i < sband->n_bitrates; i++) {
-               if (sta->supp_rates[sband->band] & BIT(i)) {
-                       ath_rc_priv->neg_rates.rs_rates[j]
-                               = (sband->bitrates[i].bitrate * 2) / 10;
-                       j++;
-               }
-       }
-       ath_rc_priv->neg_rates.rs_nrates = j;
-
-       if (sta->ht_cap.ht_supported) {
-               for (i = 0, j = 0; i < 77; i++) {
-                       if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
-                               ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
-                       if (j == ATH_RATE_MAX)
-                               break;
-               }
-               ath_rc_priv->neg_ht_rates.rs_nrates = j;
-       }
-
-       is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-       is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
-
-       /* Choose rate table first */
-
-       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
-               rate_table = ath_choose_rate_table(sc, sband->band,
-                                                  sta->ht_cap.ht_supported,
-                                                  is_cw40);
-       } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
-               /* cur_rate_table would be set on init through config() */
-               rate_table = sc->cur_rate_table;
-       }
-
-       ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
-       ath_rc_init(sc, priv_sta, sband, sta, rate_table);
-}
-
-static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
-                           struct ieee80211_sta *sta, void *priv_sta,
-                           u32 changed)
-{
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *ath_rc_priv = priv_sta;
-       struct ath_rate_table *rate_table = NULL;
-       bool oper_cw40 = false, oper_sgi40;
-       bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
-               true : false;
-       bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
-               true : false;
-
-       /* FIXME: Handle AP mode later when we support CWM */
-
-       if (changed & IEEE80211_RC_HT_CHANGED) {
-               if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
-                       return;
-
-               if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
-                   sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
-                       oper_cw40 = true;
-
-               oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
-                       true : false;
-
-               if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
-                       rate_table = ath_choose_rate_table(sc, sband->band,
-                                                  sta->ht_cap.ht_supported,
-                                                  oper_cw40);
-                       ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
-                                                  oper_cw40, oper_sgi40);
-                       ath_rc_init(sc, priv_sta, sband, sta, rate_table);
-
-                       DPRINTF(sc, ATH_DBG_CONFIG,
-                               "Operating HT Bandwidth changed to: %d\n",
-                               sc->hw->conf.channel_type);
-               }
-       }
-}
-
-static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       return aphy->sc;
-}
-
-static void ath_rate_free(void *priv)
-{
-       return;
-}
-
-static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
-{
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *rate_priv;
-
-       rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
-       if (!rate_priv) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to allocate private rc structure\n");
-               return NULL;
-       }
-
-       rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
-       rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
-
-       return rate_priv;
-}
-
-static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
-                             void *priv_sta)
-{
-       struct ath_rate_priv *rate_priv = priv_sta;
-       kfree(rate_priv);
-}
-
-static struct rate_control_ops ath_rate_ops = {
-       .module = NULL,
-       .name = "ath9k_rate_control",
-       .tx_status = ath_tx_status,
-       .get_rate = ath_get_rate,
-       .rate_init = ath_rate_init,
-       .rate_update = ath_rate_update,
-       .alloc = ath_rate_alloc,
-       .free = ath_rate_free,
-       .alloc_sta = ath_rate_alloc_sta,
-       .free_sta = ath_rate_free_sta,
-};
-
-void ath_rate_attach(struct ath_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;
-}
-
-int ath_rate_control_register(void)
-{
-       return ieee80211_rate_control_register(&ath_rate_ops);
-}
-
-void ath_rate_control_unregister(void)
-{
-       ieee80211_rate_control_unregister(&ath_rate_ops);
-}
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
deleted file mode 100644 (file)
index e3abd76..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 2004 Sam Leffler, Errno Consulting
- * Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2008-2009 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 RC_H
-#define RC_H
-
-struct ath_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)
-
-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
-};
-
-#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;
-       struct {
-               int valid;
-               int valid_single_stream;
-               u8 phy;
-               u32 ratekbps;
-               u32 user_ratekbps;
-               u8 ratecode;
-               u8 short_preamble;
-               u8 dot11rate;
-               u8 ctrl_rate;
-               int8_t rssi_ack_validmin;
-               int8_t rssi_ack_deltamin;
-               u8 base_index;
-               u8 cw40index;
-               u8 sgi_index;
-               u8 ht_index;
-               u32 max_4ms_framelen;
-       } info[RATE_TABLE_SIZE];
-       u32 probe_interval;
-       u32 rssi_reduce_interval;
-       u8 initial_ratemax;
-};
-
-struct ath_tx_ratectrl_state {
-       int8_t rssi_thres;      /* required rssi for this rate (dB) */
-       u8 per;                 /* recent estimate of packet error rate (%) */
-};
-
-struct ath_rateset {
-       u8 rs_nrates;
-       u8 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
- * @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;
-       u8 rate_table_size;
-       u8 probe_rate;
-       u8 hw_maxretry_pktcnt;
-       u8 max_valid_rate;
-       u8 valid_rate_index[RATE_TABLE_SIZE];
-       u8 ht_cap;
-       u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
-       u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
-       u8 rate_max_phy;
-       u32 rssi_time;
-       u32 rssi_down_time;
-       u32 probe_time;
-       u32 per_down_time;
-       u32 probe_interval;
-       u32 prev_data_rix;
-       u32 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_rate_softc *asc;
-};
-
-enum ath9k_internal_frame_type {
-       ATH9K_NOT_INTERNAL,
-       ATH9K_INT_PAUSE,
-       ATH9K_INT_UNPAUSE
-};
-
-struct ath_tx_info_priv {
-       struct ath_wiphy *aphy;
-       struct ath_tx_status tx;
-       int n_frames;
-       int n_bad_frames;
-       bool update_rc;
-       enum ath9k_internal_frame_type frame_type;
-};
-
-#define ATH_TX_INFO_PRIV(tx_info) \
-       ((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0]))
-
-void ath_rate_attach(struct ath_softc *sc);
-u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate);
-int ath_rate_control_register(void);
-void ath_rate_control_unregister(void);
-
-#endif /* RC_H */
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
deleted file mode 100644 (file)
index b46badd..0000000
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
-                                            struct ieee80211_hdr *hdr)
-{
-       struct ieee80211_hw *hw = sc->pri_wiphy->hw;
-       int i;
-
-       spin_lock_bh(&sc->wiphy_lock);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-               if (aphy == NULL)
-                       continue;
-               if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr)
-                   == 0) {
-                       hw = aphy->hw;
-                       break;
-               }
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-       return hw;
-}
-
-/*
- * Setup and link descriptors.
- *
- * 11N: we can no longer afford to self link the last descriptor.
- * MAC acknowledges BA status as long as it copies frames to host
- * buffer (or rx fifo). This can incorrectly acknowledge packets
- * to a sender if last desc is self-linked.
- */
-static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_desc *ds;
-       struct sk_buff *skb;
-
-       ATH_RXBUF_RESET(bf);
-
-       ds = bf->bf_desc;
-       ds->ds_link = 0; /* link to null */
-       ds->ds_data = bf->bf_buf_addr;
-
-       /* virtual addr of the beginning of the buffer. */
-       skb = bf->bf_mpdu;
-       ASSERT(skb != NULL);
-       ds->ds_vdata = skb->data;
-
-       /* setup rx descriptors. The rx.bufsize here tells the harware
-        * how much data it can DMA to us and that we are prepared
-        * to process */
-       ath9k_hw_setuprxdesc(ah, ds,
-                            sc->rx.bufsize,
-                            0);
-
-       if (sc->rx.rxlink == NULL)
-               ath9k_hw_putrxbuf(ah, bf->bf_daddr);
-       else
-               *sc->rx.rxlink = bf->bf_daddr;
-
-       sc->rx.rxlink = &ds->ds_link;
-       ath9k_hw_rxena(ah);
-}
-
-static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
-{
-       /* XXX block beacon interrupts */
-       ath9k_hw_setantenna(sc->sc_ah, antenna);
-       sc->rx.defant = antenna;
-       sc->rx.rxotherant = 0;
-}
-
-/*
- *  Extend 15-bit time stamp from rx descriptor to
- *  a full 64-bit TSF using the current h/w TSF.
-*/
-static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
-{
-       u64 tsf;
-
-       tsf = ath9k_hw_gettsf64(sc->sc_ah);
-       if ((tsf & 0x7fff) < rstamp)
-               tsf -= 0x8000;
-       return (tsf & ~0x7fff) | rstamp;
-}
-
-static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
-{
-       struct sk_buff *skb;
-       u32 off;
-
-       /*
-        * Cache-line-align.  This is important (for the
-        * 5210 at least) as not doing so causes bogus data
-        * in rx'd frames.
-        */
-
-       /* Note: the kernel can allocate a value greater than
-        * what we ask it to give us. We really only need 4 KB as that
-        * is this hardware supports and in fact we need at least 3849
-        * as that is the MAX AMSDU size this hardware supports.
-        * Unfortunately this means we may get 8 KB here from the
-        * kernel... and that is actually what is observed on some
-        * systems :( */
-       skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
-       if (skb != NULL) {
-               off = ((unsigned long) skb->data) % sc->cachelsz;
-               if (off != 0)
-                       skb_reserve(skb, sc->cachelsz - off);
-       } else {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "skbuff alloc of size %u failed\n", len);
-               return NULL;
-       }
-
-       return skb;
-}
-
-/*
- * For Decrypt or Demic errors, we only mark packet status here and always push
- * up the frame up to let mac80211 handle the actual error case, be it no
- * decryption key or real decryption error. This let us keep statistics there.
- */
-static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
-                         struct ieee80211_rx_status *rx_status, bool *decrypt_error,
-                         struct ath_softc *sc)
-{
-       struct ieee80211_hdr *hdr;
-       u8 ratecode;
-       __le16 fc;
-       struct ieee80211_hw *hw;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-       memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
-       hw = ath_get_virt_hw(sc, hdr);
-
-       if (ds->ds_rxstat.rs_more) {
-               /*
-                * Frame spans multiple descriptors; this cannot happen yet
-                * as we don't support jumbograms. If not in monitor mode,
-                * discard the frame. Enable this if you want to see
-                * error frames in Monitor mode.
-                */
-               if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
-                       goto rx_next;
-       } else if (ds->ds_rxstat.rs_status != 0) {
-               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
-                       rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
-               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY)
-                       goto rx_next;
-
-               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
-                       *decrypt_error = true;
-               } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
-                       if (ieee80211_is_ctl(fc))
-                               /*
-                                * Sometimes, we get invalid
-                                * MIC failures on valid control frames.
-                                * Remove these mic errors.
-                                */
-                               ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC;
-                       else
-                               rx_status->flag |= RX_FLAG_MMIC_ERROR;
-               }
-               /*
-                * Reject error frames with the exception of
-                * decryption and MIC failures. For monitor mode,
-                * we also ignore the CRC error.
-                */
-               if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
-                       if (ds->ds_rxstat.rs_status &
-                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
-                             ATH9K_RXERR_CRC))
-                               goto rx_next;
-               } else {
-                       if (ds->ds_rxstat.rs_status &
-                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
-                               goto rx_next;
-                       }
-               }
-       }
-
-       ratecode = ds->ds_rxstat.rs_rate;
-
-       if (ratecode & 0x80) {
-               /* HT rate */
-               rx_status->flag |= RX_FLAG_HT;
-               if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040)
-                       rx_status->flag |= RX_FLAG_40MHZ;
-               if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
-                       rx_status->flag |= RX_FLAG_SHORT_GI;
-               rx_status->rate_idx = ratecode & 0x7f;
-       } else {
-               int i = 0, cur_band, n_rates;
-
-               cur_band = hw->conf.channel->band;
-               n_rates = sc->sbands[cur_band].n_bitrates;
-
-               for (i = 0; i < n_rates; i++) {
-                       if (sc->sbands[cur_band].bitrates[i].hw_value ==
-                           ratecode) {
-                               rx_status->rate_idx = i;
-                               break;
-                       }
-
-                       if (sc->sbands[cur_band].bitrates[i].hw_value_short ==
-                           ratecode) {
-                               rx_status->rate_idx = i;
-                               rx_status->flag |= RX_FLAG_SHORTPRE;
-                               break;
-                       }
-               }
-       }
-
-       rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
-       rx_status->band = hw->conf.channel->band;
-       rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->noise = sc->ani.noise_floor;
-       rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
-       rx_status->antenna = ds->ds_rxstat.rs_antenna;
-
-       /* at 45 you will be able to use MCS 15 reliably. A more elaborate
-        * scheme can be used here but it requires tables of SNR/throughput for
-        * each possible mode used. */
-       rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
-
-       /* rssi can be more than 45 though, anything above that
-        * should be considered at 100% */
-       if (rx_status->qual > 100)
-               rx_status->qual = 100;
-
-       rx_status->flag |= RX_FLAG_TSFT;
-
-       return 1;
-rx_next:
-       return 0;
-}
-
-static void ath_opmode_init(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       u32 rfilt, mfilt[2];
-
-       /* configure rx filter */
-       rfilt = ath_calcrxfilter(sc);
-       ath9k_hw_setrxfilter(ah, rfilt);
-
-       /* configure bssid mask */
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-               ath9k_hw_setbssidmask(sc);
-
-       /* configure operational mode */
-       ath9k_hw_setopmode(ah);
-
-       /* Handle any link-level address change. */
-       ath9k_hw_setmac(ah, sc->sc_ah->macaddr);
-
-       /* calculate and install multicast filter */
-       mfilt[0] = mfilt[1] = ~0;
-       ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
-}
-
-int ath_rx_init(struct ath_softc *sc, int nbufs)
-{
-       struct sk_buff *skb;
-       struct ath_buf *bf;
-       int error = 0;
-
-       spin_lock_init(&sc->rx.rxflushlock);
-       sc->sc_flags &= ~SC_OP_RXFLUSH;
-       spin_lock_init(&sc->rx.rxbuflock);
-
-       sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
-                                min(sc->cachelsz, (u16)64));
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
-               sc->cachelsz, sc->rx.bufsize);
-
-       /* Initialize rx descriptors */
-
-       error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
-                                 "rx", nbufs, 1);
-       if (error != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "failed to allocate rx descriptors: %d\n", error);
-               goto err;
-       }
-
-       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-               skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
-               if (skb == NULL) {
-                       error = -ENOMEM;
-                       goto err;
-               }
-
-               bf->bf_mpdu = skb;
-               bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
-                                                sc->rx.bufsize,
-                                                DMA_FROM_DEVICE);
-               if (unlikely(dma_mapping_error(sc->dev,
-                                              bf->bf_buf_addr))) {
-                       dev_kfree_skb_any(skb);
-                       bf->bf_mpdu = NULL;
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "dma_mapping_error() on RX init\n");
-                       error = -ENOMEM;
-                       goto err;
-               }
-               bf->bf_dmacontext = bf->bf_buf_addr;
-       }
-       sc->rx.rxlink = NULL;
-
-err:
-       if (error)
-               ath_rx_cleanup(sc);
-
-       return error;
-}
-
-void ath_rx_cleanup(struct ath_softc *sc)
-{
-       struct sk_buff *skb;
-       struct ath_buf *bf;
-
-       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-               skb = bf->bf_mpdu;
-               if (skb) {
-                       dma_unmap_single(sc->dev, bf->bf_buf_addr,
-                                        sc->rx.bufsize, DMA_FROM_DEVICE);
-                       dev_kfree_skb(skb);
-               }
-       }
-
-       if (sc->rx.rxdma.dd_desc_len != 0)
-               ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
-}
-
-/*
- * 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
- */
-
-u32 ath_calcrxfilter(struct ath_softc *sc)
-{
-#define        RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
-
-       u32 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->opmode != NL80211_IFTYPE_STATION)
-               rfilt |= ATH9K_RX_FILTER_PROBEREQ;
-
-       /*
-        * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
-        * mode interface or when in monitor mode. AP mode does not need this
-        * since it receives all in-BSS frames anyway.
-        */
-       if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
-            (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
-               rfilt |= ATH9K_RX_FILTER_PROM;
-
-       if (sc->rx.rxfilter & FIF_CONTROL)
-               rfilt |= ATH9K_RX_FILTER_CONTROL;
-
-       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
-           !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC))
-               rfilt |= ATH9K_RX_FILTER_MYBEACON;
-       else
-               rfilt |= ATH9K_RX_FILTER_BEACON;
-
-       /* If in HOSTAP mode, want to enable reception of PSPOLL frames */
-       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
-               rfilt |= ATH9K_RX_FILTER_PSPOLL;
-
-       if (sc->sec_wiphy) {
-               /* TODO: only needed if more than one BSSID is in use in
-                * station/adhoc mode */
-               /* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM
-                */
-               rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
-       }
-
-       return rfilt;
-
-#undef RX_FILTER_PRESERVE
-}
-
-int ath_startrecv(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf, *tbf;
-
-       spin_lock_bh(&sc->rx.rxbuflock);
-       if (list_empty(&sc->rx.rxbuf))
-               goto start_recv;
-
-       sc->rx.rxlink = NULL;
-       list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
-               ath_rx_buf_link(sc, bf);
-       }
-
-       /* We could have deleted elements so the list may be empty now */
-       if (list_empty(&sc->rx.rxbuf))
-               goto start_recv;
-
-       bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
-       ath9k_hw_putrxbuf(ah, bf->bf_daddr);
-       ath9k_hw_rxena(ah);
-
-start_recv:
-       spin_unlock_bh(&sc->rx.rxbuflock);
-       ath_opmode_init(sc);
-       ath9k_hw_startpcureceive(ah);
-
-       return 0;
-}
-
-bool ath_stoprecv(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       bool stopped;
-
-       ath9k_hw_stoppcurecv(ah);
-       ath9k_hw_setrxfilter(ah, 0);
-       stopped = ath9k_hw_stopdmarecv(ah);
-       sc->rx.rxlink = NULL;
-
-       return stopped;
-}
-
-void ath_flushrecv(struct ath_softc *sc)
-{
-       spin_lock_bh(&sc->rx.rxflushlock);
-       sc->sc_flags |= SC_OP_RXFLUSH;
-       ath_rx_tasklet(sc, 1);
-       sc->sc_flags &= ~SC_OP_RXFLUSH;
-       spin_unlock_bh(&sc->rx.rxflushlock);
-}
-
-int ath_rx_tasklet(struct ath_softc *sc, int flush)
-{
-#define PA2DESC(_sc, _pa)                                               \
-       ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc +         \
-                            ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
-
-       struct ath_buf *bf;
-       struct ath_desc *ds;
-       struct sk_buff *skb = NULL, *requeue_skb;
-       struct ieee80211_rx_status rx_status;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ieee80211_hdr *hdr;
-       int hdrlen, padsize, retval;
-       bool decrypt_error = false;
-       u8 keyix;
-       __le16 fc;
-
-       spin_lock_bh(&sc->rx.rxbuflock);
-
-       do {
-               /* If handling rx interrupt and flush is in progress => exit */
-               if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
-                       break;
-
-               if (list_empty(&sc->rx.rxbuf)) {
-                       sc->rx.rxlink = NULL;
-                       break;
-               }
-
-               bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
-               ds = bf->bf_desc;
-
-               /*
-                * 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.
-                */
-               retval = ath9k_hw_rxprocdesc(ah, ds,
-                                            bf->bf_daddr,
-                                            PA2DESC(sc, ds->ds_link),
-                                            0);
-               if (retval == -EINPROGRESS) {
-                       struct ath_buf *tbf;
-                       struct ath_desc *tds;
-
-                       if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
-                               sc->rx.rxlink = NULL;
-                               break;
-                       }
-
-                       tbf = list_entry(bf->list.next, struct ath_buf, list);
-
-                       /*
-                        * On some hardware the descriptor status words could
-                        * get corrupted, including the done bit. Because of
-                        * this, check if the next descriptor's done bit is
-                        * set or not.
-                        *
-                        * If the next descriptor's done bit is set, the current
-                        * descriptor has been corrupted. Force s/w to discard
-                        * this descriptor and continue...
-                        */
-
-                       tds = tbf->bf_desc;
-                       retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr,
-                                            PA2DESC(sc, tds->ds_link), 0);
-                       if (retval == -EINPROGRESS) {
-                               break;
-                       }
-               }
-
-               skb = bf->bf_mpdu;
-               if (!skb)
-                       continue;
-
-               /*
-                * Synchronize the DMA transfer with CPU before
-                * 1. accessing the frame
-                * 2. requeueing the same buffer to h/w
-                */
-               dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
-                               sc->rx.bufsize,
-                               DMA_FROM_DEVICE);
-
-               /*
-                * If we're asked to flush receive queue, directly
-                * chain it back at the queue without processing it.
-                */
-               if (flush)
-                       goto requeue;
-
-               if (!ds->ds_rxstat.rs_datalen)
-                       goto requeue;
-
-               /* The status portion of the descriptor could get corrupted. */
-               if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
-                       goto requeue;
-
-               if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
-                       goto requeue;
-
-               /* Ensure we always have an skb to requeue once we are done
-                * processing the current buffer's skb */
-               requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC);
-
-               /* If there is no memory we ignore the current RX'd frame,
-                * tell hardware it can give us a new frame using the old
-                * skb and put it at the tail of the sc->rx.rxbuf list for
-                * processing. */
-               if (!requeue_skb)
-                       goto requeue;
-
-               /* Unmap the frame */
-               dma_unmap_single(sc->dev, bf->bf_buf_addr,
-                                sc->rx.bufsize,
-                                DMA_FROM_DEVICE);
-
-               skb_put(skb, ds->ds_rxstat.rs_datalen);
-               skb->protocol = cpu_to_be16(ETH_P_CONTROL);
-
-               /* see if any padding is done by the hw and remove it */
-               hdr = (struct ieee80211_hdr *)skb->data;
-               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-               fc = hdr->frame_control;
-
-               /* The MAC header is padded to have 32-bit boundary if the
-                * packet payload is non-zero. The general calculation for
-                * padsize would take into account odd header lengths:
-                * padsize = (4 - hdrlen % 4) % 4; However, since only
-                * even-length headers are used, padding can only be 0 or 2
-                * bytes and we can optimize this a bit. In addition, we must
-                * not try to remove padding from short control frames that do
-                * not have payload. */
-               padsize = hdrlen & 3;
-               if (padsize && hdrlen >= 24) {
-                       memmove(skb->data + padsize, skb->data, hdrlen);
-                       skb_pull(skb, padsize);
-               }
-
-               keyix = ds->ds_rxstat.rs_keyix;
-
-               if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
-                       rx_status.flag |= RX_FLAG_DECRYPTED;
-               } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED)
-                          && !decrypt_error && skb->len >= hdrlen + 4) {
-                       keyix = skb->data[hdrlen + 3] >> 6;
-
-                       if (test_bit(keyix, sc->keymap))
-                               rx_status.flag |= RX_FLAG_DECRYPTED;
-               }
-               if (ah->sw_mgmt_crypto &&
-                   (rx_status.flag & RX_FLAG_DECRYPTED) &&
-                   ieee80211_is_mgmt(hdr->frame_control)) {
-                       /* Use software decrypt for management frames. */
-                       rx_status.flag &= ~RX_FLAG_DECRYPTED;
-               }
-
-               /* Send the frame to mac80211 */
-               if (hdr->addr1[5] & 0x01) {
-                       int i;
-                       /*
-                        * Deliver broadcast/multicast frames to all suitable
-                        * virtual wiphys.
-                        */
-                       /* TODO: filter based on channel configuration */
-                       for (i = 0; i < sc->num_sec_wiphy; i++) {
-                               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-                               struct sk_buff *nskb;
-                               if (aphy == NULL)
-                                       continue;
-                               nskb = skb_copy(skb, GFP_ATOMIC);
-                               if (nskb)
-                                       __ieee80211_rx(aphy->hw, nskb,
-                                                      &rx_status);
-                       }
-                       __ieee80211_rx(sc->hw, skb, &rx_status);
-               } else {
-                       /* Deliver unicast frames based on receiver address */
-                       __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb,
-                                      &rx_status);
-               }
-
-               /* We will now give hardware our shiny new allocated skb */
-               bf->bf_mpdu = requeue_skb;
-               bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
-                                        sc->rx.bufsize,
-                                        DMA_FROM_DEVICE);
-               if (unlikely(dma_mapping_error(sc->dev,
-                         bf->bf_buf_addr))) {
-                       dev_kfree_skb_any(requeue_skb);
-                       bf->bf_mpdu = NULL;
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "dma_mapping_error() on RX\n");
-                       break;
-               }
-               bf->bf_dmacontext = bf->bf_buf_addr;
-
-               /*
-                * change the default rx antenna if rx diversity chooses the
-                * other antenna 3 times in a row.
-                */
-               if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
-                       if (++sc->rx.rxotherant >= 3)
-                               ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
-               } else {
-                       sc->rx.rxotherant = 0;
-               }
-
-               if (ieee80211_is_beacon(fc) &&
-                               (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) {
-                       sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
-                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
-               }
-requeue:
-               list_move_tail(&bf->list, &sc->rx.rxbuf);
-               ath_rx_buf_link(sc, bf);
-       } while (1);
-
-       spin_unlock_bh(&sc->rx.rxbuflock);
-
-       return 0;
-#undef PA2DESC
-}
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
deleted file mode 100644 (file)
index 5260524..0000000
+++ /dev/null
@@ -1,1511 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 REG_H
-#define REG_H
-
-#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  0x00000007
-#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_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_9100                  0x14
-#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_5416(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
-        ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
-#define AR_SREV_5416_20_OR_LATER(_ah) \
-       (((AR_SREV_5416(_ah)) && \
-        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
-        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
-#define AR_SREV_5416_22_OR_LATER(_ah) \
-       (((AR_SREV_5416(_ah)) && \
-        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
-        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
-
-#define AR_SREV_9100(ah) \
-       ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
-#define AR_SREV_9100_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
-
-#define AR_SREV_9160(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
-#define AR_SREV_9160_10_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160))
-#define AR_SREV_9160_11(_ah) \
-       (AR_SREV_9160(_ah) && \
-        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
-#define AR_SREV_9280(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
-#define AR_SREV_9280_10_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
-#define AR_SREV_9280_20(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
-               ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))
-#define AR_SREV_9280_20_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
-       ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)))
-
-#define AR_SREV_9285(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
-#define AR_SREV_9285_10_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
-#define AR_SREV_9285_11(_ah) \
-       (AR_SREV_9285(ah) && \
-        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
-#define AR_SREV_9285_11_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
-        (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
-                              AR_SREV_REVISION_9285_11)))
-#define AR_SREV_9285_12(_ah) \
-       (AR_SREV_9285(ah) && \
-        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
-#define AR_SREV_9285_12_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
-        (AR_SREV_9285(ah) && ((_ah)->hw_version.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,
-
-};
-
-#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 AR9285_NUM_GPIO                          12
-
-#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 AR9285_GPIO_IN_VAL                       0x00FFF000
-#define AR9285_GPIO_IN_VAL_S                     12
-
-#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_BT_PRIORITY_DEF     0x00000004
-#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2
-#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008
-#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S      3
-#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF       0x00000010
-#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S         4
-#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_BT_ACTIVE_BB        0x00001000
-#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S      12
-#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_MUX1_BT_ACTIVE             0x000f0000
-#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
-
-#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)
-
-/* RTC_DERIVED_* - only for AR9100 */
-
-#define AR_RTC_DERIVED_CLK           (AR_RTC_BASE + 0x0038)
-#define AR_RTC_DERIVED_CLK_PERIOD    0x0000fffe
-#define AR_RTC_DERIVED_CLK_PERIOD_S  1
-
-#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_TOP1                  0x7890
-#define AR_AN_TOP1_DACIPMODE       0x00040000
-#define AR_AN_TOP1_DACIPMODE_S     18
-
-#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_COMPR_BAR     0x00000400
-
-#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_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
-#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
-
-#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_TSFOOR_THRESHOLD       0x813c
-#define AR_TSFOOR_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_PCU_MISC_MODE2               0x8344
-#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
-#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT   0x00000004
-
-#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)
-
-#endif
diff --git a/drivers/net/wireless/ath9k/virtual.c b/drivers/net/wireless/ath9k/virtual.c
deleted file mode 100644 (file)
index 1ff429b..0000000
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-struct ath9k_vif_iter_data {
-       int count;
-       u8 *addr;
-};
-
-static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
-{
-       struct ath9k_vif_iter_data *iter_data = data;
-       u8 *nbuf;
-
-       nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN,
-                       GFP_ATOMIC);
-       if (nbuf == NULL)
-               return;
-
-       memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN);
-       iter_data->addr = nbuf;
-       iter_data->count++;
-}
-
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath9k_vif_iter_data iter_data;
-       int i, j;
-       u8 mask[ETH_ALEN];
-
-       /*
-        * Add primary MAC address even if it is not in active use since it
-        * will be configured to the hardware as the starting point and the
-        * BSSID mask will need to be changed if another address is active.
-        */
-       iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
-       if (iter_data.addr) {
-               memcpy(iter_data.addr, sc->sc_ah->macaddr, ETH_ALEN);
-               iter_data.count = 1;
-       } else
-               iter_data.count = 0;
-
-       /* Get list of all active MAC addresses */
-       spin_lock_bh(&sc->wiphy_lock);
-       ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter,
-                                                  &iter_data);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] == NULL)
-                       continue;
-               ieee80211_iterate_active_interfaces_atomic(
-                       sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data);
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-
-       /* Generate an address mask to cover all active addresses */
-       memset(mask, 0, ETH_ALEN);
-       for (i = 0; i < iter_data.count; i++) {
-               u8 *a1 = iter_data.addr + i * ETH_ALEN;
-               for (j = i + 1; j < iter_data.count; j++) {
-                       u8 *a2 = iter_data.addr + j * ETH_ALEN;
-                       mask[0] |= a1[0] ^ a2[0];
-                       mask[1] |= a1[1] ^ a2[1];
-                       mask[2] |= a1[2] ^ a2[2];
-                       mask[3] |= a1[3] ^ a2[3];
-                       mask[4] |= a1[4] ^ a2[4];
-                       mask[5] |= a1[5] ^ a2[5];
-               }
-       }
-
-       kfree(iter_data.addr);
-
-       /* Invert the mask and configure hardware */
-       sc->bssidmask[0] = ~mask[0];
-       sc->bssidmask[1] = ~mask[1];
-       sc->bssidmask[2] = ~mask[2];
-       sc->bssidmask[3] = ~mask[3];
-       sc->bssidmask[4] = ~mask[4];
-       sc->bssidmask[5] = ~mask[5];
-
-       ath9k_hw_setbssidmask(sc);
-}
-
-int ath9k_wiphy_add(struct ath_softc *sc)
-{
-       int i, error;
-       struct ath_wiphy *aphy;
-       struct ieee80211_hw *hw;
-       u8 addr[ETH_ALEN];
-
-       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops);
-       if (hw == NULL)
-               return -ENOMEM;
-
-       spin_lock_bh(&sc->wiphy_lock);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] == NULL)
-                       break;
-       }
-
-       if (i == sc->num_sec_wiphy) {
-               /* No empty slot available; increase array length */
-               struct ath_wiphy **n;
-               n = krealloc(sc->sec_wiphy,
-                            (sc->num_sec_wiphy + 1) *
-                            sizeof(struct ath_wiphy *),
-                            GFP_ATOMIC);
-               if (n == NULL) {
-                       spin_unlock_bh(&sc->wiphy_lock);
-                       ieee80211_free_hw(hw);
-                       return -ENOMEM;
-               }
-               n[i] = NULL;
-               sc->sec_wiphy = n;
-               sc->num_sec_wiphy++;
-       }
-
-       SET_IEEE80211_DEV(hw, sc->dev);
-
-       aphy = hw->priv;
-       aphy->sc = sc;
-       aphy->hw = hw;
-       sc->sec_wiphy[i] = aphy;
-       spin_unlock_bh(&sc->wiphy_lock);
-
-       memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN);
-       addr[0] |= 0x02; /* Locally managed address */
-       /*
-        * XOR virtual wiphy index into the least significant bits to generate
-        * a different MAC address for each virtual wiphy.
-        */
-       addr[5] ^= i & 0xff;
-       addr[4] ^= (i & 0xff00) >> 8;
-       addr[3] ^= (i & 0xff0000) >> 16;
-
-       SET_IEEE80211_PERM_ADDR(hw, addr);
-
-       ath_set_hw_capab(sc, hw);
-
-       error = ieee80211_register_hw(hw);
-
-       if (error == 0) {
-               /* Make sure wiphy scheduler is started (if enabled) */
-               ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int);
-       }
-
-       return error;
-}
-
-int ath9k_wiphy_del(struct ath_wiphy *aphy)
-{
-       struct ath_softc *sc = aphy->sc;
-       int i;
-
-       spin_lock_bh(&sc->wiphy_lock);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (aphy == sc->sec_wiphy[i]) {
-                       sc->sec_wiphy[i] = NULL;
-                       spin_unlock_bh(&sc->wiphy_lock);
-                       ieee80211_unregister_hw(aphy->hw);
-                       ieee80211_free_hw(aphy->hw);
-                       return 0;
-               }
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-       return -ENOENT;
-}
-
-static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
-                              struct ieee80211_vif *vif, const u8 *bssid,
-                              int ps)
-{
-       struct ath_softc *sc = aphy->sc;
-       struct ath_tx_control txctl;
-       struct sk_buff *skb;
-       struct ieee80211_hdr *hdr;
-       __le16 fc;
-       struct ieee80211_tx_info *info;
-
-       skb = dev_alloc_skb(24);
-       if (skb == NULL)
-               return -ENOMEM;
-       hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
-       memset(hdr, 0, 24);
-       fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
-                        IEEE80211_FCTL_TODS);
-       if (ps)
-               fc |= cpu_to_le16(IEEE80211_FCTL_PM);
-       hdr->frame_control = fc;
-       memcpy(hdr->addr1, bssid, ETH_ALEN);
-       memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN);
-       memcpy(hdr->addr3, bssid, ETH_ALEN);
-
-       info = IEEE80211_SKB_CB(skb);
-       memset(info, 0, sizeof(*info));
-       info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS;
-       info->control.vif = vif;
-       info->control.rates[0].idx = 0;
-       info->control.rates[0].count = 4;
-       info->control.rates[1].idx = -1;
-
-       memset(&txctl, 0, sizeof(struct ath_tx_control));
-       txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
-       txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE;
-
-       if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
-               goto exit;
-
-       return 0;
-exit:
-       dev_kfree_skb_any(skb);
-       return -1;
-}
-
-static bool __ath9k_wiphy_pausing(struct ath_softc *sc)
-{
-       int i;
-       if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING)
-               return true;
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING)
-                       return true;
-       }
-       return false;
-}
-
-static bool ath9k_wiphy_pausing(struct ath_softc *sc)
-{
-       bool ret;
-       spin_lock_bh(&sc->wiphy_lock);
-       ret = __ath9k_wiphy_pausing(sc);
-       spin_unlock_bh(&sc->wiphy_lock);
-       return ret;
-}
-
-static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
-{
-       int i;
-       if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
-               return true;
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
-                       return true;
-       }
-       return false;
-}
-
-bool ath9k_wiphy_scanning(struct ath_softc *sc)
-{
-       bool ret;
-       spin_lock_bh(&sc->wiphy_lock);
-       ret = __ath9k_wiphy_scanning(sc);
-       spin_unlock_bh(&sc->wiphy_lock);
-       return ret;
-}
-
-static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);
-
-/* caller must hold wiphy_lock */
-static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy)
-{
-       if (aphy == NULL)
-               return;
-       if (aphy->chan_idx != aphy->sc->chan_idx)
-               return; /* wiphy not on the selected channel */
-       __ath9k_wiphy_unpause(aphy);
-}
-
-static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
-{
-       int i;
-       spin_lock_bh(&sc->wiphy_lock);
-       __ath9k_wiphy_unpause_ch(sc->pri_wiphy);
-       for (i = 0; i < sc->num_sec_wiphy; i++)
-               __ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]);
-       spin_unlock_bh(&sc->wiphy_lock);
-}
-
-void ath9k_wiphy_chan_work(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
-       struct ath_wiphy *aphy = sc->next_wiphy;
-
-       if (aphy == NULL)
-               return;
-
-       /*
-        * All pending interfaces paused; ready to change
-        * channels.
-        */
-
-       /* Change channels */
-       mutex_lock(&sc->mutex);
-       /* XXX: remove me eventually */
-       ath9k_update_ichannel(sc, aphy->hw,
-                             &sc->sc_ah->channels[sc->chan_idx]);
-       ath_update_chainmask(sc, sc->chan_is_ht);
-       if (ath_set_channel(sc, aphy->hw,
-                           &sc->sc_ah->channels[sc->chan_idx]) < 0) {
-               printk(KERN_DEBUG "ath9k: Failed to set channel for new "
-                      "virtual wiphy\n");
-               mutex_unlock(&sc->mutex);
-               return;
-       }
-       mutex_unlock(&sc->mutex);
-
-       ath9k_wiphy_unpause_channel(sc);
-}
-
-/*
- * ath9k version of ieee80211_tx_status() for TX frames that are generated
- * internally in the driver.
- */
-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-
-       if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE &&
-           aphy->state == ATH_WIPHY_PAUSING) {
-               if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
-                       printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
-                              "frame\n", wiphy_name(hw->wiphy));
-                       /*
-                        * The AP did not reply; ignore this to allow us to
-                        * continue.
-                        */
-               }
-               aphy->state = ATH_WIPHY_PAUSED;
-               if (!ath9k_wiphy_pausing(aphy->sc)) {
-                       /*
-                        * Drop from tasklet to work to allow mutex for channel
-                        * change.
-                        */
-                       queue_work(aphy->sc->hw->workqueue,
-                                  &aphy->sc->chan_work);
-               }
-       }
-
-       kfree(tx_info_priv);
-       tx_info->rate_driver_data[0] = NULL;
-
-       dev_kfree_skb(skb);
-}
-
-static void ath9k_mark_paused(struct ath_wiphy *aphy)
-{
-       struct ath_softc *sc = aphy->sc;
-       aphy->state = ATH_WIPHY_PAUSED;
-       if (!__ath9k_wiphy_pausing(sc))
-               queue_work(sc->hw->workqueue, &sc->chan_work);
-}
-
-static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
-{
-       struct ath_wiphy *aphy = data;
-       struct ath_vif *avp = (void *) vif->drv_priv;
-
-       switch (vif->type) {
-       case NL80211_IFTYPE_STATION:
-               if (!vif->bss_conf.assoc) {
-                       ath9k_mark_paused(aphy);
-                       break;
-               }
-               /* TODO: could avoid this if already in PS mode */
-               if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) {
-                       printk(KERN_DEBUG "%s: failed to send PS nullfunc\n",
-                              __func__);
-                       ath9k_mark_paused(aphy);
-               }
-               break;
-       case NL80211_IFTYPE_AP:
-               /* Beacon transmission is paused by aphy->state change */
-               ath9k_mark_paused(aphy);
-               break;
-       default:
-               break;
-       }
-}
-
-/* caller must hold wiphy_lock */
-static int __ath9k_wiphy_pause(struct ath_wiphy *aphy)
-{
-       ieee80211_stop_queues(aphy->hw);
-       aphy->state = ATH_WIPHY_PAUSING;
-       /*
-        * TODO: handle PAUSING->PAUSED for the case where there are multiple
-        * active vifs (now we do it on the first vif getting ready; should be
-        * on the last)
-        */
-       ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter,
-                                                  aphy);
-       return 0;
-}
-
-int ath9k_wiphy_pause(struct ath_wiphy *aphy)
-{
-       int ret;
-       spin_lock_bh(&aphy->sc->wiphy_lock);
-       ret = __ath9k_wiphy_pause(aphy);
-       spin_unlock_bh(&aphy->sc->wiphy_lock);
-       return ret;
-}
-
-static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
-{
-       struct ath_wiphy *aphy = data;
-       struct ath_vif *avp = (void *) vif->drv_priv;
-
-       switch (vif->type) {
-       case NL80211_IFTYPE_STATION:
-               if (!vif->bss_conf.assoc)
-                       break;
-               ath9k_send_nullfunc(aphy, vif, avp->bssid, 0);
-               break;
-       case NL80211_IFTYPE_AP:
-               /* Beacon transmission is re-enabled by aphy->state change */
-               break;
-       default:
-               break;
-       }
-}
-
-/* caller must hold wiphy_lock */
-static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy)
-{
-       ieee80211_iterate_active_interfaces_atomic(aphy->hw,
-                                                  ath9k_unpause_iter, aphy);
-       aphy->state = ATH_WIPHY_ACTIVE;
-       ieee80211_wake_queues(aphy->hw);
-       return 0;
-}
-
-int ath9k_wiphy_unpause(struct ath_wiphy *aphy)
-{
-       int ret;
-       spin_lock_bh(&aphy->sc->wiphy_lock);
-       ret = __ath9k_wiphy_unpause(aphy);
-       spin_unlock_bh(&aphy->sc->wiphy_lock);
-       return ret;
-}
-
-static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc)
-{
-       int i;
-       if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE)
-               sc->pri_wiphy->state = ATH_WIPHY_PAUSED;
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE)
-                       sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED;
-       }
-}
-
-/* caller must hold wiphy_lock */
-static void __ath9k_wiphy_pause_all(struct ath_softc *sc)
-{
-       int i;
-       if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
-               __ath9k_wiphy_pause(sc->pri_wiphy);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
-                       __ath9k_wiphy_pause(sc->sec_wiphy[i]);
-       }
-}
-
-int ath9k_wiphy_select(struct ath_wiphy *aphy)
-{
-       struct ath_softc *sc = aphy->sc;
-       bool now;
-
-       spin_lock_bh(&sc->wiphy_lock);
-       if (__ath9k_wiphy_scanning(sc)) {
-               /*
-                * For now, we are using mac80211 sw scan and it expects to
-                * have full control over channel changes, so avoid wiphy
-                * scheduling during a scan. This could be optimized if the
-                * scanning control were moved into the driver.
-                */
-               spin_unlock_bh(&sc->wiphy_lock);
-               return -EBUSY;
-       }
-       if (__ath9k_wiphy_pausing(sc)) {
-               if (sc->wiphy_select_failures == 0)
-                       sc->wiphy_select_first_fail = jiffies;
-               sc->wiphy_select_failures++;
-               if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2))
-               {
-                       printk(KERN_DEBUG "ath9k: Previous wiphy select timed "
-                              "out; disable/enable hw to recover\n");
-                       __ath9k_wiphy_mark_all_paused(sc);
-                       /*
-                        * TODO: this workaround to fix hardware is unlikely to
-                        * be specific to virtual wiphy changes. It can happen
-                        * on normal channel change, too, and as such, this
-                        * should really be made more generic. For example,
-                        * tricker radio disable/enable on GTT interrupt burst
-                        * (say, 10 GTT interrupts received without any TX
-                        * frame being completed)
-                        */
-                       spin_unlock_bh(&sc->wiphy_lock);
-                       ath_radio_disable(sc);
-                       ath_radio_enable(sc);
-                       queue_work(aphy->sc->hw->workqueue,
-                                  &aphy->sc->chan_work);
-                       return -EBUSY; /* previous select still in progress */
-               }
-               spin_unlock_bh(&sc->wiphy_lock);
-               return -EBUSY; /* previous select still in progress */
-       }
-       sc->wiphy_select_failures = 0;
-
-       /* Store the new channel */
-       sc->chan_idx = aphy->chan_idx;
-       sc->chan_is_ht = aphy->chan_is_ht;
-       sc->next_wiphy = aphy;
-
-       __ath9k_wiphy_pause_all(sc);
-       now = !__ath9k_wiphy_pausing(aphy->sc);
-       spin_unlock_bh(&sc->wiphy_lock);
-
-       if (now) {
-               /* Ready to request channel change immediately */
-               queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work);
-       }
-
-       /*
-        * wiphys will be unpaused in ath9k_tx_status() once channel has been
-        * changed if any wiphy needs time to become paused.
-        */
-
-       return 0;
-}
-
-bool ath9k_wiphy_started(struct ath_softc *sc)
-{
-       int i;
-       spin_lock_bh(&sc->wiphy_lock);
-       if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
-               spin_unlock_bh(&sc->wiphy_lock);
-               return true;
-       }
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) {
-                       spin_unlock_bh(&sc->wiphy_lock);
-                       return true;
-               }
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-       return false;
-}
-
-static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
-                                  struct ath_wiphy *selected)
-{
-       if (selected->state == ATH_WIPHY_SCAN) {
-               if (aphy == selected)
-                       return;
-               /*
-                * Pause all other wiphys for the duration of the scan even if
-                * they are on the current channel now.
-                */
-       } else if (aphy->chan_idx == selected->chan_idx)
-               return;
-       aphy->state = ATH_WIPHY_PAUSED;
-       ieee80211_stop_queues(aphy->hw);
-}
-
-void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
-                                 struct ath_wiphy *selected)
-{
-       int i;
-       spin_lock_bh(&sc->wiphy_lock);
-       if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
-               ath9k_wiphy_pause_chan(sc->pri_wiphy, selected);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
-                       ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected);
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-}
-
-void ath9k_wiphy_work(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc,
-                                           wiphy_work.work);
-       struct ath_wiphy *aphy = NULL;
-       bool first = true;
-
-       spin_lock_bh(&sc->wiphy_lock);
-
-       if (sc->wiphy_scheduler_int == 0) {
-               /* wiphy scheduler is disabled */
-               spin_unlock_bh(&sc->wiphy_lock);
-               return;
-       }
-
-try_again:
-       sc->wiphy_scheduler_index++;
-       while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) {
-               aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1];
-               if (aphy && aphy->state != ATH_WIPHY_INACTIVE)
-                       break;
-
-               sc->wiphy_scheduler_index++;
-               aphy = NULL;
-       }
-       if (aphy == NULL) {
-               sc->wiphy_scheduler_index = 0;
-               if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) {
-                       if (first) {
-                               first = false;
-                               goto try_again;
-                       }
-                       /* No wiphy is ready to be scheduled */
-               } else
-                       aphy = sc->pri_wiphy;
-       }
-
-       spin_unlock_bh(&sc->wiphy_lock);
-
-       if (aphy &&
-           aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN &&
-           ath9k_wiphy_select(aphy)) {
-               printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy "
-                      "change\n");
-       }
-
-       queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
-                          sc->wiphy_scheduler_int);
-}
-
-void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
-{
-       cancel_delayed_work_sync(&sc->wiphy_work);
-       sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
-       if (sc->wiphy_scheduler_int)
-               queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
-                                  sc->wiphy_scheduler_int);
-}
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
deleted file mode 100644 (file)
index 628b780..0000000
+++ /dev/null
@@ -1,2171 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.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
-
-static u32 bits_per_symbol[][2] = {
-       /* 20MHz 40MHz */
-       {    26,   54 },     /*  0: BPSK */
-       {    52,  108 },     /*  1: QPSK 1/2 */
-       {    78,  162 },     /*  2: QPSK 3/4 */
-       {   104,  216 },     /*  3: 16-QAM 1/2 */
-       {   156,  324 },     /*  4: 16-QAM 3/4 */
-       {   208,  432 },     /*  5: 64-QAM 2/3 */
-       {   234,  486 },     /*  6: 64-QAM 3/4 */
-       {   260,  540 },     /*  7: 64-QAM 5/6 */
-       {    52,  108 },     /*  8: BPSK */
-       {   104,  216 },     /*  9: QPSK 1/2 */
-       {   156,  324 },     /* 10: QPSK 3/4 */
-       {   208,  432 },     /* 11: 16-QAM 1/2 */
-       {   312,  648 },     /* 12: 16-QAM 3/4 */
-       {   416,  864 },     /* 13: 64-QAM 2/3 */
-       {   468,  972 },     /* 14: 64-QAM 3/4 */
-       {   520, 1080 },     /* 15: 64-QAM 5/6 */
-};
-
-#define IS_HT_RATE(_rate)     ((_rate) & 0x80)
-
-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
-                                 struct ath_atx_tid *tid,
-                                 struct list_head *bf_head);
-static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
-                               struct list_head *bf_q,
-                               int txok, int sendbar);
-static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
-                            struct list_head *head);
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
-                             int txok);
-static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
-                            int nbad, int txok, bool update_rc);
-
-/*********************/
-/* Aggregation logic */
-/*********************/
-
-static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
-{
-       struct ath_atx_tid *tid;
-       tid = ATH_AN_2_TID(an, tidno);
-
-       if (tid->state & AGGR_ADDBA_COMPLETE ||
-           tid->state & AGGR_ADDBA_PROGRESS)
-               return 1;
-       else
-               return 0;
-}
-
-static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
-{
-       struct ath_atx_ac *ac = tid->ac;
-
-       if (tid->paused)
-               return;
-
-       if (tid->sched)
-               return;
-
-       tid->sched = true;
-       list_add_tail(&tid->list, &ac->tid_q);
-
-       if (ac->sched)
-               return;
-
-       ac->sched = true;
-       list_add_tail(&ac->list, &txq->axq_acq);
-}
-
-static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
-
-       spin_lock_bh(&txq->axq_lock);
-       tid->paused++;
-       spin_unlock_bh(&txq->axq_lock);
-}
-
-static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
-
-       ASSERT(tid->paused > 0);
-       spin_lock_bh(&txq->axq_lock);
-
-       tid->paused--;
-
-       if (tid->paused > 0)
-               goto unlock;
-
-       if (list_empty(&tid->buf_q))
-               goto unlock;
-
-       ath_tx_queue_tid(txq, tid);
-       ath_txq_schedule(sc, txq);
-unlock:
-       spin_unlock_bh(&txq->axq_lock);
-}
-
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
-       struct ath_buf *bf;
-       struct list_head bf_head;
-       INIT_LIST_HEAD(&bf_head);
-
-       ASSERT(tid->paused > 0);
-       spin_lock_bh(&txq->axq_lock);
-
-       tid->paused--;
-
-       if (tid->paused > 0) {
-               spin_unlock_bh(&txq->axq_lock);
-               return;
-       }
-
-       while (!list_empty(&tid->buf_q)) {
-               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-               ASSERT(!bf_isretried(bf));
-               list_move_tail(&bf->list, &bf_head);
-               ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
-       }
-
-       spin_unlock_bh(&txq->axq_lock);
-}
-
-static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
-                             int seqno)
-{
-       int index, cindex;
-
-       index  = ATH_BA_INDEX(tid->seq_start, seqno);
-       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-
-       tid->tx_buf[cindex] = NULL;
-
-       while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) {
-               INCR(tid->seq_start, IEEE80211_SEQ_MAX);
-               INCR(tid->baw_head, ATH_TID_MAX_BUFS);
-       }
-}
-
-static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
-                            struct ath_buf *bf)
-{
-       int index, cindex;
-
-       if (bf_isretried(bf))
-               return;
-
-       index  = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
-       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-
-       ASSERT(tid->tx_buf[cindex] == NULL);
-       tid->tx_buf[cindex] = bf;
-
-       if (index >= ((tid->baw_tail - tid->baw_head) &
-               (ATH_TID_MAX_BUFS - 1))) {
-               tid->baw_tail = cindex;
-               INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
-       }
-}
-
-/*
- * TODO: For frame(s) that are in the retry state, we will reuse the
- * sequence number(s) without setting the retry bit. The
- * alternative is to give up on these and BAR the receiver's window
- * forward.
- */
-static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
-                         struct ath_atx_tid *tid)
-
-{
-       struct ath_buf *bf;
-       struct list_head bf_head;
-       INIT_LIST_HEAD(&bf_head);
-
-       for (;;) {
-               if (list_empty(&tid->buf_q))
-                       break;
-
-               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-               list_move_tail(&bf->list, &bf_head);
-
-               if (bf_isretried(bf))
-                       ath_tx_update_baw(sc, tid, bf->bf_seqno);
-
-               spin_unlock(&txq->axq_lock);
-               ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
-               spin_lock(&txq->axq_lock);
-       }
-
-       tid->seq_next = tid->seq_start;
-       tid->baw_tail = tid->baw_head;
-}
-
-static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
-{
-       struct sk_buff *skb;
-       struct ieee80211_hdr *hdr;
-
-       bf->bf_state.bf_type |= BUF_RETRY;
-       bf->bf_retries++;
-
-       skb = bf->bf_mpdu;
-       hdr = (struct ieee80211_hdr *)skb->data;
-       hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
-}
-
-static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
-{
-       struct ath_buf *tbf;
-
-       spin_lock_bh(&sc->tx.txbuflock);
-       ASSERT(!list_empty((&sc->tx.txbuf)));
-       tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-       list_del(&tbf->list);
-       spin_unlock_bh(&sc->tx.txbuflock);
-
-       ATH_TXBUF_RESET(tbf);
-
-       tbf->bf_mpdu = bf->bf_mpdu;
-       tbf->bf_buf_addr = bf->bf_buf_addr;
-       *(tbf->bf_desc) = *(bf->bf_desc);
-       tbf->bf_state = bf->bf_state;
-       tbf->bf_dmacontext = bf->bf_dmacontext;
-
-       return tbf;
-}
-
-static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
-                                struct ath_buf *bf, struct list_head *bf_q,
-                                int txok)
-{
-       struct ath_node *an = NULL;
-       struct sk_buff *skb;
-       struct ieee80211_sta *sta;
-       struct ieee80211_hdr *hdr;
-       struct ath_atx_tid *tid = NULL;
-       struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
-       struct ath_desc *ds = bf_last->bf_desc;
-       struct list_head bf_head, bf_pending;
-       u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
-       u32 ba[WME_BA_BMP_SIZE >> 5];
-       int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
-       bool rc_update = true;
-
-       skb = bf->bf_mpdu;
-       hdr = (struct ieee80211_hdr *)skb->data;
-
-       rcu_read_lock();
-
-       sta = ieee80211_find_sta(sc->hw, hdr->addr1);
-       if (!sta) {
-               rcu_read_unlock();
-               return;
-       }
-
-       an = (struct ath_node *)sta->drv_priv;
-       tid = ATH_AN_2_TID(an, bf->bf_tidno);
-
-       isaggr = bf_isaggr(bf);
-       memset(ba, 0, WME_BA_BMP_SIZE >> 3);
-
-       if (isaggr && txok) {
-               if (ATH_DS_TX_BA(ds)) {
-                       seq_st = ATH_DS_BA_SEQ(ds);
-                       memcpy(ba, ATH_DS_BA_BITMAP(ds),
-                              WME_BA_BMP_SIZE >> 3);
-               } else {
-                       /*
-                        * AR5416 can become deaf/mute when BA
-                        * issue happens. Chip needs to be reset.
-                        * But AP code may have sychronization issues
-                        * when perform internal reset in this routine.
-                        * Only enable reset in STA mode for now.
-                        */
-                       if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION)
-                               needreset = 1;
-               }
-       }
-
-       INIT_LIST_HEAD(&bf_pending);
-       INIT_LIST_HEAD(&bf_head);
-
-       nbad = ath_tx_num_badfrms(sc, bf, txok);
-       while (bf) {
-               txfail = txpending = 0;
-               bf_next = bf->bf_next;
-
-               if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
-                       /* transmit completion, subframe is
-                        * acked by block ack */
-                       acked_cnt++;
-               } else if (!isaggr && txok) {
-                       /* transmit completion */
-                       acked_cnt++;
-               } else {
-                       if (!(tid->state & AGGR_CLEANUP) &&
-                           ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
-                               if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
-                                       ath_tx_set_retry(sc, bf);
-                                       txpending = 1;
-                               } else {
-                                       bf->bf_state.bf_type |= BUF_XRETRY;
-                                       txfail = 1;
-                                       sendbar = 1;
-                                       txfail_cnt++;
-                               }
-                       } else {
-                               /*
-                                * cleanup in progress, just fail
-                                * the un-acked sub-frames
-                                */
-                               txfail = 1;
-                       }
-               }
-
-               if (bf_next == NULL) {
-                       INIT_LIST_HEAD(&bf_head);
-               } else {
-                       ASSERT(!list_empty(bf_q));
-                       list_move_tail(&bf->list, &bf_head);
-               }
-
-               if (!txpending) {
-                       /*
-                        * complete the acked-ones/xretried ones; update
-                        * block-ack window
-                        */
-                       spin_lock_bh(&txq->axq_lock);
-                       ath_tx_update_baw(sc, tid, bf->bf_seqno);
-                       spin_unlock_bh(&txq->axq_lock);
-
-                       if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
-                               ath_tx_rc_status(bf, ds, nbad, txok, true);
-                               rc_update = false;
-                       } else {
-                               ath_tx_rc_status(bf, ds, nbad, txok, false);
-                       }
-
-                       ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
-               } else {
-                       /* retry the un-acked ones */
-                       if (bf->bf_next == NULL && bf_last->bf_stale) {
-                               struct ath_buf *tbf;
-
-                               tbf = ath_clone_txbuf(sc, bf_last);
-                               ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
-                               list_add_tail(&tbf->list, &bf_head);
-                       } else {
-                               /*
-                                * Clear descriptor status words for
-                                * software retry
-                                */
-                               ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
-                       }
-
-                       /*
-                        * Put this buffer to the temporary pending
-                        * queue to retain ordering
-                        */
-                       list_splice_tail_init(&bf_head, &bf_pending);
-               }
-
-               bf = bf_next;
-       }
-
-       if (tid->state & AGGR_CLEANUP) {
-               if (tid->baw_head == tid->baw_tail) {
-                       tid->state &= ~AGGR_ADDBA_COMPLETE;
-                       tid->addba_exchangeattempts = 0;
-                       tid->state &= ~AGGR_CLEANUP;
-
-                       /* send buffered frames as singles */
-                       ath_tx_flush_tid(sc, tid);
-               }
-               rcu_read_unlock();
-               return;
-       }
-
-       /* prepend un-acked frames to the beginning of the pending frame queue */
-       if (!list_empty(&bf_pending)) {
-               spin_lock_bh(&txq->axq_lock);
-               list_splice(&bf_pending, &tid->buf_q);
-               ath_tx_queue_tid(txq, tid);
-               spin_unlock_bh(&txq->axq_lock);
-       }
-
-       rcu_read_unlock();
-
-       if (needreset)
-               ath_reset(sc, false);
-}
-
-static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
-                          struct ath_atx_tid *tid)
-{
-       struct ath_rate_table *rate_table = sc->cur_rate_table;
-       struct sk_buff *skb;
-       struct ieee80211_tx_info *tx_info;
-       struct ieee80211_tx_rate *rates;
-       struct ath_tx_info_priv *tx_info_priv;
-       u32 max_4ms_framelen, frmlen;
-       u16 aggr_limit, legacy = 0, maxampdu;
-       int i;
-
-       skb = bf->bf_mpdu;
-       tx_info = IEEE80211_SKB_CB(skb);
-       rates = tx_info->control.rates;
-       tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
-
-       /*
-        * Find the lowest frame length among the rate series that will have a
-        * 4ms transmit duration.
-        * TODO - TXOP limit needs to be considered.
-        */
-       max_4ms_framelen = ATH_AMPDU_LIMIT_MAX;
-
-       for (i = 0; i < 4; i++) {
-               if (rates[i].count) {
-                       if (!WLAN_RC_PHY_HT(rate_table->info[rates[i].idx].phy)) {
-                               legacy = 1;
-                               break;
-                       }
-
-                       frmlen = rate_table->info[rates[i].idx].max_4ms_framelen;
-                       max_4ms_framelen = min(max_4ms_framelen, frmlen);
-               }
-       }
-
-       /*
-        * limit aggregate size by the minimum rate if rate selected is
-        * not a probe rate, if rate selected is a probe rate then
-        * avoid aggregation of this packet.
-        */
-       if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
-               return 0;
-
-       aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT);
-
-       /*
-        * h/w can accept aggregates upto 16 bit lengths (65535).
-        * The IE, however can hold upto 65536, which shows up here
-        * as zero. Ignore 65536 since we  are constrained by hw.
-        */
-       maxampdu = tid->an->maxampdu;
-       if (maxampdu)
-               aggr_limit = min(aggr_limit, maxampdu);
-
-       return aggr_limit;
-}
-
-/*
- * Returns the number of delimiters to be added to
- * meet the minimum required mpdudensity.
- * caller should make sure that the rate is HT rate .
- */
-static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
-                                 struct ath_buf *bf, u16 frmlen)
-{
-       struct ath_rate_table *rt = sc->cur_rate_table;
-       struct sk_buff *skb = bf->bf_mpdu;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       u32 nsymbits, nsymbols, mpdudensity;
-       u16 minlen;
-       u8 rc, flags, rix;
-       int width, half_gi, ndelim, mindelim;
-
-       /* Select standard number of delimiters based on frame length alone */
-       ndelim = ATH_AGGR_GET_NDELIM(frmlen);
-
-       /*
-        * If encryption enabled, hardware requires some more padding between
-        * subframes.
-        * TODO - this could be improved to be dependent on the rate.
-        *      The hardware can keep up at lower rates, but not higher rates
-        */
-       if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR)
-               ndelim += ATH_AGGR_ENCRYPTDELIM;
-
-       /*
-        * Convert desired mpdu density from microeconds to bytes based
-        * on highest rate in rate series (i.e. first rate) to determine
-        * required minimum length for subframe. Take into account
-        * whether high rate is 20 or 40Mhz and half or full GI.
-        */
-       mpdudensity = tid->an->mpdudensity;
-
-       /*
-        * If there is no mpdu density restriction, no further calculation
-        * is needed.
-        */
-       if (mpdudensity == 0)
-               return ndelim;
-
-       rix = tx_info->control.rates[0].idx;
-       flags = tx_info->control.rates[0].flags;
-       rc = rt->info[rix].ratecode;
-       width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0;
-       half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0;
-
-       if (half_gi)
-               nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity);
-       else
-               nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity);
-
-       if (nsymbols == 0)
-               nsymbols = 1;
-
-       nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
-       minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
-
-       if (frmlen < minlen) {
-               mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
-               ndelim = max(mindelim, ndelim);
-       }
-
-       return ndelim;
-}
-
-static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
-                                            struct ath_atx_tid *tid,
-                                            struct list_head *bf_q)
-{
-#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
-       struct ath_buf *bf, *bf_first, *bf_prev = NULL;
-       int rl = 0, nframes = 0, ndelim, prev_al = 0;
-       u16 aggr_limit = 0, al = 0, bpad = 0,
-               al_delta, h_baw = tid->baw_size / 2;
-       enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
-
-       bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
-
-       do {
-               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-
-               /* do not step over block-ack window */
-               if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
-                       status = ATH_AGGR_BAW_CLOSED;
-                       break;
-               }
-
-               if (!rl) {
-                       aggr_limit = ath_lookup_rate(sc, bf, tid);
-                       rl = 1;
-               }
-
-               /* do not exceed aggregation limit */
-               al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
-
-               if (nframes &&
-                   (aggr_limit < (al + bpad + al_delta + prev_al))) {
-                       status = ATH_AGGR_LIMITED;
-                       break;
-               }
-
-               /* do not exceed subframe limit */
-               if (nframes >= min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
-                       status = ATH_AGGR_LIMITED;
-                       break;
-               }
-               nframes++;
-
-               /* add padding for previous frame to aggregation length */
-               al += bpad + al_delta;
-
-               /*
-                * Get the delimiters needed to meet the MPDU
-                * density for this node.
-                */
-               ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
-               bpad = PADBYTES(al_delta) + (ndelim << 2);
-
-               bf->bf_next = NULL;
-               bf->bf_desc->ds_link = 0;
-
-               /* link buffers of this frame to the aggregate */
-               ath_tx_addto_baw(sc, tid, bf);
-               ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
-               list_move_tail(&bf->list, bf_q);
-               if (bf_prev) {
-                       bf_prev->bf_next = bf;
-                       bf_prev->bf_desc->ds_link = bf->bf_daddr;
-               }
-               bf_prev = bf;
-       } while (!list_empty(&tid->buf_q));
-
-       bf_first->bf_al = al;
-       bf_first->bf_nframes = nframes;
-
-       return status;
-#undef PADBYTES
-}
-
-static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
-                             struct ath_atx_tid *tid)
-{
-       struct ath_buf *bf;
-       enum ATH_AGGR_STATUS status;
-       struct list_head bf_q;
-
-       do {
-               if (list_empty(&tid->buf_q))
-                       return;
-
-               INIT_LIST_HEAD(&bf_q);
-
-               status = ath_tx_form_aggr(sc, tid, &bf_q);
-
-               /*
-                * no frames picked up to be aggregated;
-                * block-ack window is not open.
-                */
-               if (list_empty(&bf_q))
-                       break;
-
-               bf = list_first_entry(&bf_q, struct ath_buf, list);
-               bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
-
-               /* if only one frame, send as non-aggregate */
-               if (bf->bf_nframes == 1) {
-                       bf->bf_state.bf_type &= ~BUF_AGGR;
-                       ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
-                       ath_buf_set_rate(sc, bf);
-                       ath_tx_txqaddbuf(sc, txq, &bf_q);
-                       continue;
-               }
-
-               /* setup first desc of aggregate */
-               bf->bf_state.bf_type |= BUF_AGGR;
-               ath_buf_set_rate(sc, bf);
-               ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
-
-               /* anchor last desc of aggregate */
-               ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
-
-               txq->axq_aggr_depth++;
-               ath_tx_txqaddbuf(sc, txq, &bf_q);
-
-       } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
-                status != ATH_AGGR_BAW_CLOSED);
-}
-
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
-                     u16 tid, u16 *ssn)
-{
-       struct ath_atx_tid *txtid;
-       struct ath_node *an;
-
-       an = (struct ath_node *)sta->drv_priv;
-
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               txtid = ATH_AN_2_TID(an, tid);
-               txtid->state |= AGGR_ADDBA_PROGRESS;
-               ath_tx_pause_tid(sc, txtid);
-               *ssn = txtid->seq_start;
-       }
-
-       return 0;
-}
-
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
-{
-       struct ath_node *an = (struct ath_node *)sta->drv_priv;
-       struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
-       struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
-       struct ath_buf *bf;
-       struct list_head bf_head;
-       INIT_LIST_HEAD(&bf_head);
-
-       if (txtid->state & AGGR_CLEANUP)
-               return 0;
-
-       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
-               txtid->addba_exchangeattempts = 0;
-               return 0;
-       }
-
-       ath_tx_pause_tid(sc, txtid);
-
-       /* drop all software retried frames and mark this TID */
-       spin_lock_bh(&txq->axq_lock);
-       while (!list_empty(&txtid->buf_q)) {
-               bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
-               if (!bf_isretried(bf)) {
-                       /*
-                        * NB: it's based on the assumption that
-                        * software retried frame will always stay
-                        * at the head of software queue.
-                        */
-                       break;
-               }
-               list_move_tail(&bf->list, &bf_head);
-               ath_tx_update_baw(sc, txtid, bf->bf_seqno);
-               ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
-       }
-       spin_unlock_bh(&txq->axq_lock);
-
-       if (txtid->baw_head != txtid->baw_tail) {
-               txtid->state |= AGGR_CLEANUP;
-       } else {
-               txtid->state &= ~AGGR_ADDBA_COMPLETE;
-               txtid->addba_exchangeattempts = 0;
-               ath_tx_flush_tid(sc, txtid);
-       }
-
-       return 0;
-}
-
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
-{
-       struct ath_atx_tid *txtid;
-       struct ath_node *an;
-
-       an = (struct ath_node *)sta->drv_priv;
-
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               txtid = ATH_AN_2_TID(an, tid);
-               txtid->baw_size =
-                       IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
-               txtid->state |= AGGR_ADDBA_COMPLETE;
-               txtid->state &= ~AGGR_ADDBA_PROGRESS;
-               ath_tx_resume_tid(sc, txtid);
-       }
-}
-
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
-{
-       struct ath_atx_tid *txtid;
-
-       if (!(sc->sc_flags & SC_OP_TXAGGR))
-               return false;
-
-       txtid = ATH_AN_2_TID(an, tidno);
-
-       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
-               if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
-                   (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
-                       txtid->addba_exchangeattempts++;
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-/********************/
-/* Queue Management */
-/********************/
-
-static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
-                                         struct ath_txq *txq)
-{
-       struct ath_atx_ac *ac, *ac_tmp;
-       struct ath_atx_tid *tid, *tid_tmp;
-
-       list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
-               list_del(&ac->list);
-               ac->sched = false;
-               list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
-                       list_del(&tid->list);
-                       tid->sched = false;
-                       ath_tid_drain(sc, txq, tid);
-               }
-       }
-}
-
-struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath9k_tx_queue_info qi;
-       int qnum;
-
-       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->tx.txq)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "qnum %u out of range, max %u!\n",
-                       qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
-               ath9k_hw_releasetxqueue(ah, qnum);
-               return NULL;
-       }
-       if (!ATH_TXQ_SETUP(sc, qnum)) {
-               struct ath_txq *txq = &sc->tx.txq[qnum];
-
-               txq->axq_qnum = qnum;
-               txq->axq_link = NULL;
-               INIT_LIST_HEAD(&txq->axq_q);
-               INIT_LIST_HEAD(&txq->axq_acq);
-               spin_lock_init(&txq->axq_lock);
-               txq->axq_depth = 0;
-               txq->axq_aggr_depth = 0;
-               txq->axq_totalqueued = 0;
-               txq->axq_linkbuf = NULL;
-               sc->tx.txqsetup |= 1<<qnum;
-       }
-       return &sc->tx.txq[qnum];
-}
-
-static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
-{
-       int qnum;
-
-       switch (qtype) {
-       case ATH9K_TX_QUEUE_DATA:
-               if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "HAL AC %u out of range, max %zu!\n",
-                               haltype, ARRAY_SIZE(sc->tx.hwq_map));
-                       return -1;
-               }
-               qnum = sc->tx.hwq_map[haltype];
-               break;
-       case ATH9K_TX_QUEUE_BEACON:
-               qnum = sc->beacon.beaconq;
-               break;
-       case ATH9K_TX_QUEUE_CAB:
-               qnum = sc->beacon.cabq->axq_qnum;
-               break;
-       default:
-               qnum = -1;
-       }
-       return qnum;
-}
-
-struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
-{
-       struct ath_txq *txq = NULL;
-       int qnum;
-
-       qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
-       txq = &sc->tx.txq[qnum];
-
-       spin_lock_bh(&txq->axq_lock);
-
-       if (txq->axq_depth >= (ATH_TXBUF - 20)) {
-               DPRINTF(sc, ATH_DBG_XMIT,
-                       "TX queue: %d is full, depth: %d\n",
-                       qnum, txq->axq_depth);
-               ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
-               txq->stopped = 1;
-               spin_unlock_bh(&txq->axq_lock);
-               return NULL;
-       }
-
-       spin_unlock_bh(&txq->axq_lock);
-
-       return txq;
-}
-
-int ath_txq_update(struct ath_softc *sc, int qnum,
-                  struct ath9k_tx_queue_info *qinfo)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       int error = 0;
-       struct ath9k_tx_queue_info qi;
-
-       if (qnum == sc->beacon.beaconq) {
-               /*
-                * XXX: for beacon queue, we just save the parameter.
-                * It will be picked up by ath_beaconq_config when
-                * it's necessary.
-                */
-               sc->beacon.beacon_qi = *qinfo;
-               return 0;
-       }
-
-       ASSERT(sc->tx.txq[qnum].axq_qnum == qnum);
-
-       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)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to update hardware queue %u!\n", qnum);
-               error = -EIO;
-       } else {
-               ath9k_hw_resettxqueue(ah, qnum);
-       }
-
-       return error;
-}
-
-int ath_cabq_update(struct ath_softc *sc)
-{
-       struct ath9k_tx_queue_info qi;
-       int qnum = sc->beacon.cabq->axq_qnum;
-
-       ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
-       /*
-        * Ensure the readytime % is within the bounds.
-        */
-       if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
-               sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
-       else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
-               sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
-
-       qi.tqi_readyTime = (sc->hw->conf.beacon_int *
-                           sc->config.cabqReadytime) / 100;
-       ath_txq_update(sc, qnum, &qi);
-
-       return 0;
-}
-
-/*
- * Drain a given TX queue (could be Beacon or Data)
- *
- * This assumes output has been stopped and
- * we do not need to block ath_tx_tasklet.
- */
-void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
-{
-       struct ath_buf *bf, *lastbf;
-       struct list_head bf_head;
-
-       INIT_LIST_HEAD(&bf_head);
-
-       for (;;) {
-               spin_lock_bh(&txq->axq_lock);
-
-               if (list_empty(&txq->axq_q)) {
-                       txq->axq_link = NULL;
-                       txq->axq_linkbuf = NULL;
-                       spin_unlock_bh(&txq->axq_lock);
-                       break;
-               }
-
-               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
-
-               if (bf->bf_stale) {
-                       list_del(&bf->list);
-                       spin_unlock_bh(&txq->axq_lock);
-
-                       spin_lock_bh(&sc->tx.txbuflock);
-                       list_add_tail(&bf->list, &sc->tx.txbuf);
-                       spin_unlock_bh(&sc->tx.txbuflock);
-                       continue;
-               }
-
-               lastbf = bf->bf_lastbf;
-               if (!retry_tx)
-                       lastbf->bf_desc->ds_txstat.ts_flags =
-                               ATH9K_TX_SW_ABORTED;
-
-               /* remove ath_buf's of the same mpdu from txq */
-               list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
-               txq->axq_depth--;
-
-               spin_unlock_bh(&txq->axq_lock);
-
-               if (bf_isampdu(bf))
-                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
-               else
-                       ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
-       }
-
-       /* flush any pending frames if aggregation is enabled */
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               if (!retry_tx) {
-                       spin_lock_bh(&txq->axq_lock);
-                       ath_txq_drain_pending_buffers(sc, txq);
-                       spin_unlock_bh(&txq->axq_lock);
-               }
-       }
-}
-
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_txq *txq;
-       int i, npend = 0;
-
-       if (sc->sc_flags & SC_OP_INVALID)
-               return;
-
-       /* Stop beacon queue */
-       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-
-       /* Stop data queues */
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (ATH_TXQ_SETUP(sc, i)) {
-                       txq = &sc->tx.txq[i];
-                       ath9k_hw_stoptxdma(ah, txq->axq_qnum);
-                       npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
-               }
-       }
-
-       if (npend) {
-               int r;
-
-               DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
-
-               spin_lock_bh(&sc->sc_resetlock);
-               r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
-               if (r)
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Unable to reset hardware; reset status %u\n",
-                               r);
-               spin_unlock_bh(&sc->sc_resetlock);
-       }
-
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
-       }
-}
-
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
-{
-       ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
-       sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
-}
-
-void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
-{
-       struct ath_atx_ac *ac;
-       struct ath_atx_tid *tid;
-
-       if (list_empty(&txq->axq_acq))
-               return;
-
-       ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
-       list_del(&ac->list);
-       ac->sched = false;
-
-       do {
-               if (list_empty(&ac->tid_q))
-                       return;
-
-               tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
-               list_del(&tid->list);
-               tid->sched = false;
-
-               if (tid->paused)
-                       continue;
-
-               if ((txq->axq_depth % 2) == 0)
-                       ath_tx_sched_aggr(sc, txq, tid);
-
-               /*
-                * add tid to round-robin queue if more frames
-                * are pending for the tid
-                */
-               if (!list_empty(&tid->buf_q))
-                       ath_tx_queue_tid(txq, tid);
-
-               break;
-       } while (!list_empty(&ac->tid_q));
-
-       if (!list_empty(&ac->tid_q)) {
-               if (!ac->sched) {
-                       ac->sched = true;
-                       list_add_tail(&ac->list, &txq->axq_acq);
-               }
-       }
-}
-
-int ath_tx_setup(struct ath_softc *sc, int haltype)
-{
-       struct ath_txq *txq;
-
-       if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "HAL AC %u out of range, max %zu!\n",
-                        haltype, ARRAY_SIZE(sc->tx.hwq_map));
-               return 0;
-       }
-       txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
-       if (txq != NULL) {
-               sc->tx.hwq_map[haltype] = txq->axq_qnum;
-               return 1;
-       } else
-               return 0;
-}
-
-/***********/
-/* TX, DMA */
-/***********/
-
-/*
- * Insert a chain of ath_buf (descriptors) on a txq and
- * assume the descriptors are already chained together by caller.
- */
-static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
-                            struct list_head *head)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf;
-
-       /*
-        * Insert the frame on the outbound list and
-        * pass it on to the hardware.
-        */
-
-       if (list_empty(head))
-               return;
-
-       bf = list_first_entry(head, struct ath_buf, list);
-
-       list_splice_tail_init(head, &txq->axq_q);
-       txq->axq_depth++;
-       txq->axq_totalqueued++;
-       txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
-
-       DPRINTF(sc, ATH_DBG_QUEUE,
-               "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
-
-       if (txq->axq_link == NULL) {
-               ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
-               DPRINTF(sc, ATH_DBG_XMIT,
-                       "TXDP[%u] = %llx (%p)\n",
-                       txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
-       } else {
-               *txq->axq_link = bf->bf_daddr;
-               DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
-                       txq->axq_qnum, txq->axq_link,
-                       ito64(bf->bf_daddr), bf->bf_desc);
-       }
-       txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
-       ath9k_hw_txstart(ah, txq->axq_qnum);
-}
-
-static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
-{
-       struct ath_buf *bf = NULL;
-
-       spin_lock_bh(&sc->tx.txbuflock);
-
-       if (unlikely(list_empty(&sc->tx.txbuf))) {
-               spin_unlock_bh(&sc->tx.txbuflock);
-               return NULL;
-       }
-
-       bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-       list_del(&bf->list);
-
-       spin_unlock_bh(&sc->tx.txbuflock);
-
-       return bf;
-}
-
-static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
-                             struct list_head *bf_head,
-                             struct ath_tx_control *txctl)
-{
-       struct ath_buf *bf;
-
-       bf = list_first_entry(bf_head, struct ath_buf, list);
-       bf->bf_state.bf_type |= BUF_AMPDU;
-
-       /*
-        * Do not queue to h/w when any of the following conditions is true:
-        * - there are pending frames in software queue
-        * - the TID is currently paused for ADDBA/BAR request
-        * - seqno is not within block-ack window
-        * - h/w queue depth exceeds low water mark
-        */
-       if (!list_empty(&tid->buf_q) || tid->paused ||
-           !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
-           txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
-               /*
-                * Add this frame to software queue for scheduling later
-                * for aggregation.
-                */
-               list_move_tail(&bf->list, &tid->buf_q);
-               ath_tx_queue_tid(txctl->txq, tid);
-               return;
-       }
-
-       /* Add sub-frame to BAW */
-       ath_tx_addto_baw(sc, tid, bf);
-
-       /* Queue to h/w without aggregation */
-       bf->bf_nframes = 1;
-       bf->bf_lastbf = bf;
-       ath_buf_set_rate(sc, bf);
-       ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
-}
-
-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
-                                 struct ath_atx_tid *tid,
-                                 struct list_head *bf_head)
-{
-       struct ath_buf *bf;
-
-       bf = list_first_entry(bf_head, struct ath_buf, list);
-       bf->bf_state.bf_type &= ~BUF_AMPDU;
-
-       /* update starting sequence number for subsequent ADDBA request */
-       INCR(tid->seq_start, IEEE80211_SEQ_MAX);
-
-       bf->bf_nframes = 1;
-       bf->bf_lastbf = bf;
-       ath_buf_set_rate(sc, bf);
-       ath_tx_txqaddbuf(sc, txq, bf_head);
-}
-
-static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
-                              struct list_head *bf_head)
-{
-       struct ath_buf *bf;
-
-       bf = list_first_entry(bf_head, struct ath_buf, list);
-
-       bf->bf_lastbf = bf;
-       bf->bf_nframes = 1;
-       ath_buf_set_rate(sc, bf);
-       ath_tx_txqaddbuf(sc, txq, bf_head);
-}
-
-static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
-{
-       struct ieee80211_hdr *hdr;
-       enum ath9k_pkt_type htype;
-       __le16 fc;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-
-       if (ieee80211_is_beacon(fc))
-               htype = ATH9K_PKT_TYPE_BEACON;
-       else if (ieee80211_is_probe_resp(fc))
-               htype = ATH9K_PKT_TYPE_PROBE_RESP;
-       else if (ieee80211_is_atim(fc))
-               htype = ATH9K_PKT_TYPE_ATIM;
-       else if (ieee80211_is_pspoll(fc))
-               htype = ATH9K_PKT_TYPE_PSPOLL;
-       else
-               htype = ATH9K_PKT_TYPE_NORMAL;
-
-       return htype;
-}
-
-static bool is_pae(struct sk_buff *skb)
-{
-       struct ieee80211_hdr *hdr;
-       __le16 fc;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-
-       if (ieee80211_is_data(fc)) {
-               if (ieee80211_is_nullfunc(fc) ||
-                   /* Port Access Entity (IEEE 802.1X) */
-                   (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-static int get_hw_crypto_keytype(struct sk_buff *skb)
-{
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-
-       if (tx_info->control.hw_key) {
-               if (tx_info->control.hw_key->alg == ALG_WEP)
-                       return ATH9K_KEY_TYPE_WEP;
-               else if (tx_info->control.hw_key->alg == ALG_TKIP)
-                       return ATH9K_KEY_TYPE_TKIP;
-               else if (tx_info->control.hw_key->alg == ALG_CCMP)
-                       return ATH9K_KEY_TYPE_AES;
-       }
-
-       return ATH9K_KEY_TYPE_CLEAR;
-}
-
-static void assign_aggr_tid_seqno(struct sk_buff *skb,
-                                 struct ath_buf *bf)
-{
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr;
-       struct ath_node *an;
-       struct ath_atx_tid *tid;
-       __le16 fc;
-       u8 *qc;
-
-       if (!tx_info->control.sta)
-               return;
-
-       an = (struct ath_node *)tx_info->control.sta->drv_priv;
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-
-       if (ieee80211_is_data_qos(fc)) {
-               qc = ieee80211_get_qos_ctl(hdr);
-               bf->bf_tidno = qc[0] & 0xf;
-       }
-
-       /*
-        * For HT capable stations, we save tidno for later use.
-        * We also override seqno set by upper layer with the one
-        * in tx aggregation state.
-        *
-        * If fragmentation is on, the sequence number is
-        * not overridden, since it has been
-        * incremented by the fragmentation routine.
-        *
-        * FIXME: check if the fragmentation threshold exceeds
-        * IEEE80211 max.
-        */
-       tid = ATH_AN_2_TID(an, bf->bf_tidno);
-       hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
-                       IEEE80211_SEQ_SEQ_SHIFT);
-       bf->bf_seqno = tid->seq_next;
-       INCR(tid->seq_next, IEEE80211_SEQ_MAX);
-}
-
-static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
-                         struct ath_txq *txq)
-{
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       int flags = 0;
-
-       flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
-       flags |= ATH9K_TXDESC_INTREQ;
-
-       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
-               flags |= ATH9K_TXDESC_NOACK;
-
-       return flags;
-}
-
-/*
- * rix - rate index
- * pktlen - total bytes (delims + data + fcs + pads + pad delims)
- * width  - 0 for 20 MHz, 1 for 40 MHz
- * half_gi - to use 4us v/s 3.6 us for symbol time
- */
-static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
-                           int width, int half_gi, bool shortPreamble)
-{
-       struct ath_rate_table *rate_table = sc->cur_rate_table;
-       u32 nbits, nsymbits, duration, nsymbols;
-       u8 rc;
-       int streams, pktlen;
-
-       pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
-       rc = rate_table->info[rix].ratecode;
-
-       /* for legacy rates, use old function to compute packet duration */
-       if (!IS_HT_RATE(rc))
-               return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
-                                             rix, shortPreamble);
-
-       /* find number of symbols: PLCP + data */
-       nbits = (pktlen << 3) + OFDM_PLCP_BITS;
-       nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
-       nsymbols = (nbits + nsymbits - 1) / nsymbits;
-
-       if (!half_gi)
-               duration = SYMBOL_TIME(nsymbols);
-       else
-               duration = SYMBOL_TIME_HALFGI(nsymbols);
-
-       /* addup duration for legacy/ht training and signal fields */
-       streams = HT_RC_2_STREAMS(rc);
-       duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
-
-       return duration;
-}
-
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
-{
-       struct ath_rate_table *rt = sc->cur_rate_table;
-       struct ath9k_11n_rate_series series[4];
-       struct sk_buff *skb;
-       struct ieee80211_tx_info *tx_info;
-       struct ieee80211_tx_rate *rates;
-       struct ieee80211_hdr *hdr;
-       int i, flags = 0;
-       u8 rix = 0, ctsrate = 0;
-       bool is_pspoll;
-
-       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
-
-       skb = bf->bf_mpdu;
-       tx_info = IEEE80211_SKB_CB(skb);
-       rates = tx_info->control.rates;
-       hdr = (struct ieee80211_hdr *)skb->data;
-       is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
-
-       /*
-        * We check if Short Preamble is needed for the CTS rate by
-        * checking the BSS's global flag.
-        * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
-        */
-       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
-               ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode |
-                       rt->info[tx_info->control.rts_cts_rate_idx].short_preamble;
-       else
-               ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode;
-
-       /*
-        * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
-        * Check the first rate in the series to decide whether RTS/CTS
-        * or CTS-to-self has to be used.
-        */
-       if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
-               flags = ATH9K_TXDESC_CTSENA;
-       else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
-               flags = ATH9K_TXDESC_RTSENA;
-
-       /* FIXME: Handle aggregation protection */
-       if (sc->config.ath_aggr_prot &&
-           (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
-               flags = ATH9K_TXDESC_RTSENA;
-       }
-
-       /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
-       if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
-               flags &= ~(ATH9K_TXDESC_RTSENA);
-
-       for (i = 0; i < 4; i++) {
-               if (!rates[i].count || (rates[i].idx < 0))
-                       continue;
-
-               rix = rates[i].idx;
-               series[i].Tries = rates[i].count;
-               series[i].ChSel = sc->tx_chainmask;
-
-               if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
-                       series[i].Rate = rt->info[rix].ratecode |
-                               rt->info[rix].short_preamble;
-               else
-                       series[i].Rate = rt->info[rix].ratecode;
-
-               if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
-                       series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
-               if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-                       series[i].RateFlags |= ATH9K_RATESERIES_2040;
-               if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
-                       series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
-
-               series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
-                        (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0,
-                        (rates[i].flags & IEEE80211_TX_RC_SHORT_GI),
-                        (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE));
-       }
-
-       /* set dur_update_en for l-sig computation except for PS-Poll frames */
-       ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
-                                    bf->bf_lastbf->bf_desc,
-                                    !is_pspoll, ctsrate,
-                                    0, series, 4, flags);
-
-       if (sc->config.ath_aggr_prot && flags)
-               ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
-}
-
-static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
-                               struct sk_buff *skb,
-                               struct ath_tx_control *txctl)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ath_tx_info_priv *tx_info_priv;
-       int hdrlen;
-       __le16 fc;
-
-       tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
-       if (unlikely(!tx_info_priv))
-               return -ENOMEM;
-       tx_info->rate_driver_data[0] = tx_info_priv;
-       tx_info_priv->aphy = aphy;
-       tx_info_priv->frame_type = txctl->frame_type;
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       fc = hdr->frame_control;
-
-       ATH_TXBUF_RESET(bf);
-
-       bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
-
-       if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
-               bf->bf_state.bf_type |= BUF_HT;
-
-       bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
-
-       bf->bf_keytype = get_hw_crypto_keytype(skb);
-       if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
-               bf->bf_frmlen += tx_info->control.hw_key->icv_len;
-               bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
-       } else {
-               bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
-       }
-
-       if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
-               assign_aggr_tid_seqno(skb, bf);
-
-       bf->bf_mpdu = skb;
-
-       bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
-                                          skb->len, DMA_TO_DEVICE);
-       if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
-               bf->bf_mpdu = NULL;
-               DPRINTF(sc, ATH_DBG_CONFIG,
-                       "dma_mapping_error() on TX\n");
-               return -ENOMEM;
-       }
-
-       bf->bf_buf_addr = bf->bf_dmacontext;
-       return 0;
-}
-
-/* FIXME: tx power */
-static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
-                            struct ath_tx_control *txctl)
-{
-       struct sk_buff *skb = bf->bf_mpdu;
-       struct ieee80211_tx_info *tx_info =  IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ath_node *an = NULL;
-       struct list_head bf_head;
-       struct ath_desc *ds;
-       struct ath_atx_tid *tid;
-       struct ath_hw *ah = sc->sc_ah;
-       int frm_type;
-       __le16 fc;
-
-       frm_type = get_hw_packet_type(skb);
-       fc = hdr->frame_control;
-
-       INIT_LIST_HEAD(&bf_head);
-       list_add_tail(&bf->list, &bf_head);
-
-       ds = bf->bf_desc;
-       ds->ds_link = 0;
-       ds->ds_data = bf->bf_buf_addr;
-
-       ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
-                              bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
-
-       ath9k_hw_filltxdesc(ah, ds,
-                           skb->len,   /* segment length */
-                           true,       /* first segment */
-                           true,       /* last segment */
-                           ds);        /* first descriptor */
-
-       spin_lock_bh(&txctl->txq->axq_lock);
-
-       if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
-           tx_info->control.sta) {
-               an = (struct ath_node *)tx_info->control.sta->drv_priv;
-               tid = ATH_AN_2_TID(an, bf->bf_tidno);
-
-               if (!ieee80211_is_data_qos(fc)) {
-                       ath_tx_send_normal(sc, txctl->txq, &bf_head);
-                       goto tx_done;
-               }
-
-               if (ath_aggr_query(sc, an, bf->bf_tidno)) {
-                       /*
-                        * Try aggregation if it's a unicast data frame
-                        * and the destination is HT capable.
-                        */
-                       ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
-               } else {
-                       /*
-                        * Send this frame as regular when ADDBA
-                        * exchange is neither complete nor pending.
-                        */
-                       ath_tx_send_ht_normal(sc, txctl->txq,
-                                             tid, &bf_head);
-               }
-       } else {
-               ath_tx_send_normal(sc, txctl->txq, &bf_head);
-       }
-
-tx_done:
-       spin_unlock_bh(&txctl->txq->axq_lock);
-}
-
-/* Upon failure caller should free skb */
-int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
-                struct ath_tx_control *txctl)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_buf *bf;
-       int r;
-
-       bf = ath_tx_get_buffer(sc);
-       if (!bf) {
-               DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
-               return -1;
-       }
-
-       r = ath_tx_setup_buffer(hw, bf, skb, txctl);
-       if (unlikely(r)) {
-               struct ath_txq *txq = txctl->txq;
-
-               DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
-
-               /* upon ath_tx_processq() this TX queue will be resumed, we
-                * guarantee this will happen by knowing beforehand that
-                * we will at least have to run TX completionon one buffer
-                * on the queue */
-               spin_lock_bh(&txq->axq_lock);
-               if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
-                       ieee80211_stop_queue(sc->hw,
-                               skb_get_queue_mapping(skb));
-                       txq->stopped = 1;
-               }
-               spin_unlock_bh(&txq->axq_lock);
-
-               spin_lock_bh(&sc->tx.txbuflock);
-               list_add_tail(&bf->list, &sc->tx.txbuf);
-               spin_unlock_bh(&sc->tx.txbuflock);
-
-               return r;
-       }
-
-       ath_tx_start_dma(sc, bf, txctl);
-
-       return 0;
-}
-
-void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       int hdrlen, padsize;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_control txctl;
-
-       memset(&txctl, 0, sizeof(struct ath_tx_control));
-
-       /*
-        * As a temporary workaround, assign seq# here; this will likely need
-        * to be cleaned up to work better with Beacon transmission and virtual
-        * BSSes.
-        */
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-                       sc->tx.seq_no += 0x10;
-               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-       }
-
-       /* Add the padding after the header if this is not already done */
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       if (hdrlen & 3) {
-               padsize = hdrlen % 4;
-               if (skb_headroom(skb) < padsize) {
-                       DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
-                       dev_kfree_skb_any(skb);
-                       return;
-               }
-               skb_push(skb, padsize);
-               memmove(skb->data, skb->data + padsize, hdrlen);
-       }
-
-       txctl.txq = sc->beacon.cabq;
-
-       DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
-
-       if (ath_tx_start(hw, skb, &txctl) != 0) {
-               DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
-               goto exit;
-       }
-
-       return;
-exit:
-       dev_kfree_skb_any(skb);
-}
-
-/*****************/
-/* TX Completion */
-/*****************/
-
-static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
-                           int tx_flags)
-{
-       struct ieee80211_hw *hw = sc->hw;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       int hdrlen, padsize;
-       int frame_type = ATH9K_NOT_INTERNAL;
-
-       DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
-
-       if (tx_info_priv) {
-               hw = tx_info_priv->aphy->hw;
-               frame_type = tx_info_priv->frame_type;
-       }
-
-       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
-           tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
-               kfree(tx_info_priv);
-               tx_info->rate_driver_data[0] = NULL;
-       }
-
-       if (tx_flags & ATH_TX_BAR)
-               tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
-
-       if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
-               /* Frame was ACKed */
-               tx_info->flags |= IEEE80211_TX_STAT_ACK;
-       }
-
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       padsize = hdrlen & 3;
-       if (padsize && hdrlen >= 24) {
-               /*
-                * Remove MAC header padding before giving the frame back to
-                * mac80211.
-                */
-               memmove(skb->data + padsize, skb->data, hdrlen);
-               skb_pull(skb, padsize);
-       }
-
-       if (frame_type == ATH9K_NOT_INTERNAL)
-               ieee80211_tx_status(hw, skb);
-       else
-               ath9k_tx_status(hw, skb);
-}
-
-static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
-                               struct list_head *bf_q,
-                               int txok, int sendbar)
-{
-       struct sk_buff *skb = bf->bf_mpdu;
-       unsigned long flags;
-       int tx_flags = 0;
-
-
-       if (sendbar)
-               tx_flags = ATH_TX_BAR;
-
-       if (!txok) {
-               tx_flags |= ATH_TX_ERROR;
-
-               if (bf_isxretried(bf))
-                       tx_flags |= ATH_TX_XRETRY;
-       }
-
-       dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
-       ath_tx_complete(sc, skb, tx_flags);
-
-       /*
-        * Return the list of ath_buf of this mpdu to free queue
-        */
-       spin_lock_irqsave(&sc->tx.txbuflock, flags);
-       list_splice_tail_init(bf_q, &sc->tx.txbuf);
-       spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
-}
-
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
-                             int txok)
-{
-       struct ath_buf *bf_last = bf->bf_lastbf;
-       struct ath_desc *ds = bf_last->bf_desc;
-       u16 seq_st = 0;
-       u32 ba[WME_BA_BMP_SIZE >> 5];
-       int ba_index;
-       int nbad = 0;
-       int isaggr = 0;
-
-       if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
-               return 0;
-
-       isaggr = bf_isaggr(bf);
-       if (isaggr) {
-               seq_st = ATH_DS_BA_SEQ(ds);
-               memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
-       }
-
-       while (bf) {
-               ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
-               if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
-                       nbad++;
-
-               bf = bf->bf_next;
-       }
-
-       return nbad;
-}
-
-static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
-                            int nbad, int txok, bool update_rc)
-{
-       struct sk_buff *skb = bf->bf_mpdu;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       struct ieee80211_hw *hw = tx_info_priv->aphy->hw;
-       u8 i, tx_rateindex;
-
-       if (txok)
-               tx_info->status.ack_signal = ds->ds_txstat.ts_rssi;
-
-       tx_rateindex = ds->ds_txstat.ts_rateindex;
-       WARN_ON(tx_rateindex >= hw->max_rates);
-
-       tx_info_priv->update_rc = update_rc;
-       if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
-               tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-
-       if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
-           (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
-               if (ieee80211_is_data(hdr->frame_control)) {
-                       memcpy(&tx_info_priv->tx, &ds->ds_txstat,
-                              sizeof(tx_info_priv->tx));
-                       tx_info_priv->n_frames = bf->bf_nframes;
-                       tx_info_priv->n_bad_frames = nbad;
-               }
-       }
-
-       for (i = tx_rateindex + 1; i < hw->max_rates; i++)
-               tx_info->status.rates[i].count = 0;
-
-       tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
-}
-
-static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
-{
-       int qnum;
-
-       spin_lock_bh(&txq->axq_lock);
-       if (txq->stopped &&
-           sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
-               qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
-               if (qnum != -1) {
-                       ieee80211_wake_queue(sc->hw, qnum);
-                       txq->stopped = 0;
-               }
-       }
-       spin_unlock_bh(&txq->axq_lock);
-}
-
-static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf, *lastbf, *bf_held = NULL;
-       struct list_head bf_head;
-       struct ath_desc *ds;
-       int txok;
-       int status;
-
-       DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
-               txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
-               txq->axq_link);
-
-       for (;;) {
-               spin_lock_bh(&txq->axq_lock);
-               if (list_empty(&txq->axq_q)) {
-                       txq->axq_link = NULL;
-                       txq->axq_linkbuf = NULL;
-                       spin_unlock_bh(&txq->axq_lock);
-                       break;
-               }
-               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
-
-               /*
-                * There is a race condition that a BH gets scheduled
-                * after sw writes TxE and before hw re-load the last
-                * descriptor to get the newly chained one.
-                * Software must keep the last DONE descriptor as a
-                * holding descriptor - software does so by marking
-                * it with the STALE flag.
-                */
-               bf_held = NULL;
-               if (bf->bf_stale) {
-                       bf_held = bf;
-                       if (list_is_last(&bf_held->list, &txq->axq_q)) {
-                               txq->axq_link = NULL;
-                               txq->axq_linkbuf = NULL;
-                               spin_unlock_bh(&txq->axq_lock);
-
-                               /*
-                                * The holding descriptor is the last
-                                * descriptor in queue. It's safe to remove
-                                * the last holding descriptor in BH context.
-                                */
-                               spin_lock_bh(&sc->tx.txbuflock);
-                               list_move_tail(&bf_held->list, &sc->tx.txbuf);
-                               spin_unlock_bh(&sc->tx.txbuflock);
-
-                               break;
-                       } else {
-                               bf = list_entry(bf_held->list.next,
-                                               struct ath_buf, list);
-                       }
-               }
-
-               lastbf = bf->bf_lastbf;
-               ds = lastbf->bf_desc;
-
-               status = ath9k_hw_txprocdesc(ah, ds);
-               if (status == -EINPROGRESS) {
-                       spin_unlock_bh(&txq->axq_lock);
-                       break;
-               }
-               if (bf->bf_desc == txq->axq_lastdsWithCTS)
-                       txq->axq_lastdsWithCTS = NULL;
-               if (ds == txq->axq_gatingds)
-                       txq->axq_gatingds = NULL;
-
-               /*
-                * Remove ath_buf's of the same transmit unit from txq,
-                * however leave the last descriptor back as the holding
-                * descriptor for hw.
-                */
-               lastbf->bf_stale = true;
-               INIT_LIST_HEAD(&bf_head);
-               if (!list_is_singular(&lastbf->list))
-                       list_cut_position(&bf_head,
-                               &txq->axq_q, lastbf->list.prev);
-
-               txq->axq_depth--;
-               if (bf_isaggr(bf))
-                       txq->axq_aggr_depth--;
-
-               txok = (ds->ds_txstat.ts_status == 0);
-               spin_unlock_bh(&txq->axq_lock);
-
-               if (bf_held) {
-                       spin_lock_bh(&sc->tx.txbuflock);
-                       list_move_tail(&bf_held->list, &sc->tx.txbuf);
-                       spin_unlock_bh(&sc->tx.txbuflock);
-               }
-
-               if (!bf_isampdu(bf)) {
-                       /*
-                        * This frame is sent out as a single frame.
-                        * Use hardware retry status for this frame.
-                        */
-                       bf->bf_retries = ds->ds_txstat.ts_longretry;
-                       if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
-                               bf->bf_state.bf_type |= BUF_XRETRY;
-                       ath_tx_rc_status(bf, ds, 0, txok, true);
-               }
-
-               if (bf_isampdu(bf))
-                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
-               else
-                       ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
-
-               ath_wake_mac80211_queue(sc, txq);
-
-               spin_lock_bh(&txq->axq_lock);
-               if (sc->sc_flags & SC_OP_TXAGGR)
-                       ath_txq_schedule(sc, txq);
-               spin_unlock_bh(&txq->axq_lock);
-       }
-}
-
-
-void ath_tx_tasklet(struct ath_softc *sc)
-{
-       int i;
-       u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
-
-       ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
-
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
-                       ath_tx_processq(sc, &sc->tx.txq[i]);
-       }
-}
-
-/*****************/
-/* Init, Cleanup */
-/*****************/
-
-int ath_tx_init(struct ath_softc *sc, int nbufs)
-{
-       int error = 0;
-
-       spin_lock_init(&sc->tx.txbuflock);
-
-       error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
-                                 "tx", nbufs, 1);
-       if (error != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Failed to allocate tx descriptors: %d\n", error);
-               goto err;
-       }
-
-       error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
-                                 "beacon", ATH_BCBUF, 1);
-       if (error != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Failed to allocate beacon descriptors: %d\n", error);
-               goto err;
-       }
-
-err:
-       if (error != 0)
-               ath_tx_cleanup(sc);
-
-       return error;
-}
-
-void ath_tx_cleanup(struct ath_softc *sc)
-{
-       if (sc->beacon.bdma.dd_desc_len != 0)
-               ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
-
-       if (sc->tx.txdma.dd_desc_len != 0)
-               ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
-}
-
-void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
-{
-       struct ath_atx_tid *tid;
-       struct ath_atx_ac *ac;
-       int tidno, acno;
-
-       for (tidno = 0, tid = &an->tid[tidno];
-            tidno < WME_NUM_TID;
-            tidno++, tid++) {
-               tid->an        = an;
-               tid->tidno     = tidno;
-               tid->seq_start = tid->seq_next = 0;
-               tid->baw_size  = WME_MAX_BA;
-               tid->baw_head  = tid->baw_tail = 0;
-               tid->sched     = false;
-               tid->paused    = false;
-               tid->state &= ~AGGR_CLEANUP;
-               INIT_LIST_HEAD(&tid->buf_q);
-               acno = TID_TO_WME_AC(tidno);
-               tid->ac = &an->ac[acno];
-               tid->state &= ~AGGR_ADDBA_COMPLETE;
-               tid->state &= ~AGGR_ADDBA_PROGRESS;
-               tid->addba_exchangeattempts = 0;
-       }
-
-       for (acno = 0, ac = &an->ac[acno];
-            acno < WME_NUM_AC; acno++, ac++) {
-               ac->sched    = false;
-               INIT_LIST_HEAD(&ac->tid_q);
-
-               switch (acno) {
-               case WME_AC_BE:
-                       ac->qnum = ath_tx_get_qnum(sc,
-                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
-                       break;
-               case WME_AC_BK:
-                       ac->qnum = ath_tx_get_qnum(sc,
-                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
-                       break;
-               case WME_AC_VI:
-                       ac->qnum = ath_tx_get_qnum(sc,
-                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
-                       break;
-               case WME_AC_VO:
-                       ac->qnum = ath_tx_get_qnum(sc,
-                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
-                       break;
-               }
-       }
-}
-
-void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
-{
-       int i;
-       struct ath_atx_ac *ac, *ac_tmp;
-       struct ath_atx_tid *tid, *tid_tmp;
-       struct ath_txq *txq;
-
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (ATH_TXQ_SETUP(sc, i)) {
-                       txq = &sc->tx.txq[i];
-
-                       spin_lock(&txq->axq_lock);
-
-                       list_for_each_entry_safe(ac,
-                                       ac_tmp, &txq->axq_acq, list) {
-                               tid = list_first_entry(&ac->tid_q,
-                                               struct ath_atx_tid, list);
-                               if (tid && tid->an != an)
-                                       continue;
-                               list_del(&ac->list);
-                               ac->sched = false;
-
-                               list_for_each_entry_safe(tid,
-                                               tid_tmp, &ac->tid_q, list) {
-                                       list_del(&tid->list);
-                                       tid->sched = false;
-                                       ath_tid_drain(sc, txq, tid);
-                                       tid->state &= ~AGGR_ADDBA_COMPLETE;
-                                       tid->addba_exchangeattempts = 0;
-                                       tid->state &= ~AGGR_CLEANUP;
-                               }
-                       }
-
-                       spin_unlock(&txq->axq_lock);
-               }
-       }
-}