Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0cfcb29
xdp: use modulo operation to calculate XDP frag tailroom
walking-machine Mar 5, 2026
d040ccb
xsk: introduce helper to determine rxq->frag_size
walking-machine Mar 5, 2026
8468091
libeth, idpf: use truesize as XDP RxQ info frag_size
walking-machine Mar 5, 2026
05efcc8
xdp: produce a warning when calculated tailroom is negative
walking-machine Mar 5, 2026
f2908e7
ixgbevf: remove legacy Rx
walking-machine Jun 23, 2025
d7bf74b
ixgbevf: do not share pages between packets
walking-machine Jun 24, 2025
c070272
ixgbevf: use libeth in Rx processing
walking-machine Jul 9, 2025
6f14b56
ixgbevf: branch prediction and cleanup
walking-machine Jul 28, 2025
83ccc4d
ixgbevf: support XDP multi-buffer on Rx path
walking-machine Sep 2, 2025
7875adb
ixgbevf: XDP_TX in multi-buffer through libeth
walking-machine Sep 9, 2025
aef135f
ixgbevf: support XDP_REDIRECT and .ndo_xdp_xmit
walking-machine Sep 22, 2025
a9ab74d
ixgbevf: add pseudo header split
nwochtma Sep 19, 2025
096cf89
ixgbevf: reconfigure page pool when reallocating buffers
walking-machine Nov 25, 2025
ffc83fd
ixgbevf: allow changing MTU when XDP program is attached
walking-machine Jan 8, 2026
b460fa6
ixgbevf: add a helper to flush Tx queue
walking-machine Oct 22, 2025
105a17e
ixgbevf: move skb-filling code to a header
walking-machine Oct 24, 2025
604d887
ixgbevf: move XDP queue management code to a header
walking-machine Oct 24, 2025
3fd82a9
ixgbevf: handle single context descriptor on an XDP queue
walking-machine Oct 24, 2025
4b4822e
ixgbevf: implement AF_XDP ZC initialization
walking-machine Oct 27, 2025
bb6974a
ixgbevf: implement AF_XDP zero-copy Tx
walking-machine Oct 27, 2025
f2f514b
ixgbevf: implement AF_XDP zero-copy Rx
walking-machine Oct 27, 2025
d4e2907
ixgbevf: implement .ndo_xsk_wakeup() and set features
walking-machine Oct 27, 2025
25ec6fa
ixgbevf: multi-buffer AF_XDP Tx
walking-machine Dec 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ config IXGBE_IPSEC
config IXGBEVF
tristate "Intel(R) 10GbE PCI Express Virtual Function Ethernet support"
depends on PCI_MSI
select LIBETH_XDP
help
This driver supports Intel(R) PCI Express virtual functions for the
Intel(R) ixgbe driver. For more information on how to identify your
Expand Down
6 changes: 5 additions & 1 deletion drivers/net/ethernet/intel/idpf/xdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,15 @@ static int __idpf_xdp_rxq_info_init(struct idpf_rx_queue *rxq, void *arg)
{
const struct idpf_vport *vport = rxq->q_vector->vport;
bool split = idpf_is_queue_model_split(vport->rxq_model);
u32 frag_size = 0;
int err;

if (idpf_queue_has(XSK, rxq))
frag_size = rxq->bufq_sets[0].bufq.truesize;

err = __xdp_rxq_info_reg(&rxq->xdp_rxq, vport->netdev, rxq->idx,
rxq->q_vector->napi.napi_id,
rxq->rx_buf_size);
frag_size);
if (err)
return err;

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/idpf/xsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ int idpf_xskfq_init(struct idpf_buf_queue *bufq)
bufq->pending = fq.pending;
bufq->thresh = fq.thresh;
bufq->rx_buf_size = fq.buf_len;
bufq->truesize = fq.truesize;

if (!idpf_xskfq_refill(bufq))
netdev_err(bufq->pool->netdev,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/ixgbevf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@

obj-$(CONFIG_IXGBEVF) += ixgbevf.o

ixgbevf-y := vf.o mbx.o ethtool.o ixgbevf_main.o
ixgbevf-y := vf.o mbx.o ethtool.o ixgbevf_main.o ixgbevf_xsk.o
ixgbevf-$(CONFIG_IXGBEVF_IPSEC) += ipsec.o
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/ixgbevf/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ typedef u32 ixgbe_link_speed;
#define IXGBE_PSRTYPE_L2HDR 0x00001000

/* SRRCTL bit definitions */
#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
#define IXGBE_SRRCTL_BSIZEPKT_STEP 1024
#define IXGBE_SRRCTL_RDMTS_SHIFT 22
#define IXGBE_SRRCTL_RDMTS_MASK 0x01C00000
#define IXGBE_SRRCTL_DROP_EN 0x10000000
Expand Down
48 changes: 0 additions & 48 deletions drivers/net/ethernet/intel/ixgbevf/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,6 @@ static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {

#define IXGBEVF_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)

static const char ixgbevf_priv_flags_strings[][ETH_GSTRING_LEN] = {
#define IXGBEVF_PRIV_FLAGS_LEGACY_RX BIT(0)
"legacy-rx",
};

#define IXGBEVF_PRIV_FLAGS_STR_LEN ARRAY_SIZE(ixgbevf_priv_flags_strings)

static int ixgbevf_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd)
{
Expand Down Expand Up @@ -216,8 +209,6 @@ static void ixgbevf_get_drvinfo(struct net_device *netdev,
strscpy(drvinfo->driver, ixgbevf_driver_name, sizeof(drvinfo->driver));
strscpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));

drvinfo->n_priv_flags = IXGBEVF_PRIV_FLAGS_STR_LEN;
}

static void ixgbevf_get_ringparam(struct net_device *netdev,
Expand Down Expand Up @@ -409,8 +400,6 @@ static int ixgbevf_get_sset_count(struct net_device *netdev, int stringset)
return IXGBEVF_TEST_LEN;
case ETH_SS_STATS:
return IXGBEVF_STATS_LEN;
case ETH_SS_PRIV_FLAGS:
return IXGBEVF_PRIV_FLAGS_STR_LEN;
default:
return -EINVAL;
}
Expand Down Expand Up @@ -538,10 +527,6 @@ static void ixgbevf_get_strings(struct net_device *netdev, u32 stringset,
p += ETH_GSTRING_LEN;
}
break;
case ETH_SS_PRIV_FLAGS:
memcpy(data, ixgbevf_priv_flags_strings,
IXGBEVF_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN);
break;
}
}

Expand Down Expand Up @@ -931,37 +916,6 @@ static int ixgbevf_get_rxfh(struct net_device *netdev,
return err;
}

static u32 ixgbevf_get_priv_flags(struct net_device *netdev)
{
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
u32 priv_flags = 0;

if (adapter->flags & IXGBEVF_FLAGS_LEGACY_RX)
priv_flags |= IXGBEVF_PRIV_FLAGS_LEGACY_RX;

return priv_flags;
}

static int ixgbevf_set_priv_flags(struct net_device *netdev, u32 priv_flags)
{
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
unsigned int flags = adapter->flags;

flags &= ~IXGBEVF_FLAGS_LEGACY_RX;
if (priv_flags & IXGBEVF_PRIV_FLAGS_LEGACY_RX)
flags |= IXGBEVF_FLAGS_LEGACY_RX;

if (flags != adapter->flags) {
adapter->flags = flags;

/* reset interface to repopulate queues */
if (netif_running(netdev))
ixgbevf_reinit_locked(adapter);
}

return 0;
}

static const struct ethtool_ops ixgbevf_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS,
.get_drvinfo = ixgbevf_get_drvinfo,
Expand All @@ -984,8 +938,6 @@ static const struct ethtool_ops ixgbevf_ethtool_ops = {
.get_rxfh_key_size = ixgbevf_get_rxfh_key_size,
.get_rxfh = ixgbevf_get_rxfh,
.get_link_ksettings = ixgbevf_get_link_ksettings,
.get_priv_flags = ixgbevf_get_priv_flags,
.set_priv_flags = ixgbevf_set_priv_flags,
};

void ixgbevf_set_ethtool_ops(struct net_device *netdev)
Expand Down
122 changes: 53 additions & 69 deletions drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/netdevice.h>
#include <linux/if_vlan.h>
#include <linux/u64_stats_sync.h>
#include <net/libeth/types.h>
#include <net/xdp.h>

#include "vf.h"
Expand Down Expand Up @@ -42,17 +43,6 @@ struct ixgbevf_tx_buffer {
u32 tx_flags;
};

struct ixgbevf_rx_buffer {
dma_addr_t dma;
struct page *page;
#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
__u32 page_offset;
#else
__u16 page_offset;
#endif
__u16 pagecnt_bias;
};

struct ixgbevf_stats {
u64 packets;
u64 bytes;
Expand All @@ -72,12 +62,11 @@ struct ixgbevf_rx_queue_stats {
};

enum ixgbevf_ring_state_t {
__IXGBEVF_RX_3K_BUFFER,
__IXGBEVF_RX_BUILD_SKB_ENABLED,
__IXGBEVF_TX_DETECT_HANG,
__IXGBEVF_HANG_CHECK_ARMED,
__IXGBEVF_TX_XDP_RING,
__IXGBEVF_TX_XDP_RING_PRIMED,
__IXGBEVF_RXTX_XSK_RING,
};

#define ring_is_xdp(ring) \
Expand All @@ -87,41 +76,63 @@ enum ixgbevf_ring_state_t {
#define clear_ring_xdp(ring) \
clear_bit(__IXGBEVF_TX_XDP_RING, &(ring)->state)

#define ring_is_xsk(ring) \
test_bit(__IXGBEVF_RXTX_XSK_RING, &(ring)->state)
#define set_ring_xsk(ring) \
set_bit(__IXGBEVF_RXTX_XSK_RING, &(ring)->state)
#define clear_ring_xsk(ring) \
clear_bit(__IXGBEVF_RXTX_XSK_RING, &(ring)->state)

struct ixgbevf_ring {
struct ixgbevf_ring *next;
struct ixgbevf_q_vector *q_vector; /* backpointer to q_vector */
struct net_device *netdev;
struct bpf_prog *xdp_prog;
struct device *dev;
struct bpf_prog __rcu *xdp_prog;
union {
struct page_pool *pp; /* Rx and XDP rings */
struct device *dev; /* Tx ring */
};
void *desc; /* descriptor ring memory */
dma_addr_t dma; /* phys. address of descriptor ring */
unsigned int size; /* length in bytes */
u32 truesize; /* Rx buffer full size */
u32 hdr_truesize; /* Rx header buffer full size */
u16 count; /* amount of descriptors */
u16 next_to_use;
u16 next_to_clean;
u16 next_to_alloc;
u32 next_to_use;
u32 pending; /* Sent-not-completed descriptors */

union {
struct libeth_fqe *rx_fqes;
struct libeth_xdp_buff **xsk_fqes;
struct ixgbevf_tx_buffer *tx_buffer_info;
struct ixgbevf_rx_buffer *rx_buffer_info;
struct libeth_sqe *xdp_sqes;
};
struct libeth_xdpsq_lock xdpq_lock;
u32 cached_ntu;
u32 thresh;
unsigned long state;
struct ixgbevf_stats stats;
struct u64_stats_sync syncp;
union {
struct ixgbevf_tx_queue_stats tx_stats;
struct ixgbevf_rx_queue_stats rx_stats;
};
struct libeth_fqe *hdr_fqes;
struct page_pool *hdr_pp;
struct xdp_rxq_info xdp_rxq;
u64 hw_csum_rx_error;
u8 __iomem *tail;
struct sk_buff *skb;

/* holds the special value that gets the hardware register offset
* associated with this ring, which is different for DCB and RSS modes
*/
u16 reg_idx;
int queue_index; /* needed for multiqueue queue management */
u32 rx_buf_len;
struct libeth_xdp_buff_stash xdp_stash;
struct libeth_xdp_buff *xsk_xdp_head;
unsigned int dma_size; /* length in bytes */
dma_addr_t dma; /* phys. address of descriptor ring */
struct xsk_buff_pool *xsk_pool; /* AF_XDP ZC rings */
} ____cacheline_internodealigned_in_smp;

/* How many Rx Buffers do we bundle into one write to the hardware ? */
Expand All @@ -144,21 +155,17 @@ struct ixgbevf_ring {
#define IXGBEVF_MIN_RXD 64

/* Supported Rx Buffer Sizes */
#define IXGBEVF_RXBUFFER_256 256 /* Used for packet split */
#define IXGBEVF_RXBUFFER_2048 2048
#define IXGBEVF_RXBUFFER_256 256
#define IXGBEVF_RXBUFFER_3072 3072

#define IXGBEVF_RX_HDR_SIZE IXGBEVF_RXBUFFER_256

#define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)

#define IXGBEVF_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
#if (PAGE_SIZE < 8192)
#define IXGBEVF_MAX_FRAME_BUILD_SKB \
(SKB_WITH_OVERHEAD(IXGBEVF_RXBUFFER_2048) - IXGBEVF_SKB_PAD)
#else
#define IXGBEVF_MAX_FRAME_BUILD_SKB IXGBEVF_RXBUFFER_2048
#endif
#define IXGBEVF_RX_PAGE_LEN(hr) (ALIGN_DOWN(LIBETH_RX_PAGE_LEN(hr), \
IXGBE_SRRCTL_BSIZEPKT_STEP))
#define IXGBEVF_RX_SRRCTL_BUF_SIZE(mtu) (ALIGN((mtu) + LIBETH_RX_LL_LEN, \
IXGBE_SRRCTL_BSIZEPKT_STEP))

#define IXGBE_TX_FLAGS_CSUM BIT(0)
#define IXGBE_TX_FLAGS_VLAN BIT(1)
Expand All @@ -169,43 +176,6 @@ struct ixgbevf_ring {
#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000
#define IXGBE_TX_FLAGS_VLAN_SHIFT 16

#define ring_uses_large_buffer(ring) \
test_bit(__IXGBEVF_RX_3K_BUFFER, &(ring)->state)
#define set_ring_uses_large_buffer(ring) \
set_bit(__IXGBEVF_RX_3K_BUFFER, &(ring)->state)
#define clear_ring_uses_large_buffer(ring) \
clear_bit(__IXGBEVF_RX_3K_BUFFER, &(ring)->state)

#define ring_uses_build_skb(ring) \
test_bit(__IXGBEVF_RX_BUILD_SKB_ENABLED, &(ring)->state)
#define set_ring_build_skb_enabled(ring) \
set_bit(__IXGBEVF_RX_BUILD_SKB_ENABLED, &(ring)->state)
#define clear_ring_build_skb_enabled(ring) \
clear_bit(__IXGBEVF_RX_BUILD_SKB_ENABLED, &(ring)->state)

static inline unsigned int ixgbevf_rx_bufsz(struct ixgbevf_ring *ring)
{
#if (PAGE_SIZE < 8192)
if (ring_uses_large_buffer(ring))
return IXGBEVF_RXBUFFER_3072;

if (ring_uses_build_skb(ring))
return IXGBEVF_MAX_FRAME_BUILD_SKB;
#endif
return IXGBEVF_RXBUFFER_2048;
}

static inline unsigned int ixgbevf_rx_pg_order(struct ixgbevf_ring *ring)
{
#if (PAGE_SIZE < 8192)
if (ring_uses_large_buffer(ring))
return 1;
#endif
return 0;
}

#define ixgbevf_rx_pg_size(_ring) (PAGE_SIZE << ixgbevf_rx_pg_order(_ring))

#define check_for_tx_hang(ring) \
test_bit(__IXGBEVF_TX_DETECT_HANG, &(ring)->state)
#define set_check_for_tx_hang(ring) \
Expand Down Expand Up @@ -377,8 +347,6 @@ struct ixgbevf_adapter {
u32 flags;
bool link_state;

#define IXGBEVF_FLAGS_LEGACY_RX BIT(1)

#ifdef CONFIG_XFRM
struct ixgbevf_ipsec *ipsec;
#endif /* CONFIG_XFRM */
Expand All @@ -396,6 +364,8 @@ enum ixbgevf_state_t {
__IXGBEVF_QUEUE_RESET_REQUESTED,
};

#define IXGBEVF_FLAG_HSPLIT BIT(0)

enum ixgbevf_boards {
board_82599_vf,
board_82599_vf_hv,
Expand Down Expand Up @@ -439,14 +409,28 @@ int ixgbevf_open(struct net_device *netdev);
int ixgbevf_close(struct net_device *netdev);
void ixgbevf_up(struct ixgbevf_adapter *adapter);
void ixgbevf_down(struct ixgbevf_adapter *adapter);
void ixgbevf_flush_tx_queue(struct ixgbevf_ring *ring);
void ixgbevf_disable_rx_queue(struct ixgbevf_adapter *adapter,
struct ixgbevf_ring *ring);
void ixgbevf_rx_desc_queue_enable(struct ixgbevf_adapter *adapter,
struct ixgbevf_ring *ring);
void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter);
void ixgbevf_reset(struct ixgbevf_adapter *adapter);
void ixgbevf_set_ethtool_ops(struct net_device *netdev);
int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter,
struct ixgbevf_ring *rx_ring);
void ixgbevf_irq_enable(struct ixgbevf_adapter *adapter);
void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter,
struct ixgbevf_ring *ring);
int ixgbevf_setup_tx_resources(struct ixgbevf_ring *);
void ixgbevf_configure_tx_ring(struct ixgbevf_adapter *adapter,
struct ixgbevf_ring *ring);
void ixgbevf_free_rx_resources(struct ixgbevf_ring *);
void ixgbevf_clean_rx_ring(struct ixgbevf_ring *rx_ring);
void ixgbevf_rx_destroy_pp(struct ixgbevf_ring *rx_ring);
void ixgbevf_free_tx_resources(struct ixgbevf_ring *);
void ixgbevf_clean_tx_ring(struct ixgbevf_ring *tx_ring);
void ixgbevf_clean_xdp_ring(struct ixgbevf_ring *xdp_ring);
void ixgbevf_update_stats(struct ixgbevf_adapter *adapter);
int ethtool_ioctl(struct ifreq *ifr);

Expand Down
Loading