Commit Graph

192 Commits

Author SHA1 Message Date
Mateusz Guzik
662c13053f net: clean up empty lines in .c and .h files 2020-09-01 21:19:14 +00:00
Adrian Chadd
f1481c8d3b [net80211] Migrate HT/legacy protection mode and preamble calculation to per-VAP flags
The later firmware devices (including iwn!) support multiple configuration
contexts for a lot of things, leaving it up to the firmware to decide
which channel and vap is active.  This allows for things like off-channel
p2p sta/ap operation and other weird things.

However, net80211 is still focused on a "net80211 drives all" when it comes to driving
the NIC, and as part of this history a lot of these options are global and not per-VAP.
This is fine when net80211 drives things and all VAPs share a single channel - these
parameters importantly really reflect the state of the channel! - but it will increasingly
be not fine when we start supporting more weird configurations and more recent NICs.
Yeah, recent like iwn/iwm.

Anyway - so, migrate all of the HT protection, legacy protection and preamble
stuff to be per-VAP.  The global flags are still there; they're now calculated
in a deferred taskqueue that mirrors the old behaviour.  Firmware based drivers
which have per-VAP configuration of these parameters can now just listen to the
per-VAP options.

What do I mean by per-channel? Well, the above configuration parameters really
are about interoperation with other devices on the same channel. Eg, HT protection
mode will flip to legacy/mixed if it hears ANY BSS that supports non-HT stations or
indicates it has non-HT stations associated.  So, these flags really should be
per-channel rather than per-VAP, and then for things like "do i need short preamble
or long preamble?" turn into a "do I need it for this current operating channel".
Then any VAP using it can query the channel that it's on, reflecting the real
required state.

This patch does none of the above paragraph just yet.

I'm also cheating a bit - I'm currently not using separate taskqueues for
the beacon updates and the per-VAP configuration updates.  I can always further
split it later if I need to but I didn't think it was SUPER important here.

So:

* Create vap taskqueue entries for ERP/protection, HT protection and short/long
  preamble;
* Migrate the HT station count, short/long slot station count, etc - into per-VAP
  variables rather than global;
* Fix a bug with my WME work from a while ago which made it per-VAP - do the WME
  beacon update /after/ the WME update taskqueue runs, not before;
* Any time the HT protmode configuration changes or the ERP protection mode
  config changes - schedule the task, which will call the driver without the
  net80211 lock held and all correctly serialised;
* Use the global flags for beacon IEs and VAP flags for probe responses and
  other IE situations.

The primary consumer of this is ath10k.  iwn could use it when sending RXON,
but we don't support IBSS or AP modes on it yet, and I'm not yet sure whether
it's required in STA mode (ie whether the firmware parses beacons to change
protection mode or whether we need to.)

Tested:

* AR9280, STA/AP
* AR9380, DWDS STA+STA/AP
* ath10k work, STA/AP
* Intel 6235, STA
* Various rtwn / run NICs, DWDS STA and STA configurations
2020-07-01 00:23:49 +00:00
Adrian Chadd
8379e8db7a [net80211] Add initial U-APSD negotiation support.
U-APSD (unscheduled automatic power save delivery) is a power save method
that's a bit better than legacy PS-POLL - stations can mark frames with
an extra flag that tells the AP to leak out more frames after it sends
its own frames rather than needing to send a PS-POLL to get another frame
from the AP.

Now, this code just handles the negotiation bits; it doesn't actually
implement U-APSD.  That's up to drivers, and nothing in the tree yet
implements this.  I /may/ implement this for ath(4) if I eventually care
enough but right now I plan on just implementing it for firmware offload
based NICs that handle this in the NIC.

I'll commit the ifconfig bit after this and I may have some follow-up
commits as this gets used more by me in local testing.

This should be a glorious no-op for everyone else.  If things change
for anyone that isn't fixed by a complete recompile then please reach out
to me.
2020-06-16 00:27:32 +00:00
Adrian Chadd
b3d0e274bf [net80211] Flip on A-MPDU, A-MSDU, A-MPDU+A-MSDU and Fast frames options.
This updates the logic to allow:

* A-MPDU if available;
* A-MSDU if available and A-MPDU is off/NACKed;
* A-MPDU+A-MSDU if it's available and negotiated;
* Fast frames if the node is 11abg (and not HT/VHT.)

This allows for things to fail back to A-MSDU or fast frames
if A-MPDU isn't available rather than needing to be non-HT/non-VHT.
It also allows A-MPDU+A-MSDU to work if it's negotiated.

Tested:

* AR9380, STA + AP mode (A-MPDU, A-MSDU, FF, A-MPDU+A-MSDU)
* RT5350, STA mode (A-MSDU, FF)
* AR9170, STA mode (A-MSDU, FF)
2020-06-06 22:25:00 +00:00
Adrian Chadd
d20ff6e680 [net80211] Migrate short slot time configuration into per-vap and deferred taskqueue updates.
The 11b/11g ERP and slot time update handling are two things which weren't
migrated into the per-VAP state when Sam did the initial VAP work.
That makes sense for a lot of setups where net80211 is driving radio state
and the radio only cares about the shared state.

However, as noted by a now deleted comment, the ERP and slot time updates
aren't EXACTLY correct/accurate - they only take into account the most
RECENTLY created VAP, and the state updates when one creates/destroys
VAPs isn't exactly great.

So:

* track the short slot logic per VAP;
* whenever the slot time configuration changes, just push it into a deferred
  task queue update so drivers don't have to serialise it themselves;
* if a driver registers a per-VAP slot time handler then it'll just get the
  per VAP one;
* .. if a driver registers a global one then the legacy behaviour is maintained -
  a single slot time is calculated and pushed out.

Note that the calculated slot time is better than the existing logic - if ANY
of the VAPs require long slot then it's disabled for all VAPs rather than
whatever the last configured VAP did.

Now, this isn't entirely complete - the rest of ERP tracking around short/long
slot capable station tracking needs to be converted into per-VAP, as well
as the preamble/barker flags.  Luckily those also can be done in a similar
fashion - keep per-VAP counters/flags and unify them before doing the driver
update.  I'll defer that work until later.

All the existing drivers can keep doing what they're doing with the global
slot time flags as that is maintained. One driver (iwi) used the per-VAP
flags instead of the ic flags, so now that driver will work properly.

This unblocks some ath10k porting work as the firmware takes the slot time
configuration per-VAP rather than globally, and some firmware handles
STA+AP and STA+STA (on same/different channels) configurations where
the firmware will switch slot time as appropriate.

Tested:

* AR9380, STA/AP mode
* AR9880 (ath10k), STA mode
2020-06-05 06:21:23 +00:00
Adrian Chadd
2172664c4b [net80211] Use the unicast key when transmitting DWDS AP multicast frames.
I'm still not sure whether this is the full solution, but here goes.

I have a two node DWDS setup - a main AP with the ethernet bridge uplink
and a satellite AP in the back of the house. They're both AR9344+AR9580
dual band 11n APs.

The problem was that multicast frames was not going from the DWDS AP to
the DWDS STA. Unicast frames are fine, and multicast frames from the
DWDS STA to AP are fine.

Now, multicast and unicast frames from the STA -> AP are just transmitted
using the unicast key.  That's fine.  However, the AP -> STA multicast
frames by default are transmitted using the current default / multicast
key, the shared one between all STAs in a BSS.  Now, the DWDS implementation
ignores non WDS frames - it only allows about 4 address frames outside
of management / EAPOL frames! - so the STA side ignores the normal multicast
frames.

Instead, the AP side uses ieee80211_dwds_mcast() to send multicast frames
to each WDS VAP that was created as part of the "dynamic" part of DWDS.
This should be queuing them individually to each node instead of using
the normal multicast send path; and this is how they should get turned into
4-addr WDS frames.

HOWEVER, ieee80211_encap() was trying to use the default TX key to queue
them rather than the unicast key that's already setup.  Since this synthetic
node doesn't have the default TX key setup, transmission fails.  Things
would be fine in WEP and in open mode because in both cases you would
have static keys (or no keys) setup.  It just fails in WPA mode.

This resolves the issue.  AP DWDS multicast is now sent using the unicast
key just like in STA mode and I'm pretty sure the STA mode side will stil
work fine (as it's a STA VAP with a DWDS flag..)

Tested:

* TL-WDR3600/4300 APs
2020-05-08 17:01:33 +00:00
Brooks Davis
6671366a55 Fix -Wvoid-pointer-to-enum-cast warnings.
This pattern is used in callbacks with void * data arguments and seems
both relatively uncommon and relatively harmless.  Silence the warning
by casting through uintptr_t.

This warning is on by default in Clang 11.

Reviewed by:	arichardson
Obtained from:	CheriBSD (partial)
MFC after:	1 week
Sponsored by:	DARPA
Differential Revision:	https://reviews.freebsd.org/D24425
2020-04-15 18:15:58 +00:00
John Baldwin
fb3bc59600 Restructure mbuf send tags to provide stronger guarantees.
- Perform ifp mismatch checks (to determine if a send tag is allocated
  for a different ifp than the one the packet is being output on), in
  ip_output() and ip6_output().  This avoids sending packets with send
  tags to ifnet drivers that don't support send tags.

  Since we are now checking for ifp mismatches before invoking
  if_output, we can now try to allocate a new tag before invoking
  if_output sending the original packet on the new tag if allocation
  succeeds.

  To avoid code duplication for the fragment and unfragmented cases,
  add ip_output_send() and ip6_output_send() as wrappers around
  if_output and nd6_output_ifp, respectively.  All of the logic for
  setting send tags and dealing with send tag-related errors is done
  in these wrapper functions.

  For pseudo interfaces that wrap other network interfaces (vlan and
  lagg), wrapper send tags are now allocated so that ip*_output see
  the wrapper ifp as the ifp in the send tag.  The if_transmit
  routines rewrite the send tags after performing an ifp mismatch
  check.  If an ifp mismatch is detected, the transmit routines fail
  with EAGAIN.

- To provide clearer life cycle management of send tags, especially
  in the presence of vlan and lagg wrapper tags, add a reference count
  to send tags managed via m_snd_tag_ref() and m_snd_tag_rele().
  Provide a helper function (m_snd_tag_init()) for use by drivers
  supporting send tags.  m_snd_tag_init() takes care of the if_ref
  on the ifp meaning that code alloating send tags via if_snd_tag_alloc
  no longer has to manage that manually.  Similarly, m_snd_tag_rele
  drops the refcount on the ifp after invoking if_snd_tag_free when
  the last reference to a send tag is dropped.

  This also closes use after free races if there are pending packets in
  driver tx rings after the socket is closed (e.g. from tcpdrop).

  In order for m_free to work reliably, add a new CSUM_SND_TAG flag in
  csum_flags to indicate 'snd_tag' is set (rather than 'rcvif').
  Drivers now also check this flag instead of checking snd_tag against
  NULL.  This avoids false positive matches when a forwarded packet
  has a non-NULL rcvif that was treated as a send tag.

- cxgbe was relying on snd_tag_free being called when the inp was
  detached so that it could kick the firmware to flush any pending
  work on the flow.  This is because the driver doesn't require ACK
  messages from the firmware for every request, but instead does a
  kind of manual interrupt coalescing by only setting a flag to
  request a completion on a subset of requests.  If all of the
  in-flight requests don't have the flag when the tag is detached from
  the inp, the flow might never return the credits.  The current
  snd_tag_free command issues a flush command to force the credits to
  return.  However, the credit return is what also frees the mbufs,
  and since those mbufs now hold references on the tag, this meant
  that snd_tag_free would never be called.

  To fix, explicitly drop the mbuf's reference on the snd tag when the
  mbuf is queued in the firmware work queue.  This means that once the
  inp's reference on the tag goes away and all in-flight mbufs have
  been queued to the firmware, tag's refcount will drop to zero and
  snd_tag_free will kick in and send the flush request.  Note that we
  need to avoid doing this in the middle of ethofld_tx(), so the
  driver grabs a temporary reference on the tag around that loop to
  defer the free to the end of the function in case it sends the last
  mbuf to the queue after the inp has dropped its reference on the
  tag.

- mlx5 preallocates send tags and was using the ifp pointer even when
  the send tag wasn't in use.  Explicitly use the ifp from other data
  structures instead.

- Sprinkle some assertions in various places to assert that received
  packets don't have a send tag, and that other places that overwrite
  rcvif (e.g. 802.11 transmit) don't clobber a send tag pointer.

Reviewed by:	gallatin, hselasky, rgrimes, ae
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D20117
2019-05-24 22:30:40 +00:00
Andriy Voskoboinyk
f3f08e16a3 net80211(4): hide casts for 'i_seq' field offset calculation inside
ieee80211_getqos() and reuse it in various places.

Checked with RTL8188EE, HOSTAP mode + RTL8188CUS, STA mode.

MFC after:	2 weeks
2019-02-10 23:58:56 +00:00
Andriy Voskoboinyk
e42e878b35 net80211: provide rate validation for injected frames.
There may be various side effects (device timeout, firmware and / or
kernel panic) when an invalid (or inapplicable - e.g., an MCS rate
for 11g-only device) is set; check rates before sending the frame to
the driver.

How-to-reproduce:
Set an MCS (real or bogus - with 0x80 bit set) rate in ibp_rate0 field
for any device that uses ieee80211_isratevalid() for rate checks -
rum(4), run(4), ural(4), bwi(4) or ral(4); if kernel is compiled
with INVARIANTS the check will result in "rate %d is basic/mcs?" panic.

Tested with WUSB54GC (rum(4)), AP mode.

MFC after:	1 week
2019-01-13 06:01:36 +00:00
Andriy Voskoboinyk
18569211a1 net80211: fix duplicate sequence number bump for non-AMPDU QoS frames.
This should be a part of r312972.

MFC after:	4 days
2018-12-30 03:03:53 +00:00
Andriy Voskoboinyk
d1b671061b net80211: wrap protection frame allocation into ieee80211_alloc_prot()
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
2018-03-09 11:33:56 +00:00
Andriy Voskoboinyk
bcabc90835 net80211: sanitize input for ieee80211_output()
- 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
2017-12-30 00:40:34 +00:00
Pedro F. Giffuni
fe267a5590 sys: general adoption of SPDX licensing ID tags.
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.
2017-11-27 15:23:17 +00:00
Andriy Voskoboinyk
191ccdf545 net80211: fix a typo (premable -> preamble). 2017-08-27 22:13:03 +00:00
Andriy Voskoboinyk
2db223f902 net80211: initialize i_seq for A-MPDU frames.
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
2017-06-01 20:46:43 +00:00
Adrian Chadd
ac0b7d3206 [net80211] teach the probe response routine to add VHT IEs as appropriate. 2017-02-20 04:02:50 +00:00
Adrian Chadd
43eafd0d1e [net80211] don't bother doing fragmentation if the driver supports fragmentation offload.
Tested:

* ath10k, which does its own fragmentation in firmware.
2017-02-09 23:29:57 +00:00
Adrian Chadd
4d3dcce5bb [net80211] quiet IE handling improvements
* 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.
2017-02-09 04:07:30 +00:00
Adrian Chadd
ce4552cd1a [net80211] don't update quiet time counter values every probe request.
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.)
2017-02-03 06:04:06 +00:00
Adrian Chadd
9764ef21c4 [net80211] address seqno allocation for group addressed frames
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
2017-01-30 01:11:30 +00:00
Adrian Chadd
51172f62a7 [net80211] Initial VHT node upgrade/downgrade support and initial IE parsing.
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. :/
2017-01-13 07:02:04 +00:00
Adrian Chadd
f8a67728f3 [net80211] announce 11n capabilities in probe requests in IBSS mode.
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
2016-11-15 01:47:37 +00:00
Andriy Voskoboinyk
c8898568fd net80211: discard an injected frame if it is smaller than header length.
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
2016-06-09 13:42:18 +00:00
Andriy Voskoboinyk
4d4d5e2508 net80211: fix duplicate packet counter incrementation.
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>
2016-06-09 08:19:42 +00:00
Andriy Voskoboinyk
18d20be00f net80211: replace m_getcl/m_gethdr pair with m_get2 in ieee80211_fragment()
- Switch to m_get2() for mbuf allocation instead of manual mbuf size
determination.
- Reuse MIN() macro for mbuf size selection.
2016-05-28 19:13:39 +00:00
Bjoern A. Zeeb
2e9090dfbe Revert parts of r299575 in order to make more MIPS kernels build
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.
2016-05-14 08:54:34 +00:00
Andriy Voskoboinyk
601a2543a0 net80211: drop some unused variables / local macros
Most of them left after some commits (r178354, r191544, r287197 etc.);
some were never used.

Found by:	Clang Static Analyzer
2016-05-12 22:17:00 +00:00
Pedro F. Giffuni
a4641f4eaa sys/net*: minor spelling fixes.
No functional change.
2016-05-03 18:05:43 +00:00
Andriy Voskoboinyk
4357a5d1ef net80211: hide subtype mask & shift in function call.
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
2016-04-20 21:15:55 +00:00
Andriy Voskoboinyk
d72d72d381 net80211: provide descriptions for reason codes
Add text description for deauth/disassoc/etc reason codes
in addition to 'reason: <number>' string.

Reviewed by:	adrian
Obtained from:	IEEE Std 802.11-2012, 8.4.1.7 "Reason Code field"
Differential Revision:	https://reviews.freebsd.org/D5367
2016-04-20 20:30:18 +00:00
Andriy Voskoboinyk
31021a2b4e net80211: replace internal LE_READ_*/LE_WRITE_* macro with system
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
2016-04-20 18:29:30 +00:00
Adrian Chadd
1c7b0c8456 [net80211] Initial A-MSDU support for testing / evaluation
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)
2016-04-06 01:21:51 +00:00
Andriy Voskoboinyk
9f82bedaa1 net80211: wakeup scan_start() task when null data frame was actually
transmitted

- Use M_TXCB mechanism to report about null data frame transmission.
- Increase timeout from 1 to 10 ms (the previous one may be not enough
for non-empty queue).

Tested with:
 * Intel 3945BG, STA mode.
 * RTL8188CUS, STA mode.

Approved by:	adrian (mentor)
Differential Revision:	https://reviews.freebsd.org/D5147
2016-02-29 20:56:02 +00:00
Gleb Smirnoff
8ec07310fa These files were getting sys/malloc.h and vm/uma.h with header pollution
via sys/mbuf.h
2016-02-01 17:41:21 +00:00
Adrian Chadd
d957a93abe net80211: move ieee80211_free_node() call on error from ic_raw_xmit() to ieee80211_raw_output().
This doesn't free the mbuf upon error; the driver ic_raw_xmit method is still
doing that.

Submitted by:	<s3erios@gmail.com>
Differential Revision:	https://reviews.freebsd.org/D3774
2015-10-12 04:55:20 +00:00
Adrian Chadd
d3a4ade3b8 net80211: free node reference in the ieee80211_parent_xmitpkt() when error happened.
Move error handling into ieee80211_parent_xmitpkt() instead of spreading it
between functions.

Submitted by:	<s3erios@gmail.com>
Differential Revision:	https://reviews.freebsd.org/D3772
2015-10-12 04:30:38 +00:00
Adrian Chadd
d07be335a0 net80211: separate mbuf cleanup from ieee80211_fragment()
* Create ieee80211_free_mbuf() which frees a list of mbufs.
* Use it in the fragment transmit path and ath / uath transmit paths.
* Call it in xmit_pkt() if the transmission fails; otherwise fragments
  may be leaked.

This should be a big no-op.

Submitted by:	<s3erios@gmail.com>
Differential Revision:	https://reviews.freebsd.org/D3769
2015-10-12 03:27:08 +00:00
Adrian Chadd
210ab3c258 net80211: drop ieee80211_beacon_offsets parameter from ieee80211_beacon_alloc() and ieee80211_beacon_update()
Submitted by:	<s3erios@gmail.com>
Differential Revision:	https://reviews.freebsd.org/D3659
2015-10-03 22:12:25 +00:00
Adrian Chadd
f9128a1be3 Comments, mostly to remind myself of what's going on and why. 2015-09-28 00:51:24 +00:00
Adrian Chadd
4eadefc260 Expose the wme_info IE method. 2015-09-18 04:01:26 +00:00
Gleb Smirnoff
7a79cebfba Replay r286410. Change KPI of how device drivers that provide wireless
connectivity interact with the net80211 stack.

Historical background: originally wireless devices created an interface,
just like Ethernet devices do. Name of an interface matched the name of
the driver that created. Later, wlan(4) layer was introduced, and the
wlanX interfaces become the actual interface, leaving original ones as
"a parent interface" of wlanX. Kernelwise, the KPI between net80211 layer
and a driver became a mix of methods that pass a pointer to struct ifnet
as identifier and methods that pass pointer to struct ieee80211com. From
user point of view, the parent interface just hangs on in the ifconfig
list, and user can't do anything useful with it.

Now, the struct ifnet goes away. The struct ieee80211com is the only
KPI between a device driver and net80211. Details:

- The struct ieee80211com is embedded into drivers softc.
- Packets are sent via new ic_transmit method, which is very much like
  the previous if_transmit.
- Bringing parent up/down is done via new ic_parent method, which notifies
  driver about any changes: number of wlan(4) interfaces, number of them
  in promisc or allmulti state.
- Device specific ioctls (if any) are received on new ic_ioctl method.
- Packets/errors accounting are done by the stack. In certain cases, when
  driver experiences errors and can not attribute them to any specific
  interface, driver updates ic_oerrors or ic_ierrors counters.

Details on interface configuration with new world order:
- A sequence of commands needed to bring up wireless DOESN"T change.
- /etc/rc.conf parameters DON'T change.
- List of devices that can be used to create wlan(4) interfaces is
  now provided by net.wlan.devices sysctl.

Most drivers in this change were converted by me, except of wpi(4),
that was done by Andriy Voskoboinyk. Big thanks to Kevin Lo for testing
changes to at least 8 drivers. Thanks to pluknet@, Oliver Hartmann,
Olivier Cochard, gjb@, mmoll@, op@ and lev@, who also participated in
testing.

Reviewed by:	adrian
Sponsored by:	Netflix
Sponsored by:	Nginx, Inc.
2015-08-27 08:56:39 +00:00
Adrian Chadd
ba2c1fbc03 Revert the wifi ifnet changes until things are more baked and tested.
* 286410
* 286413
* 286416

The initial commit broke a variety of debug and features that aren't
in the GENERIC kernels but are enabled in other platforms.
2015-08-08 01:10:17 +00:00
Gleb Smirnoff
79d2c5e857 Change KPI of how device drivers that provide wireless connectivity interact
with the net80211 stack.

Historical background: originally wireless devices created an interface,
just like Ethernet devices do. Name of an interface matched the name of
the driver that created. Later, wlan(4) layer was introduced, and the
wlanX interfaces become the actual interface, leaving original ones as
"a parent interface" of wlanX. Kernelwise, the KPI between net80211 layer
and a driver became a mix of methods that pass a pointer to struct ifnet
as identifier and methods that pass pointer to struct ieee80211com. From
user point of view, the parent interface just hangs on in the ifconfig
list, and user can't do anything useful with it.

Now, the struct ifnet goes away. The struct ieee80211com is the only
KPI between a device driver and net80211. Details:

- The struct ieee80211com is embedded into drivers softc.
- Packets are sent via new ic_transmit method, which is very much like
  the previous if_transmit.
- Bringing parent up/down is done via new ic_parent method, which notifies
  driver about any changes: number of wlan(4) interfaces, number of them
  in promisc or allmulti state.
- Device specific ioctls (if any) are received on new ic_ioctl method.
- Packets/errors accounting are done by the stack. In certain cases, when
  driver experiences errors and can not attribute them to any specific
  interface, driver updates ic_oerrors or ic_ierrors counters.

Details on interface configuration with new world order:
- A sequence of commands needed to bring up wireless DOESN"T change.
- /etc/rc.conf parameters DON'T change.
- List of devices that can be used to create wlan(4) interfaces is
  now provided by net.wlan.devices sysctl.

Most drivers in this change were converted by me, except of wpi(4),
that was done by Andriy Voskoboinyk. Big thanks to Kevin Lo for testing
changes to at least 8 drivers. Thanks to Olivier Cochard, gjb@, mmoll@,
op@ and lev@, who also participated in testing. Details here:

https://wiki.freebsd.org/projects/ifnet/net80211

Still, drivers: ndis, wtap, mwl, ipw, bwn, wi, upgt, uath were not
tested. Changes to mwl, ipw, bwn, wi, upgt are trivial and chances
of problems are low. The wtap wasn't compilable even before this change.
But the ndis driver is complex, and it is likely to be broken with this
commit. Help with testing and debugging it is appreciated.

Differential Revision:	D2655, D2740
Sponsored by:	Nginx, Inc.
Sponsored by:	Netflix
2015-08-07 11:43:14 +00:00
Adrian Chadd
3a1da00bd9 Some hostap setups may result in raw frames being transmitted with
no parameters set.  So, don't unconditionally call things.

Thanks to jkim@ for pointing this out!

MFC after:	2 weeks
Sponsored by:	Norse Corp, Inc.
2015-06-04 23:07:21 +00:00
Adrian Chadd
ff09e23f53 Tag outbound raw 802.11 frames with both the node and an mbuf tag
with the transmit params.

This allows raw 802.11 frames to be queued in the driver if necessary,
rather than requiring it to be direct-dispatched into the hardware.

Tested:

* ath(4), STA mode
* iwn(4), STA mode

MFC after:	2 weeks
Sponsored by:	Norse Corp, Inc.
2015-06-04 17:54:41 +00:00
Gleb Smirnoff
e14a2a4cf4 Cleanup compat shims for FreeBSD versions that predate 10.0-RELEASE.
There are no plans to merge anything save a trivial bugfix to stable/9.

Discussed with:	adrian
2015-05-25 20:06:49 +00:00
Adrian Chadd
b9b533891f Convert malloc/free back to #define's, as part of OS portability work.
DragonflyBSD uses the FreeBSD wireless stack and drivers.  Their malloc()
API is named differently, so they don't have userland/kernel symbol
clashes like we do (think libuinet.)

So, to make it easier for them and to port to other BSDs/other operating
systems, start hiding the malloc specific bits behind defines in
ieee80211_freebsd.h.

DragonflyBSD can now put these portability defines in their local
ieee80211_dragonflybsd.h.

This should be a great big no-op for everyone running wifi.

TODO:

* kill M_WAITOK - some platforms just don't want you to use it
* .. and/or handle it returning NULL rather than waiting forever.
* MALLOC_DEFINE() ?
* Migrate the well-known malloc names (eg M_TEMP) to net80211
  namespace defines.
2015-05-25 19:18:16 +00:00
Andrey V. Elsukov
79077edc1a Properly update TX statistics for wlan(4).
ieee80211_pwrsave() can fail due to queue overflow, check its return code
and increment oerrors counter when it fails. Also handle more error cases
and update oerrors counter when we don't send mbuf due to some errors.
Return ENETDOWN when parent interface isn't ready. Update obytes and omcasts
counters in corresponding places.

PR:		184626
Differential Revision:	https://reviews.freebsd.org/D2621
Reviewed by:	adrian
MFC after:	1 week
2015-05-23 09:49:40 +00:00
Adrian Chadd
c3ebe01919 Do not check sequence number for QoS Null frames; set it for generated QoS Null
frames to 0

From IEEE Std. 802.11-2012, 8.3.2.1 "Data frame format", p. 415 (513):
"The Sequence Control field for QoS (+)Null frames is ignored by the receiver
upon reception."

At this moment, any <mode>_input() function interprets them as regular QoS data
frames with TID = 0. As a result, stations, that use another TX sequence for
QoS Null frames (e.g. wpi(4), where (QoS) Null frames are generated by the
firmware), may experience significant packet loss with any other NIC in hostap
mode.

Tested:

* wpi(4) (author)
* iwn(4) - Intel 5100, STA mode (me)

PR:		kern/200128
Submitted by:	Andriy Voskoboinyk <s3erios@gmail.com>
2015-05-12 16:55:50 +00:00