ath_start() is called.
This (defaults to 10 frames) gives for a little headway in the TX ath_buf
allocation, so buffer cloning is still possible.
This requires a lot omre experimenting and tuning.
It also doesn't stop a node/TID from consuming all of the available
ath_buf's, especially when the node is going through high packet loss
or only talking at a low TX rate. It also doesn't stop a paused TID
from taking all of the ath_bufs. I'll look at fixing that up in subsequent
commits.
PR: kern/168170
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
(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
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
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
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
it turns out that it negatively affects performance. I'm stil investigating
exactly why deferring the IO causes such negative TCP performance but
doesn't affect UDP preformance.
Leave the ath_tx_kick() change in there however; it's going to be useful
to have that there for if_transmit() work.
PR: kern/168649
called to "kick" along TX.
For now, schedule a taskqueue call.
Later on I may go back to the direct call of ath_rx_tasklet() - but for
now, this will do.
I've tested UDP and TCP TX. UDP TX still achieves 240MBit, but TCP
TX gets stuck at around 100MBit or so, instead of the 150MBit it should
be at. I'll re-test with no ACPI/power/sleep states enabled at startup
and see what effect it has.
This is in preparation for supporting an if_transmit() path, which will
turn ath_tx_kick() into a NUL operation (as there won't be an ifnet
queue to service.)
Tested:
* AR9280 STA
TODO:
* test on AR5416, AR9160, AR928x STA/AP modes
PR: kern/168649
implementing parallel TX and TX/RX completion can be done without
simply abusing long-held locks.
Right now, multiple concurrent ath_start() entries can result in
frames being dequeued out of order. Well, they're dequeued in order
fine, but if there's any preemption or race between CPUs between:
* removing the frame from the ifnet, and
* calling and runningath_tx_start(), until the frame is placed on a
software or hardware TXQ
Then although dequeueing the frame is in-order, queueing it to the hardware
may be out of order.
This is solved in a lot of other drivers by just holding a TX lock over
a rather long period of time. This lets them continue to direct dispatch
without races between dequeue and hardware queue.
Note to observers: if_transmit() doesn't necessarily solve this.
It removes the ifnet from the main path, but the same issue exists if
there's some intermediary queue (eg a bufring, which as an aside also
may pull in ifnet when you're using ALTQ.)
So, until I can sit down and code up a much better way of doing parallel
TX, I'm going to leave the TX path using a deferred taskqueue task.
What I will likely head towards is doing a direct dispatch to hardware
or software via if_transmit(), but it'll require some driver changes to
allow queues to be made without using the really large ath_buf / ath_desc
entries.
TODO:
* Look at how feasible it'll be to just do direct dispatch to
ath_tx_start() from if_transmit(), avoiding doing _any_ intermediary
serialisation into a global queue. This may break ALTQ for example,
so I have to be delicate.
* It's quite likely that I should break up ath_tx_start() so it
deposits frames onto the software queues first, and then only fill
in the 802.11 fields when it's being queued to the hardware.
That will make the if_transmit() -> software queue path very
quick and lightweight.
* This has some very bad behaviour when using ACPI and Cx states.
I'll do some subsequent analysis using KTR and schedgraph and file
a follow-up PR or two.
PR: kern/168649
These aren't strictly needed at the moment as we're not doing APSM
and forcing the NIC in and out of network sleep. But, they don't hurt.
Tested:
* AR9280 (mini-PCIe)
Obtained from: Qualcomm Atheros, Linux ath9k
* Now that ah_configPCIE is called for both power on and suspend/resume,
make sure the right bit(s) are cleared and set when suspending and
resuming. Specifically:
+ force disable/enable the PCIe PHY upon suspend/resume;
+ reprogram the PCIe WAR register when resuming and upon power-on.
* Add a recipe which powers down any PCIe PHY hardware inside the AR5416
(which is the PCI variant) to save on power. I have (currently) no way
to test exactly how much power is saved, if any.
Tested on:
* AR5416 cardbus - although unfortunately pccard/cbb/cardbus currently
detaches the NIC upon suspend, I don't think it's a proper test case.
* AR5418 PCIe attached to expresscard - since we're not doing PCIe APSM,
it's also not likely a full/good test case.
In both instances I went through a handful of suspend/resume cycles and
ensured that the STA vap reassociated correctly.
TODO:
* Setup a laptop to simply sit in a suspend/resume loop, making sure that
the NIC always correctly comes back;
* Start doing suspend/resume tests with actual traffic going on in the
background, as I bet this process is all quite racy at the present;
* Test adhoc/hostap mode, just to be completely sure it's working correctly;
* See if I can jury rig an external power source to an AR5416 to test out
whether ah_disablePCIE() works.
Obtained from: Qualcomm Atheros
* Add some other WAR bits (very usefully described too) in preparation for
porting over some suspend/resume fixes from ath9k/Atheros.
Obtained from: Qualcomm Atheros
not to disable the PCIe PHY in prepration for reset.
Extend the enablepci method to have a "poweroff" flag, which if equal
to true means the hardware is about to go to sleep.
* Flesh out the pcie disable method for 11n chips, as they were defaulting
to the AR5212 (empty) PCIe disable method.
* Add accessor macros for the HAL PCIe enable/disable calls.
* Call disable on ath_suspend()
* Call enable on ath_resume()
NOTE:
* This has nothing to do with the NIC sleep/run state - the NIC still
will stay in network-run state rather than supporting network-sleep
state. This is preparation work for supporting correct suspend/resume
WARs for the 11n PCIe NICs.
TODO:
* It may be feasible at this point to keep the chip powered down during
initial probe/attach and only power it up upon the first configure/reset
pass. This however would require correct (for values of "correct")
tracking of the NIC power configuration state from the driver and that
just isn't attempted at the moment.
Tested:
* AR9280 on my Lenovo T60, but with no suspend/resume pass (yet).
I'll have to leave this high for now, until I've done some significant
surgery with how ath_bufs (and descriptors) are handled.
This should significantly cut down on the opportunities for a full TX
queue hanging traffic. I'll continue making things work though; I'm
mostly doing this for users. :)
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.
There's some TX path TDMA code in if_ath_tx.c which should be migrated
out, but first I should likely try and verify/fix/repair the TDMA support
in 9.x and -HEAD.
* 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] ...
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.
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
TX and RX PCU stop/drain routines have been thoroughly debugged.
It's also very likely that I should add hooks back up to the
interface glue (if_ath_pci / if_ath_ahb) to do any relevant
bus flushes that are required. A WMAC DDR flush may be required
for the AR9130 SoC.
in the HAL. That's very memory hungry (32k just for channel statistics)
which would be better served by keeping a summary in the ANI state.
Or, later, keep a survey history in net80211.
So:
* Migrate the ah_chansurvey array to be a single entry, for the current
channel.
* Change the ioctl interface and ANI code to just reference that.
* Clear the ah_chansurvey array during channel reset, both in the AR5212
and AR5416 reset path.
* Always call ar5416GetListenTime()
* Modify ar5416GetListenTime() to:
+ don't update the ANI state if there isn't any ANI state;
+ don't update the channel survey state if there's no active
channel - just to be paranoid
+ copy the channel survey results into the current sample slot
based on the current channel; then increment the sample counter
and sample history counter.
* Modify ar5416GetMIBCyclesPct() to simply return a HAL_SURVEY_SAMPLE,
rather than a set of percentages. The ANI code wasn't using the
percentages anyway.
TODO:
* Create a new function which fetches the survey results periodically
* .. then modify the ANI code to use the pre-fetched values rather than
fetching them again
* Roll the 11n ext busy function from ar5416_misc.c to update all the
counters, then do the result calculation
* .. then, modify the MIB counter routine to correctly fetch a snapshot -
freeze the counters, fetch the values, then reset the counters.
The reference driver has a 3ms delay for the AR9130 but I'm not as yet
sure why. From what I can gather, it's likely waiting for some FIFO
flush to occur.
At some point in the future it may be worthwhile adding a WMAC
FIFO flush here, but that'd require some side-call through to the SoC
DDR flush routines.
Obtained from: Atheros
which will be needed for AR7010 and AR9287 USB access.
The names differ slightly from Linux and Atheros, for the sake of
consistency.
A lot more work is required in order to convert the 11n HAL support to
fully support USB.
at least until I can root cause what's going on.
The only platform I've seen this on is the AR9220 when attached to
the AR71xx CPUs. I get immediate PCIe bus errors and all subsequent
accesses cause further MIPS bus exceptions. I don't have any other
big-endian platforms to test this on.
If I get a chance (or two), I'll try to whack this on a bus analyser
and see exactly what happens.
I'd rather leave this on, especially for slower, embedded platforms.
But the #ifdef hell is something I'm trying to avoid.
This may result in a bit of a throughput drop. However, any throughput
drop at this point should be investigated and root caused, as it's likely
because TX scheduling (all the way down to how preemption, scheduler work,
etc) is happening in a sub-optimal fashion.
This also makes it much more likely to be reloadable on a live machine.
Allocating 5120 TX ath_buf entries via contigmalloc is very unlikely
after a few hours of using X/Chromium.
dirty and murky past.
* Override the default cache line size to be something reasonable if
it's set to 0. Some NICs initialise with '0' (eg embedded ones)
and there are comments in the driver stating that various OSes (eg
older Linux ones) would incorrectly program things and 0 out this
register.
* Just default to overriding the latency timer. Every other driver
does this.
* Use a default cache line size of 32 bytes. It should be "reasonable
enough".
Obtained from: Linux ath9k, Atheros
interface.
* Introduce a device hint, 'eeprom_firmware', which is the name of firmware
to lookup.
* If the lookup succeeds, take a copy of it and use it as the eeprom data.
This isn't enabled by default - you have to define ATH_EEPROM_FIRMWARE.
I'll add it to the configuration variables in a later commit.
TODO:
* just keep a firmware reference in ath_softc, and remove the need to
waste the extra memory in having sc_eepromdata be a malloc()ed block.
add a FreeBSD_version check. It should work fine for compiling
on -HEAD, 9.x and 8.x.
* Conditionally compile the 11n options only when 11n is enabled.
The above changes allow the ath(4) driver to compile and run on
8.1-RELEASE (Hi old PC-BSD!) but with the 11n stuff disabled.
I've done a test against the net80211 and tools in 8.1-RELEASE.
The NIC used in testing is the AR2427 in an EEEPC.
Just to be clear - this change is to allow the -HEAD ath/hal/rate
code to run on 9.x _and_ 8.x with no source changes. However,
when running on earlier kernels, it should only be used for legacy
mode. (Don't define ATH_ENABLE_11N.)
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.
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.
if any subframes in an aggregate have different protection from the
first frame in the formed aggregate, don't add that frame to the
aggregate.
This is likely a suboptimal method (I think we'll mostly be OK marking
frames that have seqno's with the same protection as normal data frames)
but I'll just be cautious for now.
This will be used by some upcoming code to ensure that aggregates
are enforced to be a certain size. The AR5416 has a limitation on
RTS protected aggregates (8KiB).
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.
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.
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.
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
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
This is not entirely correct as it simply resets the channel, flushing
whatever is in the TX/RX queue. This can and will break aggregation
BAW tracking. But the alternative (HT40 frames being sent with the hardware
in HT20 mode) is even worse.
There's still a small window between the htinfo being received (and the ni_chw
field being updated) which could cause problems. I'll look at fleshing this
out in follow-up commits.
PR: kern/166286
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
* printf -> device_printf
* print the buffer pointer and sequence number for any buffer that wasn't
correctly tidied up before it was freed. This is to aid in some
current SMP TX debugging stalls.
PR: kern/166190
Although access to the flags to check/set OACTIVE is racy due to how
the default if_start() function works, this should remove any races
with read/modify/write between threads.
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
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
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". :/
This function must be called with both the source and destination TXQs
locked or things will get hairy.
I added this as part of some debugging in a PR but it turned out to not
be the cause. I still think it's -correct- so, here it is.
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
been bait-and-switched from the rate control code.
This will avoid the panic that I saw and will avoid sending invalid rates
(eg 11a/11g OFDM rates when in 11b, on 11b-only NICs (AR5211)) where the
rate table is not "big".
It also will point out situations where this occurs for the 11n NICs
which will have sufficiently large rate tables that "invalid rix" doesn't
occur.
I'll try to follow this up with a commit that adds a current operating mode
check. The "rix" is only relevant to the current operating mode and rate
table.
PR: kern/165475
* ath_reset() is being called in softclock context, which may have the
thing sleep on a lock. To avoid this, since we really _shouldn't_
be sleeping on any locks, break out the no-loss reset path into a tasklet
and call that from:
+ ath_calibrate()
+ ath_watchdog()
This has the added advantage that it'll end up also doing the frame
RX cleanup from within the taskqueue context, rather than the softclock
context.
* Shuffle around the taskqueue_block() call to be before we grab the lock
and disable interrupts.
The trouble here is that taskqueue_block() doesn't block currently
queued (but not yet running) tasks so calling it doesn't guarantee
no further tasks (that weren't running on _A_ CPU at the time of this
call) will complete. Calling taskqueue_drain() on these tasks won't
work because if any _other_ thread calls taskqueue_enqueue() for whatever
reason, everything gets very angry and stops working.
This slightly changes the race condition enough to let ath_rx_tasklet()
run before we try disabling it, and thus quietens the warnings a bit.
The (more) true solution will be doing something like the following:
* having a taskqueue_blocked mask in ath_softc;
* having an interrupt_blocked mask in ath_softc;
* only calling taskqueue_drain() on each individual task _after_ the
lock has been acquired - that way no further tasklet scheduling
is going to occur.
* Then once the tasks have been blocked _and_ the interrupt has been
disabled, call taskqueue_drain() on each, ensuring that anything
that _was_ scheduled or running is removed.
The trouble is if something calls taskqueue_enqueue() on a task
after taskqueue_blocked() has been called but BEFORE taskqueue_drain()
has been called, ta_pending will be set to 1 and taskqueue_drain()
will sit there stuck in msleep() until you hard-kill the machine.
PR: kern/165382
PR: kern/165220
I'm not sure _why_ the ic is NULL here, but I've seen it occasionally do
this after I've been tinkering with things for a while. It ends up
crashing in a call to ath_chan_set() via the net80211 scan code and scan
task.
hold the lock.
This is part of my series of work to try and capture when net80211
locking isn't.
ObNote: it'd be nice to be able to mark a lock as "assert if the lock
is dropped", so I could capture functions which decide that dropping
and reacquiring the lock is a good idea (without re-checking the
sanity of the state protected by the lock.)
with RX/TX halting.
* Always disable/enable interrupts during a channel change, just to simply
things.
* Ensure that the ath taskqueue has completed and is paused before
continuing.
This dramatically reduces the instances of overlapping RX and reset
conditions.
PR: kern/165220
There are unfortunately a number of situations where vap->iv_bss is changed
or freed by some code in net80211. Because multiple threads can concurrently
be doing work (and the vap->iv_bss access isn't at all done behind any kind
of lock), it's quite possible that:
* a change will occur in one thread - eg, by a call through
ieee80211_sta_join1();
* a state change occurs in another thread - eg an RX is scheduled
in the ath tasklet and it calls ieee80211_input_mimo_all(), which
does dereference vap->iv_bss;
* these two executing concurrently, causing things to explode.
Another instance is ath_beacon_alloc() which takes an ieee80211_node *.
It's called with the vap->iv_bss node from ath_newstate(). If the node has
changed in the meantime (say it's been freed elsewhere) the reference
that it grabbed _before_ refcounting it may be stale.
I would _prefer_ that these sorts of things were serialised somewhere but
that may be a bit much to ask. Instead, the best we can (currently) hope
is that the underlying bss node is still (somewhat) valid.
There is a related PR (kern/164382) described by the first case above.
That should be fixed by properly serialising the RX path and reset path
so an RX can't occur at the same time as the vap free/shutdown path.
This is inspired by some related fixes in r212127.
PR: kern/165060
overridden at attach time.
Some 802.11n NICs may only have one physical antenna connected.
The radios will be very upset if you try enabling radios which aren't
connected to antennas.
This allows hints to override the TX and RX chainmask.
These hints are:
hint.ath.X.rx_chainmask
hint.ath.X.tx_chainmask
They can be set at either boot time or in kenv before the module is loaded.
This and the previous HAL commit were sponsored in late 2011 by Hobnob, Inc.
Sponsored by: Hobnob, Inc.
by capabilities.
Add an ar5416SetCapability() function, which contains logic to override
the chainmask and update the relevant stream.
This is designed to be called after the attach function, which presets
the TX/RX chainmask and stream.
TODO: check the chainmask against the hardware chainmask so non-existing
chains aren't enabled.
radar parameters for the AR5416 and later NICs.
These parameters have been tested on the following NICs:
* AR5416
* AR9160
* AR9220
* AR9280
And yes, these will return radar pulse parameters and (for AR9160 and later)
radar FFT information as PHY errors.
This is again not enough to do radar detection, it's just here to faciliate
development and validation of radar detection algorithms.
The (pulse, not FFT) decoding code for AR5212, AR5416 and later NICs exist
in the HAL.
This code is disabled for now as generating radar PHY errors can quickly
cause issues in busy environment.s Some further debugging of the RX path
is needed.
Finally, these parameters are likely not useful for the AR5212 era NICs.
The madwifi-dfs branch should have suitable example parameters for the
11a era NICs.
* Override the TX/RX stream count if the EEPROM reports a single RX or
TX stream, rather than assuming the device will always be a 2x2 strea
device.
* For AR9280 devices, don't hard-code 2x2 stream. Instead, allow the
ar5416FillCapabilityInfo() routine to correctly determine things.
The latter should be done for all 11n chips now that
ar5416FillCapabilityInfo() will set the TX/RX stream count based on the
active TX/RX chainmask in the EEPROM.
Thanks to Maciej Milewski for donating some AR9281 NICs to me for
testing.
* For legacy NICs, the combined RSSI should be used.
For earlier AR5416 NICs, use control chain 0 RSSI rather than combined
RSSI.
For AR5416 > version 2.1, use the combined RSSI again.
* Add in a missing AR5212 HAL method (get11nextbusy) which may be called
by radar code.
This serves no functional change for what's currently in FreeBSD.
* Grab the net80211com lock when calling ieee80211_dfs_notify_radar().
* Use the tsf extend function to turn the 64 bit base TSF into a per-
frame 64 bit TSF. This will improve radiotap logging (which will
now have a (more) correct per-frame TSF, rather then the single TSF64
value read at the beginning of ath_rx_proc().
to being more generic.
Other embedded SoCs also throw the configuration/PCI register
info into flash.
For now I'm just hard-coding the AR9280 option (for on-board AR9220's on
AP94 and commercial designs (eg D-Link DIR-825.))
TODO:
* Figure out how to support it for all 11n SoC NICs by doing it in
ar5416InitState();
* Don't hard-code the EEPROM size - add another field which is set
by the relevant chip initialisation code.
* 'owl_eep_start_loc' may need to be overridden in some cases to 0x0.
I need to do some further digging.
where they've disabled all the wireless devices/framework.
This is just a build workaround. If you're actively using wireless,
you must still define AH_SUPPORT_AR5416 as I'm not sure what else
will break!
The real solution is to make the module build depend if AH_SUPPORT_AR5416
is defined, as well as make the 11n code in if_ath_tx.c and if_ath_tx_ht.c
completely optional (maybe depend upon ATH_SUPPORT_11N.)
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
doing split software/hardware LED configuration, we can now simply
treat "softled" as an "output" mux type.
This works fine on this DWA-552. Previous generation (pre-11n NICs) don't
have a GPIO mux - only input/output configuration - so they ignore this
field.
The hardware (MAC) LED blinking involves a few things:
* Selecting which GPIO pins map to the MAC "power" and "network" lines;
* Configuring the MAC LED state (associated, scanning, idle);
* Configuring the MAC LED blinking type and speed.
The AR5416 HAL configures the normal blinking setup - ie, blink rate based
on TX/RX throughput. The default AR5212 HAL doesn't program in any
specific blinking type, but the default of 0 is the same.
This code introduces a few things:
* The hardware led override is configured via sysctl 'hardled';
* The MAC network and power LED GPIO lines can be set, or left at -1
if needed. This is intended to allow only one of the hardware MUX
entries to be configured (eg for PCIe cards which only have one LED
exposed.)
TODO:
* For AR2417, the software LED blinking involves software blinking the
Network LED. For the AR5416 and later, this can just be configured
as a GPIO output line. I'll chase that up with a subsequent commit.
* Add another software LED blink for "Link", separate from "activity",
which blinks based on the association state. This would make my
D-Link DWA-552 have consistent and useful LED behaviour (as they're
marked "Link" and "Activity."
* Don't expose the hardware LED override unless it's an AR5416 or later,
as the previous generation hardware doesn't have this multiplexing
setup.
Some of the NICs I have here power up with the LEDs blinking, which is
incorrect. The blinking should only occur when the NIC is attempting
to associate.
* On powerup, set the state to HAL_LED_INIT, which turns on the "Power" MAC
LED but leaves the "Network" MAC LED the way it is.
* On resume, also init it to HAL_LED_INIT unless in station mode, where
it's forced to HAL_LED_RUN. Hopefully the net80211 state machine will
call newstate() at some point, which will refiddle the LEDs.
I've tested this on a handful of 11n and pre-11n NICs. The blinking
behaviour is slightly more sensible now.
relying on what the register defaults are.
This forces the blink mode to be proportional to the TX and RX frames
which match the RX filter.
This (along with a few tweaks to if_ath_led.c to configure the correct
GPIO pins) allows my DWA-552 AR5416 NIC to blink the LEDs in a useful
fashion, however those LEDs are marked "Link" and "Act(ivity)", which
don't really map well to the "power" / "network" LED interface which
the MAC provides. Some further tinkering is needed to see what other
useful operating modes are possible.
state from correctly updating things.
The reference driver directly enables/disables the LED state as required,
rather than nailing it up like it currently is. That'll have to come
later by adding some further HAL methods.
Obtained from: Atheros
* Bring the AR5416 GPIO mux mask code in line with the code from the
HAL.
* Add HAL_DEBUG_GPIO debugging statements, to track what's going on.
* Add Kiwi GPIO specific changes for reading values back.
Obtained from: Atheros
* As a preparation for AR9287 GPIO support, add in the AR9287 GPIO mask.
* Fix the association mask values; these are post-shift values but were
being shifted in twice. This resulted in some garbage being written
in the wrong place and the link LED (at least on my d-link AR5416
NIC) giving totally incorrect blink patterns.
Some users were reporting concurrent resets _were_ occuring - ie,
either two ath_reset()s ran at the same time (likely one on each CPU)
or ath_reset() versus ath_chan_change().
Instead, this now tries to grab the serialisation semaphore and will
pause() for a while if it fails. It will always eventually succeed though
and will log an error if it hits the recursion situation.
All of this stuff needs to die a horrible death at some point and be
replaced with a properly serialising method of programming this stuff
(eg using the net80211 taskqueue for all of this stuff.) The trouble
is figuring out how to handle the concurrent ioctl() based things without
introducing more LORs (which is another reason why I haven't just wrapped
all of this stuff in large, long-lived locks, a-la what Linux can get
away with.)
MFC after: Absolutely, positively never.
This doesn't fix compilation w/out AH_SUPPORT_AR5416 as all of the software
aggregation support in if_ath_tx.c and 11n code in if_ath_tx_ht.c touches
the 11n specific fields. I'll work on that later.
going on with the occasional garbage rs_antenna field reported by AR9285
users.
I've discovered that the 11n NICs only fill out the entire RX status
descriptor on the final descriptor in an aggregate. Some of the fields
(notably RSSI) are complete nonsense for A-MPDU subframes. This may
be another example of this.
The driver doesn't currently toss out statistics for non-final aggregate
frames. It's likely that this should be done.
If any users hit this particular debugging message they should report it
immediately to freebsd-wireless@freebsd.org - please ensure you have
ATH_DEBUG enabled so it prints out the full receive descriptor.
PR: kern/163312
There's currently no public code which uses this feature and the
current reference driver doesn't enable this feature at all.
It's possible it was used by a previous version of the driver and
that indeed it should return HAL_STATUS; but at this point I'm
happy to require that they complain and submit a patch.
This was found by LLVM compile-time type checking.
Submitted by: dim
and sys/dev/ath/ath_hal/ar5416/ar5416_misc.c:
sys/dev/ath/ath_hal/ar5212/ar5212_misc.c:577:24: warning: implicit conversion from enumeration type 'HAL_STATUS' to different enumeration type 'HAL_BOOL' [-Wconversion]
return HAL_EINVAL;
~~~~~~ ^~~~~~~~~~
and:
sys/dev/ath/ath_hal/ar5416/ar5416_misc.c:164:9: warning: implicit conversion from enumeration type 'HAL_STATUS' to different enumeration type 'HAL_BOOL' [-Wconversion]
return HAL_OK;
~~~~~~ ^~~~~~
In both cases, enums HAL_BOOL and HAL_STATUS are mixed up.
MFC after: 1 week
and sys/dev/ath/ath_hal/ar5211/ar5211_power.c:
sys/dev/ath/ath_hal/ar5210/ar5210_power.c:36:3: warning: signed shift result (0x200000000) requires 35 bits to represent, but 'int' only has 32 bits [-Wshift-overflow]
OS_REG_RMW_FIELD(ah, AR_SCR, AR_SCR_SLE, AR_SCR_SLE_ALLOW);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sys/dev/ath/ath_hal/ah_internal.h:472:42: note: expanded from:
(OS_REG_READ(_a, _r) &~ (_f)) | (((_v) << _f##_S) & (_f)))
^
sys/dev/ath/ah_osdep.h:127:49: note: expanded from:
(bus_space_handle_t)(_ah)->ah_sh, (_reg), (_val))
^~~~
The AR_SCR_SLE_{WAKE,SLP,NORM} values are pre-shifted in ar5210reg.h and
ar5211reg.h, while they should be unshifted, like in ar5212reg.h. Then,
when the OS_REG_RMW_FIELD() macro shifts them again, the values will
overflow, becoming effectively zero.
MFC after: 1 week
attached this way.
The AR5212 based NICs have a variety of RF frontends, so there's a linker set
which the AR5212 attach routine calls. The same framework is used for the
AR5416 and later but as there's a fixed RF frontend for each 11n NIC, it
is just directly attached.
However in the case of compiling a cut down HAL (eg _just_ AR9130 WMAC support),
the linker set ends up being empty and this causes the compile to fail.
So this is just a workaround for that - it means those users who wish an 11n
only HAL can compile the 11n chipsets and RF frontend they need, and just
"ath_ar5212" for the AR5212/AR5416 common code, and it'll just work.
Sponsored by: Hobnob, Inc.
The calibrate callout is done with the sc lock held.
This only showed up when using an older NIC (AR5212) whose
radio/phy requires the rfgain adjustment.
Pointy-hat-to: adrian
Sponsored by: Hobnob, Inc.
* 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.
This fixes panics that users have been seeing when operating in station mode,
where the interface undergoes a lot more resets then in hostap mode (ie whilst
doing channel scanning.)
Reported by: arundel, wblock@wonkity.com
Sponsored by: Hobnob, Inc.
mode configuration registers. This is apparently required for correct
behaviour, but also requires the chip to actually officially support it.
Sponsored by: Hobnob, Inc.
"correct" handling of frames in the RX pending queue during interface
transitions.
* ath_stoprecv() doesn't blank out the descriptor list - that's what
ath_startrecv() does. So, change a comment to reflect that.
* ath_stoprecv() does include a large (3ms) delay to let pending DMA
complete. However, I'm under the impression that the stopdma hal
method does check for a bit in the PCU to indicate DMA has stopped.
So, to help with fast abort and restart, modify ath_stoprecv() to take
a flag which indicates whether this is needed.
* Modify the uses of ath_stoprecv() to pass in a flag to support the
existing behaviour (ie, do the delay.)
* Remove some duplicate PCU teardown code (which wasn't shutting down DMA,
so it wasn't entirely correct..) and replace it with a call to
ath_stoprecv(sc, 0) - which disables the DELAY call.
The upshoot of this is now channel change doesn't simply drop completed
frames on the floor, but instead it cleanly handles those frames.
It still discards pending TX frames in the software and hardware queues
as there's no (current) logic which forcibly recalculates the rate control
information (or whether they're appropriate to be on the TX queue after
a channel change), that'll come later.
This still doesn't stop all the sources of queue stalls but it does
tidy up some of the code duplication.
To be complete, queue stalls now occur during normal behaviour -
they only occur after some kind of broken behaviour causes an interface
or node flush, upsetting the TX/RX BAW. Subsequent commits will
incrementally fix these and other related issues.
Sponsored by: Hobnob, Inc.
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.
I need to investigate this a little closer, but it seems that in noisy
environments the NF load takes longer than 5 * DELAY(10) and this is
messing up future NF calibrations. (The background: NF calibrations
begin at the value programmed in after the load has completed, so
if this is never loaded in, the NF calibrations only ever start at
the currently calibrated NF value, rather than starting at something
high (say -50.)
More investigation about the effect on 11n RX and calibration results
are needed.
Sponsored by: Hobnob, Inc.
The AR5416 MAC (which shows up in the AR5008, AR9001, AR9002 devices) has
issues with PCI transactions on SMP machines. This work-around enforces
that register access is serialised through a (global for now) spinlock.
This should stop the hangs people have seen with the AR5416 PCI devices
on SMP hosts.
Obtained by: Linux, Atheros
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.
to fetch the current channel busy statistics, rather than duplicating
it here.
This forms the (very crude) basis for doing basic channel surveying.
Sponsored by: Hobnob, Inc.
enabled if required by STA operation.
This quietens a lot of OFDM errors seen in hostap mode, where
there are no beacon RSSI levels to tune the dynamic range of the
baseband.
This may reduce reception range at the fringes, but does increase
stability.
Sponsored by: Hobnob, Inc.
The 5ghz hostap mode (where DFS is being done) requires ANI to be disabled
or the radar detection parameters don't work as advertised (as they're based
on signal strength level, and tweaking ANI affects the signal strangth,
dynamic range and power increase the baseband is looking for in order to
detect it as a "signal".)
Obtained from: Linux, Atheros
Sponsored by: Hobnob, Inc.
* If we fall through from an ANI command (eg because it's out of range,
or it's disabled) then fall through to the next ANI command rather then
being stuck there.
* Fix some off-by-one comparisons, meaning the final level in some parameters
were never tweaked.
Obtained from: Atheros
Sponsored by: Hobnob, Inc.
This forces a full reset of the baseband/radio and seems needed to clear
some issues (with Merlin at least) when the baseband gets confused in a
very noisy environment.
Sponsored by: Hobnob, Inc.
RX clear, RX extension clear.
This is useful for estimating channel business.
The same routines should be written for AR5210->AR5212 where appopriate.
Obtained from: Atheros
some unmerged interrupt status debugging code from my branch.
* Add ah_intrstate[8] which will have the record of the last
call to ath_hal_getintr().
* Wrap the KTR code behind ATH_KTR_INTR_DEBUG.
* Add the HAL interrupt debugging behind AH_INTERRUPT_DEBUGGING.
This is only done for the AR5416 and later NICs but it will be
trivial to add to the earlier NICs if required.
Neither are enabled by default, although to minimise HAL binary
API differences, the ah_intrstate[] array is always compiled into
the ath_hal struct.
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
preparation for TX aggregation.
* Add in logic which calls ath_buf bf->bf_comp if it's set.
This allows for AMPDU (and RIFS, and FF, if someone desires) code
to handle completion - which includes freeing subframes, retransmitting
subframes, etc.
* Break out the buffer free, buffer busy/unbusy default completion handler
code into separate functions. This allows bf_comp methods to free and
unbusy each subframe ath_buf as required.
* Break out the statistics update code into a separate function, just
to clean up the TX completion path a little.
Sponsored by: Hobnob, Inc.
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.
* Immediately return NULL if a buffer isn't available;
* Track the "buffers not available" count;
* Clear some fields used for tx aggregation;
* Add ath_buf_clone() which clones the majority of buffer state.
This is needed when retransmission of a "busy" buffer is required.
Sponsored by: Hobnob, Inc.
Add some code (which is currently disabled) which modifies the group
multicast key cache behaviour. I haven't yet figured out what the
exact/correct behaviour is so I'm leaving it disabled. It's worth
investigating and "correcting", especially for future work with
mesh/ibss and encryption.
Sponsored by: Hobnob, Inc.
* When doing software TX queue handling and flush, it's possible
that the deletion of a VAP (eg a STA shutdown) will queue a
"STA Disassociate" frame whilst the interface is being deleted.
The VAP is then deleted, and the frame ends up being queued
to a node that is freed before it can be TX'ed. Things go awry
at this point.
There's no way at the present to avoid freeing the underlying node
when the vap is being deleted. It's too late in the game.
I suspect the real fix is to make sure the frame is software
queued with no completion information somehow, so it doesn't
link back to a node whose underlying VAP has been freed.
For now, we'll just have to do this.
* Add some comments showing what's going on.
* Move an instance of the ATH_LOCK() around to protect the interrupt
set. I'll worry about changing that to a PCU lock later on once
the 11n code is in the tree.
Sponsored by: Hobnob, Inc.
and interface resets to be marked as ATH_RESET_DEFAULT, ATH_RESET_FULL,
ATH_RESET_NOLOSS.
Currently a reset is still a reset - ie, all tx/rx frames in the hardware
queues are purged. This means that those frames will be lost to the 11n TX
and RX aggregation state tracking, breaking AMPDU sessions.
The (eventual) new semantics:
* ATH_RESET_DEFAULT:
full reset, this is the default for reset situations
which I haven't yet figured out what they should be.
* ATH_RESET_FULL:
A full reset - for things such as channel changes.
* ATH_RESET_NOLOSS:
Don't flush TX/RX queues - handle pending RX frames and leave TX
frames where they are; restart TX DMA from where it was.
* Change ath_rx_proc() to ath_rx_tasklet(); make that the taskqueue function.
This way (eventually) ath_rx_proc() can be called from elsewhere in the
packet reset/processing queue so frames aren't just "flushed" during
interface resets/reconfigure. This breaks 802.11n RX aggregation tracking.
* Extend ath_tx_proc() to take a 'resched' flag, which marks whether to
reschedule further RX PCU reads or not.
* Change ath_tx_processq() to take a "dosched" flag, which will eventually
be used to indicate whether to reschedule the software TX scheduler.
Sponsored by: Hobnob, Inc.
* Close down some of the kickpcu races, where the interrupt handler
can and will run concurrently with the taskqueue.
* Close down the TXQ active/completed race between the interrupt
handler and the concurrently running tx completion taskqueue
function.
* Add some tx and rx interrupt count tracking, for debugging.
* Fix the kickpcu logic in ath_rx_proc() to not simply drain and
restart the TX queue - instead, assume the hardware isn't
(too) confused and just restart RX DMA. This may break on
previous chipsets, so if it does I'll add a HAL flag and
conditionally handle this (ie, for broken chipsets, I'll
just restore the "stop PCU / flush things / restart PCU"
logic.)
* Misc stuff
Sponsored by: Hobnob, Inc.
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.
* Use 64 bit integer types for the sample rate statistics.
When TX'ing 11n aggregates, a 32 bit counter will overflow in a few
hours due to the high packet throughput.
* Create a default label of "" rather than defaulting to "Mb" - that way
if a rate hasn't yet been selected, it won't say "-1 Mb".
Sponsored by: Hobnob, Inc.
* Add a PCU lock, which isn't currently used but will eventually be
used to serialise some of the driver access.
* Add in all the software TX aggregation state, that's kept per-node
and per-TID.
* Add in the software and aggregation state to ath_buf.
* Add in hooks to ath_softc for aggregation state and the (upcoming)
aggregation TX state calls.
* Add / fix the HAL access macros.
Obtained from: Linux, ath9k
Sponsored by: Hobnob, Inc.
The SYSCTL_NODE macro defines a list that stores all child-elements of
that node. If there's no SYSCTL_DECL macro anywhere else, there's no
reason why it shouldn't be static.
their length.
Without this, an error frame mbuf would:
* have its size adjusted;
* thrown at the radiotap code;
* then since it's never consumed, the rxbuf/mbuf is then re-added to the
RX descriptor list with the small size;
* .. and the hardware ends up (sometimes) only DMA'ing part of a frame into
the small buffer, chaining RX frames together (setting the more flag).
I discovered this particular issue when doing some promiscuous radiotap
testing; I found that I'd occasionally get rs_more set in RX descriptors
w/ the first frame length being very small (sub-100 bytes.) The driver
handles 2-descriptor RX frames (but not more), so this still worked; it
was just odd.
This is suboptimal and may benefit from being replaced with caching
the m_pkthdr_len and m_len fields, then restoring them after completion.
* preserve AR_TxIntrReq on every descriptor in an aggregate chain,
not just the first descriptor;
* always blank out the descriptor in ar5416ChainTxDesc() when forming
aggregates - the way I'm using this in the 11n branch is to first
chain aggregates together, then use the other HAL calls to fill in
the details.
* Add the TID field in the TX status descriptor;
* Add in the 11n first/middle/last functions for fiddling
with the descriptors. These are from the Linux and the
reference driver, but I'm not (currently) using them.
* Add further AR_ISR_S5 register definitions.
Obtained from: Linux ath9k, Atheros
interfere with traffic, as the NF load can take quite a while and poking the
AGC every 10uS is just a bit silly.
Instead, just leave the baseband NF calibration where it is and just read it
back next time a longcal interval happens.
Some earlier series (~AR5212?) play badly with BIOSes.
In these instances, they may require a forced reset (by transitioning
the NIC through D0 -> D3 -> D0) before they probe/attach correctly.
This is currently disabled because:
* I haven't figured out the "right" code to ensure this only happens
for PCI NICs (not PCIe or Cardbus);
* I haven't at all done wide scale testing for this, and I'm not yet
ready for said wide-scale testing.
I'm documenting this primarily so users with misbehaving NICs have
something to tinker with.
Obtained from: Atheros
The final missing bit here is enabling the PCI configuration register
read, but there's currently no glue available for the HAL to read (and
write) PCI configuration space registers.
Obtained from: Atheros
The AR5008/AR9001 series NICs have a bug where BB register reads
will occasionally be corrupted. This could cause issues with things
such as ANI, which adjust operational parameters based on the
BB radio register reads. This was introduced in the AR5008 chip
and fixed with the first released AR9002 series NIC (AR9280v2.)
A followup commit will implement the acutal WAR when reading
BB registers. I'm still not sure how I'll implement it - whether
it should be done in the osdep layer, or whether it should just
live in the AR5416 HAL. Either way, they can use this capability
bit to determine whether to implement the WAR or not.
Thankyou to various sources inside Atheros who have helped me track
down what this particular issue is.
Obtained from: Atheros
There are HAL methods which are actually direct register
access, rather than simply HAL calls. Because of this, these
register accesses would use the non-debug path in ah_osdep.h
as opt_ah.h isn't included.
With this, the correct register access methods are used,
so debugging traces show things such as TXDP checking and
TSF32 access.
That way the radar errors aren't enabled prematurely.
A DFS tester has reported that radar events are reported
during channel scanning, before DFS is actually enabled.
* Break out the PCI setup override code into a new function.
* Re-apply the PCI overrides on powersave resume. The retry timeout
register isn't currently being saved/resumed by the PCI driver/bus
code.
Pre-11n devices and AR5416 use AR_PHY(263) for current RX RSSI.
AR9130 and later have a fourth calibration register (for doing
ADC calibration) and thus the register has moved to AR_PHY(271).
This isn't currently used by any of the active code; I'm committing
this for completeness and in case any third party code attempts to
use it for legacy reasons.
* The AR_ISR_RAC interrupt processing method has a subtle bug in all
the MAC revisions (including pre-11n NICs) until AR9300v2.
If you're unlucky, the clear phase clears an update to one of the
secondary registers, which includes TX status.
This shows up as a "watchdog timeout" if you're doing very low levels
of TX traffic. If you're doing a lot of non-11n TX traffic, you'll
end up receiving a TX interrupt from some later traffic anyway.
But when TX'ing 11n aggregation session traffic (which -HEAD isn't yet
doing), you may find that you're only able to TX one frame (due to
BAW restrictions) and this may end up hitting this race condition.
The only solution is to not use RAC and instead use AR_ISR and the
AR_ISR_Sx registers. The bit in AR_ISR which represents the secondary
registers are not cleared; only the AR_ISR_Sx bits are. This way
any updates which occur between the read and subsequent write will
stay asserted and (correctly) trigger a subsequent interrupt.
I've tested this on the AR5416, AR9160, AR9280. I will soon test
the AR9285 and AR9287.
* The AR_ISR TX and RX bits (and all others!) are set regardless of
whether the contents of the AR_IMR register. So if RX mitigation is
enabled, RXOK is going to be set in AR_ISR and it would normally set
HAL_INT_RX.
Fix the code to not set HAL_INT_RX when RXOK is set and RX mitigation
is compiled in. That way the RX path isn't prematurely called.
I would see:
* An interrupt would come in (eg a beacon, or TX completion) where
RXOK was set but RXINTM/RXMINT wasn't;
* ath_rx_proc() be called - completing RX frames;
* RXINTM/RXMINT would then fire;
* ath_rx_proc() would then be called again but find no frames in the
queue.
This fixes the RX mitigation behaviour to not overly call ath_rx_proc().
* Start to flesh out more correct timer interrupt handling - it isn't
kite/merlin specific. It's actually based on whether autosleep support
is enabled or not.
This is sourced from my 11n TX branch and has been tested for a few weeks.
Finally, the interrupt handling change should likely be implemented
for AR5210, AR5211 and AR5212.
There are some timing concerns which I've yet to fully map out.
In any case, there's an existing software driven mitigation method
for TX interrupts and when TX'ing 11n frames, the whole frame itself
generates an interrupt rather then the subframes.
Although I tried to fix this earlier by introducing HALDEBUG_G(), it
turns out there seem to be other cases where the pointer value is still
NULL.
* Fix DO_HALDEBUG() and the HALDEBUG macro to check whether ah is NULL
before deferencing it
* Remove HALDEBUG_G() as it's no longer needed
This is hopefully a merge candidate for 9.0-RELEASE as enabling
debugging at startup could result in a kernel panic.
rather than the whole beacon interval.
The reference driver and Linux ath9k both choose 80% of the
beacon interval and they do it in the driver rather than
the HAL (Ath reference) or ath9k_hw (ath9k.)
This quietens stuck beacon conditions on my AR9220/AR9280
based NICs when a lot of burst broadcast/multicast traffic
is going on. It doesn't seem to annoy the earlier MACs as
much as the AR9280 and later one.
Obtained from: Linux ath9k, Atheros
local variable with a beacon interval of 100 TU. This never gets modified
if the beacon interval configuration changes.
This may have been correct in earlier times, but with the advent of
staggered beacons (which default to 1 / ATH_BCBUF beacon interval, so
25 TU here) this value is incorrect.
It is used to configure the default CABQ readytime. So here, the cabq
was being configured to be much greater than the target beacon timer
(TBTT.)
The driver should be configuring a cabq readytime value rather then
leaving it to the HAL to choose sensible defaults. This should be
done in the future - I'm simply trying to ensure sensible defaults
are chosen.
This is another commit in a series of TDMA support fixes for the 11n NICs.
* Move ath_hal_getnexttbtt() into the HAL; write methods for it.
This returns a timer value in TSF, rather than TU.
* Move ath_hal_getcca() and ath_hal_setcca() into the HAL too, where they
likely now belong.
* Create a new HAL capability: HAL_CAP_LONG_RXDESC_TSF.
The pre-11n NICs write 15 bit TSF snapshots into the RX descriptor;
the AR5416 and later write 32 bit TSF snapshots into the RX descriptor.
* Use the new capability to choose between 15 and 31 bit TSF adjustment
functions in ath_extend_tsf().
* Write ar5416GetTsf64() and ar5416SetTsf64() methods.
ar5416GetTsf64() tries to compensate for TSF changes at the 32 bit boundary.
According to yin, this fixes the TDMA beaconing on 11n chipsets and TDMA
stations can now associate/talk, but there are still issues with traffic
stability which need to be investigated.
The ath_hal_extendtsf() function is also used in RX packet timestamping;
this may improve adhoc mode on the 11n chipsets. It also will affect the
timestamps seen in radiotap frames.
Submitted by: Kang Yin Su <cantona@cantona.net>
Approved by: re (kib)
reference driver does clear the async interrupts after each service.
I'll tinker with this in a future commit.
Obtained from: Atheros
Approved by: re (kib)
When the fast clock (44mhz) is enabled for 5ghz HT20, the
dual ADCs aren't enabled. Trying to do the ADC calibrations
here would result in calibration never completing; this
resulted in IQ calibration never running and thus performance
issues in 11a/11n HT20 mode.
Leave it enabled for non-fastclock (40mhz) 11a mode and
HT40 modes.
This has been fixed in discussion with Felix Fietkau (nbd)
and discussions with the Atheros baseband team.
Linux ath9k now has a similar fix.
Approved by: re (kib)