From 29cf0022eb3f030d538ba452487c44611b106ed2 Mon Sep 17 00:00:00 2001 From: Gennaro Cimmino Date: Mon, 5 Oct 2026 15:02:37 +0200 Subject: [PATCH] realtek: l3: build the RTL930x offload unconditionally The RTL930x L3 offload was behind NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD, marked experimental and not set in any subtarget config, so a kernel built from those configs had an empty RTL930x L3 configuration and no offload. Remove the symbol and what came with it: the __maybe_unused markers on the RTL930x helpers, and the #ifdef around the commented-out IPv6 hash and MTU helpers in rtl930x.c, which stay as they are. On RTL930x the offload now starts at probe: the L3 controls are programmed, the two catch-all rows are written, the FIB is replayed into the tables and debugfs gets realtek_otto_l3. RTL838x, RTL839x and RTL931x take their configuration by compatible and never depended on the symbol, so nothing changes there at run time. Their kernels now carry the RTL930x code as well: l3.o grows from 26472 to 36748 bytes of text and data on rtl838x, and from 26664 to 36940 on rtl839x. Tested on a Hasivo S1100W-8XGT-SE (RTL9303) with an image built from the rtl930x config as it is, which no longer has any offload symbol: the offload starts on its own, and the bench rounds on trap rows, source-specific IPv6 routes and policy rules pass 46 of 46, 20 of 20 and 47 of 48, the results of images built with the symbol set. The one miss is the test's own: it expects no packet at the gateway, but the trapped packets reach it through the kernel, which routes them by main. Compile-tested for rtl930x, rtl838x and rtl839x. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Gennaro Cimmino Link: https://github.com/openwrt/openwrt/pull/25636 Signed-off-by: Markus Stockhausen --- .../drivers/net/dsa/rtl83xx/Kconfig | 4 ---- .../files-6.18/drivers/net/dsa/rtl83xx/l3.c | 22 ------------------- .../drivers/net/dsa/rtl83xx/rtl930x.c | 4 ---- target/linux/realtek/rtl838x/config-6.18 | 1 - target/linux/realtek/rtl839x/config-6.18 | 1 - target/linux/realtek/rtl930x/config-6.18 | 1 - target/linux/realtek/rtl930x_nand/config-6.18 | 1 - target/linux/realtek/rtl931x/config-6.18 | 1 - target/linux/realtek/rtl931x_nand/config-6.18 | 1 - 9 files changed, 36 deletions(-) diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/Kconfig b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/Kconfig index ce3d8728543..cc8a9beda0f 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/Kconfig +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/Kconfig @@ -6,7 +6,3 @@ config NET_DSA_RTL83XX select REALTEK_OTTO_TABLE help This driver adds support for Realtek RTL83xx series switching. - -config NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD - bool "Realtek RTL930x layer 3 offload (experimental)" - depends on NET_DSA_RTL83XX diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/l3.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/l3.c index 620baeb8024..e47928c4800 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/l3.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/l3.c @@ -217,7 +217,6 @@ static int otto_l3_839x_setup(struct otto_l3_ctrl *ctrl) return 0; } -__maybe_unused static u32 otto_l3_930x_hash4(u32 ip, int algorithm, bool move_dip) { u32 s0, s1, pH; @@ -248,7 +247,6 @@ static u32 otto_l3_930x_hash4(u32 ip, int algorithm, bool move_dip) * Get the Destination-MAC of an L3 egress interface or the Source MAC for routed packets * from the SoC's L3_EGR_INTF_MAC table. Indexes 0-2047 are DMACs, 2048+ are SMACs */ -__maybe_unused static u64 otto_l3_930x_get_egress_mac(struct otto_l3_ctrl *ctrl, u32 idx) { u32 data[2]; @@ -265,7 +263,6 @@ static u64 otto_l3_930x_get_egress_mac(struct otto_l3_ctrl *ctrl, u32 idx) /* Set the Destination-MAC of a route or the Source MAC of an L3 egress interface * in the SoC's L3_EGR_INTF_MAC table. Indexes 0-2047 are DMACs, 2048+ are SMACs */ -__maybe_unused static void otto_l3_930x_set_egress_mac(struct otto_l3_ctrl *ctrl, u32 idx, u64 mac) { u32 data[2] = { mac >> 32, mac }; @@ -275,7 +272,6 @@ static void otto_l3_930x_set_egress_mac(struct otto_l3_ctrl *ctrl, u32 idx, u64 } /* Read a host route entry from the table using its index. Only IPv4 and IPv6 unicast supported */ -__maybe_unused static void otto_l3_930x_host_route_read(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_route *rt) { /* Only the unicast layout is handled below */ @@ -321,7 +317,6 @@ static void otto_l3_930x_host_route_read(struct otto_l3_ctrl *ctrl, int idx, str } /* Write a host route entry from the table using its index. Only unicast routes supported */ -__maybe_unused static void otto_l3_930x_host_route_write(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_route *rt) { /* Only the unicast layout is handled below */ @@ -376,7 +371,6 @@ static void otto_l3_930x_host_route_write(struct otto_l3_ctrl *ctrl, int idx, st */ static const u8 otto_l3_930x_slot_widths[] = { 1, 2, 3, 6 }; -__maybe_unused static int otto_l3_930x_find_slot(struct otto_l3_ctrl *ctrl, struct otto_l3_route *rt, bool must_exist) { int slot_width, algorithm, addr, idx; @@ -426,7 +420,6 @@ static int otto_l3_930x_find_slot(struct otto_l3_ctrl *ctrl, struct otto_l3_rout * Reads a MAC entry for L3 termination as entry point for routing from the hardware table. * idx is the index into the L3_ROUTER_MAC table */ -__maybe_unused static void otto_l3_930x_get_router_mac(struct otto_l3_ctrl *ctrl, u32 idx, struct otto_l3_router_mac *m) { @@ -454,7 +447,6 @@ static void otto_l3_930x_get_router_mac(struct otto_l3_ctrl *ctrl, * Writes a MAC entry for L3 termination as entry point for routing into the hardware table * idx is the index into the L3_ROUTER_MAC table */ -__maybe_unused static void otto_l3_930x_set_router_mac(struct otto_l3_ctrl *ctrl, u32 idx, struct otto_l3_router_mac *m) { @@ -487,7 +479,6 @@ static void otto_l3_930x_set_router_mac(struct otto_l3_ctrl *ctrl, } /* Destination MAC and L3 egress interface ID of a nexthop entry from the SoC's L3_NEXTHOP table */ -__maybe_unused static void otto_l3_930x_get_nexthop(struct otto_l3_ctrl *ctrl, int idx, u16 *dmac_id, u16 *interface) { @@ -507,7 +498,6 @@ static void otto_l3_930x_get_nexthop(struct otto_l3_ctrl *ctrl, * 0x7ffd: TRAP2MASTERCPU * 0x7fff: DMAC_ID_DROP */ -__maybe_unused static void otto_l3_930x_set_nexthop(struct otto_l3_ctrl *ctrl, int idx, u16 dmac_id, u16 interface) { @@ -521,7 +511,6 @@ static void otto_l3_930x_set_nexthop(struct otto_l3_ctrl *ctrl, } /* Prefix length of an IPv6 mask, i.e. how many leading bits are set */ -__maybe_unused static int otto_l3_930x_mask6_len(const struct in6_addr *mask) { int len = 0; @@ -543,7 +532,6 @@ static int otto_l3_930x_mask6_len(const struct in6_addr *mask) /* Read a prefix route entry from the L3_PREFIX_ROUTE_IPUC table * We currently only support IPv4 and IPv6 unicast route */ -__maybe_unused static void otto_l3_930x_route_read(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_route *rt) { bool host_route, default_route; @@ -613,7 +601,6 @@ static void otto_l3_930x_route_read(struct otto_l3_ctrl *ctrl, int idx, struct o dev_dbg(ctrl->dev, "GW: %pI4, prefix_len: %d\n", &rt->dst_ip, rt->prefix_len); } -__maybe_unused static void otto_l3_930x_net6_mask(int prefix_len, struct in6_addr *ip6_m) { int o = prefix_len >> 3; @@ -629,7 +616,6 @@ static void otto_l3_930x_net6_mask(int prefix_len, struct in6_addr *ip6_m) * Look up the index of a prefix route in the routing table CAM for unicast IPv4/6 routes * using hardware offload. */ -__maybe_unused static int otto_l3_930x_route_lookup_hw(struct otto_l3_ctrl *ctrl, struct otto_l3_route *rt) { u32 ip4_m, v; @@ -678,7 +664,6 @@ static int otto_l3_930x_route_lookup_hw(struct otto_l3_ctrl *ctrl, struct otto_l * cannot decode. Returns -EAGAIN when no row was written and the table is as * it was, and -EIO when the block may be half shifted. */ -__maybe_unused static int otto_l3_930x_route_rows_move(struct otto_l3_ctrl *ctrl, int dst, int src, int count) { u32 data[11]; @@ -718,7 +703,6 @@ static int otto_l3_930x_route_rows_move(struct otto_l3_ctrl *ctrl, int dst, int /* Write a prefix route into the routing table CAM at position idx * Currently only IPv4 and IPv6 unicast routes are supported */ -__maybe_unused static void otto_l3_930x_route_write(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_route *rt) { struct in6_addr ip6_m; @@ -868,7 +852,6 @@ static int otto_l3_alloc_router_mac(struct otto_l3_ctrl *ctrl, u64 mac) } /* Read back an egress interface descriptor, the layout written below. */ -__maybe_unused static void otto_l3_930x_get_egress_intf(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_intf *intf) { @@ -894,7 +877,6 @@ static void otto_l3_930x_get_egress_intf(struct otto_l3_ctrl *ctrl, int idx, * 0: FORWARD, 1: DROP, 2: TRAP2CPU, 3: COPY2CPU, 4: TRAP2MASTERCPU, 5: COPY2MASTERCPU, 6: HARDDROP * idx is the index in the HW interface table: idx < 0x80 */ -__maybe_unused static void otto_l3_930x_set_egress_intf(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_intf *intf) { u32 data[2]; @@ -921,7 +903,6 @@ static void otto_l3_930x_set_egress_intf(struct otto_l3_ctrl *ctrl, int idx, str * - The router's MAC address on which routed packets are expected * - MAC addresses used as source macs of routed packets */ -__maybe_unused static int otto_l3_930x_setup(struct otto_l3_ctrl *ctrl) { struct rtl838x_switch_priv *priv = ctrl->priv; @@ -3593,7 +3574,6 @@ static void otto_l3_930x_dbgfs_remove(void *data) * system would find the name taken and log the warning below rather than * share the tree, since the directory is tied to @dev's devm lifetime. */ -__maybe_unused static void otto_l3_930x_dbgfs_init(struct otto_l3_ctrl *ctrl) { struct device *dev = ctrl->dev; @@ -3628,7 +3608,6 @@ const struct otto_l3_config otto_l3_839x_cfg = { }; const struct otto_l3_config otto_l3_930x_cfg = { -#ifdef CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD .use_l3_tables = true, .find_slot = otto_l3_930x_find_slot, .get_egress_intf = otto_l3_930x_get_egress_intf, @@ -3646,7 +3625,6 @@ const struct otto_l3_config otto_l3_930x_cfg = { .route_write = otto_l3_930x_route_write, .setup = otto_l3_930x_setup, .dbgfs_init = otto_l3_930x_dbgfs_init, -#endif }; const struct otto_l3_config otto_l3_931x_cfg = { diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c index 2bef01c5bd5..b0f37d3671a 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c @@ -280,8 +280,6 @@ static void rtl930x_init_eee(struct rtl838x_switch_priv *priv, bool enable) priv->eee_enabled = enable; } -#ifdef CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD - // Currently not used // static u32 rtl930x_l3_hash6(struct in6_addr *ip6, int algorithm, bool move_dip) // { @@ -385,8 +383,6 @@ static void rtl930x_init_eee(struct rtl838x_switch_priv *priv, bool enable) // return mtu_id; // } -#endif /* CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD */ - /* A PIE rule logs its matched packets into the LOG table entry that carries * its own rule ID, in data word 1 - one entry per rule. Counters handed out * by rtldsa_packet_cntr_alloc() for L3 route statistics start above the PIE diff --git a/target/linux/realtek/rtl838x/config-6.18 b/target/linux/realtek/rtl838x/config-6.18 index a4614e35a3c..afa285d64c8 100644 --- a/target/linux/realtek/rtl838x/config-6.18 +++ b/target/linux/realtek/rtl838x/config-6.18 @@ -170,7 +170,6 @@ CONFIG_NEED_PER_CPU_KM=y CONFIG_NET_DEVLINK=y CONFIG_NET_DSA=y CONFIG_NET_DSA_RTL83XX=y -# CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD is not set CONFIG_NET_DSA_TAG_RTL_OTTO=y CONFIG_NET_EGRESS=y CONFIG_NET_INGRESS=y diff --git a/target/linux/realtek/rtl839x/config-6.18 b/target/linux/realtek/rtl839x/config-6.18 index 759c6ae6191..46623eb24eb 100644 --- a/target/linux/realtek/rtl839x/config-6.18 +++ b/target/linux/realtek/rtl839x/config-6.18 @@ -175,7 +175,6 @@ CONFIG_NEED_SRCU_NMI_SAFE=y CONFIG_NET_DEVLINK=y CONFIG_NET_DSA=y CONFIG_NET_DSA_RTL83XX=y -# CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD is not set CONFIG_NET_DSA_TAG_RTL_OTTO=y CONFIG_NET_EGRESS=y CONFIG_NET_FLOW_LIMIT=y diff --git a/target/linux/realtek/rtl930x/config-6.18 b/target/linux/realtek/rtl930x/config-6.18 index df9c8dbe4f4..949e5b7f2b4 100644 --- a/target/linux/realtek/rtl930x/config-6.18 +++ b/target/linux/realtek/rtl930x/config-6.18 @@ -166,7 +166,6 @@ CONFIG_NEED_SRCU_NMI_SAFE=y CONFIG_NET_DEVLINK=y CONFIG_NET_DSA=y CONFIG_NET_DSA_RTL83XX=y -# CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD is not set CONFIG_NET_DSA_TAG_RTL_OTTO=y CONFIG_NET_EGRESS=y CONFIG_NET_FLOW_LIMIT=y diff --git a/target/linux/realtek/rtl930x_nand/config-6.18 b/target/linux/realtek/rtl930x_nand/config-6.18 index 006594b5e99..3d8ab7abad6 100644 --- a/target/linux/realtek/rtl930x_nand/config-6.18 +++ b/target/linux/realtek/rtl930x_nand/config-6.18 @@ -176,7 +176,6 @@ CONFIG_NEED_SRCU_NMI_SAFE=y CONFIG_NET_DEVLINK=y CONFIG_NET_DSA=y CONFIG_NET_DSA_RTL83XX=y -# CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD is not set CONFIG_NET_DSA_TAG_RTL_OTTO=y CONFIG_NET_EGRESS=y CONFIG_NET_FLOW_LIMIT=y diff --git a/target/linux/realtek/rtl931x/config-6.18 b/target/linux/realtek/rtl931x/config-6.18 index 658811e415e..aa9005fefa9 100644 --- a/target/linux/realtek/rtl931x/config-6.18 +++ b/target/linux/realtek/rtl931x/config-6.18 @@ -174,7 +174,6 @@ CONFIG_NEED_SRCU_NMI_SAFE=y CONFIG_NET_DEVLINK=y CONFIG_NET_DSA=y CONFIG_NET_DSA_RTL83XX=y -# CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD is not set CONFIG_NET_DSA_TAG_RTL_OTTO=y CONFIG_NET_EGRESS=y CONFIG_NET_FLOW_LIMIT=y diff --git a/target/linux/realtek/rtl931x_nand/config-6.18 b/target/linux/realtek/rtl931x_nand/config-6.18 index 27d859fa6bf..56749cf9bed 100644 --- a/target/linux/realtek/rtl931x_nand/config-6.18 +++ b/target/linux/realtek/rtl931x_nand/config-6.18 @@ -184,7 +184,6 @@ CONFIG_NEED_SRCU_NMI_SAFE=y CONFIG_NET_DEVLINK=y CONFIG_NET_DSA=y CONFIG_NET_DSA_RTL83XX=y -# CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD is not set CONFIG_NET_DSA_TAG_RTL_OTTO=y CONFIG_NET_EGRESS=y CONFIG_NET_FLOW_LIMIT=y