summaryrefslogtreecommitdiffstats
path: root/sys/dev/ahci
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2011-08-02 02:46:03 +0000
committeradrian <adrian@FreeBSD.org>2011-08-02 02:46:03 +0000
commit3d2a0d5981d828f32f06a4056734a7790f3483f7 (patch)
tree8bfe5e97c2cb5efa59d8744865c9c9d2030132d8 /sys/dev/ahci
parent7aff360292f17cd71be6a06f2f027f1e6fe08f70 (diff)
downloadFreeBSD-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
OpenPOWER on IntegriCloud