Commit 7df4a3a7 authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller

net: stmmac: Fix the TX IOC in xmit path

IOC bit must be only set in the last descriptor. Move the logic up a
little bit to make sure it's set in the correct descriptor.
Signed-off-by: default avatarJose Abreu <Jose.Abreu@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b2f07199
...@@ -3024,6 +3024,19 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3024,6 +3024,19 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
/* Only the last descriptor gets to point to the skb. */ /* Only the last descriptor gets to point to the skb. */
tx_q->tx_skbuff[tx_q->cur_tx] = skb; tx_q->tx_skbuff[tx_q->cur_tx] = skb;
/* Manage tx mitigation */
tx_q->tx_count_frames += nfrags + 1;
if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
!((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
priv->hwts_tx_en)) {
stmmac_tx_timer_arm(priv, queue);
} else {
desc = &tx_q->dma_tx[tx_q->cur_tx];
tx_q->tx_count_frames = 0;
stmmac_set_tx_ic(priv, desc);
priv->xstats.tx_set_ic_bit++;
}
/* We've used all descriptors we need for this skb, however, /* We've used all descriptors we need for this skb, however,
* advance cur_tx so that it references a fresh descriptor. * advance cur_tx so that it references a fresh descriptor.
* ndo_start_xmit will fill this descriptor the next time it's * ndo_start_xmit will fill this descriptor the next time it's
...@@ -3041,19 +3054,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3041,19 +3054,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
priv->xstats.tx_tso_frames++; priv->xstats.tx_tso_frames++;
priv->xstats.tx_tso_nfrags += nfrags; priv->xstats.tx_tso_nfrags += nfrags;
/* Manage tx mitigation */
tx_q->tx_count_frames += nfrags + 1;
if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
!(priv->synopsys_id >= DWMAC_CORE_4_00 &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
priv->hwts_tx_en)) {
stmmac_tx_timer_arm(priv, queue);
} else {
tx_q->tx_count_frames = 0;
stmmac_set_tx_ic(priv, desc);
priv->xstats.tx_set_ic_bit++;
}
if (priv->sarc_type) if (priv->sarc_type)
stmmac_set_desc_sarc(priv, first, priv->sarc_type); stmmac_set_desc_sarc(priv, first, priv->sarc_type);
...@@ -3225,6 +3225,27 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3225,6 +3225,27 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
/* Only the last descriptor gets to point to the skb. */ /* Only the last descriptor gets to point to the skb. */
tx_q->tx_skbuff[entry] = skb; tx_q->tx_skbuff[entry] = skb;
/* According to the coalesce parameter the IC bit for the latest
* segment is reset and the timer re-started to clean the tx status.
* This approach takes care about the fragments: desc is the first
* element in case of no SG.
*/
tx_q->tx_count_frames += nfrags + 1;
if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
!((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
priv->hwts_tx_en)) {
stmmac_tx_timer_arm(priv, queue);
} else {
if (likely(priv->extend_desc))
desc = &tx_q->dma_etx[entry].basic;
else
desc = &tx_q->dma_tx[entry];
tx_q->tx_count_frames = 0;
stmmac_set_tx_ic(priv, desc);
priv->xstats.tx_set_ic_bit++;
}
/* We've used all descriptors we need for this skb, however, /* We've used all descriptors we need for this skb, however,
* advance cur_tx so that it references a fresh descriptor. * advance cur_tx so that it references a fresh descriptor.
* ndo_start_xmit will fill this descriptor the next time it's * ndo_start_xmit will fill this descriptor the next time it's
...@@ -3260,23 +3281,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3260,23 +3281,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_bytes += skb->len; dev->stats.tx_bytes += skb->len;
/* According to the coalesce parameter the IC bit for the latest
* segment is reset and the timer re-started to clean the tx status.
* This approach takes care about the fragments: desc is the first
* element in case of no SG.
*/
tx_q->tx_count_frames += nfrags + 1;
if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
!(priv->synopsys_id >= DWMAC_CORE_4_00 &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
priv->hwts_tx_en)) {
stmmac_tx_timer_arm(priv, queue);
} else {
tx_q->tx_count_frames = 0;
stmmac_set_tx_ic(priv, desc);
priv->xstats.tx_set_ic_bit++;
}
if (priv->sarc_type) if (priv->sarc_type)
stmmac_set_desc_sarc(priv, first, priv->sarc_type); stmmac_set_desc_sarc(priv, first, priv->sarc_type);
......
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