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.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 32 ++++++++++++++------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index ee267918aa70..c3f19485739b 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -1591,18 +1591,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(priv->tx_dma_dev, addr,
@@ -1625,14 +1613,28 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct 
dpaa_priv *priv,
                        dma_unmap_page(priv->tx_dma_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(priv->tx_dma_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;
 }
 
-- 
2.1.0

Reply via email to