dpaa_eth: avoid timestamp read on error paths
authorMadalin Bucur <madalin.bucur@nxp.com>
Thu, 31 Oct 2019 14:37:50 +0000 (16:37 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 31 Oct 2019 19:13:33 +0000 (12:13 -0700)
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: 4664856e9ca2 ("dpaa_eth: add support for hardware timestamping")
Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c

index 4b0a1b0..085cf06 100644 (file)
@@ -1571,13 +1571,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;
@@ -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 */
-       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,
@@ -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))
                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++;
@@ -2131,7 +2134,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);
 }
 
@@ -2171,7 +2174,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);
 }
@@ -2398,7 +2401,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);
 }