Commit Graph

29 Commits

Author SHA1 Message Date
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
6f5ed42a0c Remove some debugging that wasn't supposed to be there. 2015-09-28 06:26:46 +00:00
Adrian Chadd
d029471197 Migrate the fast-frames transmit support away from using the txa_private
field and into a separate fast-frames staging pointer in ieee80211_node.

The A-MPDU TX path allows txa_private to be used by drivers.  So it will
clash with any attempt to use fast-frames.  Now, fast-frames is not really
anything special - it's just a custom ethernet frame type that contains
two MSDUs into one MPDU.  So all the NIC has to support doing is transmitting
up to a 4KiB frame with an arbitrary ethertype and bam! Fast-frames.
However, using txa_private means we can /either/ do fast-frames or A-MPDU TX,
so fast frames has been turned off in the Atheros HAL for 11n chipsets.
This is a bit silly - it actually means that 802.11 performance to/from
11abg Atheros chips is actually better than between an 11abg atheros device
and an 11n Atheros device.

So:

* create a new mbuf staging queue for fast frames.  It only queues a single
  frame in the staging queue (and there's a top-level ic staging queue
  used for expiry/tracking) so it's just an mbuf pointer per TID.

* Still use the ampdu TX packet counter to determine whether to do
  aggregation or not.  It'll double count if we start doing both A-MPDU TX
  and fast frames, but that's not all that important right now.

* Initialise the pps tracker so ticks isn't zero.  This ensures that
  fast-frames actually gets used - without it, the ticks math overflows
  and the pps math always sets txa_pps=0.  This is the same bug that
  plagued A-MPDU TX starting logic.

This actually allows fast-frames transmit to occur between the AR9331
(in 11n HT/20 mode) and AR9170 (if_otus) in 11bg mode.

Now, this is a great big no-op on atheros 11n hardware, so don't worry.
It may mean you start seeing more reliable fast-frames transmission on
11abg hardware which may expose some more amusing bugs.

TODO:

* further testing and debugging of all of this before flipping on
  fast-frames in if_ath (for 11n) and if_otus.
2015-09-28 00:59:07 +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
Hans Petter Selasky
f0188618f2 Fix multiple incorrect SYSCTL arguments in the kernel:
- Wrong integer type was specified.

- Wrong or missing "access" specifier. The "access" specifier
sometimes included the SYSCTL type, which it should not, except for
procedural SYSCTL nodes.

- Logical OR where binary OR was expected.

- Properly assert the "access" argument passed to all SYSCTL macros,
using the CTASSERT macro. This applies to both static- and dynamically
created SYSCTLs.

- Properly assert the the data type for both static and dynamic
SYSCTLs. In the case of static SYSCTLs we only assert that the data
pointed to by the SYSCTL data pointer has the correct size, hence
there is no easy way to assert types in the C language outside a
C-function.

- Rewrote some code which doesn't pass a constant "access" specifier
when creating dynamic SYSCTL nodes, which is now a requirement.

- Updated "EXAMPLES" section in SYSCTL manual page.

MFC after:	3 days
Sponsored by:	Mellanox Technologies
2014-10-21 07:31:21 +00:00
Gleb Smirnoff
dea4512157 Mechanically convert to if_inc_counter(). 2014-09-19 09:20:55 +00:00
Gleb Smirnoff
104dc21415 - Provide necessary includes, that before came via if.h pollution.
- Remove unnecessary ones.

Sponsored by:	Netflix
Sponsored by:	Nginx, Inc.
2013-10-28 22:26:03 +00:00
Adrian Chadd
74b4c76e4e Migrate the ff_encap1() routine out into the normal output code.
This will eventually be used by the A-MSDU encapsulation code that
I'm writing - the sub-frame encapsulation requirement is the same.
2013-08-26 09:52:05 +00:00
Adrian Chadd
e7495198d5 Convert net80211 over to using if_transmit for the dispatch from the
upper layer(s).

This eliminates the if_snd queue from net80211. Yay!

This unfortunately has a few side effects:

* It breaks ALTQ to net80211 for now - sorry everyone, but fixing
  parallelism and eliminating the if_snd queue is more important
  than supporting this broken traffic scheduling model. :-)

* There's no VAP and IC flush methods just yet - I think I'll add
  some NULL methods for now just as placeholders.

* It reduces throughput a little because now net80211 will drop packets
  rather than buffer them if the driver doesn't do its own buffering.
  This will be addressed in the future as I implement per-node software
  queues.

Tested:

* ath(4) and iwn(4) in STA operation
2013-08-08 05:09:35 +00:00
Adrian Chadd
b451a99ecc Kill this, it's not needed at this point and (hopefully) the parent
has correctly locked the ic/vap.
2013-03-10 04:38:06 +00:00
Adrian Chadd
5cda6006e4 Bring over my initial work from the net80211 TX locking branch.
This patchset implements a new TX lock, covering both the per-VAP (and
thus per-node) TX locking and the serialisation through to the underlying
physical device.

This implements the hard requirement that frames to the underlying physical
device are scheduled to the underlying device in the same order that they
are processed at the VAP layer.  This includes adding extra encapsulation
state (such as sequence numbers and CCMP IV numbers.)  Any order mismatch
here will result in dropped packets at the receiver.

There are multiple transmit contexts from the upper protocol layers as well
as the "raw" interface via the management and BPF transmit paths.
All of these need to be correctly serialised or bad behaviour will result
under load.

The specifics:

* add a new TX IC lock - it will eventually just be used for serialisation
  to the underlying physical device but for now it's used for both the
  VAP encapsulation/serialisation and the physical device dispatch.

  This lock is specifically non-recursive.

* Methodize the parent transmit, vap transmit and ic_raw_xmit function
  pointers; use lock assertions in the parent/vap transmit routines.

* Add a lock assertion in ieee80211_encap() - the TX lock must be held
  here to guarantee sensible behaviour.

* Refactor out the packet sending code from ieee80211_start() - now
  ieee80211_start() is just a loop over the ifnet queue and it dispatches
  each VAP packet send through ieee80211_start_pkt().

  Yes, I will likely rename ieee80211_start_pkt() to something that
  better reflects its status as a VAP packet transmit path.  More on
  that later.

* Add locking around the management and BAR TX sending - to ensure that
  encapsulation and TX are done hand-in-hand.

* Add locking in the mesh code - again, to ensure that encapsulation
  and mesh transmit are done hand-in-hand.

* Add locking around the power save queue and ageq handling, when
  dispatching to the parent interface.

* Add locking around the WDS handoff.

* Add a note in the mesh dispatch code that the TX path needs to be
  re-thought-out - right now it's doing a direct parent device transmit
  rather than going via the vap layer.  It may "work", but it's likely
  incorrect (as it bypasses any possible per-node power save and
  aggregation handling.)

Why not a per-VAP or per-node lock?

Because in order to ensure per-VAP ordering, we'd have to hold the
VAP lock across parent->if_transmit().  There are a few problems
with this:

* There's some state being setup during each driver transmit - specifically,
  the encryption encap / CCMP IV setup.  That should eventually be dragged
  back into the encapsulation phase but for now it lives in the driver TX path.
  This should be locked.

* Two drivers (ath, iwn) re-use the node->ni_txseqs array in order to
  allocate sequence numbers when doing transmit aggregation.  This should
  also be locked.

* Drivers may have multiple frames queued already - so when one calls
  if_transmit(), it may end up dispatching multiple frames for different
  VAPs/nodes, each needing a different lock when handling that particular
  end destination.

So to be "correct" locking-wise, we'd end up needing to grab a VAP or
node lock inside the driver TX path when setting up crypto / AMPDU sequence
numbers, and we may already _have_ a TX lock held - mostly for the same
destination vap/node, but sometimes it'll be for others.  That could lead
to LORs and thus deadlocks.

So for now, I'm sticking with an IC TX lock.  It has the advantage of
papering over the above and it also has the added advantage that I can
assert that it's being held when doing a parent device transmit.
I'll look at splitting the locks out a bit more later on.

General outstanding net80211 TX path issues / TODO:

* Look into separating out the VAP serialisation and the IC handoff.
  It's going to be tricky as parent->if_transmit() doesn't give me the
  opportunity to split queuing from driver dispatch.  See above.

* Work with monthadar to fix up the mesh transmit path so it doesn't go via
  the parent interface when retransmitting frames.

* Push the encryption handling back into the driver, if it's at all
  architectually sane to do so.  I know it's possible - it's what mac80211
  in Linux does.

* Make ieee80211_raw_xmit() queue a frame into VAP or parent queue rather
  than doing a short-cut direct into the driver.  There are QoS issues
  here - you do want your management frames to be encapsulated and pushed
  onto the stack sooner than the (large, bursty) amount of data frames
  that are queued.  But there has to be a saner way to do this.

* Fragments are still broken - drivers need to be upgraded to an if_transmit()
  implementation and then fragmentation handling needs to be properly fixed.

Tested:

* STA - AR5416, AR9280, Intel 5300 abgn wifi
* Hostap - AR5416, AR9160, AR9280
* Mesh - some testing by monthadar@, more to come.
2013-03-08 20:23:55 +00:00
Adrian Chadd
9da01550a9 Wrap this in an #ifdef so IEEE80211_SUPPORT_SUPERG will work correctly
in a wlan.ko module.
2013-02-02 02:00:10 +00:00
Adrian Chadd
b3c69eef25 Atheros SuperG bug fixes, as part of hunting down kern/174283.
The stageqdepth (global, over all staging queues) was being kept
incorrectly.  It was being incremented whenever things were added,
but only decremented during a flush.  During active fast frames activity
it wasn't being decremented, resulting in it always having a non-zero
value during normal fast-frames operation.

It was only used when checking if the aging queue should be checked;
we may as well just defer to each of those staging queue counters (which
look correct, thankfully.)

Whilst I'm here, add locking assertions in the staging queue add/remove
functions.  The current crash shows that the staging queue has one frame,
but only has a tail pointer set (the head pointer being set to NULL.)
I'd like to grab a few more crashes where these locking assertions are
in place so I can narrow down the issue between "somehow locking is
messed up and things are racy" and "the stage queue head/tail pointer
manipulation logic is subtly wrong."

Tested:

* AR5416 STA, AR5413 AP; with FastFrames enabled in the AR5416 HAL.

PR:		kern/174283
2012-12-09 19:20:28 +00:00
Adrian Chadd
25b5bb4c1b Don't panic if the stageq here is empty; just fall through with NULL
pointers and leave the stage queue flush routine to just do nothing
(since both head and tail here will be NULL.)

This should quieten the "stageq empty" panic where the stageq itself
is empty, but it won't fix the second KASSERT() here "staging queue empty"
as that's likely a different underlying problem.

PR:		kern/174283
2012-12-09 01:08:44 +00:00
Adrian Chadd
132581aa5d Fix a use-after-free bug in the Atheros fast-frames support.
Tested:

* AR5212 AP, AR5413 STA, iperf TCP STA->AP, destroyed and/or shutdown
  the STA vap during active iperf TCP traffic.

PR:		kern/174273
MFC after:	1 week
2012-12-08 09:48:03 +00:00
Gleb Smirnoff
eb1b1807af Mechanically substitute flags from historic mbuf allocator with
malloc(9) flags within sys.

Exceptions:

- sys/contrib not touched
- sys/mbuf.h edited manually
2012-12-05 08:04:20 +00:00
Adrian Chadd
2aa563dfeb Migrate the net80211 TX aggregation state to be from per-AC to per-TID.
TODO:

* Test mwl(4) more thoroughly!

Reviewed by:	bschmidt (for iwn)
2012-04-15 20:29:39 +00:00
Sam Leffler
a77b10b321 distribute sysctl decls so global variables can be made static 2009-05-30 20:11:23 +00:00
Sam Leffler
5463c4a485 Overhaul monitor mode handling:
o replace DLT_IEEE802_11 support in net80211 with DLT_IEEE802_11_RADIO
  and remove explicit bpf support from wireless drivers; drivers now
  use ieee80211_radiotap_attach to setup shared data structures that
  hold the radiotap header for each packet tx/rx
o remove rx timestamp from the rx path; it was used only by the tdma support
  for debugging and was mostly useless due to it being 32-bits and mostly
  unavailable
o track DLT_IEEE80211_RADIO bpf attachments and maintain per-vap and
  per-com state when there are active taps
o track the number of monitor mode vaps
o use bpf tap and monitor mode vap state to decide when to collect radiotap
  state and dispatch frames; drivers no longer explicitly directly check
  bpf state or use bpf calls to tap frames
o handle radiotap state updates on channel change in net80211; drivers
  should not do this (unless they bypass net80211 which is almost always
  a mistake)
o update various drivers to be more consistent/correct in handling radiotap
o update ral to include TSF in radiotap'd frames
o add promisc mode callback to wi

Reviewed by:	cbzimmer, rpaulo, thompsa
2009-05-20 20:00:40 +00:00
Sam Leffler
04f19fd699 make superg/fast-frames state dynamically-allocated (and indirect off
the com structure instead of embedded); this reduces the overhead when
not configured and reduces visibility of the contents
2009-05-02 20:16:55 +00:00
Sam Leffler
7ebe9c0e2e stash the node pointer in the mbuf before doing ff aggregration so this
is done in only one place
2009-04-26 22:45:21 +00:00
Sam Leffler
dc72796759 add missing DLT_IEEE802_11 tap 2009-04-26 21:21:07 +00:00
Sam Leffler
339ccfb391 Hoist 802.11 encapsulation up into net80211:
o call ieee80211_encap in ieee80211_start so frames passed down to drivers
  are already encapsulated
o remove ieee80211_encap calls in drivers
o fixup wi so it recreates the 802.3 head it requires from the 802.11
  header contents
o move fast-frame aggregation from ath to net80211 (conditional on
  IEEE80211_SUPPORT_SUPERG):
  - aggregation is now done in ieee80211_start; it is enabled when the
    packets/sec exceeds ieee80211_ffppsmin (net.wlan.ffppsmin) and frames
    are held on a staging queue according to ieee80211_ffagemax
    (net.wlan.ffagemax) to wait for a frame to combine with
  - drivers must call back to age/flush the staging queue (ath does this
    on tx done, at swba, and on rx according to the state of the tx queues
    and/or the contents of the staging queue)
  - remove fast-frame-related data structures from ath
  - add ieee80211_ff_node_init and ieee80211_ff_node_cleanup to handle
    per-node fast-frames state (we reuse 11n tx ampdu state)
o change ieee80211_encap calling convention to include an explicit vap
  so frames coming through a WDS vap are recognized w/o setting M_WDS

With these changes any device able to tx/rx 3Kbyte+ frames can use fast-frames.

Reviewed by:	thompsa, rpaulo, avatar, imp, sephe
2009-03-30 21:53:27 +00:00
Sam Leffler
26d39e2c68 o add ic_rt to track the rate table for the current channel; this enables
calculation of packet transmit times to do things like check txop limits
o remove equivalent driver code and convert to use net80211 state
2009-03-29 21:17:08 +00:00
Sam Leffler
97fc5da03e toggling fast-frames requires clocking the state machine 2009-03-29 21:00:27 +00:00
Sam Leffler
9d90db9307 o move tdma+superg protocol defs out of public view
o add #ifdef _KERNEL to superg+tdma include files so they can be used
  by user code to get the protocol defs
2009-03-26 21:29:03 +00:00
Sam Leffler
4207227c6a Fix enough bits so that fast frames work again:
o include ath ie in beacon frames
o fix probe response check for including ath ie
o add ieee80211_add_athcap shorthand for ap-side ie additions
2009-03-26 19:13:11 +00:00
Sam Leffler
aeab3282fd dynamic turbo mode is only implemented in sta mode; don't enable it
for other operating modes based on the capability
2009-03-26 19:07:56 +00:00
Sam Leffler
616190d079 split Atheros SuperG support out into it's own file that's included only
with a new IEEE80211_SUPPORT_SUPERG option
2009-03-24 20:39:08 +00:00