diff options
author | Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> | 2013-05-12 07:43:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-05-22 15:08:35 -0400 |
commit | e0287c4ab87905dd4a2e45cf791f8e0a87fe602e (patch) | |
tree | edd55224fb599e71c7752c3df57e65b4dcffde81 /drivers/net/wireless/ath/wil6210/interrupt.c | |
parent | 98658095623109bdace46f21bece028c904fb900 (diff) |
wil6210: use NAPI
Introduce NAPI for Rx and Tx completion.
This fixes packet reordering that happens when Rx handled right in
the IRQ: netif_rx puts packet in 'percpu' queue, then network stack
fetches packets from 'percpu' queues for processing, with different
pattern of queue switching. As result, network stack see packets
in different order. This causes hard to understand TCP throughput
degradation in about 30min
Complete polling if only one packet was processed - this eliminates
empty polls that would be otherwise done at the end of each burst
Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/interrupt.c')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/interrupt.c | 23 |
1 files changed, 9 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index 5fe985cd3dfd..8205d3e4ab66 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c | |||
@@ -104,14 +104,14 @@ static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil) | |||
104 | clear_bit(wil_status_irqen, &wil->status); | 104 | clear_bit(wil_status_irqen, &wil->status); |
105 | } | 105 | } |
106 | 106 | ||
107 | static void wil6210_unmask_irq_tx(struct wil6210_priv *wil) | 107 | void wil6210_unmask_irq_tx(struct wil6210_priv *wil) |
108 | { | 108 | { |
109 | iowrite32(WIL6210_IMC_TX, wil->csr + | 109 | iowrite32(WIL6210_IMC_TX, wil->csr + |
110 | HOSTADDR(RGF_DMA_EP_TX_ICR) + | 110 | HOSTADDR(RGF_DMA_EP_TX_ICR) + |
111 | offsetof(struct RGF_ICR, IMC)); | 111 | offsetof(struct RGF_ICR, IMC)); |
112 | } | 112 | } |
113 | 113 | ||
114 | static void wil6210_unmask_irq_rx(struct wil6210_priv *wil) | 114 | void wil6210_unmask_irq_rx(struct wil6210_priv *wil) |
115 | { | 115 | { |
116 | iowrite32(WIL6210_IMC_RX, wil->csr + | 116 | iowrite32(WIL6210_IMC_RX, wil->csr + |
117 | HOSTADDR(RGF_DMA_EP_RX_ICR) + | 117 | HOSTADDR(RGF_DMA_EP_RX_ICR) + |
@@ -182,13 +182,14 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie) | |||
182 | if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) { | 182 | if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) { |
183 | wil_dbg_irq(wil, "RX done\n"); | 183 | wil_dbg_irq(wil, "RX done\n"); |
184 | isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; | 184 | isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; |
185 | wil_rx_handle(wil); | 185 | wil_dbg_txrx(wil, "NAPI schedule\n"); |
186 | napi_schedule(&wil->napi_rx); | ||
186 | } | 187 | } |
187 | 188 | ||
188 | if (isr) | 189 | if (isr) |
189 | wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); | 190 | wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); |
190 | 191 | ||
191 | wil6210_unmask_irq_rx(wil); | 192 | /* Rx IRQ will be enabled when NAPI processing finished */ |
192 | 193 | ||
193 | return IRQ_HANDLED; | 194 | return IRQ_HANDLED; |
194 | } | 195 | } |
@@ -211,23 +212,17 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie) | |||
211 | wil6210_mask_irq_tx(wil); | 212 | wil6210_mask_irq_tx(wil); |
212 | 213 | ||
213 | if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { | 214 | if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { |
214 | uint i; | ||
215 | wil_dbg_irq(wil, "TX done\n"); | 215 | wil_dbg_irq(wil, "TX done\n"); |
216 | napi_schedule(&wil->napi_tx); | ||
216 | isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; | 217 | isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; |
217 | for (i = 0; i < 24; i++) { | 218 | /* clear also all VRING interrupts */ |
218 | u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i); | 219 | isr &= ~(BIT(25) - 1UL); |
219 | if (isr & mask) { | ||
220 | isr &= ~mask; | ||
221 | wil_dbg_irq(wil, "TX done(%i)\n", i); | ||
222 | wil_tx_complete(wil, i); | ||
223 | } | ||
224 | } | ||
225 | } | 220 | } |
226 | 221 | ||
227 | if (isr) | 222 | if (isr) |
228 | wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); | 223 | wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); |
229 | 224 | ||
230 | wil6210_unmask_irq_tx(wil); | 225 | /* Tx IRQ will be enabled when NAPI processing finished */ |
231 | 226 | ||
232 | return IRQ_HANDLED; | 227 | return IRQ_HANDLED; |
233 | } | 228 | } |