Right now ath_rate_sample has a fixed rate schedule, rather than the minstrel_ht
style "best, good, most reliable" triplet. So, if higher rates are tried then
it'll not fail back to a lower MCS rate in that transmission schedule.
This means that in low SNR situations it'll not easily drop to MCS0 unless enough
transmissions occur to allow rate control to eventually decide to drop; and if
it's TCP traffic it'll get slowed down because of packet loss.
It's worse for 2-stream and 3-stream rates; it doesn't ever fall back to lower
stream rates, and these higher stream rates required higher SNR to work.
So instead let's (for now?) have each of the 11n transmit rates use MCS0 as
the last attempt. ath_rate_sample will quickly see that rate succeeds more
and will move to it much quicker.
Testing:
* AR9344 (Wasp) - 2G STA mode
These are some fun issues I've found with my upstairs wifi link at such a ridiculous
low signal level (like, < 5dB.)
* Add per-station tx/rx rssi statistics, in potential preparation to use that
in the RX rate control.
* Call the rate control on each received frame to let it potentially use
it as a hint for what rates to potentially use. It's a no-op right now.
* Do ANI calibration during scan as well. The ath_newstate() call was disabling the
ANI timer and only re-enabling it during transitions to _RUN. This has the
unfortunate side-effect that if ANI deafened the NIC because of interference
and it disassociated, it wouldn't be reset and the scan would never hear beacons.
The ANI configuration is stored at least globally on some HALs and per-channel
on others. Because of this a NIC reset wouldn't help; the ANI parameters would
simply be programmed back in.
Now, I have a feeling I also need to do this during AUTH/ASSOC too and maybe,
if I'm feeling clever, I need to reset the ANI parameters on a given channel
during a transition through INIT or if the VAP is destroyed/re-created.
However for now this gets me out of the immediate weeds with connectivity
upstairs (and thus I /can/ commit); I'll keep chipping away at tidying this
stuff up in subsequent commits.
Tested:
* AR9344 (Wasp), 2G STA mode
One of the fun issues with scanning has been how the existing
ANI values were programmed into the hardware when channels were
changed. If you're on a really crappy channel and ANI has made
you deaf then when you scan you continue to be deaf on all channels.
This code passes in a flag to startpcureceive which in AR5416 and later
is also used to enable ANI. This allows it to know if it's a normal
operation or a scan operation.
This fixes my situation at home where a temporary spot of a device
going deaf due to interference starts scanning and .. can't hear
anything until I restart.
Now, this isn't the full fix - ideally:
(a) all the ANI config and per-channel information would be migrated
to the shared HAL stuff and enabled for all of the NICs;
(b) when a station reassociates and some other error conditions
(like missed beacons, NF calibration failures, etc) a knob
to reset ANI parameters would likely help recovery.
But hey, I'm committing bits of code again! woo!
Tested:
* AR9344 (2G), STA operation
- Alignment issues:
* Add missing __packed attributes + padding across all drivers; in
most places there was an assumption that padding will be always
minimally suitable; in few places - e.g., in urtw(4) / rtwn(4) -
padding was just missing.
* Add __aligned(8) attribute for all Rx radiotap headers since they can
contain 64-bit TSF timestamp; it cannot appear in Tx radiotap headers, so
just drop the attribute here. Refresh ieee80211_radiotap(9) man page
accordingly.
- Since net80211 automatically updates channel frequency / flags in
ieee80211_radiotap_chan_change() drop duplicate setup for these fields
in drivers.
Tested with Netgear WG111 v3 (urtw(4)), STA mode.
MFC after: 2 weeks
* The ani function bitmap was being badly used when determining if a command
could be used. In hostap modes only a couple of the ANI control parameters
are enabled.
* The ani function bitmap was not being reset to HAL_ANI_ALL if transitioning
from AP -> STA.
* Change mrcCckOff to mrcCck - 1 == on, rather than 1 == off. This matches
the API used to set the value from userland via the diagnostic API.
* Handle OFDM/CCK noise immunity level commands in ar9300_ani_control().
These will only come from userland and it will go and program the rest of
the ANI control parameters with the values in the ANI table.
* Ensure all of the ANI parameters can be tweaked at runtime, even if they're
disabled.
Tested:
* carambola2 (AR9331), STA/AP modes
I'm trying to debug why reception upstairs here is so terrible and it
turns out ANI is buggy. (Which is no surprise, ANI is always buggy.)
Tested:
* Carambola2 (AR9331), STA/AP modes
If we fail noise floor calibration then we may end up with a deaf NIC
which we can't recover without a full chip reset.
Earlier chips seem to get less stuck in this condition versus AR9280/later
and AR9300/later, but whilst here just fix up the AR5212 era chips to also
return NF calibration failures.
This HAL routine would only return failure if the channel was not configured.
This is a no-op until the driver side code for doing resets and the HAL
code for being told about the reset type (and then handling it!) is
implemented.
Tested:
* AR9280, STA mode
* AR2425, STA mode
* AR9380, STA mode
I'm in the process of reworking how the reset path works with an eye
to better recovery when the chips hang and/or go RF/PHY deaf.
This is the first step in a lot of unification and API changes.
This fixes 32-bit compat (no ioctl command defintions are required
as struct ifreq is the same size). This is believed to be sufficent to
fully support ifconfig on 32-bit systems.
Reviewed by: kib
Obtained from: CheriBSD
MFC after: 1 week
Relnotes: yes
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D14900
For DWDS VAPs on ath(4) we need to ensure that the STA vap and hostap VAP
have different MAC addresses. If the STA code path doesn't utilise the
address assign / reclaim path then it doesn't update the bitmap with which
address was allocated.
This should fix a bunch of corner issues I've been seeing with DWDS STA + AP
VAPs that I was working around with manual MAC address assignment.
Uses of mallocarray(9).
The use of mallocarray(9) has rocketed the required swap to build FreeBSD.
This is likely caused by the allocation size attributes which put extra pressure
on the compiler.
Given that most of these checks are superfluous we have to choose better
where to use mallocarray(9). We still have more uses of mallocarray(9) but
hopefully this is enough to bring swap usage to a reasonable level.
Reported by: wosch
PR: 225197
Focus on code where we are doing multiplications within malloc(9). None of
these is likely to overflow, however the change is still useful as some
static checkers can benefit from the allocation attributes we use for
mallocarray.
This initial sweep only covers malloc(9) calls with M_NOWAIT. No good
reason but I started doing the changes before r327796 and at that time it
was convenient to make sure the sorrounding code could handle NULL values.
Apply the fix from r327499 to additional ioctl handlers.
Reported by: Ilja van Sprundel <ivansprundel@ioactive.com>
MFC after: 1 week
MFC with: r327499
Sponsored by: The FreeBSD Foundation
The ath_btcoex_ioctl handler allocated a buffer without M_ZERO and
returned it to userland without writing to it.
The device has permissions only for root so this is not urgent, and the
fix can be MFCd and considered for a future EN.
Reported by: Ilja van Sprundel <ivansprundel@ioactive.com>
Submitted by: Domagoj Stolfa <domagoj.stolfa@gmail.com>
Reviewed by: adrian
MFC after: 1 week
This removes the direct WME info access in the ieee80211com struct and instead
provides a method of fetching the data. Right now it's a no-op but eventually
it'll turn into a per-VAP method for drivers that support it (eg iwn, iwm,
upcoming ath10k work) as things like p2p support require this kind of behaviour.
Tested:
* ath(4), STA and AP mode
TODO:
* yes, this is slightly stack size-y, but it is an important first step
to get drivers migrated over to a sensible WME API. A lot of per-phy things
need to be converted to per-VAP before P2P, 11ac firmware, etc stuff shows up.
Mainly focus on files that use BSD 2-Clause license, however the tool I
was using misidentified many licenses so this was mostly a manual - error
prone - task.
The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.
As part of ath10k and other chipset support, the EDCA stuff has to be moved
to potentially be per-VAP. For hardware that doesn't support it (ie,
everything that we currently support) it can just fetch the "current"
global EDCA parameters for the NIC.
This is one of those parameters that is linked to the currently active
channel context / VAP in Linux mac80211 parlance.
Tested:
* ath(4), STA and AP modes
It turned out, that some models of the Atheros PCIe
adapters (e.g. AR983x family) may fail to attach
due to insufficient timeout value.
Submitted by: Bartosz Szczepanek <bsz@semihalf.com>
Obtained from: Semihalf
Sponsored by: Stormshield
Reviewed by: adrian
Differential revision: https://reviews.freebsd.org/D10903
In the deep past, when this code compiled as a binary module, ath_hal
built as a module. This allowed custom, smaller HAL modules to be built.
This was especially beneficial for small embedded platforms where you
didn't require /everything/ just to run.
However, sometime around the HAL opening fanfare, the HAL landed here
as one big driver+HAL thing, and a lot of the (dirty) infrastructure
(ie, #ifdef AH_SUPPORT_XXX) to build specific subsets of the HAL went away.
This was retained in sys/conf/files as "ath_hal_XXX" but it wasn't
really floated up to the modules themselves.
I'm now in a position where for the reaaaaaly embedded boards (both the
really old and the last couple generation of QCA MIPS boards) having a
cut down HAL module and driver loaded at runtime is /actually/ beneficial.
This reduces the kernel size down by quite a bit. The MIPS modules look
like this:
adrian@gertrude:~/work/freebsd/head-embedded/src % ls -l ../root/mips_ap/boot/kernel.CARAMBOLA2/ath*ko
-r-xr-xr-x 1 adrian adrian 5076 May 23 23:45 ../root/mips_ap/boot/kernel.CARAMBOLA2/ath_dfs.ko
-r-xr-xr-x 1 adrian adrian 100588 May 23 23:45 ../root/mips_ap/boot/kernel.CARAMBOLA2/ath_hal.ko
-r-xr-xr-x 1 adrian adrian 627324 May 23 23:45 ../root/mips_ap/boot/kernel.CARAMBOLA2/ath_hal_ar9300.ko
-r-xr-xr-x 1 adrian adrian 314588 May 23 23:45 ../root/mips_ap/boot/kernel.CARAMBOLA2/ath_main.ko
-r-xr-xr-x 1 adrian adrian 23472 May 23 23:45 ../root/mips_ap/boot/kernel.CARAMBOLA2/ath_rate.ko
And the x86 versions, like this:
root@gertrude:/home/adrian # ls -l /boot/kernel/ath*ko
-r-xr-xr-x 1 root wheel 36632 May 24 18:32 /boot/kernel/ath_dfs.ko
-r-xr-xr-x 1 root wheel 134440 May 24 18:32 /boot/kernel/ath_hal.ko
-r-xr-xr-x 1 root wheel 82320 May 24 18:32 /boot/kernel/ath_hal_ar5210.ko
-r-xr-xr-x 1 root wheel 104976 May 24 18:32 /boot/kernel/ath_hal_ar5211.ko
-r-xr-xr-x 1 root wheel 236144 May 24 18:32 /boot/kernel/ath_hal_ar5212.ko
-r-xr-xr-x 1 root wheel 336104 May 24 18:32 /boot/kernel/ath_hal_ar5416.ko
-r-xr-xr-x 1 root wheel 598336 May 24 18:32 /boot/kernel/ath_hal_ar9300.ko
-r-xr-xr-x 1 root wheel 406144 May 24 18:32 /boot/kernel/ath_main.ko
-r-xr-xr-x 1 root wheel 55352 May 24 18:32 /boot/kernel/ath_rate.ko
.. so you can see, not building the whole HAL can save quite a bit.
For example, if you don't need AR9300 support, you can actually avoid
wasting half a megabyte of RAM. On embedded routers this is quite a
big deal.
The AR9300 HAL can be later further shrunk because, hilariously,
it indeed supports AH_SUPPORT_<xxx> for optionally adding chipset support.
(I'll chase that down later as it's quite a big savings if you're only
building for a single embedded target.)
So:
* Create a very hackish way to load/unload HAL modules
* Create module metadata for each HAL subtype - ah_osdep_arXXXX.c
* Create module metadata for ath_rate and ath_dfs (bluetooth is
currently just built as part of it)
* .. yes, this means we could actually build multiple rate control
modules and pick one at load time, but I'd rather just glue this
into net80211's rate control code. Oh well, baby steps.
* Main driver is now "ath_main"
* Create an "if_ath" module that does what the ye olde one did -
load PCI glue, main driver, HAL and all child modules.
In this way, if you have "if_ath_load=YES" in /boot/modules.conf
it will load everything the old way and stuff should still work.
* For module autoloading purposes, I actually /did/ fix up
the name of the modules in if_ath_pci and if_ath_ahb.
If you want to selectively load things (eg on ye cheape ARM/MIPS platforms
where RAM is at a premium) you should:
* load ath_hal
* load the chip modules in question
* load ath_rate, ath_dfs
* load ath_main
* load if_ath_pci and/or if_ath_ahb depending upon your particular
bus bind type - this is where probe/attach is done.
TODO:
* AR5312 module and associated pieces - yes, we have the SoC side support
now so the wifi support would be good to "round things out";
* Just nuke AH_SUPPORT_AR5416 for now and always bloat the packet
structures; this'll simplify other things.
* Should add a simple refcnt thing to the HAL RF/chip modules so you
can't unload them whilst you're using them.
* Manpage updates, UPDATING if appropriate, etc.
This brings the AHB support in line with the PCI support - now other "things"
can wrap up the calibration / board data into a firmware blob and have them
probe/attach after the system has finished booting.
Note that this change requires /all/ of the AHB using kernel configurations
to change - so until I drop those changes in, this breaks AHB.
Fear not, I'll do that soon.
TODO:
* the above stuff.
Tested:
* AR9331, carambola 2, loading if_ath / wlan as modules at run time
When I initially did this 11n TX work in days of yonder, my 802.11 standards
clue was ... not as finely tuned. One of the things in 802.11-2012 (which
I guess technically was after I did this work, but I'm sure it was like this
in the previous rev?) is that among other traffic classes, three things are
important:
* group addressed frames should be default non-QoS, even if they're QoS frames, and
* group addressed frames should have a seqno out of a different space than the
per-TID QoS one; and because of this
* group addressed frames, being non-QoS, should never be in the Block-ACK window
for TX.
Now, net80211 and now this code cheats by using the non-QOS TID, but ideally
we'd introduce a separate seqno space just for multicast/group traffic for
TX and RX comparison.
Later extensions (eg reliable multicast / multimedia) express what one should do
when doing multicast traffic in a TID. Now, technically we /could/ do group traffic
as QoS traffic and throw it into a per-TID seqno space, but this definitely
introduces ordering issues when you take into account things like CABQ behaviour.
(Ie, if some traffic in the TID goes into the CABQ and some doesn't, because
it's doing a split of multicast and non-multicast traffic, then you have
seqno ordering issues.)
So, until someone implements 802.11vv reliable multicast / multimedia extensions,
group traffic is non-QoS.
Next, software/hardware queue TID mapping. In the past I believed the WME tagging
of frames because well, net80211 had a habit of tagging things like management
traffic with it. But, then we also map QoS traffic categories to TIDs as well.
So, we should obey the TID! But! then it put some management traffic into higher
WME categories too, as those frames don't have QoS TIDs. But! It'd do things like
put things like QoS action frames into higher WME categories, when they should
be kept in-order with the rest of the traffic for that TID. So! Given all of this,
the ath(4) driver does overrides to not trust the WME category.
I .. am undoing some of this. Now, the TID has a 1:1 mapping to the hardware
queue. The TID is the primary source of truth now for all QoS traffic.
The WME is only used for non-QoS traffic. This now means that any TID traffic
queued should be consistently queued regardless of WME, so things like the
"TX finished, do more TX" that is occuring right now for transmit handling
should be "better".
The consistent {TID, WME} -> hardware queue mapping is important for
transmit completion. It's used to schedule more traffic for that
particular TID, because that {many TID}:{1 TXQ} mapping in ath_tx_tid_sched()
is used for driving completion. Ie, when the hardware queue completes,
it'll walk that list of scheduled TIDs attached to that TXQ.
The eventual aim is to get ready for some other features around putting
some data into other hardware queues (eg for better PS-POLL support,
uAPSD, support, correct-er TDMA support, etc) which requires that
I tidy all of this up in preparation for then introducing further
TID scheduling that isn't linked to a hardware TXQ (likely a per-WME, per-TID
driver queue, and a per-node driver queue) to enable that.
Tested:
* AR9380, STA mode
* AR9380, AR9580, AP mode
Renumber cluase 4 to 3, per what everybody else did when BSD granted
them permission to remove clause 3. My insistance on keeping the same
numbering for legal reasons is too pedantic, so give up on that point.
Submitted by: Jan Schaumann <jschauma@stevens.edu>
Pull Request: https://github.com/freebsd/freebsd/pull/96
This implements hardware assisted quiet IE support. Quiet time is
an optional interval on DFS channels (but doesn't have to be DFS
only channels! sigh) where the station and AP can be quiet in order
to allow for channel utilisation measurements. Typically that's
stuff like radar detection, spectral scan, other-BSS frame sniffing,
checking how busy the air is, etc.
The hardware implements it as one of the generic timers, which is
supplied a period, offset from the trigger period and duration
to stay quiet. The AP can announce quiet time configurations which
change, and so this code also tracks that.
Implementation details:
* track the current quiet time IE
* compare the new one against the previous one - if only the TBTT
counter changes, don't update things
* If tbttcount=1 then program it into the hardware - that is when
it is easiest to program the correct starting offset (one TBTT +
configured offset).
* .. later on check to see if it can be done on any tbttcount
* If the IE goes away then remove the quiet timer and clear the
config
* Upon reset, state change, new beacon - clear quiet time IE
and just let it resync from the next beacon.
History:
This was work done initially by sibridgetech.com in 2011/2012/2013
as part of some FreeBSD wifi DFS contracting work they had for a
third party. They implemented the net80211 quiet time IE pieces
and had some test code for the station side which didn't entirely
use the timers correctly.
I figured out how to use the timers correctly without stopping/starting
the transmit DMA engine each time. When done correctly, the timer
just needs to be programmed once and left alone until the next
configuration change.
So, thanks to Himali Patel and Parthiv Shah for their work way
back then. I finally figured it out and finished it!
TODO:
* Now, I'd rather net80211 did the quiet time IE tracking and parsing,
pushing configurations into the driver is needed. I'll look at
doing that in a subsequent update.
* This doesn't handle multiple quiet time IEs, which will currently
just mess things up. I'll look into supporting that in the future
(at least by only obeying "one" of them, and then ignoring
subsequent IEs in a beacon/probe frame.)
* This also implements the STA side and not the AP side - the AP
side will come later, and involves taking various other intervals
into account (eg the beacon offset for multi-VAP modes, the
SWBA time, etc, etc) as well as obtaining the configuration when
a beacon is configured/generated rather than "hearing" an IE.
* .. investigate supporting quiet IE in mesh, tdma, ibss modes
* .. investigate supporting quiet IE for non-DFS channels
(so this can be done for say, 2GHz channels.)
* Chances are i should commit NULL methods for the ar5210, ar5211 HALs..
Tested:
* AR9380, STA mode - announcing quiet, removing quiet, changing quite
time config, whilst doing iperf testing;
* AR9380, AP mode.
* Although the hardware is awake, the power state handling doesn't think so.
So just explicitly wake it up early in setup so ath_hal calls don't complain.
* We shouldn't be transmitting or ACKing frames during DFS CAC or on passive
channels before we hear a beacon. So, start laying down comments in the
places where this work has to be done.
Note:
* The main bit missing from finishing this particular bit of work is a state
call to transition a VAP from passive to non-passive when a beacon is heard.
CAC is easy, it's an interface state. So, I'll go and add a method to control
that soon.
* limit cabq to 64 - in practice if this stays at ath_txbuf then
all buffers can be tied up by a very busy broadcast domain (eg ARP
storm, way too much MDNS/NETBIOS). It's been like this in the
freebsd-wifi-build AP project for the longest time.
* Now that I figured out the hilarity inherent in aggregate forming
and AR9380 EDMA work, change the per-node to 64 frames by default.
I'll do some more work to shorten the queue latency introduced when
doing data so TCP isn't so terrible, but it's now no longer /always/
tens of milliseconds of extra latency when doing active iperf tests.
Notes:
The reason for the extra latency is partly tx/rx taskqueue handling and
scheduling, and partly due to a lack of airtime/QoS awareness of per-node
traffic. Ideally we'd have different limits/priorities on the QoS/TID
levels per node so say, voice/video data got a better share of buffer
allocations over best effort/bulk data, but we currently don't implement
that. It's not /hard/ to do, I just need to do it.
Tested:
* AR9380 (STA), AR9580 (hostap) - both with the relevant changes.
TCP is now at around 180mbit with rate control and RTS protection
enabled. UDP stays at 355mbit at MCS23, no HT protection.