diff options
author | adrian <adrian@FreeBSD.org> | 2011-08-02 02:46:03 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2011-08-02 02:46:03 +0000 |
commit | 3d2a0d5981d828f32f06a4056734a7790f3483f7 (patch) | |
tree | 8bfe5e97c2cb5efa59d8744865c9c9d2030132d8 /sys/dev/ahci | |
parent | 7aff360292f17cd71be6a06f2f027f1e6fe08f70 (diff) | |
download | FreeBSD-src-3d2a0d5981d828f32f06a4056734a7790f3483f7.zip FreeBSD-src-3d2a0d5981d828f32f06a4056734a7790f3483f7.tar.gz |
Fix a corner case in RXEOL handling which was likely introduced by yours
truly.
Before 802.11n, the RX descriptor list would employ the "self-linked tail
descriptor" trick which linked the last descriptor back to itself.
This way, the RX engine would never hit the "end" of the list and stop
processing RX (and assert RXEOL) as it never hit a descriptor whose next
pointer was 0. It would just keep overwriting the last descriptor until
the software freed up some more RX descriptors and chained them onto the
end.
For 802.11n, this needs to stop as a self-linked RX descriptor tickles the
block-ack logic into ACK'ing whatever frames are received into that
self-linked descriptor - so in very busy periods, you could end up with
A-MPDU traffic that is ACKed but never received by the 802.11 stack.
This would cause some confusion as the ADDBA windows would suddenly
be out of sync.
So when that occured here, the last descriptor would be hit and the PCU
logic would stop. It would only start again when the RX descriptor list
was updated and the PCU RX engine was re-tickled. That wasn't being done,
so RXEOL would be continuously asserted and no RX would continue.
This patch introduces a new flag - sc->sc_kickpcu - which when set,
signals the RX task to kick the PCU after its processed whatever packets
it can. This way completed packets aren't discarded.
In case some other task gets called which resets the hardware, don't
update sc->sc_imask - instead, just update the hardware interrupt mask
directly and let either ath_rx_proc() or ath_reset() restore the imask
to its former setting.
Note: this bug was only triggered when doing a whole lot of frame snooping
with serial console IO in the RX task. This would defer interrupt processing
enough to cause an RX descriptor overflow. It doesn't happen in normal
conditions.
Approved by: re (kib, blanket)
Diffstat (limited to 'sys/dev/ahci')
0 files changed, 0 insertions, 0 deletions