From dce1c351b5070218f56c4b7db2fd60bb52577164 Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 24 Feb 2009 01:07:06 +0000 Subject: Add PCIE power control api: o add ah_configPCIE and ah_disablePCIE for drivers to configure PCIE power save operation (modeled after ath9k, may need changes) o add private state flag to indicate if device is PCIE (replaces private hack in 5212 code) o add serdes programming ini bits for 5416 and later parts and setup for each part (5416 and 9160 logic hand-crafted from existing routines); 5212 remains open-coded but is now hooked in via ah_configPCIE o add PCIE workaround gunk o add ar5416AttachPCIE for iodomatic code used by 5416 and later parts --- sys/dev/ath/ath_hal/ah.h | 2 + sys/dev/ath/ath_hal/ah_internal.h | 5 ++ sys/dev/ath/ath_hal/ar5210/ar5210_attach.c | 15 ++++++ sys/dev/ath/ath_hal/ar5211/ar5211_attach.c | 15 ++++++ sys/dev/ath/ath_hal/ar5212/ar2425.c | 2 +- sys/dev/ath/ath_hal/ar5212/ar5212.h | 2 - sys/dev/ath/ath_hal/ar5212/ar5212_attach.c | 80 +++++++++++++++++------------- sys/dev/ath/ath_hal/ar5212/ar5212_reset.c | 2 +- sys/dev/ath/ath_hal/ar5212/ar5413.c | 2 +- sys/dev/ath/ath_hal/ar5416/ar5416.h | 2 + sys/dev/ath/ath_hal/ar5416/ar5416.ini | 16 +++++- sys/dev/ath/ath_hal/ar5416/ar5416_attach.c | 27 ++++++++++ sys/dev/ath/ath_hal/ar5416/ar5416reg.h | 13 +++++ sys/dev/ath/ath_hal/ar5416/ar9160.ini | 16 +++++- sys/dev/ath/ath_hal/ar5416/ar9160_attach.c | 5 +- 15 files changed, 162 insertions(+), 42 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index d12c018..da9060a 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -624,6 +624,8 @@ struct ath_hal { HAL_BOOL bChannelChange, HAL_STATUS *status); HAL_BOOL __ahdecl(*ah_phyDisable)(struct ath_hal *); HAL_BOOL __ahdecl(*ah_disable)(struct ath_hal *); + void __ahdecl(*ah_configPCIE)(struct ath_hal *, HAL_BOOL restore); + void __ahdecl(*ah_disablePCIE)(struct ath_hal *); void __ahdecl(*ah_setPCUConfig)(struct ath_hal *); HAL_BOOL __ahdecl(*ah_perCalibration)(struct ath_hal*, struct ieee80211_channel *, HAL_BOOL *); diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index 3255054..8b00e30 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -269,6 +269,7 @@ struct ath_hal_private { uint16_t ah_phyRev; /* PHY revision */ uint16_t ah_analog5GhzRev; /* 2GHz radio revision */ uint16_t ah_analog2GhzRev; /* 5GHz radio revision */ + uint8_t ah_ispcie; /* PCIE, special treatment */ HAL_OPMODE ah_opmode; /* operating mode from reset */ const struct ieee80211_channel *ah_curchan;/* operating channel */ @@ -327,6 +328,10 @@ struct ath_hal_private { AH_PRIVATE(_ah)->ah_getNfAdjust(_ah, _c) #define ath_hal_getNoiseFloor(_ah, _nfArray) \ AH_PRIVATE(_ah)->ah_getNoiseFloor(_ah, _nfArray) +#define ath_hal_configPCIE(_ah, _reset) \ + (_ah)->ah_configPCIE(_ah, _reset) +#define ath_hal_disablePCIE(_ah) \ + (_ah)->ah_disablePCIE(_ah) #define ath_hal_eepromDetach(_ah) \ AH_PRIVATE(_ah)->ah_eepromDetach(_ah) diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c index 263edcc..3df3924 100644 --- a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c +++ b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c @@ -33,6 +33,9 @@ static HAL_BOOL ar5210GetChannelEdges(struct ath_hal *, static HAL_BOOL ar5210GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan); +static void ar5210ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore); +static void ar5210DisablePCIE(struct ath_hal *ah); + static const struct ath_hal_private ar5210hal = {{ .ah_magic = AR5210_MAGIC, .ah_abi = HAL_ABI_VERSION, @@ -44,6 +47,8 @@ static const struct ath_hal_private ar5210hal = {{ .ah_reset = ar5210Reset, .ah_phyDisable = ar5210PhyDisable, .ah_disable = ar5210Disable, + .ah_configPCIE = ar5210ConfigPCIE, + .ah_disablePCIE = ar5210DisablePCIE, .ah_setPCUConfig = ar5210SetPCUConfig, .ah_perCalibration = ar5210PerCalibration, .ah_perCalibrationN = ar5210PerCalibrationN, @@ -318,6 +323,16 @@ ar5210GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan) return AH_TRUE; } +static void +ar5210ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore) +{ +} + +static void +ar5210DisablePCIE(struct ath_hal *ah) +{ +} + /* * Fill all software cached or static hardware state information. */ diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c index cc969c3..81af95f 100644 --- a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c +++ b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c @@ -33,6 +33,9 @@ static HAL_BOOL ar5211GetChannelEdges(struct ath_hal *ah, static HAL_BOOL ar5211GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan); +static void ar5211ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore); +static void ar5211DisablePCIE(struct ath_hal *ah); + static const struct ath_hal_private ar5211hal = {{ .ah_magic = AR5211_MAGIC, .ah_abi = HAL_ABI_VERSION, @@ -44,6 +47,8 @@ static const struct ath_hal_private ar5211hal = {{ .ah_reset = ar5211Reset, .ah_phyDisable = ar5211PhyDisable, .ah_disable = ar5211Disable, + .ah_configPCIE = ar5211ConfigPCIE, + .ah_disablePCIE = ar5211DisablePCIE, .ah_setPCUConfig = ar5211SetPCUConfig, .ah_perCalibration = ar5211PerCalibration, .ah_perCalibrationN = ar5211PerCalibrationN, @@ -440,6 +445,16 @@ ar5211GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan) return AH_TRUE; } +static void +ar5211ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore) +{ +} + +static void +ar5211DisablePCIE(struct ath_hal *ah) +{ +} + /* * Fill all software cached or static hardware state information. */ diff --git a/sys/dev/ath/ath_hal/ar5212/ar2425.c b/sys/dev/ath/ath_hal/ar5212/ar2425.c index 8d29474..e487489 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar2425.c +++ b/sys/dev/ath/ath_hal/ar5212/ar2425.c @@ -61,7 +61,7 @@ ar2425WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, * Bit 0 enables link to go to L1 when MAC goes to sleep. * Bit 3 enables the loop back the link down to reset. */ - if (IS_PCIE(ah) && ath_hal_pcieL1SKPEnable) { + if (AH_PRIVATE(ah)->ah_ispcie && && ath_hal_pcieL1SKPEnable) { OS_REG_WRITE(ah, AR_PCIE_PMC, AR_PCIE_PMC_ENA_L1 | AR_PCIE_PMC_ENA_RESET); } diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212.h b/sys/dev/ath/ath_hal/ar5212/ar5212.h index 0b682ef..4f60c3b 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212.h +++ b/sys/dev/ath/ath_hal/ar5212/ar5212.h @@ -356,8 +356,6 @@ struct ath_hal_5212 { ((AH_PRIVATE(ah)->ah_macVersion) == AR_SREV_2417) #define IS_HB63(ah) (AH5212(ah)->ah_isHb63 == AH_TRUE) -#define IS_PCIE(ah) (IS_5424(ah) || IS_2425(ah)) - #define AH_RADIO_MAJOR(ah) \ (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) #define AH_RADIO_MINOR(ah) \ diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c index 7fa370e..742523f 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c @@ -29,6 +29,9 @@ #define AH_5212_COMMON #include "ar5212/ar5212.ini" +static void ar5212ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore); +static void ar5212DisablePCIE(struct ath_hal *ah); + static const struct ath_hal_private ar5212hal = {{ .ah_magic = AR5212_MAGIC, .ah_abi = HAL_ABI_VERSION, @@ -40,6 +43,8 @@ static const struct ath_hal_private ar5212hal = {{ .ah_reset = ar5212Reset, .ah_phyDisable = ar5212PhyDisable, .ah_disable = ar5212Disable, + .ah_configPCIE = ar5212ConfigPCIE, + .ah_disablePCIE = ar5212DisablePCIE, .ah_setPCUConfig = ar5212SetPCUConfig, .ah_perCalibration = ar5212PerCalibration, .ah_perCalibrationN = ar5212PerCalibrationN, @@ -154,36 +159,6 @@ static const struct ath_hal_private ar5212hal = {{ .ah_getChipPowerLimits = ar5212GetChipPowerLimits, }; -/* - * Disable PLL when in L0s as well as receiver clock when in L1. - * This power saving option must be enabled through the Serdes. - * - * Programming the Serdes must go through the same 288 bit serial shift - * register as the other analog registers. Hence the 9 writes. - * - * XXX Clean up the magic numbers. - */ -static void -configurePciePowerSave(struct ath_hal *ah) -{ - OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); - OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); - - /* RX shut off when elecidle is asserted */ - OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); - OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); - OS_REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); - - /* Shut off PLL and CLKREQ active in L1 */ - OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); - OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); - OS_REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); - OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); - - /* Load the new settings */ - OS_REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); -} - uint32_t ar5212GetRadioRev(struct ath_hal *ah) { @@ -320,7 +295,7 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) { #define AH_EEPROM_PROTECT(ah) \ - (IS_PCIE(ah) ? AR_EEPROM_PROTECT_PCIE : AR_EEPROM_PROTECT) + (AH_PRIVATE(ah)->ah_ispcie)? AR_EEPROM_PROTECT_PCIE : AR_EEPROM_PROTECT) struct ath_hal_5212 *ahp; struct ath_hal *ah; struct ath_hal_rf *rf; @@ -352,6 +327,7 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc, val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID; AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S; AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION; + AH_PRIVATE(ah)->ah_ispcie = IS_5424(ah) || IS_2425(ah); if (!ar5212IsMacSupported(AH_PRIVATE(ah)->ah_macVersion, AH_PRIVATE(ah)->ah_macRev)) { HALDEBUG(ah, HAL_DEBUG_ANY, @@ -374,9 +350,9 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc, AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); - if (IS_PCIE(ah)) { + if (AH_PRIVATE(ah)->ah_ispcie) { /* XXX: build flag to disable this? */ - configurePciePowerSave(ah); + ath_hal_configPCIE(ah, AH_FALSE); } if (!ar5212ChipTest(ah)) { @@ -466,7 +442,7 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc, val = OS_REG_READ(ah, AR_PCICFG); val = MS(val, AR_PCICFG_EEPROM_SIZE); if (val == 0) { - if (!IS_PCIE(ah)) { + if (!AH_PRIVATE(ah)->ah_ispcie) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unsupported EEPROM size %u (0x%x) found\n", __func__, val, val); @@ -663,6 +639,42 @@ ar5212GetChannelEdges(struct ath_hal *ah, } /* + * Disable PLL when in L0s as well as receiver clock when in L1. + * This power saving option must be enabled through the Serdes. + * + * Programming the Serdes must go through the same 288 bit serial shift + * register as the other analog registers. Hence the 9 writes. + * + * XXX Clean up the magic numbers. + */ +static void +ar5212ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore) +{ + OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); + OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); + + /* RX shut off when elecidle is asserted */ + OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); + OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); + OS_REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); + + /* Shut off PLL and CLKREQ active in L1 */ + OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); + OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); + OS_REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); + OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); + + /* Load the new settings */ + OS_REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); +} + +static void +ar5212DisablePCIE(struct ath_hal *ah) +{ + /* NB: fill in for 9100 */ +} + +/* * Fill all software cached or static hardware state information. * Return failure if capabilities are to come from EEPROM and * cannot be read. diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c b/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c index 1c29a86..fc937ea 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c @@ -1107,7 +1107,7 @@ ar5212SetResetReg(struct ath_hal *ah, uint32_t resetMask) /* XXX ar5212MacStop & co. */ - if (IS_PCIE(ah)) { + if (AH_PRIVATE(ah)->ah_ispcie) { resetMask &= ~AR_RC_PCI; } diff --git a/sys/dev/ath/ath_hal/ar5212/ar5413.c b/sys/dev/ath/ath_hal/ar5212/ar5413.c index 88ecdf2..ab6cc65 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5413.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5413.c @@ -232,7 +232,7 @@ ar5413SetRfRegs(struct ath_hal *ah, ar5212ModifyRfBuffer(priv->Bank6Data, 1 , 1, 291, 2); /* Optimum value for rf_pwd_iclobuf2G for PCIe chips only */ - if (IS_PCIE(ah)) { + if (AH_PRIVATE(ah)->ah_ispcie) { ar5212ModifyRfBuffer(priv->Bank6Data, ath_hal_reverseBits(6, 3), 3, 131, 3); } diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h index 1465238..27aa9e8 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416.h @@ -57,6 +57,7 @@ struct ath_hal_5416 { HAL_INI_ARRAY ah_ini_bank6; HAL_INI_ARRAY ah_ini_bank7; HAL_INI_ARRAY ah_ini_addac; + HAL_INI_ARRAY ah_ini_pcieserdes; u_int ah_globaltxtimeout; /* global tx timeout */ u_int ah_gpioMask; @@ -89,6 +90,7 @@ extern void ar5416InitState(struct ath_hal_5416 *, uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status); extern void ar5416Detach(struct ath_hal *ah); +extern void ar5416AttachPCIE(struct ath_hal *ah); extern HAL_BOOL ar5416FillCapabilityInfo(struct ath_hal *ah); #define IS_5GHZ_FAST_CLOCK_EN(_ah, _c) \ diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.ini b/sys/dev/ath/ath_hal/ar5416/ar5416.ini index 6e96f68..eee859e 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416.ini +++ b/sys/dev/ath/ath_hal/ar5416/ar5416.ini @@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: ar5416.ini,v 1.3 2008/11/10 04:08:04 sam Exp $ + * $FreeBSD$ */ /* Auto Generated PCI Register Writes. Created: 09/20/06 */ @@ -686,3 +686,17 @@ static const uint32_t ar5416Addac[][2] = { {0x0989c, 0x00000000 }, {0x098c4, 0x00000000 }, }; + +/* hand-crafted from code that does explicit register writes */ +static const uint32_t ar5416PciePhy[][2] = { + { AR_PCIE_SERDES, 0x9248fc00 }, + { AR_PCIE_SERDES, 0x24924924 }, + { AR_PCIE_SERDES, 0x28000039 }, + { AR_PCIE_SERDES, 0x53160824 }, + { AR_PCIE_SERDES, 0xe5980579 }, + { AR_PCIE_SERDES, 0x001defff }, + { AR_PCIE_SERDES, 0x1aaabe40 }, + { AR_PCIE_SERDES, 0xbe105554 }, + { AR_PCIE_SERDES, 0x000e3007 }, + { AR_PCIE_SERDES2, 0x00000000 }, +}; diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c index 233b0da..0eb9e22 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c @@ -28,6 +28,8 @@ #include "ar5416/ar5416.ini" +static void ar5416ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore); + static void ar5416AniSetup(struct ath_hal *ah) { @@ -76,6 +78,7 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc, ah->ah_reset = ar5416Reset; ah->ah_phyDisable = ar5416PhyDisable; ah->ah_disable = ar5416Disable; + ah->ah_configPCIE = ar5416ConfigPCIE; ah->ah_perCalibration = ar5416PerCalibration; ah->ah_perCalibrationN = ar5416PerCalibrationN, ah->ah_resetCalValid = ar5416ResetCalValid, @@ -219,6 +222,7 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc, val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID; AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S; AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION; + AH_PRIVATE(ah)->ah_ispcie = (devid == AR5416_DEVID_PCIE); /* setup common ini data; rf backends handle remainder */ HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes, 6); @@ -244,6 +248,9 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc, HAL_INI_VAL((struct ini *)&AH5416(ah)->ah_ini_addac, 31, 1) = 0; } + HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes, ar5416PciePhy, 2); + ar5416AttachPCIE(ah); + ecode = ath_hal_v14EepromAttach(ah); if (ecode != HAL_OK) goto bad; @@ -368,6 +375,26 @@ ar5416Detach(struct ath_hal *ah) ath_hal_free(ah); } +void +ar5416AttachPCIE(struct ath_hal *ah) +{ + if (AH_PRIVATE(ah)->ah_ispcie) + ath_hal_configPCIE(ah, AH_FALSE); + else + ath_hal_disablePCIE(ah); +} + +static void +ar5416ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore) +{ + if (AH_PRIVATE(ah)->ah_ispcie && !restore) { + ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0); + OS_DELAY(1000); + OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); + OS_REG_WRITE(ah, AR_WA, AR_WA_DEFAULT); + } +} + /* * Fill all software cached or static hardware state information. * Return failure if capabilities are to come from EEPROM and diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h index ac96799..3afb163 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h @@ -31,6 +31,8 @@ #define AR_GTTM 0x0068 /* global transmit timeout mode */ #define AR_CST 0x006C /* carrier sense timeout */ #define AR_MAC_LED 0x1f04 /* LED control */ +#define AR_WA 0x4004 /* PCIE work-arounds */ +#define AR_PCIE_PM_CTRL 0x4014 #define AR_AHB_MODE 0x4024 /* AHB mode for dma */ #define AR_INTR_SYNC_CAUSE_CLR 0x4028 /* clear interrupt */ #define AR_INTR_SYNC_CAUSE 0x4028 /* check pending interrupts */ @@ -185,6 +187,17 @@ #define AR_MAC_LED_ASSOC_PEND 0x00000800 /* STA is trying to associate */ #define AR_MAC_LED_ASSOC_S 10 +#define AR_WA_UNTIE_RESET_EN 0x00008000 /* ena PCI reset to POR */ +#define AR_WA_RESET_EN 0x00040000 /* ena AR_WA_UNTIE_RESET_EN */ +#define AR_WA_ANALOG_SHIFT 0x00100000 +#define AR_WA_POR_SHORT 0x00200000 /* PCIE phy reset control */ + +#define AR_WA_DEFAULT 0x0000073f +#define AR9280_WA_DEFAULT 0x0040073f +#define AR9285_WA_DEFAULT 0x004a05cb + +#define AR_PCIE_PM_CTRL_ENA 0x00080000 + #define AR_AHB_EXACT_WR_EN 0x00000000 /* write exact bytes */ #define AR_AHB_BUF_WR_EN 0x00000001 /* buffer write upto cacheline*/ #define AR_AHB_EXACT_RD_EN 0x00000000 /* read exact bytes */ diff --git a/sys/dev/ath/ath_hal/ar5416/ar9160.ini b/sys/dev/ath/ath_hal/ar5416/ar9160.ini index 85f09a3..275aa48 100755 --- a/sys/dev/ath/ath_hal/ar5416/ar9160.ini +++ b/sys/dev/ath/ath_hal/ar5416/ar9160.ini @@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: ar9160.ini,v 1.5 2008/11/10 04:08:05 sam Exp $ + * $FreeBSD$ */ /* Auto Generated PCI Register Writes. Created: 05/22/08 */ @@ -697,3 +697,17 @@ static const uint32_t ar9160Addac_1_1[][2] = { {0x0000989c, 0x00000000 }, {0x000098cc, 0x00000000 }, }; + +/* hand-crafted from code that does explicit register writes */ +static const uint32_t ar9160PciePhy[][2] = { + { AR_PCIE_SERDES, 0x9248fc00 }, + { AR_PCIE_SERDES, 0x24924924 }, + { AR_PCIE_SERDES, 0x28000039 }, + { AR_PCIE_SERDES, 0x53160824 }, + { AR_PCIE_SERDES, 0xe5980579 }, + { AR_PCIE_SERDES, 0x001defff }, + { AR_PCIE_SERDES, 0x1aaabe40 }, + { AR_PCIE_SERDES, 0xbe105554 }, + { AR_PCIE_SERDES, 0x000e3007 }, + { AR_PCIE_SERDES2, 0x00000000 }, +}; diff --git a/sys/dev/ath/ath_hal/ar5416/ar9160_attach.c b/sys/dev/ath/ath_hal/ar5416/ar9160_attach.c index 14e8d56..4e4d679 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar9160_attach.c +++ b/sys/dev/ath/ath_hal/ar5416/ar9160_attach.c @@ -148,7 +148,7 @@ ar9160Attach(uint16_t devid, HAL_SOFTC sc, AH_PRIVATE(ah)->ah_macVersion = (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S; AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION); - /* XXX extract pcie info */ + AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0; /* setup common ini data; rf backends handle remainder */ HAL_INI_INIT(&ahp->ah_ini_modes, ar9160Modes, 6); @@ -170,6 +170,9 @@ ar9160Attach(uint16_t devid, HAL_SOFTC sc, if (ecode != HAL_OK) goto bad; + HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes, ar9160PciePhy, 2); + ar5416AttachPCIE(ah); + if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); ecode = HAL_EIO; -- cgit v1.1