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, };