From owner-svn-src-projects@FreeBSD.ORG Wed Apr 30 07:09:20 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 4AEAB9C7; Wed, 30 Apr 2014 07:09:20 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3485217E5; Wed, 30 Apr 2014 07:09:20 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s3U79KaY092991; Wed, 30 Apr 2014 07:09:20 GMT (envelope-from markm@svn.freebsd.org) Received: (from markm@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s3U79Hq8092969; Wed, 30 Apr 2014 07:09:17 GMT (envelope-from markm@svn.freebsd.org) Message-Id: <201404300709.s3U79Hq8092969@svn.freebsd.org> From: Mark Murray Date: Wed, 30 Apr 2014 07:09:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r265138 - in projects/random_number_generator: crypto/openssl/ssl etc/defaults share/man/man4 sys/amd64/vmm/intel sys/arm/include sys/contrib/dev/ath/ath_hal/ar9300 sys/dev/ath sys/dev/... X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Apr 2014 07:09:20 -0000 Author: markm Date: Wed Apr 30 07:09:16 2014 New Revision: 265138 URL: http://svnweb.freebsd.org/changeset/base/265138 Log: MFC - tracking commit. Merging r265105 through r265137. Added: projects/random_number_generator/share/man/man4/full.4 - copied unchanged from r265137, head/share/man/man4/full.4 Modified: projects/random_number_generator/crypto/openssl/ssl/s3_pkt.c projects/random_number_generator/etc/defaults/rc.conf projects/random_number_generator/share/man/man4/null.4 projects/random_number_generator/share/man/man4/zero.4 projects/random_number_generator/sys/amd64/vmm/intel/vmx.c projects/random_number_generator/sys/arm/include/cpufunc.h projects/random_number_generator/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c projects/random_number_generator/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_power.c projects/random_number_generator/sys/dev/ath/ath_hal/ar5210/ar5210_power.c projects/random_number_generator/sys/dev/ath/ath_hal/ar5211/ar5211_power.c projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_power.c projects/random_number_generator/sys/dev/ath/ath_hal/ar5416/ar5416_power.c projects/random_number_generator/sys/dev/ath/if_ath.c projects/random_number_generator/sys/dev/ath/if_ath_beacon.c projects/random_number_generator/sys/dev/ath/if_ath_beacon.h projects/random_number_generator/sys/dev/ath/if_ath_debug.h projects/random_number_generator/sys/dev/ath/if_ath_keycache.c projects/random_number_generator/sys/dev/ath/if_ath_led.c projects/random_number_generator/sys/dev/ath/if_ath_misc.h projects/random_number_generator/sys/dev/ath/if_ath_rx.c projects/random_number_generator/sys/dev/ath/if_ath_rx_edma.c projects/random_number_generator/sys/dev/ath/if_ath_sysctl.c projects/random_number_generator/sys/dev/ath/if_ath_tx.c projects/random_number_generator/sys/dev/ath/if_athvar.h projects/random_number_generator/sys/dev/null/null.c projects/random_number_generator/sys/dev/pci/pci_if.m projects/random_number_generator/sys/dev/pci/pcib_if.m projects/random_number_generator/sys/kern/sched_4bsd.c projects/random_number_generator/sys/mips/mips/vm_machdep.c projects/random_number_generator/sys/netinet/tcp_reass.c projects/random_number_generator/usr.sbin/bhyve/xmsr.c Directory Properties: projects/random_number_generator/ (props changed) projects/random_number_generator/crypto/openssl/ (props changed) projects/random_number_generator/etc/ (props changed) projects/random_number_generator/share/man/man4/ (props changed) projects/random_number_generator/sys/ (props changed) projects/random_number_generator/sys/amd64/vmm/ (props changed) projects/random_number_generator/usr.sbin/bhyve/ (props changed) Modified: projects/random_number_generator/crypto/openssl/ssl/s3_pkt.c ============================================================================== --- projects/random_number_generator/crypto/openssl/ssl/s3_pkt.c Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/crypto/openssl/ssl/s3_pkt.c Wed Apr 30 07:09:16 2014 (r265138) @@ -1055,7 +1055,7 @@ start: { s->rstate=SSL_ST_READ_HEADER; rr->off=0; - if (s->mode & SSL_MODE_RELEASE_BUFFERS) + if (s->mode & SSL_MODE_RELEASE_BUFFERS && s->s3->rbuf.left == 0) ssl3_release_read_buffer(s); } } Modified: projects/random_number_generator/etc/defaults/rc.conf ============================================================================== --- projects/random_number_generator/etc/defaults/rc.conf Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/etc/defaults/rc.conf Wed Apr 30 07:09:16 2014 (r265138) @@ -641,7 +641,7 @@ devfs_rulesets="/etc/defaults/devfs.rule devfs_system_ruleset="" # The name (NOT number) of a ruleset to apply to /dev devfs_set_rulesets="" # A list of /mount/dev=ruleset_name settings to # apply (must be mounted already, i.e. fstab(5)) -devfs_load_rulesets="NO" # Enable to always load the default rulesets +devfs_load_rulesets="YES" # Enable to always load the default rulesets performance_cx_lowest="HIGH" # Online CPU idle state performance_cpu_freq="NONE" # Online CPU frequency economy_cx_lowest="HIGH" # Offline CPU idle state Copied: projects/random_number_generator/share/man/man4/full.4 (from r265137, head/share/man/man4/full.4) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/random_number_generator/share/man/man4/full.4 Wed Apr 30 07:09:16 2014 (r265138, copy of r265137, head/share/man/man4/full.4) @@ -0,0 +1,47 @@ +.\" Copyright (c) 2014 +.\" Eitan Adler . All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd March 29, 2014 +.Dt FULL 4 +.Os +.Sh NAME +.Nm full +.Nd the full device +.Sh DESCRIPTION +The +.Nm +device supplies an endless stream of zeros when read. +However, it will always be full when writing to it. +.Sh FILES +.Bl -tag -width /dev/full +.It Pa /dev/full +.El +.Sh SEE ALSO +.Xr null 4 , +.Xr zero 4 +.Sh Author +This device and man page was written by +.An Eitan Adler Aq eadler@FreeBSD.org . Modified: projects/random_number_generator/share/man/man4/null.4 ============================================================================== --- projects/random_number_generator/share/man/man4/null.4 Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/share/man/man4/null.4 Wed Apr 30 07:09:16 2014 (r265138) @@ -48,6 +48,7 @@ device is always zero. .It Pa /dev/null .El .Sh SEE ALSO +.Xr full 4 , .Xr zero 4 .Sh HISTORY A Modified: projects/random_number_generator/share/man/man4/zero.4 ============================================================================== --- projects/random_number_generator/share/man/man4/zero.4 Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/share/man/man4/zero.4 Wed Apr 30 07:09:16 2014 (r265138) @@ -49,6 +49,7 @@ supply of null bytes when read. .It Pa /dev/zero .El .Sh SEE ALSO +.Xr full 4 , .Xr null 4 .Sh HISTORY A Modified: projects/random_number_generator/sys/amd64/vmm/intel/vmx.c ============================================================================== --- projects/random_number_generator/sys/amd64/vmm/intel/vmx.c Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/sys/amd64/vmm/intel/vmx.c Wed Apr 30 07:09:16 2014 (r265138) @@ -1797,6 +1797,7 @@ vmx_exit_process(struct vmx *vmx, int vc vmm_stat_incr(vmx->vm, vcpu, VMEXIT_RDMSR, 1); retu = false; ecx = vmxctx->guest_rcx; + VCPU_CTR1(vmx->vm, vcpu, "rdmsr 0x%08x", ecx); error = emulate_rdmsr(vmx->vm, vcpu, ecx, &retu); if (error) { vmexit->exitcode = VM_EXITCODE_RDMSR; @@ -1815,6 +1816,8 @@ vmx_exit_process(struct vmx *vmx, int vc eax = vmxctx->guest_rax; ecx = vmxctx->guest_rcx; edx = vmxctx->guest_rdx; + VCPU_CTR2(vmx->vm, vcpu, "wrmsr 0x%08x value 0x%016lx", + ecx, (uint64_t)edx << 32 | eax); error = emulate_wrmsr(vmx->vm, vcpu, ecx, (uint64_t)edx << 32 | eax, &retu); if (error) { Modified: projects/random_number_generator/sys/arm/include/cpufunc.h ============================================================================== --- projects/random_number_generator/sys/arm/include/cpufunc.h Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/sys/arm/include/cpufunc.h Wed Apr 30 07:09:16 2014 (r265138) @@ -411,7 +411,7 @@ void armv6_idcache_wbinv_range (vm_offse void armv7_setttb (u_int); void armv7_tlb_flushID (void); void armv7_tlb_flushID_SE (u_int); -void armv7_icache_sync_all (); +void armv7_icache_sync_all (void); void armv7_icache_sync_range (vm_offset_t, vm_size_t); void armv7_idcache_wbinv_range (vm_offset_t, vm_size_t); void armv7_idcache_inv_all (void); Modified: projects/random_number_generator/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c ============================================================================== --- projects/random_number_generator/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c Wed Apr 30 07:09:16 2014 (r265138) @@ -60,6 +60,11 @@ ar9300_freebsd_set_tx_power_limit(struct 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) @@ -195,6 +200,7 @@ ar9300_attach_freebsd_ops(struct ath_hal 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; Modified: projects/random_number_generator/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_power.c ============================================================================== --- projects/random_number_generator/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_power.c Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_power.c Wed Apr 30 07:09:16 2014 (r265138) @@ -669,7 +669,8 @@ ar9300_set_power_mode(struct ath_hal *ah switch (mode) { case HAL_PM_AWAKE: - ah->ah_powerMode = mode; + 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) { @@ -699,8 +700,10 @@ ar9300_set_power_mode(struct ath_hal *ah } #endif ar9300_set_power_mode_sleep(ah, set_chip); - ahp->ah_chip_full_sleep = AH_TRUE; - ah->ah_powerMode = mode; + if (set_chip) { + ahp->ah_chip_full_sleep = AH_TRUE; + ah->ah_powerMode = mode; + } break; case HAL_PM_NETWORK_SLEEP: #if ATH_SUPPORT_MCI @@ -709,7 +712,9 @@ ar9300_set_power_mode(struct ath_hal *ah } #endif ar9300_set_power_mode_network_sleep(ah, set_chip); - ah->ah_powerMode = mode; + if (set_chip) { + ah->ah_powerMode = mode; + } break; default: HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, Modified: projects/random_number_generator/sys/dev/ath/ath_hal/ar5210/ar5210_power.c ============================================================================== --- projects/random_number_generator/sys/dev/ath/ath_hal/ar5210/ar5210_power.c Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/sys/dev/ath/ath_hal/ar5210/ar5210_power.c Wed Apr 30 07:09:16 2014 (r265138) @@ -108,16 +108,19 @@ ar5210SetPowerMode(struct ath_hal *ah, H setChip ? "set chip " : ""); switch (mode) { case HAL_PM_AWAKE: - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; status = ar5210SetPowerModeAwake(ah, setChip); break; case HAL_PM_FULL_SLEEP: ar5210SetPowerModeSleep(ah, setChip); - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; break; case HAL_PM_NETWORK_SLEEP: ar5210SetPowerModeAuto(ah, setChip); - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; break; default: HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown power mode %u\n", Modified: projects/random_number_generator/sys/dev/ath/ath_hal/ar5211/ar5211_power.c ============================================================================== --- projects/random_number_generator/sys/dev/ath/ath_hal/ar5211/ar5211_power.c Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/sys/dev/ath/ath_hal/ar5211/ar5211_power.c Wed Apr 30 07:09:16 2014 (r265138) @@ -110,16 +110,19 @@ ar5211SetPowerMode(struct ath_hal *ah, H setChip ? "set chip " : ""); switch (mode) { case HAL_PM_AWAKE: - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; status = ar5211SetPowerModeAwake(ah, setChip); break; case HAL_PM_FULL_SLEEP: ar5211SetPowerModeSleep(ah, setChip); - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; break; case HAL_PM_NETWORK_SLEEP: ar5211SetPowerModeNetworkSleep(ah, setChip); - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; break; default: HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown power mode %u\n", Modified: projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_power.c ============================================================================== --- projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_power.c Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_power.c Wed Apr 30 07:09:16 2014 (r265138) @@ -134,16 +134,19 @@ ar5212SetPowerMode(struct ath_hal *ah, H setChip ? "set chip " : ""); switch (mode) { case HAL_PM_AWAKE: - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; status = ar5212SetPowerModeAwake(ah, setChip); break; case HAL_PM_FULL_SLEEP: ar5212SetPowerModeSleep(ah, setChip); - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; break; case HAL_PM_NETWORK_SLEEP: ar5212SetPowerModeNetworkSleep(ah, setChip); - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; break; default: HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown power mode %u\n", Modified: projects/random_number_generator/sys/dev/ath/ath_hal/ar5416/ar5416_power.c ============================================================================== --- projects/random_number_generator/sys/dev/ath/ath_hal/ar5416/ar5416_power.c Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/sys/dev/ath/ath_hal/ar5416/ar5416_power.c Wed Apr 30 07:09:16 2014 (r265138) @@ -133,23 +133,29 @@ ar5416SetPowerMode(struct ath_hal *ah, H }; #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 " : ""); switch (mode) { case HAL_PM_AWAKE: - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; status = ar5416SetPowerModeAwake(ah, setChip); break; case HAL_PM_FULL_SLEEP: ar5416SetPowerModeSleep(ah, setChip); - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; break; case HAL_PM_NETWORK_SLEEP: ar5416SetPowerModeNetworkSleep(ah, setChip); - ah->ah_powerMode = mode; + if (setChip) + ah->ah_powerMode = mode; break; default: HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown power mode 0x%x\n", Modified: projects/random_number_generator/sys/dev/ath/if_ath.c ============================================================================== --- projects/random_number_generator/sys/dev/ath/if_ath.c Wed Apr 30 06:54:35 2014 (r265137) +++ projects/random_number_generator/sys/dev/ath/if_ath.c Wed Apr 30 07:09:16 2014 (r265138) @@ -279,6 +279,95 @@ ath_legacy_attach_comp_func(struct ath_s } } +/* + * 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); + } +} + +/* + * 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; + } +} + +/* + * 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); + } +} + #define HAL_MODE_HT20 (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20) #define HAL_MODE_HT40 \ (HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \ @@ -341,6 +430,10 @@ ath_attach(u_int16_t devid, struct ath_s 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 @@ -605,6 +698,8 @@ ath_attach(u_int16_t devid, struct ath_s #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. @@ -994,6 +1089,14 @@ ath_attach(u_int16_t devid, struct ath_s if (bootverbose) ieee80211_announce(ic); ath_announce(sc); + + /* + * Put it to sleep for now. + */ + ATH_LOCK(sc); + ath_power_setpower(sc, HAL_PM_FULL_SLEEP); + ATH_UNLOCK(sc); + return 0; bad2: ath_tx_cleanup(sc); @@ -1039,7 +1142,22 @@ 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_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ath_power_setpower(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + + /* + * Stop things cleanly. + */ ath_stop(ifp); + ieee80211_ifdetach(ifp->if_l2com); taskqueue_free(sc->sc_tq); #ifdef ATH_TX99_DIAG @@ -1402,6 +1520,10 @@ ath_vap_delete(struct ieee80211vap *vap) struct ath_hal *ah = sc->sc_ah; struct ath_vap *avp = ATH_VAP(vap); + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { /* @@ -1415,6 +1537,8 @@ ath_vap_delete(struct ieee80211vap *vap) ath_stoprecv(sc, 1); /* stop recv side */ } + /* .. leave the hardware awake for now. */ + ieee80211_vap_detach(vap); /* @@ -1502,6 +1626,9 @@ 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); } @@ -1547,8 +1674,12 @@ ath_reset_keycache(struct ath_softc *sc) struct ath_hal *ah = sc->sc_ah; int i; + ATH_LOCK(sc); + 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); + ATH_UNLOCK(sc); ieee80211_crypto_reload_keys(ic); } @@ -1600,6 +1731,13 @@ 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_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ath_power_setpower(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + ath_hal_reset(ah, sc->sc_opmode, sc->sc_curchan != NULL ? sc->sc_curchan : ic->ic_curchan, AH_FALSE, &status); @@ -1632,6 +1770,10 @@ ath_resume(struct ath_softc *sc) if (sc->sc_resume_up) ieee80211_resume_all(ic); + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); + /* XXX beacons ? */ } @@ -1689,6 +1831,10 @@ ath_intr(void *arg) return; } + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + if ((ifp->if_flags & IFF_UP) == 0 || (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { HAL_INT status; @@ -1698,6 +1844,10 @@ 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_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); return; } @@ -1737,6 +1887,11 @@ ath_intr(void *arg) /* Short-circuit un-handled interrupts */ if (status == 0x0) { ATH_PCU_UNLOCK(sc); + + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); + return; } @@ -1903,10 +2058,18 @@ 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_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); } static void @@ -1937,6 +2100,8 @@ 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 @@ -1945,6 +2110,16 @@ 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_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + if ((vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) == 0) { struct ifnet *ifp = vap->iv_ic->ic_ifp; struct ath_softc *sc = ifp->if_softc; @@ -1962,12 +2137,32 @@ ath_bmiss_vap(struct ieee80211vap *vap) if (tsf - lastrx <= bmisstimeout) { sc->sc_stats.ast_bmiss_phantom++; + + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); + return; } } + + /* + * There's no need to keep the hardware awake during the call + * to av_bmiss(). + */ + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(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) { @@ -1990,6 +2185,12 @@ ath_bmiss_proc(void *arg, int pending) DPRINTF(sc, ATH_DEBUG_ANY, "%s: pending %u\n", __func__, pending); + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + + ath_beacon_miss(sc); + /* * Do a reset upon any becaon miss event. * @@ -2003,6 +2204,13 @@ 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_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); } /* @@ -2042,6 +2250,12 @@ ath_init(void *arg) ATH_LOCK(sc); /* + * Force the sleep state awake. + */ + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ath_power_setpower(sc, HAL_PM_AWAKE); + + /* * Stop anything previously setup. This is safe * whether this is the first time through or not. */ @@ -2058,6 +2272,7 @@ ath_init(void *arg) ath_update_chainmasks(sc, ic->ic_curchan); ath_hal_setchainmasks(sc->sc_ah, sc->sc_cur_txchainmask, sc->sc_cur_rxchainmask); + if (!ath_hal_reset(ah, sc->sc_opmode, ic->ic_curchan, AH_FALSE, &status)) { if_printf(ifp, "unable to reset hardware; hal status %u\n", status); @@ -2113,6 +2328,7 @@ 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; } @@ -2139,6 +2355,15 @@ 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; @@ -2150,6 +2375,7 @@ 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 @@ -2170,6 +2396,12 @@ 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_drv_flags & IFF_DRV_RUNNING) { /* * Shutdown the hardware and driver: @@ -2210,9 +2442,20 @@ 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); } -#define MAX_TXRX_ITERATIONS 1000 +/* + * 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 static void ath_txrx_stop_locked(struct ath_softc *sc) { @@ -2231,7 +2474,8 @@ ath_txrx_stop_locked(struct ath_softc *s sc->sc_txstart_cnt || sc->sc_intr_cnt) { if (i <= 0) break; - msleep(sc, &sc->sc_pcu_mtx, 0, "ath_txrx_stop", 1); + msleep(sc, &sc->sc_pcu_mtx, 0, "ath_txrx_stop", + msecs_to_ticks(10)); i--; } @@ -2278,7 +2522,7 @@ ath_txrx_start(struct ath_softc *sc) * Another, cleaner way should be found to serialise all of * these operations. */ -#define MAX_RESET_ITERATIONS 10 +#define MAX_RESET_ITERATIONS 25 static int ath_reset_grablock(struct ath_softc *sc, int dowait) { @@ -2296,7 +2540,11 @@ ath_reset_grablock(struct ath_softc *sc, break; } ATH_PCU_UNLOCK(sc); - pause("ath_reset_grablock", 1); + /* + * 1 tick is likely not enough time for long calibrations + * to complete. So we should wait quite a while. + */ + pause("ath_reset_grablock", msecs_to_ticks(100)); i--; ATH_PCU_LOCK(sc); } while (i > 0); @@ -2361,6 +2609,13 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T /* Try to (stop any further TX/RX from occuring */ taskqueue_block(sc->sc_tq); + /* + * Wake the hardware up. + */ + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + ATH_PCU_LOCK(sc); /* @@ -2455,9 +2710,13 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T * 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); @@ -2474,6 +2733,8 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T /* Restart TX/RX as needed */ ath_txrx_start(sc); + /* XXX TODO: we need to hold the tx refcount here! */ + /* Restart TX completion and pending TX */ if (reset_type == ATH_RESET_NOLOSS) { for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { @@ -2498,6 +2759,14 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; IF_UNLOCK(&ifp->if_snd); + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(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 @@ -2638,6 +2907,7 @@ ath_buf_clone(struct ath_softc *sc, stru 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 */ @@ -2739,6 +3009,11 @@ ath_transmit(struct ifnet *ifp, struct m sc->sc_txstart_cnt++; ATH_PCU_UNLOCK(sc); + /* Wake the hardware up already */ + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + ATH_KTR(sc, ATH_KTR_TX, 0, "ath_transmit: start"); /* * Grab the TX lock - it's ok to do this here; we haven't @@ -2972,6 +3247,11 @@ finish: sc->sc_txstart_cnt--; ATH_PCU_UNLOCK(sc); + /* Sleep the hardware if required */ + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); + ATH_KTR(sc, ATH_KTR_TX, 0, "ath_transmit: finished"); return (retval); @@ -2999,7 +3279,6 @@ ath_key_update_begin(struct ieee80211vap 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 @@ -3009,7 +3288,6 @@ ath_key_update_end(struct ieee80211vap * 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); } @@ -3020,8 +3298,12 @@ ath_update_promisc(struct ifnet *ifp) u_int32_t rfilt; /* configure rx filter */ + ATH_LOCK(sc); + 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); + ATH_UNLOCK(sc); DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x\n", __func__, rfilt); } @@ -3057,7 +3339,11 @@ ath_update_mcast(struct ifnet *ifp) if_maddr_runlock(ifp); } else mfilt[0] = mfilt[1] = ~0; + ATH_LOCK(sc); + 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); + ATH_UNLOCK(sc); DPRINTF(sc, ATH_DEBUG_MODE, "%s: MC filter %08x:%08x\n", __func__, mfilt[0], mfilt[1]); } @@ -3119,8 +3405,13 @@ 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_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); ath_hal_setslottime(ah, usec); + ath_power_restore_power_state(sc); sc->sc_updateslot = OK; + ATH_UNLOCK(sc); } /* @@ -3137,6 +3428,8 @@ 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) @@ -4258,6 +4551,10 @@ ath_tx_proc_q0(void *arg, int npending) sc->sc_txq_active &= ~txqs; ATH_PCU_UNLOCK(sc); + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + ATH_KTR(sc, ATH_KTR_TXCOMP, 1, "ath_tx_proc_q0: txqs=0x%08x", txqs); @@ -4278,6 +4575,10 @@ ath_tx_proc_q0(void *arg, int npending) sc->sc_txproc_cnt--; ATH_PCU_UNLOCK(sc); + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); + ath_tx_kick(sc); } @@ -4299,6 +4600,10 @@ ath_tx_proc_q0123(void *arg, int npendin sc->sc_txq_active &= ~txqs; ATH_PCU_UNLOCK(sc); + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + ATH_KTR(sc, ATH_KTR_TXCOMP, 1, "ath_tx_proc_q0123: txqs=0x%08x", txqs); @@ -4331,6 +4636,10 @@ ath_tx_proc_q0123(void *arg, int npendin sc->sc_txproc_cnt--; ATH_PCU_UNLOCK(sc); + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); + ath_tx_kick(sc); } @@ -4351,6 +4660,10 @@ ath_tx_proc(void *arg, int npending) sc->sc_txq_active &= ~txqs; ATH_PCU_UNLOCK(sc); + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + ATH_KTR(sc, ATH_KTR_TXCOMP, 1, "ath_tx_proc: txqs=0x%08x", txqs); /* @@ -4376,6 +4689,10 @@ ath_tx_proc(void *arg, int npending) sc->sc_txproc_cnt--; ATH_PCU_UNLOCK(sc); + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); + ath_tx_kick(sc); } #undef TXQACTIVE @@ -4402,6 +4719,10 @@ ath_txq_sched_tasklet(void *arg, int npe sc->sc_txproc_cnt++; ATH_PCU_UNLOCK(sc); + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + ATH_TX_LOCK(sc); for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { @@ -4410,6 +4731,10 @@ ath_txq_sched_tasklet(void *arg, int npe } *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***