OSDN Git Service

net: stmmac: add Rx HWTS metadata to XDP receive pkt
authorSong Yoong Siang <yoong.siang.song@intel.com>
Sat, 15 Apr 2023 06:45:02 +0000 (14:45 +0800)
committerJakub Kicinski <kuba@kernel.org>
Tue, 18 Apr 2023 01:57:26 +0000 (18:57 -0700)
Add receive hardware timestamp metadata support via kfunc to XDP receive
packets.

Suggested-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Song Yoong Siang <yoong.siang.song@intel.com>
Acked-by: Stanislav Fomichev <sdf@google.com>
Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index ac8ccf8..07ea5ab 100644 (file)
@@ -94,6 +94,9 @@ struct stmmac_rx_buffer {
 
 struct stmmac_xdp_buff {
        struct xdp_buff xdp;
+       struct stmmac_priv *priv;
+       struct dma_desc *desc;
+       struct dma_desc *ndesc;
 };
 
 struct stmmac_rx_queue {
index 10b9f89..2bfcc53 100644 (file)
@@ -5313,10 +5313,15 @@ read_again:
 
                        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
@@ -7060,6 +7065,37 @@ void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable)
        }
 }
 
+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
@@ -7167,6 +7203,8 @@ int stmmac_dvr_probe(struct device *device,
 
        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 |