ieee80211_alloc_node() does not initialize rateset tables; that's not
expected by rate control modules and will result in array access at
index -1 - where ni_essid[] array is located (zeroed at allocation, so
there are no user-visible consequences).
Just delay rate control initialization to the moment, when rateset
tables are initiaziled; nothing will use rates here anyway.
MFC after: 4 days
The comment above ieee80211_ageq_cleanup specifically notes that the queue
is assumed to be empty, and in order to make it so, ieee80211_ageq_drain
must be used.
Submitted by: Augustin Cavalier <waddlesplash@gmail.com>
Obtained from: Haiku (dffc3e235360cd7b71261239ee8507b7d62a1471)
MFC after: 1 week
As the comment says, ifdetach might be called during the course of driver
detach if initialization failed. This shouldn't be a total failure, though,
we just have nothing to do there.
This has been modified slightly from Augustin's original commit to move the
bail-out slightly earlier since the ic wouldn't have been added to the
ic list in the first place, and a comment has been added describing when
this might be an issue.
Submitted by: Augustin Cavalier <waddlesplash@gmail.com>
Obtained from: Haiku (e6f6c1b4633532a8ad37c803dc7c65601e5b24ba)
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
Move copy-pasted code for RTS/CTS frame allocation into net80211.
While here, add stat / debug message for allocation failures
(copied from run(4)) + return error here in bwn(4).
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D14628
- Add some basic checks for i_fc* bits (ToDS, FromDS, MoreFrag, Protected);
those are used / checked across various places in Tx path.
- Mark injected 802.11 frame as encapsulated (just as it should be).
- Classify 802.11 frame in a proper way (extract ether_type from LLC header
for Data frames, use AC_BE queue for others (NoData / Management / Control).
- Subtract header length from tx_bytes statistics (so it will correspond
to the comment).
Was checked with RTL8188EU (AP) + Intel 6205 (STA).
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D13161
Select proper mode when node can do VHT.
Currently there are no drivers with VHT support in the tree,
so this should be noop.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D9806
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.
No functional change intended.
The duplicate detection code currently expects A-MSDU frames to be encaped -
they're decap'ed /after/ duplicate detection.
However for ath10k (and iwm hardware later on) the firmware supports
doing A-MSDU decap in hardware - which shows up as multiple frames with
the same sequence number and IV.
This is the first part of decap handling - if we see a stretch of A-MSDU
frames from the driver with the MORE bit set, then don't treat them
as duplicates.
This isn't 100% complete as crypto sequence number handling and "A-MSDU in
A-MPDU" needs handling, but it's a start.
This should be a glorified no-op for everyone. Please tell me if it isn't.
Fragment number field (part of i_seq) is used for AAD calculation;
as a result, without this patch every driver without h/w crypto support
need to clear it before ieee80211_crypto_encap().
Also fixes rtwn(4) A-MPDU Tx with dev.rtwn.%d.hwcrypto tunable
set to 0 (h/w crypto is disabled).
Tested with:
* Intel 6205, STA mode.
* RTL8188EU, STA mode.
Differential Revision: https://reviews.freebsd.org/D10753
When doing AMSDU offload, the driver (for now!) presents 802.11 frames with
the same sequence number and crypto sequence number / IV values up to the stack.
But, this will trip afoul over the sequence number detection.
So drivers now have a way to signify that a frame is part of an offloaded
AMSDU group, so we can just ensure that we pass those frames up to the
stack.
The logic will be a bit messy - the TL;DR will be that if it's part of
the previously seen sequence number then it belongs in the same burst.
But if we get a repeat of the same sequence number (eg we sent an ACK
but the receiver didn't hear it) then we shouldn't be passing those frames
up. So, we can't just say "all subframes go up", we need to track
whether we've seen the end of a burst of frames for the given sequence
number or not, so we know whether to actually pass them up or not.
The first part of doing all of this is to ensure the ieee80211_rx_stats
struct is available in the RX sequence number check path and the
RX ampdu reorder path. So, start by passing the pointer into these
functions to avoid doing another lookup.
The actual support will come in a subsequent commit once I know the
functionality actually works!
For now there isn't any per-VAP WME state. The eventual aim is to migrate
the driver direct use of WME parameters over to use these methods as
appropriate (global for most devices, per-VAP for firmware NICs that support
it) in preparation for actual per-VAP WME (and other thing) state change
support.
This is in preparation for A-MSDU decap in A-MPDU support.
* refactor out the code to purge a single reorder slot into ampdu_rx_purge_slot().
* refactor out the code to add a frame to the given reorder slot
to ampdu_rx_add_slot().
This should be a big no-op as far as current code is concerned.
Tested:
* QCA9880v2, STA mode (11ac)
* iwn(4), STA mode (11n)
Reviewed by: avos
Differential Revision: https://reviews.freebsd.org/D10328
The "dispatch a frame from the A-MPDU reorder buffer" code is essentially
duplicated in a couple of places. This refactors it out into a single
place in preparation for A-MSDU in A-MPDU offload support, where multiple
A-MSDUs are decap'ed in hardware to 802.3/802.11 frames, but with the
same sequence number.
Reviewed by: avos
Differential Revision: https://reviews.freebsd.org/D10240
If this is the last running vap wait until device will be powered off
(fixes panic when 'ifconfig wlan0 destroy' is executed for running iwn(4)
interface).
Tested with:
- Intel 6205, STA mode.
- RTL8188EU, STA / IBSS modes.
- RTL8821AU, STA / HOSTAP modes.
This should reduce overhead for aggregates (since every second frame
clears the queue and reschedules the task there is no need to cancel
the callout here; let it just run once at the end - even if queue is
empty).
Reported by: adrian
This should allow to drop 'ieee80211_ff_[age/flush]' calls from drivers
(an additional call can be made from ieee80211_tx_complete()
for non-default ieee80211_ffagemax values to prevent stalls -
but it will require an additional counter for transmitted frames).
Tested with RTL8821AU, STA mode (A-MSDU part only).
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D9984
As part of (eventual) p2p/tdls/multi-STA support, a lot of global configuration
parameters (WME, ERP (slot, preamble), channel width, HT protmode, etc are the
biggest offenders) should be per-VAP.
For multi-BSS VAP operation they may be linked, but for p2p/TDLS
operation that can be off-channel they can definitely be different
(think: 2GHz STA, 5GHz p2p.)
The global configuration view of these is mostly a "configure the current
non-smart-firmware NIC" view. This should be split up into per-VAP state,
then a global non-smart-firmware-NIC management layer to handle channel
changes and such in software.
This is step one in a loooong road for this. It should be a big non-functional
change for everyone.
* create a per-VAP WME update call.
* call it if its set, and call the global callback if it isn't
This still uses global WME state - it's just preparation for a future change
which will make the WME state per-VAP and fall through to a shared WME
configuration for hostap operation.
Note: this requires a full kernel recompile; the internal net80211 ABI has changed.
Reviewed by: avos
Differential Revision: https://reviews.freebsd.org/D9986
ucast/mcast/mgmt HT rate.
- Init global ieee80211_htrateset only once; neither ic_htcaps nor
ic_txstream is changed when device is attached;
- Move global ieee80211_htrateset structure to ieee80211com;
there was a possible data race when more than 1 wireless device is
used simultaneously;
- Discard unsupported rates in ieee80211_ioctl_settxparams(); otherwise,
an unsupported value may break connectivity (actually,
'ifconfig wlan0 ucastrate 8' for RTL8188EU results in immediate
disconnect + infinite 'device timeout's after it).
Tested with:
- Intel 6205, STA mode.
- RTL8821AU, STA mode.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D9871
* Migrate the rx_params stuff out from ieee80211_freebsd.h where it doesn't belong -
this isn't freebsd specific anymore.
* Don't use a hard-coded number of chains in the ioctl header; now we can shuffle
MAX_CHAINS around so it can be used in the right spot.
* Extend the signal/noisefloor levels in the mimo stats struct to userland to include
the signal and noisefloor levels for each 20MHz slice of a 160MHz channel.
* Bump the number of EVM pilots in preparation for 4x4 and 160MHz channels.
Tested:
* ath(4), STA mode
* iwn(4), STA mode
* local ath10k port, STA mode
TODO:
* 11ax chips will come with 5GHz 8x8 hardware for lots of MU-MIMO - I'll re-bump it
at that point.
Note:
* This breaks the driver and ifconfig ABI; please recompile the kernel,
ifconfig and wpa_supplicant/hostapd.
* on the station side, only call the quiet time IE method if we have a
quiet IE - otherwise call the NULL method once, and then don't waste
time calling NULL
* on the beacon generation side - force a beacon regeneration each time
quiet time is enabled/disabled. Without this, enabling/disabling quiet
time IE would cause the beacon contents to be corrupted since none of
the "move contents around" logic (like for CSA and TIM handling) is implemented.
This changes the size of ieee80211_node so it requires a kernel recompile,
but no userland recompile.
Tested:
* AR9380, AP mode, enabling/disabling quiet time IE
* AR9380, STA mode, with upcoming driver changes.
The quiet time counter update is happening each time the IE is added,
which also means it happens for each quiet time IE addition to the probe
response.
Only update the countdown if we request ie (ie, beacon updates.)
Flags
- IEEE80211_F_ASCAN
- IEEE80211_F_SIBSS
- IEEE80211_F_IBSSON
are not used since r170530 (old WI compatibility ioctls removal)
and r178354 (removed from other places).
IEEE80211_F_TXPOW_FIXED was never utilized; initially added with
IEEE80211_F_TXPOW_AUTO / IEEE80211_F_TXPOW_OFF flags,
which were replaced with IEEE80211_C_TXPMGT capability check in r138568.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D9369
After some digging and looking at packet traces, it looks like the
sequence number allocation being done by net80211 doesn't meet
802.11-2012.
Specifically, group addressed frames (broadcast, multicast) have
sequence numbers allocated from a separate pool, even if they're
QoS frames.
This patch starts to try and address this, both on transmit and
receive.
* When receiving, don't throw away multicast frames for now.
It's sub-optimal, but until we correctly track group addressed
frames via another TID counter, this is the best we can do.
* When doing A-MPDU checks, don't include group addressed frames
in the sequence number checks.
* When transmitting, don't allocate group frame sequence numbers
from the TID, instead use the NONQOS TID for allocation.
This may fix iwn(4) 11n because I /think/ this was one of the
handful of places where ni_txseqs[] was being assigned /outside/
of the driver itself.
This however doesn't completely fix things - notably the way that
TID assignment versus WME assignment for driver hardware queues
will mess up multicast ordering. For example, if all multicast
QoS frames come from one sequence number space but they're
expected to obey the QoS value assigned, they'll end up in
different queues in the hardware and go out in different
orders.
I can't fix that right now and indeed fixing it will require some
pretty heavy lifting of both the WME<->TID QoS assignment, as well
as figuring out what the correct way for drivers to behave.
For example, both iwn(4) and ath(4) shouldn't put QoS multicast
traffic into the same output queue as aggregate traffic, because
the sequence numbers are all wrong. So perhaps the correct thing
to do there is ignore the WME/TID for QoS traffic and map it all
to the best effort queue or something, and ensure it doesn't
muck up the TID/blockack window tracking. However, I'm /pretty/
sure that is still going to happen.
.. maybe I should disable multicast QoS frames in general as well,
but I don't know what that'll do for whatever the current state
of 802.11s mesh support is.
Tested:
* STA mode, ath10k NIC
* AP mode, AR9344/AR9580 AP
* iperf tcp/udp tests with concurrent multicast QoS traffic.
Before this, iperfs would fail pretty quickly because the sending
AP would start sending out QoS multicast frames that would be
out of order from the rest of the TID traffic, causing the blockack
window to get way, way out of sync.
This now doesn't occur.
TODO:
* verify which QoS frames SHOULD be tagged as M_AMPDU_MPDU.
For example, QoS NULL frames shouldn't be tagged!
Reviewed by: avos
Differential Revision: https://reviews.freebsd.org/D9357
* allocate an ext bit for fragment offload. Some NICs (like the ath10k
hardware in native wifi or 802.3 mode) support doing packet fragmentation
in firmware/hardware, so we don't have to do it here.
* allocate an ext bit for VHT and start using it.
I added IEEE80211_TX_LOCK() a few years ago because there were races between
seqno allocation, driver queuing and crypto IV allocation. This meant that
they'd appear out of sequence and the receiver would drop them, leading to
terrible performance or flat out traffic hangs.
This flag should be set by drivers that do their own sequence number
allocation for all frames it needs to happen for, including beacon frames.
Eventually this should lead to the driver taking care of locking for
allocating seqno and other traffic-triggered events (eg addba setup.)
This is the bulk of the magic to start enabling VHT channel negotiation.
It is absolutely, positively not yet even a complete VHT wave-1 implementation.
* parse IEs in scan, assoc req/resp, probe req/resp;
* break apart the channel upgrade from the HT IE parsing - do it after the
VHT IEs are parsed;
* (dirty! sigh) add channel width decision making in ieee80211_ht.c htinfo_update_chw().
This is the main bit where negotiated channel promotion through IEs occur.
* Shoehorn in VHT node init ,teardown, rate control, etc calls like the HT
versions;
* Do VHT channel adjustment where appropriate
Tested:
* monitor mode, ath10k port
* STA mode, ath10k port - VHT20, VHT40, VHT80 modes
TODO:
* IBSS;
* hostap;
* (ignore mesh, wds for now);
* finish 11n state engine - channel width change, opmode notifications, SMPS, etc;
* VHT basic rate negotiation and acceptance criteria when scanning, associating, etc;
* VHT control/management frame handling (group managment and operating mode being
the two big ones);
* Verify TX/RX VHT rate negotiation is actually working correctly.
Whilst here, add some comments about seqno allocation and locking. To achieve
the full VHT rates I need to push seqno allocation into the drivers and
finally remove the IEEE80211_TX_LOCK() I added years ago to fix issues. :/