Commit 9a4f4f3a authored by Madalin Bucur's avatar Madalin Bucur Committed by David S. Miller

dpaa_eth: avoid timestamp read on error paths

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>
parent c70fd318
...@@ -1571,13 +1571,15 @@ static int dpaa_eth_refill_bpools(struct dpaa_priv *priv) ...@@ -1571,13 +1571,15 @@ static int dpaa_eth_refill_bpools(struct dpaa_priv *priv)
* Skb freeing is not handled here. * Skb freeing is not handled here.
* *
* This function may be called on error paths in the Tx function, so guard * 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 * Return the skb backpointer, since for S/G frames the buffer containing it
* gets freed here. * gets freed here.
*/ */
static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv, 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; const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
struct device *dev = priv->net_dev->dev.parent; struct device *dev = priv->net_dev->dev.parent;
...@@ -1619,7 +1621,8 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv, ...@@ -1619,7 +1621,8 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv,
} }
/* DMA unmapping is required before accessing the HW provided info */ /* 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)); memset(&shhwtstamps, 0, sizeof(shhwtstamps));
if (!fman_port_get_tstamp(priv->mac_dev->port[TX], (void *)skbh, if (!fman_port_get_tstamp(priv->mac_dev->port[TX], (void *)skbh,
...@@ -2085,7 +2088,7 @@ dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev) ...@@ -2085,7 +2088,7 @@ dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
if (likely(dpaa_xmit(priv, percpu_stats, queue_mapping, &fd) == 0)) if (likely(dpaa_xmit(priv, percpu_stats, queue_mapping, &fd) == 0))
return NETDEV_TX_OK; return NETDEV_TX_OK;
dpaa_cleanup_tx_fd(priv, &fd); dpaa_cleanup_tx_fd(priv, &fd, false);
skb_to_fd_failed: skb_to_fd_failed:
enomem: enomem:
percpu_stats->tx_errors++; percpu_stats->tx_errors++;
...@@ -2131,7 +2134,7 @@ static void dpaa_tx_error(struct net_device *net_dev, ...@@ -2131,7 +2134,7 @@ static void dpaa_tx_error(struct net_device *net_dev,
percpu_priv->stats.tx_errors++; percpu_priv->stats.tx_errors++;
skb = dpaa_cleanup_tx_fd(priv, fd); skb = dpaa_cleanup_tx_fd(priv, fd, false);
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
...@@ -2171,7 +2174,7 @@ static void dpaa_tx_conf(struct net_device *net_dev, ...@@ -2171,7 +2174,7 @@ static void dpaa_tx_conf(struct net_device *net_dev,
percpu_priv->tx_confirm++; percpu_priv->tx_confirm++;
skb = dpaa_cleanup_tx_fd(priv, fd); skb = dpaa_cleanup_tx_fd(priv, fd, true);
consume_skb(skb); consume_skb(skb);
} }
...@@ -2398,7 +2401,7 @@ static void egress_ern(struct qman_portal *portal, ...@@ -2398,7 +2401,7 @@ static void egress_ern(struct qman_portal *portal,
percpu_priv->stats.tx_fifo_errors++; percpu_priv->stats.tx_fifo_errors++;
count_ern(percpu_priv, msg); 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); 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