struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
        int i;
 
+       /* struct stmmac_xdp_buff is using cb field (maximum size of 24 bytes)
+        * in struct xdp_buff_xsk to stash driver specific information. Thus,
+        * use this macro to make sure no size violations.
+        */
+       XSK_CHECK_PRIV_TYPE(struct stmmac_xdp_buff);
+
        for (i = 0; i < dma_conf->dma_rx_size; i++) {
                struct stmmac_rx_buffer *buf;
                dma_addr_t dma_addr;
        return ret;
 }
 
+static struct stmmac_xdp_buff *xsk_buff_to_stmmac_ctx(struct xdp_buff *xdp)
+{
+       /* In XDP zero copy data path, xdp field in struct xdp_buff_xsk is used
+        * to represent incoming packet, whereas cb field in the same structure
+        * is used to store driver specific info. Thus, struct stmmac_xdp_buff
+        * is laid on top of xdp and cb fields of struct xdp_buff_xsk.
+        */
+       return (struct stmmac_xdp_buff *)xdp;
+}
+
 static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
 {
        struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
        }
        while (count < limit) {
                struct stmmac_rx_buffer *buf;
+               struct stmmac_xdp_buff *ctx;
                unsigned int buf1_len = 0;
                struct dma_desc *np, *p;
                int entry;
                        goto read_again;
                }
 
+               ctx = xsk_buff_to_stmmac_ctx(buf->xdp);
+               ctx->priv = priv;
+               ctx->desc = p;
+               ctx->ndesc = np;
+
                /* XDP ZC Frame only support primary buffers for now */
                buf1_len = stmmac_rx_buf1_len(priv, p, status, len);
                len += buf1_len;