move a few unmaintained packages from trunk to /packages
[openwrt/svn-archive/archive.git] / package / madwifi / patches / 407-new_athinfo.patch
diff --git a/package/madwifi/patches/407-new_athinfo.patch b/package/madwifi/patches/407-new_athinfo.patch
deleted file mode 100644 (file)
index 6c512ad..0000000
+++ /dev/null
@@ -1,2352 +0,0 @@
---- a/tools/ath_info.c
-+++ b/tools/ath_info.c
-@@ -16,78 +16,8 @@
-  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-  */
--/* So here is how it works:
-- *
-- * First compile...
-- *
-- * gcc ath_info.c -o ath_info
-- *
-- * then find card's physical address
-- *
-- * lspci -v
-- *
-- * 02:02.0 Ethernet controller: Atheros Communications, Inc. AR5212 802.11abg NIC (rev 01)
-- *         Subsystem: Fujitsu Limited. Unknown device 1234
-- *         Flags: bus master, medium devsel, latency 168, IRQ 23
-- *         Memory at c2000000 (32-bit, non-prefetchable) [size=64K]
-- *         Capabilities: [44] Power Management version 2
-- *
-- * address here is 0xc2000000
-- *
-- * load madwifi-ng or madwifi-old if not already loaded (be sure the
-- * interface is down!)
-- *
-- * modprobe ath_pci
-- *
-- * OR
-- *
-- * call:
-- * setpci -s 02:02.0 command=0x41f cache_line_size=0x10
-- *
-- * to enable access to the PCI device.
-- *
-- * and we run the thing...
-- *
-- * ./ath_info 0xc2000000
-- *
-- * In order to change the regdomain to 0, call:
-- *
-- * ./ath_info -w 0xc2000000 regdomain 0
-- *
-- * to change any PCI ID value, say:
-- *
-- * ./ath_info -w 0xc2000000 <name> X
-- *
-- * with <name> ::= pci_dev_id | pci_vendor_id | pci_class |
-- *                 pci_subsys_dev_id | pci_subsys_vendor_id
-- *
-- * With newer chipsets (>= AR5004x, i.e. MAC >= AR5213), Atheros introduced
-- * write protection on the EEPROM. On a GIGABYTE GN-WI01HT you can set GPIO 4
-- * to low to be able to write the EEPROM. This depends highly on the PCB layout,
-- * so there may be different GPIO used.
-- * This program currently sets GPIO 4 to low for a MAC >= AR5213, but you can
-- * override this with the -g option:
-- *
-- * ./ath_info -g 5:0 -w 0xc2000000 regdomain X
-- *
-- * would set GPIO 5 to low (and wouldn't touch GPIO 4). -g can be given several times.
-- *
-- * The write function is currently not tested with 5210 devices.
-- *
-- * Use at your own risk, entering a false device address will have really
-- * nasty results!
-- *
-- * Writing wrong values to the PCI id fields may prevent the driver from
-- * detecting the card!
-- *
-- * Transmitting on illegal frequencies may violate state laws. Stick to the local
-- * regulations!
-- *
-- * DISCLAIMER:
-- * The authors are in no case responsible for damaged hardware or violation of
-- * local laws by operating modified hardware.
-- *
-- */
-+/* Try accepting 64-bit device address even with 32-bit userspace */
-+#define _FILE_OFFSET_BITS 64
- #include <stdio.h>
- #include <stdlib.h>
-@@ -130,109 +60,103 @@ fprintf(stderr, "#ERR %s: " fmt "\n", __
-  */
- #define AR5K_GPIODI   0x401c
--/*
-- * Common silicon revision/version values
-- */
--enum ath5k_srev_type {
--      AR5K_VERSION_VER,
--      AR5K_VERSION_REV,
--      AR5K_VERSION_RAD,
--};
--
- struct ath5k_srev_name {
-       const char *sr_name;
--      enum ath5k_srev_type sr_type;
--      u_int sr_val;
-+      u_int8_t sr_val;
- };
--#define AR5K_SREV_UNKNOWN     0xffff
--
- /* Known MAC revision numbers */
--#define AR5K_SREV_VER_AR5210  0x00
--#define AR5K_SREV_VER_AR5311  0x10
--#define AR5K_SREV_VER_AR5311A 0x20
--#define AR5K_SREV_VER_AR5311B 0x30
--#define AR5K_SREV_VER_AR5211  0x40
--#define AR5K_SREV_VER_AR5212  0x50
--#define AR5K_SREV_VER_AR5213  0x55
--#define AR5K_SREV_VER_AR5213A 0x59
--#define       AR5K_SREV_VER_AR2424    0xa0
--#define       AR5K_SREV_VER_AR5424    0xa3
--#define       AR5K_SREV_VER_AR5413    0xa4
--#define AR5K_SREV_VER_AR5414  0xa5
--#define       AR5K_SREV_VER_AR5416    0xc0
--#define       AR5K_SREV_VER_AR5418    0xca
--#define       AR5K_SREV_VER_AR2425    0xe0
--
--/* Known PHY revision nymbers */
--#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_2112    0x40
--#define AR5K_SREV_RAD_2112A   0x45
--#define AR5K_SREV_RAD_SC1     0x63    /* Found on 5413/5414 */
--#define       AR5K_SREV_RAD_SC2       0xa2    /* Found on 2424/5424 */
--#define       AR5K_SREV_RAD_5133      0xc0    /* MIMO found on 5418 */
--
--static const struct ath5k_srev_name ath5k_srev_names[] = {
--      {"5210", AR5K_VERSION_VER, AR5K_SREV_VER_AR5210},
--      {"5311", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311},
--      {"5311A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311A},
--      {"5311B", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311B},
--      {"5211", AR5K_VERSION_VER, AR5K_SREV_VER_AR5211},
--      {"5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212},
--      {"5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213},
--      {"5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A},
--      {"2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424},
--      {"5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424},
--      {"5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413},
--      {"5414", AR5K_VERSION_VER, AR5K_SREV_VER_AR5414},
--      {"5416", AR5K_VERSION_VER, AR5K_SREV_VER_AR5416},
--      {"5418", AR5K_VERSION_VER, AR5K_SREV_VER_AR5418},
--      {"2425", AR5K_VERSION_VER, AR5K_SREV_VER_AR2425},
--      {"xxxxx", AR5K_VERSION_VER, AR5K_SREV_UNKNOWN},
--      {"5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110},
--      {"5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111},
--      {"2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111},
--      {"5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112},
--      {"5112a", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A},
--      {"2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112},
--      {"2112a", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A},
--      {"SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1},
--      {"SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2},
--      {"5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133},
--      {"xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN},
-+#define AR5K_SREV_MAC_AR5210  0x00
-+#define AR5K_SREV_MAC_AR5311  0x10
-+#define AR5K_SREV_MAC_AR5311A 0x20
-+#define AR5K_SREV_MAC_AR5311B 0x30
-+#define AR5K_SREV_MAC_AR5211  0x40
-+#define AR5K_SREV_MAC_AR5212  0x50
-+#define AR5K_SREV_MAC_AR5213  0x55
-+#define AR5K_SREV_MAC_AR5213A 0x59
-+#define AR5K_SREV_MAC_AR5513  0x61
-+#define AR5K_SREV_MAC_AR2413  0x78
-+#define AR5K_SREV_MAC_AR2414  0x79
-+#define AR5K_SREV_MAC_AR2424  0xa0
-+#define AR5K_SREV_MAC_AR5424  0xa3
-+#define AR5K_SREV_MAC_AR5413  0xa4
-+#define AR5K_SREV_MAC_AR5414  0xa5
-+#define AR5K_SREV_MAC_AR5416  0xc0
-+#define AR5K_SREV_MAC_AR5418  0xca
-+#define AR5K_SREV_MAC_AR2425  0xe2
-+
-+/* Known PHY revision numbers */
-+#define AR5K_SREV_PHY_5110    0x00
-+#define AR5K_SREV_PHY_5111    0x10
-+#define AR5K_SREV_PHY_5111A   0x15
-+#define AR5K_SREV_PHY_2111    0x20
-+#define AR5K_SREV_PHY_5112    0x30
-+#define AR5K_SREV_PHY_5112A   0x35
-+#define AR5K_SREV_PHY_2112    0x40
-+#define AR5K_SREV_PHY_2112A   0x45
-+#define AR5K_SREV_PHY_SC0     0x56    /* Found on 2413/2414 */
-+#define AR5K_SREV_PHY_SC1     0x63    /* Found on 5413/5414 */
-+#define AR5K_SREV_PHY_SC2     0xa2    /* Found on 2424/5424 */
-+#define AR5K_SREV_PHY_5133    0xc0    /* MIMO found on 5418 */
-+
-+static const struct ath5k_srev_name ath5k_mac_names[] = {
-+      {"5210", AR5K_SREV_MAC_AR5210},
-+      {"5311", AR5K_SREV_MAC_AR5311},
-+      {"5311A", AR5K_SREV_MAC_AR5311A},
-+      {"5311B", AR5K_SREV_MAC_AR5311B},
-+      {"5211", AR5K_SREV_MAC_AR5211},
-+      {"5212", AR5K_SREV_MAC_AR5212},
-+      {"5213", AR5K_SREV_MAC_AR5213},
-+      {"5213A", AR5K_SREV_MAC_AR5213A},
-+      {"2413", AR5K_SREV_MAC_AR2413},
-+      {"2414", AR5K_SREV_MAC_AR2414},
-+      {"2424", AR5K_SREV_MAC_AR2424},
-+      {"5424", AR5K_SREV_MAC_AR5424},
-+      {"5413", AR5K_SREV_MAC_AR5413},
-+      {"5414", AR5K_SREV_MAC_AR5414},
-+      {"5416", AR5K_SREV_MAC_AR5416},
-+      {"5418", AR5K_SREV_MAC_AR5418},
-+      {"2425", AR5K_SREV_MAC_AR2425},
-+};
-+
-+static const struct ath5k_srev_name ath5k_phy_names[] = {
-+      {"5110", AR5K_SREV_PHY_5110},
-+      {"5111", AR5K_SREV_PHY_5111},
-+      {"2111", AR5K_SREV_PHY_2111},
-+      {"5112", AR5K_SREV_PHY_5112},
-+      {"5112A", AR5K_SREV_PHY_5112A},
-+      {"2112", AR5K_SREV_PHY_2112},
-+      {"2112A", AR5K_SREV_PHY_2112A},
-+      {"SChip", AR5K_SREV_PHY_SC0},
-+      {"SChip", AR5K_SREV_PHY_SC1},
-+      {"SChip", AR5K_SREV_PHY_SC2},
-+      {"5133", AR5K_SREV_PHY_5133},
- };
- /*
-  * 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
-+#define AR5K_SREV_VER         0x000000f0      /* Mask for version */
-+#define AR5K_SREV_REV         0x000000ff      /* Mask for revision */
- /*
-  * PHY chip revision register
-  */
--#define       AR5K_PHY_CHIP_ID                0x9818
-+#define AR5K_PHY_CHIP_ID              0x9818
- /*
-  * PHY register
-  */
--#define       AR5K_PHY_BASE                   0x9800
--#define       AR5K_PHY(_n)                    (AR5K_PHY_BASE + ((_n) << 2))
-+#define AR5K_PHY_BASE                 0x9800
-+#define AR5K_PHY(_n)                  (AR5K_PHY_BASE + ((_n) << 2))
- #define AR5K_PHY_SHIFT_2GHZ           0x00004007
- #define AR5K_PHY_SHIFT_5GHZ           0x00000007
- #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 only */
--#define       AR5K_RESET_CTL_BASEBAND 0x00000002      /* Baseband reset (5211/5212) */
-+#define AR5K_RESET_CTL_BASEBAND       0x00000002      /* Baseband reset (5211/5212) */
- #define AR5K_RESET_CTL_MAC    0x00000004      /* MAC reset (PCU+Baseband?) -5210 only */
- #define AR5K_RESET_CTL_PHY    0x00000008      /* PHY reset -5210 only */
- #define AR5K_RESET_CTL_PCI    0x00000010      /* PCI Core reset (interrupts etc) */
-@@ -253,7 +177,7 @@ static const struct ath5k_srev_name ath5
- #define AR5K_SLEEP_CTL_SLE_UNITS      0x00000008      /* not on 5210 */
- #define AR5K_PCICFG                   0x4010  /* Register Address */
--#define AR5K_PCICFG_EEAE              0x00000001      /* Eeprom access enable [5210] */
-+#define AR5K_PCICFG_EEAE              0x00000001      /* EEPROM access enable [5210] */
- #define AR5K_PCICFG_CLKRUNEN          0x00000004      /* CLKRUN enable [5211+] */
- #define AR5K_PCICFG_EESIZE            0x00000018      /* Mask for EEPROM size [5211+] */
- #define AR5K_PCICFG_EESIZE_S          3
-@@ -264,26 +188,118 @@ static const struct ath5k_srev_name ath5
- #define AR5K_PCICFG_SPWR_DN           0x00010000      /* Mask for power status (5210) */
--#define AR5K_EEPROM_BASE              0x6000
-+#define AR5K_EEPROM_BASE      0x6000
--#define AR5K_EEPROM_MAGIC             0x003d  /* Offset for EEPROM Magic number */
-+/*
-+ * 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_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
-+#define AR5K_EEPROM_REG_DOMAIN                0x00bf  /* EEPROM regdom */
-+#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
-+#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
-+
-+#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_T_5GHZ_DIS(_v)        (((_v) >> 15) & 0x1)    /* Disable turbo for 5GHz (?) */
-+#define AR5K_EEPROM_HDR_RFKILL(_v)    (((_v) >> 14) & 0x1)    /* Device has RFKill support */
-+
-+/* 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_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) ((int8_t)(((_v) >> 8) & 0xff))
-+#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff))
-+
-+/* 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_CHANNELS_5GHZ(_v) AR5K_EEPROM_OFF(_v, 0x0100, 0x0150)     /* List of calibrated 5GHz chans */
-+#define       AR5K_EEPROM_TARGET_PWR_OFF_11A(_v)      AR5K_EEPROM_OFF(_v, AR5K_EEPROM_CHANNELS_5GHZ(_v) + 0x0055, 0x0000)
-+#define       AR5K_EEPROM_TARGET_PWR_OFF_11B(_v)      AR5K_EEPROM_OFF(_v, AR5K_EEPROM_CHANNELS_5GHZ(_v) + 0x0065, 0x0010)
-+#define       AR5K_EEPROM_TARGET_PWR_OFF_11G(_v)      AR5K_EEPROM_OFF(_v, AR5K_EEPROM_CHANNELS_5GHZ(_v) + 0x0069, 0x0014)
-+
-+/* [3.1 - 3.3] */
-+#define AR5K_EEPROM_OBDB0_2GHZ                0x00ec
-+#define AR5K_EEPROM_OBDB1_2GHZ                0x00ed
-+
- /*
-  * EEPROM data register
-  */
- #define AR5K_EEPROM_DATA_5211 0x6004
- #define AR5K_EEPROM_DATA_5210 0x6800
--#define       AR5K_EEPROM_DATA        (mac_version == AR5K_SREV_VER_AR5210 ? \
-+#define AR5K_EEPROM_DATA      (mac_version == AR5K_SREV_MAC_AR5210 ? \
-                               AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211)
- /*
-  * EEPROM command register
-  */
--#define AR5K_EEPROM_CMD               0x6008  /* Register Addres */
-+#define AR5K_EEPROM_CMD               0x6008                  /* Register Address */
- #define AR5K_EEPROM_CMD_READ  0x00000001      /* EEPROM read */
- #define AR5K_EEPROM_CMD_WRITE 0x00000002      /* EEPROM write */
- #define AR5K_EEPROM_CMD_RESET 0x00000004      /* EEPROM reset */
-@@ -291,43 +307,163 @@ static const struct ath5k_srev_name ath5
- /*
-  * 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      (mac_version == AR5K_SREV_VER_AR5210 ? \
-+#define AR5K_EEPROM_STAT_5210 0x6c00                  /* Register Address [5210] */
-+#define AR5K_EEPROM_STAT_5211 0x600c                  /* Register Address [5211+] */
-+#define AR5K_EEPROM_STATUS    (mac_version == AR5K_SREV_MAC_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 */
--#define AR5K_EEPROM_REG_DOMAIN                0x00bf  /* Offset for EEPROM regulatory domain */
--#define AR5K_EEPROM_INFO_BASE         0x00c0  /* Offset for 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_MODE_11A          0
--#define AR5K_EEPROM_MODE_11B          1
--#define AR5K_EEPROM_MODE_11G          2
-+/*
-+ * EEPROM config register (?)
-+ */
-+#define AR5K_EEPROM_CFG       0x6010
--#define AR5K_EEPROM_VERSION           AR5K_EEPROM_INFO(1)
-+/* 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_MAX_CHAN          10
-+#define AR5K_EEPROM_N_PCDAC           11
-+#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_XPD_PER_CHANNEL 4
-+#define AR5K_EEPROM_N_XPD0_POINTS     4
-+#define AR5K_EEPROM_N_XPD3_POINTS     3
-+#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
-+
-+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,
-+};
--#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)  /* Device has a support */
--#define AR5K_EEPROM_HDR_11B(_v)               (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)  /* Device has b support */
--#define AR5K_EEPROM_HDR_11G(_v)               (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)  /* Device has g support */
--#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_T_5GHZ_DIS(_v)        (((_v) >> 15) & 0x1)    /* Disable turbo for 5Ghz (?) */
--#define AR5K_EEPROM_HDR_RFKILL(_v)    (((_v) >> 14) & 0x1)    /* Device has RFKill support */
-+/* Per channel calibration data, used for power table setup */
-+struct ath5k_chan_pcal_info {
-+      u_int16_t       freq; /* Frequency */
-+      /* Power levels in dBm * 4 units */
-+      int16_t         pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
-+      int16_t         pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
-+      /* PCDAC tables in dBm * 2 units */
-+      u_int16_t       pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
-+      u_int16_t       pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
-+      /* Max available power */
-+      u_int16_t       max_pwr;
-+};
--/* Misc values available since EEPROM 4.0 */
--#define AR5K_EEPROM_MISC0             0x00c4
--#define AR5K_EEPROM_EARSTART(_v)      ((_v) & 0xfff)
--#define AR5K_EEPROM_EEMAP(_v)         (((_v) >> 14) & 0x3)
--#define AR5K_EEPROM_MISC1             0x00c5
--#define AR5K_EEPROM_TARGET_PWRSTART(_v)       ((_v) & 0xfff)
--#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v)       (((_v) >> 14) & 0x1)
-+/* Per rate calibration data for each mode, used for power table setup */
-+struct ath5k_rate_pcal_info {
-+      u_int16_t       freq; /* Frequency */
-+      /* Power level for 6-24Mbit/s rates */
-+      u_int16_t       target_power_6to24;
-+      /* Power level for 36Mbit rate */
-+      u_int16_t       target_power_36;
-+      /* Power level for 48Mbit rate */
-+      u_int16_t       target_power_48;
-+      /* Power level for 54Mbit rate */
-+      u_int16_t       target_power_54;
-+};
-+
-+/* EEPROM calibration data */
-+struct ath5k_eeprom_info {
-+
-+      /* Header information */
-+      u_int16_t       ee_magic;
-+      u_int16_t       ee_protect;
-+      u_int16_t       ee_regdomain;
-+      u_int16_t       ee_version;
-+      u_int16_t       ee_header;
-+      u_int16_t       ee_ant_gain;
-+      u_int16_t       ee_misc0;
-+      u_int16_t       ee_misc1;
-+      u_int16_t       ee_cck_ofdm_gain_delta;
-+      u_int16_t       ee_cck_ofdm_power_delta;
-+      u_int16_t       ee_scaled_cck_delta;
-+
-+      /* Used for tx thermal adjustment (eeprom_init, rfregs) */
-+      u_int16_t       ee_tx_clip;
-+      u_int16_t       ee_pwd_84;
-+      u_int16_t       ee_pwd_90;
-+      u_int16_t       ee_gain_select;
-+
-+      /* RF Calibration settings (reset, rfregs) */
-+      u_int16_t       ee_i_cal[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_q_cal[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_fixed_bias[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_turbo_max_power[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_xr_power[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_switch_settling[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_ant_tx_rx[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
-+      u_int16_t       ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
-+      u_int16_t       ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
-+      u_int16_t       ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_thr_62[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_xlna_gain[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_xpd[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_x_gain[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_i_gain[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
-+
-+      /* Power calibration data */
-+      u_int16_t       ee_false_detect[AR5K_EEPROM_N_MODES];
-+      u_int16_t       ee_cal_piers_a;
-+      struct ath5k_chan_pcal_info     ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
-+      u_int16_t       ee_cal_piers_b;
-+      struct ath5k_chan_pcal_info     ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN];
-+      u_int16_t       ee_cal_piers_g;
-+      struct ath5k_chan_pcal_info     ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN];
-+      /* Per rate target power levels */
-+      u_int16_t       ee_rate_target_pwr_num_a;
-+      struct ath5k_rate_pcal_info     ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
-+      u_int16_t       ee_rate_target_pwr_num_b;
-+      struct ath5k_rate_pcal_info     ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN];
-+      u_int16_t       ee_rate_target_pwr_num_g;
-+      struct ath5k_rate_pcal_info     ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN];
-+
-+      /* Conformance test limits (Unused) */
-+      u_int16_t       ee_ctls;
-+      u_int16_t       ee_ctl[AR5K_EEPROM_MAX_CTLS];
-+
-+      /* Noise Floor Calibration settings */
-+      int16_t         ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
-+      int8_t          ee_adc_desired_size[AR5K_EEPROM_N_MODES];
-+      int8_t          ee_pga_desired_size[AR5K_EEPROM_N_MODES];
-+
-+      u_int32_t       ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
-+};
- /*
-  * Read data by masking
-@@ -350,7 +486,6 @@ static const struct ath5k_srev_name ath5
-       (*((volatile u_int32_t *)(mem + (_reg))) = (_val))
- #endif
--
- #define AR5K_REG_ENABLE_BITS(_reg, _flags)    \
-       AR5K_REG_WRITE(_reg, AR5K_REG_READ(_reg) | (_flags))
-@@ -359,7 +494,12 @@ static const struct ath5k_srev_name ath5
- #define AR5K_TUNE_REGISTER_TIMEOUT            20000
--/* names for eeprom fields */
-+#define AR5K_EEPROM_READ(_o, _v) do {                                 \
-+      if ((ret = ath5k_hw_eeprom_read(mem, (_o), &(_v), mac_version)) != 0)   \
-+              return (ret);                                           \
-+} while (0)
-+
-+/* Names for EEPROM fields */
- struct eeprom_entry {
-       const char *name;
-       int addr;
-@@ -375,8 +515,6 @@ static const struct eeprom_entry eeprom_
-       {"regdomain", AR5K_EEPROM_REG_DOMAIN},
- };
--static const int eeprom_addr_len = sizeof(eeprom_addr) / sizeof(eeprom_addr[0]);
--
- static int force_write = 0;
- static int verbose = 0;
-@@ -398,8 +536,8 @@ static u_int32_t ath5k_hw_bitswap(u_int3
- /*
-  * Get the PHY Chip revision
-  */
--static u_int16_t
--ath5k_hw_radio_revision(u_int16_t mac_version, void *mem, u_int8_t chip)
-+static u_int16_t ath5k_hw_radio_revision(u_int16_t mac_version, void *mem,
-+                                       u_int8_t chip)
- {
-       int i;
-       u_int32_t srev;
-@@ -427,7 +565,7 @@ ath5k_hw_radio_revision(u_int16_t mac_ve
-       for (i = 0; i < 8; i++)
-               AR5K_REG_WRITE(AR5K_PHY(0x20), 0x00010000);
--      if (mac_version == AR5K_SREV_VER_AR5210) {
-+      if (mac_version == AR5K_SREV_MAC_AR5210) {
-               srev = AR5K_REG_READ(AR5K_PHY(256) >> 28) & 0xf;
-               ret = (u_int16_t)ath5k_hw_bitswap(srev, 4) + 1;
-@@ -447,9 +585,8 @@ ath5k_hw_radio_revision(u_int16_t mac_ve
- /*
-  * Write to EEPROM
-  */
--static int
--ath5k_hw_eeprom_write(void *mem, u_int32_t offset, u_int16_t data,
--                    u_int8_t mac_version)
-+static int ath5k_hw_eeprom_write(void *mem, u_int32_t offset, u_int16_t data,
-+                               u_int8_t mac_version)
- {
-       u_int32_t status, timeout;
-@@ -457,7 +594,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
-        * Initialize EEPROM access
-        */
--      if (mac_version == AR5K_SREV_VER_AR5210) {
-+      if (mac_version == AR5K_SREV_MAC_AR5210) {
-               AR5K_REG_ENABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_EEAE);
-@@ -466,7 +603,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
-       } else {
-               /* not 5210 */
--              /* reset eeprom access */
-+              /* reset EEPROM access */
-               AR5K_REG_WRITE(AR5K_EEPROM_CMD, AR5K_EEPROM_CMD_RESET);
-               usleep(5);
-@@ -484,7 +621,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
-               status = AR5K_REG_READ(AR5K_EEPROM_STATUS);
-               if (status & AR5K_EEPROM_STAT_WRDONE) {
-                       if (status & AR5K_EEPROM_STAT_WRERR) {
--                              err("eeprom write access to 0x%04x failed",
-+                              err("EEPROM write access to 0x%04x failed",
-                                   offset);
-                               return 1;
-                       }
-@@ -499,16 +636,15 @@ ath5k_hw_eeprom_write(void *mem, u_int32
- /*
-  * Read from EEPROM
-  */
--static int
--ath5k_hw_eeprom_read(void *mem, u_int32_t offset, u_int16_t *data,
--                   u_int8_t mac_version)
-+static int ath5k_hw_eeprom_read(void *mem, u_int32_t offset, u_int16_t *data,
-+                              u_int8_t mac_version)
- {
-       u_int32_t status, timeout;
-       /*
-        * Initialize EEPROM access
-        */
--      if (mac_version == AR5K_SREV_VER_AR5210) {
-+      if (mac_version == AR5K_SREV_MAC_AR5210) {
-               AR5K_REG_ENABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_EEAE);
-               (void)AR5K_REG_READ(AR5K_EEPROM_BASE + (4 * offset));
-       } else {
-@@ -531,50 +667,701 @@ ath5k_hw_eeprom_read(void *mem, u_int32_
-       return 1;
- }
--static const char *ath5k_hw_get_part_name(enum ath5k_srev_type type,
--                                        u_int32_t val)
-+/*
-+ * Translate binary channel representation in EEPROM to frequency
-+ */
-+static u_int16_t ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee,
-+                                     u_int16_t bin, unsigned int mode)
- {
--      const char *name = "xxxxx";
--      int i;
-+      u_int16_t val;
--      for (i = 0; i < ARRAY_SIZE(ath5k_srev_names); i++) {
--              if (ath5k_srev_names[i].sr_type != type ||
--                  ath5k_srev_names[i].sr_val == AR5K_SREV_UNKNOWN)
--                      continue;
--              if ((val & 0xff) < ath5k_srev_names[i + 1].sr_val) {
--                      name = ath5k_srev_names[i].sr_name;
-+      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;
-+}
-+
-+/*
-+ * Read antenna info from EEPROM
-+ */
-+static int ath5k_eeprom_read_ants(void *mem, u_int8_t mac_version,
-+                                struct ath5k_eeprom_info *ee,
-+                                u_int32_t *offset, unsigned int mode)
-+{
-+      u_int32_t o = *offset;
-+      u_int16_t val;
-+      int ret, i = 0;
-+
-+      AR5K_EEPROM_READ(o++, val);
-+      ee->ee_switch_settling[mode]    = (val >> 8) & 0x7f;
-+      ee->ee_ant_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 */
-+      ee->ee_antenna[mode][0] =
-+          (ee->ee_ant_control[mode][0] << 4) | 0x1;
-+      ee->ee_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);
-+      ee->ee_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 from EEPROM
-+ */
-+static int ath5k_eeprom_read_modes(void *mem, u_int8_t mac_version,
-+                                 struct ath5k_eeprom_info *ee,
-+                                 u_int32_t *offset, unsigned int mode)
-+{
-+      u_int32_t o = *offset;
-+      u_int16_t val;
-+      int ret;
-+
-+      AR5K_EEPROM_READ(o++, val);
-+      ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
-+      ee->ee_thr_62[mode]             = val & 0xff;
-+
-+      if (ee->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 (ee->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 (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
-+              ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
-+
-+      if (ee->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 (ee->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 (ee->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 (ee->ee_version >= AR5K_EEPROM_VERSION_4_6 &&
-+          mode == AR5K_EEPROM_MODE_11G)
-+              ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
-+
-+      /* return new offset */
-+      *offset = o;
-+
-+      return 0;
-+}
-+
-+/*
-+ * Read per channel calibration info from EEPROM
-+ * This doesn't work on 2112+ chips (EEPROM versions >= 4.6),
-+ * I only tested it on 5213 + 5112. This is still work in progress...
-+ *
-+ * 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) and we try to "correct" this curve using offests
-+ * we pass on to phy chip (baseband -> before amplifier) so that it can
-+ * use acurate 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 scale (to create the full table for these channels) and
-+ * interpolate (in order to create the table for any channel).
-+ */
-+static int ath5k_eeprom_read_pcal_info(void *mem, u_int8_t mac_version,
-+                                     struct ath5k_eeprom_info *ee,
-+                                     u_int32_t *offset, unsigned int mode)
-+{
-+      u_int32_t o = *offset;
-+      unsigned int i, c;
-+      int ret;
-+      u_int16_t val;
-+      struct ath5k_chan_pcal_info *chan_pcal_info;
-+      u_int16_t cal_piers;
-+
-+      switch (mode) {
-+      case AR5K_EEPROM_MODE_11A:
-+              chan_pcal_info = ee->ee_pwr_cal_a;
-+              cal_piers = ee->ee_cal_piers_a;
-+              break;
-+      case AR5K_EEPROM_MODE_11B:
-+              chan_pcal_info = ee->ee_pwr_cal_b;
-+              cal_piers = ee->ee_cal_piers_b;
-+              break;
-+      case AR5K_EEPROM_MODE_11G:
-+              chan_pcal_info = ee->ee_pwr_cal_g;
-+              cal_piers = ee->ee_cal_piers_g;
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      for (i = 0; i < cal_piers; i++) {
-+              /* Power values in dBm * 4 */
-+              for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
-+                      AR5K_EEPROM_READ(o++, val);
-+                      chan_pcal_info[i].pwr_x0[c] = (val & 0xff);
-+                      chan_pcal_info[i].pwr_x0[++c] = ((val >> 8) & 0xff);
-+              }
-+
-+              /* PCDAC steps (dBm * 2) */
-+              AR5K_EEPROM_READ(o++, val);
-+              chan_pcal_info[i].pcdac_x0[1] = (val & 0x1f);
-+              chan_pcal_info[i].pcdac_x0[2] = ((val >> 5) & 0x1f);
-+              chan_pcal_info[i].pcdac_x0[3] = ((val >> 10) & 0x1f);
-+
-+              /* No idea what these power levels are for (4 xpds ?)
-+                 I got zeroes on my card and the EEPROM info
-+                 dumps we found on the net also have weird values */
-+              AR5K_EEPROM_READ(o++, val);
-+              chan_pcal_info[i].pwr_x3[0] = (val & 0xff);
-+              chan_pcal_info[i].pwr_x3[1] = ((val >> 8) & 0xff);
-+
-+              AR5K_EEPROM_READ(o++, val);
-+              chan_pcal_info[i].pwr_x3[2] = (val & 0xff);
-+              /* It's weird but they put it here, that's the
-+                 PCDAC starting step */
-+              chan_pcal_info[i].pcdac_x0[0] = ((val >> 8) & 0xff);
-+
-+              /* Static values seen on EEPROM info dumps */
-+              chan_pcal_info[i].pcdac_x3[0] = 20;
-+              chan_pcal_info[i].pcdac_x3[1] = 35;
-+              chan_pcal_info[i].pcdac_x3[2] = 63;
-+
-+              /* Last xpd0 power level is also channel maximum */
-+              chan_pcal_info[i].max_pwr = chan_pcal_info[i].pwr_x0[3];
-+
-+              /* Recreate pcdac_x0 table for this channel using pcdac steps */
-+              chan_pcal_info[i].pcdac_x0[1] += chan_pcal_info[i].pcdac_x0[0];
-+              chan_pcal_info[i].pcdac_x0[2] += chan_pcal_info[i].pcdac_x0[1];
-+              chan_pcal_info[i].pcdac_x0[3] += chan_pcal_info[i].pcdac_x0[2];
-+      }
-+
-+      /* return new offset */
-+      (*offset) = o;
-+
-+      return 0;
-+}
-+
-+/*
-+ * 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(void *mem,
-+                                                u_int8_t mac_version,
-+                                                struct ath5k_eeprom_info *ee,
-+                                                u_int32_t *offset,
-+                                                unsigned int mode)
-+{
-+      u_int32_t o = *offset;
-+      u_int16_t val;
-+      struct ath5k_rate_pcal_info *rate_pcal_info;
-+      u_int16_t *rate_target_pwr_num;
-+      int ret, i;
-+
-+      switch (mode) {
-+      case AR5K_EEPROM_MODE_11A:
-+              rate_pcal_info = ee->ee_rate_tpwr_a;
-+              ee->ee_rate_target_pwr_num_a = AR5K_EEPROM_N_5GHZ_CHAN;
-+              rate_target_pwr_num = &ee->ee_rate_target_pwr_num_a;
-+              break;
-+      case AR5K_EEPROM_MODE_11B:
-+              rate_pcal_info = ee->ee_rate_tpwr_b;
-+              ee->ee_rate_target_pwr_num_b = 2; /* 3rd is g mode'ss 1st */
-+              rate_target_pwr_num = &ee->ee_rate_target_pwr_num_b;
-+              break;
-+      case AR5K_EEPROM_MODE_11G:
-+              rate_pcal_info = ee->ee_rate_tpwr_g;
-+              ee->ee_rate_target_pwr_num_g = AR5K_EEPROM_N_2GHZ_CHAN;
-+              rate_target_pwr_num = &ee->ee_rate_target_pwr_num_g;
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      /* Different freq mask for older eeproms (<= v3.2) */
-+      if(ee->ee_version <= 0x3002){
-+              for (i = 0; i < (*rate_target_pwr_num); i++) {
-+                      AR5K_EEPROM_READ(o++, 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(o++, 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(o++, 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(o++, 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 new offset */
-+      (*offset) = o;
-+
-+      return 0;
-+}
-+
-+/*
-+ * Initialize EEPROM & capabilities data
-+ */
-+static int ath5k_eeprom_init(void *mem, u_int8_t mac_version,
-+                           struct ath5k_eeprom_info *ee)
-+{
-+      unsigned int mode, i;
-+      int ret;
-+      u_int32_t offset;
-+      u_int16_t val;
-+
-+      /* Initial TX thermal adjustment values */
-+      ee->ee_tx_clip = 4;
-+      ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
-+      ee->ee_gain_select = 1;
-+
-+      /*
-+       * Read values from EEPROM and store them in the capability structure
-+       */
-+      AR5K_EEPROM_READ(AR5K_EEPROM_MAGIC, ee->ee_magic);
-+      AR5K_EEPROM_READ(AR5K_EEPROM_PROTECT, ee->ee_protect);
-+      AR5K_EEPROM_READ(AR5K_EEPROM_REG_DOMAIN, ee->ee_regdomain);
-+      AR5K_EEPROM_READ(AR5K_EEPROM_VERSION, ee->ee_version);
-+      AR5K_EEPROM_READ(AR5K_EEPROM_HDR, ee->ee_header);
-+
-+      /* Return if we have an old EEPROM */
-+      if (ee->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) {
-+              AR5K_PRINTF("Invalid EEPROM checksum 0x%04x\n", cksum);
-+              return -EIO;
-+      }
-+#endif
-+
-+      AR5K_EEPROM_READ(AR5K_EEPROM_ANT_GAIN(ee->ee_version), ee->ee_ant_gain);
-+
-+      if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
-+              AR5K_EEPROM_READ(AR5K_EEPROM_MISC0, ee->ee_misc0);
-+              AR5K_EEPROM_READ(AR5K_EEPROM_MISC1, ee->ee_misc1);
-+      }
-+
-+      if (ee->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;
-+      }
-+
-+      /*
-+       * Get conformance test limit values
-+       */
-+      offset = AR5K_EEPROM_CTL(ee->ee_version);
-+      ee->ee_ctls = 0;
-+
-+      for (i = 0; i < AR5K_EEPROM_N_CTLS(ee->ee_version); i++) {
-+              AR5K_EEPROM_READ(offset++, val);
-+
-+              if (((val >> 8) & 0xff) == 0)
-+                      break;
-+
-+              ee->ee_ctl[i] = (val >> 8) & 0xff;
-+              ee->ee_ctls++;
-+
-+              if ((val & 0xff) == 0)
-                       break;
-+
-+              ee->ee_ctl[i + 1] = val & 0xff;
-+              ee->ee_ctls++;
-+      }
-+
-+      /*
-+       * Get values for 802.11a (5GHz)
-+       */
-+      mode = AR5K_EEPROM_MODE_11A;
-+
-+      ee->ee_turbo_max_power[mode] =
-+          AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
-+
-+      offset = AR5K_EEPROM_MODES_11A(ee->ee_version);
-+
-+      ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      AR5K_EEPROM_READ(offset++, val);
-+      ee->ee_adc_desired_size[mode]   = (int8_t)((val >> 8) & 0xff);
-+      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(offset++, 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;
-+
-+      ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1) {
-+              AR5K_EEPROM_READ(offset++, val);
-+              ee->ee_margin_tx_rx[mode] = val & 0x3f;
-+      }
-+
-+      /*
-+       * Get values for 802.11b (2.4GHz)
-+       */
-+      mode = AR5K_EEPROM_MODE_11B;
-+      offset = AR5K_EEPROM_MODES_11B(ee->ee_version);
-+
-+      ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      AR5K_EEPROM_READ(offset++, val);
-+      ee->ee_adc_desired_size[mode]   = (int8_t)((val >> 8) & 0xff);
-+      ee->ee_ob[mode][1]              = (val >> 4) & 0x7;
-+      ee->ee_db[mode][1]              = val & 0x7;
-+
-+      ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
-+              AR5K_EEPROM_READ(offset++, val);
-+
-+              ee->ee_cal_piers_b = 0;
-+
-+              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_cal_piers_b++;
-+
-+              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_cal_piers_b++;
-+
-+              AR5K_EEPROM_READ(offset++, 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_cal_piers_b++;
-+      }
-+
-+      if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1)
-+              ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
-+
-+      /*
-+       * Get values for 802.11g (2.4GHz)
-+       */
-+      mode = AR5K_EEPROM_MODE_11G;
-+      offset = AR5K_EEPROM_MODES_11G(ee->ee_version);
-+
-+      ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      AR5K_EEPROM_READ(offset++, val);
-+      ee->ee_adc_desired_size[mode]   = (signed short int)((val >> 8) & 0xff);
-+      ee->ee_ob[mode][1]              = (val >> 4) & 0x7;
-+      ee->ee_db[mode][1]              = val & 0x7;
-+
-+      ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
-+              AR5K_EEPROM_READ(offset++, val);
-+
-+              ee->ee_cal_piers_g = 0;
-+
-+              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_cal_piers_g++;
-+
-+              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_cal_piers_g++;
-+
-+              AR5K_EEPROM_READ(offset++, val);
-+              ee->ee_turbo_max_power[mode] = val & 0x7f;
-+              ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
-+
-+              AR5K_EEPROM_READ(offset++, 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_cal_piers_g++;
-+
-+              if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1)
-+                      ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
-+
-+              AR5K_EEPROM_READ(offset++, val);
-+              ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
-+              ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
-+
-+              if (ee->ee_version >= AR5K_EEPROM_VERSION_4_2) {
-+                      AR5K_EEPROM_READ(offset++, val);
-+                      ee->ee_cck_ofdm_gain_delta = val & 0xff;
-               }
-       }
--      return (name);
-+      /*
-+       * Read 5GHz EEPROM channels
-+       */
-+      offset = AR5K_EEPROM_CHANNELS_5GHZ(ee->ee_version);
-+      ee->ee_cal_piers_a = 0;
-+      for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
-+              AR5K_EEPROM_READ(offset++, val);
-+
-+              if ((val & 0xff) == 0)
-+                      break;
-+
-+              ee->ee_pwr_cal_a[i].freq =
-+                      ath5k_eeprom_bin2freq(ee, val & 0xff, AR5K_EEPROM_MODE_11A);
-+              ee->ee_cal_piers_a++;
-+
-+              if (((val >> 8) & 0xff) == 0)
-+                      break;
-+
-+              ee->ee_pwr_cal_a[++i].freq =
-+                      ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, AR5K_EEPROM_MODE_11A);
-+              ee->ee_cal_piers_a++;
-+
-+      }
-+
-+      /*
-+       * Read power calibration info
-+       */
-+      mode = AR5K_EEPROM_MODE_11A;
-+      ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      mode = AR5K_EEPROM_MODE_11B;
-+      ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      mode = AR5K_EEPROM_MODE_11G;
-+      ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+
-+      /*
-+       * Read per rate target power info
-+       */
-+      offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) + AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
-+      mode = AR5K_EEPROM_MODE_11A;
-+      ret = ath5k_eeprom_read_target_rate_pwr_info(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) + AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
-+      mode = AR5K_EEPROM_MODE_11B;
-+      ret = ath5k_eeprom_read_target_rate_pwr_info(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) + AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
-+      mode = AR5K_EEPROM_MODE_11G;
-+      ret = ath5k_eeprom_read_target_rate_pwr_info(mem, mac_version, ee, &offset, mode);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static const char *ath5k_hw_get_mac_name(u_int8_t val)
-+{
-+      static char name[16];
-+      unsigned int i;
-+
-+      for (i = 0; i < ARRAY_SIZE(ath5k_mac_names); i++) {
-+              if (val <= ath5k_mac_names[i].sr_val)
-+                      break;
-+      }
-+
-+      if (val == ath5k_mac_names[i].sr_val)
-+              return ath5k_mac_names[i].sr_name;
-+
-+      snprintf(name, sizeof(name), "%s+", ath5k_mac_names[i - 1].sr_name);
-+      return name;
-+}
-+
-+static const char *ath5k_hw_get_phy_name(u_int8_t val)
-+{
-+      const char *name = "?????";
-+      unsigned int i;
-+
-+      for (i = 0; i < ARRAY_SIZE(ath5k_phy_names); i++) {
-+              if (val < ath5k_phy_names[i + 1].sr_val) {
-+                      name = ath5k_phy_names[i].sr_name;
-+                      break;
-+              }
-+      }
-+
-+      return name;
- }
- /* returns -1 on unknown name */
- static int eeprom_name2addr(const char *name)
- {
--      int i;
-+      unsigned int i;
-+
-       if (!name || !name[0])
-               return -1;
--      for (i = 0; i < eeprom_addr_len; i++)
-+      for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
-               if (!strcmp(name, eeprom_addr[i].name))
-                       return eeprom_addr[i].addr;
-       return -1;
--}                             /* eeprom_name2addr */
-+}
- /* returns "<unknown>" on unknown address */
- static const char *eeprom_addr2name(int addr)
- {
--      int i;
--      for (i = 0; i < eeprom_addr_len; i++)
-+      unsigned int i;
-+
-+      for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
-               if (eeprom_addr[i].addr == addr)
-                       return eeprom_addr[i].name;
-       return "<unknown>";
--}                             /* eeprom_addr2name */
-+}
--static int
--do_write_pairs(int anr, int argc, char **argv, unsigned char *mem,
--             int mac_version)
-+static int do_write_pairs(int anr, int argc, char **argv, unsigned char *mem,
-+                        int mac_version)
- {
- #define MAX_NR_WRITES 16
-       struct {
-@@ -635,7 +1422,7 @@ do_write_pairs(int anr, int argc, char *
-               }
-               anr++;
-               i++;
--      }                       /* while (anr < (argc-1)) */
-+      }
-       if (!(wr_ops_len = i)) {
-               err("no (addr,val) pairs given");
-@@ -702,20 +1489,22 @@ do_write_pairs(int anr, int argc, char *
-       }
-       return errors ? 11 : 0;
--}                             /* do_write_pairs */
-+}
- static void usage(const char *n)
- {
--      int i;
-+      unsigned int i;
--      fprintf(stderr, "%s [-w [-g N:M]] [-v] [-f] [-d] <base_address> "
-+      fprintf(stderr, "%s [-w [-g N:M]] [-v] [-f] [-d] [-R addr] [-W addr val] <base_address> "
-               "[<name1> <val1> [<name2> <val2> ...]]\n\n", n);
-       fprintf(stderr,
-               "-w      write values into EEPROM\n"
-               "-g N:M  set GPIO N to level M (only used with -w)\n"
-               "-v      verbose output\n"
-               "-f      force; suppress question before writing\n"
--              "-d      dump eeprom (file 'ath-eeprom-dump.bin' and screen)\n"
-+              "-d      dump EEPROM (file 'ath-eeprom-dump.bin' and screen)\n"
-+              "-R <addr>       read register at <addr> (hex)\n"
-+              "-W <addr> <val> write <val> (hex) into register at <addr> (hex)\n"
-               "<base_address>  device base address (see lspci output)\n\n");
-       fprintf(stderr,
-@@ -725,8 +1514,8 @@ static void usage(const char *n)
-               "  %s -w <base_address> regdomain N\n\n"
-               "- set a PCI id field to value N:\n"
-               "  %s -w <base_address> <field> N\n"
--              "  where <field> is on of:\n    ", n, n, n);
--      for (i = 0; i < eeprom_addr_len; i++)
-+              "  where <field> is one of:\n    ", n, n, n);
-+      for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
-               fprintf(stderr, " %s", eeprom_addr[i].name);
-       fprintf(stderr, "\n\n");
-       fprintf(stderr,
-@@ -739,19 +1528,457 @@ static void usage(const char *n)
-               "unlawful radio transmissions!\n\n");
- }
-+static void dump_capabilities(struct ath5k_eeprom_info *ee)
-+{
-+      u_int8_t has_a, has_b, has_g, has_rfkill, turbog_dis, turboa_dis;
-+      u_int8_t xr2_dis, xr5_dis, has_crystal;
-+
-+      has_a = AR5K_EEPROM_HDR_11A(ee->ee_header);
-+      has_b = AR5K_EEPROM_HDR_11B(ee->ee_header);
-+      has_g = AR5K_EEPROM_HDR_11G(ee->ee_header);
-+      has_rfkill = AR5K_EEPROM_HDR_RFKILL(ee->ee_header);
-+      has_crystal = AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1);
-+      turbog_dis = AR5K_EEPROM_HDR_T_2GHZ_DIS(ee->ee_header);
-+      turboa_dis = AR5K_EEPROM_HDR_T_5GHZ_DIS(ee->ee_header);
-+      xr2_dis = AR5K_EEPROM_HDR_XR2_DIS(ee->ee_misc0);
-+      xr5_dis = AR5K_EEPROM_HDR_XR5_DIS(ee->ee_misc0);
-+
-+      printf("|================= Capabilities ================|\n");
-+
-+      printf("| 802.11a Support: ");
-+      if (has_a)
-+              printf(" yes |");
-+      else
-+              printf(" no  |");
-+
-+      printf(" Turbo-A disabled:");
-+      if (turboa_dis)
-+              printf(" yes |\n");
-+      else
-+              printf(" no  |\n");
-+
-+      printf("| 802.11b Support: ");
-+      if (has_b)
-+              printf(" yes |");
-+      else
-+              printf(" no  |");
-+
-+      printf(" Turbo-G disabled:");
-+      if (turbog_dis)
-+              printf(" yes |\n");
-+      else
-+              printf(" no  |\n");
-+
-+      printf("| 802.11g Support: ");
-+      if (has_g)
-+              printf(" yes |");
-+      else
-+              printf(" no  |");
-+
-+      printf(" 2GHz XR disabled:");
-+      if (xr2_dis)
-+              printf(" yes |\n");
-+      else
-+              printf(" no  |\n");
-+
-+      printf("| RFKill  Support: ");
-+      if (has_rfkill)
-+              printf(" yes |");
-+      else
-+              printf(" no  |");
-+
-+      printf(" 5GHz XR disabled:");
-+      if (xr5_dis)
-+              printf(" yes |\n");
-+      else
-+              printf(" no  |\n");
-+
-+      if (has_crystal != 2) {
-+              printf("| 32kHz   Crystal: ");
-+              if (has_crystal)
-+                      printf(" yes |");
-+              else
-+                      printf(" no  |");
-+
-+              printf("                       |\n");
-+      }
-+
-+      printf("\\===============================================/\n");
-+}
-+
-+static void dump_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
-+{
-+      int i;
-+
-+      printf("|=========================================================|\n");
-+      printf("| I power:              0x%02x |", ee->ee_i_cal[mode]);
-+      printf(" Q power:              0x%02x |\n", ee->ee_q_cal[mode]);
-+      printf("| Use fixed bias:       0x%02x |", ee->ee_fixed_bias[mode]);
-+      printf(" Max turbo power:      0x%02x |\n", ee->ee_turbo_max_power[mode]);
-+      printf("| Max XR power:         0x%02x |", ee->ee_xr_power[mode]);
-+      printf(" Switch Settling Time: 0x%02x |\n", ee->ee_switch_settling[mode]);
-+      printf("| Tx/Rx attenuation:    0x%02x |", ee->ee_ant_tx_rx[mode]);
-+      printf(" TX end to XLNA On:    0x%02x |\n", ee->ee_tx_end2xlna_enable[mode]);
-+      printf("| TX end to XPA Off:    0x%02x |", ee->ee_tx_end2xpa_disable[mode]);
-+      printf(" TX end to XPA On:     0x%02x |\n", ee->ee_tx_frm2xpa_enable[mode]);
-+      printf("| 62db Threshold:       0x%02x |", ee->ee_thr_62[mode]);
-+      printf(" XLNA gain:            0x%02x |\n", ee->ee_xlna_gain[mode]);
-+      printf("| XPD:                  0x%02x |", ee->ee_xpd[mode]);
-+      printf(" XPD gain:             0x%02x |\n", ee->ee_x_gain[mode]);
-+      printf("| I gain:               0x%02x |", ee->ee_i_gain[mode]);
-+      printf(" Tx/Rx margin:         0x%02x |\n", ee->ee_margin_tx_rx[mode]);
-+      printf("| False detect backoff: 0x%02x |", ee->ee_false_detect[mode]);
-+      printf(" Noise Floor Threshold: %3d |\n", ee->ee_noise_floor_thr[mode]);
-+      printf("| ADC desired size:      %3d |", ee->ee_adc_desired_size[mode]);
-+      printf(" PGA desired size:      %3d |\n", ee->ee_pga_desired_size[mode]);
-+      printf("|=========================================================|\n");
-+      for (i = 0; i < AR5K_EEPROM_N_PCDAC; i++) {
-+              printf("| Antenna control  %2i:  0x%02x |", i, ee->ee_ant_control[mode][i]);
-+              i++;
-+              printf(" Antenna control  %2i:  0x%02x |\n", i, ee->ee_ant_control[mode][i]);
-+      }
-+      printf("|=========================================================|\n");
-+      for (i = 0; i < AR5K_EEPROM_N_OBDB; i++) {
-+              printf("| Octave Band %i:          %2i |", i, ee->ee_ob[mode][i]);
-+              printf(" db %i:                   %2i |\n", i, ee->ee_db[mode][i]);
-+      }
-+      printf("\\=========================================================/\n");
-+}
-+
-+static void dump_power_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
-+{
-+      struct ath5k_chan_pcal_info *chan_pcal_info;
-+      u_int16_t cal_piers;
-+      int i, c;
-+
-+      switch (mode) {
-+      case AR5K_EEPROM_MODE_11A:
-+              chan_pcal_info = ee->ee_pwr_cal_a;
-+              cal_piers = ee->ee_cal_piers_a;
-+              break;
-+      case AR5K_EEPROM_MODE_11B:
-+              chan_pcal_info = ee->ee_pwr_cal_b;
-+              cal_piers = ee->ee_cal_piers_b;
-+              break;
-+      case AR5K_EEPROM_MODE_11G:
-+              chan_pcal_info = ee->ee_pwr_cal_g;
-+              cal_piers = ee->ee_cal_piers_g;
-+              break;
-+      default:
-+              return;
-+      }
-+
-+      printf("/=================== Per channel power calibration ====================\\\n");
-+      printf("| Freq | pwr_0 | pwr_1 | pwr_2 | pwr_3 |pwrx3_0|pwrx3_1|pwrx3_2|max_pwr|\n");
-+      printf("|      | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac |       |\n");
-+
-+      for (i = 0; i < cal_piers; i++) {
-+              char buf[16];
-+
-+              printf("|======|=======|=======|=======|=======|=======|=======|=======|=======|\n");
-+              printf("| %4i |", chan_pcal_info[i].freq);
-+              for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
-+                      printf(" %2i.%02i |", chan_pcal_info[i].pwr_x0[c] / 4,
-+                             chan_pcal_info[i].pwr_x0[c] % 4);
-+              }
-+              for (c = 0; c < AR5K_EEPROM_N_XPD3_POINTS; c++) {
-+                      printf(" %2i.%02i |", chan_pcal_info[i].pwr_x3[c] / 4,
-+                             chan_pcal_info[i].pwr_x3[c] % 4);
-+              }
-+              printf(" %2i.%02i |\n", chan_pcal_info[i].max_pwr / 4,
-+                     chan_pcal_info[i].max_pwr % 4);
-+
-+              printf("|      |");
-+              for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
-+                      snprintf(buf, sizeof(buf), "[%i]",
-+                               chan_pcal_info[i].pcdac_x0[c]);
-+                      printf("%6s |", buf);
-+              }
-+              for (c = 0; c < AR5K_EEPROM_N_XPD3_POINTS; c++) {
-+                      snprintf(buf, sizeof(buf), "[%i]",
-+                               chan_pcal_info[i].pcdac_x3[c]);
-+                      printf("%6s |", buf);
-+              }
-+              printf("       |\n");
-+
-+      }
-+      printf("\\======================================================================/\n");
-+}
-+
-+static void dump_rate_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
-+{
-+      int i;
-+      struct ath5k_rate_pcal_info *rate_pcal_info;
-+      u_int16_t rate_target_pwr_num;
-+
-+      switch (mode) {
-+      case AR5K_EEPROM_MODE_11A:
-+              rate_pcal_info = ee->ee_rate_tpwr_a;
-+              rate_target_pwr_num = ee->ee_rate_target_pwr_num_a;
-+              break;
-+      case AR5K_EEPROM_MODE_11B:
-+              rate_pcal_info = ee->ee_rate_tpwr_b;
-+              rate_target_pwr_num = ee->ee_rate_target_pwr_num_b;
-+              break;
-+      case AR5K_EEPROM_MODE_11G:
-+              rate_pcal_info = ee->ee_rate_tpwr_g;
-+              rate_target_pwr_num = ee->ee_rate_target_pwr_num_g;
-+              break;
-+      default:
-+              return;
-+      }
-+
-+      printf("/============== Per rate power calibration ===========\\\n");
-+      if (mode == AR5K_EEPROM_MODE_11B)
-+              printf("| Freq |   1Mbit/s  | 2Mbit/s  | 5.5Mbit/s | 11Mbit/s |\n");
-+      else
-+              printf("| Freq | 6-24Mbit/s | 36Mbit/s |  48Mbit/s | 54Mbit/s |\n");
-+
-+      for (i = 0; i < rate_target_pwr_num; i++) {
-+
-+              printf("|======|============|==========|===========|==========|\n");
-+              printf("| %4i |", rate_pcal_info[i].freq);
-+              printf("    %2i.%02i   |",rate_pcal_info[i].target_power_6to24 /2,
-+                                      rate_pcal_info[i].target_power_6to24 % 2);
-+              printf("  %2i.%02i   |",rate_pcal_info[i].target_power_36 /2,
-+                                      rate_pcal_info[i].target_power_36 % 2);
-+              printf("   %2i.%02i   |",rate_pcal_info[i].target_power_48 /2,
-+                                      rate_pcal_info[i].target_power_48 % 2);
-+              printf("  %2i.%02i   |\n",rate_pcal_info[i].target_power_54 /2,
-+                                      rate_pcal_info[i].target_power_54 % 2);
-+      }
-+      printf("\\=====================================================/\n");
-+}
-+
-+static u_int32_t extend_tu(u_int32_t base_tu, u_int32_t val, u_int32_t mask)
-+{
-+      u_int32_t result;
-+
-+      result = (base_tu & ~mask) | (val & mask);
-+      if ((base_tu & mask) > (val & mask))
-+              result += mask + 1;
-+      return result;
-+}
-+
-+static void dump_timers_register(void *mem, u_int16_t mac_version)
-+{
-+#define AR5K_TIMER0_5210              0x802c  /* next TBTT */
-+#define AR5K_TIMER0_5211              0x8028
-+#define AR5K_TIMER0                   (mac_version == AR5K_SREV_MAC_AR5210 ? \
-+                                      AR5K_TIMER0_5210 : AR5K_TIMER0_5211)
-+
-+#define AR5K_TIMER1_5210              0x8030  /* next DMA beacon */
-+#define AR5K_TIMER1_5211              0x802c
-+#define AR5K_TIMER1                   (mac_version == AR5K_SREV_MAC_AR5210 ? \
-+                                      AR5K_TIMER1_5210 : AR5K_TIMER1_5211)
-+
-+#define AR5K_TIMER2_5210              0x8034  /* next SWBA interrupt */
-+#define AR5K_TIMER2_5211              0x8030
-+#define AR5K_TIMER2                   (mac_version == AR5K_SREV_MAC_AR5210 ? \
-+                                      AR5K_TIMER2_5210 : AR5K_TIMER2_5211)
-+
-+#define AR5K_TIMER3_5210              0x8038  /* next ATIM window */
-+#define AR5K_TIMER3_5211              0x8034
-+#define AR5K_TIMER3                   (mac_version == AR5K_SREV_MAC_AR5210 ? \
-+                                      AR5K_TIMER3_5210 : AR5K_TIMER3_5211)
-+
-+#define AR5K_TSF_L32_5210             0x806c  /* TSF (lower 32 bits) */
-+#define AR5K_TSF_L32_5211             0x804c
-+#define AR5K_TSF_L32                  (mac_version == AR5K_SREV_MAC_AR5210 ? \
-+                                      AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
-+
-+#define AR5K_TSF_U32_5210             0x8070
-+#define AR5K_TSF_U32_5211             0x8050
-+#define AR5K_TSF_U32                  (mac_version == AR5K_SREV_MAC_AR5210 ? \
-+                                      AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
-+
-+#define AR5K_BEACON_5210              0x8024
-+#define AR5K_BEACON_5211              0x8020
-+#define AR5K_BEACON                   (mac_version == AR5K_SREV_MAC_AR5210 ? \
-+                                      AR5K_BEACON_5210 : AR5K_BEACON_5211)
-+
-+#define AR5K_LAST_TSTP                        0x8080
-+
-+      const int timer_mask = 0xffff;
-+
-+      u_int32_t timer0, timer1, timer2, timer3, now_tu;
-+      u_int32_t timer0_tu, timer1_tu, timer2_tu, timer3_tu;
-+      u_int64_t now_tsf;
-+
-+      timer0 = AR5K_REG_READ(AR5K_TIMER0);            /* 0x0000ffff */
-+      timer1 = AR5K_REG_READ(AR5K_TIMER1_5211);       /* 0x0007ffff */
-+      timer2 = AR5K_REG_READ(AR5K_TIMER2_5211);       /* 0x?1ffffff */
-+      timer3 = AR5K_REG_READ(AR5K_TIMER3_5211);       /* 0x0000ffff */
-+
-+      now_tsf = ((u_int64_t)AR5K_REG_READ(AR5K_TSF_U32_5211) << 32)
-+              | (u_int64_t)AR5K_REG_READ(AR5K_TSF_L32_5211);
-+
-+      now_tu = now_tsf >> 10;
-+
-+      timer0_tu = extend_tu(now_tu, timer0, 0xffff);
-+      printf("TIMER0: 0x%08x, TBTT: %5u, TU: 0x%08x\n", timer0,
-+             timer0 & timer_mask, timer0_tu);
-+      timer1_tu = extend_tu(now_tu, timer1 >> 3, 0x7ffff >> 3);
-+      printf("TIMER1: 0x%08x, DMAb: %5u, TU: 0x%08x (%+d)\n", timer1,
-+             (timer1 >> 3) & timer_mask, timer1_tu, timer1_tu - timer0_tu);
-+      timer2_tu = extend_tu(now_tu, timer2 >> 3, 0x1ffffff >> 3);
-+      printf("TIMER2: 0x%08x, SWBA: %5u, TU: 0x%08x (%+d)\n", timer2,
-+             (timer2 >> 3) & timer_mask, timer2_tu, timer2_tu - timer0_tu);
-+      timer3_tu = extend_tu(now_tu, timer3, 0xffff);
-+      printf("TIMER3: 0x%08x, ATIM: %5u, TU: 0x%08x (%+d)\n", timer3,
-+             timer3 & timer_mask, timer3_tu, timer3_tu - timer0_tu);
-+      printf("TSF: 0x%016llx, TSFTU: %5u, TU: 0x%08x\n",
-+             (unsigned long long)now_tsf, now_tu & timer_mask, now_tu);
-+
-+      printf("BEACON: 0x%08x\n", AR5K_REG_READ(AR5K_BEACON));
-+      printf("LAST_TSTP: 0x%08x\n", AR5K_REG_READ(AR5K_LAST_TSTP));
-+}
-+
-+#define AR5K_KEYTABLE_0_5210          0x9000
-+#define AR5K_KEYTABLE_0_5211          0x8800
-+#define AR5K_KEYTABLE_0                       (mac_version == AR5K_SREV_MAC_AR5210 ? \
-+                                      AR5K_KEYTABLE_0_5210 : \
-+                                      AR5K_KEYTABLE_0_5211)
-+
-+#define AR5K_KEYTABLE(_n)             (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
-+#define AR5K_KEYTABLE_OFF(_n, x)      (AR5K_KEYTABLE(_n) + ((x) << 2))
-+#define AR5K_KEYTABLE_VALID           0x00008000
-+
-+#define AR5K_KEYTABLE_SIZE_5210               64
-+#define AR5K_KEYTABLE_SIZE_5211               128
-+#define AR5K_KEYTABLE_SIZE            (mac_version == AR5K_SREV_MAC_AR5210 ? \
-+                                      AR5K_KEYTABLE_SIZE_5210 : \
-+                                      AR5K_KEYTABLE_SIZE_5211)
-+
-+static void keycache_dump(void *mem, u_int16_t mac_version)
-+{
-+      int i, keylen;
-+      u_int32_t val0, val1, val2, val3, val4, keytype, ant, mac0, mac1;
-+
-+      /* dump all 128 entries */
-+      printf("Dumping keycache entries...\n");
-+      for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) {
-+              mac1 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 7));
-+              if (mac1 & AR5K_KEYTABLE_VALID) {
-+                      val0    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 0));
-+                      val1    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 1));
-+                      val2    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 2));
-+                      val3    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 3));
-+                      val4    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 4));
-+                      keytype = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 5));
-+                      ant = keytype & 8;
-+                      keytype &= ~8;
-+                      switch (keytype) {
-+                      case 0: /* WEP40  */ keylen =  40 / 8; break;
-+                      case 1: /* WEP104 */ keylen = 104 / 8; break;
-+                      case 3: /* WEP128 */ keylen = 128 / 8; break;
-+                      case 4: /* TKIP   */ keylen = 128 / 8; break;
-+                      case 5: /* AES    */ keylen = 128 / 8; break;
-+                      case 6: /* CCM    */ keylen = 128 / 8; break;
-+                      default:             keylen = 0;       break;
-+                      }
-+                      mac0 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 6));
-+
-+                      printf("[%3u] keytype %d [%s%s%s%s%s%s%s%s] mac %02x:%02x:%02x:%02x:%02x:%02x key:%08x-%08x-%08x-%08x-%08x\n",
-+                             i,
-+                             keytype,
-+                             keytype == 0 ? "WEP40 " : "",
-+                             keytype == 1 ? "WEP104" : "",
-+                             keytype == 3 ? "WEP128" : "",
-+                             keytype == 4 ? "TKIP  " : "",
-+                             keytype == 5 ? "AES   " : "",
-+                             keytype == 6 ? "CCM   " : "",
-+                             keytype == 7 ? "NULL  " : "",
-+                             ant     == 8 ? "+ANT"   : "",
-+                             ((mac0 <<  1) & 0xff),
-+                             ((mac0 >>  7) & 0xff),
-+                             ((mac0 >> 15) & 0xff),
-+                             ((mac0 >> 23) & 0xff),
-+                             ((mac1 <<  1) & 0xff) | (mac0 >> 31),
-+                             ((mac1 >>  7) & 0xff),
-+                             val0, val1, val2, val3, val4);
-+              }
-+      }
-+}
-+
-+/* copy key index (0) to key index (idx) */
-+
-+static void keycache_copy(void *mem, u_int16_t mac_version, int idx)
-+{
-+      u_int32_t val0, val1, val2, val3, val4, keytype, mac0, mac1;
-+
-+      printf("Copying keycache entry 0 to %d\n", idx);
-+      if (idx < 0 || idx >= AR5K_KEYTABLE_SIZE) {
-+              printf("invalid keycache index\n");
-+              return;
-+      }
-+
-+      val0    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 0));
-+      val1    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 1));
-+      val2    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 2));
-+      val3    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 3));
-+      val4    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 4));
-+      keytype = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 5));
-+      mac0    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 6));
-+      mac1    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 7));
-+
-+      AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 0), val0);
-+      AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 1), val1);
-+      AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 2), val2);
-+      AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 3), val3);
-+      AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 4), val4);
-+      AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 5), keytype);
-+      AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 6), mac0);
-+      AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 7), mac1);
-+}
-+
-+static void sta_id0_id1_dump(void *mem)
-+{
-+#define AR5K_STA_ID0                  0x8000
-+#define AR5K_STA_ID1                  0x8004
-+#define AR5K_STA_ID1_AP                 0x00010000
-+#define AR5K_STA_ID1_ADHOC              0x00020000
-+#define AR5K_STA_ID1_NO_KEYSRCH               0x00080000
-+
-+      u_int32_t sta_id0, sta_id1;
-+
-+      sta_id0 = AR5K_REG_READ(AR5K_STA_ID0);
-+      sta_id1 = AR5K_REG_READ(AR5K_STA_ID1);
-+      printf("STA_ID0: %02x:%02x:%02x:%02x:%02x:%02x\n",
-+             (sta_id0 >>  0) & 0xff,
-+             (sta_id0 >>  8) & 0xff,
-+             (sta_id0 >> 16) & 0xff,
-+             (sta_id0 >> 24) & 0xff,
-+             (sta_id1 >>  0) & 0xff,
-+             (sta_id1 >>  8) & 0xff);
-+      printf("STA_ID1: 0x%08x, AP: %d, IBSS: %d, KeyCache Disable: %d\n",
-+             sta_id1,
-+             sta_id1 & AR5K_STA_ID1_AP ? 1 : 0,
-+             sta_id1 & AR5K_STA_ID1_ADHOC ? 1 : 0,
-+             sta_id1 & AR5K_STA_ID1_NO_KEYSRCH ? 1 : 0);
-+}
-+
- int
- CMD(athinfo)(int argc, char *argv[])
- {
--      u_int32_t dev_addr;
--      u_int16_t eeprom_header, srev, phy_rev_5ghz, phy_rev_2ghz;
--      u_int16_t eeprom_version, mac_version, regdomain, has_crystal, ee_magic;
--      u_int8_t error, has_a, has_b, has_g, has_rfkill, eeprom_size;
--      int byte_size = 0;
-+      unsigned long long dev_addr;
-+      u_int16_t srev, phy_rev_5ghz, phy_rev_2ghz, ee_magic;
-+      u_int8_t mac_version, mac_revision;
-+      u_int8_t error, eeprom_size, dev_type, eemap;
-+      struct ath5k_eeprom_info *ee;
-+      unsigned int byte_size = 0;
-       void *mem;
-       int fd;
--      int i, anr = 1;
-+      unsigned int i;
-+      int anr = 1;
-       int do_write = 0;       /* default: read only */
-       int do_dump = 0;
-+      int reg_read = 0;
-+      int reg_write = 0;
-+      unsigned int reg_write_val = 0;
-+      unsigned int timer_count = 1;
-+      int do_keycache_dump = 0;
-+      int keycache_copy_idx = 0;
-       struct {
-               int valid;
-@@ -759,7 +1986,7 @@ CMD(athinfo)(int argc, char *argv[])
-       } gpio_set[AR5K_NUM_GPIO];
-       int nr_gpio_set = 0;
--      for (i = 0; i < sizeof(gpio_set) / sizeof(gpio_set[0]); i++)
-+      for (i = 0; i < ARRAY_SIZE(gpio_set); i++)
-               gpio_set[i].valid = 0;
-       if (argc < 2) {
-@@ -769,6 +1996,15 @@ CMD(athinfo)(int argc, char *argv[])
-       while (anr < argc && argv[anr][0] == '-') {
-               switch (argv[anr][1]) {
-+              case 't':
-+                      if (++anr < argc) {
-+                              timer_count = atoi(argv[anr]);
-+                              printf("timer_count:%d\n", timer_count);
-+                      } else {
-+                              usage(argv[0]);
-+                              return 0;
-+                      }
-+                      break;
-               case 'w':
-                       do_write = 1;
-                       break;
-@@ -777,7 +2013,7 @@ CMD(athinfo)(int argc, char *argv[])
-                       if (strlen(argv[anr]) != 3 || argv[anr][1] != ':' ||
-                           argv[anr][0] < '0' || argv[anr][0] > '5' ||
-                           (argv[anr][2] != '0' && argv[anr][2] != '1')) {
--                              err("invalid gpio spec. %s", argv[anr]);
-+                              err("invalid GPIO spec. %s", argv[anr]);
-                               return 2;
-                       }
-                       gpio_set[argv[anr][0] - '0'].valid = 1;
-@@ -797,6 +2033,25 @@ CMD(athinfo)(int argc, char *argv[])
-                       do_dump = 1;
-                       break;
-+              case 'R':
-+                      anr++;
-+                      reg_read = strtoul(argv[anr], NULL, 16);
-+                      break;
-+
-+              case 'W':
-+                      anr++;
-+                      reg_write = strtoul(argv[anr++], NULL, 16);
-+                      reg_write_val = strtoul(argv[anr], NULL, 16);
-+                      break;
-+
-+              case 'k':
-+                      do_keycache_dump = 1;
-+                      break;
-+
-+              case 'K':
-+                      keycache_copy_idx = atoi(argv[++anr]);
-+                      break;
-+
-               case 'h':
-                       usage(argv[0]);
-                       return 0;
-@@ -805,10 +2060,10 @@ CMD(athinfo)(int argc, char *argv[])
-               default:
-                       err("unknown option %s", argv[anr]);
-                       return 2;
--              }               /* switch (argv[anr][1]) */
-+              }
-               anr++;
--      }                       /* while (anr < argc && ...) */
-+      }
-       if (anr >= argc) {
-               err("missing device address");
-@@ -816,7 +2071,7 @@ CMD(athinfo)(int argc, char *argv[])
-               return 3;
-       }
--      dev_addr = strtoul(argv[anr], NULL, 16);
-+      dev_addr = strtoull(argv[anr], NULL, 16);
-       fd = open("/dev/mem", O_RDWR);
-       if (fd < 0) {
-@@ -828,7 +2083,7 @@ CMD(athinfo)(int argc, char *argv[])
-                  MAP_SHARED | MAP_FILE, fd, dev_addr);
-       if (mem == MAP_FAILED) {
--              printf("Mmap of device at 0x%08X for 0x%X bytes failed - "
-+              printf("mmap of device at 0x%08llX for 0x%X bytes failed - "
-                      "%s\n", dev_addr, AR5K_PCI_MEM_SIZE, strerror(errno));
-               return -3;
-       }
-@@ -856,10 +2111,31 @@ CMD(athinfo)(int argc, char *argv[])
-       AR5K_REG_DISABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_SPWR_DN);
-       usleep(500);
-+      if (reg_read) {
-+              printf("READ %04x = %08x\n", reg_read, AR5K_REG_READ(reg_read));
-+              return 0;
-+      }
-+
-+      if (reg_write) {
-+              printf("WRITE %04x = %08x\n", reg_write, reg_write_val);
-+              AR5K_REG_WRITE(reg_write, reg_write_val);
-+              return 0;
-+      }
-+
-       srev = AR5K_REG_READ(AR5K_SREV);
--      mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER) << 4;
-+      if (srev >= 0x0100) {
-+              printf("MAC revision 0x%04x is not supported!\n", srev);
-+              return -1;
-+      }
-+      mac_version = srev & AR5K_SREV_VER;
-+      mac_revision = srev & AR5K_SREV_REV;
--      /* Verify eeprom magic value first */
-+      printf(" -==Device Information==-\n");
-+
-+      printf("MAC Revision: %-5s (0x%02x)\n",
-+             ath5k_hw_get_mac_name(mac_revision), mac_revision);
-+
-+      /* Verify EEPROM magic value first */
-       error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_MAGIC, &ee_magic,
-                                    mac_version);
-@@ -872,157 +2148,114 @@ CMD(athinfo)(int argc, char *argv[])
-               printf("Warning: Invalid EEPROM Magic number!\n");
-       }
--      error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_HDR, &eeprom_header,
--                                   mac_version);
--
--      if (error) {
--              printf("Unable to read EEPROM Header!\n");
--              return -1;
--      }
--
--      error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_VERSION, &eeprom_version,
--                                   mac_version);
--
--      if (error) {
--              printf("Unable to read EEPROM version!\n");
-+      ee = calloc(sizeof(struct ath5k_eeprom_info), 1);
-+      if (!ee) {
-+              printf("Cannot allocate memory for EEPROM information\n");
-               return -1;
-       }
--      error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_REG_DOMAIN, &regdomain,
--                                   mac_version);
--
--      if (error) {
--              printf("Unable to read Regdomain!\n");
-+      if (ath5k_eeprom_init(mem, mac_version, ee)) {
-+              printf("EEPROM init failed\n");
-               return -1;
-       }
--      if (eeprom_version >= 0x4000) {
--              error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_MISC0,
--                                           &has_crystal, mac_version);
--
--              if (error) {
--                      printf("Unable to read EEPROM Misc data!\n");
--                      return -1;
--              }
--
--              has_crystal = AR5K_EEPROM_HAS32KHZCRYSTAL(has_crystal);
--      } else {
--              has_crystal = 2;
--      }
--
-       eeprom_size = AR5K_REG_MS(AR5K_REG_READ(AR5K_PCICFG),
-                                 AR5K_PCICFG_EESIZE);
--      has_a = AR5K_EEPROM_HDR_11A(eeprom_header);
--      has_b = AR5K_EEPROM_HDR_11B(eeprom_header);
--      has_g = AR5K_EEPROM_HDR_11G(eeprom_header);
--      has_rfkill = AR5K_EEPROM_HDR_RFKILL(eeprom_header);
-+      dev_type = AR5K_EEPROM_HDR_DEVICE(ee->ee_header);
-+      eemap = AR5K_EEPROM_EEMAP(ee->ee_misc0);
--      if (has_a)
-+      /* 1 = ?? 2 = ?? 3 = card 4 = wmac */
-+      printf("Device type:  %1i\n", dev_type);
-+
-+      if (AR5K_EEPROM_HDR_11A(ee->ee_header))
-               phy_rev_5ghz = ath5k_hw_radio_revision(mac_version, mem, 1);
-       else
-               phy_rev_5ghz = 0;
--      if (has_b)
-+      if (AR5K_EEPROM_HDR_11B(ee->ee_header))
-               phy_rev_2ghz = ath5k_hw_radio_revision(mac_version, mem, 0);
-       else
-               phy_rev_2ghz = 0;
--      printf(" -==Device Information==-\n");
--
--      printf("MAC Version:  %-5s (0x%02x)\n",
--             ath5k_hw_get_part_name(AR5K_VERSION_VER, mac_version),
--             mac_version);
--
--      printf("MAC Revision: %-5s (0x%02x)\n",
--             ath5k_hw_get_part_name(AR5K_VERSION_VER, srev), srev);
--
--      /* Single-chip PHY with a/b/g support */
--      if (has_b && !phy_rev_2ghz) {
--              printf("PHY Revision: %-5s (0x%02x)\n",
--                     ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_5ghz),
--                     phy_rev_5ghz);
--              phy_rev_5ghz = 0;
--      }
--
--      /* Single-chip PHY with b/g support */
--      if (!has_a) {
--              printf("PHY Revision: %-5s (0x%02x)\n",
--                     ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_2ghz),
--                     phy_rev_2ghz);
--              phy_rev_2ghz = 0;
--      }
--
--      /* Different chip for 5Ghz and 2Ghz */
-       if (phy_rev_5ghz) {
--              printf("5Ghz PHY Revision: %-5s (0x%2x)\n",
--                     ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_5ghz),
--                     phy_rev_5ghz);
-+              printf("5GHz PHY Revision: %-5s (0x%02x)\n",
-+                     ath5k_hw_get_phy_name(phy_rev_5ghz), phy_rev_5ghz);
-       }
-       if (phy_rev_2ghz) {
--              printf("2Ghz PHY Revision: %-5s (0x%2x)\n",
--                     ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_2ghz),
--                     phy_rev_2ghz);
-+              printf("2GHz PHY Revision: %-5s (0x%02x)\n",
-+                     ath5k_hw_get_phy_name(phy_rev_2ghz), phy_rev_2ghz);
-       }
--      printf(" -==EEPROM Information==-\n");
--
--      printf("EEPROM Version:     %x.%x\n",
--             (eeprom_version & 0xF000) >> 12, eeprom_version & 0xFFF);
-+      printf("\n");
-+      printf("/============== EEPROM Information =============\\\n");
-+      printf("| EEPROM Version:   %1x.%1x |",
-+             (ee->ee_version & 0xF000) >> 12, ee->ee_version & 0xFFF);
--      printf("EEPROM Size: ");
-+      printf(" EEPROM Size: ");
-       if (eeprom_size == 0) {
--              printf("       4K\n");
--              byte_size = 4096;
-+              printf("  4 kbit |\n");
-+              byte_size = 4096 / 8;
-       } else if (eeprom_size == 1) {
--              printf("       8K\n");
--              byte_size = 8192;
-+              printf("  8 kbit |\n");
-+              byte_size = 8192 / 8;
-       } else if (eeprom_size == 2) {
--              printf("       16K\n");
--              byte_size = 16384;
-+              printf(" 16 kbit |\n");
-+              byte_size = 16384 / 8;
-       } else
--              printf("       ??\n");
-+              printf(" unknown |\n");
--      printf("Regulatory Domain:  0x%X\n", regdomain);
--
--      printf(" -==== Capabilities ====-\n");
--
--      printf("|  802.11a Support: ");
--      if (has_a)
--              printf("yes  |\n");
--      else
--              printf("no   |\n");
--
--      printf("|  802.11b Support: ");
--      if (has_b)
--              printf("yes  |\n");
--      else
--              printf("no   |\n");
-+      printf("| EEMAP:              %i |", eemap);
--      printf("|  802.11g Support: ");
--      if (has_g)
--              printf("yes  |\n");
--      else
--              printf("no   |\n");
-+      printf(" Reg. Domain:     0x%02X |\n", ee->ee_regdomain);
--      printf("|  RFKill  Support: ");
--      if (has_rfkill)
--              printf("yes  |\n");
--      else
--              printf("no   |\n");
-+      dump_capabilities(ee);
-+      printf("\n");
--      if (has_crystal != 2) {
--              printf("|  32KHz   Crystal: ");
--              if (has_crystal)
--                      printf("yes  |\n");
--              else
--                      printf("no   |\n");
-+      printf("/=========================================================\\\n");
-+      printf("|          Calibration data common for all modes          |\n");
-+      printf("|=========================================================|\n");
-+      printf("|          CCK/OFDM gain delta:            %2i             |\n", ee->ee_cck_ofdm_gain_delta);
-+      printf("|          CCK/OFDM power delta:           %2i             |\n", ee->ee_cck_ofdm_power_delta);
-+      printf("|          Scaled CCK delta:               %2i             |\n", ee->ee_scaled_cck_delta);
-+      printf("|          2GHz Antenna gain:              %2i             |\n", AR5K_EEPROM_ANT_GAIN_2GHZ(ee->ee_ant_gain));
-+      printf("|          5GHz Antenna gain:              %2i             |\n", AR5K_EEPROM_ANT_GAIN_5GHZ(ee->ee_ant_gain));
-+      printf("|          Turbo 2W maximum dBm:           %2i             |\n", AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header));
-+      printf("|          Target power start:          0x%03x             |\n", AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1));
-+      printf("|          EAR Start:                   0x%03x             |\n", AR5K_EEPROM_EARSTART(ee->ee_misc0));
-+      printf("\\=========================================================/\n");
-+
-+      printf("\n");
-+      if (AR5K_EEPROM_HDR_11A(ee->ee_header)) {
-+              printf("/=========================================================\\\n");
-+              printf("|          Calibration data for 802.11a operation         |\n");
-+              dump_calinfo_for_mode(AR5K_EEPROM_MODE_11A, ee);
-+              dump_rate_calinfo_for_mode(AR5K_EEPROM_MODE_11A, ee);
-+              dump_power_calinfo_for_mode(AR5K_EEPROM_MODE_11A, ee);
-+              printf("\n");
-+      }
-+
-+      if (AR5K_EEPROM_HDR_11B(ee->ee_header)) {
-+              printf("/=========================================================\\\n");
-+              printf("|          Calibration data for 802.11b operation         |\n");
-+              dump_calinfo_for_mode(AR5K_EEPROM_MODE_11B, ee);
-+              dump_rate_calinfo_for_mode(AR5K_EEPROM_MODE_11B, ee);
-+              dump_power_calinfo_for_mode(AR5K_EEPROM_MODE_11B, ee);
-+              printf("\n");
-+      }
-+
-+      if (AR5K_EEPROM_HDR_11G(ee->ee_header)) {
-+              printf("/=========================================================\\\n");
-+              printf("|          Calibration data for 802.11g operation         |\n");
-+              dump_calinfo_for_mode(AR5K_EEPROM_MODE_11G, ee);
-+              dump_rate_calinfo_for_mode(AR5K_EEPROM_MODE_11G, ee);
-+              dump_power_calinfo_for_mode(AR5K_EEPROM_MODE_11G, ee);
-+              printf("\n");
-       }
--      printf(" ========================\n");
-       /* print current GPIO settings */
--      printf("GPIO registers: CR %08x DO %08x DI %08x\n",
-+      printf("GPIO registers: CR 0x%08x, DO 0x%08x, DI 0x%08x\n",
-              AR5K_REG_READ(AR5K_GPIOCR), AR5K_REG_READ(AR5K_GPIODO),
-              AR5K_REG_READ(AR5K_GPIODI));
-@@ -1030,18 +2263,18 @@ CMD(athinfo)(int argc, char *argv[])
-               u_int16_t data;
-               FILE *dumpfile = fopen("ath-eeprom-dump.bin", "w");
--              printf("\nEEPROM dump (%d byte)\n", byte_size);
-+              printf("\nEEPROM dump (%d bytes)\n", byte_size);
-               printf("==============================================");
--              for (i = 1; i <= (byte_size / 2); i++) {
-+              for (i = 0; i < byte_size / 2; i++) {
-                       error =
-                           ath5k_hw_eeprom_read(mem, i, &data, mac_version);
-                       if (error) {
-                               printf("\nUnable to read at %04x\n", i);
-                               continue;
-                       }
--                      if (!((i - 1) % 8))
--                              printf("\n%04x:  ", i);
--                      printf("%04x ", data);
-+                      if (!(i % 8))
-+                              printf("\n%04x: ", i);
-+                      printf(" %04x", data);
-                       fwrite(&data, 2, 1, dumpfile);
-               }
-               printf("\n==============================================\n");
-@@ -1054,18 +2287,18 @@ CMD(athinfo)(int argc, char *argv[])
-               u_int32_t old_cr = rcr, old_do = rdo;
-               int rc;
--              if (mac_version >= AR5K_SREV_VER_AR5213 && !nr_gpio_set) {
--                      dbg("new MAC %x (>= AR5213) set gpio4 to low",
-+              if (mac_version >= AR5K_SREV_MAC_AR5213 && !nr_gpio_set) {
-+                      dbg("new MAC %x (>= AR5213) set GPIO4 to low",
-                           mac_version);
-                       gpio_set[4].valid = 1;
-                       gpio_set[4].value = 0;
-               }
--              /* set gpios */
-+              /* set GPIOs */
-               dbg("old GPIO CR %08x DO %08x DI %08x",
-                   rcr, rdo, AR5K_REG_READ(AR5K_GPIODI));
--              for (i = 0; i < sizeof(gpio_set) / sizeof(gpio_set[0]); i++) {
-+              for (i = 0; i < ARRAY_SIZE(gpio_set); i++) {
-                       if (gpio_set[i].valid) {
-                               rcr |= AR5K_GPIOCR_OUT(i);      /* we use mode 3 */
-                               rcr &= ~AR5K_GPIOCR_INT_SEL(i);
-@@ -1111,5 +2344,17 @@ CMD(athinfo)(int argc, char *argv[])
-               return rc;
-       }
-+
-+      sta_id0_id1_dump(mem);
-+
-+      for (i = 0; i < timer_count; i++)
-+              dump_timers_register(mem, mac_version);
-+
-+      if (do_keycache_dump)
-+              keycache_dump(mem, mac_version);
-+
-+      if (keycache_copy_idx > 0)
-+              keycache_copy(mem, mac_version, keycache_copy_idx);
-+
-       return 0;
- }