On Thu, Apr 29, 2010 at 12:27:41AM +0800, Alexander Vladimirov wrote:
> On Wed, 28 Apr 2010 14:15:27 +0100
> Luis Henriques <[email protected]> wrote:
> > Interesting. This is behaviour seems to be different from what
> > Alexander was seeing. Is this correct Alexander? I believe you
> > referred in your last email that your system is not hanging anymore.
> >
> > --
> > Luis
>
> Your latest patches lack following changeset:
>
> @@ -2860,10 +2860,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 */
>
> I think this is the reason why kernel locks up on ar5k_ar5212_reset.
Thanks Alexander. Once again, you proved that I'm not able to copy & paste
source code! :-)
Anyway, this gave me the chance to find some more differences between
ath(4) and linux ath5k device driver. Two constants (HAL_MODE_11G and
HAL_MODE_XR) were defined with the wrong values. See updated patch
bellow.
--
Luis
Index: sys/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
--- sys/dev/ic/ar5212.c 2 Jun 2009 12:39:02 -0000 1.51
+++ sys/dev/ic/ar5212.c 28 Apr 2010 17:30:34 -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: sys/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
--- sys/dev/ic/ar5212reg.h 30 Jul 2008 07:15:39 -0000 1.12
+++ sys/dev/ic/ar5212reg.h 26 Apr 2010 19:27:11 -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: sys/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
--- sys/dev/ic/ar5212var.h 30 Jul 2008 07:15:39 -0000 1.15
+++ sys/dev/ic/ar5212var.h 25 Apr 2010 12:28:03 -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: sys/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
--- sys/dev/ic/ar5xxx.c 23 Sep 2009 18:03:30 -0000 1.55
+++ sys/dev/ic/ar5xxx.c 25 Apr 2010 12:28:03 -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);
@@ -892,6 +893,12 @@ 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 (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
@@ -904,6 +911,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
*/
@@ -1127,6 +1140,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 +1301,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: sys/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
--- sys/dev/ic/ar5xxx.h 20 Apr 2010 22:05:41 -0000 1.48
+++ sys/dev/ic/ar5xxx.h 28 Apr 2010 17:33:17 -0000
@@ -92,9 +92,9 @@ typedef enum {
HAL_MODE_TURBO = 0x002,
HAL_MODE_11B = 0x004,
HAL_MODE_PUREG = 0x008,
- HAL_MODE_11G = 0x010,
+ HAL_MODE_11G = 0x080,
HAL_MODE_108G = 0x020,
- HAL_MODE_XR = 0x040,
+ HAL_MODE_XR = 0x010,
HAL_MODE_ALL = 0xfff
} HAL_MODE;
@@ -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
@@ -695,12 +697,15 @@ 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
/* Some EEPROM defines */
#define AR5K_EEPROM_EEP_SCALE 100
@@ -749,8 +754,11 @@ 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_cck_ofdm_gain_delta;
u_int16_t ee_cck_ofdm_power_delta;
u_int16_t ee_scaled_cck_delta;
@@ -1259,7 +1267,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 +1280,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