Skip site navigation (1)Skip section navigation (2)
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>