Hi,

Here's another patch with a couple of changes since the last one.  Not
sure how this will make any difference to the cards that were not working
with previous versions, but hopefully there will be some changes.

Please let me know if this works for you.

Alexander: sorry for the delay on sending you the debug output, but I've
been very busy on vacations! :-)

--
Luis

Index: dev/ic/ar5212.c
===================================================================
RCS file: /home/miguel/openbsd-cvsroot//src/sys/dev/ic/ar5212.c,v
retrieving revision 1.51
diff -u -p -r1.51 ar5212.c
--- dev/ic/ar5212.c     2 Jun 2009 12:39:02 -0000       1.51
+++ dev/ic/ar5212.c     3 May 2010 16:23:22 -0000
@@ -30,6 +30,7 @@ HAL_BOOL       ar5k_ar5212_nic_wakeup(struct 
 u_int16_t       ar5k_ar5212_radio_revision(struct ath_hal *, HAL_CHIP);
 void            ar5k_ar5212_fill(struct ath_hal *);
 HAL_BOOL        ar5k_ar5212_txpower(struct ath_hal *, HAL_CHANNEL *, u_int);
+void            ar5k_ar5212_hw_set_sleep_clock(struct ath_hal *, HAL_BOOL);
 
 /*
  * Initial register setting for the AR5212
@@ -234,9 +235,17 @@ ar5k_ar5212_attach(u_int16_t device, voi
                hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5424;
                hal->ah_radio_5ghz_revision = hal->ah_radio_2ghz_revision =
                    AR5K_SREV_VER_AR5413;
-       } else if (srev == AR5K_SREV_VER_AR2425) {
+       } else if (hal->ah_mac_version == (AR5K_SREV_VER_AR2425 >> 4) ||
+               hal->ah_mac_version == (AR5K_SREV_VER_AR2417 >> 4) ||
+               hal->ah_phy_revision == (AR5K_SREV_PHY_2425)) {
                hal->ah_radio = AR5K_AR2425;
-               hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112;
+               hal->ah_single_chip = AH_TRUE;
+               hal->ah_radio_5ghz_revision= AR5K_SREV_RAD_2425;
+       } else if ((hal->ah_mac_version == (AR5K_SREV_VER_AR2424 >> 4)) ||
+               (hal->ah_phy_revision == AR5K_SREV_PHY_5413)) {
+               hal->ah_radio = AR5K_AR5413;
+               hal->ah_single_chip = AH_TRUE;
+               hal->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
        } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
                hal->ah_radio = AR5K_AR5111;
                hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5111;
@@ -262,6 +271,12 @@ ar5k_ar5212_attach(u_int16_t device, voi
        }
        hal->ah_phy = AR5K_AR5212_PHY(0);
 
+       /* Enable pci core retry fix on Hainan (5213A) and later chips */
+       if (srev >= AR5K_SREV_VER_AR5213A) {
+               AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG,
+                       AR5K_AR5212_PCICFG_RETRY_FIX);
+       }
+
        if (hal->ah_pci_express == AH_TRUE) {
                /* PCI-Express based devices need some extra initialization */
                ar5k_write_ini(hal, ar5212_pcie, nitems(ar5212_pcie), 0);
@@ -312,7 +327,7 @@ ar5k_ar5212_nic_reset(struct ath_hal *ha
 HAL_BOOL
 ar5k_ar5212_nic_wakeup(struct ath_hal *hal, u_int16_t flags)
 {
-       u_int32_t turbo, mode, clock;
+       u_int32_t turbo, mode, clock, bus_flags;
 
        turbo = 0;
        mode = 0;
@@ -335,7 +350,10 @@ ar5k_ar5212_nic_wakeup(struct ath_hal *h
                clock |= AR5K_AR5212_PHY_PLL_44MHZ;
        } else if (flags & IEEE80211_CHAN_5GHZ) {
                mode |= AR5K_AR5212_PHY_MODE_FREQ_5GHZ;
-               clock |= AR5K_AR5212_PHY_PLL_40MHZ;
+               if (hal->ah_radio == AR5K_AR5413)
+                       clock |= AR5K_AR5212_PHY_PLL_40MHZ_5413;
+               else
+                       clock |= AR5K_AR5212_PHY_PLL_40MHZ;
        } else {
                AR5K_PRINT("invalid radio frequency mode\n");
                return (AH_FALSE);
@@ -361,23 +379,30 @@ ar5k_ar5212_nic_wakeup(struct ath_hal *h
         * Reset and wakeup the device
         */
 
-       /* ...reset chipset and PCI device (if not PCI-E) */
-       if (hal->ah_pci_express == AH_FALSE &&
-           ar5k_ar5212_nic_reset(hal, AR5K_AR5212_RC_CHIP) == AH_FALSE) {
-               AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n");
+       /* Wakeup the device */
+       if (ar5k_ar5212_set_power(hal,
+               HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
+               AR5K_PRINT("failed to wakeup the AR5212 chipset\n");
                return (AH_FALSE);
        }
 
-       /* ...wakeup */
+       /* ...reset chipset and PCI device */
+       bus_flags = (hal->ah_pci_express != AH_FALSE) ? 0 : AR5K_AR5212_RC_PCI;
+       if (ar5k_ar5212_nic_reset(hal, bus_flags) == AH_FALSE) {
+               AR5K_PRINT("failed to reset the AR5212 chipset\n");
+               return (AH_FALSE);
+       }
+
+       /* ...wakeup again */
        if (ar5k_ar5212_set_power(hal,
                HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
-               AR5K_PRINT("failed to resume the AR5212 (again)\n");
+               AR5K_PRINT("failed to wakeup (again) the AR5212 chipset\n");
                return (AH_FALSE);
        }
 
        /* ...final warm reset */
        if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE) {
-               AR5K_PRINT("failed to warm reset the AR5212\n");
+               AR5K_PRINT("failed to reset (again) the AR5212 chipset\n");
                return (AH_FALSE);
        }
 
@@ -485,12 +510,13 @@ ar5k_ar5212_reset(struct ath_hal *hal, H
         */
        if (chanchange == AH_TRUE) {
                s_seq = AR5K_REG_READ(AR5K_AR5212_DCU_SEQNUM(0));
-               s_ant = AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
        } else {
                s_seq = 0;
-               s_ant = 1;
        }
 
+       /* Save default antenna */
+       s_ant = AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
+
        s_led[0] = AR5K_REG_READ(AR5K_AR5212_PCICFG) &
            AR5K_AR5212_PCICFG_LEDSTATE;
        s_led[1] = AR5K_REG_READ(AR5K_AR5212_GPIOCR);
@@ -544,6 +570,8 @@ ar5k_ar5212_reset(struct ath_hal *hal, H
                return (AH_FALSE);
        }
 
+       ar5k_ar5212_hw_set_sleep_clock(hal, AH_FALSE);
+
        /* PHY access enable */
        AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
 
@@ -572,11 +600,12 @@ ar5k_ar5212_reset(struct ath_hal *hal, H
                    nitems(ar2413_mode), mode);
                break;
        case AR5K_AR2425:
-               AR5K_REG_WRITE(AR5K_AR5212_PHY(648), 0x018830c6);
                if (mode == AR5K_INI_VAL_11B)
                        mode = AR5K_INI_VAL_11G;
                ar5k_write_mode(hal, ar2425_mode,
                    nitems(ar2425_mode), mode);
+               AR5K_REG_WRITE(AR5K_AR5212_PHY_AGC, 0x00004000);
+               AR5K_REG_WRITE(0xa274, 0x081b7caa);
                break;
        default:
                AR5K_PRINTF("invalid radio: %d\n", hal->ah_radio);
@@ -1150,9 +1179,17 @@ ar5k_ar5212_reset_tx_queue(struct ath_ha
        /*
         * Set misc registers
         */
+       /* Enable DCU early termination for this queue */
        AR5K_REG_WRITE(AR5K_AR5212_QCU_MISC(queue),
            AR5K_AR5212_QCU_MISC_DCU_EARLY);
 
+       /* Enable DCU to wait for next fragment from QCU */
+       AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
+           AR5K_AR5212_DCU_MISC_FRAG_WAIT);
+
+       AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
+           AR5K_AR5212_DCU_MISC_SEQNUM_CTL);
+
        if (tq->tqi_cbr_period) {
                AR5K_REG_WRITE(AR5K_AR5212_QCU_CBRCFG(queue),
                    AR5K_REG_SM(tq->tqi_cbr_period,
@@ -1207,26 +1244,27 @@ ar5k_ar5212_reset_tx_queue(struct ath_ha
 
                AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
                    (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
-                   AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL) |
+                   AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_S) |
+                   AR5K_AR5212_DCU_MISC_ARBLOCK_IGNORE |
                    AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS |
                    AR5K_AR5212_DCU_MISC_BCN_ENABLE);
-
-               AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
-                   ((AR5K_TUNE_BEACON_INTERVAL -
-                   (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) -
-                   AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
-                   AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
                break;
 
        case HAL_TX_QUEUE_CAB:
                AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
-                   AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
+                   AR5K_AR5212_QCU_MISC_FRSHED_BCN_SENT_GT |
                    AR5K_AR5212_QCU_MISC_CBREXP |
                    AR5K_AR5212_QCU_MISC_CBREXP_BCN);
 
+               AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
+                   ((AR5K_TUNE_BEACON_INTERVAL -
+                   (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) -
+                   AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
+                   AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
+
                AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
                    (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
-                   AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL));
+                   AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_S));
                break;
 
        case HAL_TX_QUEUE_PSPOLL:
@@ -2860,10 +2898,8 @@ ar5k_ar5212_get_capabilities(struct ath_
 
                if (b)
                        hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
-#if 0
                if (g)
                        hal->ah_capabilities.cap_mode |= HAL_MODE_11G;
-#endif
        }
 
        /* GPIO */
@@ -3034,3 +3070,75 @@ ar5k_ar5212_set_txpower_limit(struct ath
        AR5K_PRINTF("changing txpower to %d\n", power);
        return (ar5k_ar5212_txpower(hal, channel, power));
 }
+
+/*
+ * If there is an external 32KHz crystal available, use it
+ * as ref. clock instead of 32/40MHz clock and baseband clocks
+ * to save power during sleep or restore normal 32/40MHz
+ * operation.
+ *
+ * XXX: When operating on 32KHz certain PHY registers (27 - 31,
+ *      123 - 127) require delay on access.
+ */
+void
+ar5k_ar5212_hw_set_sleep_clock(struct ath_hal *hal, HAL_BOOL enable)
+{
+       struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
+       u_int32_t scal, spending, usec32;
+
+       /* Only set 32KHz settings if we have an external
+        * 32KHz crystal present */
+       if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
+               AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
+               enable) {
+               /* TODO */
+       } else {
+               /* Disable sleep clock operation and
+                * restore default parameters */
+               AR5K_REG_DISABLE_BITS(AR5K_AR5212_PCICFG,
+                       AR5K_AR5212_PCICFG_SLEEP_CLOCK_EN);
+
+               AR5K_REG_WRITE_BITS(AR5K_AR5212_PCICFG,
+                       AR5K_AR5212_PCICFG_SLEEP_CLOCK_RATE, 0);
+
+               AR5K_REG_WRITE(AR5K_AR5212_PHY_SCR, 0x1f);
+               AR5K_REG_WRITE(AR5K_AR5212_PHY_SLMT,
+                       AR5K_AR5212_PHY_SLMT_32MHZ);
+
+               if (hal->ah_mac_version == (AR5K_SREV_VER_AR2417 >> 4))
+                       scal = AR5K_AR5212_PHY_SCAL_32MHZ_2417;
+               else if (ee->ee_is_hb63 == AH_TRUE)
+                       scal = AR5K_AR5212_PHY_SCAL_32MHZ_HB63;
+               else
+                       scal = AR5K_AR5212_PHY_SCAL_32MHZ;
+
+               AR5K_REG_WRITE(AR5K_AR5212_PHY_SCAL, scal);
+
+               AR5K_REG_WRITE(AR5K_AR5212_PHY_SCLOCK,
+                       AR5K_AR5212_PHY_SCLOCK_32MHZ);
+               AR5K_REG_WRITE(AR5K_AR5212_PHY_SDELAY,
+                       AR5K_AR5212_PHY_SCLOCK_32MHZ);
+
+               if ((hal->ah_radio == AR5K_AR5112) ||
+                   (hal->ah_radio == AR5K_AR5413) ||
+                   (hal->ah_mac_version == (AR5K_SREV_VER_AR2417 >> 4)))
+                       spending = 0x14;
+               else
+                       spending = 0x18;
+
+               AR5K_REG_WRITE(AR5K_AR5212_PHY_SPENDING, spending);
+
+               if ((hal->ah_radio == AR5K_AR5112) ||
+                   (hal->ah_radio == AR5K_AR5413))
+                       usec32 = 39;
+               else
+                       usec32 = 31;
+
+               AR5K_REG_WRITE_BITS(AR5K_AR5212_USEC,
+                       AR5K_AR5212_USEC_32, usec32);
+
+               AR5K_REG_WRITE_BITS(AR5K_AR5212_TSF_PARM,
+                       AR5K_AR5212_TSF_PARM_INC, 1);
+       }
+}
+
Index: dev/ic/ar5212reg.h
===================================================================
RCS file: /home/miguel/openbsd-cvsroot//src/sys/dev/ic/ar5212reg.h,v
retrieving revision 1.12
diff -u -p -r1.12 ar5212reg.h
--- dev/ic/ar5212reg.h  30 Jul 2008 07:15:39 -0000      1.12
+++ dev/ic/ar5212reg.h  3 May 2010 11:46:26 -0000
@@ -456,6 +456,7 @@
  */
 #define AR5K_AR5212_DCU_MISC(_n)               AR5K_AR5212_DCU(_n, 0x1100)
 #define        AR5K_AR5212_DCU_MISC_BACKOFF            0x000007ff
+#define AR5K_AR5212_DCU_MISC_FRAG_WAIT         0x00000100
 #define AR5K_AR5212_DCU_MISC_BACKOFF_FRAG      0x00000200
 #define        AR5K_AR5212_DCU_MISC_HCFPOLL_ENABLE     0x00000800
 #define        AR5K_AR5212_DCU_MISC_BACKOFF_PERSIST    0x00001000
@@ -589,34 +590,38 @@ typedef enum {
 /*
  * PCI configuration register
  */
-#define AR5K_AR5212_PCICFG             0x4010
-#define AR5K_AR5212_PCICFG_CLKRUNEN    0x00000004
-#define AR5K_AR5212_PCICFG_EESIZE      0x00000018
-#define AR5K_AR5212_PCICFG_EESIZE_S    3
-#define AR5K_AR5212_PCICFG_EESIZE_4K   0
-#define AR5K_AR5212_PCICFG_EESIZE_8K   1
-#define AR5K_AR5212_PCICFG_EESIZE_16K  2
-#define AR5K_AR5212_PCICFG_EESIZE_FAIL 3
-#define AR5K_AR5212_PCICFG_LED         0x00000060
-#define AR5K_AR5212_PCICFG_LED_NONE    0x00000000
-#define AR5K_AR5212_PCICFG_LED_PEND    0x00000020
-#define AR5K_AR5212_PCICFG_LED_ASSOC   0x00000040
-#define        AR5K_AR5212_PCICFG_BUS_SEL      0x00000380
-#define        AR5K_AR5212_PCICFG_CBEFIX_DIS   0x00000400
-#define AR5K_AR5212_PCICFG_SL_INTEN    0x00000800
-#define AR5K_AR5212_PCICFG_SL_INPEN    0x00002800
-#define AR5K_AR5212_PCICFG_SPWR_DN     0x00010000
-#define AR5K_AR5212_PCICFG_LEDMODE     0x000e0000
-#define AR5K_AR5212_PCICFG_LEDMODE_PROP        0x00000000
-#define AR5K_AR5212_PCICFG_LEDMODE_PROM        0x00020000
-#define AR5K_AR5212_PCICFG_LEDMODE_PWR 0x00040000
-#define AR5K_AR5212_PCICFG_LEDMODE_RAND        0x00060000
-#define AR5K_AR5212_PCICFG_LEDBLINK    0x00700000
-#define AR5K_AR5212_PCICFG_LEDBLINK_S  20
-#define AR5K_AR5212_PCICFG_LEDSLOW     0x00800000
+#define AR5K_AR5212_PCICFG                     0x4010
+#define AR5K_AR5212_PCICFG_SLEEP_CLOCK_EN      0x00000002 /* Enable sleep 
clock */
+#define AR5K_AR5212_PCICFG_CLKRUNEN            0x00000004
+#define AR5K_AR5212_PCICFG_EESIZE              0x00000018
+#define AR5K_AR5212_PCICFG_EESIZE_S            3
+#define AR5K_AR5212_PCICFG_EESIZE_4K           0
+#define AR5K_AR5212_PCICFG_EESIZE_8K           1
+#define AR5K_AR5212_PCICFG_EESIZE_16K          2
+#define AR5K_AR5212_PCICFG_EESIZE_FAIL         3
+#define AR5K_AR5212_PCICFG_LED                 0x00000060
+#define AR5K_AR5212_PCICFG_LED_NONE            0x00000000
+#define AR5K_AR5212_PCICFG_LED_PEND            0x00000020
+#define AR5K_AR5212_PCICFG_LED_ASSOC           0x00000040
+#define AR5K_AR5212_PCICFG_BUS_SEL             0x00000380
+#define AR5K_AR5212_PCICFG_CBEFIX_DIS          0x00000400
+#define AR5K_AR5212_PCICFG_SL_INTEN            0x00000800
+#define AR5K_AR5212_PCICFG_SL_INPEN            0x00002800
+#define AR5K_AR5212_PCICFG_RETRY_FIX           0x00001000 /* Enable pci core 
retry fix */
+#define AR5K_AR5212_PCICFG_SPWR_DN             0x00010000
+#define AR5K_AR5212_PCICFG_LEDMODE             0x000e0000
+#define AR5K_AR5212_PCICFG_LEDMODE_PROP                0x00000000
+#define AR5K_AR5212_PCICFG_LEDMODE_PROM                0x00020000
+#define AR5K_AR5212_PCICFG_LEDMODE_PWR         0x00040000
+#define AR5K_AR5212_PCICFG_LEDMODE_RAND                0x00060000
+#define AR5K_AR5212_PCICFG_LEDBLINK            0x00700000
+#define AR5K_AR5212_PCICFG_LEDBLINK_S          20
+#define AR5K_AR5212_PCICFG_LEDSLOW             0x00800000
 #define AR5K_AR5212_PCICFG_LEDSTATE                                    \
        (AR5K_AR5212_PCICFG_LED | AR5K_AR5212_PCICFG_LEDMODE |          \
        AR5K_AR5212_PCICFG_LEDBLINK | AR5K_AR5212_PCICFG_LEDSLOW)
+#define AR5K_AR5212_PCICFG_SLEEP_CLOCK_RATE    0x03000000 /* Sleep clock rate 
*/
+#define AR5K_AR5212_PCICFG_SLEEP_CLOCK_RATE_S  24
 
 /*
  * "General Purpose Input/Output" (GPIO) control register
@@ -993,7 +998,7 @@ typedef enum {
  * TSF parameter register
  */
 #define AR5K_AR5212_TSF_PARM           0x8104
-#define AR5K_AR5212_TSF_PARM_INC_M     0x000000ff
+#define AR5K_AR5212_TSF_PARM_INC       0x000000ff
 #define AR5K_AR5212_TSF_PARM_INC_S     0
 
 /*
@@ -1099,12 +1104,15 @@ typedef enum {
 #define AR5K_AR5212_PHY_SLMT_32MHZ     0x0000007f
 #define AR5K_AR5212_PHY_SCAL           0x9878
 #define AR5K_AR5212_PHY_SCAL_32MHZ     0x0000000e
+#define AR5K_AR5212_PHY_SCAL_32MHZ_2417        0x0000000a
+#define AR5K_AR5212_PHY_SCAL_32MHZ_HB63        0x00000032
 
 /*
  * PHY PLL control register
  */
 #define        AR5K_AR5212_PHY_PLL             0x987c
 #define        AR5K_AR5212_PHY_PLL_40MHZ       0x000000aa
+#define        AR5K_AR5212_PHY_PLL_40MHZ_5413  0x00000004
 #define        AR5K_AR5212_PHY_PLL_44MHZ       0x000000ab
 #define AR5K_AR5212_PHY_PLL_AR5111     0x00000000
 #define AR5K_AR5212_PHY_PLL_AR5112     0x00000040
Index: dev/ic/ar5212var.h
===================================================================
RCS file: /home/miguel/openbsd-cvsroot//src/sys/dev/ic/ar5212var.h,v
retrieving revision 1.15
diff -u -p -r1.15 ar5212var.h
--- dev/ic/ar5212var.h  30 Jul 2008 07:15:39 -0000      1.15
+++ dev/ic/ar5212var.h  3 May 2010 11:46:26 -0000
@@ -309,8 +309,6 @@ extern ar5k_attach_t ar5k_ar5212_attach;
        { 0x13fc,       0x00000000 },   \
        { 0x143c,       0x00000000 },   \
        { 0x147c,       0x00000000 },   \
-       { 0x143c,       0x00000000 },   \
-       { 0x147c,       0x00000000 },   \
        { 0x8004,       0x00000000 },   \
        { 0x8008,       0x00000000 },   \
        { 0x800c,       0x00000000 },   \
@@ -325,14 +323,7 @@ extern ar5k_attach_t ar5k_ar5212_attach;
        { 0x8048,       0x00000000 },   \
        { 0x8054,       0x00000000 },   \
        { 0x8058,       0x00000000 },   \
-       { 0x8080,       0x00000000 },   \
        { 0x805c,       0x000fc78f },   \
-       { 0x8084,       0x00000000 },   \
-       { 0x8088,       0x00000000 },   \
-       { 0x808c,       0x00000000 },   \
-       { 0x8090,       0x00000000 },   \
-       { 0x8094,       0x00000000 },   \
-       { 0x8098,       0x00000000 },   \
        { 0x80c0,       0x2a82301a },   \
        { 0x80c4,       0x05dc01e0 },   \
        { 0x80c8,       0x1f402710 },   \
@@ -431,22 +422,23 @@ extern ar5k_attach_t ar5k_ar5212_attach;
        { 0xa210,       0x00806333 },   \
        { 0xa214,       0x00106c10 },   \
        { 0xa218,       0x009c4060 },   \
-       { 0xa21c,       0x1483800a },   \
-       { 0xa220,       0x01831061 },   \
+       { 0xa220,       0x018830c6 },   \
        { 0xa224,       0x00000400 },   \
        { 0xa22c,       0x00000000 },   \
        { 0xa234,       0x20202020 },   \
-       { 0x9938,       0x20202020 },   \
+       { 0xa238,       0x20202020 },   \
        { 0xa240,       0x38490a20 },   \
        { 0xa244,       0x00007bb6 },   \
        { 0xa248,       0x0fff3ffc },   \
+       { 0x9b00,       0x00000000 },   \
+       { 0x9b28,       0x0000000c },   \
+       { 0x9b38,       0x00000012 },   \
+       { 0x9b64,       0x00000021 },   \
+       { 0x9b8c,       0x0000002d },   \
+       { 0x9b9c,       0x00000033 },   \
 }
 
 #define AR5K_AR5212_MODE       {               \
-       { 0xa200,\
-           { 0x00000008, 0x00000008, 0x0000000b, 0x0000000e, 0x0000000e } },\
-       { 0x9800,\
-           { 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 } },\
        { 0x1040,\
            { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },\
        { 0x1044,\
Index: dev/ic/ar5xxx.c
===================================================================
RCS file: /home/miguel/openbsd-cvsroot//src/sys/dev/ic/ar5xxx.c,v
retrieving revision 1.55
diff -u -p -r1.55 ar5xxx.c
--- dev/ic/ar5xxx.c     23 Sep 2009 18:03:30 -0000      1.55
+++ dev/ic/ar5xxx.c     3 May 2010 16:42:59 -0000
@@ -87,6 +87,7 @@ u_int32_t      ar5k_ar5110_chan2athchan(HAL_
 HAL_BOOL        ar5k_ar5111_channel(struct ath_hal *, HAL_CHANNEL *);
 HAL_BOOL        ar5k_ar5111_chan2athchan(u_int, struct ar5k_athchan_2ghz *);
 HAL_BOOL        ar5k_ar5112_channel(struct ath_hal *, HAL_CHANNEL *);
+HAL_BOOL        ar5k_ar2425_channel(struct ath_hal *, HAL_CHANNEL *);
 HAL_BOOL        ar5k_check_channel(struct ath_hal *, u_int16_t, u_int flags);
 
 HAL_BOOL        ar5k_ar5111_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
@@ -824,8 +825,9 @@ ar5k_eeprom_read_modes(struct ath_hal *h
                AR5K_EEPROM_READ(o++, val);
                ee->ee_i_gain[mode] |= (val << 3) & 0x38;
 
-               if (mode == AR5K_EEPROM_MODE_11G)
+               if (mode == AR5K_EEPROM_MODE_11G) {
                        ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
+               }
        }
 
        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
@@ -892,6 +894,18 @@ ar5k_eeprom_init(struct ath_hal *hal)
        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
                AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
                AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
+
+               /* XXX: Don't know which versions include these two */
+               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
+
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
+
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
+               }
        }
 
        if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
@@ -904,6 +918,12 @@ ar5k_eeprom_init(struct ath_hal *hal)
                ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
        }
 
+       AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val);
+       if ((hal->ah_mac_version == (AR5K_SREV_VER_AR2425 >> 4)) && val)
+               ee->ee_is_hb63 = AH_TRUE;
+       else
+               ee->ee_is_hb63 = AH_FALSE;
+
        /*
         * Get conformance test limit values
         */
@@ -931,17 +951,26 @@ ar5k_eeprom_init(struct ath_hal *hal)
 
        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;
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11A:
+               ee->ee_ob[mode][3]              = (val >> 5) & 0x7;
+               ee->ee_db[mode][3]              = (val >> 2) & 0x7;
+               ee->ee_ob[mode][2]              = (val << 1) & 0x7;
 
-       AR5K_EEPROM_READ(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;
+               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;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+       case AR5K_EEPROM_MODE_11B:
+               ee->ee_ob[mode][1]              = (val >> 4) & 0x7;
+               ee->ee_db[mode][1]              = val & 0x7;
+               break;
+       }
 
        if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
                return (ret);
@@ -1127,6 +1156,8 @@ ar5k_channel(struct ath_hal *hal, HAL_CH
                ret = ar5k_ar5110_channel(hal, channel);
        else if (hal->ah_radio == AR5K_AR5111)
                ret = ar5k_ar5111_channel(hal, channel);
+       else if (hal->ah_radio == AR5K_AR2425)
+               ret = ar5k_ar2425_channel(hal, channel);
        else
                ret = ar5k_ar5112_channel(hal, channel);
 
@@ -1286,6 +1317,44 @@ ar5k_ar5112_channel(struct ath_hal *hal,
 
        return (AH_TRUE);
 }
+
+HAL_BOOL
+ar5k_ar2425_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
+{
+       u_int32_t data, data0, data2;
+       u_int16_t c;
+
+       data = data0 = data2 = 0;
+       c = channel->c_channel + hal->ah_chanoff;
+
+       /*
+        * Set the channel on the AR2425
+        */
+       if (c < 4800) {
+               data0 = ar5k_bitswap((c - 2272), 8);
+               data2 = 0;
+       } else if ((c - (c % 5)) != 2 || c > 5435) {
+               if (!(c % 20) && c < 5120)
+                       data0 = ar5k_bitswap(((c - 4800) / 20 << 2), 8);
+               else if (!(c % 10))
+                       data0 = ar5k_bitswap(((c - 4800) / 10 << 1), 8);
+               else if (!(c % 5))
+                       data0 = ar5k_bitswap((c - 4800) / 5, 8);
+               else
+                       return (AH_FALSE);
+               data2 = ar5k_bitswap(1, 2);
+       } else {
+               data0 = ar5k_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
+               data2 = ar5k_bitswap(0, 2);
+       }
+
+       data = (data0 << 4) | (data2 << 2) | 0x1001;
+
+       AR5K_PHY_WRITE(0x27, data & 0xff);
+       AR5K_PHY_WRITE(0x36, (data >> 8) & 0x7f);
+ 
+       return (AH_TRUE);
+ }
 
 u_int
 ar5k_rfregs_op(u_int32_t *rf, u_int32_t offset, u_int32_t reg, u_int32_t bits,
Index: dev/ic/ar5xxx.h
===================================================================
RCS file: /home/miguel/openbsd-cvsroot//src/sys/dev/ic/ar5xxx.h,v
retrieving revision 1.48
diff -u -p -r1.48 ar5xxx.h
--- dev/ic/ar5xxx.h     20 Apr 2010 22:05:41 -0000      1.48
+++ dev/ic/ar5xxx.h     3 May 2010 15:24:14 -0000
@@ -155,7 +155,7 @@ typedef enum {
 #define AR5K_TXQ_FLAG_COMPRESSION_ENABLE       0x0008
 #define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE        0x0010
 #define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE        0x0020
-#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS         0x0040
+#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS         0x1000
 
 typedef struct {
        u_int32_t               tqi_ver;
@@ -645,6 +645,8 @@ struct ar5k_gain {
 #define AR5K_EEPROM_INFO_CKSUM         0xffff
 #define AR5K_EEPROM_INFO(_n)           (AR5K_EEPROM_INFO_BASE + (_n))
 
+#define AR5K_EEPROM_IS_HB63            0x000b  /* Talon detect */
+
 #define AR5K_EEPROM_VERSION            AR5K_EEPROM_INFO(1)
 #define AR5K_EEPROM_VERSION_3_0                0x3000
 #define AR5K_EEPROM_VERSION_3_1                0x3001
@@ -657,6 +659,7 @@ struct ar5k_gain {
 #define AR5K_EEPROM_VERSION_4_3                0x4003
 #define AR5K_EEPROM_VERSION_4_6                0x4006
 #define AR5K_EEPROM_VERSION_4_7                0x3007
+#define AR5K_EEPROM_VERSION_5_0                0x5000
 
 #define AR5K_EEPROM_MODE_11A   0
 #define AR5K_EEPROM_MODE_11B   1
@@ -695,12 +698,18 @@ struct ar5k_gain {
 #define AR5K_EEPROM_OBDB1_2GHZ 0x00ed
 
 /* 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)
+#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)
+#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v)    (((_v) >> 15) & 0x1)
+#define AR5K_EEPROM_MISC2                      0x00c6
+#define AR5K_EEPROM_MISC3                      0x00c7
+#define AR5K_EEPROM_MISC4                      AR5K_EEPROM_INFO(8)
+#define AR5K_EEPROM_MISC5                      AR5K_EEPROM_INFO(9)
+#define AR5K_EEPROM_MISC6                      AR5K_EEPROM_INFO(10)
 
 /* Some EEPROM defines */
 #define AR5K_EEPROM_EEP_SCALE          100
@@ -749,8 +758,14 @@ struct ar5k_eeprom_info {
        u_int16_t       ee_version;
        u_int16_t       ee_header;
        u_int16_t       ee_ant_gain;
+       HAL_BOOL        ee_is_hb63;
        u_int16_t       ee_misc0;
        u_int16_t       ee_misc1;
+       u_int16_t       ee_misc2;
+       u_int16_t       ee_misc3;
+       u_int16_t       ee_misc4;
+       u_int16_t       ee_misc5;
+       u_int16_t       ee_misc6;
        u_int16_t       ee_cck_ofdm_gain_delta;
        u_int16_t       ee_cck_ofdm_power_delta;
        u_int16_t       ee_scaled_cck_delta;
@@ -1259,7 +1274,8 @@ struct ar5k_srev_name {
 #define AR5K_SREV_VER_AR5414   0xa5
 #define AR5K_SREV_VER_AR5416   0xc0    /* PCI-Express */
 #define AR5K_SREV_VER_AR5418   0xca    /* PCI-Express */
-#define AR5K_SREV_VER_AR2425   0xe2    /* PCI-Express */
+#define AR5K_SREV_VER_AR2425   0xe0    /* Swan */
+#define AR5K_SREV_VER_AR2417   0xf0    /* Nala */
 #define AR5K_SREV_VER_UNSUPP   0xff
 
 #define AR5K_SREV_RAD_5110     0x00
@@ -1271,10 +1287,15 @@ struct ar5k_srev_name {
 #define AR5K_SREV_RAD_2112     0x40
 #define AR5K_SREV_RAD_2112A    0x45
 #define AR5K_SREV_RAD_SC0      0x56
+#define AR5K_SREV_RAD_5413     0x60
 #define AR5K_SREV_RAD_SC1      0x63
 #define AR5K_SREV_RAD_SC2      0xa2
+#define AR5K_SREV_RAD_2425     0xa2
 #define AR5K_SREV_RAD_5133     0xc0
 #define AR5K_SREV_RAD_UNSUPP   0xff
+
+#define AR5K_SREV_PHY_5413     0x61
+#define AR5K_SREV_PHY_2425     0x70
 
 #define AR5K_DEVID_AR2413      0x001a
 #define AR5K_DEVID_AR5413      0x001b

Reply via email to