From 3c2f86bcdb185a7c65e6658bb9938b2020239acc Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Mon, 16 Jun 2014 23:00:44 +0200
Subject: [PATCH] kernel/ath: Revert 881d974b800 and d98a0bcf56c.

---
 sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c |   4 -
 .../dev/ath/ath_hal/ar9300/ar9300_freebsd.c        |   6 -
 sys/contrib/dev/ath/ath_hal/ar9300/ar9300_power.c  |  18 +-
 sys/dev/netif/ath/ath/if_ath.c                     | 482 ++-------------------
 sys/dev/netif/ath/ath/if_ath_beacon.c              |  83 +---
 sys/dev/netif/ath/ath/if_ath_beacon.h              |   1 -
 sys/dev/netif/ath/ath/if_ath_debug.h               |   1 -
 sys/dev/netif/ath/ath/if_ath_keycache.c            |  12 +-
 sys/dev/netif/ath/ath/if_ath_led.c                 |   4 -
 sys/dev/netif/ath/ath/if_ath_misc.h                |  13 -
 sys/dev/netif/ath/ath/if_ath_rx.c                  | 109 +----
 sys/dev/netif/ath/ath/if_ath_rx_edma.c             |  26 +-
 sys/dev/netif/ath/ath/if_ath_sysctl.c              |   2 -
 sys/dev/netif/ath/ath/if_ath_tx.c                  | 414 ++++++------------
 sys/dev/netif/ath/ath/if_athvar.h                  |  23 +-
 sys/dev/netif/ath/ath_hal/ah.c                     |   2 -
 sys/dev/netif/ath/ath_hal/ah.h                     |   5 -
 sys/dev/netif/ath/ath_hal/ah_internal.h            |   3 +-
 sys/dev/netif/ath/ath_hal/ah_osdep.c               |  46 --
 sys/dev/netif/ath/ath_hal/ah_regdomain.c           |   5 -
 .../netif/ath/ath_hal/ah_regdomain/ah_rd_regenum.h |   1 -
 sys/dev/netif/ath/ath_hal/ar5210/ar5210.h          |   3 +-
 sys/dev/netif/ath/ath_hal/ar5210/ar5210_attach.c   |   2 +-
 sys/dev/netif/ath/ath_hal/ar5210/ar5210_misc.c     |   1 -
 sys/dev/netif/ath/ath_hal/ar5210/ar5210_power.c    |  12 +-
 sys/dev/netif/ath/ath_hal/ar5210/ar5210_reset.c    |   4 -
 sys/dev/netif/ath/ath_hal/ar5211/ar5211.h          |   1 +
 sys/dev/netif/ath/ath_hal/ar5211/ar5211_power.c    |  12 +-
 sys/dev/netif/ath/ath_hal/ar5212/ar5212.h          |   1 +
 sys/dev/netif/ath/ath_hal/ar5212/ar5212_power.c    |  10 +-
 sys/dev/netif/ath/ath_hal/ar5312/ar5312_power.c    |   5 +-
 sys/dev/netif/ath/ath_hal/ar5416/ar5416_attach.c   |   5 -
 sys/dev/netif/ath/ath_hal/ar5416/ar5416_beacon.c   |  26 --
 .../netif/ath/ath_hal/ar5416/ar5416_interrupts.c   |   3 -
 sys/dev/netif/ath/ath_hal/ar5416/ar5416_power.c    |  13 +-
 sys/dev/netif/ath/ath_hal/ar5416/ar5416reg.h       |   4 +-
 sys/netproto/802_11/ieee80211_power.h              |   3 -
 sys/netproto/802_11/ieee80211_proto.h              |   2 -
 sys/netproto/802_11/ieee80211_var.h                |   3 -
 sys/netproto/802_11/wlan/ieee80211.c               |   3 +-
 sys/netproto/802_11/wlan/ieee80211_ioctl.c         |  14 +-
 sys/netproto/802_11/wlan/ieee80211_output.c        |  29 +-
 sys/netproto/802_11/wlan/ieee80211_power.c         |  86 ----
 sys/netproto/802_11/wlan/ieee80211_proto.c         |   4 +-
 sys/netproto/802_11/wlan/ieee80211_sta.c           |  59 +--
 45 files changed, 238 insertions(+), 1327 deletions(-)

diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c
index 46833ef..335414e 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c
@@ -2934,10 +2934,6 @@ ar9300_fill_capability_info(struct ath_hal *ah)
         p_cap->halRxUsingLnaMixing = AH_TRUE;
     }
 
-    /*
-     * AR5416 and later NICs support MYBEACON filtering.
-     */
-    p_cap->halRxDoMyBeacon = AH_TRUE;
 
 #if ATH_WOW_OFFLOAD
     if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
index a2cc25d..251957e 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
@@ -60,11 +60,6 @@ ar9300_freebsd_set_tx_power_limit(struct ath_hal *ah, uint32_t limit)
 	return (ar9300_set_tx_power_limit(ah, limit, 0, 0));
 }
 
-static uint64_t
-ar9300_get_next_tbtt(struct ath_hal *ah)
-{
-	return (OS_REG_READ(ah, AR_NEXT_TBTT_TIMER));
-}
 
 void
 ar9300_attach_freebsd_ops(struct ath_hal *ah)
@@ -200,7 +195,6 @@ ar9300_attach_freebsd_ops(struct ath_hal *ah)
 	ah->ah_setStationBeaconTimers = ar9300_set_sta_beacon_timers;
 	/* ah_resetStationBeaconTimers */
 	/* ah_getNextTBTT */
-	ah->ah_getNextTBTT = ar9300_get_next_tbtt;
 
 	/* Interrupt functions */
 	ah->ah_isInterruptPending	= ar9300_is_interrupt_pending;
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_power.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_power.c
index 0fe4d63..44bebe4 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_power.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_power.c
@@ -666,17 +666,9 @@ ar9300_set_power_mode(struct ath_hal *ah, HAL_POWER_MODE mode, int set_chip)
     HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
         modes[ar9300_get_power_mode(ah)], modes[mode],
         set_chip ? "set chip " : "");
-
-#if 0
-    kprintf("%s: %s -> %s (%s)\n", __func__,
-        modes[ar9300_get_power_mode(ah)], modes[mode],
-        set_chip ? "set chip " : "");
-#endif
-
+    
     switch (mode) {
     case HAL_PM_AWAKE:
-        if (set_chip)
-            ah->ah_powerMode = mode;
         status = ar9300_set_power_mode_awake(ah, set_chip);
 #if ATH_SUPPORT_MCI
         if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
@@ -706,10 +698,7 @@ ar9300_set_power_mode(struct ath_hal *ah, HAL_POWER_MODE mode, int set_chip)
         }
 #endif
         ar9300_set_power_mode_sleep(ah, set_chip);
-        if (set_chip) {
-            ahp->ah_chip_full_sleep = AH_TRUE;
-            ah->ah_powerMode = mode;
-        }
+        ahp->ah_chip_full_sleep = AH_TRUE;
         break;
     case HAL_PM_NETWORK_SLEEP:
 #if ATH_SUPPORT_MCI
@@ -718,9 +707,6 @@ ar9300_set_power_mode(struct ath_hal *ah, HAL_POWER_MODE mode, int set_chip)
         }
 #endif
         ar9300_set_power_mode_network_sleep(ah, set_chip);
-        if (set_chip) {
-            ah->ah_powerMode = mode;
-        }
         break;
     default:
         HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
diff --git a/sys/dev/netif/ath/ath/if_ath.c b/sys/dev/netif/ath/ath/if_ath.c
index 279f7ce..2e0d0e5 100644
--- a/sys/dev/netif/ath/ath/if_ath.c
+++ b/sys/dev/netif/ath/ath/if_ath.c
@@ -288,164 +288,6 @@ ath_legacy_attach_comp_func(struct ath_softc *sc)
 	}
 }
 
-/*
- * Set the target power mode.
- *
- * If this is called during a point in time where
- * the hardware is being programmed elsewhere, it will
- * simply store it away and update it when all current
- * uses of the hardware are completed.
- */
-void
-_ath_power_setpower(struct ath_softc *sc, int power_state, const char *file, int line)
-{
-	ATH_LOCK_ASSERT(sc);
-
-	sc->sc_target_powerstate = power_state;
-
-	DPRINTF(sc, ATH_DEBUG_PWRSAVE, "%s: (%s:%d) state=%d, refcnt=%d\n",
-	    __func__,
-	    file,
-	    line,
-	    power_state,
-	    sc->sc_powersave_refcnt);
-
-	if (sc->sc_powersave_refcnt == 0 &&
-	    power_state != sc->sc_cur_powerstate) {
-		sc->sc_cur_powerstate = power_state;
-		ath_hal_setpower(sc->sc_ah, power_state);
-
-		/*
-		 * If the NIC is force-awake, then set the
-		 * self-gen frame state appropriately.
-		 *
-		 * If the nic is in network sleep or full-sleep,
-		 * we let the above call leave the self-gen
-		 * state as "sleep".
-		 */
-		if (sc->sc_cur_powerstate == HAL_PM_AWAKE &&
-		    sc->sc_target_selfgen_state != HAL_PM_AWAKE) {
-			ath_hal_setselfgenpower(sc->sc_ah,
-			    sc->sc_target_selfgen_state);
-		}
-	}
-}
-
-/*
- * Set the current self-generated frames state.
- *
- * This is separate from the target power mode.  The chip may be
- * awake but the desired state is "sleep", so frames sent to the
- * destination has PWRMGT=1 in the 802.11 header.  The NIC also
- * needs to know to set PWRMGT=1 in self-generated frames.
- */
-void
-_ath_power_set_selfgen(struct ath_softc *sc, int power_state, const char *file, int line)
-{
-
-	ATH_LOCK_ASSERT(sc);
-
-	DPRINTF(sc, ATH_DEBUG_PWRSAVE, "%s: (%s:%d) state=%d, refcnt=%d\n",
-	    __func__,
-	    file,
-	    line,
-	    power_state,
-	    sc->sc_target_selfgen_state);
-
-	sc->sc_target_selfgen_state = power_state;
-
-	/*
-	 * If the NIC is force-awake, then set the power state.
-	 * Network-state and full-sleep will already transition it to
-	 * mark self-gen frames as sleeping - and we can't
-	 * guarantee the NIC is awake to program the self-gen frame
-	 * setting anyway.
-	 */
-	if (sc->sc_cur_powerstate == HAL_PM_AWAKE) {
-		ath_hal_setselfgenpower(sc->sc_ah, power_state);
-	}
-}
-
-/*
- * Set the hardware power mode and take a reference.
- *
- * This doesn't update the target power mode in the driver;
- * it just updates the hardware power state.
- *
- * XXX it should only ever force the hardware awake; it should
- * never be called to set it asleep.
- */
-void
-_ath_power_set_power_state(struct ath_softc *sc, int power_state, const char *file, int line)
-{
-	ATH_LOCK_ASSERT(sc);
-
-	DPRINTF(sc, ATH_DEBUG_PWRSAVE, "%s: (%s:%d) state=%d, refcnt=%d\n",
-	    __func__,
-	    file,
-	    line,
-	    power_state,
-	    sc->sc_powersave_refcnt);
-
-	sc->sc_powersave_refcnt++;
-
-	if (power_state != sc->sc_cur_powerstate) {
-		ath_hal_setpower(sc->sc_ah, power_state);
-		sc->sc_cur_powerstate = power_state;
-
-		/*
-		 * Adjust the self-gen powerstate if appropriate.
-		 */
-		if (sc->sc_cur_powerstate == HAL_PM_AWAKE &&
-		    sc->sc_target_selfgen_state != HAL_PM_AWAKE) {
-			ath_hal_setselfgenpower(sc->sc_ah,
-			    sc->sc_target_selfgen_state);
-		}
-
-	}
-}
-
-/*
- * Restore the power save mode to what it once was.
- *
- * This will decrement the reference counter and once it hits
- * zero, it'll restore the powersave state.
- */
-void
-_ath_power_restore_power_state(struct ath_softc *sc, const char *file, int line)
-{
-
-	ATH_LOCK_ASSERT(sc);
-
-	DPRINTF(sc, ATH_DEBUG_PWRSAVE, "%s: (%s:%d) refcnt=%d, target state=%d\n",
-	    __func__,
-	    file,
-	    line,
-	    sc->sc_powersave_refcnt,
-	    sc->sc_target_powerstate);
-
-	if (sc->sc_powersave_refcnt == 0)
-		device_printf(sc->sc_dev, "%s: refcnt=0?\n", __func__);
-	else
-		sc->sc_powersave_refcnt--;
-
-	if (sc->sc_powersave_refcnt == 0 &&
-	    sc->sc_target_powerstate != sc->sc_cur_powerstate) {
-		sc->sc_cur_powerstate = sc->sc_target_powerstate;
-		ath_hal_setpower(sc->sc_ah, sc->sc_target_powerstate);
-	}
-
-	/*
-	 * Adjust the self-gen powerstate if appropriate.
-	 */
-	if (sc->sc_cur_powerstate == HAL_PM_AWAKE &&
-	    sc->sc_target_selfgen_state != HAL_PM_AWAKE) {
-		ath_hal_setselfgenpower(sc->sc_ah,
-		    sc->sc_target_selfgen_state);
-	}
-
-}
-
 #define	HAL_MODE_HT20 (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20)
 #define	HAL_MODE_HT40 \
 	(HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \
@@ -517,10 +359,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
 		ath_xmit_setup_legacy(sc);
 	}
 
-	if (ath_hal_hasmybeacon(sc->sc_ah)) {
-		sc->sc_do_mybeacon = 1;
-	}
-
 	/*
 	 * Check if the MAC has multi-rate retry support.
 	 * We do this by trying to setup a fake extended
@@ -793,8 +631,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
 #ifdef	ATH_ENABLE_DFS
 		| IEEE80211_C_DFS		/* Enable radar detection */
 #endif
-		| IEEE80211_C_PMGT		/* Station side power mgmt */
-		| IEEE80211_C_SWSLEEP
 		;
 	/*
 	 * Query the hal to figure out h/w crypto support.
@@ -1183,12 +1019,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
 	if (bootverbose)
 		ieee80211_announce(ic);
 	ath_announce(sc);
-
-	/*
-	 * Put it to sleep for now.
-	 */
-	ath_power_setpower(sc, HAL_PM_FULL_SLEEP);
-
 	return 0;
 bad2:
 	ath_tx_cleanup(sc);
@@ -1237,18 +1067,6 @@ ath_detach(struct ath_softc *sc)
 	 *   it last
 	 * Other than that, it's straightforward...
 	 */
-
-	/*
-	 * XXX Wake the hardware up first.  ath_stop() will still
-	 * wake it up first, but I'd rather do it here just to
-	 * ensure it's awake.
-	 */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-	ath_power_setpower(sc, HAL_PM_AWAKE);
-
-	/*
-	 * Stop things cleanly.
-	 */
 	ath_stop(ifp);
 	wlan_serialize_enter();
 	ieee80211_ifdetach(ifp->if_l2com);
@@ -1623,8 +1441,6 @@ ath_vap_delete(struct ieee80211vap *vap)
 	struct ath_hal *ah = sc->sc_ah;
 	struct ath_vap *avp = ATH_VAP(vap);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__);
 	if (ifp->if_flags & IFF_RUNNING) {
 		/*
@@ -1638,8 +1454,6 @@ ath_vap_delete(struct ieee80211vap *vap)
 		ath_stoprecv(sc, 1);		/* stop recv side */
 	}
 
-	/* .. leave the hardware awake for now. */
-
 	ieee80211_vap_detach(vap);
 
 	/*
@@ -1727,9 +1541,6 @@ ath_vap_delete(struct ieee80211vap *vap)
 		}
 		ath_hal_intrset(ah, sc->sc_imask);
 	}
-
-	/* Ok, let the hardware asleep. */
-	ath_power_restore_power_state(sc);
 	ATH_UNLOCK(sc);
 }
 
@@ -1775,10 +1586,8 @@ ath_reset_keycache(struct ath_softc *sc)
 	struct ath_hal *ah = sc->sc_ah;
 	int i;
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 	for (i = 0; i < sc->sc_keymax; i++)
 		ath_hal_keyreset(ah, i);
-	ath_power_restore_power_state(sc);
 	ieee80211_crypto_reload_keys(ic);
 }
 
@@ -1830,12 +1639,6 @@ ath_resume(struct ath_softc *sc)
 	    sc->sc_curchan != NULL ? sc->sc_curchan : ic->ic_curchan);
 	ath_hal_setchainmasks(sc->sc_ah, sc->sc_cur_txchainmask,
 	    sc->sc_cur_rxchainmask);
-
-	/* Ensure we set the current power state to on */
-	ath_power_setselfgen(sc, HAL_PM_AWAKE);
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-	ath_power_setpower(sc, HAL_PM_AWAKE);
-
 	ath_hal_reset(ah, sc->sc_opmode,
 	    sc->sc_curchan != NULL ? sc->sc_curchan : ic->ic_curchan,
 	    AH_FALSE, &status);
@@ -1868,8 +1671,6 @@ ath_resume(struct ath_softc *sc)
 	if (sc->sc_resume_up)
 		ieee80211_resume_all(ic);
 
-	ath_power_restore_power_state(sc);
-
 	/* XXX beacons ? */
 }
 
@@ -1927,8 +1728,6 @@ ath_intr(void *arg)
 		return;
 	}
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	if ((ifp->if_flags & IFF_UP) == 0 ||
 	    (ifp->if_flags & IFF_RUNNING) == 0) {
 		HAL_INT status;
@@ -1938,7 +1737,6 @@ ath_intr(void *arg)
 		ath_hal_getisr(ah, &status);	/* clear ISR */
 		ath_hal_intrset(ah, 0);		/* disable further intr's */
 		ATH_PCU_UNLOCK(sc);
-		ath_power_restore_power_state(sc);
 		return;
 	}
 
@@ -1978,7 +1776,6 @@ ath_intr(void *arg)
 	/* Short-circuit un-handled interrupts */
 	if (status == 0x0) {
 		ATH_PCU_UNLOCK(sc);
-		ath_power_restore_power_state(sc);
 		return;
 	}
 
@@ -2145,16 +1942,10 @@ ath_intr(void *arg)
 			ATH_KTR(sc, ATH_KTR_ERROR, 0, "ath_intr: RXORN");
 			sc->sc_stats.ast_rxorn++;
 		}
-		if (status & HAL_INT_TSFOOR) {
-			device_printf(sc->sc_dev, "%s: TSFOOR\n", __func__);
-			sc->sc_syncbeacon = 1;
-		}
 	}
 	ATH_PCU_LOCK(sc);
 	sc->sc_intr_cnt--;
 	ATH_PCU_UNLOCK(sc);
-
-	ath_power_restore_power_state(sc);
 }
 
 static void
@@ -2187,8 +1978,6 @@ ath_fatal_proc(void *arg, int pending)
 static void
 ath_bmiss_vap(struct ieee80211vap *vap)
 {
-	struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
-
 	/*
 	 * Workaround phantom bmiss interrupts by sanity-checking
 	 * the time of our last rx'd frame.  If it is within the
@@ -2197,15 +1986,9 @@ ath_bmiss_vap(struct ieee80211vap *vap)
 	 * be dispatched up for processing.  Note this applies only
 	 * for h/w beacon miss events.
 	 */
-
-	/*
-	 * XXX TODO: Just read the TSF during the interrupt path;
-	 * that way we don't have to wake up again just to read it
-	 * again.
-	 */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	if ((vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) == 0) {
+		struct ifnet *ifp = vap->iv_ic->ic_ifp;
+		struct ath_softc *sc = ifp->if_softc;
 		u_int64_t lastrx = sc->sc_lastrx;
 		u_int64_t tsf = ath_hal_gettsf64(sc->sc_ah);
 		/* XXX should take a locked ref to iv_bss */
@@ -2220,26 +2003,12 @@ ath_bmiss_vap(struct ieee80211vap *vap)
 
 		if (tsf - lastrx <= bmisstimeout) {
 			sc->sc_stats.ast_bmiss_phantom++;
-			ath_power_restore_power_state(sc);
 			return;
 		}
 	}
-
-	/*
-	 * There's no need to keep the hardware awake during the call
-	 * to av_bmiss().
-	 */
-	ath_power_restore_power_state(sc);
-
-	/*
-	 * Attempt to force a beacon resync.
-	 */
-	sc->sc_syncbeacon = 1;
-
 	ATH_VAP(vap)->av_bmiss(vap);
 }
 
-/* XXX this needs a force wakeup! */
 int
 ath_hal_gethangstate(struct ath_hal *ah, uint32_t mask, uint32_t *hangs)
 {
@@ -2269,8 +2038,6 @@ ath_bmiss_proc(void *arg, int pending)
 	 * to clear.
 	 */
 	wlan_serialize_enter();
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-	ath_beacon_miss(sc);
 	if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0) {
 		ath_reset(ifp, ATH_RESET_NOLOSS);
 		if_printf(ifp, "bb hang detected (0x%x), resetting\n", hangs);
@@ -2278,11 +2045,6 @@ ath_bmiss_proc(void *arg, int pending)
 		ath_reset(ifp, ATH_RESET_NOLOSS);
 		ieee80211_beacon_miss(ifp->if_l2com);
 	}
-
-	/* Force a beacon resync, in case they've drifted */
-	sc->sc_syncbeacon = 1;
-	ath_power_restore_power_state(sc);
-
 	wlan_serialize_exit();
 }
 
@@ -2394,7 +2156,6 @@ ath_init(void *arg)
 	 */
 	if (ath_startrecv(sc) != 0) {
 		if_printf(ifp, "unable to start recv logic\n");
-		ath_power_restore_power_state(sc);
 		ATH_UNLOCK(sc);
 		return;
 	}
@@ -2421,15 +2182,6 @@ ath_init(void *arg)
 	if (sc->sc_needmib && ic->ic_opmode == IEEE80211_M_STA)
 		sc->sc_imask |= HAL_INT_MIB;
 
-	/*
-	 * XXX add capability for this.
-	 *
-	 * If we're in STA mode (and maybe IBSS?) then register for
-	 * TSFOOR interrupts.
-	 */
-	if (ic->ic_opmode == IEEE80211_M_STA)
-		sc->sc_imask |= HAL_INT_TSFOOR;
-
 	/* Enable global TX timeout and carrier sense timeout if available */
 	if (ath_hal_gtxto_supported(ah))
 		sc->sc_imask |= HAL_INT_GTT;
@@ -2441,7 +2193,6 @@ ath_init(void *arg)
 	callout_reset(&sc->sc_wd_ch, hz, ath_watchdog, sc);
 	ath_hal_intrset(ah, sc->sc_imask);
 
-	ath_power_restore_power_state(sc);
 	ATH_UNLOCK(sc);
 
 #ifdef ATH_TX99_DIAG
@@ -2462,12 +2213,6 @@ ath_stop_locked(struct ifnet *ifp)
 		__func__, sc->sc_invalid, ifp->if_flags);
 
 	ATH_LOCK_ASSERT(sc);
-
-	/*
-	 * Wake the hardware up before fiddling with it.
-	 */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	if (ifp->if_flags & IFF_RUNNING) {
 		/*
 		 * Shutdown the hardware and driver:
@@ -2508,20 +2253,9 @@ ath_stop_locked(struct ifnet *ifp)
 			sc->sc_rxlink = NULL;
 		ath_beacon_free(sc);	/* XXX not needed */
 	}
-
-	/* And now, restore the current power state */
-	ath_power_restore_power_state(sc);
 }
 
-/*
- * Wait until all pending TX/RX has completed.
- *
- * This waits until all existing transmit, receive and interrupts
- * have completed.  It's assumed that the caller has first
- * grabbed the reset lock so it doesn't try to do overlapping
- * chip resets.
- */
-#define	MAX_TXRX_ITERATIONS	100
+#define	MAX_TXRX_ITERATIONS	1000
 static void
 ath_txrx_stop_locked(struct ath_softc *sc)
 {
@@ -2540,7 +2274,7 @@ ath_txrx_stop_locked(struct ath_softc *sc)
 	    sc->sc_txstart_cnt || sc->sc_intr_cnt) {
 		if (i <= 0)
 			break;
-		wlan_serialize_sleep(sc, 0, "ath_txrx_stop", (hz + 99) / 100);
+		wlan_serialize_sleep(sc, 0, "ath_txrx_stop", 1);
 		i--;
 	}
 
@@ -2587,7 +2321,7 @@ ath_txrx_start(struct ath_softc *sc)
  * Another, cleaner way should be found to serialise all of
  * these operations.
  */
-#define	MAX_RESET_ITERATIONS	25
+#define	MAX_RESET_ITERATIONS	10
 static int
 ath_reset_grablock(struct ath_softc *sc, int dowait)
 {
@@ -2605,8 +2339,7 @@ ath_reset_grablock(struct ath_softc *sc, int dowait)
 			break;
 		}
 		ATH_PCU_UNLOCK(sc);
-		wlan_serialize_sleep(sc, 0, "ath_reset_grablock",
-				     (hz + 9) / 10);
+		wlan_serialize_sleep(sc, 0, "ath_reset_grablock", 1);
 		i--;
 		ATH_PCU_LOCK(sc);
 	} while (i > 0);
@@ -2671,11 +2404,6 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type)
 	/* Try to (stop any further TX/RX from occuring */
 	taskqueue_block(sc->sc_tq);
 
-	/*
-	 * Wake the hardware up.
-	 */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	ATH_PCU_LOCK(sc);
 
 	/*
@@ -2770,13 +2498,9 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type)
 	 * reset counter - this way ath_intr() doesn't end up
 	 * disabling interrupts without a corresponding enable
 	 * in the rest or channel change path.
-	 *
-	 * Grab the TX reference in case we need to transmit.
-	 * That way a parallel transmit doesn't.
 	 */
 	ATH_PCU_LOCK(sc);
 	sc->sc_inreset_cnt--;
-	sc->sc_txstart_cnt++;
 	/* XXX only do this if sc_inreset_cnt == 0? */
 	ath_hal_intrset(ah, sc->sc_imask);
 	ATH_PCU_UNLOCK(sc);
@@ -2790,8 +2514,6 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type)
 	 * run.
 	 */
 
-	/* XXX TODO: we need to hold the tx refcount here! */
-
 	/* Restart TX/RX as needed */
 	ath_txrx_start(sc);
 
@@ -2822,12 +2544,6 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type)
 	IF_UNLOCK(&ifp->if_snd);
 #endif
 
-	ath_power_restore_power_state(sc);
-
-	ATH_PCU_LOCK(sc);
-	sc->sc_txstart_cnt--;
-	ATH_PCU_UNLOCK(sc);
-
 	/* Handle any frames in the TX queue */
 	/*
 	 * XXX should this be done by the caller, rather than
@@ -2968,7 +2684,6 @@ ath_buf_clone(struct ath_softc *sc, struct ath_buf *bf)
 	tbf->bf_status = bf->bf_status;
 	tbf->bf_m = bf->bf_m;
 	tbf->bf_node = bf->bf_node;
-	KASSERT((bf->bf_node != NULL), ("%s: bf_node=NULL!", __func__));
 	/* will be setup by the chain/setup function */
 	tbf->bf_lastds = NULL;
 	/* for now, last == self */
@@ -3084,9 +2799,6 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m)
 	sc->sc_txstart_cnt++;
 	ATH_PCU_UNLOCK(sc);
 
-	/* Wake the hardware up already */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	ATH_KTR(sc, ATH_KTR_TX, 0, "ath_transmit: start");
 	/*
 	 * Grab the TX lock - it's ok to do this here; we haven't
@@ -3323,9 +3035,6 @@ finish:
 	sc->sc_txstart_cnt--;
 	ATH_PCU_UNLOCK(sc);
 
-	/* Sleep the hardware if required */
-	ath_power_restore_power_state(sc);
-
 	ATH_KTR(sc, ATH_KTR_TX, 0, "ath_transmit: finished");
 	
 	return (retval);
@@ -3353,6 +3062,7 @@ ath_key_update_begin(struct ieee80211vap *vap)
 
 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__);
 	taskqueue_block(sc->sc_tq);
+	IF_LOCK(&ifp->if_snd);		/* NB: doesn't block mgmt frames */
 }
 
 static void
@@ -3362,6 +3072,7 @@ ath_key_update_end(struct ieee80211vap *vap)
 	struct ath_softc *sc = ifp->if_softc;
 
 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__);
+	IF_UNLOCK(&ifp->if_snd);
 	taskqueue_unblock(sc->sc_tq);
 }
 
@@ -3372,10 +3083,8 @@ ath_update_promisc(struct ifnet *ifp)
 	u_int32_t rfilt;
 
 	/* configure rx filter */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 	rfilt = ath_calcrxfilter(sc);
 	ath_hal_setrxfilter(sc->sc_ah, rfilt);
-	ath_power_restore_power_state(sc);
 
 	DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x\n", __func__, rfilt);
 }
@@ -3415,9 +3124,7 @@ ath_update_mcast(struct ifnet *ifp)
 #endif
 	} else
 		mfilt[0] = mfilt[1] = ~0;
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 	ath_hal_setmcastfilter(sc->sc_ah, mfilt[0], mfilt[1]);
-	ath_power_restore_power_state(sc);
 	DPRINTF(sc, ATH_DEBUG_MODE, "%s: MC filter %08x:%08x\n",
 		__func__, mfilt[0], mfilt[1]);
 }
@@ -3481,10 +3188,7 @@ ath_setslottime(struct ath_softc *sc)
 	    __func__, ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags,
 	    ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", usec);
 
-	/* Wake up the hardware first before updating the slot time */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 	ath_hal_setslottime(ah, usec);
-	ath_power_restore_power_state(sc);
 	sc->sc_updateslot = OK;
 }
 
@@ -3502,8 +3206,6 @@ ath_updateslot(struct ifnet *ifp)
 	 * When not coordinating the BSS, change the hardware
 	 * immediately.  For other operation we defer the change
 	 * until beacon updates have propagated to the stations.
-	 *
-	 * XXX sc_updateslot isn't changed behind a lock?
 	 */
 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
 	    ic->ic_opmode == IEEE80211_M_MBSS)
@@ -4635,8 +4337,6 @@ ath_tx_proc_q0(void *arg, int npending)
 	sc->sc_txq_active &= ~txqs;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	ATH_KTR(sc, ATH_KTR_TXCOMP, 1,
 	    "ath_tx_proc_q0: txqs=0x%08x", txqs);
 
@@ -4660,8 +4360,6 @@ ath_tx_proc_q0(void *arg, int npending)
 	sc->sc_txproc_cnt--;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_restore_power_state(sc);
-
 	ath_tx_kick(sc);
 	wlan_serialize_exit();
 }
@@ -4687,8 +4385,6 @@ ath_tx_proc_q0123(void *arg, int npending)
 	sc->sc_txq_active &= ~txqs;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	ATH_KTR(sc, ATH_KTR_TXCOMP, 1,
 	    "ath_tx_proc_q0123: txqs=0x%08x", txqs);
 
@@ -4724,8 +4420,6 @@ ath_tx_proc_q0123(void *arg, int npending)
 	sc->sc_txproc_cnt--;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_restore_power_state(sc);
-
 	ath_tx_kick(sc);
 	wlan_serialize_exit();
 }
@@ -4750,8 +4444,6 @@ ath_tx_proc(void *arg, int npending)
 	sc->sc_txq_active &= ~txqs;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	ATH_KTR(sc, ATH_KTR_TXCOMP, 1, "ath_tx_proc: txqs=0x%08x", txqs);
 
 	/*
@@ -4780,8 +4472,6 @@ ath_tx_proc(void *arg, int npending)
 	sc->sc_txproc_cnt--;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_restore_power_state(sc);
-
 	ath_tx_kick(sc);
 	wlan_serialize_exit();
 }
@@ -4812,8 +4502,6 @@ ath_txq_sched_tasklet(void *arg, int npending)
 	sc->sc_txproc_cnt++;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	ATH_TX_LOCK(sc);
 	for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
 		if (ATH_TXQ_SETUP(sc, i)) {
@@ -4822,8 +4510,6 @@ ath_txq_sched_tasklet(void *arg, int npending)
 	}
 	ATH_TX_UNLOCK(sc);
 
-	ath_power_restore_power_state(sc);
-
 	ATH_PCU_LOCK(sc);
 	sc->sc_txproc_cnt--;
 	ATH_PCU_UNLOCK(sc);
@@ -5480,15 +5166,6 @@ ath_calibrate(void *arg)
 	HAL_BOOL aniCal, shortCal = AH_FALSE;
 	int nextcal;
 
-	/*
-	 * Force the hardware awake for ANI work.
-	 */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
-	/* Skip trying to do this if we're in reset */
-	if (sc->sc_inreset_cnt)
-		goto restart;
-
 	wlan_serialize_enter();
 	if (ic->ic_flags & IEEE80211_F_SCAN)	/* defer, off channel */
 		goto restart;
@@ -5591,10 +5268,6 @@ restart:
 		/* NB: don't rearm timer */
 	}
 done:
-	/*
-	 * Restore power state now that we're done.
-	 */
-	ath_power_restore_power_state(sc);
 	wlan_serialize_exit();
 }
 
@@ -5689,10 +5362,8 @@ ath_set_channel(struct ieee80211com *ic)
 	 * sta/ibss mode this has no effect in other operating modes.
 	 */
 	ATH_LOCK(sc);
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 	if (!sc->sc_scanning && ic->ic_curchan == ic->ic_bsschan)
 		sc->sc_syncbeacon = 1;
-	ath_power_restore_power_state(sc);
 	ATH_UNLOCK(sc);
 }
 
@@ -5725,7 +5396,6 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 	int i, error, stamode;
 	u_int32_t rfilt;
 	int csa_run_transition = 0;
-	enum ieee80211_state ostate = vap->iv_state;
 
 	static const HAL_LED_STATE leds[] = {
 	    HAL_LED_INIT,	/* IEEE80211_S_INIT */
@@ -5739,7 +5409,7 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 	};
 
 	DPRINTF(sc, ATH_DEBUG_STATE, "%s: %s -> %s\n", __func__,
-		ieee80211_state_name[ostate],
+		ieee80211_state_name[vap->iv_state],
 		ieee80211_state_name[nstate]);
 
 	/*
@@ -5751,24 +5421,7 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 	 */
 	IEEE80211_LOCK_ASSERT(ic);
 
-	/* Before we touch the hardware - wake it up */
-	/*
-	 * If the NIC is in anything other than SLEEP state,
-	 * we need to ensure that self-generated frames are
-	 * set for PWRMGT=0.  Otherwise we may end up with
-	 * strange situations.
-	 *
-	 * XXX TODO: is this actually the case? :-)
-	 */
-	if (nstate != IEEE80211_S_SLEEP)
-		ath_power_setselfgen(sc, HAL_PM_AWAKE);
-
-	/*
-	 * Now, wake the thing up.
-	 */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
-	if (ostate == IEEE80211_S_CSA && nstate == IEEE80211_S_RUN)
+	if (vap->iv_state == IEEE80211_S_CSA && nstate == IEEE80211_S_RUN)
 		csa_run_transition = 1;
 
 	wlan_serialize_exit();
@@ -5783,11 +5436,6 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 		 * [re]setup beacons.  Unblock the task q thread so
 		 * deferred interrupt processing is done.
 		 */
-
-		/* Ensure we stay awake during scan */
-		ath_power_setselfgen(sc, HAL_PM_AWAKE);
-		ath_power_setpower(sc, HAL_PM_AWAKE);
-
 		ath_hal_intrset(ah,
 		    sc->sc_imask &~ (HAL_INT_SWBA | HAL_INT_BMISS));
 		sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
@@ -5800,11 +5448,6 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 	stamode = (vap->iv_opmode == IEEE80211_M_STA ||
 		   vap->iv_opmode == IEEE80211_M_AHDEMO ||
 		   vap->iv_opmode == IEEE80211_M_IBSS);
-
-	/*
-	 * XXX Dont need to do this (and others) if we've transitioned
-	 * from SLEEP->RUN.
-	 */
 	if (stamode && nstate == IEEE80211_S_RUN) {
 		sc->sc_curaid = ni->ni_associd;
 		IEEE80211_ADDR_COPY(sc->sc_curbssid, ni->ni_bssid);
@@ -5909,30 +5552,25 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 			 * beacon to update the beacon timer and thus we
 			 * won't get notified of the missing beacons.
 			 */
-			if (ostate != IEEE80211_S_RUN &&
-			    ostate != IEEE80211_S_SLEEP) {
-				DPRINTF(sc, ATH_DEBUG_BEACON,
-					"%s: STA; syncbeacon=1\n", __func__);
-				sc->sc_syncbeacon = 1;
-
-				if (csa_run_transition)
-					ath_beacon_config(sc, vap);
+			sc->sc_syncbeacon = 1;
+#if 0
+			if (csa_run_transition)
+#endif
+				ath_beacon_config(sc, vap);
 
-				/*
-				 * PR: kern/175227
-				 *
-				 * Reconfigure beacons during reset; as
-				 * otherwise
-				 * we won't get the beacon timers reprogrammed
-				 * after a reset and thus we won't pick up a
-				 * beacon miss interrupt.
-				 *
-				 * Hopefully we'll see a beacon before the BMISS
-				 * timer fires (too often), leading to a STA
-				 * disassociation.
-				 */
-				sc->sc_beacons = 1;
-			}
+			/*
+			 * PR: kern/175227
+			 *
+			 * Reconfigure beacons during reset; as otherwise
+			 * we won't get the beacon timers reprogrammed
+			 * after a reset and thus we won't pick up a
+			 * beacon miss interrupt.
+			 *
+			 * Hopefully we'll see a beacon before the BMISS
+			 * timer fires (too often), leading to a STA
+			 * disassociation.
+			 */
+			sc->sc_beacons = 1;
 			break;
 		case IEEE80211_M_MONITOR:
 			/*
@@ -5958,13 +5596,6 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 		sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
 		sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
 		sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
-
-		/*
-		 * Force awake for RUN mode
-		 */
-		ath_power_setselfgen(sc, HAL_PM_AWAKE);
-		ath_power_setpower(sc, HAL_PM_AWAKE);
-
 		/*
 		 * Finally, start any timers and the task q thread
 		 * (in case we didn't go through SCAN state).
@@ -5976,7 +5607,6 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 			DPRINTF(sc, ATH_DEBUG_CALIBRATE,
 			    "%s: calibration disabled\n", __func__);
 		}
-
 		taskqueue_unblock(sc->sc_tq);
 	} else if (nstate == IEEE80211_S_INIT) {
 		/*
@@ -5996,42 +5626,9 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 #ifdef IEEE80211_SUPPORT_TDMA
 		ath_hal_setcca(ah, AH_TRUE);
 #endif
-	} else if (nstate == IEEE80211_S_SLEEP) {
-		/* We're going to sleep, so transition appropriately */
-		/* For now, only do this if we're a single STA vap */
-		if (sc->sc_nvaps == 1 &&
-		    vap->iv_opmode == IEEE80211_M_STA) {
-			DPRINTF(sc, ATH_DEBUG_BEACON,
-				"%s: syncbeacon=%d\n",
-				__func__, sc->sc_syncbeacon);
-			/*
-			 * Always at least set the self-generated
-			 * frame config to set PWRMGT=1.
-			 */
-			ath_power_setselfgen(sc, HAL_PM_NETWORK_SLEEP);
-
-			/*
-			 * If we're not syncing beacons, transition
-			 * to NETWORK_SLEEP.
-			 *
-			 * We stay awake if syncbeacon > 0 in case
-			 * we need to listen for some beacons otherwise
-			 * our beacon timer config may be wrong.
-			 */
-			if (sc->sc_syncbeacon == 0) {
-				ath_power_setpower(sc, HAL_PM_NETWORK_SLEEP);
-			}
-		}
 	}
 bad:
 	ieee80211_free_node(ni);
-
-	/*
-	 * Restore the power state - either to what it was, or
-	 * to network_sleep if it's alright.
-	 */
-	ath_power_restore_power_state(sc);
-
 	return error;
 }
 
@@ -6086,16 +5683,7 @@ ath_newassoc(struct ieee80211_node *ni, int isnew)
 	an->an_mcastrix = ath_tx_findrix(sc, tp->mcastrate);
 	an->an_mgmtrix = ath_tx_findrix(sc, tp->mgmtrate);
 
-	DPRINTF(sc, ATH_DEBUG_NODE,
-		"%s: %s: reassoc; isnew=%d, is_powersave=%d\n",
-		__func__,
-		ath_hal_ether_sprintf(ni->ni_macaddr),
-		isnew,
-		an->an_is_powersave);
-
-	ATH_NODE_LOCK(an);
 	ath_rate_newassoc(sc, an, isnew);
-	ATH_NODE_UNLOCK(an);
 
 	if (isnew &&
 	    (vap->iv_flags & IEEE80211_F_PRIVACY) == 0 && sc->sc_hasclrkey &&
@@ -6339,8 +5927,6 @@ ath_watchdog(void *arg)
 		struct ifnet *ifp = sc->sc_ifp;
 		uint32_t hangs;
 
-		ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 		if (ath_hal_gethangstate(sc->sc_ah, 0xffff, &hangs) &&
 		    hangs != 0) {
 			if_printf(ifp, "%s hang detected (0x%x)\n",
@@ -6350,7 +5936,6 @@ ath_watchdog(void *arg)
 		do_reset = 1;
 		ifp->if_oerrors++;
 		sc->sc_stats.ast_watchdog++;
-		ath_power_restore_power_state(sc);
 	}
 
 	/*
@@ -6475,10 +6060,6 @@ ath_ioctl_diag(struct ath_softc *sc, struct ath_diag *ad)
 			goto bad;
 		}
 	}
-
-	if (id != HAL_DIAG_REGS)
-		ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	if (ath_hal_getdiagstate(ah, id, indata, insize, &outdata, &outsize)) {
 		if (outsize < ad->ad_out_size)
 			ad->ad_out_size = outsize;
@@ -6488,8 +6069,6 @@ ath_ioctl_diag(struct ath_softc *sc, struct ath_diag *ad)
 	} else {
 		error = EINVAL;
 	}
-	if (id != HAL_DIAG_REGS)
-		ath_power_restore_power_state(sc);
 bad:
 	if ((ad->ad_id & ATH_DIAG_IN) && indata != NULL)
 		kfree(indata, M_TEMP);
@@ -6535,8 +6114,11 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data,
 				ath_init(sc);	/* XXX lose error */
 		} else {
 			ath_stop_locked(ifp);
+#ifdef notyet
+			/* XXX must wakeup in places like ath_vap_delete */
 			if (!sc->sc_invalid)
-				ath_power_setpower(sc, HAL_PM_FULL_SLEEP);
+				ath_hal_setpower(sc->sc_ah, HAL_PM_FULL_SLEEP);
+#endif
 		}
 		ATH_UNLOCK(sc);
 		break;
diff --git a/sys/dev/netif/ath/ath/if_ath_beacon.c b/sys/dev/netif/ath/ath/if_ath_beacon.c
index bd54409..14b6e49 100644
--- a/sys/dev/netif/ath/ath/if_ath_beacon.c
+++ b/sys/dev/netif/ath/ath/if_ath_beacon.c
@@ -378,7 +378,7 @@ ath_beacon_update(struct ieee80211vap *vap, int item)
 /*
  * Handle a beacon miss.
  */
-void
+static void
 ath_beacon_miss(struct ath_softc *sc)
 {
 	HAL_SURVEY_SAMPLE hs;
@@ -914,7 +914,7 @@ ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
 	struct ieee80211_node *ni;
 	u_int32_t nexttbtt, intval, tsftu;
 	u_int32_t nexttbtt_u8, intval_u8;
-	u_int64_t tsf, tsf_beacon;
+	u_int64_t tsf;
 
 	if (vap == NULL)
 		vap = TAILQ_FIRST(&ic->ic_vaps);	/* XXX */
@@ -930,15 +930,9 @@ ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
 
 	ni = ieee80211_ref_node(vap->iv_bss);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	/* extract tstamp from last beacon and convert to TU */
 	nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4),
 			     LE_READ_4(ni->ni_tstamp.data));
-
-	tsf_beacon = ((uint64_t) LE_READ_4(ni->ni_tstamp.data + 4)) << 32;
-	tsf_beacon |= LE_READ_4(ni->ni_tstamp.data);
-
 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
 	    ic->ic_opmode == IEEE80211_M_MBSS) {
 		/*
@@ -984,63 +978,14 @@ ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
 		 */
 		tsf = ath_hal_gettsf64(ah);
 		tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
-
-		DPRINTF(sc, ATH_DEBUG_BEACON,
-		    "%s: beacon tsf=%llu, hw tsf=%llu, nexttbtt=%u, tsftu=%u\n",
-		    __func__,
-		    (unsigned long long) tsf_beacon,
-		    (unsigned long long) tsf,
-		    nexttbtt,
-		    tsftu);
-		DPRINTF(sc, ATH_DEBUG_BEACON,
-		    "%s: beacon tsf=%llu, hw tsf=%llu, tsf delta=%lld\n",
-		    __func__,
-		    (unsigned long long) tsf_beacon,
-		    (unsigned long long) tsf,
-		    (long long) tsf -
-		    (long long) tsf_beacon);
-
-		DPRINTF(sc, ATH_DEBUG_BEACON,
-		    "%s: nexttbtt=%llu, beacon tsf delta=%lld\n",
-		    __func__,
-		    (unsigned long long) nexttbtt,
-		    (long long) ((long long) nexttbtt * 1024LL) - (long long) tsf_beacon);
-
-		/* XXX cfpcount? */
-
-		if (nexttbtt > tsftu) {
-			uint32_t countdiff, oldtbtt, remainder;
-
-			oldtbtt = nexttbtt;
-			remainder = (nexttbtt - tsftu) % intval;
-			nexttbtt = tsftu + remainder;
-
-			countdiff = (oldtbtt - nexttbtt) / intval % dtimperiod;
-			if (dtimcount > countdiff) {
-				dtimcount -= countdiff;
-			} else {
-				dtimcount += dtimperiod - countdiff;
-			}
-		} else { //nexttbtt <= tsftu
-			uint32_t countdiff, oldtbtt, remainder;
-
-			oldtbtt = nexttbtt;
-			remainder = (tsftu - nexttbtt) % intval;
-			nexttbtt = tsftu - remainder + intval;
-			countdiff = (nexttbtt - oldtbtt) / intval % dtimperiod;
-			if (dtimcount > countdiff) {
-				dtimcount -= countdiff;
-			} else {
-				dtimcount += dtimperiod - countdiff;
+		do {
+			nexttbtt += intval;
+			if (--dtimcount < 0) {
+				dtimcount = dtimperiod - 1;
+				if (--cfpcount < 0)
+					cfpcount = cfpperiod - 1;
 			}
-		}
-
-		DPRINTF(sc, ATH_DEBUG_BEACON,
-		    "%s: adj nexttbtt=%llu, rx tsf delta=%lld\n",
-		    __func__,
-		    (unsigned long long) nexttbtt,
-		    (long long) ((long long)nexttbtt * 1024LL) - (long long)tsf);
-
+		} while (nexttbtt < tsftu);
 		memset(&bs, 0, sizeof(bs));
 		bs.bs_intval = intval;
 		bs.bs_nexttbtt = nexttbtt;
@@ -1087,12 +1032,9 @@ ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
 			bs.bs_sleepduration = roundup(bs.bs_sleepduration, bs.bs_dtimperiod);
 
 		DPRINTF(sc, ATH_DEBUG_BEACON,
-			"%s: tsf %ju tsf:tu %u intval %u nexttbtt %u dtim %u "
-			"nextdtim %u bmiss %u sleep %u cfp:period %u "
-			"maxdur %u next %u timoffset %u\n"
+			"%s: tsf %ju tsf:tu %u intval %u nexttbtt %u dtim %u nextdtim %u bmiss %u sleep %u cfp:period %u maxdur %u next %u timoffset %u\n"
 			, __func__
-			, tsf
-			, tsftu
+			, tsf, tsftu
 			, bs.bs_intval
 			, bs.bs_nexttbtt
 			, bs.bs_dtimperiod
@@ -1169,9 +1111,8 @@ ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
 		if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol)
 			ath_beacon_start_adhoc(sc, vap);
 	}
+	sc->sc_syncbeacon = 0;
 	ieee80211_free_node(ni);
-
-	ath_power_restore_power_state(sc);
 #undef FUDGE
 #undef TSF_TO_TU
 }
diff --git a/sys/dev/netif/ath/ath/if_ath_beacon.h b/sys/dev/netif/ath/ath/if_ath_beacon.h
index 9a17149..f3f73d7 100644
--- a/sys/dev/netif/ath/ath/if_ath_beacon.h
+++ b/sys/dev/netif/ath/ath/if_ath_beacon.h
@@ -48,6 +48,5 @@ extern	int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_node *ni);
 extern	void ath_beacon_return(struct ath_softc *sc, struct ath_buf *bf);
 extern	void ath_beacon_free(struct ath_softc *sc);
 extern	void ath_beacon_proc(void *arg, int pending);
-extern	void ath_beacon_miss(struct ath_softc *sc);
 
 #endif
diff --git a/sys/dev/netif/ath/ath/if_ath_debug.h b/sys/dev/netif/ath/ath/if_ath_debug.h
index 38d0d9c..edd53f2 100644
--- a/sys/dev/netif/ath/ath/if_ath_debug.h
+++ b/sys/dev/netif/ath/ath/if_ath_debug.h
@@ -68,7 +68,6 @@ enum {
 	ATH_DEBUG_SW_TX_FILT	= 0x400000000ULL,	/* SW TX FF */
 	ATH_DEBUG_NODE_PWRSAVE	= 0x800000000ULL,	/* node powersave */
 	ATH_DEBUG_DIVERSITY	= 0x1000000000ULL,	/* Diversity logic */
-	ATH_DEBUG_PWRSAVE	= 0x2000000000ULL,
 
 	ATH_DEBUG_ANY		= 0xffffffffffffffffULL
 };
diff --git a/sys/dev/netif/ath/ath/if_ath_keycache.c b/sys/dev/netif/ath/ath/if_ath_keycache.c
index f505258..0a654b5 100644
--- a/sys/dev/netif/ath/ath/if_ath_keycache.c
+++ b/sys/dev/netif/ath/ath/if_ath_keycache.c
@@ -75,7 +75,6 @@
 
 #include <dev/netif/ath/ath/if_ath_debug.h>
 #include <dev/netif/ath/ath/if_ath_keycache.h>
-#include <dev/netif/ath/ath/if_ath_misc.h>
 
 extern  const char* ath_hal_ether_sprintf(const uint8_t *mac);
 
@@ -198,7 +197,6 @@ ath_keyset(struct ath_softc *sc, struct ieee80211vap *vap,
 	u_int8_t gmac[IEEE80211_ADDR_LEN];
 	const u_int8_t *mac;
 	HAL_KEYVAL hk;
-	int ret;
 
 	memset(&hk, 0, sizeof(hk));
 	/*
@@ -252,17 +250,13 @@ ath_keyset(struct ath_softc *sc, struct ieee80211vap *vap,
 	} else
 		mac = k->wk_macaddr;
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 	if (hk.kv_type == HAL_CIPHER_TKIP &&
 	    (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
-		ret = ath_keyset_tkip(sc, k, &hk, mac);
+		return ath_keyset_tkip(sc, k, &hk, mac);
 	} else {
 		KEYPRINTF(sc, k->wk_keyix, &hk, mac);
-		ret = ath_hal_keyset(ah, k->wk_keyix, &hk, mac);
+		return ath_hal_keyset(ah, k->wk_keyix, &hk, mac);
 	}
-	ath_power_restore_power_state(sc);
-
-	return (ret);
 #undef N
 }
 
@@ -497,7 +491,6 @@ ath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
 
 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: delete key %u\n", __func__, keyix);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 	ath_hal_keyreset(ah, keyix);
 	/*
 	 * Handle split tx/rx keying required for TKIP with h/w MIC.
@@ -521,7 +514,6 @@ ath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
 			}
 		}
 	}
-	ath_power_restore_power_state(sc);
 	return 1;
 }
 
diff --git a/sys/dev/netif/ath/ath/if_ath_led.c b/sys/dev/netif/ath/ath/if_ath_led.c
index 14fe1d3..376e201 100644
--- a/sys/dev/netif/ath/ath/if_ath_led.c
+++ b/sys/dev/netif/ath/ath/if_ath_led.c
@@ -118,8 +118,6 @@
 void
 ath_led_config(struct ath_softc *sc)
 {
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	/* Software LED blinking - GPIO controlled LED */
 	if (sc->sc_softled) {
 		ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin,
@@ -142,8 +140,6 @@ ath_led_config(struct ath_softc *sc)
 			ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_net_pin,
 			    HAL_GPIO_OUTPUT_MUX_MAC_NETWORK_LED);
 	}
-
-	ath_power_restore_power_state(sc);
 }
 
 static void
diff --git a/sys/dev/netif/ath/ath/if_ath_misc.h b/sys/dev/netif/ath/ath/if_ath_misc.h
index 4632976..cc3df2f 100644
--- a/sys/dev/netif/ath/ath/if_ath_misc.h
+++ b/sys/dev/netif/ath/ath/if_ath_misc.h
@@ -127,19 +127,6 @@ extern	void ath_start_task(void *arg, int npending);
 extern void ath_tx_dump(struct ath_softc *sc, struct ath_txq *txq);
 
 /*
- * Power state tracking.
- */
-extern	void _ath_power_setpower(struct ath_softc *sc, int power_state, const char *file, int line);
-extern	void _ath_power_set_selfgen(struct ath_softc *sc, int power_state, const char *file, int line);
-extern	void _ath_power_set_power_state(struct ath_softc *sc, int power_state, const char *file, int line);
-extern	void _ath_power_restore_power_state(struct ath_softc *sc, const char *file, int line);
-
-#define	ath_power_setpower(sc, ps) _ath_power_setpower(sc, ps, __FILE__, __LINE__)
-#define	ath_power_setselfgen(sc, ps) _ath_power_set_selfgen(sc, ps, __FILE__, __LINE__)
-#define	ath_power_set_power_state(sc, ps) _ath_power_set_power_state(sc, ps, __FILE__, __LINE__)
-#define	ath_power_restore_power_state(sc) _ath_power_restore_power_state(sc, __FILE__, __LINE__)
-
-/*
  * Kick the frame TX task.
  */
 static inline void
diff --git a/sys/dev/netif/ath/ath/if_ath_rx.c b/sys/dev/netif/ath/ath/if_ath_rx.c
index 0812781..84af07a 100644
--- a/sys/dev/netif/ath/ath/if_ath_rx.c
+++ b/sys/dev/netif/ath/ath/if_ath_rx.c
@@ -163,22 +163,10 @@ ath_calcrxfilter(struct ath_softc *sc)
 	/* XXX ic->ic_monvaps != 0? */
 	if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC))
 		rfilt |= HAL_RX_FILTER_PROM;
-
-	/*
-	 * Only listen to all beacons if we're scanning.
-	 *
-	 * Otherwise we only really need to hear beacons from
-	 * our own BSSID.
-	 */
 	if (ic->ic_opmode == IEEE80211_M_STA ||
-	    ic->ic_opmode == IEEE80211_M_IBSS || sc->sc_swbmiss) {
-		if (sc->sc_do_mybeacon && ! sc->sc_scanning) {
-			rfilt |= HAL_RX_FILTER_MYBEACON;
-		} else { /* scanning, non-mybeacon chips */
-			rfilt |= HAL_RX_FILTER_BEACON;
-		}
-	}
-
+	    ic->ic_opmode == IEEE80211_M_IBSS ||
+	    sc->sc_swbmiss || sc->sc_scanning)
+		rfilt |= HAL_RX_FILTER_BEACON;
 	/*
 	 * NB: We don't recalculate the rx filter when
 	 * ic_protmode changes; otherwise we could do
@@ -326,23 +314,6 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
-	uint64_t tsf_beacon_old, tsf_beacon;
-	uint64_t nexttbtt;
-	int64_t tsf_delta;
-	int32_t tsf_delta_bmiss;
-	int32_t tsf_remainder;
-	uint64_t tsf_beacon_target;
-	int tsf_intval;
-
-	tsf_beacon_old = ((uint64_t) LE_READ_4(ni->ni_tstamp.data + 4)) << 32;
-	tsf_beacon_old |= LE_READ_4(ni->ni_tstamp.data);
-
-#define	TU_TO_TSF(_tu)	(((u_int64_t)(_tu)) << 10)
-	tsf_intval = 1;
-	if (ni != NULL && ni->ni_intval > 0) {
-		tsf_intval = TU_TO_TSF(ni->ni_intval);
-	}
-#undef	TU_TO_TSF
 
 	/*
 	 * Call up first so subsequent work can use information
@@ -354,79 +325,14 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
 		/* update rssi statistics for use by the hal */
 		/* XXX unlocked check against vap->iv_bss? */
 		ATH_RSSI_LPF(sc->sc_halstats.ns_avgbrssi, rssi);
-
-		tsf_beacon = ((uint64_t) LE_READ_4(ni->ni_tstamp.data + 4)) << 32;
-		tsf_beacon |= LE_READ_4(ni->ni_tstamp.data);
-
-		nexttbtt = ath_hal_getnexttbtt(sc->sc_ah);
-
-		/*
-		 * Let's calculate the delta and remainder, so we can see
-		 * if the beacon timer from the AP is varying by more than
-		 * a few TU.  (Which would be a huge, huge problem.)
-		 */
-		tsf_delta = (long long) tsf_beacon - (long long) tsf_beacon_old;
-
-		tsf_delta_bmiss = tsf_delta / tsf_intval;
-
-		/*
-		 * If our delta is greater than half the beacon interval,
-		 * let's round the bmiss value up to the next beacon
-		 * interval.  Ie, we're running really, really early
-		 * on the next beacon.
-		 */
-		if (tsf_delta % tsf_intval > (tsf_intval / 2))
-			tsf_delta_bmiss ++;
-
-		tsf_beacon_target = tsf_beacon_old +
-		    (((unsigned long long) tsf_delta_bmiss) * (long long) tsf_intval);
-
-		/*
-		 * The remainder using '%' is between 0 .. intval-1.
-		 * If we're actually running too fast, then the remainder
-		 * will be some large number just under intval-1.
-		 * So we need to look at whether we're running
-		 * before or after the target beacon interval
-		 * and if we are, modify how we do the remainder
-		 * calculation.
-		 */
-		if (tsf_beacon < tsf_beacon_target) {
-			tsf_remainder =
-			    -(tsf_intval - ((tsf_beacon - tsf_beacon_old) % tsf_intval));
-		} else {
-			tsf_remainder = (tsf_beacon - tsf_beacon_old) % tsf_intval;
-		}
-
-		DPRINTF(sc, ATH_DEBUG_BEACON, "%s: old_tsf=%llu, new_tsf=%llu, target_tsf=%llu, delta=%lld, bmiss=%d, remainder=%d\n",
-		    __func__,
-		    (unsigned long long) tsf_beacon_old,
-		    (unsigned long long) tsf_beacon,
-		    (unsigned long long) tsf_beacon_target,
-		    (long long) tsf_delta,
-		    tsf_delta_bmiss,
-		    tsf_remainder);
-
-		DPRINTF(sc, ATH_DEBUG_BEACON, "%s: tsf=%llu, nexttbtt=%llu, delta=%d\n",
-		    __func__,
-		    (unsigned long long) tsf_beacon,
-		    (unsigned long long) nexttbtt,
-		    (int32_t) tsf_beacon - (int32_t) nexttbtt + tsf_intval);
-
 		if (sc->sc_syncbeacon &&
-		    ni == vap->iv_bss &&
-		    (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)) {
-			DPRINTF(sc, ATH_DEBUG_BEACON,
-			    "%s: syncbeacon=1; syncing\n",
-			    __func__);
+		    ni == vap->iv_bss && vap->iv_state == IEEE80211_S_RUN) {
 			/*
 			 * Resync beacon timers using the tsf of the beacon
 			 * frame we just received.
 			 */
 			ath_beacon_config(sc, vap);
-			sc->sc_syncbeacon = 0;
 		}
-
-
 		/* fall thru... */
 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 		if (vap->iv_opmode == IEEE80211_M_IBSS &&
@@ -1002,8 +908,6 @@ ath_rx_proc(struct ath_softc *sc, int resched)
 	kickpcu = sc->sc_kickpcu;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: called\n", __func__);
 	ngood = 0;
 	nf = ath_hal_getchannoise(ah, sc->sc_curchan);
@@ -1159,11 +1063,6 @@ rx_proc_next:
 #undef PA2DESC
 
 	/*
-	 * Put the hardware to sleep again if we're done with it.
-	 */
-	ath_power_restore_power_state(sc);
-
-	/*
 	 * If we hit the maximum number of frames in this round,
 	 * reschedule for another immediate pass.  This gives
 	 * the TX and TX completion routines time to run, which
diff --git a/sys/dev/netif/ath/ath/if_ath_rx_edma.c b/sys/dev/netif/ath/ath/if_ath_rx_edma.c
index 53a1514..cdb9fdf 100644
--- a/sys/dev/netif/ath/ath/if_ath_rx_edma.c
+++ b/sys/dev/netif/ath/ath/if_ath_rx_edma.c
@@ -282,21 +282,17 @@ static void
 ath_edma_recv_sched_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
     int dosched)
 {
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-	ath_edma_recv_proc_queue(sc, qtype, dosched);
-	ath_power_restore_power_state(sc);
 
+	ath_edma_recv_proc_queue(sc, qtype, dosched);
 	taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask);
 }
 
 static void
 ath_edma_recv_sched(struct ath_softc *sc, int dosched)
 {
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
+
 	ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_HP, dosched);
 	ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_LP, dosched);
-	ath_power_restore_power_state(sc);
-
 	taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask);
 }
 
@@ -310,8 +306,6 @@ ath_edma_recv_flush(struct ath_softc *sc)
 	sc->sc_rxproc_cnt++;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	/*
 	 * Flush any active frames from FIFO -> deferred list
 	 */
@@ -321,16 +315,9 @@ ath_edma_recv_flush(struct ath_softc *sc)
 	/*
 	 * Process what's in the deferred queue
 	 */
-	/*
-	 * XXX: If we read the tsf/channoise here and then pass it in,
-	 * we could restore the power state before processing
-	 * the deferred queue.
-	 */
 	ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_HP, 0);
 	ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_LP, 0);
 
-	ath_power_restore_power_state(sc);
-
 	ATH_PCU_LOCK(sc);
 	sc->sc_rxproc_cnt--;
 	ATH_PCU_UNLOCK(sc);
@@ -565,21 +552,12 @@ ath_edma_recv_tasklet(void *arg, int npending)
 	sc->sc_rxproc_cnt++;
 	ATH_PCU_UNLOCK(sc);
 
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_HP, 1);
 	ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_LP, 1);
 
 	ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_HP, 1);
 	ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_LP, 1);
 
-	/*
-	 * XXX: If we read the tsf/channoise here and then pass it in,
-	 * we could restore the power state before processing
-	 * the deferred queue.
-	 */
-	ath_power_restore_power_state(sc);
-
 	/* XXX inside IF_LOCK ? */
 	if (!ifq_is_oactive(&ifp->if_snd)) {
 #ifdef	IEEE80211_SUPPORT_SUPERG
diff --git a/sys/dev/netif/ath/ath/if_ath_sysctl.c b/sys/dev/netif/ath/ath/if_ath_sysctl.c
index ddd46c8..833caae 100644
--- a/sys/dev/netif/ath/ath/if_ath_sysctl.c
+++ b/sys/dev/netif/ath/ath/if_ath_sysctl.c
@@ -109,12 +109,10 @@ ath_sysctl_slottime(SYSCTL_HANDLER_ARGS)
 	int error;
 
 	wlan_serialize_enter();
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 	slottime = ath_hal_getslottime(sc->sc_ah);
 	error = sysctl_handle_int(oidp, &slottime, 0, req);
 	if (error == 0 && req->newptr)
 		error = !ath_hal_setslottime(sc->sc_ah, slottime) ? EINVAL : 0;
-	ath_power_restore_power_state(sc);
 	wlan_serialize_exit();
 	return error;
 }
diff --git a/sys/dev/netif/ath/ath/if_ath_tx.c b/sys/dev/netif/ath/ath/if_ath_tx.c
index bc225f1..e61cae7 100644
--- a/sys/dev/netif/ath/ath/if_ath_tx.c
+++ b/sys/dev/netif/ath/ath/if_ath_tx.c
@@ -739,21 +739,37 @@ ath_tx_handoff_hw(struct ath_softc *sc, struct ath_txq *txq,
 	     ("ath_tx_handoff_hw called for mcast queue"));
 
 	/*
-	 * XXX We should instead just verify that sc_txstart_cnt
-	 * or ath_txproc_cnt > 0.  That would mean that
-	 * the reset is going to be waiting for us to complete.
+	 * XXX racy, should hold the PCU lock when checking this,
+	 * and also should ensure that the TX counter is >0!
 	 */
-	if (sc->sc_txproc_cnt == 0 && sc->sc_txstart_cnt == 0) {
-		device_printf(sc->sc_dev,
-		    "%s: TX dispatch without holding txcount/txstart refcnt!\n",
-		    __func__);
-	}
+	KASSERT((sc->sc_inreset_cnt == 0),
+	    ("%s: TX during reset?\n", __func__));
 
+#if 0
 	/*
-	 * XXX .. this is going to cause the hardware to get upset;
-	 * so we really should find some way to drop or queue
-	 * things.
+	 * This causes a LOR. Find out where the PCU lock is being
+	 * held whilst the TXQ lock is grabbed - that shouldn't
+	 * be occuring.
 	 */
+	ATH_PCU_LOCK(sc);
+	if (sc->sc_inreset_cnt) {
+		ATH_PCU_UNLOCK(sc);
+		DPRINTF(sc, ATH_DEBUG_RESET,
+		    "%s: called with sc_in_reset != 0\n",
+		    __func__);
+		DPRINTF(sc, ATH_DEBUG_XMIT,
+		    "%s: queued: TXDP[%u] = %p (%p) depth %d\n",
+		    __func__, txq->axq_qnum,
+		    (caddr_t)bf->bf_daddr, bf->bf_desc,
+		    txq->axq_depth);
+		/* XXX axq_link needs to be set and updated! */
+		ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
+		if (bf->bf_state.bfs_aggr)
+			txq->axq_aggr_depth++;
+		return;
+		}
+	ATH_PCU_UNLOCK(sc);
+#endif
 
 	ATH_TXQ_LOCK(txq);
 
@@ -1578,7 +1594,6 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
 	error = ath_tx_dmasetup(sc, bf, m0);
 	if (error != 0)
 		return error;
-	KASSERT((ni != NULL), ("%s: ni=NULL!", __func__));
 	bf->bf_node = ni;			/* NB: held reference */
 	m0 = bf->bf_m;				/* NB: may have changed */
 	wh = mtod(m0, struct ieee80211_frame *);
@@ -2070,7 +2085,6 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
 	int do_override;
 	uint8_t type, subtype;
 	int queue_to_head;
-	struct ath_node *an = ATH_NODE(ni);
 
 	ATH_TX_LOCK_ASSERT(sc);
 
@@ -2130,7 +2144,6 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
 		return error;
 	m0 = bf->bf_m;				/* NB: may have changed */
 	wh = mtod(m0, struct ieee80211_frame *);
-	KASSERT((ni != NULL), ("%s: ni=NULL!", __func__));
 	bf->bf_node = ni;			/* NB: held reference */
 
 	/* Always enable CLRDMASK for raw frames for now.. */
@@ -2149,24 +2162,12 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
 
 	rt = sc->sc_currates;
 	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
-
-	/* Fetch first rate information */
 	rix = ath_tx_findrix(sc, params->ibp_rate0);
-	try0 = params->ibp_try0;
-
-	/*
-	 * Override EAPOL rate as appropriate.
-	 */
-	if (m0->m_flags & M_EAPOL) {
-		/* XXX? maybe always use long preamble? */
-		rix = an->an_mgmtrix;
-		try0 = ATH_TXMAXTRY;	/* XXX?too many? */
-	}
-
 	txrate = rt->info[rix].rateCode;
 	if (params->ibp_flags & IEEE80211_BPF_SHORTPRE)
 		txrate |= rt->info[rix].shortPreamble;
 	sc->sc_txrix = rix;
+	try0 = params->ibp_try0;
 	ismrr = (params->ibp_try1 != 0);
 	txantenna = params->ibp_pri >> 2;
 	if (txantenna == 0)			/* XXX? */
@@ -2239,7 +2240,8 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
 	/* Blank the legacy rate array */
 	bzero(&bf->bf_state.bfs_rc, sizeof(bf->bf_state.bfs_rc));
 
-	bf->bf_state.bfs_rc[0].rix = rix;
+	bf->bf_state.bfs_rc[0].rix =
+	    ath_tx_findrix(sc, params->ibp_rate0);
 	bf->bf_state.bfs_rc[0].tries = try0;
 	bf->bf_state.bfs_rc[0].ratecode = txrate;
 
@@ -2331,14 +2333,11 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
 		    "%s: sc_inreset_cnt > 0; bailing\n", __func__);
 		error = EIO;
 		ATH_PCU_UNLOCK(sc);
-		goto badbad;
+		goto bad0;
 	}
 	sc->sc_txstart_cnt++;
 	ATH_PCU_UNLOCK(sc);
 
-	/* Wake the hardware up already */
-	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-
 	ATH_TX_LOCK(sc);
 
 	if ((ifp->if_flags & IFF_RUNNING) == 0 || sc->sc_invalid) {
@@ -2417,12 +2416,7 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
 	sc->sc_txstart_cnt--;
 	ATH_PCU_UNLOCK(sc);
 
-
-	/* Put the hardware back to sleep if required */
-	ath_power_restore_power_state(sc);
-
 	return 0;
-
 bad2:
 	ATH_KTR(sc, ATH_KTR_TX, 3, "ath_raw_xmit: bad2: m=%p, params=%p, "
 	    "bf=%p",
@@ -2432,18 +2426,14 @@ bad2:
 	ATH_TXBUF_LOCK(sc);
 	ath_returnbuf_head(sc, bf);
 	ATH_TXBUF_UNLOCK(sc);
-
 bad:
+
 	ATH_TX_UNLOCK(sc);
 
 	ATH_PCU_LOCK(sc);
 	sc->sc_txstart_cnt--;
 	ATH_PCU_UNLOCK(sc);
-
-	/* Put the hardware back to sleep if required */
-	ath_power_restore_power_state(sc);
-
-badbad:
+bad0:
 	ATH_KTR(sc, ATH_KTR_TX, 2, "ath_raw_xmit: bad0: m=%p, params=%p",
 	    m, params);
 	ifp->if_oerrors++;
@@ -2739,8 +2729,8 @@ ath_tx_update_baw(struct ath_softc *sc, struct ath_node *an,
 		INCR(tid->baw_head, ATH_TID_MAX_BUFS);
 	}
 	DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
-	    "%s: tid=%d: baw is now %d:%d, baw head=%d\n",
-	    __func__, tid->tid, tap->txa_start, tap->txa_wnd, tid->baw_head);
+	    "%s: baw is now %d:%d, baw head=%d\n",
+	    __func__, tap->txa_start, tap->txa_wnd, tid->baw_head);
 }
 
 static void
@@ -3232,11 +3222,8 @@ ath_tx_tid_pause(struct ath_softc *sc, struct ath_tid *tid)
 
 	ATH_TX_LOCK_ASSERT(sc);
 	tid->paused++;
-	DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: [%s]: tid=%d, paused = %d\n",
-	    __func__,
-	    ath_hal_ether_sprintf(tid->an->an_node.ni_macaddr),
-	    tid->tid,
-	    tid->paused);
+	DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: paused = %d\n",
+	    __func__, tid->paused);
 }
 
 /*
@@ -3253,22 +3240,15 @@ ath_tx_tid_resume(struct ath_softc *sc, struct ath_tid *tid)
 	 * until it's actually resolved.
 	 */
 	if (tid->paused == 0) {
-		device_printf(sc->sc_dev,
-			      "%s: [%s]: tid=%d, paused=0?\n",
-			      __func__,
-			      ath_hal_ether_sprintf(
-						tid->an->an_node.ni_macaddr),
-			      tid->tid);
+		DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
+		    "%s: %s: paused=0?\n", __func__,
+		    ath_hal_ether_sprintf(tid->an->an_node.ni_macaddr));
 	} else {
 		tid->paused--;
 	}
 
-	DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
-	    "%s: [%s]: tid=%d, unpaused = %d\n",
-	    __func__,
-	    ath_hal_ether_sprintf(tid->an->an_node.ni_macaddr),
-	    tid->tid,
-	    tid->paused);
+	DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: unpaused = %d\n",
+	    __func__, tid->paused);
 
 	if (tid->paused)
 		return;
@@ -3334,8 +3314,8 @@ ath_tx_tid_filt_comp_buf(struct ath_softc *sc, struct ath_tid *tid,
 	ATH_TX_LOCK_ASSERT(sc);
 
 	if (! tid->isfiltered) {
-		DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, "%s: tid=%d; filter transition\n",
-		    __func__, tid->tid);
+		DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, "%s: filter transition\n",
+		    __func__);
 		tid->isfiltered = 1;
 		ath_tx_tid_pause(sc, tid);
 	}
@@ -3355,20 +3335,15 @@ static void
 ath_tx_tid_filt_comp_complete(struct ath_softc *sc, struct ath_tid *tid)
 {
 	struct ath_buf *bf;
-	int do_resume = 0;
 
 	ATH_TX_LOCK_ASSERT(sc);
 
 	if (tid->hwq_depth != 0)
 		return;
 
-	DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, "%s: tid=%d, hwq=0, transition back\n",
-	    __func__, tid->tid);
-	if (tid->isfiltered == 1) {
-		tid->isfiltered = 0;
-		do_resume = 1;
-	}
-
+	DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, "%s: hwq=0, transition back\n",
+	    __func__);
+	tid->isfiltered = 0;
 	/* XXX ath_tx_tid_resume() also calls ath_tx_set_clrdmask()! */
 	ath_tx_set_clrdmask(sc, tid->an);
 
@@ -3378,21 +3353,16 @@ ath_tx_tid_filt_comp_complete(struct ath_softc *sc, struct ath_tid *tid)
 		ATH_TID_INSERT_HEAD(tid, bf, bf_list);
 	}
 
-	/* And only resume if we had paused before */
-	if (do_resume)
-		ath_tx_tid_resume(sc, tid);
+	ath_tx_tid_resume(sc, tid);
 }
 
 /*
  * Called when a single (aggregate or otherwise) frame is completed.
  *
- * Returns 0 if the buffer could be added to the filtered list
- * (cloned or otherwise), 1 if the buffer couldn't be added to the
+ * Returns 1 if the buffer could be added to the filtered list
+ * (cloned or otherwise), 0 if the buffer couldn't be added to the
  * filtered list (failed clone; expired retry) and the caller should
  * free it and handle it like a failure (eg by sending a BAR.)
- *
- * since the buffer may be cloned, bf must be not touched after this
- * if the return value is 0.
  */
 static int
 ath_tx_tid_filt_comp_single(struct ath_softc *sc, struct ath_tid *tid,
@@ -3412,9 +3382,8 @@ ath_tx_tid_filt_comp_single(struct ath_softc *sc, struct ath_tid *tid,
 		    "%s: bf=%p, seqno=%d, exceeded retries\n",
 		    __func__,
 		    bf,
-		    SEQNO(bf->bf_state.bfs_seqno));
-		retval = 1; /* error */
-		goto finish;
+		    bf->bf_state.bfs_seqno);
+		return (0);
 	}
 
 	/*
@@ -3434,12 +3403,11 @@ ath_tx_tid_filt_comp_single(struct ath_softc *sc, struct ath_tid *tid,
 		DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
 		    "%s: busy buffer couldn't be cloned (%p)!\n",
 		    __func__, bf);
-		retval = 1; /* error */
+		retval = 1;
 	} else {
 		ath_tx_tid_filt_comp_buf(sc, tid, nbf);
-		retval = 0; /* ok */
+		retval = 0;
 	}
-finish:
 	ath_tx_tid_filt_comp_complete(sc, tid);
 
 	return (retval);
@@ -3464,11 +3432,10 @@ ath_tx_tid_filt_comp_aggr(struct ath_softc *sc, struct ath_tid *tid,
 		if (bf->bf_state.bfs_retries > SWMAX_RETRIES) {
 			sc->sc_stats.ast_tx_swretrymax++;
 			DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
-			    "%s: tid=%d, bf=%p, seqno=%d, exceeded retries\n",
+			    "%s: bf=%p, seqno=%d, exceeded retries\n",
 			    __func__,
-			    tid->tid,
 			    bf,
-			    SEQNO(bf->bf_state.bfs_seqno));
+			    bf->bf_state.bfs_seqno);
 			TAILQ_INSERT_TAIL(bf_q, bf, bf_list);
 			goto next;
 		}
@@ -3476,8 +3443,8 @@ ath_tx_tid_filt_comp_aggr(struct ath_softc *sc, struct ath_tid *tid,
 		if (bf->bf_flags & ATH_BUF_BUSY) {
 			nbf = ath_tx_retry_clone(sc, tid->an, tid, bf);
 			DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
-			    "%s: tid=%d, busy buffer cloned: %p -> %p, seqno=%d\n",
-			    __func__, tid->tid, bf, nbf, SEQNO(bf->bf_state.bfs_seqno));
+			    "%s: busy buffer cloned: %p -> %p",
+			    __func__, bf, nbf);
 		} else {
 			nbf = bf;
 		}
@@ -3488,8 +3455,8 @@ ath_tx_tid_filt_comp_aggr(struct ath_softc *sc, struct ath_tid *tid,
 		 */
 		if (nbf == NULL) {
 			DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
-			    "%s: tid=%d, buffer couldn't be cloned! (%p) seqno=%d\n",
-			    __func__, tid->tid, bf, SEQNO(bf->bf_state.bfs_seqno));
+			    "%s: buffer couldn't be cloned! (%p)\n",
+			    __func__, bf);
 			TAILQ_INSERT_TAIL(bf_q, bf, bf_list);
 		} else {
 			ath_tx_tid_filt_comp_buf(sc, tid, nbf);
@@ -3727,7 +3694,7 @@ ath_tx_tid_drain_print(struct ath_softc *sc, struct ath_node *an,
 	txq = sc->sc_ac2q[tid->ac];
 	tap = ath_tx_get_tx_tid(an, tid->tid);
 
-	DPRINTF(sc, ATH_DEBUG_SW_TX | ATH_DEBUG_RESET,
+	DPRINTF(sc, ATH_DEBUG_SW_TX,
 	    "%s: %s: %s: bf=%p: addbaw=%d, dobaw=%d, "
 	    "seqno=%d, retry=%d\n",
 	    __func__,
@@ -3738,7 +3705,7 @@ ath_tx_tid_drain_print(struct ath_softc *sc, struct ath_node *an,
 	    bf->bf_state.bfs_dobaw,
 	    SEQNO(bf->bf_state.bfs_seqno),
 	    bf->bf_state.bfs_retries);
-	DPRINTF(sc, ATH_DEBUG_SW_TX | ATH_DEBUG_RESET,
+	DPRINTF(sc, ATH_DEBUG_SW_TX,
 	    "%s: %s: %s: bf=%p: txq[%d] axq_depth=%d, axq_aggr_depth=%d\n",
 	    __func__,
 	    pfx,
@@ -3747,7 +3714,7 @@ ath_tx_tid_drain_print(struct ath_softc *sc, struct ath_node *an,
 	    txq->axq_qnum,
 	    txq->axq_depth,
 	    txq->axq_aggr_depth);
-	DPRINTF(sc, ATH_DEBUG_SW_TX | ATH_DEBUG_RESET,
+	DPRINTF(sc, ATH_DEBUG_SW_TX,
 	    "%s: %s: %s: bf=%p: tid txq_depth=%d hwq_depth=%d, bar_wait=%d, "
 	      "isfiltered=%d\n",
 	    __func__,
@@ -3758,7 +3725,7 @@ ath_tx_tid_drain_print(struct ath_softc *sc, struct ath_node *an,
 	    tid->hwq_depth,
 	    tid->bar_wait,
 	    tid->isfiltered);
-	DPRINTF(sc, ATH_DEBUG_SW_TX | ATH_DEBUG_RESET,
+	DPRINTF(sc, ATH_DEBUG_SW_TX,
 	    "%s: %s: %s: tid %d: "
 	    "sched=%d, paused=%d, "
 	    "incomp=%d, baw_head=%d, "
@@ -3773,10 +3740,9 @@ ath_tx_tid_drain_print(struct ath_softc *sc, struct ath_node *an,
 	     ni->ni_txseqs[tid->tid]);
 
 	/* XXX Dump the frame, see what it is? */
-	if (IFF_DUMPPKTS(sc, ATH_DEBUG_XMIT))
-		ieee80211_dump_pkt(ni->ni_ic,
-		    mtod(bf->bf_m, const uint8_t *),
-		    bf->bf_m->m_len, 0, -1);
+	ieee80211_dump_pkt(ni->ni_ic,
+	    mtod(bf->bf_m, const uint8_t *),
+	    bf->bf_m->m_len, 0, -1);
 }
 
 /*
@@ -3817,7 +3783,7 @@ ath_tx_tid_drain(struct ath_softc *sc, struct ath_node *an,
 
 		if (t == 0) {
 			ath_tx_tid_drain_print(sc, an, "norm", tid, bf);
-//			t = 1;
+			t = 1;
 		}
 
 		ATH_TID_REMOVE(tid, bf, bf_list);
@@ -3833,7 +3799,7 @@ ath_tx_tid_drain(struct ath_softc *sc, struct ath_node *an,
 
 		if (t == 0) {
 			ath_tx_tid_drain_print(sc, an, "filt", tid, bf);
-//			t = 1;
+			t = 1;
 		}
 
 		ATH_TID_FILT_REMOVE(tid, bf, bf_list);
@@ -4088,19 +4054,6 @@ ath_tx_normal_comp(struct ath_softc *sc, struct ath_buf *bf, int fail)
 		DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: hwq_depth < 0: %d\n",
 		    __func__, atid->hwq_depth);
 
-	/* If the TID is being cleaned up, track things */
-	/* XXX refactor! */
-	if (atid->cleanup_inprogress) {
-		atid->incomp--;
-		if (atid->incomp == 0) {
-			DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
-			    "%s: TID %d: cleaned up! resume!\n",
-			    __func__, tid);
-			atid->cleanup_inprogress = 0;
-			ath_tx_tid_resume(sc, atid);
-		}
-	}
-
 	/*
 	 * If the queue is filtered, potentially mark it as complete
 	 * and reschedule it as needed.
@@ -4148,16 +4101,6 @@ ath_tx_comp_cleanup_unaggr(struct ath_softc *sc, struct ath_buf *bf)
 
 	ATH_TX_LOCK(sc);
 	atid->incomp--;
-
-	/* XXX refactor! */
-	if (bf->bf_state.bfs_dobaw) {
-		ath_tx_update_baw(sc, an, atid, bf);
-		if (!bf->bf_state.bfs_addedbaw)
-			DPRINTF(sc, ATH_DEBUG_SW_TX,
-			    "%s: wasn't added: seqno %d\n",
-			    __func__, SEQNO(bf->bf_state.bfs_seqno));
-	}
-
 	if (atid->incomp == 0) {
 		DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
 		    "%s: TID %d: cleaned up! resume!\n",
@@ -4170,72 +4113,14 @@ ath_tx_comp_cleanup_unaggr(struct ath_softc *sc, struct ath_buf *bf)
 	ath_tx_default_comp(sc, bf, 0);
 }
 
-
-/*
- * This as it currently stands is a bit dumb.  Ideally we'd just
- * fail the frame the normal way and have it permanently fail
- * via the normal aggregate completion path.
- */
-static void
-ath_tx_tid_cleanup_frame(struct ath_softc *sc, struct ath_node *an,
-    int tid, struct ath_buf *bf_head, ath_bufhead *bf_cq)
-{
-	struct ath_tid *atid = &an->an_tid[tid];
-	struct ath_buf *bf, *bf_next;
-
-	ATH_TX_LOCK_ASSERT(sc);
-
-	/*
-	 * Remove this frame from the queue.
-	 */
-	ATH_TID_REMOVE(atid, bf_head, bf_list);
-
-	/*
-	 * Loop over all the frames in the aggregate.
-	 */
-	bf = bf_head;
-	while (bf != NULL) {
-		bf_next = bf->bf_next;	/* next aggregate frame, or NULL */
-
-		/*
-		 * If it's been added to the BAW we need to kick
-		 * it out of the BAW before we continue.
-		 *
-		 * XXX if it's an aggregate, assert that it's in the
-		 * BAW - we shouldn't have it be in an aggregate
-		 * otherwise!
-		 */
-		if (bf->bf_state.bfs_addedbaw) {
-			ath_tx_update_baw(sc, an, atid, bf);
-			bf->bf_state.bfs_dobaw = 0;
-		}
-
-		/*
-		 * Give it the default completion handler.
-		 */
-		bf->bf_comp = ath_tx_normal_comp;
-		bf->bf_next = NULL;
-
-		/*
-		 * Add it to the list to free.
-		 */
-		TAILQ_INSERT_TAIL(bf_cq, bf, bf_list);
-
-		/*
-		 * Now advance to the next frame in the aggregate.
-		 */
-		bf = bf_next;
-	}
-}
-
 /*
  * Performs transmit side cleanup when TID changes from aggregated to
- * unaggregated and during reassociation.
+ * unaggregated.
  *
- * For now, this just tosses everything from the TID software queue
- * whether or not it has been retried and marks the TID as
- * pending completion if there's anything for this TID queued to
- * the hardware.
+ * - Discard all retry frames from the s/w queue.
+ * - Fix the tx completion function for all buffers in s/w queue.
+ * - Count the number of unacked frames, and let transmit completion
+ *   handle it later.
  *
  * The caller is responsible for pausing the TID and unpausing the
  * TID if no cleanup was required. Otherwise the cleanup path will
@@ -4246,19 +4131,18 @@ ath_tx_tid_cleanup(struct ath_softc *sc, struct ath_node *an, int tid,
     ath_bufhead *bf_cq)
 {
 	struct ath_tid *atid = &an->an_tid[tid];
+	struct ieee80211_tx_ampdu *tap;
 	struct ath_buf *bf, *bf_next;
 
 	ATH_TX_LOCK_ASSERT(sc);
 
 	DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
-	    "%s: TID %d: called; inprogress=%d\n", __func__, tid,
-	    atid->cleanup_inprogress);
+	    "%s: TID %d: called\n", __func__, tid);
 
 	/*
 	 * Move the filtered frames to the TX queue, before
 	 * we run off and discard/process things.
 	 */
-
 	/* XXX this is really quite inefficient */
 	while ((bf = ATH_TID_FILT_LAST(atid, ath_bufhead_s)) != NULL) {
 		ATH_TID_FILT_REMOVE(atid, bf, bf_list);
@@ -4273,35 +4157,47 @@ ath_tx_tid_cleanup(struct ath_softc *sc, struct ath_node *an, int tid,
 	 */
 	bf = ATH_TID_FIRST(atid);
 	while (bf) {
-		/*
-		 * Grab the next frame in the list, we may
-		 * be fiddling with the list.
-		 */
-		bf_next = TAILQ_NEXT(bf, bf_list);
-
-		/*
-		 * Free the frame and all subframes.
-		 */
-		ath_tx_tid_cleanup_frame(sc, an, tid, bf, bf_cq);
-
-		/*
-		 * Next frame!
-		 */
-		bf = bf_next;
+		if (bf->bf_state.bfs_isretried) {
+			bf_next = TAILQ_NEXT(bf, bf_list);
+			ATH_TID_REMOVE(atid, bf, bf_list);
+			if (bf->bf_state.bfs_dobaw) {
+				ath_tx_update_baw(sc, an, atid, bf);
+				if (!bf->bf_state.bfs_addedbaw)
+					DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
+					    "%s: wasn't added: seqno %d\n",
+					    __func__,
+					    SEQNO(bf->bf_state.bfs_seqno));
+			}
+			bf->bf_state.bfs_dobaw = 0;
+			/*
+			 * Call the default completion handler with "fail" just
+			 * so upper levels are suitably notified about this.
+			 */
+			TAILQ_INSERT_TAIL(bf_cq, bf, bf_list);
+			bf = bf_next;
+			continue;
+		}
+		/* Give these the default completion handler */
+		bf->bf_comp = ath_tx_normal_comp;
+		bf = TAILQ_NEXT(bf, bf_list);
 	}
 
 	/*
-	 * If there's anything in the hardware queue we wait
-	 * for the TID HWQ to empty.
+	 * Calculate what hardware-queued frames exist based
+	 * on the current BAW size. Ie, what frames have been
+	 * added to the TX hardware queue for this TID but
+	 * not yet ACKed.
 	 */
-	if (atid->hwq_depth > 0) {
-		/*
-		 * XXX how about we kill atid->incomp, and instead
-		 * replace it with a macro that checks that atid->hwq_depth
-		 * is 0?
-		 */
-		atid->incomp = atid->hwq_depth;
-		atid->cleanup_inprogress = 1;
+	tap = ath_tx_get_tx_tid(an, tid);
+	/* Need the lock - fiddling with BAW */
+	while (atid->baw_head != atid->baw_tail) {
+		if (atid->tx_buf[atid->baw_head]) {
+			atid->incomp++;
+			atid->cleanup_inprogress = 1;
+			atid->tx_buf[atid->baw_head] = NULL;
+		}
+		INCR(atid->baw_head, ATH_TID_MAX_BUFS);
+		INCR(tap->txa_start, IEEE80211_SEQ_RANGE);
 	}
 
 	if (atid->cleanup_inprogress)
@@ -4634,19 +4530,9 @@ ath_tx_comp_cleanup_aggr(struct ath_softc *sc, struct ath_buf *bf_first)
 	ATH_TX_LOCK(sc);
 
 	/* update incomp */
-	atid->incomp--;
-
-	/* Update the BAW */
 	bf = bf_first;
 	while (bf) {
-		/* XXX refactor! */
-		if (bf->bf_state.bfs_dobaw) {
-			ath_tx_update_baw(sc, an, atid, bf);
-			if (!bf->bf_state.bfs_addedbaw)
-				DPRINTF(sc, ATH_DEBUG_SW_TX,
-				    "%s: wasn't added: seqno %d\n",
-				    __func__, SEQNO(bf->bf_state.bfs_seqno));
-		}
+		atid->incomp--;
 		bf = bf->bf_next;
 	}
 
@@ -4669,11 +4555,10 @@ ath_tx_comp_cleanup_aggr(struct ath_softc *sc, struct ath_buf *bf_first)
 
 	ATH_TX_UNLOCK(sc);
 
-	/* Handle frame completion as individual frames */
+	/* Handle frame completion */
 	bf = bf_first;
 	while (bf) {
 		bf_next = bf->bf_next;
-		bf->bf_next = NULL;
 		ath_tx_default_comp(sc, bf, 1);
 		bf = bf_next;
 	}
@@ -5115,10 +5000,6 @@ ath_tx_aggr_comp_unaggr(struct ath_softc *sc, struct ath_buf *bf, int fail)
 			    "%s: isfiltered=1, fail=%d\n",
 			    __func__, fail);
 		freeframe = ath_tx_tid_filt_comp_single(sc, atid, bf);
-		/*
-		 * If freeframe=0 then bf is no longer ours; don't
-		 * touch it.
-		 */
 		if (freeframe) {
 			/* Remove from BAW */
 			if (bf->bf_state.bfs_addedbaw)
@@ -5154,6 +5035,7 @@ ath_tx_aggr_comp_unaggr(struct ath_softc *sc, struct ath_buf *bf, int fail)
 		if (freeframe)
 			ath_tx_default_comp(sc, bf, fail);
 
+
 		return;
 	}
 	/*
@@ -5858,26 +5740,12 @@ ath_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
 	 */
 	TAILQ_INIT(&bf_cq);
 	ATH_TX_LOCK(sc);
-
+	ath_tx_tid_cleanup(sc, an, tid, &bf_cq);
 	/*
-	 * In case there's a followup call to this, only call it
-	 * if we don't have a cleanup in progress.
-	 *
-	 * Since we've paused the queue above, we need to make
-	 * sure we unpause if there's already a cleanup in
-	 * progress - it means something else is also doing
-	 * this stuff, so we don't need to also keep it paused.
+	 * Unpause the TID if no cleanup is required.
 	 */
-	if (atid->cleanup_inprogress) {
+	if (! atid->cleanup_inprogress)
 		ath_tx_tid_resume(sc, atid);
-	} else {
-		ath_tx_tid_cleanup(sc, an, tid, &bf_cq);
-		/*
-		 * Unpause the TID if no cleanup is required.
-		 */
-		if (! atid->cleanup_inprogress)
-			ath_tx_tid_resume(sc, atid);
-	}
 	ATH_TX_UNLOCK(sc);
 
 	/* Handle completing frames and fail them */
@@ -5911,24 +5779,18 @@ ath_tx_node_reassoc(struct ath_softc *sc, struct ath_node *an)
 		tid = &an->an_tid[i];
 		if (tid->hwq_depth == 0)
 			continue;
+		ath_tx_tid_pause(sc, tid);
 		DPRINTF(sc, ATH_DEBUG_NODE,
 		    "%s: %s: TID %d: cleaning up TID\n",
 		    __func__,
 		    ath_hal_ether_sprintf(an->an_node.ni_macaddr),
 		    i);
+		ath_tx_tid_cleanup(sc, an, i, &bf_cq);
 		/*
-		 * In case there's a followup call to this, only call it
-		 * if we don't have a cleanup in progress.
+		 * Unpause the TID if no cleanup is required.
 		 */
-		if (! tid->cleanup_inprogress) {
-			ath_tx_tid_pause(sc, tid);
-			ath_tx_tid_cleanup(sc, an, i, &bf_cq);
-			/*
-			 * Unpause the TID if no cleanup is required.
-			 */
-			if (! tid->cleanup_inprogress)
-				ath_tx_tid_resume(sc, tid);
-		}
+		if (! tid->cleanup_inprogress)
+			ath_tx_tid_resume(sc, tid);
 	}
 	ATH_TX_UNLOCK(sc);
 
@@ -5958,42 +5820,18 @@ ath_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
 	struct ath_node *an = ATH_NODE(ni);
 	struct ath_tid *atid = &an->an_tid[tid];
 	int attempts = tap->txa_attempts;
-	int old_txa_start;
 
 	DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
-	    "%s: %s: called; txa_tid=%d, atid->tid=%d, status=%d, attempts=%d"
-	    ",  txa_start=%d, txa_seqpending=%d\n",
+	    "%s: %s: called; txa_tid=%d, atid->tid=%d, status=%d, attempts=%d\n",
 	    __func__,
 	    ath_hal_ether_sprintf(ni->ni_macaddr),
 	    tap->txa_ac,
 	    atid->tid,
 	    status,
-	    attempts,
-	    tap->txa_start,
-	    tap->txa_seqpending);
+	    attempts);
 
 	/* Note: This may update the BAW details */
-	/*
-	 * XXX What if this does slide the BAW along? We need to somehow
-	 * XXX either fix things when it does happen, or prevent the
-	 * XXX seqpending value to be anything other than exactly what
-	 * XXX the hell we want!
-	 *
-	 * XXX So for now, how I do this inside the TX lock for now
-	 * XXX and just correct it afterwards? The below condition should
-	 * XXX never happen and if it does I need to fix all kinds of things.
-	 */
-	old_txa_start = tap->txa_start;
 	sc->sc_bar_response(ni, tap, status);
-	if (tap->txa_start != old_txa_start) {
-		device_printf(sc->sc_dev,
-			      "%s: tid=%d; txa_start=%d, old=%d, adjusting\n",
-			      __func__,
-			      tid,
-			      tap->txa_start,
-			      old_txa_start);
-	}
-	tap->txa_start = old_txa_start;
 
 	/* Unpause the TID */
 	/*
diff --git a/sys/dev/netif/ath/ath/if_athvar.h b/sys/dev/netif/ath/ath/if_athvar.h
index 8125877..3d609ec 100644
--- a/sys/dev/netif/ath/ath/if_athvar.h
+++ b/sys/dev/netif/ath/ath/if_athvar.h
@@ -633,8 +633,7 @@ struct ath_softc {
 				sc_resetcal : 1,/* reset cal state next trip */
 				sc_rxslink  : 1,/* do self-linked final descriptor */
 				sc_rxtsf32  : 1,/* RX dec TSF is 32 bits */
-				sc_isedma   : 1,/* supports EDMA */
-				sc_do_mybeacon : 1; /* supports mybeacon */
+				sc_isedma   : 1;/* supports EDMA */
 
 	/*
 	 * Second set of flags.
@@ -881,22 +880,6 @@ struct ath_softc {
 	void			(*sc_bar_response)(struct ieee80211_node *ni,
 				    struct ieee80211_tx_ampdu *tap,
 				    int status);
-
-	/*
-	 * Powersave state tracking.
-	 *
-	 * target/cur powerstate is the chip power state.
-	 * target selfgen state is the self-generated frames
-	 *   state.  The chip can be awake but transmitted frames
-	 *   can have the PWRMGT bit set to 1 so the destination
-	 *   thinks the node is asleep.
-	 */
-	HAL_POWER_MODE		sc_target_powerstate;
-	HAL_POWER_MODE		sc_target_selfgen_state;
-
-	HAL_POWER_MODE		sc_cur_powerstate;
-
-	int			sc_powersave_refcnt;
 };
 
 #define	ATH_LOCK_INIT(_sc)
@@ -1019,8 +1002,6 @@ void	ath_intr(void *);
 	((*(_ah)->ah_updateTxTrigLevel)((_ah), (_inc)))
 #define	ath_hal_setpower(_ah, _mode) \
 	((*(_ah)->ah_setPowerMode)((_ah), (_mode), AH_TRUE))
-#define	ath_hal_setselfgenpower(_ah, _mode) \
-	((*(_ah)->ah_setPowerMode)((_ah), (_mode), AH_FALSE))
 #define	ath_hal_keycachesize(_ah) \
 	((*(_ah)->ah_getKeyCacheSize)((_ah)))
 #define	ath_hal_keyreset(_ah, _ix) \
@@ -1249,8 +1230,6 @@ void	ath_intr(void *);
 #define	ath_hal_setintmit(_ah, _v) \
 	ath_hal_setcapability(_ah, HAL_CAP_INTMIT, \
 	HAL_CAP_INTMIT_ENABLE, _v, NULL)
-#define	ath_hal_hasmybeacon(_ah) \
-	(ath_hal_getcapability(_ah, HAL_CAP_DO_MYBEACON, 1, NULL) == HAL_OK)
 
 #define	ath_hal_hasenforcetxop(_ah) \
 	(ath_hal_getcapability(_ah, HAL_CAP_ENFORCE_TXOP, 0, NULL) == HAL_OK)
diff --git a/sys/dev/netif/ath/ath_hal/ah.c b/sys/dev/netif/ath/ath_hal/ah.c
index bbfc09b..7187d57 100644
--- a/sys/dev/netif/ath/ath_hal/ah.c
+++ b/sys/dev/netif/ath/ath_hal/ah.c
@@ -786,8 +786,6 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
 		return HAL_OK;
 	case HAL_CAP_RX_LNA_MIXING:	/* Hardware uses an RX LNA mixer to map 2 antennas to a 1 stream receiver */
 		return pCap->halRxUsingLnaMixing ? HAL_OK : HAL_ENOTSUPP;
-	case HAL_CAP_DO_MYBEACON:	/* Hardware supports filtering my-beacons */
-		return pCap->halRxDoMyBeacon ? HAL_OK : HAL_ENOTSUPP;
 	default:
 		return HAL_EINVAL;
 	}
diff --git a/sys/dev/netif/ath/ath_hal/ah.h b/sys/dev/netif/ath/ath_hal/ah.h
index 4f2d3e9..2480803 100644
--- a/sys/dev/netif/ath/ath_hal/ah.h
+++ b/sys/dev/netif/ath/ath_hal/ah.h
@@ -199,7 +199,6 @@ typedef enum {
 	HAL_CAP_SERIALISE_WAR	= 245,	/* serialise register access on PCI */
 	HAL_CAP_ENFORCE_TXOP	= 246,	/* Enforce TXOP if supported */
 	HAL_CAP_RX_LNA_MIXING	= 247,	/* RX hardware uses LNA mixing */
-	HAL_CAP_DO_MYBEACON	= 248,	/* Supports HAL_RX_FILTER_MYBEACON */
 } HAL_CAPABILITY_TYPE;
 
 /* 
@@ -405,7 +404,6 @@ typedef enum {
 	HAL_RX_FILTER_PROM	= 0x00000020,	/* Promiscuous mode */
 	HAL_RX_FILTER_PROBEREQ	= 0x00000080,	/* Allow probe request frames */
 	HAL_RX_FILTER_PHYERR	= 0x00000100,	/* Allow phy errors */
-	HAL_RX_FILTER_MYBEACON  = 0x00000200,   /* Filter beacons other than mine */
 	HAL_RX_FILTER_COMPBAR	= 0x00000400,	/* Allow compressed BAR */
 	HAL_RX_FILTER_COMP_BA	= 0x00000800,	/* Allow compressed blockack */
 	HAL_RX_FILTER_PHYRADAR	= 0x00002000,	/* Allow phy radar errors */
@@ -1299,9 +1297,6 @@ struct ath_hal {
 	uint32_t	ah_intrstate[8];	/* last int state */
 	uint32_t	ah_syncstate;		/* last sync intr state */
 
-	/* Current powerstate from HAL calls */
-	HAL_POWER_MODE	ah_powerMode;
-
 	HAL_OPS_CONFIG ah_config;
 	const HAL_RATE_TABLE *__ahdecl(*ah_getRateTable)(struct ath_hal *,
 				u_int mode);
diff --git a/sys/dev/netif/ath/ath_hal/ah_internal.h b/sys/dev/netif/ath/ath_hal/ah_internal.h
index 460c138..331093b 100644
--- a/sys/dev/netif/ath/ath_hal/ah_internal.h
+++ b/sys/dev/netif/ath/ath_hal/ah_internal.h
@@ -280,8 +280,7 @@ typedef struct {
 			halAntDivCombSupportOrg		: 1,
 			halRadioRetentionSupport	: 1,
 			halSpectralScanSupport		: 1,
-			halRxUsingLnaMixing		: 1,
-			halRxDoMyBeacon			: 1;
+			halRxUsingLnaMixing		: 1;
 
 	uint32_t	halWirelessModes;
 	uint16_t	halTotalQueues;
diff --git a/sys/dev/netif/ath/ath_hal/ah_osdep.c b/sys/dev/netif/ath/ath_hal/ah_osdep.c
index e5b27dd..75e8967 100644
--- a/sys/dev/netif/ath/ath_hal/ah_osdep.c
+++ b/sys/dev/netif/ath/ath_hal/ah_osdep.c
@@ -149,24 +149,6 @@ ath_hal_ether_sprintf(const u_int8_t *mac)
 
 #ifdef AH_DEBUG
 
-/*
- * XXX This is highly relevant only for the AR5416 and later
- * PCI/PCIe NICs.  It'll need adjustment for other hardware
- * variations.
- */
-static int
-ath_hal_reg_whilst_asleep(struct ath_hal *ah, uint32_t reg)
-{
-
-	if (reg >= 0x4000 && reg < 0x5000)
-		return (1);
-	if (reg >= 0x6000 && reg < 0x7000)
-		return (1);
-	if (reg >= 0x7000 && reg < 0x8000)
-		return (1);
-	return (0);
-}
-
 void
 DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
 {
@@ -281,13 +263,6 @@ ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
 	bus_space_tag_t tag = BUSTAG(ah);
 	bus_space_handle_t h = ah->ah_sh;
 
-	/* Debug - complain if we haven't fully waken things up */
-	if (! ath_hal_reg_whilst_asleep(ah, reg) &&
-	    ah->ah_powerMode != HAL_PM_AWAKE) {
-		ath_hal_printf(ah, "%s: reg=0x%08x, val=0x%08x, pm=%d\n",
-		    __func__, reg, val, ah->ah_powerMode);
-	}
-
 	if (ath_hal_alq) {
 		struct ale *ale = ath_hal_alq_get(ah);
 		if (ale) {
@@ -313,13 +288,6 @@ ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
 	bus_space_handle_t h = ah->ah_sh;
 	u_int32_t val;
 
-	/* Debug - complain if we haven't fully waken things up */
-	if (! ath_hal_reg_whilst_asleep(ah, reg) &&
-	    ah->ah_powerMode != HAL_PM_AWAKE) {
-		ath_hal_printf(ah, "%s: reg=0x%08x, pm=%d\n",
-		    __func__, reg, ah->ah_powerMode);
-	}
-
 	if (ah->ah_config.ah_serialise_reg_war)
 		spin_lock(&ah_regser_spin);
 	val = bus_space_read_4(tag, h, reg);
@@ -372,20 +340,6 @@ ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
 	bus_space_tag_t tag = BUSTAG(ah);
 	bus_space_handle_t h = ah->ah_sh;
 
-	/* Debug - complain if we haven't fully waken things up */
-	if (! ath_hal_reg_whilst_asleep(ah, reg) &&
-	    ah->ah_powerMode != HAL_PM_AWAKE) {
-		ath_hal_printf(ah, "%s: reg=0x%08x, val=0x%08x, pm=%d\n",
-		    __func__, reg, val, ah->ah_powerMode);
-	}
-
-	/* Debug - complain if we haven't fully waken things up */
-	if (! ath_hal_reg_whilst_asleep(ah, reg) &&
-	    ah->ah_powerMode != HAL_PM_AWAKE) {
-		ath_hal_printf(ah, "%s: reg=0x%08x, pm=%d\n",
-		    __func__, reg, ah->ah_powerMode);
-	}
-
 	if (ah->ah_config.ah_serialise_reg_war)
 		spin_lock(&ah_regser_spin);
 	bus_space_write_4(tag, h, reg, val);
diff --git a/sys/dev/netif/ath/ath_hal/ah_regdomain.c b/sys/dev/netif/ath/ath_hal/ah_regdomain.c
index c699448..e871cd7 100644
--- a/sys/dev/netif/ath/ath_hal/ah_regdomain.c
+++ b/sys/dev/netif/ath/ath_hal/ah_regdomain.c
@@ -169,11 +169,6 @@ isEepromValid(struct ath_hal *ah)
 			if (regDomainPairs[i].regDmnEnum == rd)
 				return AH_TRUE;
 	}
-
-	if (rd == FCC_UBNT) {
-		return AH_TRUE;
-	}
-
 	HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
 	    "%s: invalid regulatory domain/country code 0x%x\n", __func__, rd);
 	return AH_FALSE;
diff --git a/sys/dev/netif/ath/ath_hal/ah_regdomain/ah_rd_regenum.h b/sys/dev/netif/ath/ath_hal/ah_regdomain/ah_rd_regenum.h
index d8d211e..bc569cb 100644
--- a/sys/dev/netif/ath/ath_hal/ah_regdomain/ah_rd_regenum.h
+++ b/sys/dev/netif/ath/ath_hal/ah_regdomain/ah_rd_regenum.h
@@ -51,7 +51,6 @@ enum {
 	FCC2_FCCA	= 0x20,		/* Canada */
 	FCC2_WORLD	= 0x21,		/* Australia & HK */
 	FCC2_ETSIC	= 0x22,
-	FCC_UBNT	= 0x2A,		/* Ubiquity PicoStation M2HP */
 	FRANCE_RES	= 0x31,		/* Legacy France for OEM */
 	FCC3_FCCA	= 0x3A,		/* USA & Canada w/5470 band, 11h, DFS enabled */
 	FCC3_WORLD	= 0x3B,		/* USA & Canada w/5470 band, 11h, DFS enabled */
diff --git a/sys/dev/netif/ath/ath_hal/ar5210/ar5210.h b/sys/dev/netif/ath/ath_hal/ar5210/ar5210.h
index 3e372f7..48ccc20 100644
--- a/sys/dev/netif/ath/ath_hal/ar5210/ar5210.h
+++ b/sys/dev/netif/ath/ath_hal/ar5210/ar5210.h
@@ -108,6 +108,7 @@ struct ath_hal_5210 {
 	uint32_t	ah_txDescInterruptMask;
 	uint32_t	ah_txEolInterruptMask;
 	uint32_t	ah_txUrnInterruptMask;
+	HAL_POWER_MODE	ah_powerMode;
 	uint8_t		ah_bssid[IEEE80211_ADDR_LEN];
 	HAL_TX_QUEUE_INFO ah_txq[HAL_NUM_TX_QUEUES]; /* beacon+cab+data */
 	/*
@@ -120,8 +121,6 @@ struct ath_hal_5210 {
 	u_int		ah_slottime;		/* user-specified slot time */
 	u_int		ah_acktimeout;		/* user-specified ack timeout */
 	u_int		ah_ctstimeout;		/* user-specified cts timeout */
-
-	uint16_t	ah_associd;		/* association id */
 };
 #define	AH5210(ah)	((struct ath_hal_5210 *)(ah))
 
diff --git a/sys/dev/netif/ath/ath_hal/ar5210/ar5210_attach.c b/sys/dev/netif/ath/ath_hal/ar5210/ar5210_attach.c
index ee11ce9..3c0ed71 100644
--- a/sys/dev/netif/ath/ath_hal/ar5210/ar5210_attach.c
+++ b/sys/dev/netif/ath/ath_hal/ar5210/ar5210_attach.c
@@ -219,7 +219,7 @@ ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh,
 	AH_PRIVATE(ah)->ah_powerLimit = AR5210_MAX_RATE_POWER;
 	AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX;	/* no scaling */
 
-	ah->ah_powerMode = HAL_PM_UNDEFINED;
+	ahp->ah_powerMode = HAL_PM_UNDEFINED;
 	ahp->ah_staId1Defaults = 0;
 	ahp->ah_rssiThr = INIT_RSSI_THR;
 	ahp->ah_sifstime = (u_int) -1;
diff --git a/sys/dev/netif/ath/ath_hal/ar5210/ar5210_misc.c b/sys/dev/netif/ath/ath_hal/ar5210/ar5210_misc.c
index 5eaa18e..8170880 100644
--- a/sys/dev/netif/ath/ath_hal/ar5210/ar5210_misc.c
+++ b/sys/dev/netif/ath/ath_hal/ar5210/ar5210_misc.c
@@ -315,7 +315,6 @@ ar5210WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId)
 
 	/* XXX save bssid for possible re-use on reset */
 	OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN);
-	ahp->ah_associd = assocId;
 	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
 	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) |
 				     ((assocId & 0x3fff)<<AR_BSS_ID1_AID_S));
diff --git a/sys/dev/netif/ath/ath_hal/ar5210/ar5210_power.c b/sys/dev/netif/ath/ath_hal/ar5210/ar5210_power.c
index ec5e75d..1c6909b 100644
--- a/sys/dev/netif/ath/ath_hal/ar5210/ar5210_power.c
+++ b/sys/dev/netif/ath/ath_hal/ar5210/ar5210_power.c
@@ -93,6 +93,7 @@ ar5210SetPowerModeSleep(struct ath_hal *ah, int setChip)
 HAL_BOOL
 ar5210SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 {
+	struct ath_hal_5210 *ahp = AH5210(ah);
 #ifdef AH_DEBUG
 	static const char* modes[] = {
 		"AWAKE",
@@ -104,30 +105,25 @@ ar5210SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 	int status = AH_TRUE;
 
 	HALDEBUG(ah, HAL_DEBUG_POWER, "%s: %s -> %s (%s)\n", __func__,
-		modes[ah->ah_powerMode], modes[mode],
+		modes[ahp->ah_powerMode], modes[mode],
 		setChip ? "set chip " : "");
 	switch (mode) {
 	case HAL_PM_AWAKE:
-		if (setChip)
-			ah->ah_powerMode = mode;
 		status = ar5210SetPowerModeAwake(ah, setChip);
 		break;
 	case HAL_PM_FULL_SLEEP:
 		ar5210SetPowerModeSleep(ah, setChip);
-		if (setChip)
-			ah->ah_powerMode = mode;
 		break;
 	case HAL_PM_NETWORK_SLEEP:
 		ar5210SetPowerModeAuto(ah, setChip);
-		if (setChip)
-			ah->ah_powerMode = mode;
 		break;
 	default:
 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown power mode %u\n",
 		    __func__, mode);
 		return AH_FALSE;
 	}
-	return status;
+	ahp->ah_powerMode = mode;
+	return status; 
 }
 
 HAL_POWER_MODE
diff --git a/sys/dev/netif/ath/ath_hal/ar5210/ar5210_reset.c b/sys/dev/netif/ath/ath_hal/ar5210/ar5210_reset.c
index 1dba729..1d50f99 100644
--- a/sys/dev/netif/ath/ath_hal/ar5210/ar5210_reset.c
+++ b/sys/dev/netif/ath/ath_hal/ar5210/ar5210_reset.c
@@ -152,12 +152,8 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
 	/* Restore previous led state */
 	OS_REG_WRITE(ah, AR_PCICFG, OS_REG_READ(ah, AR_PCICFG) | ledstate);
 
-#if 0
 	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
 	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));
-#endif
-	/* BSSID, association id, ps-poll */
-	ar5210WriteAssocid(ah, ahp->ah_bssid, ahp->ah_associd);
 
 	OS_REG_WRITE(ah, AR_TXDP0, 0);
 	OS_REG_WRITE(ah, AR_TXDP1, 0);
diff --git a/sys/dev/netif/ath/ath_hal/ar5211/ar5211.h b/sys/dev/netif/ath/ath_hal/ar5211/ar5211.h
index 6f04624..c50531e 100644
--- a/sys/dev/netif/ath/ath_hal/ar5211/ar5211.h
+++ b/sys/dev/netif/ath/ath_hal/ar5211/ar5211.h
@@ -119,6 +119,7 @@ struct ath_hal_5211 {
 	uint32_t	ah_txEolInterruptMask;
 	uint32_t	ah_txUrnInterruptMask;
 	HAL_TX_QUEUE_INFO ah_txq[HAL_NUM_TX_QUEUES];
+	HAL_POWER_MODE	ah_powerMode;
 	HAL_ANT_SETTING ah_diversityControl;	/* antenna setting */
 	uint32_t	ah_calibrationTime;
 	HAL_BOOL	ah_bIQCalibration;
diff --git a/sys/dev/netif/ath/ath_hal/ar5211/ar5211_power.c b/sys/dev/netif/ath/ath_hal/ar5211/ar5211_power.c
index e646d90..776cfb3 100644
--- a/sys/dev/netif/ath/ath_hal/ar5211/ar5211_power.c
+++ b/sys/dev/netif/ath/ath_hal/ar5211/ar5211_power.c
@@ -95,6 +95,7 @@ ar5211SetPowerModeNetworkSleep(struct ath_hal *ah, int setChip)
 HAL_BOOL
 ar5211SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 {
+	struct ath_hal_5211 *ahp = AH5211(ah);
 #ifdef AH_DEBUG
 	static const char* modes[] = {
 		"AWAKE",
@@ -106,30 +107,25 @@ ar5211SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 	int status = AH_TRUE;
 
 	HALDEBUG(ah, HAL_DEBUG_POWER, "%s: %s -> %s (%s)\n", __func__,
-		modes[ah->ah_powerMode], modes[mode],
+		modes[ahp->ah_powerMode], modes[mode],
 		setChip ? "set chip " : "");
 	switch (mode) {
 	case HAL_PM_AWAKE:
-		if (setChip)
-			ah->ah_powerMode = mode;
 		status = ar5211SetPowerModeAwake(ah, setChip);
 		break;
 	case HAL_PM_FULL_SLEEP:
 		ar5211SetPowerModeSleep(ah, setChip);
-		if (setChip)
-			ah->ah_powerMode = mode;
 		break;
 	case HAL_PM_NETWORK_SLEEP:
 		ar5211SetPowerModeNetworkSleep(ah, setChip);
-		if (setChip)
-			ah->ah_powerMode = mode;
 		break;
 	default:
 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown power mode %u\n",
 		    __func__, mode);
 		return AH_FALSE;
 	}
-	return status;
+	ahp->ah_powerMode = mode;
+	return status; 
 }
 
 HAL_POWER_MODE
diff --git a/sys/dev/netif/ath/ath_hal/ar5212/ar5212.h b/sys/dev/netif/ath/ath_hal/ar5212/ar5212.h
index 8086e71..6d38d65 100644
--- a/sys/dev/netif/ath/ath_hal/ar5212/ar5212.h
+++ b/sys/dev/netif/ath/ath_hal/ar5212/ar5212.h
@@ -270,6 +270,7 @@ struct ath_hal_5212 {
 	uint32_t	ah_intrTxqs;		/* tx q interrupt state */
 						/* decomp mask array */
 	uint8_t		ah_decompMask[HAL_DECOMP_MASK_SIZE];
+	HAL_POWER_MODE	ah_powerMode;
 	HAL_ANT_SETTING ah_antControl;		/* antenna setting */
 	HAL_BOOL	ah_diversity;		/* fast diversity setting */
 	enum {
diff --git a/sys/dev/netif/ath/ath_hal/ar5212/ar5212_power.c b/sys/dev/netif/ath/ath_hal/ar5212/ar5212_power.c
index 3068510..3f755bd 100644
--- a/sys/dev/netif/ath/ath_hal/ar5212/ar5212_power.c
+++ b/sys/dev/netif/ath/ath_hal/ar5212/ar5212_power.c
@@ -119,6 +119,7 @@ ar5212SetPowerModeNetworkSleep(struct ath_hal *ah, int setChip)
 HAL_BOOL
 ar5212SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 {
+	struct ath_hal_5212 *ahp = AH5212(ah);
 #ifdef AH_DEBUG
 	static const char* modes[] = {
 		"AWAKE",
@@ -130,29 +131,24 @@ ar5212SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 	int status = AH_TRUE;
 
 	HALDEBUG(ah, HAL_DEBUG_POWER, "%s: %s -> %s (%s)\n", __func__,
-		modes[ah->ah_powerMode], modes[mode],
+		modes[ahp->ah_powerMode], modes[mode],
 		setChip ? "set chip " : "");
 	switch (mode) {
 	case HAL_PM_AWAKE:
-		if (setChip)
-			ah->ah_powerMode = mode;
 		status = ar5212SetPowerModeAwake(ah, setChip);
 		break;
 	case HAL_PM_FULL_SLEEP:
 		ar5212SetPowerModeSleep(ah, setChip);
-		if (setChip)
-			ah->ah_powerMode = mode;
 		break;
 	case HAL_PM_NETWORK_SLEEP:
 		ar5212SetPowerModeNetworkSleep(ah, setChip);
-		if (setChip)
-			ah->ah_powerMode = mode;
 		break;
 	default:
 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown power mode %u\n",
 		    __func__, mode);
 		return AH_FALSE;
 	}
+	ahp->ah_powerMode = mode;
 	return status;
 }
 
diff --git a/sys/dev/netif/ath/ath_hal/ar5312/ar5312_power.c b/sys/dev/netif/ath/ath_hal/ar5312/ar5312_power.c
index 7db6d80..94a0f1c 100644
--- a/sys/dev/netif/ath/ath_hal/ar5312/ar5312_power.c
+++ b/sys/dev/netif/ath/ath_hal/ar5312/ar5312_power.c
@@ -71,6 +71,7 @@ ar5312SetPowerModeNetworkSleep(struct ath_hal *ah, int setChip)
 HAL_BOOL
 ar5312SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 {
+	struct ath_hal_5212 *ahp = AH5212(ah);
 #ifdef AH_DEBUG
 	static const char* modes[] = {
 		"AWAKE",
@@ -82,7 +83,7 @@ ar5312SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 	int status = AH_TRUE;
 
 	HALDEBUG(ah, HAL_DEBUG_POWER, "%s: %s -> %s (%s)\n", __func__,
-		modes[ah->ah_powerMode], modes[mode],
+		modes[ahp->ah_powerMode], modes[mode],
 		setChip ? "set chip " : "");
 	switch (mode) {
 	case HAL_PM_AWAKE:
@@ -99,7 +100,7 @@ ar5312SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 		    __func__, mode);
 		return AH_FALSE;
 	}
-	ah->ah_powerMode = mode;
+	ahp->ah_powerMode = mode;
 	return status; 
 }
 
diff --git a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_attach.c
index bdc6111..99bab06 100644
--- a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_attach.c
+++ b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_attach.c
@@ -1059,11 +1059,6 @@ ar5416FillCapabilityInfo(struct ath_hal *ah)
 	if (! AH_PRIVATE(ah)->ah_ispcie)
 		pCap->halSerialiseRegWar = 1;
 
-	/*
-	 * AR5416 and later NICs support MYBEACON filtering.
-	 */
-	pCap->halRxDoMyBeacon = AH_TRUE;
-
 	return AH_TRUE;
 }
 
diff --git a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_beacon.c b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_beacon.c
index 6691c11..e2bf6c7 100644
--- a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_beacon.c
+++ b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_beacon.c
@@ -197,25 +197,6 @@ ar5416SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *bs)
 	 *   beacon jitter; cab timeout is max time to wait for cab
 	 *   after seeing the last DTIM or MORE CAB bit
 	 */
-
-/*
- * I've bumped these to 30TU for now.
- *
- * Some APs (AR933x/AR934x?) in 2GHz especially seem to not always
- * transmit beacon frames at exactly the right times and with it set
- * to 10TU, the NIC starts not waking up at the right times to hear
- * these slightly-larger-jitering beacons.  It also never recovers
- * from that (it doesn't resync? I'm not sure.)
- *
- * So for now bump this to 30TU.  Ideally we'd cap this based on
- * the beacon interval so the sum of CAB+BEACON timeouts never
- * exceeded the beacon interval.
- *
- * Now, since we're doing all the math in the ath(4) driver in TU
- * rather than TSF, we may be seeing the result of dumb rounding
- * errors causing the jitter to actually be a much bigger problem.
- * I'll have to investigate that with a fine tooth comb.
- */
 #define CAB_TIMEOUT_VAL     10 /* in TU */
 #define BEACON_TIMEOUT_VAL  10 /* in TU */
 #define SLEEP_SLOP          3  /* in TU */
@@ -267,13 +248,6 @@ ar5416SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *bs)
 
 	OS_REG_SET_BIT(ah, AR_TIMER_MODE,
 	     AR_TIMER_MODE_TBTT | AR_TIMER_MODE_TIM | AR_TIMER_MODE_DTIM);
-
-#define	HAL_TSFOOR_THRESHOLD	0x00004240 /* TSF OOR threshold (16k us) */
-
-	/* TSF out of range threshold */
-//	OS_REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
-	OS_REG_WRITE(ah, AR_TSFOOR_THRESHOLD, HAL_TSFOOR_THRESHOLD);
-
 	HALDEBUG(ah, HAL_DEBUG_BEACON, "%s: next DTIM %d\n",
 	    __func__, bs->bs_nextdtim);
 	HALDEBUG(ah, HAL_DEBUG_BEACON, "%s: next beacon %d\n",
diff --git a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_interrupts.c b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_interrupts.c
index 32ce2ed..631ca2f 100644
--- a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_interrupts.c
+++ b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_interrupts.c
@@ -337,9 +337,6 @@ ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints)
 	/* Write the new IMR and store off our SW copy. */
 	HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask);
 	OS_REG_WRITE(ah, AR_IMR, mask);
-	/* Flush write */
-	(void) OS_REG_READ(ah, AR_IMR);
-
 	mask = OS_REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
 					AR_IMR_S2_DTIM |
 					AR_IMR_S2_DTIMSYNC |
diff --git a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_power.c b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_power.c
index dff9a85..43a9241 100644
--- a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_power.c
+++ b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_power.c
@@ -124,6 +124,7 @@ ar5416SetPowerModeNetworkSleep(struct ath_hal *ah, int setChip)
 HAL_BOOL
 ar5416SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 {
+	struct ath_hal_5212 *ahp = AH5212(ah);
 #ifdef AH_DEBUG
 	static const char* modes[] = {
 		"AWAKE",
@@ -133,35 +134,27 @@ ar5416SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip)
 	};
 #endif
 	int status = AH_TRUE;
-
-#if 0
 	if (!setChip)
 		return AH_TRUE;
-#endif
 
 	HALDEBUG(ah, HAL_DEBUG_POWER, "%s: %s -> %s (%s)\n", __func__,
-	    modes[ah->ah_powerMode], modes[mode], setChip ? "set chip " : "");
+	    modes[ahp->ah_powerMode], modes[mode], setChip ? "set chip " : "");
 	switch (mode) {
 	case HAL_PM_AWAKE:
-		if (setChip)
-			ah->ah_powerMode = mode;
 		status = ar5416SetPowerModeAwake(ah, setChip);
 		break;
 	case HAL_PM_FULL_SLEEP:
 		ar5416SetPowerModeSleep(ah, setChip);
-		if (setChip)
-			ah->ah_powerMode = mode;
 		break;
 	case HAL_PM_NETWORK_SLEEP:
 		ar5416SetPowerModeNetworkSleep(ah, setChip);
-		if (setChip)
-			ah->ah_powerMode = mode;
 		break;
 	default:
 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown power mode 0x%x\n",
 		    __func__, mode);
 		return AH_FALSE;
 	}
+	ahp->ah_powerMode = mode;
 	return status;
 }
 
diff --git a/sys/dev/netif/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/netif/ath/ath_hal/ar5416/ar5416reg.h
index 29b84b1..2602353 100644
--- a/sys/dev/netif/ath/ath_hal/ar5416/ar5416reg.h
+++ b/sys/dev/netif/ath/ath_hal/ar5416/ar5416reg.h
@@ -476,10 +476,10 @@
 /* Sleep control */
 #define	AR5416_SLEEP1_ASSUME_DTIM	0x00080000
 #define	AR5416_SLEEP1_CAB_TIMEOUT	0xFFE00000	/* Cab timeout (TU) */
-#define	AR5416_SLEEP1_CAB_TIMEOUT_S	21
+#define	AR5416_SLEEP1_CAB_TIMEOUT_S	22
 
 #define	AR5416_SLEEP2_BEACON_TIMEOUT	0xFFE00000	/* Beacon timeout (TU)*/
-#define	AR5416_SLEEP2_BEACON_TIMEOUT_S	21
+#define	AR5416_SLEEP2_BEACON_TIMEOUT_S	22
 
 /* Sleep Registers */
 #define	AR_SLP32_HALFCLK_LATENCY      0x000FFFFF	/* rising <-> falling edge */
diff --git a/sys/netproto/802_11/ieee80211_power.h b/sys/netproto/802_11/ieee80211_power.h
index c23cf24..11d1737 100644
--- a/sys/netproto/802_11/ieee80211_power.h
+++ b/sys/netproto/802_11/ieee80211_power.h
@@ -73,9 +73,6 @@ int	ieee80211_node_psq_age(struct ieee80211_node *);
 int	ieee80211_pwrsave(struct ieee80211_node *, struct mbuf *);
 void	ieee80211_node_pwrsave(struct ieee80211_node *, int enable);
 void	ieee80211_sta_pwrsave(struct ieee80211vap *, int enable);
-void	ieee80211_sta_tim_notify(struct ieee80211vap *vap, int set);
-void	ieee80211_sta_ps_timer_check(struct ieee80211vap *vap);
 
-/* XXX what's this? */
 void	ieee80211_power_poll(struct ieee80211com *);
 #endif /* _NET80211_IEEE80211_POWER_H_ */
diff --git a/sys/netproto/802_11/ieee80211_proto.h b/sys/netproto/802_11/ieee80211_proto.h
index b61f6d4..198dfd0 100644
--- a/sys/netproto/802_11/ieee80211_proto.h
+++ b/sys/netproto/802_11/ieee80211_proto.h
@@ -290,8 +290,6 @@ void	ieee80211_dturbo_switch(struct ieee80211vap *, int newflags);
 void	ieee80211_swbmiss_callout(void *arg);
 void	ieee80211_beacon_miss(struct ieee80211com *);
 int	ieee80211_new_state(struct ieee80211vap *, enum ieee80211_state, int);
-int     ieee80211_new_state_locked(struct ieee80211vap *, enum ieee80211_state,
-		int);
 void	ieee80211_print_essid(const uint8_t *, int);
 void	ieee80211_dump_pkt(struct ieee80211com *,
 		const uint8_t *, int, int, int);
diff --git a/sys/netproto/802_11/ieee80211_var.h b/sys/netproto/802_11/ieee80211_var.h
index f16c97a..05a871f 100644
--- a/sys/netproto/802_11/ieee80211_var.h
+++ b/sys/netproto/802_11/ieee80211_var.h
@@ -469,8 +469,6 @@ struct ieee80211vap {
 	/* power save handling */
 	void			(*iv_update_ps)(struct ieee80211vap *, int);
 	int			(*iv_set_tim)(struct ieee80211_node *, int);
-	void			(*iv_node_ps)(struct ieee80211_node *, int);
-	void			(*iv_sta_ps)(struct ieee80211vap *, int);
 	/* state machine processing */
 	int			(*iv_newstate)(struct ieee80211vap *,
 				    enum ieee80211_state, int);
@@ -603,7 +601,6 @@ MALLOC_DECLARE(M_80211_VAP);
 #define	IEEE80211_C_MONITOR	0x00010000	/* CAPABILITY: monitor mode */
 #define	IEEE80211_C_DFS		0x00020000	/* CAPABILITY: DFS/radar avail*/
 #define	IEEE80211_C_MBSS	0x00040000	/* CAPABILITY: MBSS available */
-#define IEEE80211_C_SWSLEEP	0x00080000	/* CAPABILITY: do sleep here */
 /* 0x7c0000 available */
 #define	IEEE80211_C_WPA1	0x00800000	/* CAPABILITY: WPA1 avail */
 #define	IEEE80211_C_WPA2	0x01000000	/* CAPABILITY: WPA2 avail */
diff --git a/sys/netproto/802_11/wlan/ieee80211.c b/sys/netproto/802_11/wlan/ieee80211.c
index f7bed22..5fea668 100644
--- a/sys/netproto/802_11/wlan/ieee80211.c
+++ b/sys/netproto/802_11/wlan/ieee80211.c
@@ -1359,8 +1359,7 @@ ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
 	 * rate only when running; otherwise we may have a mismatch
 	 * in which case the rate will not be convertible.
 	 */
-	if (vap->iv_state == IEEE80211_S_RUN ||
-	    vap->iv_state == IEEE80211_S_SLEEP) {
+	if (vap->iv_state == IEEE80211_S_RUN) {
 		imr->ifm_status |= IFM_ACTIVE;
 		mode = ieee80211_chan2mode(ic->ic_curchan);
 	} else
diff --git a/sys/netproto/802_11/wlan/ieee80211_ioctl.c b/sys/netproto/802_11/wlan/ieee80211_ioctl.c
index 80e98a3..15a2815 100644
--- a/sys/netproto/802_11/wlan/ieee80211_ioctl.c
+++ b/sys/netproto/802_11/wlan/ieee80211_ioctl.c
@@ -600,7 +600,7 @@ ieee80211_ioctl_getcurchan(struct ieee80211vap *vap, struct ieee80211req *ireq)
 	 * in use.  When in RUN state report the vap-specific channel.
 	 * Otherwise return curchan.
 	 */
-	if (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)
+	if (vap->iv_state == IEEE80211_S_RUN)
 		c = vap->iv_bss->ni_chan;
 	else
 		c = ic->ic_curchan;
@@ -919,7 +919,7 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
 	case IEEE80211_IOC_BSSID:
 		if (ireq->i_len != IEEE80211_ADDR_LEN)
 			return EINVAL;
-		if (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP) {
+		if (vap->iv_state == IEEE80211_S_RUN) {
 			error = copyout(vap->iv_opmode == IEEE80211_M_WDS ?
 			    vap->iv_bss->ni_macaddr : vap->iv_bss->ni_bssid,
 			    ireq->i_data, ireq->i_len);
@@ -1010,7 +1010,7 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
 	case IEEE80211_IOC_AMPDU_LIMIT:
 		if (vap->iv_opmode == IEEE80211_M_HOSTAP)
 			ireq->i_val = vap->iv_ampdu_rxmax;
-		else if (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)
+		else if (vap->iv_state == IEEE80211_S_RUN)
 			ireq->i_val = MS(vap->iv_bss->ni_htparam,
 			    IEEE80211_HTCAP_MAXRXAMPDU);
 		else
@@ -1018,7 +1018,7 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
 		break;
 	case IEEE80211_IOC_AMPDU_DENSITY:
 		if (vap->iv_opmode == IEEE80211_M_STA &&
-		    (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP))
+		    vap->iv_state == IEEE80211_S_RUN)
 			ireq->i_val = MS(vap->iv_bss->ni_htparam,
 			    IEEE80211_HTCAP_MPDUDENSITY);
 		else
@@ -1092,7 +1092,7 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
 		break;
 	case IEEE80211_IOC_SMPS:
 		if (vap->iv_opmode == IEEE80211_M_STA &&
-		    (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)) {
+		    vap->iv_state == IEEE80211_S_RUN) {
 			if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_RTS)
 				ireq->i_val = IEEE80211_HTCAP_SMPS_DYNAMIC;
 			else if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_PS)
@@ -1104,7 +1104,7 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
 		break;
 	case IEEE80211_IOC_RIFS:
 		if (vap->iv_opmode == IEEE80211_M_STA &&
-		    (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP))
+		    vap->iv_state == IEEE80211_S_RUN)
 			ireq->i_val =
 			    (vap->iv_bss->ni_flags & IEEE80211_NODE_RIFS) != 0;
 		else
@@ -1858,7 +1858,7 @@ setcurchan(struct ieee80211vap *vap, struct ieee80211_channel *c)
 			if (IEEE80211_IS_CHAN_NOADHOC(c))
 				return EINVAL;
 		}
-		if ((vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP) &&
+		if (vap->iv_state == IEEE80211_S_RUN &&
 		    vap->iv_bss->ni_chan == c)
 			return 0;	/* NB: nothing to do */
 	}
diff --git a/sys/netproto/802_11/wlan/ieee80211_output.c b/sys/netproto/802_11/wlan/ieee80211_output.c
index 82c268e..5b02b20 100644
--- a/sys/netproto/802_11/wlan/ieee80211_output.c
+++ b/sys/netproto/802_11/wlan/ieee80211_output.c
@@ -135,17 +135,23 @@ ieee80211_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
 		ifsq_purge(ifsq);
 		return;
 	}
+	if (vap->iv_state == IEEE80211_S_SLEEP) {
+		/*
+		 * In power save, wakeup device for transmit.
+		 */
+		ieee80211_new_state(vap, IEEE80211_S_RUN, 0);
+		ifsq_purge(ifsq);
+		return;
+	}
 	/*
 	 * No data frames go out unless we're running.
 	 * Note in particular this covers CAC and CSA
 	 * states (though maybe we should check muting
 	 * for CSA).
 	 */
-	if (vap->iv_state != IEEE80211_S_RUN &&
-	    vap->iv_state != IEEE80211_S_SLEEP) {
+	if (vap->iv_state != IEEE80211_S_RUN) {
 		/* re-check under the com lock to avoid races */
-		if (vap->iv_state != IEEE80211_S_RUN &&
-		    vap->iv_state != IEEE80211_S_SLEEP) {
+		if (vap->iv_state != IEEE80211_S_RUN) {
 			IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
 			    "%s: ignore queue, in %s state\n",
 			    __func__, ieee80211_state_name[vap->iv_state]);
@@ -264,21 +270,6 @@ ieee80211_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
 			}
 		}
 #endif
-		/*
-		 * We've resolved the sender, so attempt to transmit it.
-		 */
-		if (vap->iv_state == IEEE80211_S_SLEEP) {
-			/*
-			 * In power save; queue frame and then  wakeup device
-			 * for transmit.
-			 */
-			ic->ic_lastdata = ticks;
-			(void) ieee80211_pwrsave(ni, m);
-			ieee80211_free_node(ni);
-			ieee80211_new_state(vap, IEEE80211_S_RUN, 0);
-			continue;
-		}
-
 		if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
 		    (m->m_flags & M_PWR_SAV) == 0) {
 			/*
diff --git a/sys/netproto/802_11/wlan/ieee80211_power.c b/sys/netproto/802_11/wlan/ieee80211_power.c
index 044bee6..2fdbf4d 100644
--- a/sys/netproto/802_11/wlan/ieee80211_power.c
+++ b/sys/netproto/802_11/wlan/ieee80211_power.c
@@ -70,8 +70,6 @@ ieee80211_power_vattach(struct ieee80211vap *vap)
 		vap->iv_update_ps = ieee80211_update_ps;
 		vap->iv_set_tim = ieee80211_set_tim;
 	}
-	vap->iv_node_ps = ieee80211_node_pwrsave;
-	vap->iv_sta_ps = ieee80211_sta_pwrsave;
 }
 
 void
@@ -541,87 +539,3 @@ ieee80211_sta_pwrsave(struct ieee80211vap *vap, int enable)
 		ieee80211_send_nulldata(ieee80211_ref_node(ni));
 	}
 }
-
-/*
- * Handle being notified that we have data available for us in a TIM/ATIM.
- *
- * This may schedule a transition from _SLEEP -> _RUN if it's appropriate.
- */
-void
-ieee80211_sta_tim_notify(struct ieee80211vap *vap, int set)
-{
-	/*
-	 * Schedule the driver state change.  It'll happen at some point soon.
-	 * Since the hardware shouldn't know that we're running just yet
-	 * (and thus tell the peer that we're awake before we actually wake
-	 * up said hardware), we leave the actual node state transition
-	 * up to the transition to RUN.
-	 *
-	 * XXX TODO: verify that the transition to RUN will wake up the
-	 * BSS node!
-	 */
-	IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, "%s: TIM=%d\n", __func__, set);
-	if (set == 1 && vap->iv_state == IEEE80211_S_SLEEP) {
-		ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0);
-	}
-}
-
-/*
- * Timer check on whether the VAP has had any transmit activity.
- *
- * This may schedule a transition from _RUN -> _SLEEP if it's appropriate.
- */
-void
-ieee80211_sta_ps_timer_check(struct ieee80211vap *vap)
-{
-	struct ieee80211com *ic = vap->iv_ic;
-
-	/* XXX lock assert */
-
-	/* For no, only do this in STA mode */
-	if (! (vap->iv_caps & IEEE80211_C_SWSLEEP))
-		goto out;
-
-	if (vap->iv_opmode != IEEE80211_M_STA)
-		goto out;
-
-	/* If we're not at run state, bail */
-	if (vap->iv_state != IEEE80211_S_RUN)
-		goto out;
-
-	IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER,
-	    "%s: lastdata=%llu, ticks=%llu\n",
-	    __func__, (unsigned long long) ic->ic_lastdata,
-	    (unsigned long long) ticks);
-
-	/* If powersave is disabled on the VAP, don't bother */
-	if (! (vap->iv_flags & IEEE80211_F_PMGTON))
-		goto out;
-
-	/* If we've done any data within our idle interval, bail */
-	/* XXX hard-coded to one second for now, ew! */
-	if (time_after(ic->ic_lastdata + 500, ticks))
-		goto out;
-
-	/*
-	 * Signify we're going into power save and transition the
-	 * node to powersave.
-	 */
-	if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0)
-		vap->iv_sta_ps(vap, 1);
-
-	/*
-	 * XXX The driver has to handle the fact that we're going
-	 * to sleep but frames may still be transmitted;
-	 * hopefully it and/or us will do the right thing and mark any
-	 * transmitted frames with PWRMGT set to 1.
-	 */
-	ieee80211_new_state_locked(vap, IEEE80211_S_SLEEP, 0);
-
-	IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER,
-	    "%s: time delta=%d msec\n", __func__,
-	    (int) ticks_to_msecs(ticks - ic->ic_lastdata));
-
-out:
-	return;
-}
diff --git a/sys/netproto/802_11/wlan/ieee80211_proto.c b/sys/netproto/802_11/wlan/ieee80211_proto.c
index a9b782e..12443e7 100644
--- a/sys/netproto/802_11/wlan/ieee80211_proto.c
+++ b/sys/netproto/802_11/wlan/ieee80211_proto.c
@@ -106,6 +106,8 @@ static void update_mcast_task(void *, int);
 static void update_promisc_task(void *, int);
 static void update_channel_task(void *, int);
 static void ieee80211_newstate_task(void *, int);
+static int ieee80211_new_state_locked(struct ieee80211vap *,
+	enum ieee80211_state, int);
 
 static int
 null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
@@ -1706,7 +1708,7 @@ done:
  * is usually a mistake and indicates lack of proper integration
  * with the net80211 layer.
  */
-int
+static int
 ieee80211_new_state_locked(struct ieee80211vap *vap,
 	enum ieee80211_state nstate, int arg)
 {
diff --git a/sys/netproto/802_11/wlan/ieee80211_sta.c b/sys/netproto/802_11/wlan/ieee80211_sta.c
index d62d56a..8c25c96 100644
--- a/sys/netproto/802_11/wlan/ieee80211_sta.c
+++ b/sys/netproto/802_11/wlan/ieee80211_sta.c
@@ -225,7 +225,6 @@ sta_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 		switch (ostate) {
 		case IEEE80211_S_SLEEP:
 			/* XXX wakeup */
-			/* XXX driver hook to wakeup the hardware? */
 		case IEEE80211_S_RUN:
 			IEEE80211_SEND_MGMT(ni,
 			    IEEE80211_FC0_SUBTYPE_DISASSOC,
@@ -291,18 +290,12 @@ sta_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 			if (vap->iv_roaming == IEEE80211_ROAMING_AUTO)
 				ieee80211_check_scan_current(vap);
 			break;
-		case IEEE80211_S_SLEEP:		/* beacon miss */
-			/*
-			 * XXX if in sleep we need to wakeup the hardware.
-			 */
-			/* FALLTHROUGH */
 		case IEEE80211_S_RUN:		/* beacon miss */
 			/*
 			 * Beacon miss.  Notify user space and if not
 			 * under control of a user application (roaming
 			 * manual) kick off a scan to re-connect.
 			 */
-
 			ieee80211_sta_leave(ni);
 			if (vap->iv_roaming == IEEE80211_ROAMING_AUTO)
 				ieee80211_check_scan_current(vap);
@@ -401,8 +394,7 @@ sta_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 			    arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
 			break;
 		case IEEE80211_S_SLEEP:
-			/* Wake up from sleep */
-			vap->iv_sta_ps(vap, 0);
+			ieee80211_sta_pwrsave(vap, 0);
 			break;
 		default:
 			goto invalid;
@@ -429,11 +421,9 @@ sta_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 			ieee80211_node_authorize(ni);
 		/*
 		 * Fake association when joining an existing bss.
-		 *
-		 * Don't do this if we're doing SLEEP->RUN.
 		 */
-		if (ic->ic_newassoc != NULL && ostate != IEEE80211_S_SLEEP)
-			ic->ic_newassoc(vap->iv_bss, (ostate != IEEE80211_S_RUN));
+		if (ic->ic_newassoc != NULL)
+			ic->ic_newassoc(vap->iv_bss, ostate != IEEE80211_S_RUN);
 		break;
 	case IEEE80211_S_CSA:
 		if (ostate != IEEE80211_S_RUN)
@@ -1351,40 +1341,23 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
 				    scan.htcap, scan.htinfo);
 				/* XXX state changes? */
 			}
-
 			if (scan.tim != NULL) {
 				struct ieee80211_tim_ie *tim =
 				    (struct ieee80211_tim_ie *) scan.tim;
-				/*
-				 * XXX Check/debug this code; see if it's about
-				 * the right time to force the VAP awake if we
-				 * receive a frame destined for us?
-				 */
+#if 0
 				int aid = IEEE80211_AID(ni->ni_associd);
 				int ix = aid / NBBY;
 				int min = tim->tim_bitctl &~ 1;
 				int max = tim->tim_len + min - 4;
-
-				/*
-				 * Only do this for unicast traffic in the TIM
-				 * The multicast traffic notification for
-				 * the scan notification stuff should occur
-				 * differently.
-				 */
-				if (min <= ix && ix <= max &&
-				    isset(tim->tim_bitmap - min, aid)) {
-					ieee80211_sta_tim_notify(vap, 1);
-					ic->ic_lastdata = ticks;
-				}
-
-				/*
-				 * XXX TODO: do a separate notification
-				 * for the multicast bit being set.
-				 */
-#if 0
-				if (tim->tim_bitctl & 1) {
-					ieee80211_sta_tim_notify(vap, 1);
+				if ((tim->tim_bitctl&1) ||
+				    (min <= ix && ix <= max &&
+				     isset(tim->tim_bitmap - min, aid))) {
+					/* 
+					 * XXX Do not let bg scan kick off
+					 * we are expecting data.
+					 */
 					ic->ic_lastdata = ticks;
+					ieee80211_sta_pwrsave(vap, 0);
 				}
 #endif
 				ni->ni_dtim_count = tim->tim_count;
@@ -1429,16 +1402,8 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
 #endif
 				ieee80211_bg_scan(vap, 0);
 			}
-
-			/*
-			 * Put the station to sleep if we haven't seen
-			 * traffic in a while.
-			 */
-			ieee80211_sta_ps_timer_check(vap);
-
 			return;
 		}
-
 		/*
 		 * If scanning, just pass information to the scan module.
 		 */
-- 
1.8.4.1

