Re: [Intel-wired-lan] [PATCH net] iavf: cap advertised max_pkt_size at the single-buffer HW limit
From: Jacob Keller
Date: Tue Jun 16 2026 - 19:18:55 EST
On 6/16/2026 1:01 PM, Dave 🧔 Butler wrote:
> From: Dave Butler <david.butler@xxxxxxxxxxx>
>
> Since commit 5fa4caff59f2 ("iavf: switch to Page Pool")
> iavf_configure_queues() advertises max_pkt_size to the PF as:
>
> max_frame = LIBIE_MAX_RX_FRM_LEN(adapter->rx_rings->pp->p.offset);
> max_frame = min_not_zero(adapter->vf_res->max_mtu, max_frame);
>
> LIBIE_MAX_RX_FRM_LEN (16382) is the multi-descriptor scatter/gather frame
> ceiling, not a single-queue value, and it exceeds the E810 MAC frame size
> maximum of 9728. Per the E810 datasheet (613875-009 section 13.2.2.17.1)
> the Tx frame-size register PRTDCB_TDPUC.MAX_TXFRAME has a maximum of
> 0x2600 (9728); larger frames are discarded. The in-tree ice driver encodes
> the same value as ICE_AQ_SET_MAC_FRAME_SIZE_MAX (== LIBIE_MAX_RX_BUF_LEN ==
> 9728), and the VF clamped max_frame to IAVF_MAX_RXBUFFER (9728) before this
> commit.
>
> When the PF advertises vf_res->max_mtu as 0, min_not_zero() leaves
> max_frame at 16382. The Linux ice PF advertises max_mtu = port MAC frame
> size (<= 9728), so a VF behind ice never sends more than that. The ESXi
> "icen" PF on E810 advertises max_mtu as 0, so the VF sends
> max_pkt_size = 16382, which icen rejects while programming the queue
> context for VIRTCHNL_OP_CONFIG_VSI_QUEUES (opcode 6):
>
> icen_ConfigureTxQueue: VSI 8: Failed to set LAN Tx queue context for
> absolute Tx queue 64, Error: ICE_ERR_PARAM
> indrv_SendMsgToVf: VF 0: Failed opcode 6, Error -5
>
> iavf 0000:03:00.0: PF returned error -5 (IAVF_ERR_PARAM) to our request 6
> iavf 0000:03:00.0 ethX: NETDEV WATCHDOG: transmit queue N timed out
>
> The VF's queues never come up; under SR-IOV passthrough the mis-programmed
> queue can also trigger a fatal IOMMU fault in the guest. Forcing only
> max_pkt_size back to 9728 (and leaving the Page Pool rx_buf_len/
> databuffer_size untouched) makes the VF come up; databuffer_size is not
> involved. This was confirmed on two E810 NVM revisions (3.00 and 4.51) and
> two icen versions (1.14.2.0 and the latest 2.3.3.0): all reject the
> unpatched VF and accept the patched one, so the trigger is the icen PF
> behaviour, not the firmware or icen revision. Reported by several users on
> E810 + ESXi icen with v6.10+ guests:
>
> Link: https://community.intel.com/t5/Ethernet-Products/E810-C-iavf-driver-issue-on-Linux-6-12/m-p/1737490
> Link: https://access.redhat.com/solutions/6973766
> Link: https://knowledge.broadcom.com/external/article/404315/sriov-enabled-vms-network-adaptor-goes-d.html
>
> Cap max_frame at the single-buffer hardware limit, restoring the
> pre-Page-Pool behaviour while keeping the Page Pool rx_buf_len unchanged.
>
> Fixes: 5fa4caff59f2 ("iavf: switch to Page Pool")
> Signed-off-by: Dave Butler <david.butler@xxxxxxxxxxx>
> ---
I suppose it makes sense to restore the previous behavior pre-pagepool
even if this smells like a bug on the PF side advertising 0 as the
maximum size.
The only real downside here would be if the iAVF interface is ever used
again with another device that supports a larger maximum frame size. I
suppose we can always handle that in the future with an additional check
based on some other data. One possibility is to only apply the final
maximum here if the PF actually sends us 0? Mayube not worth it until/if
we actually have such devices.
Acked-by: Jacob Keller <jacob.e.keller@xxxxxxxxx>
> drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> index 4f2defd2331b..2632eeed776c 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> @@ -382,6 +382,14 @@ void iavf_configure_queues(struct iavf_adapter *adapter)
>
> max_frame = LIBIE_MAX_RX_FRM_LEN(adapter->rx_rings->pp->p.offset);
> max_frame = min_not_zero(adapter->vf_res->max_mtu, max_frame);
> + /* The PF programs max_pkt_size into the per-queue Rx context "rxmax".
> + * LIBIE_MAX_RX_FRM_LEN is the multi-descriptor (S/G) frame ceiling
> + * (16382), but that exceeds the E810 max MAC frame size (9728); some
> + * PFs reject the out-of-range value with VIRTCHNL_STATUS_ERR_PARAM.
> + * Cap it at the single-buffer HW limit (== the MAC frame max),
> + * restoring the pre-Page-Pool behaviour.
> + */
> + max_frame = min(max_frame, LIBIE_MAX_RX_BUF_LEN);
>
> if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
> /* bail because we already have a command pending */
>
> base-commit: fbc6a80cb5d3fd4ac4b56e8c9d791dd17be890c4