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. :/
This sets up:
* vht capabilities in vaps;
* calls vht_announce to announce VHT capabilities if any;
* sets up vht20, vht40 and vht80 channels, assuming the regulatory code
does the right thing with 80MHz available ranges;
* adds support to the ieee80211_add_channel_list_5ghz() code to populate
VHT channels, as this is the API my ath10k driver is using;
* add support for the freq1/freq2 field population and lookup that
VHT channels require.
The VHT80 code assumes that the regulatory domain already has limited VHT80
bands to, well, 80MHz wide chunks.
This is needed for two reasons:
* Drivers will need to know what the negotiated set of VHT capabilities
and rates are in order to configure (and reconfigure for opmode/chanwidth
changes) how to speak to a given peer; and
* Because some vendors are "special", we should be careful in what we announce
to them during peer association.
This isn't the complete solution, as I still need to make sure that when
sending out probe requests before we know what we want, we don't limit
the capabilities being announced. This is important for IBSS/mesh work
later on as probe request/response exchanges are the first hint at what
a peer supports. I'll look at adding that to the API soon.
This is a skeleton set based on ieee80211_ht.c. It implements some IE
parsing, some basic unfinished negotiation, and channel promotion/demotion.
However, by itself it's not enough to do VHT - notably, the actual
channel promotion for STA mode at least is done in ieee80211_ht.c as
part of htinfo_update_chw(). I was .. quite amused when I found that
out.
I'm checking this in so others can see progress rather than one huge
commit when VHT is "done" (which will likely be quite a while.)
* Add the VHT capability element to the driver capabilities so ifconfig
can see if VHT is available
* Add ioctl plumbing for enabling/disabling VHT and each of the VHT
widths.
Note: this DOES change the ABI (the driver caps ioctl struct size, sigh)
so this will require a recompile of at least ifconfig.
In preparation for VHT station support, we need to store VHT IEs when
scanning so we can choose to upgrade to VHT.
This doesn't change the ABI - it just steals spare[] entries.
The VHT operational element (VHTOPMODE) isn't a uint32_t - it's
the MCS sets, freq1/freq2 parameters and channel width.
So, store the channel width too in lieu of just storing the
IE struct.
This changes the VHT parameter layout in ieee80211_node but it
doesn't change ABI at all.
The 11n code uses these bits for both configuration /and/ controlling
the channel width on softmac chips - it uses it to find the widest
width for all VAPs (eg a HT20 vap and a HT40 vap) to know what to
configure the ic_curchan.
For fullmac devices it isn't /as/ important, as each virtual device
exposed by the firmware will likely have its own configuration and the
firmware figures out what to do to enable it.
These came from Linux mac80211 headers and are configuration bits, not
VHTOPMODE field parameters.
Whilst here, add the field names for the VHTCAP bits.
Tested:
* ath10k, 11ac STA mode
* rename the ieee80211com field for vht mcsinfo to be ic_, not iv;
* add a vht config field, stealing from the spares I left there.
This doesn't change the ABI.
The ath10k firmware supports hardware WEP offload, and in native wifi mode
(or 802.3 ethernet mode, for that matter) the WEP key isn't actually included
in the TX payload from net80211. Instead, a separate firmware command is issued
that sets the default TX key to be the specified key.
However, net80211 doesn't at all inform the driver layer that this is
occuring - it just "expects" to be inserting WEP header information
when doing WEP TX, even with hardware encryption.
So, to better support the newer world order, turn the default TX key assignment
into a VAP method that can be overridden by the driver and ensure its wrapped
in a crypto begin/end set. That way it should be correctly atomic from the
point of view of keychanges (as long as the driver does the right thing.)
It'd be nice if we passed through to the key_set call a flag that says
"also make this the default key" - that's captured here by calling the
deftxkey method after the key_set method. Maybe I can do that later.
Note: this is a net80211 ABI change, and will require a kernel+modules
recompile. Happy Holidays, etc.
Tested:
* ath10k driver port
* rtwn_usb, WEP station
This is a work in progress and some of this stuff may change;
but hopefully I'm laying down enough stuff and space in fields
to allow it to grow without another major recompile.
We'll see!
* Add a net80211 PHY type for VHT 2G and VHT 5G.
Note - yes, VHT is supposed to be for 5GHZ, however some vendors
(*cough* most of them) support some subset of VHT rate support
in 2GHz. No - not 80MHz wide channels, but at least some MCS8-9
support, maybe some beamforming, and maybe some longer A-MPDU
aggregates. I don't want to even think about MU-MIMO on 2GHz.
* Add an ifmedia placeholder type for VHT rates.
* Add channel flags for VHT, VHT20/40U/40D/80/80+80/160
* Add channel macros for the above
* Add ieee80211_channel fields for the VHT information and flags,
along with some padding (so this struct definitely grows.)
* Add a phy type flag for VHT - 'v'
* Bump the number of channels to a much higher amount - until we get
something like the linux mac80211 chanctx abstraction (where the
stack provides a current channel configuration via callbacks,
versus the driver ever checking ic->ic_curchan or similar) we'll
have to populate VHT+HT combinations.
Eg, there'll likely be a full set of duplicate VHT20/40 channels to match
HT channels. There will also be a full set of duplicate VHT80 channels -
note that for VHT80, its assumed you're doing VHT40 as a base, so we
don't need a duplicate of VHT80 + 20MHz only primary channels, only
a duplicate of all the VHT40 combinations.
I don't want to think about VHT80+80 or VHT160 for now - and I won't,
as the current device I'm doing 11ac bringup on (QCA9880) only does
VHT80.
I'll likely revisit the channel configuration and scanning related
stuff after I get VHT20/40 up.
* Add vht flags and the basic MCS rate setup to ieee80211com, ieee80211vap
and ieee80211_node in preparation for 11ac configuration.
There is zero code that uses this right now.
* Whilst here, add some more placeholders in case I need to extend
out things by some uint32_t flag sized fields. Hopefully I won't!
What I haven't yet done:
* any of the code that uses this
* any of the beamforming related fields
* any of the MU-MIMO fields required for STA/AP operation
* any of the IE fields in beacon frame / probe request/response handling
and the calculations required for shifting beacon contents around
when the TIM grows/shrinks
This will require a full rebuild of net80211 related programs -
ifconfig, hostapd, wpa_supplicant.
I'm teaching my ath10k port to communicate up the per-rate / channel width
information I get from the firmware.
The HT40 flag field should just be retired and instead moved to use the
PHY bandwidth field.
* ic_freq is the centre of the primary channel, not the centre of the
HT40/HT80/etc channel. Add a method to access that.
* Add a method to access the centre of the primary channel, including
knowing the centre of the 5/10/20/40/80, versus the primary channel.
Ie, it's the centre of the 40, 80, 160MHz channel.
* Add a method to access the centre frequency of the secondary 80MHz
channel - we don't support VHT yet, but when we do.
* Add methods to access the current channel and the per-dev desired
channel. Ideally drivers that do full offload with a per-vap channel
configuration should use the vap channel, NOT ic_curchan.
Non-offload drivers that require net80211 to change the channel should
be accessing ic_curchan.
TODO:
* drink real coffee before committing in the morning, or there's a high
risk of more obviously self-evident commits being turned into attempts
at humour.
Reported by: cem, Coverity CID 1366219
This just stores pointers to the IE; it doesn't yet parse anything.
Note: it blows out the size of ieee80211_node, so this will require
ye olde kernel/modules recompile.
* Pepper comments around which describe what state(s) we're in when faking
up 11n nodes.
* By default don't fake it up as 11n until we properly negotiate the 11n
capabilities using probe request/response frames.
* Send a probe request with our HT information, as the 802.11-2012 spec
suggests.
* Reassociate with the driver if we've been promoted.
This is done because although learning a peer via beacons can learn 11n
state, learning peers via hearing probe frames and broadcast frames
does not. Thus, sometimes you end up with an 11n peer in the peer
table and sometimes you don't.
Note that the probe request/response exchange may not actually succeed.
Ideally we'd put the peer into some blocking state until we've exchanged
probe request/reponse to learn capabilities, or we timeout and just
stay non-11n.
This is more an experiment to get 11n IBSS nodes actually discovering
each other and be able to transmit. There are other issues that creep
up which I'll attempt to address in future commits.
Tested:
* AR9380 NICs in 11n mode.
Reviewed by: avos
Differential Revision: https://reviews.freebsd.org/D8365
* teach the crypto modules about receive offload - although I have
to do some further reviewing in places where we /can't/ have an RX key
* teach the RX data path about receive offload encryption - check the flag,
handle NULL key, do decap and checking as appropriate.
Tested:
* iwn(4), STA mode
* ath(4), STA and AP mode
* ath10k port, STA mode (hardware encryption)
Reviewed by: avos
Differential Revision: https://reviews.freebsd.org/D8533
If full-offload scan is used, the NIC driver (or rather the firmware of
the NIC) should take care of interrupting and continuing the background
scan. So net80211 should ignore the vap->iv_bgscanidle setting then, instead
the NIC driver might look at this setting and pass it on to the firmware
in some way if possible.
Since full-offload scans won't be explicitly interrupted by net80211, it
also doesn't really make sense to check the vap->iv_bgscanidle condition
in that case, before starting a background scan. If the NIC driver
advertises background scan support and full-offload scanning, the firmware
should be able to execute that scan without interfering too much with our
data traffic.
Reviewed by: adrian, avos
Approved by: adrian (mentor)
Differential Revision: https://reviews.freebsd.org/D8539
The 802.11-2012 specification notes that a subset of IEs should be present
in IBSS probe requests. This is what (initially) allows nodes to discover
that other nodes are 11n capable. Notably - HTCAP, but not HTINFO.
This isn't everything required to reliably enable 11n between net80211
peers; there's more work to come.
Tested:
* AR9380, IBSS+11n mode
Unfortunately (sigh) some firmware doesn't provide the RX BA starting point,
so we need to cope and set a "close enough" sequence number so we (hopefully!)
don't discard frames as duplicates.
Tested:
* QCA9880v2, athp driver (under development), STA mode
Also - allow driver specific bits to be added, rather than just net80211.
This still isn't as useful as it should be by default; it needs to
be a standalone struct/instance so it can be done before net80211
registration occurs, and it can log per-device items.
But, it's getting there.
* extend the keycache flag word to be 32 bits, not 16 bits
* add new key flags for transmit:
+ IEEE80211_KEY_NOIV: Don't insert IV in the payload when transmitting data frames;
+ IEEE80211_KEY_NOIVMGT: Don't insert IV in the payload when transmitting MIC frames;
+ IEEE80211_KEY_NOMIC: Don't insert MIC in the payload when transmitting data frames;
+ IEEE80211_KEY_NOMICMGT: don't insert MIC in the payload when transmitting management
frames.
* teach ieee80211_crypto_demic() about hardware decrypted frames:
+ if frames are hardware decrypted and the frame has failed MIC, treat it as a
michael failure.
+ if frames are hardware decrypted and the frame has stripped MIC, we can't check the
MIC in the payload - we don't have anything to compare it against.
This is only part of the work required to successfully transmit/receive
hardware crypto frames such as the qualcomm atheros 11ac offload chips.
There will be further work in the transmit and receive path before this
can be done by default.
Reviewed by: avos
Differential Revision: https://reviews.freebsd.org/D8364
This is a very simple addition to the net80211 scan support.
It doesn't implement a replacement scan interface - it just disables
the pieces that we should disable to make this lifecycle a bit
more managable.
There's more work to come before full scan offload support is available
but it should be good enough for driver work.
* add a flag to say "full offload"
* don't do probe requests when scanning full-offload - firmware can do that
* don't do powersave transitions and buffering - firmware can do that
tested:
* iwm(4) - STA mode
* ath10k port (local, not in freebsd-head yet)
Reviewed by: avos
Differential Revision: https://reviews.freebsd.org/D8262
to ieee80211_add_rx_params() + drop last (ieee80211_rx_stats) parameter
Note: there is an additional check for ieee80211_get_rx_params()
return value (which does not exist in the original diff).
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D8207
There are a variety of more interesting RX statistics that we should
keep track of but we don't. This is a starting point for adding more
information.
Specifically:
* now the RX rate information and some of the packet status is
passed up;
* The 32 bit or 64 bit TSF is passed up;
* the PHY mode is passed up;
* the "I'm decap'ed AMSDU!" state is passed up;
* number of RX chains is bumped to 4.
This is all mostly a placeholder for getting the data into the RX status
before we pass it up to net80211 - unfortunately we don't yet enforce
that drivers provide it, nor do we pass the provided info back up the
stack so anyone can use the data.
We're going to need to use some of this data moving forward.
Notably, now that some hardware can do AMSDU decap for us (the intel iwm
driver can do it when we flip it on; the ath10k port I'm doing does
it for us) then we need to pass it up through the stack so the duplicate
RX sequence numbers and crypto/IV details don't cause the packet to
be dropped and/or counted against a replay counter.
It's also the beginning of being able to do more interesting node
accounting in net80211. Specifically, once drivers start populating
per-packet rate information, AMPDU information, timestamps, etc,
we can start providing histograms of rate-versus-RSSI, account
for receive time spent per node and other such interesting things.
(Note: I'm also hoping to include ranging and RTT information for
future chipset support; and it's likely going to include it in
this kind of fashion.)
Replace various void * / int argument combinations with common structures:
- ieee80211_ratectl_tx_status for *_tx_complete();
- ieee80211_ratectl_tx_stats for *_tx_update();
While here, improve amrr_tx_update() for a bit:
1. In case, if receiver is not known (typical for Ralink USB drivers),
refresh Tx rate for all nodes on the interface.
2. There was a misuse:
- otus(4) sends non-decreasing counters (as originally intended);
- but ural(4), rum(4) and run(4) are using 'read & clear' registers
to obtain statistics for some period of time (and those 'last period'
values are used as arguments for tx_update()). If arguments are not big
enough, they are just discarded after the next call.
Fix: move counting into *_tx_update()
(now otus(4) will zero out all node counters after every tx_update() call)
Tested with:
- Intel 3945BG (wpi(4)), STA mode.
- WUSB54GC (rum(4)), STA / HOSTAP mode.
- RTL8188EU (urtwn(4)), STA mode.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D8037
- Add a counter into 'struct ieee80211_node_table' to save current number
of allocated nodes.
(allows to remove array overflow checking in ieee80211_iterate_nodes()).
- Add ieee80211_iterate_nodes_vap() function; unlike non-vap version,
it iterates on nodes for specified vap only.
In addition to the above:
- Remove ieee80211_iterate_nt(); it is not used by drivers / net80211
outside ieee80211_iterate_nodes() function + cannot be separated due
to structural changes in code.
Since size of 'struct ieee80211_node_table' (part of ieee80211com,
which is a part of driver's softc) is changed all wireless drivers /
kernel need to be recompiled.
Tested with wpi(4), STA mode.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D7996
Restore pre-r300383 behavior when a frame is sent:
- stop scan;
- send frame;
- when beacon arrives and our bit in TIM is not set - restart the scan.
NOTE:
Ideally, this should introduce new interface (ieee80211_pause_anyscan());
however, since ieee80211_cancel_anyscan() is not used by drivers and only
called by ieee80211_start_pkt() the current patch overrides it's behavior
instead.
Tested with Intel 3945BG, STA mode
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D7979
The adhoc probe/beacon input path was creating nodes for all SSIDs.
This wasn't a problem when the NICs were configured to only process
frames for the current BSSID, but that didn't allow IBSS merges.
Once avos and I flipped on "beacons from all BSSIDs" to allow for
correct IBSS merging, we found this interesting behaviour.
This adds a check against the current SSID.
* If there's no VAP SSID, allow anything
* If there's a VAP SSID, check if the incoming frame has a suitable
SSID and if so, allow it.
This prevents nodes being created for other SSIDs in probe and beacon
frames - ie, beacons overlapping IBSSes with different SSIDs, and
probe requests from arbitrary devices.
Tested:
* AR9380, IBSS mode, both local and other IBSSes.
Reviewed by: avos
Differential Revision: https://reviews.freebsd.org/D7959
IBSS negotiation is a subset of the STA/AP negotiation. We always have a
current channel, so base the HT capabilities on the current channel.
This is then put into IBSS probe requests to inform peers of our
11n capabilities.
Add IEEE80211_KEY_SWCRYPT / IEEE80211_KEY_SWMIC bits to the
IEEE80211_KEY_DEVICE mask - as a result, those bits will be preserved
during group key handshake.
A driver can override them in iv_key_alloc() for some keys in case
when hardware crypto support is not possible. As an example:
- multi-vap without multicast key search support;
- IBSS RSN for devices w/ fixed storage for group keys;
Tested with RTL8188EU (AP, sw crypto) and
RTL8821AU (STA, sw crypto for group keys + hw crypto for pairwise keys)
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D7901
- Add few checks for group/pairwise ciphers into
ieee80211_parse_{wpa,rsn}().
- Split error code and cipher value in wpa_cipher() / rsn_cipher(); current
hack with (1 << 32) does not work - it's 1, not 0 (detected by CSA).
- Return IEEE80211_REASON_UNSUPP_RSN_IE_VERSION instead of
IEEE80211_REASON_IE_INVALID when version field is not equal to RSN_VERSION.
Tested with wpi(4) / urtwn(4) (HOSTAP mode).
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D7887
In case if there is already running interface, a second non-sta
interface will omit scanning, going directly to RUN state. Handle
this case for adhoc mode appropriately.
Tested with RTL8821AU, 2 vaps in IBSS mode.
Uses of commas instead of a semicolons can easily go undetected. The comma
can serve as a statement separator but this shouldn't be abused when
statements are meant to be standalone.
Detected with devel/coccinelle following a hint from DragonFlyBSD.
MFC after: 1 month
turn them into a shared definition.
Set M_MCAST/M_BCAST appropriately upon packet reception in net80211, just
before they are delivered up to the ethernet stack.
Submitted by: rstone
Add new lock for stageq (part of ieee80211_superg structure) and
ni_tx_superg (part of ieee80211_node structure);
drop com_lock protection where it is used to protect them.
While here, drop duplicate OPACKETS counter incrementation.
ni_tx_ampdu is not protected with it (however, it is also used without
locking in other places; probably, it requires some other solution
to be thread-safe).
Tested with RTL8188CUS (AP) and RTL8188EU (STA).
NOTE: Since this change breaks KBI, all wireless drivers need to be
recompiled.
Reviewed by: adrian
Approved by: re (gjb)
Differential Revision: https://reviews.freebsd.org/D6958
avos@ pointed out to me that this broke IBSS merging because the rest of
the input path no longer was called for non-IBSS frames.
I committed a change to not input non-IBSS frames, which stopped
nodes being created for BSSes that weren't ours. Unfortunately
thta stopped the input path for non-IBSS frames in general,
so the management input path didn't work.
So, I'll revert this until I come up with a better solution.
(Hopefully before 11.)
Reviewed by: avos
Approved by: re (gjb)
Drop scan generation number and node table scan lock - the only place
where ni_scangen is checked is in ieee80211_timeout_stations() (and it
is used to prevent duplicate checking of the same node); node scan lock
protects only this variable + node table scan generation number.
This will fix (at least) next LOR (hostap mode):
lock order reversal:
1st 0xc175f84c urtwm0_scan_loc (urtwm0_scan_loc) @ /usr/src/sys/modules/wlan/../../net80211/ieee80211_node.c:2019
2nd 0xc175e018 urtwm0_com_lock (urtwm0_com_lock) @ /usr/src/sys/modules/wlan/../../net80211/ieee80211_node.c:2693
stack backtrace:
#0 0xa070d1c5 at witness_debugger+0x75
#1 0xa070d0f6 at witness_checkorder+0xd46
#2 0xa0694cce at __mtx_lock_flags+0x9e
#3 0xb03ad9ef at ieee80211_node_leave+0x12f
#4 0xb03afd13 at ieee80211_timeout_stations+0x483
#5 0xb03aa1c2 at ieee80211_node_timeout+0x42
#6 0xa06c6fa1 at softclock_call_cc+0x1e1
#7 0xa06c7518 at softclock+0xc8
#8 0xa06789ae at intr_event_execute_handlers+0x8e
#9 0xa0678fa0 at ithread_loop+0x90
#10 0xa0675fbe at fork_exit+0x7e
#11 0xa08af910 at fork_trampoline+0x8
In addition to the above:
* switch to ieee80211_iterate_nodes();
* do not assert that node table lock is held, while calling node_age();
that's not really needed (there are no resources, which can be protected
by this lock) + this fixes LOR/deadlock between ieee80211_timeout_stations()
and ieee80211_set_tim() (easy to reproduce in HOSTAP mode while
sending something to an STA with enabled power management).
Tested:
* (avos) urtwn0, hostap mode
* (adrian) AR9380, STA mode
* (adrian) AR9380, AR9331, AR9580, hostap mode
Notes:
* This changes the net80211 internals, so you have to recompile all of it
and the wifi drivers.
Submitted by: avos
Approved by: re (delphij)
Differential Revision: https://reviews.freebsd.org/D6833
Do not try to pass such frames; a correct frame cannot be smaller than
(the corresponding) header size.
(for wpi(4) an additional check was added in r289012).
PR: 144987
Remove 'if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);' from raw xmit
and apbridge path; it will be incremented by ieee80211_tx_complete()
after packet transmission.
Noticed by: Imre Vadasz <imre@vdsz.com>
- Assign frame sequence/fragment number before frame concatenation;
otherwise, frame header pointer (wh) will be invalid.
- Move this code block upper and eliminate duplicate 'lwh = mtod()'
assignment.
Tested with wpi(4) (transmitter) (STA mode) and urtwn(4) (receiver)
(HOSTAP mode).
Change default regulatory domain from DEBUG (no limitations;
exposes all device channels) to FCC; as a result, newly created wireless
interface with default settings will have less chances to violate
country-specific regulations.
This change will not affect drivers with pre-initialized regdomain
structure (currentry ath(4) and mwl(4)); in that case, the default
channel list must correspond to the default regdomain / country setting.
You can switch to another regdomain / country via corresponding
ifconfig(8) options; the driver must implement ic_getradiocaps()
method to restore full channel list.
Full country / regdomain list may be obtained via
'ifconfig <iface> list countries' command.
Example: change country to Germany:
ifconfig wlan0 down # all wlans on the device must be down
ifconfig wlan0 country DE
ifconfig wlan0 up
# wpa_supplicant(8), dhclient(8) etc
At the creation time:
ifconfig wlan0 create wlandev wpi0 country DE
To make changes permanent add the following line to the rc.conf(5):
create_args_wlan0="country DE"
Tested with
- Intel 3945BG (wpi(4)).
- WUSB54GC (rum(4)).
Reviewed by: adrian
Relnotes: yes
Differential Revision: https://reviews.freebsd.org/D6228
wpa_supplicant(8) expects to see 'scan complete' event after every
scan command; in case, when event is not sent it will hang for
indefinite time.
PR: 209198
Do not try to start a scan when interface is not running.
How-to-reproduce:
1) ifconfig wlan0 create wlandev urtwn0
2) wlandebug -i wlan0 state
3) ifconfig wlan0 scan
ieee80211.c:
add_chanlist(): 'error' variable will be uninitialized if
no channels were passed; return '0' instead.
ieee80211_action.c:
ieee80211_send_action_register(): drop 'break' after 'return'.
ieee80211_crypto_none.c:
none_encap(): 'keyid' is not used in non-debug builds; hide it
behind IEEE80211_DEBUG ifdef.
ieee80211_freebsd.c:
Staticize global 'ieee80211_debug' variable (used only in this
file).
ieee80211_hostap.c:
Fix a comment (associatio -> association).
ieee80211_ht.c:
ieee80211_setup_htrates(): initialize 'maxunequalmcs' to 0 to mute
compiler warning.
ieee80211_hwmp.c:
hwmp_recv_preq(): copy 'prep' between conditional blocks to fix
-Wshadow warning.
ieee80211_mesh.c:
mesh_newstate(): remove duplicate 'ni' definition.
mesh_recv_group_data(): fix -Wempty-body warning in non-debug
builds.
ieee80211_phy.c:
ieee80211_compute_duration(): remove 'break' after panic() call.
ieee80211_scan_sta.c:
Hide some TDMA-specific macros under IEEE80211_SUPPORT_TDMA ifdef
adhoc_pick_bss(): remove 'ic' pointer redefinition.
ieee80211_sta.c:
sta_beacon_miss(): remove 'ic' pointer redefinition.
ieee80211_superg.c:
superg_ioctl_set80211(): drop unreachable return.
Tested with clang 3.8.0, gcc 4.6.4 and gcc 5.3.0.
Replace ifnet list lookup (which is broken since r287197, because
IFT_IEEE80211 type is not used anymore) with iteration on
ieee80211com list.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D6419
again hopefully.
Rather than blindly removing a supposedly unused variable as reported by
the Clang Static Analyzer, inspect the code and hide them with proper
#ifdefs as they are used in certain conditional parts of the code.
This change adds few methods for net80211 channel table setup:
- ieee80211_add_channel()
- ieee80211_add_channel_ht40()
(primarily for drivers, that parse EEPROM to get channel list -
they will allow to hide implementation details).
- ieee80211_add_channel_list_2ghz()
- ieee80211_add_channel_list_5ghz()
(mostly as a replacement for ieee80211_init_channels() - they will allow
to specify non-default channel list; may be used in ic_getradiocaps()).
Tested with wpi(4) (add_channel) and rum(4) (add_channel_list_2ghz).
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D6124
We don't have a separate bss node; instead we dup the first node we saw
and turn that into the BSS node. This means that action frames from
that node would be rejected.
So, check that the node is the bss node /and/ the MAC doesn't match ni_macaddr.
That's the "right" way for now to verify it's an unknown node.
This fixes handling action frames in adhoc mode, which includes negotiating
11n aggregation via ADDBA/DELBA.
This by itself isn't enough to correctly create 11n adhoc networks; but
it is required for aggregation to be negotiated.
Tested:
* AR9380, 11n adhoc mode
* broadcom 11ac adhoc (vendor platform)
Sponsored by: Eva Automation, Inc.
This is in preparation for exposing configuring STBC flags up to ifconfig
so STBC TX/RX can be configured at runtime.
* Set the FHT_STBC flags for TX/RX if the HT capabilitiex exist
* Clear the RX STBC HT capability flag when creating a HTCAP IE, so
we only announce it if it's configured in the FHT flags.
Tested:
* AR9331 (carambola2), AP/STA modes
rounddown2 tends to produce longer lines than the original code
and when the code has a high indentation level it was not really
advantageous to do the replacement.
This tries to strike a balance between readability using the macros
and flexibility of having the expressions, so not everything is
converted.
ieee80211_scan_done().
Refresh comments that reference scan_next() method
(does not exist since r191746) + fix spelling of 'current'.
Differential Revision: https://reviews.freebsd.org/D5137
- Allow to enable/disable promiscuous mode when:
* interface is not a member of bridge, or;
* request was issued by user (ifconfig wlan0 promisc), or;
* interface is in MONITOR or AHDEMO mode.
- Drop local workarounds in mwl(4) and malo(4).
Tested with:
- Intel 3945BG, STA mode;
- RTL8188CUS, MONITOR mode;
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D5472
Hide subtype mask/shift (which is used for index calculation
in ieee80211_mgt_subtype_name[] array) in function call.
Tested with RTL8188CUS, STA mode.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D5369
le*dec / le*enc functions.
Replace net80211 specific macros with system-wide bytestream
encoding/decoding functions:
- LE_READ_2 -> le16dec
- LE_READ_4 -> le32dec
- LE_WRITE_2 -> le16enc
- LE_WRITE_4 -> le32enc
+ drop ieee80211_input.h include, where it was included for these
operations only.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D6030
Although we correctly (now!) calculate the right A-MPDU parameters, the
ioctl() has some faulty logic for choosing which to display. The BSS
params are what were advertised to us, and we would have chosen the
lower of theirs/ours when advertising the HT bits back at them.
So, we /should/ track and fix that so we display the correct A-MPDU
density and size.
However, since I'm a forgetful type, and I don't want to have to re-learn
that this is wrong, drop in a comment so I or someone else fixes it.
Or, when I discover this again in 4 years, I don't have to go digging
too much to remember.
I was seeing the stack constantly attempt to renegotiate A-MPDU TX
even after 3 failures. My hunch is that the direct ticks comparison
is failing around the ticks wrap-around point.
This failure shouldn't /really/ happen normally, but it turns out being
the IBSS master node on FreeBSD doesn't quite setup 11n right, so
negotiating A-MPDU TX fails.
It's 2016 and vendors (including us!) still have 802.11n TX/RX sequence
handling bugs. It's suboptimal, but I'd rather see us default to handling
things in a sensible way.
So, just delete the #ifdef'ed code for now. I'll leave the option in
so it doesn't break existing configurations.
This all started because I've started getting reports about urtwn not
working after I enabled 802.11n support, and it's because the ARM kernel
configs don't include A-MPDU RX aging.
This makes it easier to track which node is having what done do it
during normal use.
This is likely the eighth time I've done this since I started doing
net80211 development, so I think it's about time I just committed it.
The ath(4) driver now sees beacons and management frames for different
BSSIDs in IBSS mode, which is a problem when you're in a very busy
IBSS environment.
So, expose this function so drivers can use it to check if the current
RX node is actually for a BSS we need to pay attention to or not.
PR: kern/208644
Sponsored by: Eva Automation. Inc.
This prevents nodes being created for peers on BSSes that are not our own.
(Ie, same channel, IBSS, but different BSS.)
The "IBSS merge" thing was fixed by me enabling "see all beacons" in
the ath(4) driver a few months ago. Trouble is, we now need the filtering
again.
Tested:
* ath(4), IBSS, on a very busy IBSS channel with lots (> 15) IBSS networks.
PR: kern/208643
Sponsored by: Eva Automation, Inc.
A-MSDU is another 11n aggregation mechanism where multiple ethernet
frames get LLC encapsulated (so they have a length field), padded,
and put in a single MPDU (802.11 MAC frame.) This means it gets sent
out as a single frame, with a single seqno, it's acked as one frame, etc.
It turns out that, hah, atheros fast frames is almost but not quite
like this, so I'm reusing all of the current superg/fast-frames stuff
in order to actually transmit A-MSDU. Yes, this means that A-MSDU
frames are also only aggregated two at a time, so it's not necessarily
a huge win, but it's better than nothing.
This doesn't do anything by default - the driver needs to say it does
A-MSDU as well as set the AMSDU software TX capability so this code path
gets exercised.
For now, the only driver that enables this is urtwn. I'll enable it
for rsu at some point soon.
Tested:
* Add an amsdu encap path to aggregate two frames, same as the
fast-frames path.
* Always do the superg init/teardown and node init/teardown stuff,
regardless of whether the nodes are doing fast-frames (the ATH
capability stuff.) That way we can reuse it for amsdu.
* Don't do AMSDU for multicast/broadcast and EAPOL frames.
* If we're doing A-MPDU, then don't bother doing FF/A-MSDU.
We can likely do both together, but I don't want to change
behaviour.
* Teach the fast frames approx txtime logic to support the 11n
rates. But, since we don't currently have a full "current rate"
support, assume it's HT20, long-gi, etc. That way we overshoot
on the TX time estimation, so we're always inside the requirements.
(And we only aggregate two frames for now, so we're not really
going to exceed that.)
* Drop the maximum FF age default down to 2ms, otherwise we end up
with some very annoyingly large latencies.
TODO:
* We only aggregate two ethernet frames, so I'm not checking the max
A-MSDU size. But when it comes time to support >2 frames, we should
obey that.
Tested:
* urtwn(4)
* begin moving the 11n macros out of ieee80211_phy.c and
into a header so they can be used elsewhere.
* rename some of them into the IEEE80211_* namespace.
* convert HT_RC_2_MCS() to work with three-stream rates.
do software A-MSDU encapsulation.
Right now there's AMSDU TX/RX capability bits and they're mostly
unused, however I'd like to maintain those as the general configuration,
not also "please software encap AMSDU." For platforms that can do
A-MSDU in firmware (iwn, iwm, etc) then their init paths can read
this flag to configure A-MSDU.