Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6cdadd4d authored by Vladimir Kondratiev's avatar Vladimir Kondratiev Committed by John W. Linville
Browse files

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: default avatarVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f88f113a
Loading
Loading
Loading
Loading
+6 −5
Original line number Original line Diff line number Diff line
@@ -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->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
	*_d = *d;
	*_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,
	wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
			  (const void *)d, sizeof(*d), false);
			  (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);
	wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
	trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags);
	trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags);
	iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
	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;
	return 0;
 dma_error:
 dma_error: