qca / open-ath9k-htc-firmware

The firmware for QCA AR7010/AR9271 802.11n USB NICs
Other
428 stars 182 forks source link

Power Save for Multi-VIF #125

Open doru91 opened 7 years ago

doru91 commented 7 years ago

Hello, everyone

I try to design a Power Save Algorithm in the case of a mobile client that has multiple virtual interfaces [1] and is connected to multiple Access Points simultaneously. My implementation is for the Atheros AR9271 WiFi chip.

The biggest challenge in implementing this algorithm is waking up the WiFi chip for RX traffic. E.g.: the WiFi chip is in the sleep state and it has to wake up in order to receive beacons from all the APs that the client is connected to.

Reading the AR9271 datasheet [2] I noticed that the chip is equipped with hardware timers for waking up the hardware. The registers for programming these hardware timers are MAC_PCU_SLP1 and MAC_PCU_SLP2.

After the registers have been programmed, the RTC_FORCE_WAKE bit has to be cleared in order to allow the card to enter sleep mode (at least this is how is done in the existing implementation for the single VIF scenario).

I used the logic above for programming the hardware to wake up for beacons from multiple APs. I used a power device for measuring the energy consumption and it seems that the WiFi card wakes up periodically to receive beacons from multiple APs. The problem is that after a time, out of nowhere, the WiFi card refuses to enter sleep mode and stays just in the awake state, although the logic for programming the hardware timers does not change.

Could someone give more details about the FORCE_WAKE signal and what is the relation between this signal and the MAC and RTC layers? I believe that the problem comes from here. The AR9271 datasheet just references this signal (page 106) but it offers no details about it.

@erikarn, I read your presentation from [4] and I was wondering if you have any suggestions.

PS: This is my Master Project, I work at this just for fame and glory :)

[1] https://github.com/doru91/linux-stable/wiki/Two-Interfaces-Power-Save [2] https://wikidevi.com/wiki/Atheros_AR9271 [3] http://lxr.free-electrons.com/source/drivers/net/wireless/ath/ath9k/hw.c?v=4.9#L2068 [4] https://docs.google.com/presentation/d/1CofNlbHs2bLdJuW3VACzAImqesGQoktUTXS6zKgDDKI/edit#slide=id.g371192f19_0140

Regards, Doru

erikarn commented 7 years ago

Hi,

So I don't know how the timers can be used for multiple virtual interfaces. You can figure that out. :-)

However, i wonder if the hardware auto-sleep functionality is broken. IIRC, the hardware wakes up when it sees an entry in the beacon TIM for its own AID, and stays awake for the duration of that receive processing. Do your beacons have the TIM bit set for that stations AID?

In FreeBSD I explicitly wake up the device when doing receive handling, even though I don't need to for later model parts.

If your'e associated to multiple APs then your AIDs may differ, and that tracking logic may be broken.

(And it could be chip bugs too, I can go ask, but AR9285/AR9271 are old chips..)

-adrian

erikarn commented 7 years ago

(also, what hardware are you using to measure current draw?)

-a

doru91 commented 7 years ago

Hi,

Yes, some beacons have the TIM set with the stations AID.

Are you sure that the AR9271 chip have this feature? I put some printks inside the ath9k_set_power_network_sleep and the pCap->hw_caps field does not have the ATH9K_HW_CAP_AUTOSLEEP bit set [2].

For measuring the power consumption I use a power tool from Moonson [1].

[1] https://www.msoon.com/LabEquipment/PowerMonitor/ [2] http://lxr.free-electrons.com/source/drivers/net/wireless/ath/ath9k/hw.c?v=4.5#L2093

Thanks, Doru

erikarn commented 7 years ago

Hm, I'll have to check. I'm worried that it's there-but-buggy. :-)

-adrian

olerem commented 7 years ago

@doru91 hi, good work. Did you tested it in singe VIF more? Did you played with all MAC_PCU_SLP* registers?

olerem commented 7 years ago

May be you will need to set CLR_CNT in MAC_PCU_SLP_MIB3 register.

doru91 commented 7 years ago

Hello, Oleksij, Adrian

Using the above commit I repeated the PS tests but the PS bug still occurs. However, there are situations (1/20 tests) when the card stays longer in PS mode (e.g.: 10 minutes).

I will update the wiki page with the capture files and a detailed analysis this week-end. However, having a quick look in the capture files, it seems that the sleep counters never reach the threshold so I don't reset the counters, I just read them. It would be pretty strange that a read from a register could solve this problem. I have to do more tests also without the above patch and see the behaviour.

I did not play with all MAC_PCU_SLP* register in single-VIF mode but I plan to do it.

Adrian, did you have time to check the autosleep functionality?

Regards, Doru

doru91 commented 7 years ago

As I promised, I updated the wiki with the progress for the RX bug (Work-In-Progress) https://github.com/doru91/linux-stable/wiki/Bug%233-Progress