opnsense-src/sys
Adrian Chadd f1bc738ece Implement my first cut at filtered frames in aggregation sessions.
The hardware can optionally "filter" frames if successive transmissions
to a given node (ie, "entry in the keycache") fail.  That way the hardware
can implement a kind of early abort of all the other frames queued to
that destination, rather than simply trying to TX each frame to that
destination (and failing.)

The background:

* If a frame comes back as being filtered, the hardware didn't try to
  TX it (or it was outside the TX burst opportunity.) So, take it as a hint
  that some (but not all, see below) frames to the destination may be
  filtered.

* If the CLRDMASK bit is set in a TX descriptor, the "filter to this
  destination" bit in the keycache entry is cleared and TX to that host
  will be unconditionally retried.

* Right now everything has the CLRDMASK bit set, so filtered frames
  tend to be aggregates and frames that fall outside of the WME burst
  window. It was a bit worse in the past as I had messed up the TX
  flags and CLRDMASK wasn't being set on aggregate frames.

The annoying bits:

* It's easy (ish) to do for aggregate session frames - firstly, they
  can be retried in any order as long as they're within the BAW, and
  there's already a bunch of infrastructure tracking how many frames
  the TID has queued to the hardware (tid->hwq_depth.) However, for
  frames that bypassed the software queue, hwq_depth doesn't get
  incremented. I'll fix that in a subsequent commit.

* For non-aggregate session frames, the only retries that can occur
  are ones for sequence numbers that hvaen't successfully been TXed yet.
  Since there's no re-ordering going on in non-aggregate sessions, if any
  subsequent seqno frames make it out, any filtered frames before that
  seqno need to be dropped.

  Hence why this initially is just for aggregate session frames.

* Since there may be intermediary frames to the destination that
  have CLRDMASK set - for example, any directly dispatched management
  frames to that destination - it's possible that there will be some
  filtered frames followed up by some non filtered frames.  Thus,
  it can't be assumed that once you see a filtered frame for the given
  destination node, all subsequent frames for all TIDs will be filtered.

Ok, with that in mind:

* Create a per-TID filtered frame queue for frames that the hardware
  returns as filtered.

* Track filtered frames per-tid, rather than per-node.  It just makes
  the locking much easier.

* When a filtered frame appears in the completion function, the node
  transitions to "filtered", and all subsequent completed error frames
  (filtered or otherwise) are put on the filtered frame queue.  The TID
  is paused once (during the transition from non-filtered to filtered).

* If a filtered frame retry count exceeds SWMAX_RETRIES, a BAR should be
  sent.

* Once all the frames queued to the hardware for the given filtered frame
  TID, transition back from filtered frame to non-filtered frame, which
  means pre-pending all the filtered frames onto the head of the software
  queue, clearing the filtered frame state and unpausing the TID.

Things get quite hairy around handling completion (aggr, non-aggr, norm,
direct-dispatched frames to a hardware queue); whether it's an "error",
"cleanup" or "BAR" state as well as filtered, which order to do things
in (eg do filtered BEFORE checking for BAR, as the filter completion
may be needed to actually transmit a BAR frame.)

This work has definitely reminded me that I have to tidy up all the locking
and remove some of the ridiculous lock/unlock/lock/unlock going on in the
completion functions.

It's also reminded me that I should really split out TID versus hardware TXQ
locking, even if the underlying locking is still the destination hardware TXQ.

Finally, this is all pre-requisite for working on AP mode power save support
(PS-POLL, uAPSD) as well as improving performance to misbehaving nodes (as
they can transition into filter mode, stopping any TX until everything has
caught up.)

Finally (ish) - this should also be done for non-aggregate sessions as
there are still plenty of laptops and mobile devices that don't speak
802.11n but do wish for stable, useful power save AP support where packets
aren't simply dropped.  This requires software retransmission for
non-aggregate sessions to be implemented, which includes the caveats I've
mentioned above.

Finally finally - this doesn't yet do anything about the CLRDMASK bit in the
TX descriptor.  That's still unconditionally set to 1.  I'll debug the
current work (mostly ensuring I haven't busted up the hairy transitions
between BAR, filtered, error (all frames in an aggregate failing) and
cleanup (when transitioning from aggregation -> non-aggregation.))

Finally finally finally - this is all original work by yours truely, rather
than ported from the Atheros internal driver codebase or Linux ath9k.

Tested:
 * AR9280, AR5416 in STA mode
 * AR9280, AR9130 in hostap mode
 * Lots and lots of iperf testing in very marginal and non-marginal conditions,
   complete with inducing filtered frames + BAR TX conditions.
2012-09-18 10:14:17 +00:00
..
amd64 Integrate nvme(4) and nvd(4) into the amd64 and i386 builds. 2012-09-17 19:26:33 +00:00
arm Add a kernel config for the Toshiba AC100. The AC100 is an ARM laptop with 2012-09-17 09:22:59 +00:00
boot loader/i386: replace ugly inb/outb re-implementations with cpufunc.h 2012-09-18 08:53:11 +00:00
bsm
cam s/ is is / is /g 2012-09-14 22:00:03 +00:00
cddl zfs: correctly calculate dn_bonuslen for saving SAs to disk 2012-09-18 08:02:54 +00:00
compat Remove redundant check 2012-09-12 10:12:03 +00:00
conf Integrate nvme(4) and nvd(4) into the amd64 and i386 builds. 2012-09-17 19:26:33 +00:00
contrib o Create directory sys/netpfil, where all packet filters should 2012-09-14 11:51:49 +00:00
crypto
ddb
dev Implement my first cut at filtered frames in aggregation sessions. 2012-09-18 10:14:17 +00:00
fs Prefer __containerof() above member2struct(). 2012-09-15 19:28:54 +00:00
gdb
geom g_disk_flushcache definitely should not be traced under G_T_TOPOLOGY 2012-09-18 07:57:34 +00:00
gnu/fs Add VFCF_READONLY flag that indicates ntfs and xfs file systems are 2012-09-12 03:42:52 +00:00
i386 Integrate nvme(4) and nvd(4) into the amd64 and i386 builds. 2012-09-17 19:26:33 +00:00
ia64 userret() already checks for td_locks when INVARIANTS is enabled, so 2012-09-08 18:27:11 +00:00
isa
kern Correct double "the the" 2012-09-14 21:28:56 +00:00
kgssapi
libkern s/ is is / is /g 2012-09-14 22:00:03 +00:00
mips Prefer __containerof() above member2struct(). 2012-09-15 19:28:54 +00:00
modules Add nvme(4) and nvd(4) Makefiles to the tree. 2012-09-17 19:58:02 +00:00
net o Create directory sys/netpfil, where all packet filters should 2012-09-14 11:51:49 +00:00
net80211 Fix a crash bug introduced in the iterate node work recently done. 2012-09-16 22:45:00 +00:00
netatalk
netgraph o Create directory sys/netpfil, where all packet filters should 2012-09-14 11:51:49 +00:00
netinet s/teh/the/g 2012-09-14 21:59:55 +00:00
netinet6 Merge the projects/pf/head branch, that was worked on for last six months, 2012-09-08 06:41:54 +00:00
netipsec Add missing break 2012-09-18 08:00:43 +00:00
netipx
netnatm
netncp
netpfil Fix DIOCNATLOOK: zero key padding before performing lookup. 2012-09-18 09:15:32 +00:00
netsmb Change a duplicated check to clarify that we really want to set a 2012-07-10 21:02:59 +00:00
nfs - Typo fix 2012-08-16 19:22:34 +00:00
nfsclient Do not leave invalid pages in the object after the short read for a 2012-08-14 11:45:47 +00:00
nfsserver
nlm Fix grammar. 2012-08-16 13:01:56 +00:00
ofed Remove unneeded ipfw headers introduced in r213447 from Infiniband code. 2012-09-04 10:56:30 +00:00
opencrypto
pc98 Grammar fix: s/NIC's/NICs/ 2012-08-26 01:21:02 +00:00
pci
powerpc userret() already checks for td_locks when INVARIANTS is enabled, so 2012-09-08 18:27:11 +00:00
rpc Fix RPC headers for C++ 2012-09-02 21:04:40 +00:00
security
sparc64 Correct double "the the" 2012-09-14 21:28:56 +00:00
sys Remove namespace pollution in _rmlock.h by defining rm_queue structure 2012-09-18 00:43:15 +00:00
teken
tools
ufs Remove unused member of struct indir (in_exists) from UFS and EXT2 code. 2012-08-17 17:45:27 +00:00
vm Correct double "the the" 2012-09-14 21:28:56 +00:00
x86 Allow static DMA allocations that allow for enough segments to do page-sized 2012-08-17 14:14:25 +00:00
xdr
xen
Makefile