aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
diff options
context:
space:
mode:
authorNiklas Cassel <niklas.cassel@axis.com>2017-04-10 20:33:29 +0200
committerDavid S. Miller <davem@davemloft.net>2017-04-13 12:40:09 -0400
commitfe6af0e1229e2d22a798fb7375ff0e58670073d3 (patch)
tree11bb4aa27a8b74397f05f0cc07dfae0b718e524a /drivers/net/ethernet/stmicro/stmmac/ring_mode.c
parentcxgb4: save tid while creating server filter (diff)
downloadlinux-dev-fe6af0e1229e2d22a798fb7375ff0e58670073d3.tar.xz
linux-dev-fe6af0e1229e2d22a798fb7375ff0e58670073d3.zip
net: stmmac: set total length of the packet to be transmitted in TDES3
Field FL/TPL in register TDES3 is not correctly set on GMAC4. TX appears to be functional on GMAC 4.10a even if this field is not set, however, to avoid relying on undefined behavior, set the length in TDES3. The field has a different meaning depending on if the TSE bit in TDES3 is set or not (TSO). However, regardless of the TSE bit, the field is not optional. The field is already set correctly when the TSE bit is set. Since there is no limit for the number of descriptors that can be used for a single packet, the field should be set to the sum of the buffers contained in: [<desc with First Descriptor bit set> ... <desc n> ... <desc with Last Descriptor bit set>], which should be equal to skb->len. Signed-off-by: Niklas Cassel <niklas.cassel@axis.com> Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/ring_mode.c')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/ring_mode.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
index 31213e64513d..28e4b5d50ce6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
@@ -59,7 +59,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum,
- STMMAC_RING_MODE, 0, false);
+ STMMAC_RING_MODE, 0,
+ false, skb->len);
tx_q->tx_skbuff[entry] = NULL;
entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
@@ -79,7 +80,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
- STMMAC_RING_MODE, 1, true);
+ STMMAC_RING_MODE, 1,
+ true, skb->len);
} else {
des2 = dma_map_single(priv->device, skb->data,
nopaged_len, DMA_TO_DEVICE);
@@ -91,7 +93,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
tx_q->tx_skbuff_dma[entry].is_jumbo = true;
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum,
- STMMAC_RING_MODE, 0, true);
+ STMMAC_RING_MODE, 0,
+ true, skb->len);
}
tx_q->cur_tx = entry;