#
272461 |
|
02-Oct-2014 |
gjb |
Copy stable/10@r272459 to releng/10.1 as part of the 10.1-RELEASE process.
Approved by: re (implicit) Sponsored by: The FreeBSD Foundation |
#
262998 |
|
11-Mar-2014 |
rpaulo |
MFC r262930 Call ieee80211_dump_pkt() based on IFF_DUMPPKTS().
|
#
262007 |
|
16-Feb-2014 |
kevlo |
MFC r260444:
Rename definition of IEEE80211_FC1_WEP to IEEE80211_FC1_PROTECTED.
The origin of WEP comes from IEEE Std 802.11-1997 where it defines whether the frame body of MAC frame has been encrypted using WEP algorithm or not. IEEE Std. 802.11-2007 changes WEP to Protected Frame, indicates whether the frame is protected by a cryptographic encapsulation algorithm.
Reviewed by: adrian, rpaulo
|
#
259341 |
|
13-Dec-2013 |
rpaulo |
MFC r256658, r256666:
Move a lot of debugging printf's to DPRINTF.
|
#
256281 |
|
10-Oct-2013 |
gjb |
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
Approved by: re (implicit) Sponsored by: The FreeBSD Foundation
|
#
254435 |
|
16-Aug-2013 |
adrian |
Log the MAC address of the node in question rather than the pointer.
|
#
251090 |
|
28-May-2013 |
adrian |
Shuffle around the cleanup unpause calls a bit.
|
#
251014 |
|
26-May-2013 |
adrian |
Migrate ath(4) to now use if_transmit instead of the legacy if_start and if queue mechanism; also fix up (non-11n) TX fragment handling.
This may result in a bit of a performance drop for now but I plan on debugging and resolving this at a later stage.
Whilst here, fix the transmit path so fragment transmission works.
The TX fragmentation handling is a bit more special. In order to correctly transmit TX fragments, there's a bunch of corner cases that need to be handled:
* They must be transmitted back to back, in the same order.. * .. ie, you need to hold the TX lock whilst transmitting this set of fragments rather than interleaving it with other MSDUs destined to other nodes; * The length of the next fragment is required when transmitting, in order to correctly set the NAV field in the current frame to the length of the next frame; which requires .. * .. that we know the transmit duration of the next frame, which .. * .. requires us to set the rate of all fragments to the same length, or make the decision up-front, etc.
To facilitate this, I've added a new ath_buf field to describe the length of the next fragment. This avoids having to keep the mbuf chain together. This used to work before my 11n TX path work because the ath_tx_start() routine would be handed a single mbuf with m_nextpkt pointing to the next frame, and that would be maintained all the way up to when the duration calculation was done. This doesn't hold true any longer - the actual queuing may occur at any point in the future (think ath_node TID software queuing) so this information needs to be maintained.
Right now this does work for non-11n frames but it doesn't at all enforce the same rate control decision for all frames in the fragment. I plan on fixing this in a followup commit.
RTS/CTS has the same issue, I'll look at fixing this in a subsequent commit.
Finaly, 11n fragment support requires the driver to have fully decided what the rate scenario setup is - including 20/40MHz, short/long GI, STBC, LDPC, number of streams, etc. Right now that decision is (currently) made _after_ the NAV field value is updated. I'll fix all of this in subsequent commits.
Tested:
* AR5416, STA, transmitting 11abg fragments * AR5416, STA, 11n fragments work but the NAV field is incorrect for the reasons above.
TODO:
* It would be nice to be able to queue mbufs per-node and per-TID so we can only queue ath_buf entries when it's time to assemble frames to send to the hardware.
But honestly, we should just do that level of software queue management in net80211 rather than ath(4), so I'm going to leave this alone for now.
* More thorough AP, mesh and adhoc testing.
* Ensure that net80211 doesn't hand us fragmented frames when A-MPDU has been negotiated, as we can't do software retransmission of fragments.
* .. set CLRDMASK when transmitting fragments, just to ensure.
|
#
250866 |
|
21-May-2013 |
adrian |
Implement a separate hardware queue threshold for aggregate and non-aggr traffic.
When transmitting non-aggregate traffic, we need to keep the hardware busy whilst transmitting or small bursts in txdone/tx latency will kill us.
This restores non-aggregate iperf performance, especially when doing TDMA.
Tested:
* AR5416<->AR5416, TDMA * AR5416 STA <-> AR9280 AP
|
#
250796 |
|
18-May-2013 |
adrian |
More non-ATH_DEBUG build fixes.
|
#
250783 |
|
18-May-2013 |
adrian |
Be (very) careful about how to add more TX DMA work.
The list-based DMA engine has the following behaviour:
* When the DMA engine is in the init state, you can write the first descriptor address to the QCU TxDP register and it will work.
* Then when it hits the end of the list (ie, it either hits a NULL link pointer, OR it hits a descriptor with VEOL set) the QCU stops, and the TxDP points to the last descriptor that was transmitted.
* Then when you want to transmit a new frame, you can then either: + write the head of the new list into TxDP, or + you write the head of the new list into the link pointer of the last completed descriptor (ie, where TxDP points), then kick TxE to restart transmission on that QCU>
* The hardware then will re-read the descriptor to pick up the link pointer and then jump to that.
Now, the quirks:
* If you write a TxDP when there's been no previous TxDP (ie, it's 0), it works.
* If you write a TxDP in any other instance, the TxDP write may actually fail. Thus, when you start transmission, it will re-read the last transmitted descriptor to get the link pointer, NOT just start a new transmission.
So the correct thing to do here is:
* ALWAYS use the holding descriptor (ie, the last transmitted descriptor that we've kept safe) and use the link pointer in _THAT_ to transmit the next frame.
* NEVER write to the TxDP after you've done the initial write.
* .. also, don't do this whilst you're also resetting the NIC.
With this in mind, the following patch does basically the above.
* Since this encapsulates Sam's issues with the QCU behaviour w/ TDMA, kill the TDMA special case and replace it with the above.
* Add a new TXQ flag - PUTRUNNING - which indicates that we've started DMA.
* Clear that flag when DMA has been shutdown.
* Ensure that we're not restarting DMA with PUTRUNNING enabled.
* Fix the link pointer logic during TXQ drain - we should always ensure the link pointer does point to something if there's a list of frames. Having it be NULL as an indication that DMA has finished or during a reset causes trouble.
Now, given all of this, i want to nuke axq_link from orbit. There's now HAL methods to get and set the link pointer of a descriptor, so what we should do instead is to update the right link pointer.
* If there's a holding descriptor and an empty TXQ list, set the link pointer of said holding descriptor to the new frame.
* If there's a non-empty TXQ list, set the link pointer of the last descriptor in the list to the new frame.
* Nuke axq_link from orbit.
Note:
* The AR9380 doesn't need this. FIFO TX writes are atomic. As long as we don't append to a list of frames that we've already passed to the hardware, all of the above doesn't apply. The holding descriptor stuff is still needed to ensure the hardware can re-read a completed descriptor to move onto the next one, but we restart DMA by pushing in a new FIFO entry into the TX QCU. That doesn't require any real gymnastics.
Tested:
* AR5210, AR5211, AR5212, AR5416, AR9380 - STA mode.
|
#
250735 |
|
17-May-2013 |
adrian |
Add some more debugging printf()s to complain if the ath_buf tx queue doesn't match the actual hardware queue this frame is queued to.
I'm trying to ensure that the holding buffers are actually being queued to the same TX queue as the holding buffer that they end up on. I'm pretty sure this is all correct so if this complains, it'll be due to some kind of subtle broken-ness that needs fixing.
This is only done for legacy hardware, not EDMA hardware.
Tested:
* AR5416 STA mode, very lightly
|
#
250705 |
|
16-May-2013 |
adrian |
Tidy up the debugging - don't bother printing out TID pointers; now that we are printing out the MAC address in these fields, just printing out the TID is enough.
|
#
250704 |
|
16-May-2013 |
adrian |
Limit the number of software queued frames when doing non-aggregation.
This should prevent the TX queue being filled with non-aggregate frames, causing starvation and non-fair queue behaviour.
|
#
250665 |
|
15-May-2013 |
adrian |
Implement my first cut at "correct" node power-save and PS-POLL support.
This implements PS-POLL awareness i nthe
* Implement frame "leaking", which allows for a software queue to be scheduled even though it's asleep * Track whether a frame has been leaked or not * Leak out a single non-AMPDU frame when transmitting aggregates * Queue BAR frames if the node is asleep * Direct-dispatch the rest of control and management frames. This allows for things like re-association to occur (which involves sending probe req/resp as well as assoc request/response) when the node is asleep and then tries reassociating. * Limit how many frames can set in the software node queue whilst the node is asleep. net80211 is already buffering frames for us so this is mostly just paranoia. * Add a PS-POLL method which leaks out a frame if there's something in the software queue, else it calls net80211's ps-poll routine. Since the ath PS-POLL routine marks the node as having a single frame to leak, either a software queued frame would leak, OR the next queued frame would leak. The next queued frame could be something from the net80211 power save queue, OR it could be a NULL frame from net80211.
TODO:
* Don't transmit further BAR frames (eg via a timeout) if the node is currently asleep. Otherwise we may end up exhausting management frames due to the lots of queued BAR frames.
I may just undo this bit later on and direct-dispatch BAR frames even if the node is asleep.
* It would be nice to burst out a single A-MPDU frame if both ends support this. I may end adding a FreeBSD IE soon to negotiate this power save behaviour.
* I should make STAs timeout of power save mode if they've been in power save for more than a handful of seconds. This way cards that get "stuck" in power save mode don't stay there for the "inactivity" timeout in net80211.
* Move the queue depth check into the driver layer (ath_start / ath_transmit) rather than doing it in the TX path.
* There could be some naughty corner cases with ps-poll leaking. Specifically, if net80211 generates a NULL data frame whilst another transmitter sends a normal data frame out net80211 output / transmit, we need to ensure that the NULL data frame goes out first. This is one of those things that should occur inside the VAP/ic TX lock. Grr, more investigations to do..
Tested:
* STA: AR5416, AR9280 * AP: AR5416, AR9280, AR9160
|
#
250611 |
|
13-May-2013 |
adrian |
Improve the debugging output - use the MAC address rather than various pointer values everywhere.
|
#
250608 |
|
13-May-2013 |
adrian |
Oops, commit the other half of r250606.
|
#
250325 |
|
07-May-2013 |
adrian |
Simplify this bit of code!
|
#
249715 |
|
20-Apr-2013 |
adrian |
When doing BAW tracking, don't dereference a NULL pointer if the BAW slot is actually NULL.
|
#
249713 |
|
20-Apr-2013 |
adrian |
There's some races (likely in the BAR handling, sigh) which is causing the pause/resume code to not be called completely symmetrically.
I'll chase down the root cause of that soon; this at least works around the bug and tells me when it happens.
|
#
249569 |
|
16-Apr-2013 |
adrian |
Use the new net80211 method to fetch the node TX power, rather than directly referencing ni->ni_txpower.
This provides the hardware with a slightly more accurate idea of the maximum TX power to be using.
This is part of a series to get per-packet TPC to work (better).
Tested:
* AR5416, hostap mode
|
#
249000 |
|
02-Apr-2013 |
adrian |
Mark a couple of places where I think the dmamap isn't being unmapped before the TX path is being aborted.
Right now it's in the TDMA code and I can live with that; but it really should get fixed.
I'll do a more thorough audit of this code soon.
|
#
248988 |
|
01-Apr-2013 |
adrian |
Ensure that we only call the busdma unmap/flush routines once, when the buffer is being freed.
* When buffers are cloned, the original mapping isn't copied but it wasn't freeing the mapping until later. To be safe, free the mapping when the buffer is cloned.
* ath_freebuf() now no longer calls the busdma sync/unmap routines.
* ath_tx_freebuf() now calls sync/unmap.
* Call sync first, before calling unmap.
Tested:
* AR5416, STA mode
|
#
248985 |
|
01-Apr-2013 |
adrian |
Use ATH_MAX_SCATTER rather than ATH_TXDESC.
ATH_MAX_SCATTER is used to size the ath_buf DMA segment array. We thus should use it when checking sizes of things.
|
#
248750 |
|
26-Mar-2013 |
adrian |
Implement the replacement EDMA FIFO code.
(Yes, the previous code temporarily broke EDMA TX. I'm sorry; I should've actually setup ATH_BUF_FIFOEND on frames so txq->axq_fifo_depth was cleared!)
This code implements a whole bunch of sorely needed EDMA TX improvements along with CABQ TX support.
The specifics:
* When filling/refilling the FIFO, use the new TXQ staging queue for FIFO frames
* Tag frames with ATH_BUF_FIFOPTR and ATH_BUF_FIFOEND correctly. For now the non-CABQ transmit path pushes one frame into the TXQ staging queue without setting up the intermediary link pointers to chain them together, so draining frames from the txq staging queue to the FIFO queue occurs AMPDU / MPDU at a time.
* In the CABQ case, manually tag the list with ATH_BUF_FIFOPTR and ATH_BUF_FIFOEND so a chain of frames is pushed into the FIFO at once.
* Now that frames are in a FIFO pending queue, we can top up the FIFO after completing a single frame. This means we can keep it filled rather than waiting for it drain and _then_ adding more frames.
* The EDMA restart routine now walks the FIFO queue in the TXQ rather than the pending queue and re-initialises the FIFO with that.
* When restarting EDMA, we may have partially completed sending a list. So stamp the first frame that we see in a list with ATH_BUF_FIFOPTR and push _that_ into the hardware.
* When completing frames, only check those on the FIFO queue. We should never ever queue frames from the pending queue direct to the hardware, so there's no point in checking.
* Until I figure out what's going on, make sure if the TXSTATUS for an empty queue pops up, complain loudly and continue. This will stop the panics that people are seeing. I'll add some code later which will assist in ensuring I'm populating each descriptor with the correct queue ID.
* When considering whether to queue frames to the hardware queue directly or software queue frames, make sure the depth of the FIFO is taken into account now.
* When completing frames, tag them with ATH_BUF_BUSY if they're not the final frame in a FIFO list. The same holding descriptor behaviour is required when handling descriptors linked together with a link pointer as the hardware will re-read the previous descriptor to refresh the link pointer before contiuning.
* .. and if we complete the FIFO list (ie, the buffer has ATH_BUF_FIFOEND set), then we don't need the holding buffer any longer. Thus, free it.
Tested:
* AR9380/AR9580, STA and hostap * AR9280, STA/hostap
TODO:
* I don't yet trust that the EDMA restart routine is totally correct in all circumstances. I'll continue to thrash this out under heavy multiple-TXQ traffic load and fix whatever pops up.
|
#
248717 |
|
26-Mar-2013 |
adrian |
Remove the mcast path calls to ath_hal_gettxdesclinkptr() for axq_link - they're no longer needed for the legacy path and they're not wanted for the EDMA path.
Tested:
* AR9280, hostap + CABQ * AR9380/AR9580, hostap + CABQ
|
#
248713 |
|
26-Mar-2013 |
adrian |
Migrate the multicast queue assembly code to not use the axq_link pointer and instead use the HAL method to set the link pointer.
Tested:
* AR9280, hostap mode, CABQ frames being queued and transmitted
|
#
248676 |
|
24-Mar-2013 |
adrian |
Move the TXQ lock earlier in this routine - so to correctly protect the link pointer check.
|
#
248671 |
|
23-Mar-2013 |
adrian |
Overhaul the TXQ locking (again!) as part of some beacon/cabq timing related issues.
Moving the TX locking under one lock made things easier to progress on but it had one important side-effect - it increased the latency when handling CABQ setup when sending beacons.
This commit introduces a bunch of new changes and a few unrelated changs that are just easier to lump in here.
The aim is to have the CABQ locking separate from other locking. The CABQ transmit path in the beacon process thus doesn't have to grab the general TX lock, reducing lock contention/latency and making it more likely that we'll make the beacon TX timing.
The second half of this commit is the CABQ related setup changes needed for sane looking EDMA CABQ support. Right now the EDMA TX code naively assumes that only one frame (MPDU or A-MPDU) is being pushed into each FIFO slot. For the CABQ this isn't true - a whole list of frames is being pushed in - and thus CABQ handling breaks very quickly.
The aim here is to setup the CABQ list and then push _that list_ to the hardware for transmission. I can then extend the EDMA TX code to stamp that list as being "one" FIFO entry (likely by tagging the last buffer in that list as "FIFO END") so the EDMA TX completion code correctly tracks things.
Major:
* Migrate the per-TXQ add/removal locking back to per-TXQ, rather than a single lock.
* Leave the software queue side of things under the ATH_TX_LOCK lock, (continuing) to serialise things as they are.
* Add a new function which is called whenever there's a beacon miss, to print out some debugging. This is primarily designed to help me figure out if the beacon miss events are due to a noisy environment, issues with the PHY/MAC, or other.
* Move the CABQ setup/enable to occur _after_ all the VAPs have been looked at. This means that for multiple VAPS in bursted mode, the CABQ gets primed once all VAPs are checked, rather than being primed on the first VAP and then having frames appended after this.
Minor:
* Add a (disabled) twiddle to let me enable/disable cabq traffic. It's primarily there to let me easily debug what's going on with beacon and CABQ setup/traffic; there's some DMA engine hangs which I'm finally trying to trace down.
* Clear bf_next when flushing frames; it should quieten some warnings that show up when a node goes away.
Tested:
* AR9280, STA/hostap, up to 4 vaps (staggered) * AR5416, STA/hostap, up to 4 vaps (staggered)
TODO:
* (Lots) more AR9380 and later testing, as I may have missed something here. * Leverage this to fix CABQ hanling for AR9380 and later chips. * Force bursted beaconing on the chips that default to staggered beacons and ensure the CABQ stuff is all sane (eg, the MORE bits that aren't being correctly set when chaining descriptors.)
|
#
248527 |
|
19-Mar-2013 |
adrian |
Now that the tx map field is correctly populated for both edma and legacy chips, just use that.
|
#
248347 |
|
15-Mar-2013 |
adrian |
Why'd I keep this here? remove it entirely now.
|
#
248341 |
|
15-Mar-2013 |
adrian |
Fix two bugs:
* when pulling frames off of the TID queue, the ATH_TID_REMOVE() macro decrements the axq_depth field. So don't do it twice.
* in ath_tx_comp_cleanup_aggr(), bf wasn't being reset to bf_first before walking the buffer list to complete buffers; so those buffers will leak.
|
#
248312 |
|
15-Mar-2013 |
adrian |
Remove a now incorrect comment.
This comment dates back to my initial stab at TX aggregation completion, where I didn't even bother trying to do software retries.
|
#
248091 |
|
09-Mar-2013 |
adrian |
Disable the hw TID != buffer TID check.
I can 100% reliably trigger this on TID 1 traffic by using iperf -S 32 <client fields> to create traffic that maps to TID 1.
The reference driver doesn't do this check.
|
#
247135 |
|
21-Feb-2013 |
adrian |
Disable debugging entries about BAW issues. I haven't seen any issues to do with BAW tracking in the last 9 months or so.
|
#
247029 |
|
20-Feb-2013 |
adrian |
A couple of quick tidyups:
* Delete this debugging print - I used it when debugging the initial TX descriptor chaining code. It now works, so let's toss it. It just confuses people if they enable TX descriptor debugging as they get two slightly different versions of the same descriptor.
* Indenting.
|
#
246745 |
|
13-Feb-2013 |
adrian |
Pull out the if_transmit() work and revert back to ath_start().
My changed had some rather significant behavioural changes to throughput. The two issues I noticed:
* With if_start and the ifnet mbuf queue, any temporary latency would get eaten up by some mbufs being queued. With ath_transmit() queuing things to ath_buf's, I'd only get 512 TX buffers before I couldn't queue any further frames.
* There's also some non-zero latency involved with TX being pushed into a taskqueue via direct dispatch. Any time the scheduler didn't immediately schedule the ath TX task would cause extra latency. Various 1ge/10ge drivers implement both direct dispatch (if the TX lock can be acquired) and deferred task transmission (if the TX lock can't be acquired), with frames being pushed into a drbd queue. I'll have to do this at some point, but until I figure out how to deal with 802.11 fragments, I'll have to wait a while longer.
So what I saw:
* lots of extra latency, specially under load - if the taskqueue wasn't immediately scheduled, things went pear shaped;
* any extra latency would result in TX ath_buf's taking their sweet time being replenished, so any further calls to ath_transmit() would drop mbufs.
* .. yes, there's no explicit backpressure here - things are just dropped. Eek.
With this, the general performance has gone up, but those subtle if_start() related race conditions are back. For some reason, this is doubly-obvious with the AR5416 NIC and I don't quite understand why yet.
There's an unrelated issue with AR5416 performance in STA mode (it's fine in AP mode when bridging frames, weirdly..) that requires a little further investigation. Specifically - it works fine on a Lenovo T40 (single core CPU) running a March 2012 9-STABLE kernel, but a Lenovo T60 (dual core) running an early November 2012 kernel behaves very poorly. The same hardware with an AR9160 or AR9280 behaves perfectly.
|
#
246450 |
|
07-Feb-2013 |
adrian |
Methodize the process of adding the software TX queue to the taskqueue.
Move it (for now) to the TX taskqueue.
|
#
245927 |
|
25-Jan-2013 |
adrian |
Migrate the TX sending code out from under the ath0 taskq and into the separate ath0 TX taskq.
Whilst here, make sure that the TX software scheduler is also running out of the TX task, rather than the ath0 taskqueue.
Make sure that the tx taskqueue is blocked/unblocked as necessary.
This allows for a little more parallelism on multi-core machines, as well as (eventually) supporting a higher task priority for TX tasks, allowing said TX task to preempt an already running RX or TX completion task.
Tested:
* AR5416, AR9280 hostap and STA modes
|
#
245739 |
|
21-Jan-2013 |
adrian |
Fix this routine to acutally break out and not set clrdmask if any of the TIDs are currently marked as "filtered."
|
#
245708 |
|
21-Jan-2013 |
adrian |
Migrate CLRDMASK to be a per-node flag, rather than a per-TID flag.
This is easily possible now that the TX is protected by a single lock, rather than a per-TXQ (and thus per-TID) lock.
Only set CLRDMASK if none of the destinations are filtered. This likely will need some tuning when it comes time to do UASPD/PS-POLL TX, however at that point it should be manually set anyway.
Tested:
* AR9280, STA mode
TODO:
* More thorough testing in AP mode * test other chipsets, just to be safe/sure.
|
#
245465 |
|
15-Jan-2013 |
adrian |
Implement frame (data) transmission using if_transmit(), rather than if_start().
This removes the overlapping data path TX from occuring, which solves quite a number of the potential TX queue races in ath(4). It doesn't fix the net80211 layer TX queue races and it doesn't fix the raw TX path yet, but it's an important step towards this.
This hasn't dropped the TX performance in my testing; primarily because now the TX path can quickly queue frames and continue along processing.
This involves a few rather deep changes:
* Use the ath_buf as a queue placeholder for now, as we need to be able to support queuing a list of mbufs (ie, when transmitting fragments) and m_nextpkt can't be used here (because it's what is joining the fragments together)
* if_transmit() now simply allocates the ath_buf and queues it to a driver TX staging queue.
* TX is now moved into a taskqueue function.
* The TX taskqueue function now dequeues and transmits frames.
* Fragments are handled correctly here - as the current API passes the fragment list as one mbuf list (joined with m_nextpkt) through to the driver if_transmit().
* For the couple of places where ath_start() may be called (mostly from net80211 when starting the VAP up again), just reimplement it using the new enqueue and taskqueue methods.
What I don't like (about this work and the TX code in general):
* I'm using the same lock for the staging TX queue management and the actual TX. This isn't required; I'm just being slack.
* I haven't yet moved TX to a separate taskqueue (but the taskqueue is created); it's easy enough to do this later if necessary. I just need to make sure it's a higher priority queue, so TX has the same behaviour as it used to (where it would preempt existing RX..)
* I need to re-review the TX path a little more and make sure that ieee80211_node_*() functions aren't called within the TX lock. When queueing, I should just push failed frames into a queue and when I'm wrapping up the TX code, unlock the TX lock and call ieee80211_node_free() on each.
* It would be nice if I could hold the TX lock for the entire TX and TX completion, rather than this release/re-acquire behaviour. But that requires that I shuffle around the TX completion code to handle actual ath_buf free and net80211 callback/free outside of the TX lock. That's one of my next projects.
* the ic_raw_xmit() path doesn't use this yet - so it still has sequencing problems with parallel, overlapping calls to the data path. I'll fix this later.
Tested:
* Hostap - AR9280, AR9220 * STA - AR5212, AR9280, AR5416
|
#
244109 |
|
11-Dec-2012 |
adrian |
There's no need to use a TXQ pointer here; we specifically need the hardware queue ID when queuing to EDMA descriptors.
This is a small part of trying to reduce the size of ath_buf entries.
|
#
243857 |
|
04-Dec-2012 |
glebius |
Mechanically substitute flags from historic mbuf allocator with malloc(9) flags in sys/dev.
|
#
243787 |
|
02-Dec-2012 |
adrian |
Don't grab the PCU lock inside the TX lock.
|
#
243786 |
|
02-Dec-2012 |
adrian |
Delete the per-TXQ locks and replace them with a single TX lock.
I couldn't think of a way to maintain the hardware TXQ locks _and_ layer on top of that per-TXQ software queuing and any other kind of fine-grained locks (eg per-TID, or per-node locks.)
So for now, to facilitate some further code refactoring and development as part of the final push to get software queue ps-poll and u-apsd handling into this driver, just do away with them entirely.
I may eventually bring them back at some point, when it looks slightly more architectually cleaner to do so. But as it stands at the present, it's not really buying us much:
* in order to properly serialise things and not get bitten by scheduling and locking interactions with things higher up in the stack, we need to wrap the whole TX path in a long held lock. Otherwise we can end up being pre-empted during frame handling, resulting in some out of order frame handling between sequence number allocation and encryption handling (ie, the seqno and the CCMP IV get out of sequence);
* .. so whilst that's the case, holding the lock for that long means that we're acquiring and releasing the TXQ lock _inside_ that context;
* And we also acquire it per-frame during frame completion, but we currently can't hold the lock for the duration of the TX completion as we need to call net80211 layer things with the locks _unheld_ to avoid LOR.
* .. the other places were grab that lock are reset/flush, which don't happen often.
My eventual aim is to change the TX path so all rejected frame transmissions and all frame completions result in any ieee80211_free_node() calls to occur outside of the TX lock; then I can cut back on the amount of locking that goes on here.
There may be some LORs that occur when ieee80211_free_node() is called when the TX queue path fails; I'll begin to address these in follow-up commits.
|
#
243647 |
|
28-Nov-2012 |
adrian |
Until I figure out what to do here, remind myself that this needs some rate control 'adjustment' when NOACK is set.
|
#
243162 |
|
16-Nov-2012 |
adrian |
ALQ logging enhancements:
* upon setup, tell the alq code what the chip information is. * add TX/RX path logging for legacy chips. * populate the tx/rx descriptor length fields with a best-estimate. It's overly big (96 bytes when AH_SUPPORT_AR5416 is enabled) but it'll do for now.
Whilst I'm here, add CURVNET_RESTORE() here during probe/attach as a partial solution to fixing crashes during attach when the attach fails. There are other attach failures that I have to deal with; those'll come later.
|
#
243047 |
|
15-Nov-2012 |
adrian |
Make sure the final descriptor in an aggregate has rate control information.
This was broken by me when merging the 802.11n aggregate descriptor chain setup with the default descriptor chain setup, in preparation for supporting AR9380 NICs.
The corner case here is quite specific - if you queue an aggregate frame with >1 frames in it, and the last subframe has only one descriptor making it up, then that descriptor won't have the rate control information copied into it. Look at what happens inside ar5416FillTxDesc() if both firstSeg and lastSeg are set to 1.
Then when ar5416ProcTxDesc() goes to fill out ts_rate based on the transmit index, it looks at the rate control fields in that descriptor and dutifully sets it to be 0.
It doesn't happen for non-aggregate frames - if they have one descriptor, the first descriptor already has rate control info.
I removed the call to ath_hal_setuplasttxdesc() when I migrated the code to use the "new" style aggregate chain routines from the HAL. But I missed this particular corner case.
This is a bit inefficient with MIPS boards as it involves a few redundant writes into non-cachable memory. I'll chase that up when it matters.
Tested:
* AR9280 STA mode, TCP iperf traffic * Rui Paulo <rpaulo@> first reported this and has verified it on his AR9160 based AP.
PR: kern/173636
|
#
242951 |
|
13-Nov-2012 |
adrian |
Add some debugging to try and catch an invalid TX rate (0x0) that is being reported.
|
#
242898 |
|
11-Nov-2012 |
adrian |
Remove this; i incorrectly committed the wrong (debug) changes in my previous commit.
|
#
242881 |
|
10-Nov-2012 |
adrian |
Don't call av_set_tim() if it's NULL.
This happens during a scan in STA mode; any queued data frames will be power save queued but as there's no TIM in STA mode, it panics.
This was introduced by me when I disabled my driver-aware power save handling support.
|
#
242782 |
|
08-Nov-2012 |
adrian |
Add some hooks into the driver to attach, detach and record EDMA descriptor events.
This is primarily for the TX EDMA and TX EDMA completion. I haven't yet tied it into the EDMA RX path or the legacy TX/RX path.
Things that I don't quite like:
* Make the pointer type 'void' in ath_softc and have if_ath_alq*() return a malloc'ed buffer. That would remove the need to include if_ath_alq.h in if_athvar.h. * The sysctl setup needs to be cleaned up.
|
#
242656 |
|
06-Nov-2012 |
adrian |
Convert the aggregate descriptor path over to use the same API as the non-aggregate path.
I "cheated" by using some TX setup code in our HAL that isn't present in the atheros HAL (or Linux ath9k.)
The old path for forming aggregates was:
* setup the rate control in the first descriptor; * call chaintxdesc() on all the frames; * call setupfirsttxdesc() on the first descrpitor in the first frame; * call setuplasttxdesc() on the last descriptor in the last frame.
The new path for forming aggregates looks like the non-aggregate path:
* call setuptxdesc() on the first descriptor in the first frame; * setup the rate control in the first descriptor; * call filltxdesc() on each descriptor in the frame; * if it's an aggregate - call set11n_aggr_{first, middle, last} as appropriate (see the code for a description of what is "appropriate".)
Now, this is done primarily for the AR9300 HAL - it doesn't implement the first set of aggregate functions. It just has the older methods and the "first/middle/last" aggregate methods. So, let's convert the code to use these.
Note: the AR5416 HAL in FreeBSD had that code (from me, a while ago) and a previous commit brought it up to behave the same as the AR9300 HAL routines.
There's some further tidyups to be done - specifically, avoid doing multiple calls to the 11n descriptor functions. I shouldn't call clr11n_aggr(), then set11n_aggr_middle(), then also set11n_aggr_first(). On (at least MIPS) the TX descriptors are in non-cachable memory and this will cause multiple slow writes.
I'll debug/tidy that up in a future commit.
Tested:
* AR9280, STA * AR9280/AR9160, AP * AR9380, STA (using a local, closed source HAL, sorry!)
|
#
242391 |
|
31-Oct-2012 |
adrian |
I give up - introduce a TX lock to serialise TX operations.
I've tried serialising TX using queues and such but unfortunately due to how this interacts with the locking going on elsewhere in the networking stack, the TX task gets delayed, resulting in quite a noticable throughput loss:
* baseline TCP for 2x2 11n HT40 is ~ 170mbit/sec; * TCP for TX task in the ath taskq, with the RX also going on - 80mbit/sec; * TCP for TX task in a separate, second taskq - 100mbit/sec.
So for now I'm going with the Linux wireless stack approach - lock tx early. The linux code does in the wireless stack, before the 802.11 state stuff happens and before it's punted to the driver. But TX locking needs to also occur at the driver layer as the TX completion code _also_ begins to drain the ifnet TX queue.
Whilst I'm here, add some KTR traces for the TX path.
Note:
* This really should be done at the net80211 layer (as well, at least.) But that'll have to wait for a little more thought to happen.
|
#
242271 |
|
28-Oct-2012 |
adrian |
Begin fleshing out some software queue awareness for TIM handling with the power save queue.
* introduce some new ATH_NODE lock protected fields, tracking the net80211 psq and TIM state; * when doing buffer transitions - ie, when sending and completing buffers - check the state of the SWQ and update the TIM appropriately. * when clearing the TIM bit, if the SWQ is not empty then delay clearing it.
This is racy, but it's no less racy than the current net80211 power save queue management code. Specifically, with multiple TX threads, it's quite plausible that parallel state updates will race and the TIM will be left in an inconsistent state. I'll address that in a follow-up commit.
|
#
242144 |
|
26-Oct-2012 |
adrian |
Since it's not immediately obvious whether the current TX path handles fragment rate lookups correctly, add a comment describing exactly that.
The assumption in the fragment duration code is the duration of the next fragment will match the rate used by the current fragment. But I think a rate lookup is being done for _each_ fragment. For older pre-sample rate control this would almost always be the case, but for sample it may be incorrect more often then correct.
|
#
241566 |
|
14-Oct-2012 |
adrian |
Stop abusing the ATH_TID_*() queue macros for filtered frames and give them their own macro set.
|
#
241500 |
|
13-Oct-2012 |
adrian |
Fix the non-TDMA build.
|
#
241336 |
|
07-Oct-2012 |
adrian |
Migrate the TID TXQ accesses to a new set of macros, rather than reusing the ATH_TXQ_* macros.
* Introduce the new macros; * rename the TID queue and TID filtered frame queue so the compiler tells me I'm using the wrong macro.
These should correspond 1:1 to the existing code.
|
#
241170 |
|
03-Oct-2012 |
adrian |
Pause and unpause the software queues for a given node based on the net80211 node power save state.
* Add an ATH_NODE_UNLOCK_ASSERT() check * Add a new node field - an_is_powersave * Pause/unpause the queue based on the node state * Attempt to handle net80211 concurrency issues so the queue doesn't get paused/unpaused more than once at a time from the net80211 power save code.
Whilst here (and breaking my usual rule), set CLRDMASK when a queue is unpaused, regardless of whether the queue has some pending traffic. This means the first frame from that TID (now or later) will hvae CLRDMASK set.
Also whilst here, bump the swretrymax counters whenever the filtered frames code expires a frame. Again, breaking my rule, but this is just a statistics thing rather than a functional change.
This doesn't fix ps-poll (but it doesn't break it too much worse than it is at the present) or correcting the TID updates. That's next on the list.
Tested: * AR9220 AP (Atheros AP96 reference design) * Macbook Pro and LG Optimus 1 Android phone, both setting and clearing power save state (but not using PS-POLL.)
|
#
240946 |
|
26-Sep-2012 |
adrian |
Map the non-QoS TID to the voice queue, in order to ensure important things like EAPOL frames make it out.
After a whole bunch of hacking/testing, I discovered that they weren't being early-dropped by the stack (but I should look at ensuring that later..) but were even making to the hardware transmit queue. They were mostly even being received by the remote end. However, the remote end was completely ignoring them.
This didn't happen under 150-170MBit TCP tests as I'm guessing the TX queue stayed very busy and the STA didn't do any scanning. However, when doing 100Mbit/s of TCP traffic, the STA would do background scanning - which involves it coming in and out of powersave mode with the AP.
Now, this is a total and utter hack around the real problems, which are:
* I need to implement proper power save handling and integrate it into the filtered frames support, so the driver/stack doesn't send frames whilst the station is actually in sleep;
* .. but frames were actually making it to the STA (macbook pro) and the AP did receive an ACK; but a tcpdump on the receiving side showed the EAPOL frame never made it. So the stack was dropping it for some reason;
* Importantly - the EAPOL frames are currently going into the non-QoS TID, which maps to the BE queue and is susceptible to that queue being busy doing other things, but;
* There's other traffic going on in the non-QoS TID from other contexts when scanning is going on and it's possible there's some races causing sequence number/IV issues, but;
* Importantly importantlly, I think the interaction with TID 16 multicast traffic in power save mode is causing issues - since I -believe- the sequence number space being used by the EAPOL frames on TID 16 overlaps with the multicast frames that have sequence numbers allocated and are then stuffed on the cabq. Since with EAPOL frames being in TID 16 and queued to the BE queue, it's going to be waiting to be serviced with all of the aggregate traffic going on - and if the CABQ gets emptied beforehand, those TID 16 multicast frames with sequence numbers will go out beforehand.
Now, there's quite likely a bunch of "stuff happening slightly out of sequence" going on due to the nature of the TX path (read: lots of overlapping and concurrent ath_start() and ath_raw_xmit() calls going on, sigh) but I thought I had caught them all and stuffed each TID TX behind a lock (that lasted as long as it needed to in order to get the frame onto the relevant destination queue - thus keeping things in order.)
Unfortunately the last problem is the big one and I'm going to stare at it some more. If it _is_
So this is a work around for now to ensure that EAPOL frames actually make it out before any other stuff in the non-QoS TID and HOPEFULLY before the CABQ gets active.
I'm now going to spend a little time in the TX path figuring out exactly why the sender is rejecting things. There's two (well, three if you count EAPOL contents invalid) possibilities:
* The sequence number is out of order (ie, something else like the multicast traffic on CABQ) is going out first on TID 16; * The CCMP IV is out of order (similar to above - but less likely, as the TX key for multicast traffic is different to unicast traffic); * EAPOL contents strangely invalid.
AP: Ubiquiti RSPRO, AR9160/AR9220 NICs STA: Macbook Pro, Broadcom 11n NIC
|
#
240926 |
|
25-Sep-2012 |
adrian |
Oops - don't do the clrdmask check in ath_tx_xmit_normal() - the wrong lock may be held.
Kim reported that the TID lock wasn't held when ath_tx_update_clrdmask() was called. Well, the underlying hardware TXQ for that TID.
I'm betting it's the cabq stuff. ath_tx_xmit_normal() can be called for both real and software cabq. For software cabq, the real destination txq is different to the txq. So, the lock check will fail.
Reported by: Kim Culhan <w8hdkim@gmail.com>
|
#
240914 |
|
25-Sep-2012 |
adrian |
Call ath_tx_tid_unsched() after the node has been flushed, so the state can be printed correctly.
|
#
240899 |
|
24-Sep-2012 |
adrian |
Migrate the ath(4) KTR logging to use an ATH_KTR() macro.
This should eventually be unified with ATH_DEBUG() so I can get both from one macro; that may take some time.
Add some new probes for TX and TX completion.
|
#
240883 |
|
24-Sep-2012 |
adrian |
Prepare for software retransmission of non-aggregate frames but ensure it's disabled.
The previous commit to enable CLRDMASK setting didn't do it at all correctly for non-aggregate sessions - so the CLRDMASK bit would be cleared and never re-set.
* move ath_tx_update_clrdmask() to be called by functions that setup descriptors and queue frames to the hardware, rather than scattered everywhere.
* Force CLRDMASK to be set on all non-aggregate session frames being transmitted.
* Use ath_tx_normal_comp() now on non-aggregate sessoin frames that are queued via ath_tx_xmit_normal(). That way the TID hwq is updated and they can trigger (eventual) filter frame queue resets and software retransmits.
There's still a bit more work to do in this area to reverse the silly short-sightedness on my part, however it's likely going to be better to fix this now than just reverting the patch.
Thanks to people on the freebsd-wireless@ mailing list for promptly pointing this out.
|
#
240882 |
|
24-Sep-2012 |
adrian |
In (eventual) preparation for supporting disabling the whole 11n/software retry path - add some code to make it obvious (to me!) how to disable the software tx path.
|
#
240724 |
|
20-Sep-2012 |
adrian |
Introduce the CLRDMASK gating based on tid->clrdmask, enabling filtered frames to occur.
* Create a new function which will set the bf_flags CLRDMASK bit if required. * For raw frames, always set CLRDMASK. * For BAR, ADDBA frames, always set CLRDMASK. * For everything else, check if CLRDMASK needs to be set before calling tx_setds() or tx_setds11n(). * When unpausing a queue or drain/resetting it, set tid->clrdmask=1 just to ensure traffic starts flowing.
What I need to do:
* Modify that function to _clear_ the CLRDMASK if it's not required, or retried frames may have CLRDMASK set when they don't need to. (Which isn't a huge deal, but..)
Whilst I'm here:
* ath_tx_normal_xmit() should really act like the AMPDU session TX functions - any incomplete frames will end up being assigned ath_tx_normal_comp() which will decrement tid->hwq_depth - but that won't have been incremented.
So whilst I'm here, add a comment to do that.
* Fix the debug print function to be slightly clearer about things; it's not a good sign when I can't interpret my own debugging output.
I've done some testing on AR9280/AR5416/AR9160 STA and AP modes.
|
#
240722 |
|
20-Sep-2012 |
adrian |
Place the comment where it should be.
|
#
240721 |
|
20-Sep-2012 |
adrian |
Add a work-around for some strange net80211 BAR races in the wireless stack.
There are unfortunately quite a few odd cases in BAR TX and BAR TX retransmission that I haven't yet fully diagnosed. So for now, add this work-around so the resume() function isn't called too often, decrementing pause to -1 (and causing things to stay paused.)
|
#
240677 |
|
18-Sep-2012 |
adrian |
Oops - take a copy of ath_tx_status from the buffer before the TX processing is done.
The aggregate path was definitely accessing 'ts' before it was actually being assigned.
This had the side effect of over-filtering frames, since occasionally that bit would be '1'.
Whilst here, do the same thing in the non-aggregate completion function - as calling the filter function may also invalidate bf.
Pointy hat to: adrian, for not noticing this over many, many code reviews.
|
#
240639 |
|
18-Sep-2012 |
adrian |
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.
|
#
240592 |
|
17-Sep-2012 |
adrian |
Take credit for the work I've done in this source file.
|
#
240333 |
|
11-Sep-2012 |
adrian |
Clear the correct descriptor when going through the chained together gather DMA descriptor list.
Pointy hat to: adrian@, for even USING bf->bf_desc here instead of 'ds'.
|
#
240255 |
|
09-Sep-2012 |
adrian |
Make sure the aggregate fields are properly cleared - both in the ath_buf and when forming a non-aggregate frame.
The non-11n setds function is called when TXing aggregate frames (and yes, I should fix this!) and the non-11n TX aggregation code doesn't clear the delimiter field. I figure it's nicer to do that.
|
#
240180 |
|
06-Sep-2012 |
adrian |
Ensure that single-frame aggregate session frames are retransmitted with the correct configuration.
Occasionally an aggregate TX would fail and the first frame would be retransmitted as a non-AMPDU frame. Since bfs_aggr=1 and bfs_nframes > 1 (from the previous AMPDU attempt), the aggr completion function would be called and be very confused about what's going on.
Noticed by: Kim <w8hdkim@gmail.com> PR: kern/171394
|
#
239465 |
|
20-Aug-2012 |
adrian |
Fix a build issue when ATH_DEBUG isn't defined - just initialise and use qnum.
|
#
239438 |
|
20-Aug-2012 |
adrian |
Wrap debugging in #ifdef ATH_DEBUG
|
#
239409 |
|
20-Aug-2012 |
adrian |
Advance the descriptor pointer by sc->sc_tx_desclen bytes, rather than sizeof(struct ath_desc). This isn't correct for EDMA TX descriptors.
This popped up during iperf tests. Ping tests never created frames that had enough segments to overflow into a second descriptor. However, an iperf TCP test would do that after a few seconds; the second descriptor would almost always certainly have garbage.
Tested:
* AR9380, STA mode * AR9280, STA mode (802.11n TX, legacy TX)
|
#
239380 |
|
19-Aug-2012 |
adrian |
When assembling the descriptor list, make sure that the "first" descriptor is marked correctly.
The existing logic assumed that the first descriptor is i == 0, which doesn't hold for EDMA TX. In this instance, the first time filltxdesc() is called can be up to i == 3.
So for a two-buffer descriptor:
* firstSeg is set to 0; * lastSeg is set to 1; * the ath_hal_filltxdesc() code will treat it as the last segment in a descriptor chain and blank some of the descriptor fields, causing the TX to stop.
When firstSeg is set to 1 (regardless of lastSeg), it overrides the lastSeg setting. Thus, ath_hal_filltxdesc() won't blank out these fields.
Tested: AR9380, STA mode. With this, association is successful.
|
#
239290 |
|
15-Aug-2012 |
adrian |
Extend the non-aggregate TX descriptor chain routine to be aware of:
* the descriptor ID, and * the multi-buffer support that the EDMA chips support.
This is required for successful MAC transmission of multi-descriptor frames. The MAC simply hangs if there are NULL buffers + 0 length pointers, but the descriptor did have TxMore set.
This won't be done for the 11n aggregate path, as that will be modified to use the newer API (ie, ath_hal_filltxdesc() and then set first|middle| last_aggr), which will deprecate some of the current code.
TODO:
* Populate the numTxMaps field in the HAL, then make sure that's fetched by the driver. Then I can undo that hack.
Tested:
* AR9380, AP mode, TX'ing non-aggregate 802.11n frames; * AR9280, STA/AP mode, doing aggregate and non-aggregate traffic.
|
#
239205 |
|
11-Aug-2012 |
adrian |
Revert the ath_tx_draintxq() method, and instead teach it the minimum necessary to "do" EDMA.
It was just using the TX completion status for logging information about the descriptor completion. Since with EDMA we don't know this without checking the TX completion FIFO, we can't provide this information. So don't.
|
#
239204 |
|
11-Aug-2012 |
adrian |
Break out ath_draintxq() into a method and un-methodize ath_tx_processq().
Now that I understand what's going on with this, I've realised that it's going to be quite difficult to implement a processq method in the EDMA case. Because there's a separate TX status FIFO, I can't just run processq() on each EDMA TXQ to see what's finished. i have to actually run the TX status queue and handle individual TXQs.
So:
* unmethodize ath_tx_processq(); * leave ath_tx_draintxq() as a method, as it only uses the completion status for debugging rather than actively completing the frames (ie, all frames here are failed); * Methodize ath_draintxq().
The EDMA ath_draintxq() will have to take care of running the TX completion FIFO before (potentially) freeing frames in the queue.
The only two places where ath_tx_draintxq() (on a single TXQ) are used:
* ath_draintxq(); and * the CABQ handling in the beacon setup code - it drains the CABQ before populating the CABQ with frames for a new beacon (when doing multi-VAP operation.)
So it's quite possible that once I methodize the CABQ and beacon handling, I can just drop ath_tx_draintxq() in its entirety.
Finally, it's also quite possible that I can remove ath_tx_draintxq() in the future and just "teach" it to not check the status when doing EDMA.
|
#
239198 |
|
11-Aug-2012 |
adrian |
Add the AR9300 HAL ID in to the 11n check routine.
I was having TX hang issues, which I root caused to having the legacy ath_hal_setupxtxdesc() called, rather than the 11n rate scenario setup code. This meant that rate control information wasn't being put into frames, causing the MAC to stall/hang.
|
#
239120 |
|
06-Aug-2012 |
adrian |
Correct re-initialise the link pointer to be the final descriptor in the last buffer.
This fixes traffic stalls that were occuring with stuck beacon events.
PR: kern/170433
|
#
239053 |
|
05-Aug-2012 |
adrian |
Migrate the 802.11n ath_hal_chaintxdesc() API to use a buffer/segment array, similar to what filltxdesc() uses.
This removes the last reference to ds_data in the TX path outside of debugging statements. These need to be adjusted/fixed.
Tested:
* AR9280 STA/AP with iperf TCP traffic
|
#
239051 |
|
05-Aug-2012 |
adrian |
Migrate the ath_hal_filltxdesc() API to take a list of buffer/seglen values.
The existing API only exposes 'seglen' (the current buffer (segment) length) with the data buffer pointer set in 'ds_data'. This is fine for the legacy DMA engine but it won't work for the EDMA engines.
The EDMA engine has a significantly different TX descriptor layout.
* The legacy DMA engine had a ds_data pointer at the same offset in the descriptor for both TX and RX buffers; * The EDMA engine has no ds_data for RX - the data is DMAed after the descriptor; * The EDMA engine has support for 4 TX buffer/segment pairs in the TX DMA descriptor; * The EDMA TX completion is in a different FIFO, and the driver will 'link' the status completion entry to a QCU by a "QCU ID". I don't know why it's just not filled in by the hardware, alas.
So given that, here are the changes:
* Instead of directly fondling 'ds_data' in ath_desc, change the ath_hal_filltxdesc() to take an array of buffer pointers as well as segment len pointers; * The EDMA TX completion status wants a descriptor and queue id. This (for now) uses bf_state.bfs_txq and will extract the hardware QCU ID from that. * .. and this is ugly and wasteful; it should change to just store the QCU in the bf_state and save 3/7 bytes in the process.
Now, the weird crap:
* The aggregate TX path was using bf_state->bfs_txq for the TXQ, rather than taking a function argument. I've tidied that up. * The multicast queue frames get put on a software TXQ and then that is appended to the hardware CABQ when appropriate. So for now, make sure that bf_state->bfs_txq points at the CABQ when adding frames to the multicast queue. * .. but the multicast queue TX path for now doesn't use the software queue and instead (a) directly sets up the descriptor contents at that point; (b) the frames on the vap->avp_mcastq are then just appended wholesale to the CABQ. So for now, I don't have to worry about making the multicast path work with aggregation or the per-TID software queue. Phew.
What's left to do:
* I need to modify the 11n ath_hal_chaintxdesc() API to do the same. I'll do that in a subsequent commit. * Remove bf_state.bfs_txq entirely and store the QCU as appropriate. * .. then do the runtime "is this going on the right HWQ?" checks using that, rather than comparing pointer values.
Tested on:
* AR9280 STA/AP * AR5416 STA/AP
|
#
238993 |
|
02-Aug-2012 |
adrian |
Fix an issue that crept in with the previous descriptor tidyup.
When forming aggregates, the last descriptor was now not being correctly setup - instead, the "setuplasttxdesc" call was being handed the first descriptor in the last subframe, rather than the last descriptor in the last subframe.
This showed up as "bad series0 hwrate" messages, as the final descriptor just didn't have any of the rate control information squirreled away.
Tested: * AR9280 STA -> 11n AP, iperf TCP
|
#
238961 |
|
31-Jul-2012 |
adrian |
Allow 802.11n hardware to support multi-rate retry when RTS/CTS is enabled.
The legacy (pre-802.11n) hardware doesn't support this - although the AR5212 era hardware supports MRR, it doesn't have all the bits needed to support MRR + RTS/CTS. The AR5416 and later support a packet duration and RTS/CTS flags per rate scenario, so we should support it.
Tested:
* AR9280, STA
PR: kern/170302
|
#
238949 |
|
31-Jul-2012 |
adrian |
Shuffle the call to ath_hal_setuplasttxdesc() to _after_ the rate control code is called and remove it from ath_buf_set_rate().
For the legacy (non-11n API) TX routines, ath_hal_filltxdesc() takes care of setting up the intermediary and final descriptors right, complete with copying the rate control info into the final descriptor so the rate modules can grab it.
The 11n version doesn't do this - ath_hal_chaintxdesc() doesn't copy the rate control bits over, nor does it clear isaggr/moreaggr/ pad delimiters. So the call to setuplasttxdesc() is needed here.
So:
* legacy NICs - never call the 11n rate control stuff, so filltxdesc copies the rate control info right; * 11n NICs transmitting legacy or 11n non-aggregate frames - ath_hal_set11nratescenario() is called to setup rate control and then ath_hal_filltxdesc() chains them together - so the rate control info is right; * 11n aggregate frames - set11nratescenario() is called, then ath_hal_chaintxdesc() is called to chain a list of aggregate and subframes together. This requires a call to ath_hal_setuplasttxdesc() to complete things.
Tested:
* AR9280 in station mode
TODO:
* I really should make sure that the descriptor contents get blanked out correctly or garbage left over from aggregate frames may show up in non-aggregate frames, leading to badness.
|
#
238947 |
|
31-Jul-2012 |
adrian |
Push the rate control and descriptor chaining into the descriptor "set" functions, for both legacy and 802.11n.
This will simplify supporting the EDMA chipsets as these two descriptor setup functions can just be overridden in their entirety, hiding all of the subtle differences in setting things up.
It's not a permanent solution, as eventually the AR5416 HAL should grow similar versions of the 11n descriptor functions and then those can be used.
TODO:
* Push the "clr11naggr" call into the legacy setds, just to ensure that retried frames don't end up with the aggregate bits set inappropriately; * Remove the "setlasttxdesc" call from the 11n TX path and push it into setds_11n. * Ensure that setds_11n will work correctly for non-aggregate frames; * .. and then when it does, just unconditionally call "setds_11n" for 11n NICs and "setds" for non-11n NICs.
|
#
238931 |
|
31-Jul-2012 |
adrian |
Migrate some more TX side setup routines to be methods.
|
#
238930 |
|
31-Jul-2012 |
adrian |
Break out the hardware handoff and TX DMA restart code into methods.
These (and a few others) will differ based on the underlying DMA implementation.
For the EDMA NICs, simply stub them out in a fashion which will let me focus on implementing the necessary descriptor API changes.
|
#
238885 |
|
29-Jul-2012 |
adrian |
Shuffle the rate control call to be consistent with non-aggregate TX.
The correct ordering for non-aggregate TX is:
* call ath_hal_setuptxdesc() to setup the first TX descriptor complete with the first TX rate/try count; * call ath_hal_setupxtxdesc() to setup the multi-rate retry; * .. or for 802.11n NICs, call ath_hal_set11nratescenario() for MRR and 802.11n flags; * then call ath_hal_filltxdesc() to setup intermediary descriptors in a multi-descriptor single frame.
The call to ath_hal_filltxdesc() routines seem to correctly (consistently?) handle the intermediary descriptor flags, including copying the rate control information to the final descriptor in the frame. That's used by the rate control module rather than the hardware.
Tested:
* Only on AR9280 STA mode, however it should work on other chips in both STA and AP mode.
|
#
238729 |
|
23-Jul-2012 |
adrian |
Modify ath_descdma_setup() to take a descriptor size parameter.
The AR9300 and later descriptors are 128 bytes, however I'd like to make sure that isn't used for earlier chips.
* Populate the TX descriptor length field in the softc with sizeof(ath_desc)
* Use this field when allocating the TX descriptors
* Pre-AR93xx TX/RX descriptors will use the ath_desc size; newer ones will query the HAL for these sizes.
|
#
238710 |
|
23-Jul-2012 |
adrian |
Begin separating out the TX DMA setup in preparation for TX EDMA support.
* Introduce TX DMA setup/teardown methods, mirroring what's done in the RX path.
Although the TX DMA descriptor is setup via ath_desc_alloc() / ath_desc_free(), there TX status descriptor ring will be allocated in this path.
* Remove some of the TX EDMA capability probing from the RX path and push it into the new TX EDMA path.
|
#
238708 |
|
23-Jul-2012 |
adrian |
Begin modifying the descriptor allocation functions to support a variable sized TX descriptor.
This is required for the AR93xx EDMA support which requires 128 byte TX descriptors (which is significantly larger than the earlier hardware.)
|
#
238609 |
|
19-Jul-2012 |
adrian |
Convert the TX path to use the new HAL methods for accessing the TX descriptor link pointers.
This is required for the AR93xx and later chipsets.
The RX path is slightly different - the legacy RX path directly accesses ath_desc->ds_link for now, however this isn't at all done for EDMA (FIFO) RX.
Now, for those performing a little software archeology here:
This is all a bit sub-optimal. "struct ath_desc" is only really relevant for the pre-AR93xx NICs - where ds_link and ds_data is always in the same location.
The AR93xx and later NICs have different descriptor layouts altogether.
Now, for AR93xx and later NICs, you should never directly reference ds_link and ds_data, as:
* the RX descriptors don't have either - the data is _after_ the RX descriptor. They're just one large buffer. There's also no need for a per-descriptor RX buffer size as they're all fixed sizes.
* the TX descriptors have 4 buffer and 4 length fields _and_ a link pointer. Each frame takes up one TX FIFO pointer, but it can contain multiple subframes (either multiple frames in a buffer, and/or multiple frames in an aggregate/RIFS burst.)
* .. so, when TX frames are queued to a hardware queue, the link pointer is ONLY for buffers in that frame/aggregate. The next frame starts in a new FIFO pointer.
* Finally, descriptor completion status is in a different ring. I'll write something up about that when its time to do so.
This was inspired by Linux ath9k and the reference driver but is a reimplementation.
Obtained from: Linux ath9k, Qualcomm Atheros
|
#
238350 |
|
10-Jul-2012 |
jhb |
Fix build when ATH_DEBUG is not defined.
|
#
238338 |
|
10-Jul-2012 |
adrian |
Print the TX buffer if this error condition is asserted.
I need to figure out why this is occuring. Hopefully I can get enough descriptor dumps to figure it out.
|
#
237593 |
|
26-Jun-2012 |
adrian |
Make sure the BAR TX session pause is correctly unpaused when a node is reassociating.
PR: kern/169432
|
#
237041 |
|
14-Jun-2012 |
adrian |
Disable this warning debug for now, as I'm now aware of the particular situation where it's occuring.
Whilst I'm here, flesh out a more descriptive description.
|
#
237000 |
|
13-Jun-2012 |
adrian |
Implement a separate, smaller pool of ath_buf entries for use by management traffic.
* Create sc_mgmt_txbuf and sc_mgmt_txdesc, initialise/free them appropriately. * Create an enum to represent buffer types in the API. * Extend ath_getbuf() and _ath_getbuf_locked() to take the above enum. * Right now anything sent via ic_raw_xmit() allocates via ATH_BUFTYPE_MGMT. This may not be very useful. * Add ATH_BUF_MGMT flag (ath_buf.bf_flags) which indicates the current buffer is a mgmt buffer and should go back onto the mgmt free list. * Extend 'txagg' to include debugging output for both normal and mgmt txbufs. * When checking/clearing ATH_BUF_BUSY, do it on both TX pools.
Tested:
* STA mode, with heavy UDP injection via iperf. This filled the TX queue however BARs were still going out successfully.
TODO:
* Initialise the mgmt buffers with ATH_BUF_MGMT and then ensure the right type is being allocated and freed on the appropriate list. That'd save a write operation (to bf->bf_flags) on each buffer alloc/free.
* Test on AP mode, ensure that BAR TX and probe responses go out nicely when the main TX queue is filled (eg with paused traffic to a TID, awaiting a BAR to complete.)
PR: kern/168170
|
#
236994 |
|
13-Jun-2012 |
adrian |
Oops, return the newly allocated buffer to the queue, not the completed buffer.
PR: kern/168170
|
#
236993 |
|
13-Jun-2012 |
adrian |
Replace the direct sc_txbuf manipulation with a pair of functions.
This is preparation work for having a separate ath_buf queue for management traffic.
PR: kern/168170
|
#
236886 |
|
11-Jun-2012 |
adrian |
Fix uninitialised reference.
Noticed by: John Hay <jhay@meraka.org.za>
|
#
236880 |
|
11-Jun-2012 |
adrian |
Wrap the whole (software) TX path from ifnet dequeue to software queue (or direct dispatch) behind the TXQ lock (which, remember, is doubling as the TID lock too for now.)
This ensures that:
(a) the sequence number and the CCMP PN allocation is done together; (b) overlapping transmit paths don't interleave frames, so we don't end up with the original issue that triggered kern/166190.
Ie, that we don't end up with seqno A, B in thread 1, C, D in thread 2, and they being queued to the software queue as "A C D B" or similar, leading to the BAW stalls.
This has been tested:
* both STA and AP modes with INVARIANTS and WITNESS; * TCP and UDP TX; * both STA->AP and AP->STA.
STA is a Routerstation Pro (single CPU MIPS) and the AP is a dual-core Centrino.
PR: kern/166190
|
#
236879 |
|
11-Jun-2012 |
adrian |
Add another TID lock.
|
#
236878 |
|
11-Jun-2012 |
adrian |
Make sure the frames are queued to the head of the list, not the tail. See previous commit.
PR: kern/166190
|
#
236877 |
|
11-Jun-2012 |
adrian |
When scheduling frames in an aggregate session, the frames should be scheduled from the head of the software queue rather than trying to queue the newly given frame.
This leads to some rather unfortunate out of order (but still valid as it's inside the BAW) frame TX.
This now:
* Always queues the frame at the end of the software queue; * Tries to direct dispatch the frame at the head of the software queue, to try and fill up the hardware queue.
TODO:
* I should likely try to queue as many frames to the hardware as I can at this point, rather than doing one at a time; * ath_tx_xmit_aggr() may fail and this code assumes that it'll schedule the TID. Otherwise TX may stall.
PR: kern/166190
|
#
236876 |
|
11-Jun-2012 |
adrian |
Retried frames need to be inserted in the head of the list, not the tail.
This is an unfortunate byproduct of how the routine is used - it's called with the head frame on the queue, but if the frame is failed, it's inserted into the tail of the queue.
Because of this, the sequence numbers would get all shuffled around and the BAW would be bumped past this sequence number, that's now at the end of the software queue. Then, whenever it's time for that frame to be transmitted, it'll be immediately outside of the BAW and TX will stall until the BAW catches up.
It can also result in all kinds of weird duplicate BAW frames, leading to hilarious panics.
PR: kern/166190
|
#
236874 |
|
11-Jun-2012 |
adrian |
Finish undoing the previous commit - this part of the code is no longer required.
PR: kern/166190
|
#
236873 |
|
11-Jun-2012 |
adrian |
Introduce a new lock debug which is specifically for making sure the _TID_ lock is held.
For now the TID lock is also the TXQ lock. This is just to make sure that the right TXQ lock is held for the given TID.
|
#
236872 |
|
11-Jun-2012 |
adrian |
Revert r233227 and followup commits as it breaks CCMP PN replay detection.
This showed up when doing heavy UDP throughput on SMP machines.
The problem with this is because the 802.11 sequence number is being allocated separately to the CCMP PN replay number (which is assigned during ieee80211_crypto_encap()).
Under significant throughput (200+ MBps) the TX path would be stressed enough that frame TX/retry would force sequence number and PN allocation to be out of order. So once the frames were reordered via 802.11 seqnos, the CCMP PN would be far out of order, causing most frames to be discarded by the receiver.
I've fixed this in some local work by being forced to:
(a) deal with the issues that lead to the parallel TX causing out of order sequence numbers in the first place; (b) fix all the packet queuing issues which lead to strange (but mostly valid) TX.
I'll begin fixing these in a subsequent commit or five.
PR: kern/166190
|
#
236038 |
|
25-May-2012 |
adrian |
Avoid using hard-coded numbers here.
|
#
235774 |
|
22-May-2012 |
adrian |
Fix up some corner cases with aggregation handling.
I've come across a weird scenario in net80211 where two TX streams will happily attempt to setup an aggregation session together. If we're very lucky, it happens concurrently on separate CPUs and the total lack of locking in the net80211 aggregation code causes this stuff to race. Badly.
So >1 call would occur to the ath(4) addba start, but only one call would complete to addba complete or timeout. The TID would thus stay paused.
The real fix is to implement some proper per-node (or maybe per-TID) locking in net80211, which then could be leveraged by the ath(4) TX aggregation code.
Whilst I'm at it, shuffle around the debugging messages a bit. I like to keep people on their toes.
|
#
235750 |
|
21-May-2012 |
adrian |
For now, add a quick debugging patch to log when the hw TXQ != the TID/AC.
|
#
235749 |
|
21-May-2012 |
adrian |
Rename ath_tx_cleanup() -> ath_tx_tid_cleanup() in order to not clash with a symbol in if_ath.c
|
#
235676 |
|
20-May-2012 |
adrian |
Migrate the bulk of the RX routines out from if_ath.c to if_ath_rx.[ch].
* migrate the rx processing out into if_ath_rx.c * migrate the TSF functions into if_ath_tsf.h, as inlines
This is in prepration for supporting the EDMA RX routines, required to support the AR93xx series NICs.
TODO:
* ath_start() shouldn't be private, but it's called as part of the RX path. I should likely migrate ath_rx_tasklet() back into if_ath.c and then return this to be 'static'. The RX code really shouldn't need to see TX routines (and vice versa.)
* ath_beacon_* should be in if_ath_beacon.[ch].
* ath_tdma_* should be in if_ath_tdma.[ch] ...
|
#
235491 |
|
15-May-2012 |
adrian |
Migrate ath_debug and sc_debug from an int to a uint64_t / QUAD; add some more BAR debugging logic.
* Change the definition of ath_debug and ath_softc.sc_debug from int to uint64_t; * Change the relevant sysctls; * Add a new BAR TX debugging field; * Use this in if_ath_tx.
This has been tested by using the sysctl program, which happily allows for fields > 32 bits to be configured.
|
#
235461 |
|
15-May-2012 |
adrian |
Handle non-xretry errors the same as xretry errors for now.
Although I _should_ handle the other errors in various ways (specifically errors like FILT), treating them as having transmitted successfully is completely wrong. Here, they'd be counted as successful and the BAW would be advanced.. but the RX side wouldn't have received them.
The specific errors I've been seeing here are HAL_TXERR_FILT.
This patch does fix the issue - I've tested it using -i 0.001 pings (enough to start aggregation) and now the behaviour is correct:
* The RX side never sees a "moved window" error, and * The TX side sends BARs as needed, with the RX side correctly handling them.
PR: kern/167902
|
#
235034 |
|
04-May-2012 |
adrian |
Fix a couple of sc_ac2q[] mappings that were using the TID, not the AC.
PR: kern/167588
|
#
234725 |
|
26-Apr-2012 |
adrian |
Remove some of the redundant locking done in the TX completion path, when checking whether BAR frames need to be checked.
|
#
234324 |
|
15-Apr-2012 |
adrian |
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)
|
#
234009 |
|
07-Apr-2012 |
adrian |
After reviewing the mcast/sleep station code a little, undo some brain damage which I committed when I had less clue about such things.
Don't ever put normal data frames on the mcast software queue. Just put mcast frames there if needed.
Pass the txq decision into ath_tx_normal_setup(), as we've already made the decision. Don't re-do it.
Whilst i'm here, add another random debugging statement.
|
#
233990 |
|
07-Apr-2012 |
adrian |
Do a dma sync before the descriptors are chained together.
I need to find a better place to do this..
|
#
233989 |
|
07-Apr-2012 |
adrian |
Break out the legacy duration and protection code into routines, call these after rate control selection is done.
The duration/protection code wasn't working - it expected the rix to be valid. Unfortunately after I moved the rate control selection into late in the process, the rix value isn't valid and thus the protection/ duration code would get things wrong.
HT frames are now correctly protected with an RTS and for the AR5416, this involves having the aggregate frames be limited to 8K.
TODO:
* Fix up the DMA sync to occur just before the frame is queued to the hardware. I'm adjusting the duration here but not doing the DMA flush.
* Doubly/triply ensure that the aggregate frames are being limited to the correct size, or the AR5416 will get unhappy when TXing RTS-protected aggregates.
|
#
233966 |
|
07-Apr-2012 |
adrian |
Remove duplicate txflags field from ath_buf.
rename bf_state.bfs_flags to bf_state.bfs_txflags, as that is what it effectively is.
|
#
233908 |
|
04-Apr-2012 |
adrian |
Implement BAR TX.
A BAR frame must be transmitted when an frame in an A-MPDU session fails to transmit - it's retried too often, or it can't be cloned for re-transmission. The BAR frame tells the remote side to advance the left edge of the block-ack window (BAW) to a new value.
In order to do this:
* TX for that particular node/TID must be paused; * The existing frames in the hardware queue needs to be completed, whether they're TXed successfully or otherwise; * The new left edge of the BAW is then communicated to the remote side via a BAR frame; * Once the BAR frame has been sucessfully TXed, aggregation can resume; * If the BAR frame can't be successfully TXed, the aggregation session is torn down.
This is a first pass that implements the above. What needs to be done/ tested:
* What happens during say, a channel reset / stuck beacon _and_ BAR TX. It _should_ be correctly buffered and retried once the reset has completed. But if a bgscan occurs (and they shouldn't, grr) the BAR frame will be forcibly failed and the aggregation session will be torn down.
Yes, another reason to disable bgscan until I've figured this out.
* There's way too much locking going on here. I'm going to do a couple of further passes of sanitising and refactoring so the (re) locking isn't so heavy. Right now I'm going for correctness, not speed.
* The BAR TX can fail if the hardware TX queue is full. Since there's no "free" space kept for management frames, a full TX queue (from eg an iperf test) can race with your ability to allocate ath_buf/mbufs and cause issues. I'll knock this on the head with a subsequent commit.
* I need to do some _much_ more thorough testing in hostap mode to ensure that many concurrent traffic streams to different end nodes are correctly handled. I'll find and squish whichever bugs show up here.
But, this is an important step to being able to flip on 802.11n by default. The last issue (besides bug fixes, of course) is HT frame protection and I'll address that in a subsequent commit.
|
#
233897 |
|
04-Apr-2012 |
adrian |
Now that I've fixed the BAW TX hangs, disable this verbose debugging again.
|
#
233895 |
|
04-Apr-2012 |
adrian |
Correctly handle AR_MoreAggr when assembling multi-descriptor final frames.
Linux ath9k doesn't have this issue as it doesn't try queuing multi- descriptor frames to the hardware.
Before, I was only setting the first and last descriptor in the final frame correctly - and that was done by accident. The first descriptor in the last sub-frame was being correctly updated by ath_tx_setds_11n(); the last descriptor in the last sub-frame was being correctly updated by ath_buf_set_rate(). But both of those are "incorrect".
The correct behaviour is:
* AR_IsAggr is set for all descriptors for all subframes in an aggregate. * AR_MoreAggr is set for all descriptors for all non-final sub-frames in an aggregate.
Ie, all descriptors in the last sub-frame of an aggregate must have this field set to 0.
I still need to do a couple of extra passes to ensure the pad delimiter field is being correctly handled in all descriptors in the last sub-frame.
|
#
233673 |
|
29-Mar-2012 |
adrian |
Defer the rescheduling of TID -> TXQ frames in some instances.
Right now ath_txq_sched() is mainly called from the TX ath_tx_processq() routine, which is (mostly) done as part of the taskqueue. It shouldn't be called outside the taskqueue.
But now that I'm about to flip back on BAR TX, I'm going to start stressing the ath_tx_tid_pause() and ath_tx_tid_resume() paths. What I don't want to have happen is a reschedule of the TID traffic _during_ the completion of TX frames.
Ideally I'd like to have a way to flag back up to the processing code that the current hardware queue should be rechecked for software TID queue frames. But for now, this should suffice for the BAR TX case.
I may eventually delete this code once I've brought some further sanity to the general TX queue/completion path.
|
#
233514 |
|
26-Mar-2012 |
adrian |
Use the assigned sequence number when checking if a retried packet is within the BAW.
This regression was introduced in ane earlier commit by me to fix the BAW seqno allocation-but-not-insertion-into-BAW race. Since it was only ever using the to-be allocated sequence number, any frame retries with the first frame in the BAW still in the software queue would have constantly failed, as ni_txseqs[tid] would always be outside the BAW.
TODO:
* Extract out the mostly common code here in the agg and non-agg ADDBA case and stuff it into a single function.
PR: kern/166357
|
#
233480 |
|
25-Mar-2012 |
adrian |
Add some more debugging to try and nail down exactly what's going on when I see traffic stalls.
It turns out that the bug isn't because the first and last frame in the BAW is in the software queue. It is more likely that it's because the first frame in the BAW is still in the software queue and thus there's no more room to allocate and do subsequent TX.
PR: kern/166357
|
#
233330 |
|
22-Mar-2012 |
adrian |
Add some further debugging to try and aid tracking down what the state of things were just before a full software queue is drained.
|
#
233227 |
|
20-Mar-2012 |
adrian |
Delay sequence number allocation for A-MPDU until just before the frame is queued to the hardware.
Because multiple concurrent paths can execute ath_start(), multiple concurrent paths can push frames into the software/hardware TX queue and since preemption/interrupting can occur, there's the possibility that a gap in time will occur between allocating the sequence number and queuing it to the hardware.
Because of this, it's possible that a thread will have allocated a sequence number and then be preempted by another thread doing the same. If the second thread sneaks the frame into the BAW, the (earlier) sequence number of the first frame will be now outside the BAW and will result in the frame being constantly re-added to the tail of the queue. There it will live until the sequence numbers cycle around again.
This also creates a hole in the RX BAW tracking which can also cause issues.
This patch delays the sequence number allocation to occur only just before the frame is going to be added to the BAW. I've been wanting to do this anyway as part of a general code tidyup but I've not gotten around to it. This fixes the PR.
However, it still makes it quite difficult to try and ensure in-order queuing and dequeuing of frames. Since multiple copies of ath_start() can be run at the same time (eg one TXing process thread, one TX completion task/one RX task) the driver may end up having frames dequeued and pushed into the hardware slightly/occasionally out of order.
And, to make matters more annoying, net80211 may have the same behaviour - in the non-aggregation case, the TX code allocates sequence numbers before it's thrown to the driver. I'll open another PR to investigate this and potentially introduce some kind of final-pass TX serialisation before frames are thrown to the hardware. It's also very likely worthwhile adding some debugging code into ath(4) and net80211 to catch when/if this does occur.
PR: kern/166190
|
#
232794 |
|
10-Mar-2012 |
adrian |
Fix a panic introduced in a previous commit - non-beaconing modes (eg STA) don't setup the avp mcast queue.
This is a bit annoying though - it turns out the mcast queue isn't initialised for STA mode but it's then touched to see whether anything is in it. That should be fixed in a subsequent commit.
Noticed by: gperez@entel.upc.edu PR: kern/165895
|
#
232764 |
|
10-Mar-2012 |
adrian |
Don't flood the cabq/mcastq with frames.
In a very noisy 2.4GHz environment (with HT/40 enabled, making it worse) I saw the following occur:
* the air was considered "busy" a lot of the time; * the cabq time is quite short due to staggered beacons being enabled; * it just wasn't able to keep up TX'ing CABQ frames; * .. and the cabq would swallow up all the TX ath_buf's.
This patch introduces a twiddle which allows the maximum cabq depth to be set, forcing further frames to be dropped.
It defaults to the TX buffer count at the moment, so the default behaviour isn't changed.
I've also started fleshing out a similar setup for the data path, so it doesn't swallow up all the available TX buffers and preventing management frames (such as ADDBA) out.
PR: kern/165895
|
#
232753 |
|
09-Mar-2012 |
adrian |
Document that we may end up with some suboptimal handling of data frames with stations in power saving mode.
I'm not (yet) sure how to handle TX'ing aggregates frames to stations that are in power saving mode, or whether that's even a feasible thing to do. So in order to (mostly) not forget, leave a couple of comments in the code.
The code presently assumes that the aggregation TID state for an ath_node is locked not by the ath_node lock or a node+TID lock, but behind the hardware queue said TID maps to. This assumption is going to be incorrect for stations in power saving mode as we'll be TX'ing frames on the multicast queue.
In any case, I'm afraid its a "later problem". :/
|
#
232707 |
|
08-Mar-2012 |
adrian |
Correctly initialise the TXQ link pointer to the last descriptor in the last buffer in the list.
The current behaviour (due to me, so pointy hat is firmly on my head here) was incorrect - it was setting the link pointer to the last descriptor of the _first_ buffer in the TXQ. Instead, it should have set it to the last descriptor in the _last_ buffer in the TXQ.
This showed up as occasional TX stalls with frames in the TXQ but no TX progress being made. Further inspection showed the TXQ looked like it contained multiple "lists" of frames - there'd be a list of correct frames, then a NULL link pointer, but there'd be a next buffer in the list.
Since this code is only called upon an interface reset, it's likely this only began showing up when I started doing stress testing in environments which annoy the radios enough to cause lockups.
I've not yet any TX stalls with this patch applied.
PR: kern/165866
|
#
229949 |
|
10-Jan-2012 |
adrian |
style(9) changes. This shouldn't change functionality.
|
#
229165 |
|
31-Dec-2011 |
adrian |
If frames are dumped out of the queue, let's at least see what they are.
This shows that the majority of the weird traffic I see here are probe frames that haven't been sent out, but I can also trigger this condition by doing ICMP w/ -i 0.3 - enough to trigger the TX during actual scanning, but not fast enough to stop scanning from occuring.
PR: kern/163689
|
#
227868 |
|
23-Nov-2011 |
adrian |
Flesh out the TX aggregation completion statistics.
* Failall is now named just that. * Add TX ok and TX fail, for aggregate frame sub-frames.
This will break athstats; a followup commit wil resolve this.
Sponsored by: Hobnob, Inc.
|
#
227651 |
|
18-Nov-2011 |
adrian |
Flesh out some slightly dirty reset/channel change serialisation code for the ath(4) driver.
Currently, there's nothing stopping reset, channel change and general TX/RX from overlapping with each other. This wasn't a big deal with pre-11n traffic as it just results in some dropped frames. It's possible this may have also caused some inconsistencies and badly-setup hardware.
Since locks can't be held across all of this (the Linux solution) due to LORs with the network stack locks, some state counter variables are used to track what parts of the code the driver is currently in.
When the hardware is being reset, it disables the taskqueue and waits for pending interrupts, tx, rx and tx completion before it begins the reset or channel change.
TX and RX both abort if called during an active reset or channel change.
Finally, the reset path now doesn't flush frames if ATH_RESET_NOLOSS is set. Instead, completed TX and RX frames are passed back up to net80211 before the reset occurs.
This is not without problems:
* Raw frame xmit are just dropped, rather than placed on a queue. The net80211 stack should be the one which queues these frames rather than the driver.
* It's all very messy. It'd be better if these hardware operations were serialised on some kind of work queue, rather than hoping they can be run in parallel.
* The taskqueue block/unblock may occur in parallel with the newstate() function - which shuts down the taskqueue and restarts it once the new state is known. It's likely these operations should be refcounted so the taskqueue is restored once no other areas in the code wish to suspend operations.
* .. interrupt disable/enable should likely be refcounted as well.
With this work, the driver does not drop frames during stuck beacon or fatal errors and thus 11n traffic continues to run correctly. Default and full resets however do still drop frames and it's possible this may occur, causing traffic loss and session stalls.
Sponsored by: Hobnob, Inc.
|
#
227398 |
|
09-Nov-2011 |
adrian |
If software retransmit occurs with an ath_buf marked ATH_BUF_BUSY, it's cloned and that clone is retransmitted. This means that the ath_buf pointer squirreled away on the baw window array is suddenly wrong and was causing all kinds of console output.
This updates the pointer in that particular BAW slot to the new ath_buf after ensuring that:
* the new and old buffers have the same seqno; * the current slot pointer matches the old buffer pointer.
This quietens the debugging output (again), restoring said debugging to only signify when a broken condition has occured.
Sponsored by: Hobnob, Inc.
|
#
227364 |
|
08-Nov-2011 |
adrian |
Introduce TX aggregation and software TX queue management for Atheros AR5416 and later wireless devices.
This is a very large commit - the complete history can be found in the user/adrian/if_ath_tx branch.
Legacy (ie, pre-AR5416) devices also use the per-software TXQ support and (in theory) can support non-aggregation ADDBA sessions. However, the net80211 stack doesn't currently support this.
In summary:
TX path:
* queued frames normally go onto a per-TID, per-node queue * some special frames (eg ADDBA control frames) are thrown directly onto the relevant hardware queue so they can go out before any software queued frames are queued. * Add methods to create, suspend, resume and tear down an aggregation session. * Add in software retransmission of both normal and aggregate frames. * Add in completion handling of aggregate frames, including parsing the block ack bitmap provided by the hardware. * Write an aggregation function which can assemble frames into an aggregate based on the selected rate control and channel configuration. * The per-TID queues are locked based on their target hardware TX queue. This matches what ath9k/atheros does, and thus simplified porting over some of the aggregation logic. * When doing TX aggregation, stick the sequence number allocation in the TX path rather than net80211 TX path, and protect it by the TXQ lock.
Rate control:
* Delay rate control selection until the frame is about to be queued to the hardware, so retried frames can have their rate control choices changed. Frames with a static rate control selection have that applied before each TX, just to simplify the TX path (ie, not have "static" and "dynamic" rate control special cased.) * Teach ath_rate_sample about aggregates - both completion and errors. * Add an EWMA for tracking what the current "good" MCS rate is based on failure rates.
Misc:
* Introduce a bunch of dirty hacks and workarounds so TID mapping and net80211 frame inspection can be kept out of the net80211 layer. Because of the way this code works (and it's from Atheros and Linux ath9k), there is a consistent, 1:1 mapping between TID and AC. So we need to ensure that frames going to a specific TID will _always_ end up on the right AC, and vice versa, or the completion/locking will simply get very confused. I plan on addressing this mess in the future.
Known issues:
* There is no BAR frame transmission just yet. A whole lot of tidying up needs to occur before BAR frame TX can occur in the "correct" place - ie, once the TID TX queue has been drained.
* Interface reset/purge/etc results in frames in the TX and RX queues being removed. This creates holes in the sequence numbers being assigned and the TX/RX AMPDU code (on either side) just hangs.
* There's no filtered frame support at the present moment, so stations going into power saving mode will simply have a number of frames dropped - likely resulting in a traffic "hang".
* Raw frame TX is going to just not function with 11n aggregation. Likely this needs to be modified to always override the sequence number if the frame is going into an aggregation session. However, general raw frame injection currently doesn't work in general in net80211, so let's just ignore this for now until this is sorted out.
* HT protection is just not implemented and won't be until the above is sorted out. In addition, the AR5416 has issues RTS protecting large aggregates (anything >8k), so the work around needs to be ported and tested. Thus, this will be put on hold until the above work is complete.
* The rate control module 'sample' is the only currently supported module; onoe/amrr haven't been tested and have likely bit rotted a little. I'll follow up with some commits to make them work again for non-11n rates, but they won't be updated to handle 11n and aggregation. If someone wishes to do so then they're welcome to send along patches.
* .. and "sample" doesn't really do a good job of 11n TX. Specifically, the metrics used (packet TX time and failure/success rates) isn't as useful for 11n. It's likely that it should be extended to take into account the aggregate throughput possible and then choose a rate which maximises that. Ie, it may be acceptable for a higher MCS rate with a higher failure to be used if it gives a more acceptable throughput/latency then a lower MCS rate @ a lower error rate. Again, patches will be gratefully accepted.
Because of this, ATH_ENABLE_11N is still not enabled by default.
Sponsored by: Hobnob, Inc. Obtained from: Linux, Atheros
|
#
227360 |
|
08-Nov-2011 |
adrian |
Change the descriptor logic to use bf_lastds to point to the last descriptor, rather than using the maths involving bf_desc[bf_nseg - 1].
When doing TX aggregation, the status will be updated in the -final- descriptor of the -final- subframe in an aggregate. Thus bf_lastds may point to the last descriptor in a completely different ath_buf.
Sponsored by: Hobnob, Inc.
|
#
227344 |
|
08-Nov-2011 |
adrian |
Migrate the STAILQ lists to TAILQs.
A bunch of the 11n TX aggregation logic wants to traverse lists of buffers in various ways. In order to provide O(1) behaviour in this instance, use TAILQs.
This does blow out the memory footprint and CPU cycles slightly for some of these operations. I may convert some of these back to STAILQs once the rest of the software transmit queue handling has been stabilised.
Sponsored by: Hobnob, Inc.
|
#
220098 |
|
28-Mar-2011 |
adrian |
Add in HT protection but disable it by default.
I'll clear how it's supposed to work with Bernhard and then look at enabling this in the correct situations.
But this -does- enable HT RTS protection (using the appropriate legacy rates) if this bit of code is enabled.
|
#
218932 |
|
21-Feb-2011 |
adrian |
Shuffle around the RTS/CTS rate/duration logic.
* Turn ath_tx_calc_ctsduration() into a function that returns the ctsduration, or -1 for HT rates; * add a printf() to ath_tx_calc_ctsduration() which will be very loud if somehow that function is called with an MCS rate; * Add ath_tx_get_rtscts_rate() which returns the RTS/CTS rate to use for the given data rate, incl. the short preamble flag; * Only call ath_tx_calc_ctsduration() for non-11n chipsets; 11n chipsets don't require the rtscts duration to be calculated.
|
#
218593 |
|
12-Feb-2011 |
adrian |
The current code used the fields in ath_set11nratescenario() . Use them correctly:
* pass in whether to allow the hardware to override the duration field in the main data frame (durupdate_en) - PS_POLL frames in particular don't have the duration bit overriden; * there's no rts/cts duration here; that's done elsehwere
|
#
218240 |
|
03-Feb-2011 |
adrian |
Modify the TX path to set and use the 11n rate scenario bits.
This isn't strictly required to TX (at least non-agg and non-HT40, non-short-GI) frames; but as it needs to be done anyway, just get it done.
Linux ath9k uses the rate scenario style path for -all- packets, legacy or otherwise. This code does much the same.
Beacon TX still uses the legacy, non-rate-scenario TX descriptor setup. Ath9k also does this.
This 11n rate scenario path is only called for chips in the AR5416 HAL; legacy chips use the previous interface for TX'ing.
|
#
218157 |
|
01-Feb-2011 |
adrian |
Refator the common code which calculates the 802.11g protection duration.
|
#
218154 |
|
01-Feb-2011 |
adrian |
* Add a rather hacky "does this speak the 11n TX descriptor format" function; which will be later used by the TX path to determine whether to use the extended features or not.
* Break out the descriptor chaining logic into a separate function; again so it can be switched out later on for the 11n version when needed.
* Refactor out the encryption-swizzling code that's common in the raw and normal TX path.
|
#
218065 |
|
29-Jan-2011 |
adrian |
Migrate the TX path code out of if_ath and into a separate source file.
There's two reasons for this:
* the raw and non-raw TX path shares a lot of duplicate code which should be refactored; * the 11n-ready chip TX path needs a little reworking.
|