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

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
...@@ -94,6 +94,9 @@ struct stmmac_rx_buffer { ...@@ -94,6 +94,9 @@ struct stmmac_rx_buffer {
struct stmmac_xdp_buff { struct stmmac_xdp_buff {
struct xdp_buff xdp; struct xdp_buff xdp;
struct stmmac_priv *priv;
struct dma_desc *desc;
struct dma_desc *ndesc;
}; };
struct stmmac_rx_queue { struct stmmac_rx_queue {
......
...@@ -5313,10 +5313,15 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) ...@@ -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_init_buff(&ctx.xdp, buf_sz, &rx_q->xdp_rxq);
xdp_prepare_buff(&ctx.xdp, page_address(buf->page), 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 - pre_len = ctx.xdp.data_end - ctx.xdp.data_hard_start -
buf->page_offset; buf->page_offset;
ctx.priv = priv;
ctx.desc = p;
ctx.ndesc = np;
skb = stmmac_xdp_run_prog(priv, &ctx.xdp); skb = stmmac_xdp_run_prog(priv, &ctx.xdp);
/* Due xdp_adjust_tail: DMA sync for_device /* Due xdp_adjust_tail: DMA sync for_device
* cover max len CPU touch * cover max len CPU touch
...@@ -7060,6 +7065,37 @@ void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable) ...@@ -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 * stmmac_dvr_probe
* @device: device pointer * @device: device pointer
...@@ -7167,6 +7203,8 @@ int stmmac_dvr_probe(struct device *device, ...@@ -7167,6 +7203,8 @@ int stmmac_dvr_probe(struct device *device,
ndev->netdev_ops = &stmmac_netdev_ops; 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 | ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM; NETIF_F_RXCSUM;
ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT | ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment