Commit e3f9c3e3 authored by Song Yoong Siang's avatar Song Yoong Siang Committed by Jakub Kicinski
Browse files

net: stmmac: add Rx HWTS metadata to XDP receive pkt



Add receive hardware timestamp metadata support via kfunc to XDP receive
packets.

Suggested-by: default avatarStanislav Fomichev <sdf@google.com>
Signed-off-by: default avatarSong Yoong Siang <yoong.siang.song@intel.com>
Acked-by: default avatarStanislav Fomichev <sdf@google.com>
Acked-by: default avatarJesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 5b24324a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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 {
+39 −1
Original line number Diff line number Diff line
@@ -5313,10 +5313,15 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)

			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 |