From: Harshal Gohel Date: Fri, 8 Aug 2025 15:31:03 +0000 (+0200) Subject: realtek: rtl930x: Add support for trapping management frames X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=75fe6b2d0b919be29c5f7d6dca373c617747b8d1;p=openwrt%2Fstaging%2Fnbd.git realtek: rtl930x: Add support for trapping management frames Driver needs to configure management frame actions To support LLDP, EAPOL or MSTP, which needs to be trapped to the CPU instead of being forwarded Signed-off-by: Harshal Gohel Signed-off-by: Sharadanand Karanjkar Link: https://github.com/openwrt/openwrt/pull/19571 Signed-off-by: Hauke Mehrtens --- diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h index 544f693883..5ec3905a80 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h @@ -471,6 +471,7 @@ typedef enum { #define RTL931X_RMA_LLDP_CTRL (0x8918) #define RTL930X_RMA_EAPOL_CTRL (0x9F08) +#define RTL930X_SPCL_TRAP_PORT_CTRL (0xA1A0) #define RTL931X_RMA_EAPOL_CTRL (0x8930) #define RTL931X_TRAP_ARP_GRAT_PORT_ACT (0x8C04) diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h index ef5230d92e..6d7f154129 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h @@ -209,7 +209,10 @@ void rtl9300_dump_debug(void); void rtl930x_pie_rule_dump_raw(u32 r[]); void rtl931x_print_matrix(void); + +void rtldsa_930x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action); void rtl931x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action); + void rtl931x_sw_init(struct rtl838x_switch_priv *priv); #endif /* _NET_DSA_RTL83XX_H */ diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c index c84ed6cca0..a421db4d0d 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c @@ -657,6 +657,85 @@ static void rtl930x_write_mcast_pmask(int idx, u64 portmask) rtl_table_release(q); } +void rtldsa_930x_set_receive_management_action(int port, rma_ctrl_t type, + action_type_t action) +{ + u32 shift; + u32 value; + u32 reg; + + /* hack for value mapping */ + if (type == GRATARP && action == COPY2CPU) + action = TRAP2MASTERCPU; + + /* PTP doesn't allow to flood to all ports */ + if (action == FLOODALL && + (type == PTP || type == PTP_UDP || type == PTP_ETH2)) { + pr_warn("%s: Port flooding not supported for PTP\n", __func__); + return; + } + + switch(action) { + case FORWARD: + value = 0; + break; + case DROP: + value = 1; + break; + case TRAP2CPU: + value = 2; + break; + case TRAP2MASTERCPU: + value = 3; + break; + case FLOODALL: + value = 4; + break; + default: + return; + } + + switch(type) { + case BPDU: + reg = RTL930X_RMA_BPDU_CTRL + (port / 10) * 4; + shift = (port % 10) * 3; + sw_w32_mask(GENMASK(shift + 2, shift), value << shift, reg); + break; + case PTP: + reg = RTL930X_RMA_PTP_CTRL + port * 4; + + /* udp */ + sw_w32_mask(GENMASK(3, 2), value << 2, reg); + + /* eth2 */ + sw_w32_mask(GENMASK(1, 0), value, reg); + break; + case PTP_UDP: + reg = RTL930X_RMA_PTP_CTRL + port * 4; + sw_w32_mask(GENMASK(3, 2), value << 2, reg); + break; + case PTP_ETH2: + reg = RTL930X_RMA_PTP_CTRL + port * 4; + sw_w32_mask(GENMASK(1, 0), value, reg); + break; + case LLDP: + reg = RTL930X_RMA_LLDP_CTRL + (port / 10) * 4; + shift = (port % 10) * 3; + sw_w32_mask(GENMASK(shift + 2, shift), value << shift, reg); + break; + case EAPOL: + reg = RTL930X_RMA_EAPOL_CTRL + (port / 10) * 4; + shift = (port % 10) * 3; + sw_w32_mask(GENMASK(shift + 2, shift), value << shift, reg); + break; + case GRATARP: + reg = RTL930X_SPCL_TRAP_PORT_CTRL + (port / 16) * 4; + shift = (port % 16) * 2; + sw_w32_mask(GENMASK(shift + 1, shift), value << shift, reg); + break; + } +} + static u64 rtl930x_traffic_get(int source) { u32 v; @@ -2419,4 +2498,5 @@ const struct rtl838x_reg rtl930x_reg = { .led_init = rtl930x_led_init, .enable_learning = rtldsa_930x_enable_learning, .enable_flood = rtldsa_930x_enable_flood, + .set_receive_management_action = rtldsa_930x_set_receive_management_action, };