From 0d6b7fb56e06490caf70daad2e6e5386190569c3 Mon Sep 17 00:00:00 2001 From: Issam Hamdi Date: Tue, 9 Sep 2025 15:32:29 +0200 Subject: [PATCH] realtek: rtl93xx: Ignore STP for per port TX If transmissions are done outside of the DSA switch (directly from the CPU port), the STP state must not block the transmission. Otherwise, STP frames are not correctly submitted and the STP frames cannot correctly detect loops before switching a port in the forwarding state. The same applies for the LLDP frames. These must be submitted independent of the STP state to identify neighbors or configure POE limits. It is not necessary to filter specific destination mac addresses because the transmission was done outside the bridge/switch in the first place. The transmission is therefore forced. Signed-off-by: Issam Hamdi Co-developed-by: Sven Eckelmann Signed-off-by: Sven Eckelmann Link: https://github.com/openwrt/openwrt/pull/20184 Signed-off-by: Robert Marko --- .../files-6.12/drivers/net/ethernet/rtl838x_eth.c | 10 ++++++++-- .../files-6.12/drivers/net/ethernet/rtl838x_eth.h | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c index 99422d0d4ca..6d7baee3176 100644 --- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c +++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c @@ -131,7 +131,10 @@ static void rtl839x_create_tx_header(struct p_hdr *h, unsigned int dest_port, in static void rtl930x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio) { h->cpu_tag[0] = 0x8000; /* CPU tag marker */ - h->cpu_tag[1] = 0x0200; /* Set FWD_TYPE to LOGICAL (2) */ + + h->cpu_tag[1] = FIELD_PREP(RTL93XX_CPU_TAG1_FWD_MASK, + RTL93XX_CPU_TAG1_FWD_LOGICAL); + h->cpu_tag[1] |= FIELD_PREP(RTL93XX_CPU_TAG1_IGNORE_STP_MASK, 1); h->cpu_tag[2] = 0; h->cpu_tag[3] = 0; h->cpu_tag[4] = 0; @@ -147,7 +150,10 @@ static void rtl930x_create_tx_header(struct p_hdr *h, unsigned int dest_port, in static void rtl931x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio) { h->cpu_tag[0] = 0x8000; /* CPU tag marker */ - h->cpu_tag[1] = 0x0200; /* Set FWD_TYPE to LOGICAL (2) */ + + h->cpu_tag[1] = FIELD_PREP(RTL93XX_CPU_TAG1_FWD_MASK, + RTL93XX_CPU_TAG1_FWD_LOGICAL); + h->cpu_tag[1] |= FIELD_PREP(RTL93XX_CPU_TAG1_IGNORE_STP_MASK, 1); h->cpu_tag[2] = 0; h->cpu_tag[3] = 0; h->cpu_tag[4] = h->cpu_tag[5] = h->cpu_tag[6] = h->cpu_tag[7] = 0; diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h index f639bc6d43a..f220a4dd64d 100644 --- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h +++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h @@ -222,6 +222,21 @@ /* Registers of the internal Serdes of the 8380 */ #define RTL838X_SDS4_FIB_REG0 (0xF800) +/* shared CPU tag definitions for RTL930X/RTL931X */ +#define RTL93XX_CPU_TAG1_FWD_MASK GENMASK(11, 8) + +#define RTL93XX_CPU_TAG1_FWD_ALE 0 +#define RTL93XX_CPU_TAG1_FWD_PHYSICAL 1 +#define RTL93XX_CPU_TAG1_FWD_LOGICAL 2 +#define RTL93XX_CPU_TAG1_FWD_TRUNK 3 +#define RTL93XX_CPU_TAG1_FWD_ONE_HOP 4 +#define RTL93XX_CPU_TAG1_FWD_LOGICAL_ONE_HOP 5 +#define RTL93XX_CPU_TAG1_FWD_UCST_CPU_MIN_PORT 6 +#define RTL93XX_CPU_TAG1_FWD_UCST_CPU 7 +#define RTL93XX_CPU_TAG1_FWD_BCST_CPU 8 + +#define RTL93XX_CPU_TAG1_IGNORE_STP_MASK GENMASK(2, 2) + /* Default MTU with jumbo frames support */ #define DEFAULT_MTU 9000 -- 2.47.3