From 908341abeb90b579699a0481e61a2574f61baaab Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Mon, 28 Nov 2016 08:13:20 +0000 Subject: [PATCH] [ath] wake up the hardware from power-save before doing transmit completion checking. This was being done in the pre-AR9380 case, but not for AR9380 and later. When powersave in STA mode is enabled, this may have lead to the transmit completion code doing this: * call the task, which doesn't wake up the hardware * complete the frames, which doesn't touch the hardware * schedule pending frames on the hardware queue, which DOES touch the hardware, and this will be ignored This would show up in the logs like this: (with debugging enabled): Nov 27 23:03:56 lovelace kernel: Q1[ 0] (nseg=1) (DS.V:0xfffffe011bd57300 DS.P:0x49b57300) I: 168cc117 L:00000000 F:0005 ... (in general, doesn't require debugging enabled): Nov 27 23:03:56 lovelace kernel: ath_hal_reg_write: reg=0x00000804, val=0x49b57300, pm=2 That register is a EDMA TX FIFO register (queue 1), and the val is the descriptor being written. Whilst here, make sure the software queue gets kicked here. Tested; * AR9485, STA mode + powersave --- sys/dev/ath/if_ath_tx_edma.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sys/dev/ath/if_ath_tx_edma.c b/sys/dev/ath/if_ath_tx_edma.c index c465bb98fdbe..d65a44c761f8 100644 --- a/sys/dev/ath/if_ath_tx_edma.c +++ b/sys/dev/ath/if_ath_tx_edma.c @@ -755,11 +755,30 @@ ath_edma_tx_proc(void *arg, int npending) { struct ath_softc *sc = (struct ath_softc *) arg; + ATH_PCU_LOCK(sc); + sc->sc_txproc_cnt++; + ATH_PCU_UNLOCK(sc); + + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + #if 0 DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: called, npending=%d\n", __func__, npending); #endif ath_edma_tx_processq(sc, 1); + + + ATH_PCU_LOCK(sc); + sc->sc_txproc_cnt--; + ATH_PCU_UNLOCK(sc); + + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); + + ath_tx_kick(sc); } /*