From owner-svn-src-all@FreeBSD.ORG Tue Oct 18 03:17:06 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B41BD106564A; Tue, 18 Oct 2011 03:17:06 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A37EF8FC08; Tue, 18 Oct 2011 03:17:06 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p9I3H6jL053793; Tue, 18 Oct 2011 03:17:06 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9I3H6p2053790; Tue, 18 Oct 2011 03:17:06 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201110180317.p9I3H6p2053790@svn.freebsd.org> From: Adrian Chadd Date: Tue, 18 Oct 2011 03:17:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226489 - head/sys/dev/ath/ath_hal/ar5212 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Oct 2011 03:17:06 -0000 Author: adrian Date: Tue Oct 18 03:17:06 2011 New Revision: 226489 URL: http://svn.freebsd.org/changeset/base/226489 Log: Port over some missing code from the ar5212 reference driver reset path. The final missing bit here is enabling the PCI configuration register read, but there's currently no glue available for the HAL to read (and write) PCI configuration space registers. Obtained from: Atheros Modified: head/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c head/sys/dev/ath/ath_hal/ar5212/ar5212reg.h Modified: head/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c ============================================================================== --- head/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c Tue Oct 18 03:01:41 2011 (r226488) +++ head/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c Tue Oct 18 03:17:06 2011 (r226489) @@ -96,6 +96,16 @@ write_common(struct ath_hal *ah, const H #define IS_DISABLE_FAST_ADC_CHAN(x) (((x) == 2462) || ((x) == 2467)) /* + * XXX NDIS 5.x code had MAX_RESET_WAIT set to 2000 for AP code + * and 10 for Client code + */ +#define MAX_RESET_WAIT 10 + +#define TX_QUEUEPEND_CHECK 1 +#define TX_ENABLE_CHECK 2 +#define RX_ENABLE_CHECK 4 + +/* * Places the device in and out of reset and then places sane * values in the registers based on EEPROM config, initialization * vectors (as determined by the mode), and station configuration @@ -1104,6 +1114,76 @@ ar5212ResetCalValid(struct ath_hal *ah, return AH_TRUE; } +/************************************************************** + * ar5212MacStop + * + * Disables all active QCUs and ensure that the mac is in a + * quiessence state. + */ +static HAL_BOOL +ar5212MacStop(struct ath_hal *ah) +{ + HAL_BOOL status; + uint32_t count; + uint32_t pendFrameCount; + uint32_t macStateFlag; + uint32_t queue; + + status = AH_FALSE; + + /* Disable Rx Operation ***********************************/ + OS_REG_SET_BIT(ah, AR_CR, AR_CR_RXD); + + /* Disable TX Operation ***********************************/ +#ifdef NOT_YET + ar5212SetTxdpInvalid(ah); +#endif + OS_REG_SET_BIT(ah, AR_Q_TXD, AR_Q_TXD_M); + + /* Polling operation for completion of disable ************/ + macStateFlag = TX_ENABLE_CHECK | RX_ENABLE_CHECK; + + for (count = 0; count < MAX_RESET_WAIT; count++) { + if (macStateFlag & RX_ENABLE_CHECK) { + if (!OS_REG_IS_BIT_SET(ah, AR_CR, AR_CR_RXE)) { + macStateFlag &= ~RX_ENABLE_CHECK; + } + } + + if (macStateFlag & TX_ENABLE_CHECK) { + if (!OS_REG_IS_BIT_SET(ah, AR_Q_TXE, AR_Q_TXE_M)) { + macStateFlag &= ~TX_ENABLE_CHECK; + macStateFlag |= TX_QUEUEPEND_CHECK; + } + } + if (macStateFlag & TX_QUEUEPEND_CHECK) { + pendFrameCount = 0; + for (queue = 0; queue < AR_NUM_DCU; queue++) { + pendFrameCount += OS_REG_READ(ah, + AR_Q0_STS + (queue * 4)) & + AR_Q_STS_PEND_FR_CNT; + } + if (pendFrameCount == 0) { + macStateFlag &= ~TX_QUEUEPEND_CHECK; + } + } + if (macStateFlag == 0) { + status = AH_TRUE; + break; + } + OS_DELAY(50); + } + + if (status != AH_TRUE) { + HALDEBUG(ah, HAL_DEBUG_RESET, + "%s:Failed to stop the MAC state 0x%x\n", + __func__, macStateFlag); + } + + return status; +} + + /* * Write the given reset bit mask into the reset register */ @@ -1113,12 +1193,75 @@ ar5212SetResetReg(struct ath_hal *ah, ui uint32_t mask = resetMask ? resetMask : ~0; HAL_BOOL rt; - /* XXX ar5212MacStop & co. */ - + /* Never reset the PCIE core */ if (AH_PRIVATE(ah)->ah_ispcie) { resetMask &= ~AR_RC_PCI; } + if (resetMask & (AR_RC_MAC | AR_RC_PCI)) { + /* + * To ensure that the driver can reset the + * MAC, wake up the chip + */ + rt = ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE); + + if (rt != AH_TRUE) { + return rt; + } + + /* + * Disable interrupts + */ + OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE); + OS_REG_READ(ah, AR_IER); + + if (ar5212MacStop(ah) != AH_TRUE) { + /* + * Failed to stop the MAC gracefully; let's be more forceful then + */ + + /* need some delay before flush any pending MMR writes */ + OS_DELAY(15); + OS_REG_READ(ah, AR_RXDP); + + resetMask |= AR_RC_MAC | AR_RC_BB; + /* _Never_ reset PCI Express core */ + if (! AH_PRIVATE(ah)->ah_ispcie) { + resetMask |= AR_RC_PCI; + } +#if 0 + /* + * Flush the park address of the PCI controller + */ + /* Read PCI slot information less than Hainan revision */ + if (AH_PRIVATE(ah)->ah_bustype == HAL_BUS_TYPE_PCI) { + if (!IS_5112_REV5_UP(ah)) { +#define PCI_COMMON_CONFIG_STATUS 0x06 + u_int32_t i; + u_int16_t reg16; + + for (i = 0; i < 32; i++) { + ath_hal_read_pci_config_space(ah, + PCI_COMMON_CONFIG_STATUS, + ®16, sizeof(reg16)); + } + } +#undef PCI_COMMON_CONFIG_STATUS + } +#endif + } else { + /* + * MAC stopped gracefully; no need to warm-reset the PCI bus + */ + + resetMask &= ~AR_RC_PCI; + + /* need some delay before flush any pending MMR writes */ + OS_DELAY(15); + OS_REG_READ(ah, AR_RXDP); + } + } + (void) OS_REG_READ(ah, AR_RXDP);/* flush any pending MMR writes */ OS_REG_WRITE(ah, AR_RC, resetMask); OS_DELAY(15); /* need to wait at least 128 clocks Modified: head/sys/dev/ath/ath_hal/ar5212/ar5212reg.h ============================================================================== --- head/sys/dev/ath/ath_hal/ar5212/ar5212reg.h Tue Oct 18 03:01:41 2011 (r226488) +++ head/sys/dev/ath/ath_hal/ar5212/ar5212reg.h Tue Oct 18 03:17:06 2011 (r226489) @@ -94,7 +94,9 @@ #define AR_QTXDP(_i) (AR_Q0_TXDP + ((_i)<<2)) #define AR_Q_TXE 0x0840 /* MAC Transmit Queue enable */ +#define AR_Q_TXE_M 0x000003FF /* Mask for TXE (QCU 0-9) */ #define AR_Q_TXD 0x0880 /* MAC Transmit Queue disable */ +#define AR_Q_TXD_M 0x000003FF /* Mask for TXD (QCU 0-9) */ #define AR_Q0_CBRCFG 0x08c0 /* MAC CBR configuration */ #define AR_Q1_CBRCFG 0x08c4 /* MAC CBR configuration */