Commit cef9d517 authored by Madalin Bucur's avatar Madalin Bucur Committed by Greg Kroah-Hartman

dpaa_eth: avoid timestamp read on error paths

[ Upstream commit 9a4f4f3a ]

The dpaa_cleanup_tx_fd() function is called by the frame transmit
confirmation callback but also on several error paths. This function
is reading the transmit timestamp value. Avoid reading an invalid
timestamp value on the error paths.

Fixes: 4664856e ("dpaa_eth: add support for hardware timestamping")
Signed-off-by: default avatarMadalin Bucur <madalin.bucur@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 5fdb1715
......@@ -1600,13 +1600,15 @@ static int dpaa_eth_refill_bpools(struct dpaa_priv *priv)
* Skb freeing is not handled here.
*
* This function may be called on error paths in the Tx function, so guard
* against cases when not all fd relevant fields were filled in.
* against cases when not all fd relevant fields were filled in. To avoid
* reading the invalid transmission timestamp for the error paths set ts to
* false.
*
* Return the skb backpointer, since for S/G frames the buffer containing it
* gets freed here.
*/
static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv,
const struct qm_fd *fd)
const struct qm_fd *fd, bool ts)
{
const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
struct device *dev = priv->net_dev->dev.parent;
......@@ -1648,7 +1650,8 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv,
}
/* DMA unmapping is required before accessing the HW provided info */
if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
if (ts && priv->tx_tstamp &&
skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
memset(&shhwtstamps, 0, sizeof(shhwtstamps));
if (!fman_port_get_tstamp(priv->mac_dev->port[TX], (void *)skbh,
......@@ -2118,7 +2121,7 @@ dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
if (likely(dpaa_xmit(priv, percpu_stats, queue_mapping, &fd) == 0))
return NETDEV_TX_OK;
dpaa_cleanup_tx_fd(priv, &fd);
dpaa_cleanup_tx_fd(priv, &fd, false);
skb_to_fd_failed:
enomem:
percpu_stats->tx_errors++;
......@@ -2164,7 +2167,7 @@ static void dpaa_tx_error(struct net_device *net_dev,
percpu_priv->stats.tx_errors++;
skb = dpaa_cleanup_tx_fd(priv, fd);
skb = dpaa_cleanup_tx_fd(priv, fd, false);
dev_kfree_skb(skb);
}
......@@ -2205,7 +2208,7 @@ static void dpaa_tx_conf(struct net_device *net_dev,
percpu_priv->tx_confirm++;
skb = dpaa_cleanup_tx_fd(priv, fd);
skb = dpaa_cleanup_tx_fd(priv, fd, true);
consume_skb(skb);
}
......@@ -2435,7 +2438,7 @@ static void egress_ern(struct qman_portal *portal,
percpu_priv->stats.tx_fifo_errors++;
count_ern(percpu_priv, msg);
skb = dpaa_cleanup_tx_fd(priv, fd);
skb = dpaa_cleanup_tx_fd(priv, fd, false);
dev_kfree_skb_any(skb);
}
......
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