xdp_init_buff(&ctx.xdp, buf_sz, &rx_q->xdp_rxq);
                        xdp_prepare_buff(&ctx.xdp, page_address(buf->page),
-                                        buf->page_offset, buf1_len, false);
+                                        buf->page_offset, buf1_len, true);
 
                        pre_len = ctx.xdp.data_end - ctx.xdp.data_hard_start -
                                  buf->page_offset;
+
+                       ctx.priv = priv;
+                       ctx.desc = p;
+                       ctx.ndesc = np;
+
                        skb = stmmac_xdp_run_prog(priv, &ctx.xdp);
                        /* Due xdp_adjust_tail: DMA sync for_device
                         * cover max len CPU touch
        }
 }
 
+static int stmmac_xdp_rx_timestamp(const struct xdp_md *_ctx, u64 *timestamp)
+{
+       const struct stmmac_xdp_buff *ctx = (void *)_ctx;
+       struct dma_desc *desc_contains_ts = ctx->desc;
+       struct stmmac_priv *priv = ctx->priv;
+       struct dma_desc *ndesc = ctx->ndesc;
+       struct dma_desc *desc = ctx->desc;
+       u64 ns = 0;
+
+       if (!priv->hwts_rx_en)
+               return -ENODATA;
+
+       /* For GMAC4, the valid timestamp is from CTX next desc. */
+       if (priv->plat->has_gmac4 || priv->plat->has_xgmac)
+               desc_contains_ts = ndesc;
+
+       /* Check if timestamp is available */
+       if (stmmac_get_rx_timestamp_status(priv, desc, ndesc, priv->adv_ts)) {
+               stmmac_get_timestamp(priv, desc_contains_ts, priv->adv_ts, &ns);
+               ns -= priv->plat->cdc_error_adj;
+               *timestamp = ns_to_ktime(ns);
+               return 0;
+       }
+
+       return -ENODATA;
+}
+
+static const struct xdp_metadata_ops stmmac_xdp_metadata_ops = {
+       .xmo_rx_timestamp               = stmmac_xdp_rx_timestamp,
+};
+
 /**
  * stmmac_dvr_probe
  * @device: device pointer
 
        ndev->netdev_ops = &stmmac_netdev_ops;
 
+       ndev->xdp_metadata_ops = &stmmac_xdp_metadata_ops;
+
        ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
                            NETIF_F_RXCSUM;
        ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |