Date: Wed, 30 Apr 2014 23:19:31 -0700 From: Adrian Chadd <adrian@freebsd.org> To: "freebsd-wireless@freebsd.org" <freebsd-wireless@freebsd.org> Subject: [ath] basic STA powersave for atheros devices is in -HEAD, be warned! Message-ID: <CAJ-VmoksCaqj5w_amcwK=ndoejmkrFef1x5wyewpKrg8HkHPJg@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
TL;DR: I've just committed basic STA mode powersave support to Freebsd-HEAD. If you add 'powersave' to your ifconfig wlan0 clone line, the NIC will dip in and out of chip sleep state if the link is idle. Don't do this without IEEE80211_DEBUG, ATH_DEBUG and AH_DEBUG or you won't be able to debug it. Works for me. YMMV. The long version. I've been working on basic chipset powersave support in station mode on and off for the last three weeks or so. It's nowhere near complete or what I would even begin to call correct. It however is a required step towards well, all the correct stuff. The chipset sleep stuff lets the chip drift into powersave if it isn't currently actively doing transmit or receive. It wakes up for beacons; it stays awake if there's multicast traffic to receive or anything to transmit. The driver now wakes up and sleeps based on what net80211 tells it to do. It's the same highly inefficient sleep management from circa 2002 or so, but it's better than no sleep management. However, the thing is, 802.11 powersave as it's implemented is .. tricksy. There's a bit in the 802.11 header (PWRMGT) that when set to 1 tells the recipient that it's actually asleep, and to buffer frames until the transmitter is awake. When PWRMGT is set to 0, the recipient now knows the transmitter is awake and buffered frames can be transmitted. So the only way this can work is if everything happens in the right order. Ie, if we're going to sleep, we need to: * pause transmitting anything other than the NULL "I'm going to sleep" data frame; * finish transmitting what we're transmitting; * once everything is transmitted, transition the NIC from power save to network sleep; * transmit the NULL data frame that says we're asleep; * any further frames transmitted need to be marked with PWRMGT=1 so the peer stays asleep. Then, the wakeup is the opposite: transition the VAP to awake, send a data frame with PWRGMT=0, and everything subsequent to that should be transmitted with PWRGMT=0. However, none of this is currently going on. The net80211 stack just transitions things to and from sleep state, but there's currently nothing that implements all that buffering, pausing, resuming and such. So it's quite possible that: * data frames are going out with PWRMGT=0; * the VAP transitions to SLEEP; * the NULL data frame goes out to tell the receiver that the transmitter is asleep; * .. then some other concurrently sending frames go out with PWRMGT=0. .. then the station think it's asleep; the hardware is asleep and not receiving things, but the AP or other peer decides the station is awake and sends it data. Which isn't received. Sigh. So, I'm not going to fix all of that just yet. I wanted to debug the hardware side of things. The NIC gets extremely upset if it's put to sleep and then programmed in any way other than "please wake up now." I'll work out the kinks in the driver side of things before I worry about tackling the rest of the legacy power save stuff. There's a bunch more work to do before I start down the path of PS-POLL station support (where the station sends PS-POLL frames to get a single frame back from the AP or peer.) I have no ETA on that; it's likely "whenever I get a bunch of free weekends." So if you have an Atheros NIC in your device and you feel a little adventurous, update to the latest -HEAD and flip on powersave. You can debug by using "wlandebug +power" to see the NIC going in and out of powersave and why it is or isn't doing it. Don't be afraid to report weird stuff to the mailing list. -a
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-VmoksCaqj5w_amcwK=ndoejmkrFef1x5wyewpKrg8HkHPJg>