dpaa_eth: perform DMA unmapping before read
authorMadalin Bucur <madalin.bucur@nxp.com>
Thu, 31 Oct 2019 14:37:49 +0000 (16:37 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jan 2020 13:51:20 +0000 (14:51 +0100)
[ Upstream commit c70fd3182caef014e6c628b412f81aa57a3ef9e4 ]

DMA unmapping is required before accessing the HW provided timestamping
information.

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c

index 462bb8c..3cd62a7 100644 (file)
@@ -1620,18 +1620,6 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv,
        skbh = (struct sk_buff **)phys_to_virt(addr);
        skb = *skbh;
 
-       if (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,
-                                         &ns)) {
-                       shhwtstamps.hwtstamp = ns_to_ktime(ns);
-                       skb_tstamp_tx(skb, &shhwtstamps);
-               } else {
-                       dev_warn(dev, "fman_port_get_tstamp failed!\n");
-               }
-       }
-
        if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) {
                nr_frags = skb_shinfo(skb)->nr_frags;
                dma_unmap_single(dev, addr,
@@ -1654,14 +1642,28 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv,
                        dma_unmap_page(dev, qm_sg_addr(&sgt[i]),
                                       qm_sg_entry_get_len(&sgt[i]), dma_dir);
                }
-
-               /* Free the page frag that we allocated on Tx */
-               skb_free_frag(phys_to_virt(addr));
        } else {
                dma_unmap_single(dev, addr,
                                 skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
        }
 
+       /* DMA unmapping is required before accessing the HW provided info */
+       if (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,
+                                         &ns)) {
+                       shhwtstamps.hwtstamp = ns_to_ktime(ns);
+                       skb_tstamp_tx(skb, &shhwtstamps);
+               } else {
+                       dev_warn(dev, "fman_port_get_tstamp failed!\n");
+               }
+       }
+
+       if (qm_fd_get_format(fd) == qm_fd_sg)
+               /* Free the page frag that we allocated on Tx */
+               skb_free_frag(phys_to_virt(addr));
+
        return skb;
 }