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 _______________________________________________ firstname.lastname@example.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-wireless To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"