]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: ti: icssg-prueth: Make emac_run_xdp function independent of page
authorMeghana Malladi <m-malladi@ti.com>
Tue, 18 Nov 2025 13:55:40 +0000 (19:25 +0530)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 20 Nov 2025 14:24:11 +0000 (15:24 +0100)
emac_run_xdp function runs xdp program, at a given hook point
in the Rx path of the driver in NAPI context and returns
XDP return codes. In zero copy mode the driver receives
packets using UMEM frames instead of pages (native XDP).
Decouple the usage of page in this function.

Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Meghana Malladi <m-malladi@ti.com>
Link: https://patch.msgid.link/20251118135542.380574-5-m-malladi@ti.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/ti/icssg/icssg_common.c
drivers/net/ethernet/ti/icssg/icssg_prueth.c
drivers/net/ethernet/ti/icssg/icssg_prueth.h

index d7469ad457fd78de5e7d10b500e89ce6e415dbf4..b88cfe99e8b7f8f96ad14be288981bab593e19f0 100644 (file)
@@ -647,15 +647,15 @@ void emac_rx_timestamp(struct prueth_emac *emac,
  * emac_xmit_xdp_frame - transmits an XDP frame
  * @emac: emac device
  * @xdpf: data to transmit
- * @page: page from page pool if already DMA mapped
  * @q_idx: queue id
+ * @buff_type: Type of buffer to be transmitted
  *
  * Return: XDP state
  */
 u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
                        struct xdp_frame *xdpf,
-                       struct page *page,
-                       unsigned int q_idx)
+                       unsigned int q_idx,
+                       enum prueth_tx_buff_type buff_type)
 {
        struct cppi5_host_desc_t *first_desc;
        struct net_device *ndev = emac->ndev;
@@ -663,6 +663,7 @@ u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
        struct prueth_tx_chn *tx_chn;
        dma_addr_t desc_dma, buf_dma;
        struct prueth_swdata *swdata;
+       struct page *page;
        u32 *epib;
        int ret;
 
@@ -679,7 +680,12 @@ u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
                return ICSSG_XDP_CONSUMED;      /* drop */
        }
 
-       if (page) { /* already DMA mapped by page_pool */
+       if (buff_type == PRUETH_TX_BUFF_TYPE_XDP_TX) { /* already DMA mapped by page_pool */
+               page = virt_to_head_page(xdpf->data);
+               if (unlikely(!page)) {
+                       netdev_err(ndev, "xdp tx: failed to get page from xdpf\n");
+                       goto drop_free_descs;
+               }
                buf_dma = page_pool_get_dma_addr(page);
                buf_dma += xdpf->headroom + sizeof(struct xdp_frame);
        } else { /* Map the linear buffer */
@@ -734,13 +740,11 @@ EXPORT_SYMBOL_GPL(emac_xmit_xdp_frame);
  * emac_run_xdp - run an XDP program
  * @emac: emac device
  * @xdp: XDP buffer containing the frame
- * @page: page with RX data if already DMA mapped
  * @len: Rx descriptor packet length
  *
  * Return: XDP state
  */
-static u32 emac_run_xdp(struct prueth_emac *emac, struct xdp_buff *xdp,
-                       struct page *page, u32 *len)
+static u32 emac_run_xdp(struct prueth_emac *emac, struct xdp_buff *xdp, u32 *len)
 {
        struct net_device *ndev = emac->ndev;
        struct netdev_queue *netif_txq;
@@ -767,7 +771,8 @@ static u32 emac_run_xdp(struct prueth_emac *emac, struct xdp_buff *xdp,
                q_idx = cpu % emac->tx_ch_num;
                netif_txq = netdev_get_tx_queue(ndev, q_idx);
                __netif_tx_lock(netif_txq, cpu);
-               result = emac_xmit_xdp_frame(emac, xdpf, page, q_idx);
+               result = emac_xmit_xdp_frame(emac, xdpf, q_idx,
+                                            PRUETH_TX_BUFF_TYPE_XDP_TX);
                __netif_tx_unlock(netif_txq);
                if (result == ICSSG_XDP_CONSUMED) {
                        ndev->stats.tx_dropped++;
@@ -792,7 +797,8 @@ drop:
                fallthrough; /* handle aborts by dropping packet */
        case XDP_DROP:
                ndev->stats.rx_dropped++;
-               page_pool_recycle_direct(emac->rx_chns.pg_pool, page);
+               page_pool_recycle_direct(emac->rx_chns.pg_pool,
+                                        virt_to_head_page(xdp->data));
                return ICSSG_XDP_CONSUMED;
        }
 }
@@ -861,7 +867,7 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id, u32 *xdp_state)
                xdp_init_buff(&xdp, PAGE_SIZE, &rx_chn->xdp_rxq);
                xdp_prepare_buff(&xdp, pa, PRUETH_HEADROOM, pkt_len, false);
 
-               *xdp_state = emac_run_xdp(emac, &xdp, page, &pkt_len);
+               *xdp_state = emac_run_xdp(emac, &xdp, &pkt_len);
                if (*xdp_state != ICSSG_XDP_PASS)
                        goto requeue;
                headroom = xdp.data - xdp.data_hard_start;
index bdce5a40defeff87f86ff757cf7dbf1143355aff..bb8d42ba0102febeebedb433216b73278564f3eb 100644 (file)
@@ -1185,7 +1185,8 @@ static int emac_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frame
        __netif_tx_lock(netif_txq, cpu);
        for (i = 0; i < n; i++) {
                xdpf = frames[i];
-               err = emac_xmit_xdp_frame(emac, xdpf, NULL, q_idx);
+               err = emac_xmit_xdp_frame(emac, xdpf, q_idx,
+                                         PRUETH_TX_BUFF_TYPE_XDP_NDO);
                if (err != ICSSG_XDP_TX) {
                        ndev->stats.tx_dropped++;
                        break;
index 67339cdf2ddf4c4bbb95ad4abd9eee69dd2637bc..3147a1d8f59a95619b0e52a47c7d96e5e9d973f2 100644 (file)
@@ -154,6 +154,11 @@ enum prueth_swdata_type {
        PRUETH_SWDATA_XSK,
 };
 
+enum prueth_tx_buff_type {
+       PRUETH_TX_BUFF_TYPE_XDP_TX,
+       PRUETH_TX_BUFF_TYPE_XDP_NDO,
+};
+
 struct prueth_swdata {
        enum prueth_swdata_type type;
        union prueth_data {
@@ -506,8 +511,8 @@ void prueth_put_cores(struct prueth *prueth, int slice);
 u64 icssg_ts_to_ns(u32 hi_sw, u32 hi, u32 lo, u32 cycle_time_ns);
 u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
                        struct xdp_frame *xdpf,
-                       struct page *page,
-                       unsigned int q_idx);
+                       unsigned int q_idx,
+                       enum prueth_tx_buff_type buff_type);
 void prueth_rx_cleanup(void *data, dma_addr_t desc_dma);
 void prueth_tx_cleanup(void *data, dma_addr_t desc_dma);
 int prueth_xsk_wakeup(struct net_device *ndev, u32 qid, u32 flags);