Skip to content

Commit

Permalink
net: stmmac: clean all pending Tx buffers during suspend
Browse files Browse the repository at this point in the history
To ensure driver enters low power state without leaving behind Tx frame
that are in Tx DMA ring but not yet returned through Tx Done operation,
we introduce a function here to clean them.

Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com>
  • Loading branch information
elvinongbl authored and SevenQC committed May 18, 2020
1 parent 34f5730 commit c219880
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6271,6 +6271,37 @@ int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size)
return ret;
}

static void stmmac_clean_tx_queue(struct stmmac_priv *priv,
struct stmmac_tx_queue *tx_q)
{
u32 queue = tx_q->queue_index;
unsigned int entry;

entry = tx_q->dirty_tx;
while (entry != tx_q->cur_tx) {
/* Free all the Tx ring sk_buffs */
stmmac_free_tx_buffer(priv, queue, entry);

entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size);
}
tx_q->dirty_tx = entry;

/* reset BQL for queue */
netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
}

void stmmac_clean_all_tx_rings(struct stmmac_priv *priv)
{
u32 tx_count = priv->plat->tx_queues_to_use;
u32 queue;

for (queue = 0; queue < tx_count; queue++) {
struct stmmac_tx_queue *tx_q = get_tx_queue(priv, queue);

stmmac_clean_tx_queue(priv, tx_q);
}
}

/**
* stmmac_dvr_probe
* @device: device pointer
Expand Down Expand Up @@ -6764,6 +6795,8 @@ int stmmac_suspend(struct device *dev)
stmmac_fpe_set_enable(priv, priv->hw, ndev, false);
}

stmmac_clean_all_tx_rings(priv);

mutex_unlock(&priv->lock);

priv->speed = SPEED_UNKNOWN;
Expand Down

0 comments on commit c219880

Please sign in to comment.