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

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

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
Loading
Loading
Loading
Loading
+34 −30
Original line number Original line Diff line number Diff line
@@ -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)
	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)
	/* 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)


	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);