net: ethernet: ti: am65-cpsw: Add minimal XDP support

This patch adds XDP (eXpress Data Path) support to TI AM65 CPSW
Ethernet driver. The following features are implemented:
- NETDEV_XDP_ACT_BASIC (XDP_PASS, XDP_TX, XDP_DROP, XDP_ABORTED)
- NETDEV_XDP_ACT_REDIRECT (XDP_REDIRECT)
- NETDEV_XDP_ACT_NDO_XMIT (ndo_xdp_xmit callback)

The page pool memory model is used to get better performance.
Below are benchmark results obtained for the receiver with iperf3 default
parameters:
- Without page pool: 495 Mbits/sec
- With page pool: 605 Mbits/sec (actually 610 Mbits/sec, with a 5 Mbits/sec
loss due to extra processing in the hot path to handle XDP).

Signed-off-by: Julien Panis <jpanis@baylibre.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Julien Panis 2024-04-12 17:38:34 +02:00 committed by David S. Miller
parent 84d767a3c0
commit 8acacc40f7
2 changed files with 575 additions and 95 deletions

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/soc/ti/k3-ringacc.h>
#include <net/devlink.h>
#include <net/xdp.h>
#include "am65-cpsw-qos.h"
struct am65_cpts;
@ -56,10 +57,18 @@ struct am65_cpsw_port {
bool rx_ts_enabled;
struct am65_cpsw_qos qos;
struct devlink_port devlink_port;
struct bpf_prog *xdp_prog;
struct xdp_rxq_info xdp_rxq;
/* Only for suspend resume context */
u32 vid_context;
};
enum am65_cpsw_tx_buf_type {
AM65_CPSW_TX_BUF_TYPE_SKB,
AM65_CPSW_TX_BUF_TYPE_XDP_TX,
AM65_CPSW_TX_BUF_TYPE_XDP_NDO,
};
struct am65_cpsw_host {
struct am65_cpsw_common *common;
void __iomem *port_base;
@ -80,6 +89,7 @@ struct am65_cpsw_tx_chn {
int irq;
u32 id;
u32 descs_num;
unsigned char dsize_log2;
char tx_chn_name[128];
u32 rate_mbps;
};
@ -89,7 +99,10 @@ struct am65_cpsw_rx_chn {
struct device *dma_dev;
struct k3_cppi_desc_pool *desc_pool;
struct k3_udma_glue_rx_channel *rx_chn;
struct page_pool *page_pool;
struct page **pages;
u32 descs_num;
unsigned char dsize_log2;
int irq;
};