mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2026-09-01 (i40e) Kohei Enju adds support for XDP metadata of Rx hash and VLAN tag. Chris Packham reduces messaging when Rx filters are exhausted, and promiscuous mode is enabled, to occur once when the mode is enabled rather than repeated messaging for each filter. * '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue: i40e: Avoid repeating RX filter warning i40e: add support for bpf_xdp_metadata_rx_vlan_tag() i40e: add support for bpf_xdp_metadata_rx_hash() i40e: prepare for XDP metadata ops support ==================== Link: https://patch.msgid.link/20260901211752.1922993-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
4c5c71852c
|
|
@ -4,6 +4,7 @@
|
|||
#include <generated/utsrelease.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include <linux/net/intel/libie/pctype.h>
|
||||
#include <linux/net/intel/libie/rx.h>
|
||||
#include <linux/if_bridge.h>
|
||||
#include <linux/if_macvlan.h>
|
||||
#include <linux/module.h>
|
||||
|
|
@ -2411,10 +2412,12 @@ void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
|
|||
|
||||
if (fcnt != num_add) {
|
||||
if (vsi->type == I40E_VSI_MAIN) {
|
||||
set_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
|
||||
dev_warn(&vsi->back->pdev->dev,
|
||||
"Error %s adding RX filters on %s, promiscuous mode forced on\n",
|
||||
libie_aq_str(aq_status), vsi_name);
|
||||
if (!test_and_set_bit(__I40E_VSI_OVERFLOW_PROMISC,
|
||||
vsi->state)) {
|
||||
dev_warn(&vsi->back->pdev->dev,
|
||||
"Error %s adding RX filters on %s, promiscuous mode forced on\n",
|
||||
libie_aq_str(aq_status), vsi_name);
|
||||
}
|
||||
} else if (vsi->type == I40E_VSI_SRIOV ||
|
||||
vsi->type == I40E_VSI_VMDQ1 ||
|
||||
vsi->type == I40E_VSI_VMDQ2) {
|
||||
|
|
@ -2464,10 +2467,11 @@ i40e_aqc_broadcast_filter(struct i40e_vsi *vsi, const char *vsi_name,
|
|||
}
|
||||
|
||||
if (aq_ret) {
|
||||
set_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
|
||||
dev_warn(&vsi->back->pdev->dev,
|
||||
"Error %s, forcing overflow promiscuous on %s\n",
|
||||
libie_aq_str(hw->aq.asq_last_status), vsi_name);
|
||||
if (!test_and_set_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state)) {
|
||||
dev_warn(&vsi->back->pdev->dev,
|
||||
"Error %s, forcing overflow promiscuous on %s\n",
|
||||
libie_aq_str(hw->aq.asq_last_status), vsi_name);
|
||||
}
|
||||
}
|
||||
|
||||
return aq_ret;
|
||||
|
|
@ -3622,7 +3626,7 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
|
|||
}
|
||||
|
||||
skip:
|
||||
xdp_init_buff(&ring->xdp, xdp_frame_sz, &ring->xdp_rxq);
|
||||
xdp_init_buff(&ring->xdp_ctx.xdp, xdp_frame_sz, &ring->xdp_rxq);
|
||||
|
||||
rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len,
|
||||
BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT));
|
||||
|
|
@ -13582,6 +13586,53 @@ static int i40e_xdp(struct net_device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
static int i40e_xdp_rx_hash(const struct xdp_md *_ctx, u32 *hash,
|
||||
enum xdp_rss_hash_type *rss_type)
|
||||
{
|
||||
const struct i40e_xdp_buff *ctx = (const void *)_ctx;
|
||||
const union i40e_rx_desc *desc = ctx->desc;
|
||||
struct libeth_rx_pt rx_ptype;
|
||||
u8 raw_rx_ptype;
|
||||
u64 status;
|
||||
|
||||
status = le64_to_cpu(desc->wb.qword1.status_error_len);
|
||||
raw_rx_ptype = FIELD_GET(I40E_RXD_QW1_PTYPE_MASK, status);
|
||||
rx_ptype = libie_rx_pt_parse(raw_rx_ptype);
|
||||
|
||||
if (!libeth_rx_pt_has_hash(ctx->xdp.rxq->dev, rx_ptype) ||
|
||||
FIELD_GET(I40E_RX_DESC_STATUS_FLTSTAT_MASK, status) !=
|
||||
I40E_RX_DESC_FLTSTAT_RSS_HASH)
|
||||
return -ENODATA;
|
||||
|
||||
*hash = le32_to_cpu(desc->wb.qword0.hi_dword.rss);
|
||||
*rss_type = rx_ptype.hash_type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i40e_xdp_rx_vlan_tag(const struct xdp_md *_ctx, __be16 *vlan_proto,
|
||||
u16 *vlan_tci)
|
||||
{
|
||||
const struct i40e_xdp_buff *ctx = (const void *)_ctx;
|
||||
const union i40e_rx_desc *desc = ctx->desc;
|
||||
u64 status;
|
||||
|
||||
status = le64_to_cpu(desc->wb.qword1.status_error_len);
|
||||
|
||||
if (!(status & BIT(I40E_RX_DESC_STATUS_L2TAG1P_SHIFT)))
|
||||
return -ENODATA;
|
||||
|
||||
*vlan_proto = cpu_to_be16(ETH_P_8021Q);
|
||||
*vlan_tci = le16_to_cpu(desc->wb.qword0.lo_dword.l2tag1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct xdp_metadata_ops i40e_xdp_metadata_ops = {
|
||||
.xmo_rx_hash = i40e_xdp_rx_hash,
|
||||
.xmo_rx_vlan_tag = i40e_xdp_rx_vlan_tag,
|
||||
};
|
||||
|
||||
static const struct net_device_ops i40e_netdev_ops = {
|
||||
.ndo_open = i40e_open,
|
||||
.ndo_stop = i40e_close,
|
||||
|
|
@ -13784,6 +13835,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
|
|||
i40e_vsi_config_netdev_tc(vsi, vsi->tc_config.enabled_tc);
|
||||
|
||||
netdev->netdev_ops = &i40e_netdev_ops;
|
||||
netdev->xdp_metadata_ops = &i40e_xdp_metadata_ops;
|
||||
netdev->watchdog_timeo = 5 * HZ;
|
||||
i40e_set_ethtool_ops(netdev);
|
||||
|
||||
|
|
|
|||
|
|
@ -2438,10 +2438,11 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,
|
|||
unsigned int *rx_cleaned)
|
||||
{
|
||||
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
|
||||
struct i40e_xdp_buff *xdp_ctx = &rx_ring->xdp_ctx;
|
||||
u16 cleaned_count = I40E_DESC_UNUSED(rx_ring);
|
||||
u16 clean_threshold = rx_ring->count / 2;
|
||||
unsigned int offset = rx_ring->rx_offset;
|
||||
struct xdp_buff *xdp = &rx_ring->xdp;
|
||||
struct xdp_buff *xdp = &xdp_ctx->xdp;
|
||||
unsigned int xdp_xmit = 0;
|
||||
struct bpf_prog *xdp_prog;
|
||||
bool failure = false;
|
||||
|
|
@ -2530,6 +2531,8 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,
|
|||
if (neop)
|
||||
continue;
|
||||
|
||||
xdp_ctx->desc = rx_desc;
|
||||
|
||||
xdp_res = i40e_run_xdp(rx_ring, xdp, xdp_prog);
|
||||
|
||||
if (xdp_res) {
|
||||
|
|
|
|||
|
|
@ -283,6 +283,11 @@ struct i40e_rx_buffer {
|
|||
__u32 page_count;
|
||||
};
|
||||
|
||||
struct i40e_xdp_buff {
|
||||
struct xdp_buff xdp;
|
||||
const union i40e_rx_desc *desc;
|
||||
};
|
||||
|
||||
struct i40e_queue_stats {
|
||||
u64 packets;
|
||||
u64 bytes;
|
||||
|
|
@ -345,7 +350,7 @@ struct i40e_ring {
|
|||
* and to resume packet building for this ring in the next call to
|
||||
* i40e_clean_rx_ring_irq().
|
||||
*/
|
||||
struct xdp_buff xdp;
|
||||
struct i40e_xdp_buff xdp_ctx;
|
||||
|
||||
/* Next descriptor to be processed; next_to_clean is updated only on
|
||||
* processing EOP descriptor
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#ifndef _I40E_TYPE_H_
|
||||
#define _I40E_TYPE_H_
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <uapi/linux/if_ether.h>
|
||||
#include "i40e_adminq.h"
|
||||
#include "i40e_hmc.h"
|
||||
|
|
@ -699,6 +700,10 @@ enum i40e_rx_desc_status_bits {
|
|||
I40E_RX_DESC_STATUS_LAST /* this entry must be last!!! */
|
||||
};
|
||||
|
||||
#define I40E_RX_DESC_STATUS_FLTSTAT_MASK \
|
||||
GENMASK_ULL(I40E_RX_DESC_STATUS_FLTSTAT_SHIFT + 1, \
|
||||
I40E_RX_DESC_STATUS_FLTSTAT_SHIFT)
|
||||
|
||||
#define I40E_RXD_QW1_STATUS_SHIFT 0
|
||||
#define I40E_RXD_QW1_STATUS_MASK ((BIT(I40E_RX_DESC_STATUS_LAST) - 1) \
|
||||
<< I40E_RXD_QW1_STATUS_SHIFT)
|
||||
|
|
|
|||
|
|
@ -246,6 +246,8 @@ bool i40e_alloc_rx_buffers_zc(struct i40e_ring *rx_ring, u16 count)
|
|||
u32 nb_buffs, i;
|
||||
dma_addr_t dma;
|
||||
|
||||
XSK_CHECK_PRIV_TYPE(struct i40e_xdp_buff);
|
||||
|
||||
rx_desc = I40E_RX_DESC(rx_ring, ntu);
|
||||
xdp = i40e_rx_bi(rx_ring, ntu);
|
||||
|
||||
|
|
@ -396,6 +398,14 @@ static void i40e_handle_xdp_result_zc(struct i40e_ring *rx_ring,
|
|||
WARN_ON_ONCE(1);
|
||||
}
|
||||
|
||||
static struct i40e_xdp_buff *xsk_buff_to_i40e_ctx(struct xdp_buff *xdp)
|
||||
{
|
||||
/* xdp_buff pointer used by ZC code path is allocated as xdp_buff_xsk.
|
||||
* i40e_xdp_buff private fields overlap with xdp_buff_xsk->cb.
|
||||
*/
|
||||
return (struct i40e_xdp_buff *)xdp;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_clean_rx_irq_zc - Consumes Rx packets from the hardware ring
|
||||
* @rx_ring: Rx ring
|
||||
|
|
@ -472,6 +482,8 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
|
|||
if (i40e_is_non_eop(rx_ring, rx_desc))
|
||||
continue;
|
||||
|
||||
xsk_buff_to_i40e_ctx(first)->desc = rx_desc;
|
||||
|
||||
xdp_res = i40e_run_xdp_zc(rx_ring, first, xdp_prog);
|
||||
i40e_handle_xdp_result_zc(rx_ring, first, rx_desc, &rx_packets,
|
||||
&rx_bytes, xdp_res, &failure);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user