Commit Graph

59 Commits

Author SHA1 Message Date
Gleb Smirnoff
76039bc84f The r48589 promised to remove implicit inclusion of if_var.h soon. Prepare
to this event, adding if_var.h to files that do need it. Also, include
all includes that now are included due to implicit pollution via if_var.h

Sponsored by:	Netflix
Sponsored by:	Nginx, Inc.
2013-10-26 17:58:36 +00:00
Adrian Chadd
5b58efc6cc Fix a VAP BSS node reference in the HT code to actually take a reference
before using said node.

The "blessed" way here is to take a node reference before referencing
anything inside the node, otherwise the node can be freed between
the time the pointer is copied/dereferenced and the time the node contents
are used.

This mirrors fixes that I've done elsewhere in the net80211/driver
stack.

PR:		kern/178470
2013-05-10 09:37:58 +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
0ef1bc21bc Add some further BAR TX debugging; it was useful when figuring out
when BAR TX was actually failing.
2012-10-28 04:18:49 +00:00
Adrian Chadd
545c886250 Fix some corner cases in the ieee80211_send_bar() handling.
* If the first call succeeded but failed to transmit, a timer would
  reschedule it via bar_timeout().  Unfortunately bar_timeout() didn't
  check the return value from the ieee80211_send_bar() reattempt and
  if that failed (eg the driver ic_raw_xmit() failed), it would never
  re-arm the timer.

* If BARPEND is cleared (which ieee80211_send_bar() will do if it can't
  TX), then re-arming the timer isn't enough - once bar_timeout() occurs,
  it'll see BARPEND is 0 and not run through the rest of the routine.
  So when rearming the timer, also set that flag.

* If the TX wasn't occuring, bar_tx_complete() wouldn't be called and the
  driver callback wouldn't be called either.  So the driver had no idea
  that the BAR TX attempt had failed.  In the ath(4) case, TX would stay
  paused.

  (There's no callback to indicate that BAR TX had failed or not;
  only a "BAR TX was attempted".  That's a separate, later problem.)

  So call the driver callback (ic_bar_response()) before the ADDBA session
  is torn down, so it has a chance of being notified that things didn't
  quite go to plan.

I've verified that yes, this does suspend traffic for ath(4), retry BAR
TX even if the driver is failing ic_raw_xmit(), and then eventually giving
up and sending a DELBA.  I'll address the "out of ath_buf" issue in ath(4)
in a subsequent commit - this commit just fixes the edge case where any
driver is (way) out of internal buffers/descriptors and fails frame TX.

PR:		kern/168170
Reviewed by:	bschmidt
MFC after:	1 month
2012-05-22 19:37:12 +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
Adrian Chadd
fcacf9318c Add some statistics to track BAR TX. 2012-04-08 04:51:25 +00:00
Adrian Chadd
b94299c437 Create a new task to handle 802.11n channel width changes.
Currently, a channel width change updates the 802.11n HT info data in
net80211 but it doesn't trigger any device changes.  So the device
driver may decide that HT40 frames can be transmitted but the last
device channel set only had HT20 set.

Now, a task is scheduled so a hardware reset or change isn't done
during any active ongoing RX. It also means that it's serialised
with the other task operations (eg channel change.)

This isn't the final incantation of this work, see below.

For now, any unmodified drivers will simply receive a channel
change log entry.  A subsequent patch to ath(4) will introduce
some basic channel change handling (by resetting the NIC.)
Other NICs may need to update their rate control information.

TODO:

* There's still a small window at the present moment where the
  channel width has been updated but the task hasn't been fired.
  The final version of this should likely pass in a channel width
  field to the driver and let the driver atomically do whatever
  it needs to before changing the channel.

PR:		kern/166286
2012-03-25 03:11:57 +00:00
Bernhard Schmidt
65d22fe921 MCS32 equals 32, not 8*ic_txstream. 2012-01-02 16:02:30 +00:00
Bernhard Schmidt
fcd9500f91 Fix some net80211 enum nits:
- ic_vap_create() uses an ieee80211_opmode argument
- ieee80211_rate2media() takes an ieee80211_phymode argument
- ieee80211_plcp2rate() takes an ieee80211_phytype argument
- cast to enum ieee80211_protmode and ieee80211_roamingmode to silence
  compiler warnings

Submitted by:	arundel@
2011-12-17 10:23:17 +00:00
Adrian Chadd
198af96ed7 Correctly handle BAR TX failures.
On a TX failure, ic_raw_xmit will still call ieee80211_node_free().
There's no need to call it here.

Submitted by:	moonlightakkiy@yahoo.ca
Approved by:	re (kib)
2011-08-19 15:21:13 +00:00
Adrian Chadd
6291312c14 Fix BAR frame TX completion - successful transmission is indicated
by a status of 0.

Approved by:	re (kib)
2011-08-16 09:07:59 +00:00
Adrian Chadd
a834836d83 Add a callback for ADDBA response timeouts.
TX for the given TID needs to be paused during ADDBA requests (and unpaused
once the session is established.) Since net80211 currently doesn't implement
software aggregation, if this pause/unpause is done in the driver (as it
is in my development branch) then it will need to be unpaused both on
ADDBA response and on ADDBA timeout.

This callback allows the driver to unpause TX for the relevant TID.

Reviewed by:	bschmidt
2011-06-20 11:46:03 +00:00
Bernhard Schmidt
bf1f922275 Certain adapters have HT40 support on some but not all channels. The
Intel 4965 devices for example have HT40 on 2GHz completely disabled
but it is still supported for 5GHz. To handle that in sta mode we
need to check if we can "upgrade" to a HT40 channel after the
association, if that is not possible but we are still announcing
support to the remote side we are left with a very flabby connection.

Reviewed by:	adrian
2011-06-04 15:05:32 +00:00
Bernhard Schmidt
8dc8c1f7e3 Constantly use MHz instead of Mhz.
Pointed out by:	N.J. Mann <njm at njm.me.uk>
2011-03-13 13:05:50 +00:00
Bernhard Schmidt
597029bf18 Honor device capabilities while initializing ni_htrates.
Instead of hardcoding MCS0-15 generate the table dynamically, also
restrict the MCS rates to our own capabilities while parsing a htcap
element.
2011-03-13 12:16:23 +00:00
Bernhard Schmidt
d8e14b5eac Fill hc_mcsset completely.
Contrary to the rateset information in legacy frames the MCS Set
field also contains TX capability information in cases where the
number of available TX and RX spartial streams differ. Because a
rateset doesn't contain that information we have to pull the
those directly from the hardware capabilities.
2011-03-13 11:56:33 +00:00
Bernhard Schmidt
bffb67e30f Change the way HT capatibilities are announced.
Get rid of the assumption that every device is capable of 40MHz,
SGI and 2 spartial streams. Instead of printing, in the worst case,
8 times 76 MCS rates, print logically connect ranges and the
support RX/TX streams.

A device without 40MHz and SGI support looks like:
ath0: 2T2R
ath0: 11na MCS 20Mhz
ath0: MCS 0-7: 6.5Mbps - 65Mbps
ath0: MCS 8-15: 13Mbps - 130Mbps
ath0: 11ng MCS 20Mhz
ath0: MCS 0-7: 6.5Mbps - 65Mbps
ath0: MCS 8-15: 13Mbps - 130Mbps
2011-03-13 11:45:58 +00:00
Bernhard Schmidt
f136f45f39 Complete the MCS rate table based on the final 802.11n std. While here
adjust the IEEE80211_HTRATE_MAXSIZE constant, only MCS0 - 76 are valid
the other bits in the mcsset IE (77 - 127) are either reserved or used
for TX parameters.
2011-03-10 18:17:24 +00:00
Rui Paulo
e1d36f8395 Add a new field for extended HT capabilities.
Submitted by:	Alexander Egorenkov <egorenar at gmail.com>
MFC after:	2 weeks
Sponsored by:	iXsystems, inc.
2010-03-23 12:03:09 +00:00
Rui Paulo
fec0a521a7 Unbreak build by removing a code bit that is only related to other code
in my branch.
2010-03-18 15:28:17 +00:00
Rui Paulo
0917631f16 Fix a couple of bugs with 802.11n:
o Process the BAR frame on the adhoc, mesh and sta modes
o Fix the format of the ADDBA reply frame
o Fix references to the spec section numbers

Also, print the all the MCS rates in bootverbose.

Sponsored by:	iXsystems, Inc.
Obtained from:	//depot/user/rpaulo/80211n/...
2010-03-18 11:06:38 +00:00
Sam Leffler
7634012302 Revamp 802.11 action frame handling:
o add a new facility for components to register send+recv handlers
o ieee80211_send_action and ieee80211_recv_action now use the registered
  handlers to dispatch operations
o rev ieee80211_send_action api to enable passing arbitrary data
o rev ieee80211_recv_action api to pass the 802.11 frame header as it may
  be difficult to locate
o update existing IEEE80211_ACTION_CAT_BA and IEEE80211_ACTION_CAT_HT handling
o update mwl for api rev

Reviewed by:	rpaulo
Approved by:	re (kensmith)
2009-07-05 17:59:19 +00:00
Sam Leffler
32bdd57b9b Correct ieee80211_gettid:
o don't increment extracted tid, this was a vestige of IEEE80211_NONQOS_TID
  being defined as 0 (w/ real tid's +1)
o handle 4-address frames (add IEEE80211_IS_DSTODS to check if an 802.11
  header is DSTODS)

Submitted by:	cbzimmer
Reviewed by:	avatar
2009-06-09 16:32:07 +00:00
Sam Leffler
2bfc8a91c9 iv_flags_ext is full, make room by moving HT-related flags to a new
iv_flags_ht word
2009-06-07 22:00:22 +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
51b5aba2d6 allow drivers to hook ampdu rx start/stop 2009-04-26 22:54:51 +00:00
Sam Leffler
8ac160cd2e o change ieee80211_mgmt_output to take a raw xmit parameters block so
the net80211 layer has complete control over the handling of mgt frames
  (in particular, the ac, tx rate, and retry count); this also allows us
  to purge the M_LINK0 flag that was attached to mbufs to mark them as
  needing encryption for shared key auth
o change ieee80211_send_setup to take a tid parameter so it can be used
  to setup QoS frames
2008-10-26 00:43:11 +00:00
Sam Leffler
cc71a422ea Sync BAR frame handling with out of tree work:
o correct BAR frame construction for AMPDU
o retransmit BAR frames until ACK'd or timeout (use tunables to
  control behaviour, default is very aggressive)
o defer seq# update until BAR frame is ACK'd
o add BAR response handling callback for driver to interpose and
  push new state to device or push pending aggregates

While here also:
o add backpointer to node in the per-tid tx aggregation data structure
o move ampdu tx state setup/teardown work to separate functions
2008-10-25 23:58:59 +00:00
Sam Leffler
86c55fc405 cleanup after merge 2008-09-22 00:21:24 +00:00
Sam Leffler
49942a9784 Fix handling of shortgi: use the local configuration (and implicitly
device capabilities) to decide whether to use short gi.  Drivers
inspect ni_flags to decide whether to send a frame w/ short sgi.
2008-09-22 00:14:50 +00:00
Sam Leffler
44f7a6edcf RIFS support; needs driver callback for dynamic state change 2008-09-22 00:10:22 +00:00
Sam Leffler
8c070d69c7 MIMO power save support; still needs callbacks for notifying drivers
of dynamic state change in station mode.
2008-09-21 23:59:14 +00:00
Sam Leffler
fdabd982e7 Revamp ht ie handling:
o change ieee80211_parse_htcap and ieee80211_parse_htinfo to save only
  internal state obtained from the ie's; no dynamic state such as
  ni_chw is altered
o add ieee80211_ht_updateparams to parse ht cap+info ie's and update
  dynamic node state
o change ieee80211_ht_node_init to not take an htcap ie that is parsed;
  instead have the caller make a separate call as one caller wants to
  parse the ie while another wants to parse both cap+info ie's and
  update state so can better do this with ieee80211_ht_updateparams

These changes fix sta mode state handling where the node's channel
width was shifted to ht20/ht40 prematurely.
2008-09-21 23:44:15 +00:00
Sam Leffler
bd985970b6 don't propagate ht bss occupancy changes to legacy vaps;
they won't have an htinfo ie to update
2008-09-21 23:32:48 +00:00
Sam Leffler
3c1a492e4a change ieee80211_ampdu_stop to take an explicit reason code 2008-09-21 23:20:04 +00:00
Sam Leffler
af4ec66eb5 simplify debug msg 2008-09-21 23:18:36 +00:00
Sam Leffler
45f856e3ac Cleanup AMPDU handling:
For receive:
o explicitly tag rx frames w/ M_AMPDU instead of passing frames through
  the reorder processing according to the node having HT and the frame
  being QoS data
o relax ieee80211_ampdu_reorder asserts to allow any frame to be passed
  in, unsuitable frames are returned to the caller for normal processing;
  this permits drivers that cannot inspect the PLCP to mark all data
  frames as potential ampdu candidates with only a small penalty
o add M_AMPDU_MPDU to identify frames resubmitted from the reorder q

For transmit:
o tag aggregation candidates with M_AMPDU_MPDU
o fix the QoS ack policy set in ampdu subframes; we only support immediate
  BA streams which should be marked for "normal ack" to get implicit block
  ack behaviour; interestingly certain vendor parts BA'd frames with the
  11e BA ack policy set
o do not assign a sequence # to aggregation candidates; this must be done
  when frames are submitted for transmit (NB: this can/will be handled
  better when aggregation is pulled up to net80211)
2008-09-21 23:00:19 +00:00
Sam Leffler
b69b7fe758 Always update ic_lastnonht so we track overlapping legacy bss
properly; was doing this only on a change in the protection mode
so the advertised protection mode in the beacon would oscillate.

Submitted by:	Chris Zimmermann
2008-09-21 22:24:07 +00:00
Sam Leffler
c5f9511e91 Cleanup starting seq# for tx ampdu:
o use txa_start to form the addba request and purge txa_seqstart
o fill txa_start before calling ic_addba_request to permit drivers
  to override when they handle seq# generation (e.g. mwl)
2008-09-21 22:22:28 +00:00
Sam Leffler
c54fbb33b9 o kill IEEE80211_NODE_PSUPDATE; it was never used
o kill IEEE80211_NODE_CHWUPDATE; it's use was pointless and it was defined
  wrong (overlap w/ existing flags)
2008-09-06 17:42:51 +00:00
Sam Leffler
c0756f5f2e put back placeholder comment 2008-09-06 17:39:31 +00:00
Sam Leffler
eaff8e2689 o validate the ba policy in addba response
o leave a check for the max ba window disabled; we accept out of range
  values and just truncate them but may want to act differently in the future
2008-09-06 17:38:20 +00:00
Sam Leffler
9c62b7d4ed add IEEE80211_NODE_HT_ALL to collect up all the HT-related node flags 2008-09-06 17:33:46 +00:00
Sam Leffler
1582f2562d don't do ampdu reordering of fragments; they should never happen 2008-09-06 17:31:55 +00:00
Sam Leffler
33b9a974d5 moreve the aggregation q; it's not being used and
there's a better way to do this
2008-09-06 17:29:11 +00:00
Sam Leffler
d3d6c95298 add missing lock for htinfo update
Submitted by:	Chris Zimmermann
2008-08-02 18:04:09 +00:00
Sam Leffler
4d5ed46093 correct construction of delba action frame; don't shift+mask the initiator
argument

Submitted by:	Marvell
2008-07-05 19:56:47 +00:00
Sam Leffler
7f5144364e use the current left edge of the BA window when forming ADDBA request
so an existing session is re-established with the correct seq#
2008-05-11 23:27:57 +00:00