Re: [RFC/RFT 2/5] ath9k: use mac80211 intermediate software queues

2016-06-06 Thread Tim Shepard

> And the patchset I was testing included your fq_codel port for ath9k
> but it was based on codel5.h. Michal's latest stuff reworked mainline
> codel to be generically usable, and it *is* a different variant of the
> algorithm.

I think you probably do understand what you are doing and which patch
is which, but I want to make sure that everyone else (and you, just in
case) understands that my patch to ath9k hooks ath9k up to the new
mac80211 per-station and per-tid intermediate queues and does *not*
have any codel or fq stuff in it, and is useful and worth doing even
if you aren't taking the codel and fq stuff.   (I didn't port any
fq_codel stuff to ath9k.)

My ath9k patch is a prerequisite for people who want to take Michal's
mac80211 fq and mac80211 codel stuff for a test drive on an ath9k
interface.  (Otherwise the ath9k uses the old transmit path through
mac80211 which wouldn't touch Michal's fq and codel tweaks to
mac80211's new intermediate queues.)  But it is useful and there are
some benefits to it (especially with Michal's IFF_NO_QUEUE) even
without the fq and codel stuff.


-Tim Shepard
 s...@alum.mit.edu

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/RFT 2/5] ath9k: use mac80211 intermediate software queues

2016-06-06 Thread Toke Høiland-Jørgensen
Tim Shepard  writes:

> OK, makes sense. But you left it called txq in mac80211. So someone
> reading the mac80211 code and ath9k at the same time (to understand
> the whole stack) winds up with txq meaning different things, including
> in places in ath9k where it has to reference a field in a structure
> defined by mac80211's header files to point to one of its txqs.

Yeah, realise there's a problem here. I was coming at it from the ath9k
side, so to speak, and having the variable txq suddenly be something
else was confusing.
>
>> As for the first point, I think it would be easier if you did not call
>> the mac80211 queues 'txq' but something else ('swq' like I did, perhaps;
>> I also considered 'imq' for intermediate queue). This will at least make
>> it clear at a glance that it is something different than 'txq' was
>> previously.
>
> I'm not the one who called them txq.

I was referring to the variable names, not the struct name. Having
'txq->foo' suddenly be something else is what ticked me off.

> That was Felix's patch. He also wrote the mt76 driver and in that
> driver txq consistently means the mac80211 intermediate queue and not
> a driver internal queue or a hardware queue. So I was trying to
> converge ath9k to be more like the one and only example I had of a
> driver that uses the intermediate queue.

Well, that is certainly an argument for going ahead with the renaming.
Hmm, would posting the renaming as a proper proposed patch explaining
the reasoning be a way to get some feedback on whether this would be a
tractable way forward (and also of keeping the delta against mainline
lower)?

> Thanks. I've gotten no other feedback that suggests anyone else has
> read the code. So I very much appreciate it.

You're very welcome; your patch made it possible for me to get straight
to hacking on the parts that I wanted to, without having to first figure
out how to best interface with the mac80211 stuff. Very helpful :)

> Yes, I didn't like that side effect either, but (at least for my first
> attempt) wanted to leave the old transmit path working, in particular
> because I couldn't see how to get all the chanctx stuff working right
> without leaving the old driver-internal queues in place. (I'm not even
> sure what I would have to do to test the driver with
> CONFIG_ATH9K_CHANNEL_CONTEXT turned on. I did test that it compiles
> without error when CONFIG_ATH9K_CHANNEL_CONTEXT=y before I released my
> v2 patch, and I tried to understand it enough to avoid breaking
> anything. (My v1 patch broke compilation when
> CONFIG_ATH9K_CHANNEL_CONTEXT=y as some robot notified me after I
> posted it.)

Right. Well I have been cheerfully ignoring the chanctx stuff so far.
What does that do?

> I looked for a way to ask mac80211 if there are any packets left in
> the intermediate queue without dequeueing a packet and I failed to
> find such an interface. I guess I should have submitted a patch to add
> that to mac80211. Or maybe there's a way to refactor the aggregation
> code in ath9k so that it can cleanly work with the existing
> ieee80211_tx_dequeue() without having to add another interface to
> mac80211, but I didn't figure it out. It would have been a bigger
> patch to ath9k, and require more thinking when reading the patch to
> see if it works (assuming pre-patch ath9k works).

Well code actually building the aggregates is not the problem, I think.
That just loops on while(ath_tid_has_buffered()) which is pretty
straight forward to turn into a dequeue + checking for NULL. It's the
aggr_{sleep,wakup,resume} that's conditioning txq wakeup on
ath_tid_has_buffered() that's the main problem I guess. What would
happen if that was changed to just unconditionally schedule the tid on
wakeup?

But maybe having an ieee80211_tx_peek() function would be useful in any
case? It seems that there's an internal data structure in mac80211
(struct txq_info) that keeps a byte count for that queue, so exporting
that would be trivial...

> I'm now working on figuring out the right way to fix my bug in the <=
> v2 patch where I fail to respect the hwq_max_pending values on the new
> transmit path, and I plan to post a v3 patch when I get that done.

What's the symptom of this? As I said I haven't noticed anything, but it
might be worth looking out for.

-Toke
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/RFT 2/5] ath9k: use mac80211 intermediate software queues

2016-06-06 Thread Dave Taht
For the record, michal's lastest patchset for the ath10k is here:

https://github.com/kazikcz/linux/tree/fqmac-v5

which includes the reworked codel.h support (which also landed in
net-next as of april 22) (no, haven't tried it yet, I'm only a day
back from vacation)

... but it would pay to leverage rate control more, for the ath9k, and
I'd like folk to agree on a standardized set of statistics in a std
location that can be polled for all implementations (ath9k, ath10k,
mt76)


I am also reviewing this:

http://info.iet.unipi.it/~luigi/papers/20160511-mysched-preprint.pdf

as we have a chance to innovate and use less locking with all this
stuff happening at the mac80211 layer.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/RFT 2/5] ath9k: use mac80211 intermediate software queues

2016-06-06 Thread Dave Taht
On Sun, Jun 5, 2016 at 10:50 PM, Tim Shepard  wrote:
>
>
>> > Thanks.  I've gotten no other feedback that suggests anyone else has
>> > read the code.  So I very much appreciate it.
>>
>> I not only read it but tested it extensively against the ath9k stock,
>> ath10k stock, ath10k -michal's fqmac 3.5 patches, and your ath9k
>> patches...
>
> My patch to ath9k shouldn't have any effect on any of the ath10k
> stuff.  It only cuts ath9k over to use the new intermediate queues.

Like the Sith, there are always at least two wifi chips on a link. One
behaving significantly differently (like flow queuing and codeling and
striving for airtime fairness) does affect the behavior of the other.

While I did do some ath9k to ath9k testing, I was mostly testing the
"whole enchalada". There are many, many moving parts left to swap out.

And the patchset I was testing included your fq_codel port for ath9k
but it was based on codel5.h. Michal's latest stuff reworked mainline
codel to be generically usable, and it *is* a different variant of the
algorithm.

The airtime-fair stuff does not as yet include fq_codel on top. It's a
MPU, and still puzzling as to why it did not get closer to perfect
fairness.

I also fiddled with the idea of dynamically altering the beacon's txop
sizes. A really short best effort  txop (94) was "Interesting". I need
to take apart how more beacons are constructed from non-linux vendors.

The whole enchalada is tasting pretty good thus far.

> I should point out again that Avery's observation that michal's
> mac80211 flow queueing patches and mac80211 codel stuff aren't needed
> to the improvement between competing client stations.

To *2* competing client stations, this is somewhat true at present.
There are at least 5 other (pending) factors to factor in.

* Toke's preliminary airtime-fair patches already showed a net gain in
bandwidth for the higher rate competing station. The "performance
anomaly", identified way back in 2003, is still with us without also
striving for airtime fairness.
* In order to hold latencies low with > 2 stations active, I advocate
gradually using shorter txops, which will improve behavior for
stations doing interactive tasks, and offering service sooner to
infrequently seen stations.
* In order to do gang scheduling for mu-mimo, we need to have several
2-3ms sized queues outstanding for the devices that can be mu-mimoed.
* Getting minstrel-blues in there to sample more dynamically would be nice
* Reducing retries and retransmits would be nice when already
congested. I'd also like to try QosNoack.


> All that's
> needed is to use the new mac80211 per-station per-tid intermediate
> queues and also set the IFF_NO_QUEUE bit.

It's a heckofastart.

>
> For ath9k, Felix's mac80211 interemediate queues patch (already in
> mainline Linux over a year ago), my patch to ath9k, and just
> Michal's first patch alone "[PATCHv3 1/5] mac80211: skip netdev
> queue control with software queuing" should (and seems to in
> testing I've done so far) get all the latency improvement there is
> to be had when the competing traffic is to a different client
> station.

I think it can be shaved from the presently observed 7-12ms minimum at
160mbit by another 2-3x. Also the codel implementation is not as yet
as tightly controlling queue size as I'd like - I haven't pushed it as
hard at sub 20mbit performance as I'd like (coping with being enraged
at networkmanager's over-use of channel scans was what I was at, last)
but I'm showing queue depth of well over 25ms at that rate right now
on the ath9k patch.

>
>
>
>> After losing my temper at the impact of channel scans...
>>
>> ( https://plus.google.com/u/0/107942175615993706558/posts/WA915Pt4SRN
>> ), I got told how to get rid of them for testing, and started redoing
>> the work when I got back from vacation.
>
> Heh... I've never seen that problem.  But I'm not running
> network-manager on any machine in my testbed.

I tend to think it is important to measure what happens in the real
world, to clearly identify what the real world problems actually are.

I let everybody else, with attenuators, and emulators, do whatever
they want. Me, I'm perpetually setting up real-world labs like the
yurtlab and sflab and the isclab to try to see what happens in
practice.

I now plan to put some work in on making channel scans less nasty and
to also look into what it takes to implement  802.11k, 802.11r and
802.11v.

or at the very least, nag people to get it more right.

https://bugzilla.gnome.org/show_bug.cgi?id=766482

NetworkManager's author suggests here that

https://blogs.gnome.org/dcbw/2016/05/16/networkmanager-and-wifi-scans/

"You can also advocate that your favorite WiFi interface add support
for NetworkManager’s RequestScan()"

>
>> > I looked for a way to ask mac80211 if there are any packets left in
>> > the intermediate queue without dequeueing a packet and I failed to
>> > find such an interface.
>>
>> qdisc->peek like function? 

Re: [RFC/RFT 2/5] ath9k: use mac80211 intermediate software queues

2016-06-05 Thread Tim Shepard


> > Thanks.  I've gotten no other feedback that suggests anyone else has
> > read the code.  So I very much appreciate it.
> 
> I not only read it but tested it extensively against the ath9k stock,
> ath10k stock, ath10k -michal's fqmac 3.5 patches, and your ath9k
> patches...

My patch to ath9k shouldn't have any effect on any of the ath10k
stuff.  It only cuts ath9k over to use the new intermediate queues.

I should point out again that Avery's observation that michal's
mac80211 flow queueing patches and mac80211 codel stuff aren't needed
to the improvement between competing client stations.  All that's
needed is to use the new mac80211 per-station per-tid intermediate
queues and also set the IFF_NO_QUEUE bit.

For ath9k, Felix's mac80211 interemediate queues patch (already in
mainline Linux over a year ago), my patch to ath9k, and just
Michal's first patch alone "[PATCHv3 1/5] mac80211: skip netdev
queue control with software queuing" should (and seems to in
testing I've done so far) get all the latency improvement there is
to be had when the competing traffic is to a different client
station.



> After losing my temper at the impact of channel scans...
> 
> ( https://plus.google.com/u/0/107942175615993706558/posts/WA915Pt4SRN
> ), I got told how to get rid of them for testing, and started redoing
> the work when I got back from vacation. 

Heh... I've never seen that problem.  But I'm not running
network-manager on any machine in my testbed.


> > I looked for a way to ask mac80211 if there are any packets left in
> > the intermediate queue without dequeueing a packet and I failed to
> > find such an interface.
> 
> qdisc->peek like function? A bitmap that says these stations have data
> outstanding?
> 

I'm not sure what you mean here.  Are you asking if that was what I
was looking for in the existing mac80211 code?  If so, yes, that is
what I was looking for.  Or are you suggesting (or agreeing) that
indeed such an interface should be added to mac80211?

Though I don't see how it could be a bitmap...  stations don't have
any obvious stable associated index into such a bitmap.

The real problem might be the way all the code in ath9k/xmit.c is
designed where it needs ath_tid_has_buffered() in so many places.

Look at the mt76 driver, and see how it also maintains a small
(probably only at most one packet ever) queue "retry_q" which
sometimes does hold a packet which will get sent before it will
pull another packet from ieee80211_tx_dequeue.  But the rest of the
driver is structured so that a NULL return from mt76_txq_dequeue()
is all it needs.  That's probably the sort of structure we ought to
have in ath9k, but that's going to be a more invasive patch to
ath9k (and I haven't figured out how to do it yet).

I think we can get there incrementally though.  I hope the patch for
ath9k that I've got now (and the one I hope to have soon that fixes
the problem of not making use of hwq_max_pending() ) might be useful
intermediate steps (that work, and provide improvements) then we can
clean up ath9k removing mechanisms that are no longer needed (breaking
the old transmit path, and somehow handling the chanctx stuff).


-Tim Shepard
 s...@alum.mit.edu
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/RFT 2/5] ath9k: use mac80211 intermediate software queues

2016-06-05 Thread Tim Shepard


> > Huh.  I wonder why you did that?  Is it really better to call the
> > ieee80211_txq a swq and call the ath9k hardware queue a txq?  I
> > thought doing the renaming made for more readable and much more
> > maintainable code (where searching for text strings produced much
> > cleaner results when trying to track down all references).
> 
> Well, the immediate reason was that at the time I just spent two weeks
> figuring out how ath9k worked and what the different concepts were, and
> suddenly they start to mean something different. The txq->hwq renaming
> would probably make sense in itself, but suddenly the same variable
> (txq) meant something different, which was quite confusing. So I found
> it was easier to change your patch to not require the renaming.
> 
> A secondary reason was to keep the patch delta as small as possible. I'm
> definitely not the right person to make that call, but I found the
> global renaming somewhat intrusive.
> 

OK, makes sense.  But you left it called txq in mac80211.   So someone
reading the mac80211 code and ath9k at the same time (to understand
the whole stack) winds up with txq meaning different things, including
in places in ath9k where it has to reference a field in a structure
defined by mac80211's header files to point to one of its txqs.

> As for the first point, I think it would be easier if you did not call
> the mac80211 queues 'txq' but something else ('swq' like I did, perhaps;
> I also considered 'imq' for intermediate queue). This will at least make
> it clear at a glance that it is something different than 'txq' was
> previously.

I'm not the one who called them txq.  That was Felix's patch.
He also wrote the mt76 driver and in that driver txq consistently
means the mac80211 intermediate queue and not a driver internal queue
or a hardware queue.  So I was trying to converge ath9k to be more
like the one and only example I had of a driver that uses the
intermediate queue.


> > I am grateful to learn that someone has read my patched version of
> > ath9k at least enough to do this rework. Any comments on the actual
> > work?
> 
> Well, it seems to work well enough (haven't noticed the pending_frames
> issue, but on the other hand I haven't been looking very hard). However,
> it does fell like somewhat of a temporary solution. Having another
> intermediate queue in the driver (tid->i_q) and having a side-effect in
> ath_tid_has_buffered() seems a bit iffy to me. Wouldn't the 'right' way
> to do it be to have ath_tid_has_buffered() ask the mac layer if it has
> any frames queued, and then have ath_tx_get_tid_subframe() basically
> translate straight to a call to ieee80211_tx_dequeue() (taking into
> account the retry queue)? Not sure if that covers all code paths, but
> the current approach seems like it has one too many layers of queues?
> 
> Haven't given the above a lot of thought, but since you asked... :)

Thanks.  I've gotten no other feedback that suggests anyone else has
read the code.  So I very much appreciate it.

Yes, I didn't like that side effect either, but (at least for my first
attempt) wanted to leave the old transmit path working, in particular
because I couldn't see how to get all the chanctx stuff working right
without leaving the old driver-internal queues in place.  (I'm not
even sure what I would have to do to test the driver with
CONFIG_ATH9K_CHANNEL_CONTEXT turned on.  I did test that it compiles
without error when CONFIG_ATH9K_CHANNEL_CONTEXT=y before I released my
v2 patch, and I tried to understand it enough to avoid breaking
anything.  (My v1 patch broke compilation when
CONFIG_ATH9K_CHANNEL_CONTEXT=y as some robot notified me after I
posted it.)

I looked for a way to ask mac80211 if there are any packets left in
the intermediate queue without dequeueing a packet and I failed to
find such an interface.  I guess I should have submitted a patch to
add that to mac80211.  Or maybe there's a way to refactor the
aggregation code in ath9k so that it can cleanly work with the
existing ieee80211_tx_dequeue() without having to add another
interface to mac80211, but I didn't figure it out.  It would have been
a bigger patch to ath9k, and require more thinking when reading the
patch to see if it works (assuming pre-patch ath9k works).

My current approach was an attempt to get it working.  Yes, the code
looks like it has another layer of queues, but at run time there's
only one packet at a time on the internal queue that packets wind up
on from the mac80211 intermediate queue and by putting it on that
queue it can interface to the same code that pulls from that queue or
the previously existing queues (which the chanctx code seems to
require remain around without major surgery).

I thought about first patching ath9k to remove all the chanctx stuff
just to have a simpler starting point to work on, but I wouldn't
expect that patch to ever be accepted upstream (assuming that somebody
somewhere is getting useful stuff from the chanctx 

Re: [RFC/RFT 2/5] ath9k: use mac80211 intermediate software queues

2016-06-04 Thread Toke Høiland-Jørgensen
Tim Shepard  writes:

>> Reworked to not require the global variable renaming in ath9k.
>> 
>> Signed-off-by: Toke Høiland-Jørgensen 
>
> Huh.  I wonder why you did that?  Is it really better to call the
> ieee80211_txq a swq and call the ath9k hardware queue a txq?  I
> thought doing the renaming made for more readable and much more
> maintainable code (where searching for text strings produced much
> cleaner results when trying to track down all references).

Well, the immediate reason was that at the time I just spent two weeks
figuring out how ath9k worked and what the different concepts were, and
suddenly they start to mean something different. The txq->hwq renaming
would probably make sense in itself, but suddenly the same variable
(txq) meant something different, which was quite confusing. So I found
it was easier to change your patch to not require the renaming.

A secondary reason was to keep the patch delta as small as possible. I'm
definitely not the right person to make that call, but I found the
global renaming somewhat intrusive.

As for the first point, I think it would be easier if you did not call
the mac80211 queues 'txq' but something else ('swq' like I did, perhaps;
I also considered 'imq' for intermediate queue). This will at least make
it clear at a glance that it is something different than 'txq' was
previously.

> I am grateful to learn that someone has read my patched version of
> ath9k at least enough to do this rework. Any comments on the actual
> work?

Well, it seems to work well enough (haven't noticed the pending_frames
issue, but on the other hand I haven't been looking very hard). However,
it does fell like somewhat of a temporary solution. Having another
intermediate queue in the driver (tid->i_q) and having a side-effect in
ath_tid_has_buffered() seems a bit iffy to me. Wouldn't the 'right' way
to do it be to have ath_tid_has_buffered() ask the mac layer if it has
any frames queued, and then have ath_tx_get_tid_subframe() basically
translate straight to a call to ieee80211_tx_dequeue() (taking into
account the retry queue)? Not sure if that covers all code paths, but
the current approach seems like it has one too many layers of queues?

Haven't given the above a lot of thought, but since you asked... :)

-Toke
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/RFT 2/5] ath9k: use mac80211 intermediate software queues

2016-06-03 Thread Tim Shepard


> Reworked to not require the global variable renaming in ath9k.
> 
> Signed-off-by: Toke Høiland-Jørgensen 


Huh.  I wonder why you did that?  Is it really better to call the
ieee80211_txq a swq and call the ath9k hardware queue a txq?  I
thought doing the renaming made for more readable and much more
maintainable code (where searching for text strings produced much
cleaner results when trying to track down all references).


I am grateful to learn that someone has read my patched version of
ath9k at least enough to do this rework.   Any comments on the actual
work?

I've recently figured out that I botched something to do with flow
control from the mac80211 intermediate queue into the hwq.  With my v2
patch the ath9k xmit path via the intermediate queues fails to
increment hwq->pending_frames, making the hwq_max_pending values
(which are tweakble in the debug file system) inneffective.  I'm in
the process of fixing this flaw in my patch and hope to have that done
soon so I can post a v3 of my ath9k patch.


Now I'm wondering if there is some reason I should also rework it to
avoid the renaming, making it more like what you just posted.

Or was your effort to rework the patch to avoid the renaming just to
make things easier in the interim while we (some of us) are testing
this patch in various systems (with slightly different versions of
ath9k driver)?


-Tim Shepard
 s...@alum.mit.edu
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC/RFT 2/5] ath9k: use mac80211 intermediate software queues

2016-06-03 Thread Toke Høiland-Jørgensen
This patch leaves the code for ath9k's internal per-node per-tid
queues in place and just modifies the driver to also pull from
the new mac80211 intermediate software queues, and implements
the .wake_tx_queue method, which will cause mac80211 to deliver
packets to be sent via the new intermediate queue.

Signed-off-by: Tim Shepard 

Reworked to not require the global variable renaming in ath9k.

Signed-off-by: Toke Høiland-Jørgensen 
---
 drivers/net/wireless/ath/ath9k/ath9k.h |  16 +++-
 drivers/net/wireless/ath/ath9k/debug_sta.c |   7 +-
 drivers/net/wireless/ath/ath9k/init.c  |   1 +
 drivers/net/wireless/ath/ath9k/main.c  |   1 +
 drivers/net/wireless/ath/ath9k/xmit.c  | 119 +
 5 files changed, 125 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h 
b/drivers/net/wireless/ath/ath9k/ath9k.h
index 93b3793..caeae10 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -145,8 +145,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct 
ath_descdma *dd,
 #define BAW_WITHIN(_start, _bawsz, _seqno) \
_seqno) - (_start)) & 4095) < (_bawsz))
 
-#define ATH_AN_2_TID(_an, _tidno)  (&(_an)->tid[(_tidno)])
-
 #define IS_HT_RATE(rate)   (rate & 0x80)
 #define IS_CCK_RATE(rate)  ((rate >= 0x18) && (rate <= 0x1e))
 #define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf))
@@ -232,8 +230,10 @@ struct ath_buf {
 
 struct ath_atx_tid {
struct list_head list;
+   struct sk_buff_head i_q;
struct sk_buff_head buf_q;
struct sk_buff_head retry_q;
+   struct ieee80211_txq *swq;
struct ath_node *an;
struct ath_txq *txq;
unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
@@ -247,13 +247,13 @@ struct ath_atx_tid {
s8 bar_index;
bool active;
bool clear_ps_filter;
+   bool swq_nonempty;
 };
 
 struct ath_node {
struct ath_softc *sc;
struct ieee80211_sta *sta; /* station struct we're part of */
struct ieee80211_vif *vif; /* interface with which we're associated */
-   struct ath_atx_tid tid[IEEE80211_NUM_TIDS];
 
u16 maxampdu;
u8 mpdudensity;
@@ -271,6 +271,15 @@ struct ath_node {
struct list_head list;
 };
 
+static inline
+struct ath_atx_tid *ath_an_2_tid(struct ath_node *an, u8 tidno)
+{
+   struct ieee80211_sta *sta = an->sta;
+   struct ieee80211_vif *vif = an->vif;
+   struct ieee80211_txq *swq = sta ? sta->txq[tidno] : vif->txq;
+   return (struct ath_atx_tid *) swq->drv_priv;
+}
+
 struct ath_tx_control {
struct ath_txq *txq;
struct ath_node *an;
@@ -585,6 +594,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
   u16 tids, int nframes,
   enum ieee80211_frame_release_type reason,
   bool more_data);
+void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *swq);
 
 //
 /* VIFs */
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c 
b/drivers/net/wireless/ath/ath9k/debug_sta.c
index b66cfa9..0e7f6b5 100644
--- a/drivers/net/wireless/ath/ath9k/debug_sta.c
+++ b/drivers/net/wireless/ath/ath9k/debug_sta.c
@@ -25,6 +25,7 @@ static ssize_t read_file_node_aggr(struct file *file, char 
__user *user_buf,
 {
struct ath_node *an = file->private_data;
struct ath_softc *sc = an->sc;
+   struct ieee80211_txq *swq;
struct ath_atx_tid *tid;
struct ath_txq *txq;
u32 len = 0, size = 4096;
@@ -52,8 +53,10 @@ static ssize_t read_file_node_aggr(struct file *file, char 
__user *user_buf,
 "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE",
 "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED");
 
-   for (tidno = 0, tid = >tid[tidno];
-tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
+   for (tidno = 0;
+tidno < IEEE80211_NUM_TIDS; tidno++) {
+   swq = an->sta->txq[tidno];
+   tid = (struct ath_atx_tid *) swq->drv_priv;
txq = tid->txq;
ath_txq_lock(sc, txq);
if (tid->active) {
diff --git a/drivers/net/wireless/ath/ath9k/init.c 
b/drivers/net/wireless/ath/ath9k/init.c
index 2ee8624..211736c 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -873,6 +873,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct 
ieee80211_hw *hw)
hw->max_rate_tries = 10;
hw->sta_data_size = sizeof(struct ath_node);
hw->vif_data_size = sizeof(struct ath_vif);
+   hw->txq_data_size = sizeof(struct ath_atx_tid);
hw->extra_tx_headroom = 4;
 
hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
diff --git a/drivers/net/wireless/ath/ath9k/main.c 
b/drivers/net/wireless/ath/ath9k/main.c
index 8b63988..6ab56e5