summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-04-28 03:07:36 +0000
committeradrian <adrian@FreeBSD.org>2012-04-28 03:07:36 +0000
commitbd74977b95dd7056d2ce4b2d956b562f422b3e39 (patch)
treea975dce7b50c0b24e282f295d861c519f880198d
parent62cedd908a624bdacbdd0154d0cf129e694cb27a (diff)
downloadFreeBSD-src-bd74977b95dd7056d2ce4b2d956b562f422b3e39.zip
FreeBSD-src-bd74977b95dd7056d2ce4b2d956b562f422b3e39.tar.gz
Add an AR5416 PCU DMA stop method, as a check for the AR9130 is needed.
The reference driver has a 3ms delay for the AR9130 but I'm not as yet sure why. From what I can gather, it's likely waiting for some FIFO flush to occur. At some point in the future it may be worthwhile adding a WMAC FIFO flush here, but that'd require some side-call through to the SoC DDR flush routines. Obtained from: Atheros
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416.h1
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_attach.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_recv.c34
3 files changed, 36 insertions, 0 deletions
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h
index ecb2443..1483622 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416.h
@@ -234,6 +234,7 @@ extern HAL_BOOL ar5416SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry,
extern uint32_t ar5416GetRxFilter(struct ath_hal *ah);
extern void ar5416SetRxFilter(struct ath_hal *ah, uint32_t bits);
+extern HAL_BOOL ar5416StopDmaReceive(struct ath_hal *ah);
extern void ar5416StartPcuReceive(struct ath_hal *ah);
extern void ar5416StopPcuReceive(struct ath_hal *ah);
extern HAL_BOOL ar5416SetupRxDesc(struct ath_hal *,
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
index 80d6a25..422845d 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
@@ -119,6 +119,7 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
/* Receive Functions */
ah->ah_getRxFilter = ar5416GetRxFilter;
ah->ah_setRxFilter = ar5416SetRxFilter;
+ ah->ah_stopDmaReceive = ar5416StopDmaReceive;
ah->ah_startPcuReceive = ar5416StartPcuReceive;
ah->ah_stopPcuReceive = ar5416StopPcuReceive;
ah->ah_setupRxDesc = ar5416SetupRxDesc;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c b/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
index de4343e..87d7de7 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
@@ -67,6 +67,40 @@ ar5416SetRxFilter(struct ath_hal *ah, u_int32_t bits)
}
/*
+ * Stop Receive at the DMA engine
+ */
+HAL_BOOL
+ar5416StopDmaReceive(struct ath_hal *ah)
+{
+ HAL_BOOL status;
+
+ OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP);
+ OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */
+ if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) {
+ OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP_ERR);
+#ifdef AH_DEBUG
+ ath_hal_printf(ah, "%s: dma failed to stop in 10ms\n"
+ "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
+ __func__,
+ OS_REG_READ(ah, AR_CR),
+ OS_REG_READ(ah, AR_DIAG_SW));
+#endif
+ status = AH_FALSE;
+ } else {
+ status = AH_TRUE;
+ }
+
+ /*
+ * XXX Is this to flush whatever is in a FIFO somewhere?
+ * XXX If so, what should the correct behaviour should be?
+ */
+ if (AR_SREV_9100(ah))
+ OS_DELAY(3000);
+
+ return (status);
+}
+
+/*
* Start receive at the PCU engine
*/
void
OpenPOWER on IntegriCloud