summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/scanf.c
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2015-10-30 23:18:02 +0000
committeradrian <adrian@FreeBSD.org>2015-10-30 23:18:02 +0000
commit6b197b2c77057e98cb3dd200d6ec14fe5f95399b (patch)
tree1efb0937220a974480961499c85ad031790a47ae /lib/libc/stdio/scanf.c
parent1c25d2a7594ac721b82a0ed598f11ebd01b8adf9 (diff)
downloadFreeBSD-src-6b197b2c77057e98cb3dd200d6ec14fe5f95399b.zip
FreeBSD-src-6b197b2c77057e98cb3dd200d6ec14fe5f95399b.tar.gz
arge: attempt to close a transmit race by only enabling the descriptor at the end of setup.
This driver and the linux ag71xx driver both treat the transmit ring as a circular linked list of descriptors. There's no "end" pointer that is ever NULL - instead, it expects the MAC to hit a finished descriptor (ARGE_DESC_EMPTY) and stop. Now, since it's a circular buffer, we may end up with the hardware hitting the beginning of our multi-descriptor frame before we've finished setting it up. It then DMA's it in, starts sending it, and we finish writing out the new descriptor. The hardware may then write its completion for the next descriptor out; then we do, and when we next read it it'll show up as "not done" and transmit completion stops. This unfortunately manifests itself as the transmit queue always being active and a massive TX interrupt storm. We need to actively ACK packets back from the transmit engine and if we don't (eg because we think the transmit isn't finished but it is) then the unit will just keep generating interrupts. I hit this finally with the below testing setup. This fixed it for me. Strictly speaking I should put in a sync in between writing out all of the descriptors and writing out that final descriptor. Tested: * QCA9558 SoC (AP135 reference board) w/ arge1 + vlans acting as a router, and iperf -d (tcp, bidirectional traffic.) Obtained from: Linux OpenWRT (ag71xx_main.c.)
Diffstat (limited to 'lib/libc/stdio/scanf.c')
0 files changed, 0 insertions, 0 deletions
OpenPOWER on IntegriCloud