Astrit Zhushi <a.zhushi <at> cs.ucl.ac.uk>
2014-10-24 16:12:04 GMT
I was wondering if someone can help me understand receiver buffer
management on the ath9k driver.
While running TCP experiments using an AP and a wireless node (both
running AR9380 mini PCI-e cards, with PCI-e adapter) I noticed that
TCP was invoking fast retransmit. At the transmitter, the retry
counters didn't show that the frame was dropped. In addition, looking
at the over the air captured traces (by a third party wireless node),
the receiver's card actually acknowledges the missing frame and the
traces show only one transmission of the missing frame.
Instrumenting the driver I noticed that the missing frames are being
dropped because the received frame descriptor ID didn't match that of
the Athero's vendor ID.
That is, AR_DescId=0 and MS(rxsp->ds_info, AR_DescId) != 0x168c (maybe
replace it with ATHEROS_VENDOR_ID?) condition on ar9003_mac.c fails.
So I started looking at the way the receive buffers are managed by the
ath9k driver. This is my understanding so far:
Before the the card can use the DMA allocated buffers (the pool of 512
buffers kept in rx.rxbuf, they are added to ATH9K_RX_QUEUE_LP (128
buffers) or ATH9K_RX_QUEUE_HP (16 buffers) FIFO queues) and then the
hardware is told about the address by calling ath9k_hw_addrxbuf_edma
function. After which point the hardware can make use of those
On a receive interrupt, the driver processes incoming buffers, calls
ath_edma_get_buffers, removes the buffer from rx_edma->rx_fifo
(__skb_unlink(skb, &rx_edma->rx_fifo). This buffer ends up being put
back to the rx.rxbuff pool.
I don't see any call informing the hardware that it shouldn't be using
that buffer. It could be that the equivalent of this is happening
somewhere in the code, but I am missing it?
The only place where the descriptor is memset to zero is when calling
ath_rx_edma_buf_link, before telling the hardware that it can use the
buffer. Now supposing that the card still thinks that it can use a
buffer, and memset(0) is called on the same buffer (because it is
being added back to the rx.rx_buf queue) wouldn't I end up receiving
frames where AR_DescId is 0?
I hope I was clear enough