Although there's no RTS/CTS rate control available yet, the support
is enough to enable firmware rate control for experimenting.
This won't be enabled by default - users will need to set a tunable
before loading the driver (eg kenv dev.rtwn.0.ratectl=2) but it is
enough for experimentation, feedback and continued work.
Locally tested:
* RTL8192CU, STA mode
Differential Revision: https://reviews.freebsd.org/D48143
Reviewed by: bz, emaste
* refactor out the r92c path protection (RTS/CTS) decision
* handle firmware rate control being enabled - if DRVRATE isn't
set then the RTSRATE field is ignored and instead RRSR/INIRTS
registers are used (and the firmware/hardware will do RTS
rate adaptation / retry.)
* when making protection decisions with firmware rate control,
default to the channel mode rather than rate index.
This works on RTL8192CU both with firmware rate control and driver
rate control.
Locally tested:
* RTL8192CU, STA - firmware and net80211 rate control
Differential Revision: https://reviews.freebsd.org/D48142
Refactor out the datarate setup and short preamble setup.
These will eventually be slightly different based on whether
firmware rate control is being performed or not.
Locally tested:
* RTL8192CU, STA mode
Differential Revision: https://reviews.freebsd.org/D48141
The NIC/firmware initialises the initial RTS/CTS rate to something
high, like OFDM48. That's not going to be very reliable.
It's not a problem right now as we program in the RTS/CTS value
to use in the TX descriptor setup path based on the control rate
for the given frame TX rate, and like the INIDATA/driver rate
stuff in the TX descriptor, the TX descriptor RTS/CTS rate overrides
the INIRTS rate.
However when it's time to flip on firmware based rate control,
the initial rate needs to not be OFDM48. Yes, the firmware and
hardware does have some rate retry schedule for RTS/CTS frames,
but there's no point in wasting short retries trying to do OFDM48
based RTS/CTS setup.
Add some warning logging if there are no basic or RTS/CTS rates
available, and leave things at default. If this happens in
production for someone then it would be good to know and what
the rate mask was.
Locally tested:
* RTL8192CU, STA mode (with/without firmware rate control enabled locally)
Differential Revision: https://reviews.freebsd.org/D48140
Although the transmit path doesn't yet support VHT rates (because
the rate control and rate representation in net80211 doesn't yet
know about VHT rates) the NIC will receive VHT frames but only
transmit HT frames.
Locally tested:
* RTL8812AU, STA mode
Differential Revision: https://reviews.freebsd.org/D48103
According to the rtl8812au reference driver, this seems to control
the bandwidth used by lower-bandwidth frames when transmitted in
a higher bandwidth channel. For example, transmitting a 20MHz frame
on an 80MHz channel (eg in hostap mode) is doable, but you may want
to at least duplicate the RTS/CTS exchange across all four 20MHz
subchannels, AND perhaps duplicate the 20MHz frame.
I haven't fired this up with a spectrum analyser to see what the
result is.
The vendor driver doesn't bother with this and it doesn't change
performance. My guess is that for modes like AP mode we MAY wantto
be able to control the RTS/CTS bandwidth choices rather than letting
the firmare do it, but we're not there yet.
The rtl8812au code in hal/rtl8812a_xmit.c:SCMapping_8812() has
the gory details, but then the one place it's used just has it
commented out and 0 (ie "do not care") is always programmed in.
Differential Revision: https://reviews.freebsd.org/D48113
Obtained from: https://github.com/lwfinger/rtl8812au
Reviewed by: bz
If the passed in rate is a VHT rate, use rtwn_ctl_vhtrate() to
find a suitable rate for RTS/CTS.
Differential Revision: https://reviews.freebsd.org/D48295
Reviewed by: bz, cy, emaste
When doing firmware rate control there will be situations where
the rate being passed in needs to actually override the rate
control selection. So add a flag to the descriptor setup path
to indicate that indeed this particular rate should be forced,
rather than rely on the firmware rate control.
This is currently a no-op as firmware rate control isn't working
in-tree, but it is working for me locally with other changes.
Without this, there's no way to force low rates for management,
DHCP traffic, and to allow fixed rate via "ifconfig wlanX ucastrate Y"
to function.
Locally tested:
* RTL8192CU, STA mode (firmware and driver/net80211 rate control)
Differential Revision: https://reviews.freebsd.org/D48100
Reviewed by: bz, gavin
If the driver attach path adds the VHT flag then add the 20/40/80 MHz
VHT channels.
This is a no-op right now as nothing is enabling it.
Differential Revision: https://reviews.freebsd.org/D48097
Reviewed by: bz
The firmware version isn't enough; different firmware is loaded
for different revisions of a given chip. So print out the file too;
it'll make handling reports much easier.
Differential Revision: https://reviews.freebsd.org/D48067
Reviewed by: emaste
* remove the hard-coded ridx values in rate2ridx(), use the RIDX
defines for CCK/OFDM rates
* Add a placeholder rtwn_ctl_vhtrate() which returns the dot11rate
control rate to use for the given VHT rate index. Since net80211
currently doesn't have any VHT PHY tables, there's no mapping for
us to leverage so just return OFDM 12M for now.
* Use the new macro to convert rate index to MCS rate
* Add a printf() in rate2ridx if it's passed a HT/VHT rate.
Differential Revision: https://reviews.freebsd.org/D48098
Reviewed by: bz
This register (array) controls the initial rate to use for each
MACID. There's no need to set it if firmware rate control is enabled -
it'll actually be under firmware control (and we can read it back to
see what choices the firmware is making.)
Locally tested:
* RTL8188EU, STA
* RTL8192CU, STA
* RTL8192EU, STA
Differential Revision: https://reviews.freebsd.org/D48094
Reviewed by: bz
The RTL8188E firmware doesn't have the "full" offload firmware
rate control. Instead, the vendor driver has a bunch of logic
in the driver for rate probing and selection.
Part of this is the periodic TX report - which uploads a summary
of multi-rate retries and drops per MAC. Using it drastically
cuts down on the TX notifications - it's fired from a timer
(defaulting to ~ 1.6 seconds) and is a single receive frame in
the normal bulk RX path.
I've not ported / reimplemented the whole vendor driver rate adaption
code - instead, I'm just using the normal net80211 rate control APIs.
It seems to behave OK - I get 25-30mbit down and 20mbit up using TCP/
speedtest.
Locally tested:
* RTL8188EU, STA mode
Differential Revision: https://reviews.freebsd.org/D48088
Reviewed by: fuz, bz
Obtained from: https://github.com/lwfinger/rtl8188eu/blob/master/hal/Hal8188ERateAdaptive.c
Add support to read/write the MAC/PHY registers.
Hide it behind RTWN_DEBUG.
This doesn't cover the RF registers as they require a different
IO path, but I haven't yet debugged the RF paths.
Locally tested:
* RTL8192CU, STA
* RTL8188EU, STA
* RTL8812AU / RTL8821AU, STA
Differential Revision: https://reviews.freebsd.org/D48084
Reviewed by: bz
I've reviewed all of the linux vendor and upstream drivers.
This SEQ_SEL field isn't a mask and doesn't ever look like it
it was; instead this bit is set to tag QoS data frames.
In fact, it effectively was set to 0 for STA frames and potentially 1
for broadcast/multicast frames as the STA macid of 0 and broadcast/
multicast macid of 1 maps to that. In AP modes it would be tagged
based on bit 0.
So, bring it in line with the vendor and linux drivers.
Locally tested:
* RTL8192CU, STA, hostap
* RTL8188EU, STA
* RTL8192EU, STA
Differential Revision: https://reviews.freebsd.org/D48092
My previous commit meant that APPFCS wasn't enabled during monitor
mode and likely other corner cases.
Ensure it stays on at all times.
This, amusingly, fixes monitor mode in RTL8812AU/RTL8821AU - without it,
I don't see HT/VHT frames in monitor mode but I can still receive them
in normal STA mode.
Differential Revision: https://reviews.freebsd.org/D48112
For some NICs (notably the rtl8192cu that I'm working on) the
firmware rate adaptation requires beacon processing to be enabled.
Instead of making assumptions in the if_rtwn beacon routines (and
honestly all of that should be in the HAL too), create a HAL method
for enabling/disabling beacon processing specifically in STA mode.
Since this isn't necessarily required for all NICs (notably the RTL8188E
NICs, where some will do firmware rate control and some will require
driver rate control), only enable it for the RTL8192CU and RT8192EU.
The RTL8188E and RTL8812/RTL8821 just have no-op routines for now.
Locally tested:
* RTL8192CU, STA mode
Differential Revision: https://reviews.freebsd.org/D48066
Reviewed by: bz
The rate control message was doing 11g+11n without 11b rates, but
the TX descriptor setup supports also falling back on 11b rates
when doing multi-rate retry / per-descriptor rate control.
So, line them up. They're not exactly the same as the TX path
supports pure-N and pure-G modes which the rate control configuration
does not, but there'll need to be a lot more work on supporting
those operating modes anyway (around things like self-generated
frame rate control/masks, beacon config, RTS/CTS selection, etc.)
Locally tested:
* RTL8192CU, STA mode
Differential Revision: https://reviews.freebsd.org/D48081
Reviewed by: bz
I'm unable to reproduce the original problem with my RTL8192CU USB
devices with the current codebase and I can't find any reference
to what this power register is doing - I see it defined in drivers,
but it's not described or used anywhere.
This reverts 7f74097165 -
rtwn_usb(4): fix Tx instability with RTL8192CU chipsets
In any case being able to do higher rate RTS/CTS is beneficial.
Local testing:
* rtl8192cu, STA mode, TX/RX testing
PR: 233949
Differential Revision: https://reviews.freebsd.org/D48026
Reviewed by: imp
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, applied over the
basic rates provided.
* Make sure there's at least an OFDM rate (for 2G/5G) rate available if
the peer node is HT, which avoids the MAC defaulting to MCS7 when
generating ACK/block-ACK.
* Add register definitions for INIDATA/INIRTS, which set the default
data rate when the driver doesn't specify the initial data / RTS/CTS
rates in the TX descriptor.
* Leave a comment about why I've modified the mask from Linux.
Locally tested:
* RTL8192CU, STA mode
* RTL8188EU, STA mode
* RTL8192EU, STA mode
* RTL8812AU, STA mode
Differential Revision: https://reviews.freebsd.org/D48019
Reviewed by: bz
The 32 bit bitmap is enough for CCK/OFDM rates and MCS0..15, but
won't work for > MCS15, nor VHT rates.
So, break out the legacy rates and HT rates.
* break the rates and htrates out
* document which calls are looking up basic rates and which care
about the rates themselves
* ensure the rate bitmap passed into the rate control firmware call
(which isn't enabled yet!) is capped at 28 bits so they don't
set the mode field.
Differential Revision: https://reviews.freebsd.org/D47993
Reviewed by: bz, imp
This is an attempt to reverse engineer what the actual transmit power
calculations are doing and apply net80211 limits on them. It doesn't
look as simple as just applying the check at the end - there are plenty
of places where offsets are calculated between different PHY modes and
1 / 2 antenna MCS transmit rates.
There are also some places where the offset being added is negative,
so handle the potential underflow so when things hit 0, they don't
just wrap and cause the maximum transmit power into the registers.
This is being done to aide in power/performance debugging - if there
are issues with the transmit power being wrongly calculated and are too
high, the output waveform will be distorted and it will effect performance.
Being able to drop the transmit power by a few dB here and there can
quickly identify if this is happening (because suddenly higher MCS
rates / OFDM rates suddenly work better!)
I've tested each NIC through the transmit power values from 0 dBm
to 30dBm via ifconfig (and they're all capped far before that,
normally around 20-25dBm) and they're not underflowing.
Locally tested:
* RTL8192CU, STA
* RTL8192EU, STA
* RTL8188EU, STA
Differential Revision: https://reviews.freebsd.org/D47987
Reviewed by: bz, imp
* Refactor out the TX power register register dump - it's done in
a couple places and it makes sense to refactor it.
* Condense the output into a few lines per transmit chain. It's
very long with the 8 and 16 MCS rates, and it made it difficult
to eyeball what's going on when tweaking TX power.
Differential Revision: https://reviews.freebsd.org/D47986
Reviewed by: bz, imp
The RTL8188/RTL8192/RTL8821/RTL8812 NICs all seem happy to have
their transmit power changed at runtime - and it does seem to do
what's expected - the transmit power level does change.
So, add the API call here, even though it's all currently no-ops.
A follow-up commit will land changes for the chipsets to both
limit transmit power to the configured / regulatory limit AND
allow reconfiguration at runtime.
Differential Revision: https://reviews.freebsd.org/D47979
Reviewed by: bz, imp
This apparently kicks off TX power level self-calibration, which
can't hurt.
Locally tested:
* RTL8812AU, STA
* RTL8821AU, STA
Obtained from: Linux rtw88
Differential Revision: https://reviews.freebsd.org/D47978
Reviewed by: bz, imp
* add a register value for the R92C_FPGA0_POWER_SAVE register
* add the field names and mask
* add a mask for the 40MHz upper/lower bits in R92C_RMRR; I think
I need to debug and overhaul the 20/40MHz config path to get 40MHz
working right.
Local testing:
* rtl8188eu, sta mode
* rtl8192cu, sta mode
* RX frames with short-GI can be either HT or VHT
* Add placeholders for RX VHT rate, PHY type, etc
Differential Revision: https://reviews.freebsd.org/D47902
After discussion with the rtlwifi maintainers, it looks like this
path isn't even used.
(And it's part of the firmware rate control path which we currently
don't enable for other reasons.)
Differential Revision: https://reviews.freebsd.org/D47938
This is needed to be able to successfully transmit VHT frames.
Locally tested:
* RTL8821AU, STA mode (with the rest of VHT work to actually test VHT)
Differential Revision: https://reviews.freebsd.org/D47899
The VHT rate power array wasn't populated, and it needs to be in order
to use VHT rates.
The vendor driver reuses the HT40 values for VHT rates.
Differential Revision: https://reviews.freebsd.org/D47898
In preparation for the VHT TX power programming, refactor out the
CCK, OFDM and HT programming into their own routines.
Locally tested:
* RTL8821AU, STA mode
* expand the ridx field all the way through 4x4 11n (MCS0..MCS31)
* and then expand it through VHT 4x4 (MCS0..9 for each stream)
* add accessor macros to check if the rate is HT, VHT
* use accessor macros to check if the rate is HT rather than
comparing it against OFDM54 or RIDX_HT_MCS(0); the values
aobve HT MCS will be VHT, and we don't want to trigger on those!
* add a couple of appropriate TODO VHT bits in the TX path
Locally tested:
* RTL8192CU, STA mode
* RTL8188EU, STA mode
* RTL8821AU, STA mode
* RTL8192EU, STA mode
Differential Revision: https://reviews.freebsd.org/D47896
Some chipsets (such as the RTL8188E) have firmware which supports
a second kind of TX report - instead of a per-packet TX report,
it can generate a per-MACID summary of packet success/failure counters.
This would be helpful for those chips to cut back on the USB traffic
to get rate control feedback for the driver based rate control we're
currently using.
This is a no-op; it just gets the pieces in place for future work.
Differential Revision: https://reviews.freebsd.org/D47894
HT40 works fine in 2GHz and 5GHz modes in both 1 and 2 stream
scenarios, so just enable it here.
Differential Revision: https://reviews.freebsd.org/D47874
Using ieee80211_ht_check_tx_ht40() means that not only the
bss and node channel are checked, but the ni_chw value is also
now correctly checked.
Differential Revision: https://reviews.freebsd.org/D47862
The TSF64 extension involves at least 3 reads from TSF registers
(R92C_TSFTR(0), R92C_TSFTR(1), R92C_TSFTR(2)) which are 4 byte
control transfers. They take up valuable USB link time.
It's likely much less expensive for PCIe adapters. At some point
it may be worthwhile enabling it by default just for those.
With this disabled, the only USB traffic that I see during
normal data operation are bulk TX/RX data transfers for 802.11
packets, and on NICs w/ net80211 rate control, the control register
space read/writes for TX completion. (And that will also need
addressing.)
This is the difference between 15mbit TCP RX and 30mbit TCP RX
on the 11n NICs, and around 40 to 50mbit TCP RX on the 11ac NICs
in HT40 and VHT80.
Locally tested:
* RTL8188EU, STA mode
* RTL8192CU, STA mode
* RTL8192EU, STA mode
* RTL8811AU, STA mode
* RTL8821AU, STA mode
Differential Revision: https://reviews.freebsd.org/D47861
This option stems from a bunch of issues a long time ago where HT40
support on some NICs is unstable - likely because we're not setting
up the RF/baseband correctly.
In any case, it doesn't need to be conditionally compiled anymore.
Leave it in, leave it off by default, and various chipset initialisation
paths can decide whether to enable it themselves.
Reviewed by: emaste
All of the supported NICs should support this.
Locally tested:
* RTL8192CU, STA mode
* RTL8192EU, STA mode
* RTL8821AU, STA mode
* RTL8812AU, STA mode
Differential Revision: https://reviews.freebsd.org/D47776
I noticed that on RTL8812AU/RTL8821AU receiving VHT frames that
I'd occasionally see frames missing the last 4 bytes. I can
easily reproduce it with a ping sweep and fast (10ms) between frames.
There's also a report of an earlier NIC (RTL8188EU) doing the same
thing with HT frames but not with OFDM (11g) frames.
After a bunch of poking, it turns out a driver where things DID work
properly for the other report kept FCS enabled, and trimmed it from
the frame before pushing it up to the network layer.
I did the same and it also worked fine.
The other solution was to disable PHYSTATUS notifications, but then
we'd get no per packet RX notifications (RX rate, RSSI, etc.)
Locally tested:
* RTL8192EU, STA mode (HT)
* RTL8812AU, STA mode (HT, VHT)
* RTL8821AU, STA mode (HT, VHT)
Differential Revision: https://reviews.freebsd.org/D47775
* Add support for 80MHz channels during IQ calibration
* Correct the RAID flags for 1 and 2 stream VHT - the later ones
are for 2GHz VHT and then 3/4 stream VHT
* Add VHT to the RAID calculation for when we eventually transmit
VHT rates.
Obtained from: Linux rtw88 (https://github.com/lwfinger/rtw88)
Differential Revision: https://reviews.freebsd.org/D47774