aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2013-07-11 18:03:41 +0300
committerJohn W. Linville <linville@tuxdriver.com>2013-07-22 16:54:38 -0400
commit6cdadd4dc7621e47739a84548e70713e157fa850 (patch)
tree87a61bc13d0ccaad77fe2a21d6a25fbfe142de59 /drivers
parentwil6210: Introduce struct for sw context (diff)
downloadlinux-dev-6cdadd4dc7621e47739a84548e70713e157fa850.tar.xz
linux-dev-6cdadd4dc7621e47739a84548e70713e157fa850.zip
wil6210: fix subtle race in wil_tx_vring
Finish all SW context modifications prior to notifying hardware It used to be race condition: if HW finish Tx and issue Tx completion IRQ very fast, prior to SW context update in wil_tx_vring, Tx completion will mis-handle descriptor, as SW part will have no skb pointer stored. Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 44cdd2a3dff3..2a9d56a5fd0c 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -712,6 +712,12 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
*_d = *d;
+ /* hold reference to skb
+ * to prevent skb release before accounting
+ * in case of immediate "tx done"
+ */
+ vring->ctx[i].skb = skb_get(skb);
+
wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
(const void *)d, sizeof(*d), false);
@@ -720,11 +726,6 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags);
iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
- /* hold reference to skb
- * to prevent skb release before accounting
- * in case of immediate "tx done"
- */
- vring->ctx[i].skb = skb_get(skb);
return 0;
dma_error: