Commit b5745290 authored by Malcolm Priestley's avatar Malcolm Priestley Committed by Greg Kroah-Hartman

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: default avatarMalcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 84c00afe
...@@ -1232,7 +1232,7 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) ...@@ -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 = priv->apCurrTD[dma_idx];
head_td->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); head_td->m_td1TD1.byTCR = 0;
head_td->pTDInfo->skb = skb; head_td->pTDInfo->skb = skb;
...@@ -1257,6 +1257,11 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) ...@@ -1257,6 +1257,11 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
priv->bPWBitOn = false; 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; head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;
if (dma_idx == TYPE_AC0DMA) if (dma_idx == TYPE_AC0DMA)
......
...@@ -1204,13 +1204,10 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, ...@@ -1204,13 +1204,10 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
ptdCurr = (PSTxDesc)pHeadTD; ptdCurr = (PSTxDesc)pHeadTD;
ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; ptdCurr->pTDInfo->dwReqCount = cbReqCount;
ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
/* Set TSR1 & ReqCount in TxDescHead */
ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
return cbHeaderLength; return cbHeaderLength;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment