Commit 428e68e1 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'stmmac-xdp'

Ong Boon Leong says:

====================
stmmac: Add XDP support

This is the v4 patch series for adding XDP native support to stmmac.

Changes in v4:
5/6: Move TX clean timer setup to the end of NAPI RX process and
     group it under stmmac_finalize_xdp_rx().
     Also, fixed stmmac_xdp_xmit_back() returns STMMAC_XDP_CONSUMED
     if XDP buffer conversion to XDP frame fails.

6/6: Move xdp_do_flush(0 into stmmac_finalize_xdp_rx() and combine
     the XDP verdict of XDP TX and XDP REDIRECT together.

I retested the patch series on the 'xdp2' and 'xdp_redirect' related to
changes above and found the result to be satisfactory.

History of previous patch series:
v3: https://patchwork.kernel.org/project/netdevbpf/cover/20210331154135.8507-1-boon.leong.ong@intel.com/
v2: https://patchwork.kernel.org/project/netdevbpf/list/?series=457757
v1: https://patchwork.kernel.org/project/netdevbpf/list/?series=457139



It will be great if community can help to test or review the v4 series
and provide me any input if any.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 82506665 8b278a5b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o	\
	      dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
	      stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
	      stmmac_xdp.o \
	      $(stmmac-y)

stmmac-$(CONFIG_STMMAC_SELFTESTS) += stmmac_selftests.o
+33 −2
Original line number Diff line number Diff line
@@ -36,12 +36,19 @@ struct stmmac_resources {
	int tx_irq[MTL_MAX_TX_QUEUES];
};

enum stmmac_txbuf_type {
	STMMAC_TXBUF_T_SKB,
	STMMAC_TXBUF_T_XDP_TX,
	STMMAC_TXBUF_T_XDP_NDO,
};

struct stmmac_tx_info {
	dma_addr_t buf;
	bool map_as_page;
	unsigned len;
	bool last_segment;
	bool is_jumbo;
	enum stmmac_txbuf_type buf_type;
};

#define STMMAC_TBS_AVAIL	BIT(0)
@@ -57,7 +64,10 @@ struct stmmac_tx_queue {
	struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp;
	struct dma_edesc *dma_entx;
	struct dma_desc *dma_tx;
	union {
		struct sk_buff **tx_skbuff;
		struct xdp_frame **xdpf;
	};
	struct stmmac_tx_info *tx_skbuff_dma;
	unsigned int cur_tx;
	unsigned int dirty_tx;
@@ -68,14 +78,16 @@ struct stmmac_tx_queue {

struct stmmac_rx_buffer {
	struct page *page;
	struct page *sec_page;
	dma_addr_t addr;
	__u32 page_offset;
	struct page *sec_page;
	dma_addr_t sec_addr;
};

struct stmmac_rx_queue {
	u32 rx_count_frames;
	u32 queue_index;
	struct xdp_rxq_info xdp_rxq;
	struct page_pool *page_pool;
	struct stmmac_rx_buffer *buf_pool;
	struct stmmac_priv *priv_data;
@@ -160,6 +172,7 @@ struct stmmac_priv {
	bool tx_path_in_lpi_mode;
	bool tso;
	int sph;
	int sph_cap;
	u32 sarc_type;

	unsigned int dma_buf_sz;
@@ -268,6 +281,9 @@ struct stmmac_priv {

	/* Receive Side Scaling */
	struct stmmac_rss rss;

	/* XDP BPF Program */
	struct bpf_prog *xdp_prog;
};

enum stmmac_state {
@@ -284,6 +300,8 @@ void stmmac_set_ethtool_ops(struct net_device *netdev);

void stmmac_ptp_register(struct stmmac_priv *priv);
void stmmac_ptp_unregister(struct stmmac_priv *priv);
int stmmac_open(struct net_device *dev);
int stmmac_release(struct net_device *dev);
int stmmac_resume(struct device *dev);
int stmmac_suspend(struct device *dev);
int stmmac_dvr_remove(struct device *dev);
@@ -297,6 +315,19 @@ int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size);
int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled);
void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable);

static inline bool stmmac_xdp_is_enabled(struct stmmac_priv *priv)
{
	return !!priv->xdp_prog;
}

static inline unsigned int stmmac_rx_offset(struct stmmac_priv *priv)
{
	if (stmmac_xdp_is_enabled(priv))
		return XDP_PACKET_HEADROOM;

	return 0;
}

#if IS_ENABLED(CONFIG_STMMAC_SELFTESTS)
void stmmac_selftest_run(struct net_device *dev,
			 struct ethtool_test *etest, u64 *buf);
+461 −78

File changed.

Preview size limit exceeded, changes collapsed.

+40 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2021, Intel Corporation. */

#include "stmmac.h"
#include "stmmac_xdp.h"

int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog,
			struct netlink_ext_ack *extack)
{
	struct net_device *dev = priv->dev;
	struct bpf_prog *old_prog;
	bool need_update;
	bool if_running;

	if_running = netif_running(dev);

	if (prog && dev->mtu > ETH_DATA_LEN) {
		/* For now, the driver doesn't support XDP functionality with
		 * jumbo frames so we return error.
		 */
		NL_SET_ERR_MSG_MOD(extack, "Jumbo frames not supported");
		return -EOPNOTSUPP;
	}

	need_update = !!priv->xdp_prog != !!prog;
	if (if_running && need_update)
		stmmac_release(dev);

	old_prog = xchg(&priv->xdp_prog, prog);
	if (old_prog)
		bpf_prog_put(old_prog);

	/* Disable RX SPH for XDP operation */
	priv->sph = priv->sph_cap && !stmmac_xdp_is_enabled(priv);

	if (if_running && need_update)
		stmmac_open(dev);

	return 0;
}
+12 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2021, Intel Corporation. */

#ifndef _STMMAC_XDP_H_
#define _STMMAC_XDP_H_

#define STMMAC_MAX_RX_BUF_SIZE(num)	(((num) * PAGE_SIZE) - XDP_PACKET_HEADROOM)

int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog,
			struct netlink_ext_ack *extack);

#endif /* _STMMAC_XDP_H_ */