Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Mar 2014 01:31:25 -0700
From:      Adrian Chadd <adrian@freebsd.org>
To:        "freebsd-wireless@freebsd.org" <freebsd-wireless@freebsd.org>
Subject:   [rft] ath(4) and preparations for power save support in STA mode
Message-ID:  <CAJ-Vmo=L_o1kvnWSROQi0=2rRvKue_QaGqb_4iHOZb7DLJR5Lw@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Hi,

I've been working towards supporting basic power save support in ath(4).

Now, this patch implements the basic driver hooks required to attempt
to do this. It's only been lightly tested on the AR5416. I haven't
tested it on any other hardware so if you do try this, it may just
blow up in your face.

http://people.freebsd.org/~adrian/ath/20140330-ath-powersave-1.diff

However, it's also supposed to be a no-op during normal driver use.

So what's it do?

Firstly, the hardware has three main states. "full sleep" is the
lowest power mode. "force awake" is "being forced fully awake,
regardless of whether we need to be." Finally, and the most
interesting one, is "network sleep." This is where the MAC powers down
bits and pieces of things until each beacon interval when it wakes up
to receive the beacon, check if the station AID is set in the TIM (or
ATIM for later hardware, if in IBSS mode) and if so, stays awake long
enough to receive further frames before going to sleep.

Now for the gruesome details.

* The hardware has to be woken up for things like calibration and DMA work.
* The hardware can go into network sleep until each beacon interval
(but, see below.)
* Only some registers can be read - for the AR5416 family, it's the
RTC (clock programming and power mode), the host interface (GPIO, LED
and PCI/PCIe interface, including SYNC interrupts), and the EEPROM
interface. So in order to ensure everything else is valid, one must
force the device awake if the pending-interrupts check shows there's
something to handle.
* .. and it should also be forced awake for the TX, RX and TX completion path
* .. as well as reset, channel programming, etc.
* The hardware may decide to go to sleep once the reason(s) for it to
be awake are gone, so it's best to force it awake to do whatever's
needed and then put it back to network sleep once it's done.
* The AR5416 at least will stay awake if you start a transmit and then
let it go back to network sleep. Ie, you don't have to keep the
hardware set as "force awake" when doing a transmit - which greatly
simplifies the transmit logic. However, I've no idea if this holds
true for all the other various chips out there.

So, the patch as posted actually seems to work well enough if I force
the hardware to network sleep - I'm not programming the TX or RX
registers inappropriately or trying to do calibration whilst the NIC
is asleep. However, it won't stay associated because, and this is
totally expected - none of the net80211 station powersave framework is
hooked in. Specifically:

* The frames being transmitted whilst the NIC is asleep don't have the
FC1 PWR_MGT bit set to 1, so the AP doesn't try buffering things, and
* There's nothing comprehensive to hook into the receive path to tell
the AP that we're now awake.

It turns out there's a powersave state (IEEE80211_S_SLEEP) which is
mostly implemented. There's also the STA powersave stuff that's used
by the bgscan code that also is useful for exactly this. It will
correctly buffer outbound frames until we come out of powersave and
it'll send NULL frames appropriately to the AP to bring it in and out
of powersave.

What's however missing is:

* if a beacon is received with the TIM bit for us set to 1, we need to
either kick off a ps-poll (which we have no support for transmitting
yet) or wake the VAP up. Otherwise we'll just stay asleep until we
force ourselves back to RUN.
* There's no actual sleep management code for station mode operation.
Ie, nothing tracks ic_lastdata or anything else and decides to
transition the VAP to SLEEP, neither does it have any logic to
transition it back to RUN after a timeout (ie, being asleep too long.)

I'm going to take a crack at sorting out the missing power-save hooks
in net80211 so we can do explicit power save if the NIC requires it.
iwn(4) doesn't, so the IEEE80211_S_SLEEP stuff just plain won't be
used there.

Given all of this, I'd appreciate it if people would try the above
patch out with AH_DEBUG and ATH_DEBUG compiled in. Let me know if it
complains about anything.

Thanks,


-a



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-Vmo=L_o1kvnWSROQi0=2rRvKue_QaGqb_4iHOZb7DLJR5Lw>