History log of /freebsd/sys/dev/ath/if_ath_tx.c (Results 151 – 175 of 272)
Revision (<<< Hide revision tags) (Show revision tags >>>) Date Author Comments
# b69b0dcc 08-Nov-2012 Adrian Chadd <adrian@FreeBSD.org>

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 legac

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.

show more ...


# 6e84772f 06-Nov-2012 Adrian Chadd <adrian@FreeBSD.org>

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.)

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!)

show more ...


# 23090366 04-Nov-2012 Simon J. Gerraty <sjg@FreeBSD.org>

Sync from head


# 1b5c5f5a 31-Oct-2012 Adrian Chadd <adrian@FreeBSD.org>

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
net

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.

show more ...


# 548a605d 28-Oct-2012 Adrian Chadd <adrian@FreeBSD.org>

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 do

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.

show more ...


# 9572684a 26-Oct-2012 Adrian Chadd <adrian@FreeBSD.org>

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 dur

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.

show more ...


# 13aa9ee5 15-Oct-2012 Adrian Chadd <adrian@FreeBSD.org>

Stop abusing the ATH_TID_*() queue macros for filtered frames and give
them their own macro set.


# b1dddc28 13-Oct-2012 Adrian Chadd <adrian@FreeBSD.org>

Fix the non-TDMA build.


# 3e6cc97f 08-Oct-2012 Adrian Chadd <adrian@FreeBSD.org>

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

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.

show more ...


# 0eb81626 04-Oct-2012 Adrian Chadd <adrian@FreeBSD.org>

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 t

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.)

show more ...


# 7403d1b9 26-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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

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

show more ...


# 0a544719 25-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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 har

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>

show more ...


# 23f44d2b 25-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

Call ath_tx_tid_unsched() after the node has been flushed, so the
state can be printed correctly.


# 03682514 24-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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 an

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.

show more ...


# 0c54de88 24-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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

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.

show more ...


# 94eefcf1 24-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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.


# 4e81f27c 20-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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

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.

show more ...


# d05b576d 20-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

Place the comment where it should be.


# 088d8b81 20-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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

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.)

show more ...


# 0aa5c1bb 18-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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 effec

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.

show more ...


# f1bc738e 18-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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 w

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.

show more ...


# c6e9cee2 17-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

Take credit for the work I've done in this source file.


# 5d9b19f7 11-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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'.


# 21840808 09-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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

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.

show more ...


# 2a9f83af 07-Sep-2012 Adrian Chadd <adrian@FreeBSD.org>

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

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

show more ...


1234567891011