Page MenuHomeFreeBSD

rtwn: add a default OFDM and MCS0 rate for self-generated frames
ClosedPublic

Authored by adrian on Dec 10 2024, 7:08 PM.
Referenced Files
Unknown Object (File)
Thu, Dec 26, 7:50 AM
Unknown Object (File)
Thu, Dec 26, 6:43 AM
Unknown Object (File)
Wed, Dec 25, 11:23 AM
Unknown Object (File)
Wed, Dec 25, 9:32 AM
Unknown Object (File)
Wed, Dec 25, 6:36 AM
Unknown Object (File)
Fri, Dec 20, 8:13 PM
Unknown Object (File)
Thu, Dec 19, 7:42 PM
Unknown Object (File)
Thu, Dec 19, 7:01 PM
Subscribers

Details

Summary

I noticed during testing that the MAC was generating MCS7 ACKs and
MCS7 block-ACK frames in response to MCS frames from its peer.
This is very suboptimal - it means that unless you're very close
to your peer (in this case a 2GHz AP), you'll end up failing a lot
of ACKs.

Linux faced the opposite problem in rtl8xxxu - the rate set being
programmed in here included a lot MORE rates, including MCS 0->7
and OFDM 6M->54M. This meant that they were INTENTIONALLY telling
the hardware to transmit at higher rates, and their fix was to
mask out the higher rates so self-generated frames don't try the
high rates at all.

Now, I am not sure why I'm not seeing any OFDM or HT basic rates.
We don't mark any OFDM / HT rates as basic in net80211 (in
ieee80211_phy.c) so I'm going to need to go and do a review of the
standard to see what's up. Additionally, the HT rate set that we
populate isn't tagging any of the HT rates as IEEE80211_RATE_BASIC,
so the code I added for now is a no-op.

So:

  • Extend rtwn_get_rates() and its consumers to populate the HT rateset with basic rates if they're provided
  • Add a default 2GHz / 5GHz mask, inspired by linux
  • Make sure there's at least an OFDM and MCS rate available if the peer node is HT, which avoids the MAC defaulting to MCS7 when generating ACK/block-ACK.

Locally tested:

  • RTL8192CU, STA mode

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

imp added inline comments.
sys/dev/rtwn/if_rtwn.c
1206

does it matter that these initializers are done only once not each loop (IIRC)

This revision is now accepted and ready to land.Thu, Dec 12, 6:07 PM
  • correct description
  • correct mask
  • add documentation about why the magic values are magic
This revision now requires review to proceed.Sat, Dec 14, 6:13 PM
bz added inline comments.
sys/dev/rtwn/if_rtwn.c
1251

remove extra blank line

bz added inline comments.
sys/dev/rtwn/if_rtwn.c
1206

@imp they should be done on every iteration. In the end it won't matter as rtwn_get_rates() assignes a new value and overwrites in this case. So possibly the question should have been if the initialization is pointless in first place?

#include <stdio.h>
#include <sys/types.h>

int
main(int argc, char *argv[])
{
        for (int i = 0; i < 3; i++) {
                uint32_t x = 0, y = 0;
                printf("%d: x %#10x, y %#10x\n", __LINE__, x, y);
                x |= (1 << (i * 8));
                y += 7;
                printf("%d: x %#10x, y %#10x\n", __LINE__, x, y);
        }
        return (0);
}
 
9: x          0, y          0
12: x        0x1, y        0x7
9: x          0, y          0
12: x      0x100, y        0x7
9: x          0, y          0
12: x    0x10000, y        0x7
This revision is now accepted and ready to land.Wed, Dec 18, 10:30 PM