rt73 in AP mode: powersave support, set_tim() missing

Live forum: http://rt2x00.serialmonkey.com/viewtopic.php?t=5486

salsasepp

07-07-2009 21:37:07

Dear rt2x00 wizards,

I have an rt73 USB stick running with hostapd, latest wireless-testing, works almost OK.
I have reported missing beacon TIM bits with buffered frames during powersave with my iPod station here
http//thread.gmane.org/gmane.linux.ker ... eral/35559

Digging around the source I seem to understand that the necessary infrastructure (i.e. the set_tim() function for rt73usb) is not implemented.
Being clueless about kernel/driver/wireless development, I thought I'd ask whether
a) somebody is working on it, or
b) someone can provide a clue, a code fragment or some starting point for me to do it myself

Thank you,
Stefan.

IvD

07-07-2009 21:50:20


a) somebody is working on it
[/quote3b2n8of1]

As far as I know, nobody is working on it.


b) someone can provide a clue, a code fragment or some starting point for me to do it myself
[/quote3b2n8of1]

Sorry, I don't know all steps which might be required to do this correctly.

salsasepp

08-07-2009 00:39:28


Sorry, I don't know all steps which might be required to do this correctly.
[/quote3kqohnp1]
Thank you for this info.
Who might know?

I have considerable interest in helping to implement and test this, as rt2x00 based usb sticks seem to be about the only current hardware in this formfactor that can be used as an access point.

Thank you,
Stefan.

IvD

08-07-2009 02:01:07


Who might know?
[/quotelnuozv15]

If I had time to look into this, I would/should know. But I fear that if you want to implement this you are on your own.
I can help a bit with the implementation details if you give me a clear description where the tim bit should be set (beacon, register, ..?)

salsasepp

08-07-2009 03:32:59

Ok, thanks, I might just try and learn something.

If I understand correctly, the following needs to be done
- define rt73usb_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,bool set) in rt73usb.c
- add it to rt73usb_mac80211_ops
- In there, iterate over all active interfaces
- Update beacon for each interface

mac80211 seems to take care of buffered frames accounting and assembling the TIM virtual bitmap for us. If that is true, I might get by with just calling rt2x00queue_update_beacon(), which is however not exported from rt2x00queue.c (and which may or may not be appropriate for this task at all).

Thats all of my wild guesses. Any of this makes the least bit of sense? If so, I'll give it a try.

IvD

08-07-2009 04:02:03


- In there, iterate over all active interfaces
- Update beacon for each interface
[/quote2mnoriin]

This sounds like code which belongs in rt2x00lib rather then just the driver.


mac80211 seems to take care of buffered frames accounting and assembling the TIM virtual bitmap for us. If that is true, I might get by with just calling rt2x00queue_update_beacon(), which is however not exported from rt2x00queue.c (and which may or may not be appropriate for this task at all).
[/quote2mnoriin]

I think you will be forced to use the update_beacon callback function, since you can't modify a beacon on the fly with the USB drivers, once the beacon has been uploaded to the device it will keep sending that beacon until a new beacon was uploaded.

iap

10-07-2009 23:58:00

Dear colleagues,

I'm also interested in setting up an rt73 usb stick as an AP.
Currently I have the same troubles with D-Link DWA-110 using vanilla kernel 2.6.30 with the patch from Alexandre Becholey (mentioned by Stefan) and hostapd 0.6.9.
Everything else looks working.

Could you please inform about your progress?

P.S. Many thanks to Stefan for identifying the cause of the problem.

Best regards,
Igor

IvD

11-07-2009 01:09:26

The patch Stefan has produced will be submitted upstream in a couple of hours.

iap

16-07-2009 19:26:18

Hi Ivo,

Unfortunately I don't see any patch at http//git.kernel.org/?p=linux/kernel/g ... ;a=summary.
Am I looking it at a wrong place? Or has something gone wrong with the patch?

Best Regards,
Igor

salsasepp

16-07-2009 19:41:42

Ivo hast posted the patch here
http//thread.gmane.org/gmane.linux.ker ... eral/35789

iap

22-07-2009 21:18:51

I've tested the patch on 2.6.30 kernel and have 4 issues.

My AP environment
1. Linux kernel 2.6.30 with the patch from Alexandre Becholey (mentioned previously) and the set_tim patch.
2. Hostapd 0.6.9.
3. D-Link DWA-110 USB Wi-Fi stick (ID 07d13c07 D-Link System Wireless G DWA-110 Adapter).

Clients
1. Dell notebook with Broadcom Wi-Fi card (Broadcom Corporation BCM4312 802.11b/g (rev 01)) under Ubuntu Linux 9.04.
I use Asus WL-167g USB Wi-Fi stick (ID 0b051706 ASUSTek Computer, Inc. WL-167G 802.11g Adapter [ralink]) as the monitor on it.
2. Toshiba G900 PDA under Windows Mobile 6.0.

After I've applied the set_tim patch, beacon frames contain correct TIM information and the notebook connects to the AP and exchanges traffic almost fine, but kernel oops happen from time to time (null pointer dereference) and significant delays (up to 3 seconds) took place.
PDA still encounters a difficulty.
A sniffer showed that the notebook uses "null function" frames to indicate power save transitions, whereas the PDA uses PS Poll frames, but the mac80211 code doesn't receive them (there is no "STA xxx aid y PS Poll" messages in the log).

Issue 1. The rt73 usb stick is configured to filter out all control frames including the PS Poll one.

Who should configure the filter in a right way the driver, the mac80211 stack or an application (hostapd)?

I'm not sure of that (I'm not a network programming guru -) ) and I've assumed that the driver should.
So, I've added following lines in rt2x00mac_configure_filter
if (rt2x00dev->intf_ap_count)
*total_flags |= FIF_CONTROL;
Note, this is just my "RFC", I'd like to get your comments. Analogous approach I've seen in other wi-fi drivers.

After this step the PDA began exchange traffic, but kernel oops (null pointer dereference) and delays take place also.

Issue 2. Oops in rt73usb_write_beacon.
I've found that the oops are caused by two race conditions
* In case of two near calls to set_tim rt2x00lib_beacondone_iter is cleaning the beacon skb, whereas rt73usb_write_beacon is still using it.
* In case of two near updates of beacon first as the result of set_tim and second as the result of a call from hostapd.

To avoid the race I've done the following
* Moved cleanup of the beacon skb from rt2x00lib_beacondone_iter into the beginning of rt2x00queue_update_beacon.
* Added a mutex in struct rt2x00_intf, which guards the entire body of rt2x00queue_update_beacon.

Question 2 Should extra cleanup of the beacon skb be added somewhere else?
Or doing that in rt2x00queue_update_beacon is enough?

Issue 3. Delays in traffic exchange are caused by de-synchronization of beacon frames when beacon is being updated to refresh TIM (i.e. two neighbor beacon frames - before and after update - are being transmitted with a wrong time interval in this case).
I think, this is because rt73usb_write_beacon clears not only TXRX_CSR9_BEACON_GEN flags but also TXRX_CSR9_TSF_TICKING one (this is my guess, I have no Ralink documentation).
To keep beacon in sync I've commented out TXRX_CSR9_TSF_TICKING and TXRX_CSR9_TBTT_ENABLE clearing in rt73usb_write_beacon. I don't know, what the second flag is for, but I think, clearing TXRX_CSR9_BEACON_GEN is enough to prevent invalid beacon generation while new beacon is being uploaded.
So, we clear TXRX_CSR9_BEACON_GEN before uploading the beacon data and set it back further in rt73usb_kick_tx_queue.

Issue 4. It is related to the mac80211 implementation or hostapd (I'm not yet sure), but just for completeness of my report.
The station can't reconnect (e.g. the PDA can't reconnect after wake up).

Consider following step-by-step
1. A station authenticates at AP and exchanges traffic.
2. The station indicates to the AP that it is going to sleep.
3. The station goes to the stand-by mode (not only the wi-fi card, but the device itself).
4. The station wakes up and begins authentication with an Authentication management frame.
This is the behavior of my PDA.

The problem is the mac80211 stack remembers that the station has gone to sleep. So, response frames from hostapd are buffered by mac80211.
The station indicates in the Authentication frame that it isn't sleeping anymore. But the mac80211 stack analyzes sleep/wake transitions in _data_ frames only, but not in management ones. See ieee80211_rx_h_sta_process in net/mac80211/rx.c. A comment there notes "Ignore doze->wake transitions that are indicated by non-data frames, the standard is unclear here".
As the result, the station never receives the authentication response from the AP.

I think, there may be 2 alternative solutions
A) In mac80211 implementation improve ieee80211_rx_h_sta_process - analyze not only data frames, but also management ones. I've tried to add analysis of authentication frames there and it worked in my case. But I'm not sure if it is enough and if it doesn't brake some other functionality.
B) In hostapd remove the station from the mac80211 stack just after receiving an authentication frame. In my case this approach also works.

I fixed these issues on the 2.6.30 kernel, but the code in Ivo's git repository seems containing these problems too.

What do you think about solutions of these issues, first of all issues 1 - 3?
If the proposed solutions have sense, I could supply a patch for further testing.

As for issue 4, may be you heard about that problem and/or its solution somewhere else?
Please let me know.

Best regards,
Igor

IvD

23-07-2009 05:14:10


Issue 1. The rt73 usb stick is configured to filter out all control frames including the PS Poll one.

Who should configure the filter in a right way the driver, the mac80211 stack or an application (hostapd)?

I'm not sure of that (I'm not a network programming guru -) ) and I've assumed that the driver should.
So, I've added following lines in rt2x00mac_configure_filter
if (rt2x00dev->intf_ap_count)
*total_flags |= FIF_CONTROL;
Note, this is just my "RFC", I'd like to get your comments. Analogous approach I've seen in other wi-fi drivers.
[/quote2hoas7t0]

Not sure, I would say mac80211 should be in charge. But if you want to be really sure, you should
ask on the linux-wireless@vger.kernel.org mailinglist.


Issue 2. Oops in rt73usb_write_beacon.
I've found that the oops are caused by two race conditions
* In case of two near calls to set_tim rt2x00lib_beacondone_iter is cleaning the beacon skb, whereas rt73usb_write_beacon is still using it.
* In case of two near updates of beacon first as the result of set_tim and second as the result of a call from hostapd.

To avoid the race I've done the following
* Moved cleanup of the beacon skb from rt2x00lib_beacondone_iter into the beginning of rt2x00queue_update_beacon.
* Added a mutex in struct rt2x00_intf, which guards the entire body of rt2x00queue_update_beacon.

Question 2 Should extra cleanup of the beacon skb be added somewhere else?
Or doing that in rt2x00queue_update_beacon is enough?
[/quote2hoas7t0]

Will need to see a patch before I can judge that more clearly.
But it is too bad a mutex is needed while a spinlock was already present in the rt2x00_intf structure.


Issue 3. Delays in traffic exchange are caused by de-synchronization of beacon frames when beacon is being updated to refresh TIM (i.e. two neighbor beacon frames - before and after update - are being transmitted with a wrong time interval in this case).
I think, this is because rt73usb_write_beacon clears not only TXRX_CSR9_BEACON_GEN flags but also TXRX_CSR9_TSF_TICKING one (this is my guess, I have no Ralink documentation).
To keep beacon in sync I've commented out TXRX_CSR9_TSF_TICKING and TXRX_CSR9_TBTT_ENABLE clearing in rt73usb_write_beacon. I don't know, what the second flag is for, but I think, clearing TXRX_CSR9_BEACON_GEN is enough to prevent invalid beacon generation while new beacon is being uploaded.
So, we clear TXRX_CSR9_BEACON_GEN before uploading the beacon data and set it back further in rt73usb_kick_tx_queue.
[/quote2hoas7t0]

Sounds good, the current code is based on the legacy driver, but perhaps your solution works for the hardware as well.
Might even be applicable for all drivers.


Issue 4. It is related to the mac80211 implementation or hostapd (I'm not yet sure), but just for completeness of my report.
The station can't reconnect (e.g. the PDA can't reconnect after wake up).

Consider following step-by-step
1. A station authenticates at AP and exchanges traffic.
2. The station indicates to the AP that it is going to sleep.
3. The station goes to the stand-by mode (not only the wi-fi card, but the device itself).
4. The station wakes up and begins authentication with an Authentication management frame.
This is the behavior of my PDA.

The problem is the mac80211 stack remembers that the station has gone to sleep. So, response frames from hostapd are buffered by mac80211.
The station indicates in the Authentication frame that it isn't sleeping anymore. But the mac80211 stack analyzes sleep/wake transitions in _data_ frames only, but not in management ones. See ieee80211_rx_h_sta_process in net/mac80211/rx.c. A comment there notes "Ignore doze->wake transitions that are indicated by non-data frames, the standard is unclear here".
As the result, the station never receives the authentication response from the AP.

I think, there may be 2 alternative solutions
A) In mac80211 implementation improve ieee80211_rx_h_sta_process - analyze not only data frames, but also management ones. I've tried to add analysis of authentication frames there and it worked in my case. But I'm not sure if it is enough and if it doesn't brake some other functionality.
B) In hostapd remove the station from the mac80211 stack just after receiving an authentication frame. In my case this approach also works.
[/quote2hoas7t0]

This issue/question belongs on the linux-wireless@vger.kernel.org mailinglist as well, please send it there and you will get an answer from the mac80211 and hostapd developers.

iap

23-07-2009 09:32:47


Issue 2. Oops in rt73usb_write_beacon.
I've found that the oops are caused by two race conditions
* In case of two near calls to set_tim rt2x00lib_beacondone_iter is cleaning the beacon skb, whereas rt73usb_write_beacon is still using it.
* In case of two near updates of beacon first as the result of set_tim and second as the result of a call from hostapd.

To avoid the race I've done the following
* Moved cleanup of the beacon skb from rt2x00lib_beacondone_iter into the beginning of rt2x00queue_update_beacon.
* Added a mutex in struct rt2x00_intf, which guards the entire body of rt2x00queue_update_beacon.

Question 2 Should extra cleanup of the beacon skb be added somewhere else?
Or doing that in rt2x00queue_update_beacon is enough?
[/quote2hvtn1z5]
Will need to see a patch before I can judge that more clearly.
[/quote2hvtn1z5]
The patch is here
http//rt2x00.serialmonkey.com/pipermai ... 00155.html
It is for the kernel 2.6.30, but can be applied to the rt2x00 git kernel tree as well.


But it is too bad a mutex is needed while a spinlock was already present in the rt2x00_intf structure.
[/quote2hvtn1z5]
The spinlock guards members of the structure. And the mutex guards rt2x00_intf->beacon->skb.
Unfortunately, a spinlock can't be used to serialize access to beacon->skb, because a thread can sleep when calling rt73usb_write_beacon (and perhaps analogous functions for other USB drivers) from rt2x00queue_update_beacon.


Issue 3. Delays in traffic exchange are caused by de-synchronization of beacon frames when beacon is being updated to refresh TIM (i.e. two neighbor beacon frames - before and after update - are being transmitted with a wrong time interval in this case).
I think, this is because rt73usb_write_beacon clears not only TXRX_CSR9_BEACON_GEN flags but also TXRX_CSR9_TSF_TICKING one (this is my guess, I have no Ralink documentation).
To keep beacon in sync I've commented out TXRX_CSR9_TSF_TICKING and TXRX_CSR9_TBTT_ENABLE clearing in rt73usb_write_beacon. I don't know, what the second flag is for, but I think, clearing TXRX_CSR9_BEACON_GEN is enough to prevent invalid beacon generation while new beacon is being uploaded.
So, we clear TXRX_CSR9_BEACON_GEN before uploading the beacon data and set it back further in rt73usb_kick_tx_queue.
[/quote2hvtn1z5]
Sounds good, the current code is based on the legacy driver, but perhaps your solution works for the hardware as well.
Might even be applicable for all drivers.
[/quote2hvtn1z5]
The patch for rt73usb is here
http//rt2x00.serialmonkey.com/pipermai ... 00156.html
It is also for the kernel 2.6.30 and also can be applied to the rt2x00 git kernel tree as well.

The solution has been tested when only TXRX_CSR9_BEACON_GEN is set to 0 in rt73usb_write_beacon and isn't set to 1 in rt73usb_kick_tx_queue, beacon frames aren't transmitted. And when this flag is set to 1 some time later, beacon frames are transmitted again in sync with previous sequence.

salsasepp

24-07-2009 18:03:41

Thanks a lot Igor!

I'm still following this. I'd love to test these patches, but I haven't got my hardware at this time.
As to your Issue #1, I just re-checked that my iPod (firmware version 2.2) uses Null Function frames, not PS Poll ones, so I wouldn't have seen that. Same for all other wireless clients (notebooks) I have access to.
As to everything else, no opinion at this time.

Please continue updating this thread as your solution firms up, I plan on some more testing in about 10 days.

Thank you,
Stefan.

salsasepp

24-07-2009 18:25:30


Issue 3. Delays in traffic exchange are caused by de-synchronization of beacon frames when beacon is being updated to refresh TIM (i.e. two neighbor beacon frames - before and after update - are being transmitted with a wrong time interval in this case).
I think, this is because rt73usb_write_beacon clears not only TXRX_CSR9_BEACON_GEN flags but also TXRX_CSR9_TSF_TICKING one (this is my guess, I have no Ralink documentation).
To keep beacon in sync I've commented out TXRX_CSR9_TSF_TICKING and TXRX_CSR9_TBTT_ENABLE clearing in rt73usb_write_beacon. I don't know, what the second flag is for, but I think, clearing TXRX_CSR9_BEACON_GEN is enough to prevent invalid beacon generation while new beacon is being uploaded.
So, we clear TXRX_CSR9_BEACON_GEN before uploading the beacon data and set it back further in rt73usb_kick_tx_queue.
[/quote2rkscooz]
Sounds good, the current code is based on the legacy driver, but perhaps your solution works for the hardware as well.
Might even be applicable for all drivers.
[/quote2rkscooz]
The patch for rt73usb is here
http//rt2x00.serialmonkey.com/pipermai ... 00156.html
It is also for the kernel 2.6.30 and also can be applied to the rt2x00 git kernel tree as well.

The solution has been tested when only TXRX_CSR9_BEACON_GEN is set to 0 in rt73usb_write_beacon and isn't set to 1 in rt73usb_kick_tx_queue, beacon frames aren't transmitted. And when this flag is set to 1 some time later, beacon frames are transmitted again in sync with previous sequence.
[/quote2rkscooz]
I see this Issue 3 in my capture logs as well.

Question please
I understand that a station wakes up its receiver for a very short time span just to receive the beacon. So, when the beacon sequences before and after the PS buffering are out of sync relative to each other, the station will miss all beacons after the PS buffering and never wake up to receive the buffered frames, correct? This would explain the application-level timeouts on a TCP connection I am seeing.

iap

25-07-2009 01:24:02


Question please
I understand that a station wakes up its receiver for a very short time span just to receive the beacon. So, when the beacon sequences before and after the PS buffering are out of sync relative to each other, the station will miss all beacons after the PS buffering and never wake up to receive the buffered frames, correct? This would explain the application-level timeouts on a TCP connection I am seeing.
[/quote3gaxn5lr]
Yes, a station misses beacon frames when they are out of sync and therefore doesn't wake up.
And things look like if the station doesn't receive beacons for a long time it wakes up its receiver for a longer time span and tries to re-synchronize.
In my case this time period didn't exceed 3 seconds and there were no connection timeouts. Just a delay in data transmission.

iap

31-07-2009 21:52:48


Issue 1. The rt73 usb stick is configured to filter out all control frames including the PS Poll one.

Who should configure the filter in a right way the driver, the mac80211 stack or an application (hostapd)?

I'm not sure of that (I'm not a network programming guru -) ) and I've assumed that the driver should.
So, I've added following lines in rt2x00mac_configure_filter
if (rt2x00dev->intf_ap_count)
*total_flags |= FIF_CONTROL;
Note, this is just my "RFC", I'd like to get your comments. Analogous approach I've seen in other wi-fi drivers.
[/quoter1dyrv91]
Not sure, I would say mac80211 should be in charge. But if you want to be really sure, you should
ask on the linux-wireless@vger.kernel.org mailinglist.
[/quoter1dyrv91]
I've posted two RFC patches, which implement filter configuration for PS Poll frames
1. http//marc.info/?l=linux-wireless&m=12 ... 330807&w=2 (mac80211 FIF_PSPOLL filter flag).
2. http//rt2x00.serialmonkey.com/pipermai ... 00163.html (rt2x00 FIF_PSPOLL filter flag support).
Both patches are for current wireless-testing kernel.

Also this thread may be interesting
http//marc.info/?l=linux-wireless&m=12 ... 226634&w=2

The second patch implements support of FIF_PSPOLL for all drivers in drivers/net/wireless/rt2x00 directory. Including rt2400pci, rt2500pci
and rt2500usb, which are not modified at all.
I've tested the patch with rt73usb and rt2500usb sticks only. Unfortunately, I have no other kinds of Ralink hardware.
Any help in testing is very appreciated.

IvD

01-08-2009 05:21:38

For some odd reason I received neither of your 2 patch mails, only the replies to the mails have reached my inbox. S
Could you resend the rt2x00 patch with me in the CC? Thanks.

iap

01-08-2009 06:38:57

Done.
http//rt2x00.serialmonkey.com/pipermai ... 00165.html

Have you received it?

IvD

01-08-2009 20:56:33

Yes, finally found the mail in my spamfolder. S

iap

04-08-2009 20:06:03

JFYI A patch for hostapd solving the Issue 4 has been posted here
http//lists.shmoo.com/pipermail/hostap ... 20055.html

Best regards,
Igor