hw/net/fsl_etsec/registers.h | 1 + hw/net/fsl_etsec/rings.c | 10 ++++++++++ 2 files changed, 11 insertions(+)
The eTSEC hardware strips the 4-byte FCS from received frames by
default (RCTRL[CFA]=0). When CFA=1, FCS is copied to the application
buffer and bd->length includes it.
Previously QEMU always included FCS in bd->length regardless of CFA,
causing guests using the default RCTRL to receive 4 extra bytes per
frame, breaking protocols that validate frame length (e.g. ARP).
Fix by subtracting 4 from bd->length when RCTRL[CFA]=0 (default).
Signed-off-by: Vivien LEGER <vivien.leger@gmail.com>
---
hw/net/fsl_etsec/registers.h | 1 +
hw/net/fsl_etsec/rings.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/hw/net/fsl_etsec/registers.h b/hw/net/fsl_etsec/registers.h
index f085537ecd..1766e39a1a 100644
--- a/hw/net/fsl_etsec/registers.h
+++ b/hw/net/fsl_etsec/registers.h
@@ -103,6 +103,7 @@ extern const eTSEC_Register_Definition eTSEC_registers_def[];
#define RCTRL_PRSDEP_MASK (0x3)
#define RCTRL_PRSDEP_OFFSET (6)
#define RCTRL_RSF (1 << 2)
+#define RCTRL_CFA (1 << 11) /* Copy FCS to application */
/* Index of each register */
diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c
index 22660c32b8..38e27ad6d8 100644
--- a/hw/net/fsl_etsec/rings.c
+++ b/hw/net/fsl_etsec/rings.c
@@ -442,6 +442,16 @@ static void fill_rx_bd(eTSEC *etsec,
cpu_physical_memory_write(bufptr, padd, rem);
}
}
+
+ /* Strip FCS unless RCTRL[CFA] requests copy to application.
+ * Per FSL eTSEC architecture (RCTRL field descriptions):
+ * CFA=0 (reset default): FCS is checked and discarded by hardware,
+ * bd->length should not include the 4-byte FCS.
+ * CFA=1: FCS is copied to the application buffer, bd->length includes FCS.
+ */
+ if (!(etsec->regs[RCTRL].value & RCTRL_CFA) && bd->length >= 4) {
+ bd->length -= 4;
+ }
}
static void rx_init_frame(eTSEC *etsec, const uint8_t *buf, size_t size)
--
2.53.0
Please disregard the previous patch.
The RCTRL[CFA] bit reference was incorrect; CFA appears in the DFVLAN
register context, not RCTRL.
The patch needs further research before resubmission.
Sorry for the noise.
On Sun, Apr 12, 2026 at 3:40 PM Vivien LEGER <vivien.leger@gmail.com> wrote:
> The eTSEC hardware strips the 4-byte FCS from received frames by
> default (RCTRL[CFA]=0). When CFA=1, FCS is copied to the application
> buffer and bd->length includes it.
>
> Previously QEMU always included FCS in bd->length regardless of CFA,
> causing guests using the default RCTRL to receive 4 extra bytes per
> frame, breaking protocols that validate frame length (e.g. ARP).
>
> Fix by subtracting 4 from bd->length when RCTRL[CFA]=0 (default).
>
> Signed-off-by: Vivien LEGER <vivien.leger@gmail.com>
> ---
> hw/net/fsl_etsec/registers.h | 1 +
> hw/net/fsl_etsec/rings.c | 10 ++++++++++
> 2 files changed, 11 insertions(+)
>
> diff --git a/hw/net/fsl_etsec/registers.h b/hw/net/fsl_etsec/registers.h
> index f085537ecd..1766e39a1a 100644
> --- a/hw/net/fsl_etsec/registers.h
> +++ b/hw/net/fsl_etsec/registers.h
> @@ -103,6 +103,7 @@ extern const eTSEC_Register_Definition
> eTSEC_registers_def[];
> #define RCTRL_PRSDEP_MASK (0x3)
> #define RCTRL_PRSDEP_OFFSET (6)
> #define RCTRL_RSF (1 << 2)
> +#define RCTRL_CFA (1 << 11) /* Copy FCS to application */
>
> /* Index of each register */
>
> diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c
> index 22660c32b8..38e27ad6d8 100644
> --- a/hw/net/fsl_etsec/rings.c
> +++ b/hw/net/fsl_etsec/rings.c
> @@ -442,6 +442,16 @@ static void fill_rx_bd(eTSEC *etsec,
> cpu_physical_memory_write(bufptr, padd, rem);
> }
> }
> +
> + /* Strip FCS unless RCTRL[CFA] requests copy to application.
> + * Per FSL eTSEC architecture (RCTRL field descriptions):
> + * CFA=0 (reset default): FCS is checked and discarded by hardware,
> + * bd->length should not include the 4-byte FCS.
> + * CFA=1: FCS is copied to the application buffer, bd->length
> includes FCS.
> + */
> + if (!(etsec->regs[RCTRL].value & RCTRL_CFA) && bd->length >= 4) {
> + bd->length -= 4;
> + }
> }
>
> static void rx_init_frame(eTSEC *etsec, const uint8_t *buf, size_t size)
> --
> 2.53.0
>
>
© 2016 - 2026 Red Hat, Inc.