aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/vt6655/device_main.c
diff options
context:
space:
mode:
authorMalcolm Priestley <tvboxspy@gmail.com>2014-12-21 12:56:34 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-01-12 19:49:47 -0800
commitb5745290af06a621aaddfd636bab4f08432d0492 (patch)
treecc99212cedea7b790504c2d9c9605082d5265fdf /drivers/staging/vt6655/device_main.c
parentstaging: vt6655: fix sparse warnings: incorrect argument type (diff)
downloadlinux-dev-b5745290af06a621aaddfd636bab4f08432d0492.tar.xz
linux-dev-b5745290af06a621aaddfd636bab4f08432d0492.zip
staging: vt6655: vnt_tx_packet Fix corrupted tx packets.
Move PSTxDesc->m_td1TD1 to inside spin locks. if m_td1TD1.byTCR has TCR_EDP and TCR_STP are set, the interrupt handler will try and complete the buffer before it is completed. Usually on the tail of a burst of tx packets. This results in a partially completed packet being transmitted or worse sitll dead lock when skb is freed by the interrupt handler. Set head_td->m_td1TD1.byTCR to 0 in first lock of vnt_tx_packet to stop interrupt handler completing the buffer. Move Set TSR1 & ReqCount in s_cbFillTxBufHead to the second lock. cbReqCount is carried to the second lock in pTDInfo->dwReqCount without the padding removed. Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/vt6655/device_main.c')
-rw-r--r--drivers/staging/vt6655/device_main.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index ce616f98b8cb..cd1a277d853b 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -1232,7 +1232,7 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
head_td = priv->apCurrTD[dma_idx];
- head_td->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
+ head_td->m_td1TD1.byTCR = 0;
head_td->pTDInfo->skb = skb;
@@ -1257,6 +1257,11 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
priv->bPWBitOn = false;
+ /* Set TSR1 & ReqCount in TxDescHead */
+ head_td->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
+ head_td->m_td1TD1.wReqCount =
+ cpu_to_le16((u16)head_td->pTDInfo->dwReqCount);
+
head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;
if (dma_idx == TYPE_AC0DMA)