Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Nov 2016 08:13:20 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r309246 - head/sys/dev/ath
Message-ID:  <201611280813.uAS8DKJW058302@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Mon Nov 28 08:13:20 2016
New Revision: 309246
URL: https://svnweb.freebsd.org/changeset/base/309246

Log:
  [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

Modified:
  head/sys/dev/ath/if_ath_tx_edma.c

Modified: head/sys/dev/ath/if_ath_tx_edma.c
==============================================================================
--- head/sys/dev/ath/if_ath_tx_edma.c	Mon Nov 28 07:56:03 2016	(r309245)
+++ head/sys/dev/ath/if_ath_tx_edma.c	Mon Nov 28 08:13:20 2016	(r309246)
@@ -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);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611280813.uAS8DKJW058302>