From nobody Sun Feb 8 02:08:24 2026 Received: from fllvem-ot03.ext.ti.com (fllvem-ot03.ext.ti.com [198.47.19.245]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2AE42205ACB; Wed, 5 Mar 2025 10:15:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.245 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741169714; cv=none; b=I9c84PiD8Kl9SGhahylmwafMkK6pkEXrNQCweZBVPZIoyMbMsGKG8IQM61D3k40Ye3mvoE8QeNLTPbZSpKNnk7iL5nx/jibqvkQ9XyKDFsE/tJWOLt+t2p2QtbOyHGEP2PJJfJ9JIB/VHYVJni9jdmeEEANw4w4xCW5oY5O2LfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741169714; c=relaxed/simple; bh=JdsijZu1EfVvvNIS1D9odn18sDPAashGiVVdxuRv4Ww=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DkXuSlO5SLlBuD7TTj3IRyIb94GTarwcBg1xjh3Drmd+ztgNlX//bXL8eaAA9IQHryEVdPWz/XT7pyl4bP8ED++WeDEvRZXIi3OJnVQNfk1fZBObwzOwUCkOuFsl0SHPL9wv53TFN/9CpTI7Yot8/Qf6mVksbiW8F81WEUyCwM0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=JreROxho; arc=none smtp.client-ip=198.47.19.245 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="JreROxho" Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllvem-ot03.ext.ti.com (8.15.2/8.15.2) with ESMTPS id 525AEUSU3282302 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 5 Mar 2025 04:14:30 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1741169670; bh=SXrxm4giKxEyAMhzZdzR0r0C/bgsOLVqYh/xhsQVV4M=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=JreROxhovoqm43MfyTa2kusu8DrxJpaOrpimplrVuDwaSMm/hCcTsaAzBF0JnLN6I Q4g1C2H3gD85P436FV0EH0HDC0FOuRwDbSX8adxXtVvDEyCbOFNO0UydMVSGkzT09B Przwrtwe7ThUdAs10Did/lnVjizViIWR1dtq6ynI= Received: from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 525AEUw1085819 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 5 Mar 2025 04:14:30 -0600 Received: from DFLE111.ent.ti.com (10.64.6.32) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Wed, 5 Mar 2025 04:14:30 -0600 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DFLE111.ent.ti.com (10.64.6.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Wed, 5 Mar 2025 04:14:30 -0600 Received: from lelv0854.itg.ti.com (lelv0854.itg.ti.com [10.181.64.140]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 525AEUcI101108; Wed, 5 Mar 2025 04:14:30 -0600 Received: from localhost (meghana-pc.dhcp.ti.com [10.24.69.13] (may be forged)) by lelv0854.itg.ti.com (8.14.7/8.14.7) with ESMTP id 525AETnR005827; Wed, 5 Mar 2025 04:14:29 -0600 From: Meghana Malladi To: , , , , , , CC: , , , , , , , , , , , , , , , , , , Vignesh Raghavendra Subject: [PATCH net-next v4 1/3] net: ti: icssg-prueth: Use page_pool API for RX buffer allocation Date: Wed, 5 Mar 2025 15:44:20 +0530 Message-ID: <20250305101422.1908370-2-m-malladi@ti.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305101422.1908370-1-m-malladi@ti.com> References: <20250305101422.1908370-1-m-malladi@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" From: Roger Quadros This is to prepare for native XDP support. The page pool API is more faster in allocating pages than __alloc_skb(). Drawback is that it works at PAGE_SIZE granularity so we are not efficient in memory usage. i.e. we are using PAGE_SIZE (4KB) memory for 1.5KB max packet size. Signed-off-by: Roger Quadros Signed-off-by: MD Danish Anwar Signed-off-by: Meghana Malladi --- Changes from v3 (v4-v3): - Get rid of skb from Rx management code in SR1 as suggested by=20 Roger Quadros drivers/net/ethernet/ti/Kconfig | 1 + drivers/net/ethernet/ti/icssg/icssg_common.c | 174 ++++++++++++------ drivers/net/ethernet/ti/icssg/icssg_prueth.h | 14 +- .../net/ethernet/ti/icssg/icssg_prueth_sr1.c | 51 +++-- 4 files changed, 150 insertions(+), 90 deletions(-) diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kcon= fig index 3a13d60a947a..a07c910c497a 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@ -205,6 +205,7 @@ config TI_ICSSG_PRUETH_SR1 select PHYLIB select TI_ICSS_IEP select TI_K3_CPPI_DESC_POOL + select PAGE_POOL depends on PRU_REMOTEPROC depends on NET_SWITCHDEV depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/eth= ernet/ti/icssg/icssg_common.c index 74f0f200a89d..acbb79ad8b0c 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_common.c +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c @@ -45,6 +45,11 @@ void prueth_cleanup_rx_chns(struct prueth_emac *emac, struct prueth_rx_chn *rx_chn, int max_rflows) { + if (rx_chn->pg_pool) { + page_pool_destroy(rx_chn->pg_pool); + rx_chn->pg_pool =3D NULL; + } + if (rx_chn->desc_pool) k3_cppi_desc_pool_destroy(rx_chn->desc_pool); =20 @@ -461,17 +466,17 @@ int prueth_init_rx_chns(struct prueth_emac *emac, } EXPORT_SYMBOL_GPL(prueth_init_rx_chns); =20 -int prueth_dma_rx_push(struct prueth_emac *emac, - struct sk_buff *skb, - struct prueth_rx_chn *rx_chn) +int prueth_dma_rx_push_mapped(struct prueth_emac *emac, + struct prueth_rx_chn *rx_chn, + struct page *page, u32 buf_len) { struct net_device *ndev =3D emac->ndev; struct cppi5_host_desc_t *desc_rx; - u32 pkt_len =3D skb_tailroom(skb); dma_addr_t desc_dma; dma_addr_t buf_dma; void **swdata; =20 + buf_dma =3D page_pool_get_dma_addr(page) + PRUETH_HEADROOM; desc_rx =3D k3_cppi_desc_pool_alloc(rx_chn->desc_pool); if (!desc_rx) { netdev_err(ndev, "rx push: failed to allocate descriptor\n"); @@ -479,25 +484,18 @@ int prueth_dma_rx_push(struct prueth_emac *emac, } desc_dma =3D k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx); =20 - buf_dma =3D dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_= DEVICE); - if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) { - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - netdev_err(ndev, "rx push: failed to map rx pkt buffer\n"); - return -EINVAL; - } - cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT, PRUETH_NAV_PS_DATA_SIZE); k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma); - cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_= tailroom(skb)); + cppi5_hdesc_attach_buf(desc_rx, buf_dma, buf_len, buf_dma, buf_len); =20 swdata =3D cppi5_hdesc_get_swdata(desc_rx); - *swdata =3D skb; + *swdata =3D page; =20 - return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0, + return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, PRUETH_RX_FLOW_DATA, desc_rx, desc_dma); } -EXPORT_SYMBOL_GPL(prueth_dma_rx_push); +EXPORT_SYMBOL_GPL(prueth_dma_rx_push_mapped); =20 u64 icssg_ts_to_ns(u32 hi_sw, u32 hi, u32 lo, u32 cycle_time_ns) { @@ -541,12 +539,16 @@ static int emac_rx_packet(struct prueth_emac *emac, u= 32 flow_id) u32 buf_dma_len, pkt_len, port_id =3D 0; struct net_device *ndev =3D emac->ndev; struct cppi5_host_desc_t *desc_rx; - struct sk_buff *skb, *new_skb; dma_addr_t desc_dma, buf_dma; + struct page *page, *new_page; + struct page_pool *pool; + struct sk_buff *skb; void **swdata; u32 *psdata; + void *pa; int ret; =20 + pool =3D rx_chn->pg_pool; ret =3D k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); if (ret) { if (ret !=3D -ENODATA) @@ -558,15 +560,9 @@ static int emac_rx_packet(struct prueth_emac *emac, u3= 2 flow_id) return 0; =20 desc_rx =3D k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); - swdata =3D cppi5_hdesc_get_swdata(desc_rx); - skb =3D *swdata; - - psdata =3D cppi5_hdesc_get_psdata(desc_rx); - /* RX HW timestamp */ - if (emac->rx_ts_enabled) - emac_rx_timestamp(emac, skb, psdata); - + page =3D *swdata; + page_pool_dma_sync_for_cpu(pool, page, 0, PAGE_SIZE); cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); pkt_len =3D cppi5_hdesc_get_pktlen(desc_rx); @@ -574,32 +570,51 @@ static int emac_rx_packet(struct prueth_emac *emac, u= 32 flow_id) pkt_len -=3D 4; cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL); =20 - dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); =20 - skb->dev =3D ndev; - new_skb =3D netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE); /* if allocation fails we drop the packet but push the - * descriptor back to the ring with old skb to prevent a stall + * descriptor back to the ring with old page to prevent a stall */ - if (!new_skb) { + new_page =3D page_pool_dev_alloc_pages(pool); + if (unlikely(!new_page)) { + new_page =3D page; ndev->stats.rx_dropped++; - new_skb =3D skb; - } else { - /* send the filled skb up the n/w stack */ - skb_put(skb, pkt_len); - if (emac->prueth->is_switch_mode) - skb->offload_fwd_mark =3D emac->offload_fwd_mark; - skb->protocol =3D eth_type_trans(skb, ndev); - napi_gro_receive(&emac->napi_rx, skb); - ndev->stats.rx_bytes +=3D pkt_len; - ndev->stats.rx_packets++; + goto requeue; + } + + /* prepare skb and send to n/w stack */ + pa =3D page_address(page); + skb =3D napi_build_skb(pa, PAGE_SIZE); + if (!skb) { + ndev->stats.rx_dropped++; + page_pool_recycle_direct(pool, page); + goto requeue; } =20 + skb_reserve(skb, PRUETH_HEADROOM); + skb_put(skb, pkt_len); + skb->dev =3D ndev; + + psdata =3D cppi5_hdesc_get_psdata(desc_rx); + /* RX HW timestamp */ + if (emac->rx_ts_enabled) + emac_rx_timestamp(emac, skb, psdata); + + if (emac->prueth->is_switch_mode) + skb->offload_fwd_mark =3D emac->offload_fwd_mark; + skb->protocol =3D eth_type_trans(skb, ndev); + + skb_mark_for_recycle(skb); + napi_gro_receive(&emac->napi_rx, skb); + ndev->stats.rx_bytes +=3D pkt_len; + ndev->stats.rx_packets++; + +requeue: /* queue another RX DMA */ - ret =3D prueth_dma_rx_push(emac, new_skb, &emac->rx_chns); + ret =3D prueth_dma_rx_push_mapped(emac, &emac->rx_chns, new_page, + PRUETH_MAX_PKT_SIZE); if (WARN_ON(ret < 0)) { - dev_kfree_skb_any(new_skb); + page_pool_recycle_direct(pool, new_page); ndev->stats.rx_errors++; ndev->stats.rx_dropped++; } @@ -611,22 +626,16 @@ static void prueth_rx_cleanup(void *data, dma_addr_t = desc_dma) { struct prueth_rx_chn *rx_chn =3D data; struct cppi5_host_desc_t *desc_rx; - struct sk_buff *skb; - dma_addr_t buf_dma; - u32 buf_dma_len; + struct page_pool *pool; + struct page *page; void **swdata; =20 + pool =3D rx_chn->pg_pool; desc_rx =3D k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); swdata =3D cppi5_hdesc_get_swdata(desc_rx); - skb =3D *swdata; - cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); - k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); - - dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, - DMA_FROM_DEVICE); + page =3D *swdata; + page_pool_recycle_direct(pool, page); k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - - dev_kfree_skb_any(skb); } =20 static int prueth_tx_ts_cookie_get(struct prueth_emac *emac) @@ -907,29 +916,71 @@ int icssg_napi_rx_poll(struct napi_struct *napi_rx, i= nt budget) } EXPORT_SYMBOL_GPL(icssg_napi_rx_poll); =20 +static struct page_pool *prueth_create_page_pool(struct prueth_emac *emac, + struct device *dma_dev, + int size) +{ + struct page_pool_params pp_params =3D { 0 }; + struct page_pool *pool; + + pp_params.order =3D 0; + pp_params.flags =3D PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV; + pp_params.pool_size =3D size; + pp_params.nid =3D dev_to_node(emac->prueth->dev); + pp_params.dma_dir =3D DMA_BIDIRECTIONAL; + pp_params.dev =3D dma_dev; + pp_params.napi =3D &emac->napi_rx; + pp_params.max_len =3D PAGE_SIZE; + + pool =3D page_pool_create(&pp_params); + if (IS_ERR(pool)) + netdev_err(emac->ndev, "cannot create rx page pool\n"); + + return pool; +} + int prueth_prepare_rx_chan(struct prueth_emac *emac, struct prueth_rx_chn *chn, int buf_size) { - struct sk_buff *skb; + struct page_pool *pool; + struct page *page; int i, ret; =20 + pool =3D prueth_create_page_pool(emac, chn->dma_dev, chn->descs_num); + if (IS_ERR(pool)) + return PTR_ERR(pool); + + chn->pg_pool =3D pool; + for (i =3D 0; i < chn->descs_num; i++) { - skb =3D __netdev_alloc_skb_ip_align(NULL, buf_size, GFP_KERNEL); - if (!skb) - return -ENOMEM; + /* NOTE: we're not using memory efficiently here. + * 1 full page (4KB?) used here instead of + * PRUETH_MAX_PKT_SIZE (~1.5KB?) + */ + page =3D page_pool_dev_alloc_pages(pool); + if (!page) { + netdev_err(emac->ndev, "couldn't allocate rx page\n"); + ret =3D -ENOMEM; + goto recycle_alloc_pg; + } =20 - ret =3D prueth_dma_rx_push(emac, skb, chn); + ret =3D prueth_dma_rx_push_mapped(emac, chn, page, buf_size); if (ret < 0) { netdev_err(emac->ndev, - "cannot submit skb for rx chan %s ret %d\n", + "cannot submit page for rx chan %s ret %d\n", chn->name, ret); - kfree_skb(skb); - return ret; + page_pool_recycle_direct(pool, page); + goto recycle_alloc_pg; } } =20 return 0; + +recycle_alloc_pg: + prueth_reset_rx_chan(&emac->rx_chns, PRUETH_MAX_RX_FLOWS, false); + + return ret; } EXPORT_SYMBOL_GPL(prueth_prepare_rx_chan); =20 @@ -958,6 +1009,9 @@ void prueth_reset_rx_chan(struct prueth_rx_chn *chn, prueth_rx_cleanup, !!i); if (disable) k3_udma_glue_disable_rx_chn(chn->rx_chn); + + page_pool_destroy(chn->pg_pool); + chn->pg_pool =3D NULL; } EXPORT_SYMBOL_GPL(prueth_reset_rx_chan); =20 diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/eth= ernet/ti/icssg/icssg_prueth.h index 329b46e9ee53..c7b906de18af 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -33,6 +33,8 @@ #include =20 #include +#include +#include =20 #include "icssg_config.h" #include "icss_iep.h" @@ -131,6 +133,7 @@ struct prueth_rx_chn { u32 descs_num; unsigned int irq[ICSSG_MAX_RFLOWS]; /* separate irq per flow */ char name[32]; + struct page_pool *pg_pool; }; =20 /* There are 4 Tx DMA channels, but the highest priority is CH3 (thread 3) @@ -210,6 +213,10 @@ struct prueth_emac { struct netdev_hw_addr_list vlan_mcast_list[MAX_VLAN_ID]; }; =20 +/* The buf includes headroom compatible with both skb and xdpf */ +#define PRUETH_HEADROOM_NA (max(XDP_PACKET_HEADROOM, NET_SKB_PAD) + NET_IP= _ALIGN) +#define PRUETH_HEADROOM ALIGN(PRUETH_HEADROOM_NA, sizeof(long)) + /** * struct prueth_pdata - PRUeth platform data * @fdqring_mode: Free desc queue mode @@ -410,9 +417,10 @@ int prueth_init_rx_chns(struct prueth_emac *emac, struct prueth_rx_chn *rx_chn, char *name, u32 max_rflows, u32 max_desc_num); -int prueth_dma_rx_push(struct prueth_emac *emac, - struct sk_buff *skb, - struct prueth_rx_chn *rx_chn); +int prueth_dma_rx_push_mapped(struct prueth_emac *emac, + struct prueth_rx_chn *rx_chn, + struct page *page, u32 buf_len); +unsigned int prueth_rxbuf_total_len(unsigned int len); void emac_rx_timestamp(struct prueth_emac *emac, struct sk_buff *skb, u32 *psdata); enum netdev_tx icssg_ndo_start_xmit(struct sk_buff *skb, struct net_device= *ndev); diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c b/drivers/net= /ethernet/ti/icssg/icssg_prueth_sr1.c index 64a19ff39562..8f5719a98614 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c @@ -268,15 +268,15 @@ static int emac_phy_connect(struct prueth_emac *emac) * Returns skb pointer if packet found else NULL * Caller must free the returned skb. */ -static struct sk_buff *prueth_process_rx_mgm(struct prueth_emac *emac, - u32 flow_id) +static struct page *prueth_process_rx_mgm(struct prueth_emac *emac, + u32 flow_id) { struct prueth_rx_chn *rx_chn =3D &emac->rx_mgm_chn; struct net_device *ndev =3D emac->ndev; struct cppi5_host_desc_t *desc_rx; - struct sk_buff *skb, *new_skb; + struct page *page, *new_page; dma_addr_t desc_dma, buf_dma; - u32 buf_dma_len, pkt_len; + u32 buf_dma_len; void **swdata; int ret; =20 @@ -299,34 +299,31 @@ static struct sk_buff *prueth_process_rx_mgm(struct p= rueth_emac *emac, } =20 swdata =3D cppi5_hdesc_get_swdata(desc_rx); - skb =3D *swdata; + page =3D *swdata; cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); - pkt_len =3D cppi5_hdesc_get_pktlen(desc_rx); =20 dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); =20 - new_skb =3D netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE); + new_page =3D page_pool_dev_alloc_pages(rx_chn->pg_pool); /* if allocation fails we drop the packet but push the * descriptor back to the ring with old skb to prevent a stall */ - if (!new_skb) { + if (!new_page) { netdev_err(ndev, - "skb alloc failed, dropped mgm pkt from flow %d\n", + "page alloc failed, dropped mgm pkt from flow %d\n", flow_id); - new_skb =3D skb; - skb =3D NULL; /* return NULL */ - } else { - /* return the filled skb */ - skb_put(skb, pkt_len); + new_page =3D page; + page =3D NULL; /* return NULL */ } =20 /* queue another DMA */ - ret =3D prueth_dma_rx_push(emac, new_skb, &emac->rx_mgm_chn); + ret =3D prueth_dma_rx_push_mapped(emac, &emac->rx_chns, new_page, + PRUETH_MAX_PKT_SIZE); if (WARN_ON(ret < 0)) - dev_kfree_skb_any(new_skb); + page_pool_recycle_direct(rx_chn->pg_pool, new_page); =20 - return skb; + return page; } =20 static void prueth_tx_ts_sr1(struct prueth_emac *emac, @@ -362,14 +359,14 @@ static void prueth_tx_ts_sr1(struct prueth_emac *emac, static irqreturn_t prueth_rx_mgm_ts_thread_sr1(int irq, void *dev_id) { struct prueth_emac *emac =3D dev_id; - struct sk_buff *skb; + struct page *page; =20 - skb =3D prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_TIMESTAMP_SR1); - if (!skb) + page =3D prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_TIMESTAMP_SR1); + if (!page) return IRQ_NONE; =20 - prueth_tx_ts_sr1(emac, (void *)skb->data); - dev_kfree_skb_any(skb); + prueth_tx_ts_sr1(emac, (void *)page_address(page)); + page_pool_recycle_direct(page->pp, page); =20 return IRQ_HANDLED; } @@ -377,15 +374,15 @@ static irqreturn_t prueth_rx_mgm_ts_thread_sr1(int ir= q, void *dev_id) static irqreturn_t prueth_rx_mgm_rsp_thread(int irq, void *dev_id) { struct prueth_emac *emac =3D dev_id; - struct sk_buff *skb; + struct page *page; u32 rsp; =20 - skb =3D prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_RESPONSE_SR1); - if (!skb) + page =3D prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_RESPONSE_SR1); + if (!page) return IRQ_NONE; =20 /* Process command response */ - rsp =3D le32_to_cpu(*(__le32 *)skb->data) & 0xffff0000; + rsp =3D le32_to_cpu(*(__le32 *)page_address(page)) & 0xffff0000; if (rsp =3D=3D ICSSG_SHUTDOWN_CMD_SR1) { netdev_dbg(emac->ndev, "f/w Shutdown cmd resp %x\n", rsp); complete(&emac->cmd_complete); @@ -394,7 +391,7 @@ static irqreturn_t prueth_rx_mgm_rsp_thread(int irq, vo= id *dev_id) complete(&emac->cmd_complete); } =20 - dev_kfree_skb_any(skb); + page_pool_recycle_direct(page->pp, page); =20 return IRQ_HANDLED; } --=20 2.43.0 From nobody Sun Feb 8 02:08:24 2026 Received: from fllvem-ot03.ext.ti.com (fllvem-ot03.ext.ti.com [198.47.19.245]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5D5ED2063ED; Wed, 5 Mar 2025 10:15:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.245 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741169717; cv=none; b=n7vYkUELbybQG3xmuk6/W9udCWUnhFCqXod9aLFOZn4xWZN0l8LQScBdcSWe/EFAZZ7MUOFtmcDBAO8s1OUybiCNgQvZLojILm7Cbp5jS5PMIAwrhw66JEKtuIIuPcE8LF7a7DPcLxa3chQ1gGMPf//tvTzvuHlgyqvUJzu4DnI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741169717; c=relaxed/simple; bh=IYGeX6wCtPvsVRSGdW3NGvekk0z55XEcxkrzbrxzQaE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ejEhICdzjTcOUg34fDtZvDuE5eRDrbzMPylMrAJxksZx8UO9C0kChqqIFzhfXKrFX4i9zVet52WaBgqGaySggUJ+A2dJTFtJmPWu8hDiiKMCMWZBw32FWSLidsKkpDukQqcO+69GQXSZwCxXnyq6ASc3pS9cp1olFixxfjH9TzA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=fD/zMfzm; arc=none smtp.client-ip=198.47.19.245 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="fD/zMfzm" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllvem-ot03.ext.ti.com (8.15.2/8.15.2) with ESMTPS id 525AEXJD3282315 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 5 Mar 2025 04:14:33 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1741169673; bh=WKe8i56YW9+FKurGjSLcFKVh/d3KB3RrqZMs1az8ESg=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=fD/zMfzmSo5ULO8LQg7Pnq8m4sDPbrfcLvw8jCdgnRiEbCw/5x0anco2yrdINPgJ0 6ZMelgt6butc9NHZj2pZdcYISBvOsjgYTLzSeWGj1sCabPsiWJXbrl7mg8SyqosxSB 6z8PXh5Y+IluqlHhEDFGVTyA+rloCUVuYoVaWjTw= Received: from DFLE103.ent.ti.com (dfle103.ent.ti.com [10.64.6.24]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 525AEXpF005480 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 5 Mar 2025 04:14:33 -0600 Received: from DFLE105.ent.ti.com (10.64.6.26) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Wed, 5 Mar 2025 04:14:33 -0600 Received: from fllvsmtp8.itg.ti.com (10.64.41.158) by DFLE105.ent.ti.com (10.64.6.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Wed, 5 Mar 2025 04:14:32 -0600 Received: from lelv0854.itg.ti.com (lelv0854.itg.ti.com [10.181.64.140]) by fllvsmtp8.itg.ti.com (8.15.2/8.15.2) with ESMTP id 525AEWDp130413; Wed, 5 Mar 2025 04:14:32 -0600 Received: from localhost (meghana-pc.dhcp.ti.com [10.24.69.13] (may be forged)) by lelv0854.itg.ti.com (8.14.7/8.14.7) with ESMTP id 525AEWKw005834; Wed, 5 Mar 2025 04:14:32 -0600 From: Meghana Malladi To: , , , , , , CC: , , , , , , , , , , , , , , , , , , Vignesh Raghavendra Subject: [PATCH net-next v4 2/3] net: ti: icssg-prueth: introduce and use prueth_swdata struct for SWDATA Date: Wed, 5 Mar 2025 15:44:21 +0530 Message-ID: <20250305101422.1908370-3-m-malladi@ti.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305101422.1908370-1-m-malladi@ti.com> References: <20250305101422.1908370-1-m-malladi@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" From: Roger Quadros We have different cases for SWDATA (skb, page, cmd, etc) so it is better to have a dedicated data structure for that. We can embed the type field inside the struct and use it to interpret the data in completion handlers. Signed-off-by: Roger Quadros Signed-off-by: MD Danish Anwar Signed-off-by: Meghana Malladi --- Changes from v3 (v4-v3): - remove SWDATA size information from commit message - Fix handling of packets for non-skb type inside emac_tx_complete_packets() - Remove incrementing budget for incorrect swdata type - use PRUETH_SWDATA_CMD in emac_send_command_sr1() All the above changes are suggested by Roger Quadros and Dan Carpenter drivers/net/ethernet/ti/icssg/icssg_common.c | 52 +++++++++++-------- drivers/net/ethernet/ti/icssg/icssg_prueth.c | 3 ++ drivers/net/ethernet/ti/icssg/icssg_prueth.h | 16 ++++++ .../net/ethernet/ti/icssg/icssg_prueth_sr1.c | 9 ++-- 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/eth= ernet/ti/icssg/icssg_common.c index acbb79ad8b0c..fee1204db367 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_common.c +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c @@ -136,12 +136,12 @@ int emac_tx_complete_packets(struct prueth_emac *emac= , int chn, struct net_device *ndev =3D emac->ndev; struct cppi5_host_desc_t *desc_tx; struct netdev_queue *netif_txq; + struct prueth_swdata *swdata; struct prueth_tx_chn *tx_chn; unsigned int total_bytes =3D 0; struct sk_buff *skb; dma_addr_t desc_dma; int res, num_tx =3D 0; - void **swdata; =20 tx_chn =3D &emac->tx_chns[chn]; =20 @@ -161,16 +161,11 @@ int emac_tx_complete_packets(struct prueth_emac *emac= , int chn, desc_tx =3D k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); swdata =3D cppi5_hdesc_get_swdata(desc_tx); - - /* was this command's TX complete? */ - if (emac->is_sr1 && *(swdata) =3D=3D emac->cmd_data) { - prueth_xmit_free(tx_chn, desc_tx); - continue; - } - - skb =3D *(swdata); prueth_xmit_free(tx_chn, desc_tx); + if (swdata->type !=3D PRUETH_SWDATA_SKB) + continue; =20 + skb =3D swdata->data.skb; ndev =3D skb->dev; ndev->stats.tx_packets++; ndev->stats.tx_bytes +=3D skb->len; @@ -472,9 +467,9 @@ int prueth_dma_rx_push_mapped(struct prueth_emac *emac, { struct net_device *ndev =3D emac->ndev; struct cppi5_host_desc_t *desc_rx; + struct prueth_swdata *swdata; dma_addr_t desc_dma; dma_addr_t buf_dma; - void **swdata; =20 buf_dma =3D page_pool_get_dma_addr(page) + PRUETH_HEADROOM; desc_rx =3D k3_cppi_desc_pool_alloc(rx_chn->desc_pool); @@ -490,7 +485,8 @@ int prueth_dma_rx_push_mapped(struct prueth_emac *emac, cppi5_hdesc_attach_buf(desc_rx, buf_dma, buf_len, buf_dma, buf_len); =20 swdata =3D cppi5_hdesc_get_swdata(desc_rx); - *swdata =3D page; + swdata->type =3D PRUETH_SWDATA_PAGE; + swdata->data.page =3D page; =20 return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, PRUETH_RX_FLOW_DATA, desc_rx, desc_dma); @@ -539,11 +535,11 @@ static int emac_rx_packet(struct prueth_emac *emac, u= 32 flow_id) u32 buf_dma_len, pkt_len, port_id =3D 0; struct net_device *ndev =3D emac->ndev; struct cppi5_host_desc_t *desc_rx; + struct prueth_swdata *swdata; dma_addr_t desc_dma, buf_dma; struct page *page, *new_page; struct page_pool *pool; struct sk_buff *skb; - void **swdata; u32 *psdata; void *pa; int ret; @@ -561,7 +557,13 @@ static int emac_rx_packet(struct prueth_emac *emac, u3= 2 flow_id) =20 desc_rx =3D k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); swdata =3D cppi5_hdesc_get_swdata(desc_rx); - page =3D *swdata; + if (swdata->type !=3D PRUETH_SWDATA_PAGE) { + netdev_err(ndev, "rx_pkt: invalid swdata->type %d\n", swdata->type); + k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); + return 0; + } + + page =3D swdata->data.page; page_pool_dma_sync_for_cpu(pool, page, 0, PAGE_SIZE); cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); @@ -626,15 +628,18 @@ static void prueth_rx_cleanup(void *data, dma_addr_t = desc_dma) { struct prueth_rx_chn *rx_chn =3D data; struct cppi5_host_desc_t *desc_rx; + struct prueth_swdata *swdata; struct page_pool *pool; struct page *page; - void **swdata; =20 pool =3D rx_chn->pg_pool; desc_rx =3D k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); swdata =3D cppi5_hdesc_get_swdata(desc_rx); - page =3D *swdata; - page_pool_recycle_direct(pool, page); + if (swdata->type =3D=3D PRUETH_SWDATA_PAGE) { + page =3D swdata->data.page; + page_pool_recycle_direct(pool, page); + } + k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); } =20 @@ -671,13 +676,13 @@ enum netdev_tx icssg_ndo_start_xmit(struct sk_buff *s= kb, struct net_device *ndev struct prueth_emac *emac =3D netdev_priv(ndev); struct prueth *prueth =3D emac->prueth; struct netdev_queue *netif_txq; + struct prueth_swdata *swdata; struct prueth_tx_chn *tx_chn; dma_addr_t desc_dma, buf_dma; u32 pkt_len, dst_tag_id; int i, ret =3D 0, q_idx; bool in_tx_ts =3D 0; int tx_ts_cookie; - void **swdata; u32 *epib; =20 pkt_len =3D skb_headlen(skb); @@ -739,7 +744,8 @@ enum netdev_tx icssg_ndo_start_xmit(struct sk_buff *skb= , struct net_device *ndev k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma); cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); swdata =3D cppi5_hdesc_get_swdata(first_desc); - *swdata =3D skb; + swdata->type =3D PRUETH_SWDATA_SKB; + swdata->data.skb =3D skb; =20 /* Handle the case where skb is fragmented in pages */ cur_desc =3D first_desc; @@ -842,15 +848,17 @@ static void prueth_tx_cleanup(void *data, dma_addr_t = desc_dma) { struct prueth_tx_chn *tx_chn =3D data; struct cppi5_host_desc_t *desc_tx; + struct prueth_swdata *swdata; struct sk_buff *skb; - void **swdata; =20 desc_tx =3D k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); swdata =3D cppi5_hdesc_get_swdata(desc_tx); - skb =3D *(swdata); - prueth_xmit_free(tx_chn, desc_tx); + if (swdata->type =3D=3D PRUETH_SWDATA_SKB) { + skb =3D swdata->data.skb; + dev_kfree_skb_any(skb); + } =20 - dev_kfree_skb_any(skb); + prueth_xmit_free(tx_chn, desc_tx); } =20 irqreturn_t prueth_rx_irq(int irq, void *dev_id) diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/eth= ernet/ti/icssg/icssg_prueth.c index 00ed97860547..3ff8c322f9d9 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -1522,6 +1522,9 @@ static int prueth_probe(struct platform_device *pdev) =20 np =3D dev->of_node; =20 + BUILD_BUG_ON_MSG((sizeof(struct prueth_swdata) > PRUETH_NAV_SW_DATA_SIZE), + "insufficient SW_DATA size"); + prueth =3D devm_kzalloc(dev, sizeof(*prueth), GFP_KERNEL); if (!prueth) return -ENOMEM; diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/eth= ernet/ti/icssg/icssg_prueth.h index c7b906de18af..3bbabd007129 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -136,6 +136,22 @@ struct prueth_rx_chn { struct page_pool *pg_pool; }; =20 +enum prueth_swdata_type { + PRUETH_SWDATA_INVALID =3D 0, + PRUETH_SWDATA_SKB, + PRUETH_SWDATA_PAGE, + PRUETH_SWDATA_CMD, +}; + +struct prueth_swdata { + enum prueth_swdata_type type; + union prueth_data { + struct sk_buff *skb; + struct page *page; + u32 cmd; + } data; +}; + /* There are 4 Tx DMA channels, but the highest priority is CH3 (thread 3) * and lower three are lower priority channels or threads. */ diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c b/drivers/net= /ethernet/ti/icssg/icssg_prueth_sr1.c index 8f5719a98614..ff5f41bf499e 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c @@ -84,7 +84,7 @@ static int emac_send_command_sr1(struct prueth_emac *emac= , u32 cmd) __le32 *data =3D emac->cmd_data; dma_addr_t desc_dma, buf_dma; struct prueth_tx_chn *tx_chn; - void **swdata; + struct prueth_swdata *swdata; int ret =3D 0; u32 *epib; =20 @@ -122,7 +122,8 @@ static int emac_send_command_sr1(struct prueth_emac *em= ac, u32 cmd) =20 cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); swdata =3D cppi5_hdesc_get_swdata(first_desc); - *swdata =3D data; + swdata->type =3D PRUETH_SWDATA_CMD; + swdata->data.cmd =3D le32_to_cpu(data[0]); =20 cppi5_hdesc_set_pktlen(first_desc, pkt_len); desc_dma =3D k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc); @@ -275,9 +276,9 @@ static struct page *prueth_process_rx_mgm(struct prueth= _emac *emac, struct net_device *ndev =3D emac->ndev; struct cppi5_host_desc_t *desc_rx; struct page *page, *new_page; + struct prueth_swdata *swdata; dma_addr_t desc_dma, buf_dma; u32 buf_dma_len; - void **swdata; int ret; =20 ret =3D k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); @@ -299,7 +300,7 @@ static struct page *prueth_process_rx_mgm(struct prueth= _emac *emac, } =20 swdata =3D cppi5_hdesc_get_swdata(desc_rx); - page =3D *swdata; + page =3D swdata->data.page; cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); =20 dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); --=20 2.43.0 From nobody Sun Feb 8 02:08:24 2026 Received: from lelvem-ot01.ext.ti.com (lelvem-ot01.ext.ti.com [198.47.23.234]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 27CAD2066D9; Wed, 5 Mar 2025 10:15:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741169731; cv=none; b=SwH4g+6SJv4ETo/smh2ixHMqzYqlvqd3cOUzyzvBowbVID0sIZhKbv1qIv6/w/74LLz1Vjm7y0AGRmHu3HixnMb4qUzFX0on4nY5sT+16wSmmCHMo0OTnz/xVco3lluLZi2uRhf09xrz1jX/j+pDzN6BQVbjnqcuch8lyktmMcc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741169731; c=relaxed/simple; bh=0Mez4h6v+qVY7DgvnHeg7RRwYZ2nkobNOy9DgfG3sGM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=urgl9lC7dIgwyDkDpQvZ+9UqEXnnZD5NRrkiLZyo3ugE6jb4mp1a3HE2tR00FgxqYrpZNTMCMzSRtOB3SRm50SUhRGT3wo402siZpIF8aXI2bt0whJUwwcQSIwKKLTt999JlyAWGwD46wWqUfIGu7CYjPaSZrW80Xtyh5RgaDxE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=S8BMwjIo; arc=none smtp.client-ip=198.47.23.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="S8BMwjIo" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelvem-ot01.ext.ti.com (8.15.2/8.15.2) with ESMTPS id 525AEasi3365532 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 5 Mar 2025 04:14:36 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1741169676; bh=46R3UjR8U080i9lalYTR+/jDd0aKmnmmB/pxW+KPQGE=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=S8BMwjIosw6i9LWbpvSgiG1qla6WpyocNO2iebRIIH5TsjOjRlq4yi2s2C2gasHcK V4EhCCrkoOi31lzlX5USasoPBSKr48PGKC2uhzC9AIby3iiWCOd7NO25kQ4QYF1Sg7 bxtVCUN8vf9z/20VGRe5l9pTMCYVw8+2kRIWZXLA= Received: from DLEE100.ent.ti.com (dlee100.ent.ti.com [157.170.170.30]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 525AEaxs005493 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 5 Mar 2025 04:14:36 -0600 Received: from DLEE108.ent.ti.com (157.170.170.38) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Wed, 5 Mar 2025 04:14:35 -0600 Received: from fllvsmtp8.itg.ti.com (10.64.41.158) by DLEE108.ent.ti.com (157.170.170.38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Wed, 5 Mar 2025 04:14:35 -0600 Received: from lelv0854.itg.ti.com (lelv0854.itg.ti.com [10.181.64.140]) by fllvsmtp8.itg.ti.com (8.15.2/8.15.2) with ESMTP id 525AEZQe130438; Wed, 5 Mar 2025 04:14:35 -0600 Received: from localhost (meghana-pc.dhcp.ti.com [10.24.69.13] (may be forged)) by lelv0854.itg.ti.com (8.14.7/8.14.7) with ESMTP id 525AEYeI005841; Wed, 5 Mar 2025 04:14:35 -0600 From: Meghana Malladi To: , , , , , , CC: , , , , , , , , , , , , , , , , , , Vignesh Raghavendra Subject: [PATCH net-next v4 3/3] net: ti: icssg-prueth: Add XDP support Date: Wed, 5 Mar 2025 15:44:22 +0530 Message-ID: <20250305101422.1908370-4-m-malladi@ti.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305101422.1908370-1-m-malladi@ti.com> References: <20250305101422.1908370-1-m-malladi@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" From: Roger Quadros Add native XDP support. We do not support zero copy yet. Signed-off-by: Roger Quadros Signed-off-by: MD Danish Anwar Signed-off-by: Meghana Malladi --- Changes from v3 (v4-v3): - few cosmetic changes inside emac_xmit_xdp_frame() func - change xdp_state type to u32 from int Above changes are suggested by Dan Carpenter - Few improvements in emac_run_xdp case handling as suggested by=20 Roger Quadros drivers/net/ethernet/ti/icssg/icssg_common.c | 225 +++++++++++++++++-- drivers/net/ethernet/ti/icssg/icssg_prueth.c | 128 ++++++++++- drivers/net/ethernet/ti/icssg/icssg_prueth.h | 17 ++ 3 files changed, 355 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/eth= ernet/ti/icssg/icssg_common.c index fee1204db367..df5da7a98abf 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_common.c +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c @@ -98,11 +98,20 @@ void prueth_xmit_free(struct prueth_tx_chn *tx_chn, { struct cppi5_host_desc_t *first_desc, *next_desc; dma_addr_t buf_dma, next_desc_dma; + struct prueth_swdata *swdata; + struct page *page; u32 buf_dma_len; =20 first_desc =3D desc; next_desc =3D first_desc; =20 + swdata =3D cppi5_hdesc_get_swdata(desc); + if (swdata->type =3D=3D PRUETH_SWDATA_PAGE) { + page =3D swdata->data.page; + page_pool_recycle_direct(page->pp, swdata->data.page); + goto free_desc; + } + cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len); k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma); =20 @@ -126,6 +135,7 @@ void prueth_xmit_free(struct prueth_tx_chn *tx_chn, k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc); } =20 +free_desc: k3_cppi_desc_pool_free(tx_chn->desc_pool, first_desc); } EXPORT_SYMBOL_GPL(prueth_xmit_free); @@ -139,6 +149,7 @@ int emac_tx_complete_packets(struct prueth_emac *emac, = int chn, struct prueth_swdata *swdata; struct prueth_tx_chn *tx_chn; unsigned int total_bytes =3D 0; + struct xdp_frame *xdpf; struct sk_buff *skb; dma_addr_t desc_dma; int res, num_tx =3D 0; @@ -161,16 +172,28 @@ int emac_tx_complete_packets(struct prueth_emac *emac= , int chn, desc_tx =3D k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); swdata =3D cppi5_hdesc_get_swdata(desc_tx); - prueth_xmit_free(tx_chn, desc_tx); - if (swdata->type !=3D PRUETH_SWDATA_SKB) + + switch (swdata->type) { + case PRUETH_SWDATA_SKB: + skb =3D swdata->data.skb; + dev_sw_netstats_tx_add(skb->dev, 1, skb->len); + total_bytes +=3D skb->len; + napi_consume_skb(skb, budget); + break; + case PRUETH_SWDATA_XDPF: + xdpf =3D swdata->data.xdpf; + dev_sw_netstats_tx_add(ndev, 1, xdpf->len); + total_bytes +=3D xdpf->len; + xdp_return_frame(xdpf); + break; + default: + netdev_err(ndev, "tx_complete: invalid swdata type %d\n", swdata->type); + prueth_xmit_free(tx_chn, desc_tx); + ndev->stats.tx_dropped++; continue; + } =20 - skb =3D swdata->data.skb; - ndev =3D skb->dev; - ndev->stats.tx_packets++; - ndev->stats.tx_bytes +=3D skb->len; - total_bytes +=3D skb->len; - napi_consume_skb(skb, budget); + prueth_xmit_free(tx_chn, desc_tx); num_tx++; } =20 @@ -529,7 +552,153 @@ void emac_rx_timestamp(struct prueth_emac *emac, ssh->hwtstamp =3D ns_to_ktime(ns); } =20 -static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) +/** + * 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 + * + * Return: XDP state + */ +u32 emac_xmit_xdp_frame(struct prueth_emac *emac, + struct xdp_frame *xdpf, + struct page *page, + unsigned int q_idx) +{ + struct cppi5_host_desc_t *first_desc; + struct net_device *ndev =3D emac->ndev; + struct prueth_tx_chn *tx_chn; + dma_addr_t desc_dma, buf_dma; + struct prueth_swdata *swdata; + u32 *epib; + int ret; + + if (q_idx >=3D PRUETH_MAX_TX_QUEUES) { + netdev_err(ndev, "xdp tx: invalid q_id %d\n", q_idx); + return ICSSG_XDP_CONSUMED; /* drop */ + } + + tx_chn =3D &emac->tx_chns[q_idx]; + + first_desc =3D k3_cppi_desc_pool_alloc(tx_chn->desc_pool); + if (!first_desc) { + netdev_dbg(ndev, "xdp tx: failed to allocate descriptor\n"); + goto drop_free_descs; /* drop */ + } + + if (page) { /* already DMA mapped by page_pool */ + buf_dma =3D page_pool_get_dma_addr(page); + buf_dma +=3D xdpf->headroom + sizeof(struct xdp_frame); + } else { /* Map the linear buffer */ + buf_dma =3D dma_map_single(tx_chn->dma_dev, xdpf->data, xdpf->len, DMA_T= O_DEVICE); + if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) { + netdev_err(ndev, "xdp tx: failed to map data buffer\n"); + goto drop_free_descs; /* drop */ + } + } + + cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT, + PRUETH_NAV_PS_DATA_SIZE); + cppi5_hdesc_set_pkttype(first_desc, 0); + epib =3D first_desc->epib; + epib[0] =3D 0; + epib[1] =3D 0; + + /* set dst tag to indicate internal qid at the firmware which is at + * bit8..bit15. bit0..bit7 indicates port num for directed + * packets in case of switch mode operation + */ + cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8= ))); + k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma); + cppi5_hdesc_attach_buf(first_desc, buf_dma, xdpf->len, buf_dma, xdpf->len= ); + swdata =3D cppi5_hdesc_get_swdata(first_desc); + if (page) { + swdata->type =3D PRUETH_SWDATA_PAGE; + swdata->data.page =3D page; + } else { + swdata->type =3D PRUETH_SWDATA_XDPF; + swdata->data.xdpf =3D xdpf; + } + + cppi5_hdesc_set_pktlen(first_desc, xdpf->len); + desc_dma =3D k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc); + + ret =3D k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma); + if (ret) { + netdev_err(ndev, "xdp tx: push failed: %d\n", ret); + goto drop_free_descs; + } + + return ICSSG_XDP_TX; + +drop_free_descs: + prueth_xmit_free(tx_chn, first_desc); + return ICSSG_XDP_CONSUMED; +} +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) +{ + struct net_device *ndev =3D emac->ndev; + struct bpf_prog *xdp_prog; + struct xdp_frame *xdpf; + u32 pkt_len =3D *len; + u32 act, result; + int q_idx, err; + + xdp_prog =3D READ_ONCE(emac->xdp_prog); + act =3D bpf_prog_run_xdp(xdp_prog, xdp); + switch (act) { + case XDP_PASS: + return ICSSG_XDP_PASS; + case XDP_TX: + /* Send packet to TX ring for immediate transmission */ + xdpf =3D xdp_convert_buff_to_frame(xdp); + if (unlikely(!xdpf)) { + ndev->stats.tx_dropped++; + goto drop; + } + + q_idx =3D smp_processor_id() % emac->tx_ch_num; + result =3D emac_xmit_xdp_frame(emac, xdpf, page, q_idx); + if (result =3D=3D ICSSG_XDP_CONSUMED) + goto drop; + + dev_sw_netstats_rx_add(ndev, xdpf->len); + return result; + case XDP_REDIRECT: + err =3D xdp_do_redirect(emac->ndev, xdp, xdp_prog); + if (err) + goto drop; + + dev_sw_netstats_rx_add(ndev, pkt_len); + return ICSSG_XDP_REDIR; + default: + bpf_warn_invalid_xdp_action(emac->ndev, xdp_prog, act); + fallthrough; + case XDP_ABORTED: +drop: + trace_xdp_exception(emac->ndev, xdp_prog, act); + fallthrough; /* handle aborts by dropping packet */ + case XDP_DROP: + ndev->stats.rx_dropped++; + page_pool_recycle_direct(emac->rx_chns.pg_pool, page); + return ICSSG_XDP_CONSUMED; + } +} + +static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id, u32 *xdp_= state) { struct prueth_rx_chn *rx_chn =3D &emac->rx_chns; u32 buf_dma_len, pkt_len, port_id =3D 0; @@ -540,10 +709,12 @@ static int emac_rx_packet(struct prueth_emac *emac, u= 32 flow_id) struct page *page, *new_page; struct page_pool *pool; struct sk_buff *skb; + struct xdp_buff xdp; u32 *psdata; void *pa; int ret; =20 + *xdp_state =3D 0; pool =3D rx_chn->pg_pool; ret =3D k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); if (ret) { @@ -584,9 +755,21 @@ static int emac_rx_packet(struct prueth_emac *emac, u3= 2 flow_id) goto requeue; } =20 - /* prepare skb and send to n/w stack */ pa =3D page_address(page); - skb =3D napi_build_skb(pa, PAGE_SIZE); + if (emac->xdp_prog) { + xdp_init_buff(&xdp, PAGE_SIZE, &rx_chn->xdp_rxq); + xdp_prepare_buff(&xdp, pa, PRUETH_HEADROOM, pkt_len, false); + + *xdp_state =3D emac_run_xdp(emac, &xdp, page, &pkt_len); + if (*xdp_state =3D=3D ICSSG_XDP_PASS) + skb =3D xdp_build_skb_from_buff(&xdp); + else + goto requeue; + } else { + /* prepare skb and send to n/w stack */ + skb =3D napi_build_skb(pa, PAGE_SIZE); + } + if (!skb) { ndev->stats.rx_dropped++; page_pool_recycle_direct(pool, page); @@ -849,13 +1032,23 @@ static void prueth_tx_cleanup(void *data, dma_addr_t= desc_dma) struct prueth_tx_chn *tx_chn =3D data; struct cppi5_host_desc_t *desc_tx; struct prueth_swdata *swdata; + struct xdp_frame *xdpf; struct sk_buff *skb; =20 desc_tx =3D k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); swdata =3D cppi5_hdesc_get_swdata(desc_tx); - if (swdata->type =3D=3D PRUETH_SWDATA_SKB) { + + switch (swdata->type) { + case PRUETH_SWDATA_SKB: skb =3D swdata->data.skb; dev_kfree_skb_any(skb); + break; + case PRUETH_SWDATA_XDPF: + xdpf =3D swdata->data.xdpf; + xdp_return_frame(xdpf); + break; + default: + break; } =20 prueth_xmit_free(tx_chn, desc_tx); @@ -892,15 +1085,18 @@ int icssg_napi_rx_poll(struct napi_struct *napi_rx, = int budget) PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA; int flow =3D emac->is_sr1 ? PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS; + int xdp_state_or =3D 0; int num_rx =3D 0; int cur_budget; + u32 xdp_state; int ret; =20 while (flow--) { cur_budget =3D budget - num_rx; =20 while (cur_budget--) { - ret =3D emac_rx_packet(emac, flow); + ret =3D emac_rx_packet(emac, flow, &xdp_state); + xdp_state_or |=3D xdp_state; if (ret) break; num_rx++; @@ -910,6 +1106,9 @@ int icssg_napi_rx_poll(struct napi_struct *napi_rx, in= t budget) break; } =20 + if (xdp_state_or & ICSSG_XDP_REDIR) + xdp_do_flush(); + if (num_rx < budget && napi_complete_done(napi_rx, num_rx)) { if (unlikely(emac->rx_pace_timeout_ns)) { hrtimer_start(&emac->rx_hrtimer, diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/eth= ernet/ti/icssg/icssg_prueth.c index 3ff8c322f9d9..c4a995630eca 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -559,6 +559,33 @@ const struct icss_iep_clockops prueth_iep_clockops =3D= { .perout_enable =3D prueth_perout_enable, }; =20 +static int prueth_create_xdp_rxqs(struct prueth_emac *emac) +{ + struct xdp_rxq_info *rxq =3D &emac->rx_chns.xdp_rxq; + struct page_pool *pool =3D emac->rx_chns.pg_pool; + int ret; + + ret =3D xdp_rxq_info_reg(rxq, emac->ndev, 0, emac->napi_rx.napi_id); + if (ret) + return ret; + + ret =3D xdp_rxq_info_reg_mem_model(rxq, MEM_TYPE_PAGE_POOL, pool); + if (ret) + xdp_rxq_info_unreg(rxq); + + return ret; +} + +static void prueth_destroy_xdp_rxqs(struct prueth_emac *emac) +{ + struct xdp_rxq_info *rxq =3D &emac->rx_chns.xdp_rxq; + + if (!xdp_rxq_info_is_reg(rxq)) + return; + + xdp_rxq_info_unreg(rxq); +} + static int icssg_prueth_add_mcast(struct net_device *ndev, const u8 *addr) { struct net_device *real_dev; @@ -780,10 +807,14 @@ static int emac_ndo_open(struct net_device *ndev) if (ret) goto free_tx_ts_irq; =20 - ret =3D k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn); + ret =3D prueth_create_xdp_rxqs(emac); if (ret) goto reset_rx_chn; =20 + ret =3D k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn); + if (ret) + goto destroy_xdp_rxqs; + for (i =3D 0; i < emac->tx_ch_num; i++) { ret =3D k3_udma_glue_enable_tx_chn(emac->tx_chns[i].tx_chn); if (ret) @@ -809,6 +840,8 @@ static int emac_ndo_open(struct net_device *ndev) * any SKB for completion. So set false to free_skb */ prueth_reset_tx_chan(emac, i, false); +destroy_xdp_rxqs: + prueth_destroy_xdp_rxqs(emac); reset_rx_chn: prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false); free_tx_ts_irq: @@ -879,7 +912,7 @@ static int emac_ndo_stop(struct net_device *ndev) k3_udma_glue_tdown_rx_chn(emac->rx_chns.rx_chn, true); =20 prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, true); - + prueth_destroy_xdp_rxqs(emac); napi_disable(&emac->napi_rx); hrtimer_cancel(&emac->rx_hrtimer); =20 @@ -1024,6 +1057,93 @@ static int emac_ndo_vlan_rx_del_vid(struct net_devic= e *ndev, return 0; } =20 +/** + * emac_xdp_xmit - Implements ndo_xdp_xmit + * @dev: netdev + * @n: number of frames + * @frames: array of XDP buffer pointers + * @flags: XDP extra info + * + * Return: number of frames successfully sent. Failed frames + * will be free'ed by XDP core. + * + * For error cases, a negative errno code is returned and no-frames + * are transmitted (caller must handle freeing frames). + **/ +static int emac_xdp_xmit(struct net_device *dev, int n, struct xdp_frame *= *frames, + u32 flags) +{ + struct prueth_emac *emac =3D netdev_priv(dev); + struct net_device *ndev =3D emac->ndev; + struct xdp_frame *xdpf; + unsigned int q_idx; + int nxmit =3D 0; + u32 err; + int i; + + q_idx =3D smp_processor_id() % emac->tx_ch_num; + + if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) + return -EINVAL; + + for (i =3D 0; i < n; i++) { + xdpf =3D frames[i]; + err =3D emac_xmit_xdp_frame(emac, xdpf, NULL, q_idx); + if (err !=3D ICSSG_XDP_TX) { + ndev->stats.tx_dropped++; + break; + } + nxmit++; + } + + return nxmit; +} + +/** + * emac_xdp_setup - add/remove an XDP program + * @emac: emac device + * @bpf: XDP program + * + * Return: Always 0 (Success) + **/ +static int emac_xdp_setup(struct prueth_emac *emac, struct netdev_bpf *bpf) +{ + struct bpf_prog *prog =3D bpf->prog; + xdp_features_t val; + + val =3D NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT | + NETDEV_XDP_ACT_NDO_XMIT; + xdp_set_features_flag(emac->ndev, val); + + if (!emac->xdpi.prog && !prog) + return 0; + + WRITE_ONCE(emac->xdp_prog, prog); + + xdp_attachment_setup(&emac->xdpi, bpf); + + return 0; +} + +/** + * emac_ndo_bpf - implements ndo_bpf for icssg_prueth + * @ndev: network adapter device + * @bpf: XDP program + * + * Return: 0 on success, error code on failure. + **/ +static int emac_ndo_bpf(struct net_device *ndev, struct netdev_bpf *bpf) +{ + struct prueth_emac *emac =3D netdev_priv(ndev); + + switch (bpf->command) { + case XDP_SETUP_PROG: + return emac_xdp_setup(emac, bpf); + default: + return -EINVAL; + } +} + static const struct net_device_ops emac_netdev_ops =3D { .ndo_open =3D emac_ndo_open, .ndo_stop =3D emac_ndo_stop, @@ -1038,6 +1158,8 @@ static const struct net_device_ops emac_netdev_ops = =3D { .ndo_fix_features =3D emac_ndo_fix_features, .ndo_vlan_rx_add_vid =3D emac_ndo_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid =3D emac_ndo_vlan_rx_del_vid, + .ndo_bpf =3D emac_ndo_bpf, + .ndo_xdp_xmit =3D emac_xdp_xmit, }; =20 static int prueth_netdev_init(struct prueth *prueth, @@ -1066,6 +1188,8 @@ static int prueth_netdev_init(struct prueth *prueth, emac->prueth =3D prueth; emac->ndev =3D ndev; emac->port_id =3D port; + emac->xdp_prog =3D NULL; + emac->ndev->pcpu_stat_type =3D NETDEV_PCPU_STAT_TSTATS; emac->cmd_wq =3D create_singlethread_workqueue("icssg_cmd_wq"); if (!emac->cmd_wq) { ret =3D -ENOMEM; diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/eth= ernet/ti/icssg/icssg_prueth.h index 3bbabd007129..1dd76e2adfcd 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -8,6 +8,8 @@ #ifndef __NET_TI_ICSSG_PRUETH_H #define __NET_TI_ICSSG_PRUETH_H =20 +#include +#include #include #include #include @@ -134,6 +136,7 @@ struct prueth_rx_chn { unsigned int irq[ICSSG_MAX_RFLOWS]; /* separate irq per flow */ char name[32]; struct page_pool *pg_pool; + struct xdp_rxq_info xdp_rxq; }; =20 enum prueth_swdata_type { @@ -141,6 +144,7 @@ enum prueth_swdata_type { PRUETH_SWDATA_SKB, PRUETH_SWDATA_PAGE, PRUETH_SWDATA_CMD, + PRUETH_SWDATA_XDPF, }; =20 struct prueth_swdata { @@ -149,6 +153,7 @@ struct prueth_swdata { struct sk_buff *skb; struct page *page; u32 cmd; + struct xdp_frame *xdpf; } data; }; =20 @@ -159,6 +164,12 @@ struct prueth_swdata { =20 #define PRUETH_MAX_TX_TS_REQUESTS 50 /* Max simultaneous TX_TS requests */ =20 +/* XDP BPF state */ +#define ICSSG_XDP_PASS 0 +#define ICSSG_XDP_CONSUMED BIT(0) +#define ICSSG_XDP_TX BIT(1) +#define ICSSG_XDP_REDIR BIT(2) + /* Minimum coalesce time in usecs for both Tx and Rx */ #define ICSSG_MIN_COALESCE_USECS 20 =20 @@ -227,6 +238,8 @@ struct prueth_emac { unsigned long rx_pace_timeout_ns; =20 struct netdev_hw_addr_list vlan_mcast_list[MAX_VLAN_ID]; + struct bpf_prog *xdp_prog; + struct xdp_attachment_info xdpi; }; =20 /* The buf includes headroom compatible with both skb and xdpf */ @@ -465,5 +478,9 @@ void prueth_put_cores(struct prueth *prueth, int slice); =20 /* Revision specific helper */ 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); =20 #endif /* __NET_TI_ICSSG_PRUETH_H */ --=20 2.43.0