From: Markus Stockhausen Date: Sun, 28 Jun 2026 07:36:35 +0000 (+0200) Subject: realtek: l3: move host_route_write to layer 3 source X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=04ca93a8561f3909dfb2ccd5538cd9959c855906;p=thirdparty%2Fopenwrt.git realtek: l3: move host_route_write to layer 3 source Move another function from DSA to layer 3 coding. Link: https://github.com/openwrt/openwrt/pull/23979 Signed-off-by: Markus Stockhausen --- 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 deef903306a..2dbadb60675 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 @@ -95,6 +95,59 @@ static void otto_l3_839x_route_write(struct otto_l3_ctrl *ctrl, int idx, struct rtl_table_release(r); } +/* 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) +{ + /* The table has a size of 5 (for UC, 11 for MC) registers */ + struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 1); + u32 v; + + idx = ((idx / 6) * 8) + (idx % 6); + + dev_dbg(ctrl->dev, "index %d is valid: %d\n", idx, rt->attr.valid); + dev_dbg(ctrl->dev, "next_hop: %d, hit: %d, action :%d, ttl_dec %d, ttl_check %d, dst_null %d\n", + rt->nh.id, rt->attr.hit, rt->attr.action, rt->attr.ttl_dec, rt->attr.ttl_check, + rt->attr.dst_null); + dev_dbg(ctrl->dev, "GW: %pI4, prefix_len: %d\n", &rt->dst_ip, rt->prefix_len); + + v = BIT(31); /* Entry is valid */ + v |= (rt->attr.type & 0x3) << 29; + v |= rt->attr.hit ? BIT(20) : 0; + v |= rt->attr.dst_null ? BIT(19) : 0; + v |= (rt->attr.action & 0x3) << 17; + v |= (rt->nh.id & 0x7ff) << 6; + v |= rt->attr.ttl_dec ? BIT(5) : 0; + v |= rt->attr.ttl_check ? BIT(4) : 0; + v |= rt->attr.qos_as ? BIT(3) : 0; + v |= rt->attr.qos_prio & 0x7; + + sw_w32(v, rtl_table_data(r, 0)); + switch (rt->attr.type) { + case 0: /* IPv4 Unicast route */ + sw_w32(0, rtl_table_data(r, 1)); + sw_w32(0, rtl_table_data(r, 2)); + sw_w32(0, rtl_table_data(r, 3)); + sw_w32(rt->dst_ip, rtl_table_data(r, 4)); + break; + case 2: /* IPv6 Unicast route */ + sw_w32(rt->dst_ip6.s6_addr32[0], rtl_table_data(r, 1)); + sw_w32(rt->dst_ip6.s6_addr32[1], rtl_table_data(r, 2)); + sw_w32(rt->dst_ip6.s6_addr32[2], rtl_table_data(r, 3)); + sw_w32(rt->dst_ip6.s6_addr32[3], rtl_table_data(r, 4)); + break; + case 1: /* IPv4 Multicast route */ + case 3: /* IPv6 Multicast route */ + dev_warn(ctrl->dev, "route type not supported\n"); + goto out; + } + + rtl_table_write(r, idx); + +out: + rtl_table_release(r); +} + /* * 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 @@ -591,7 +644,7 @@ static int otto_l3_nexthop_update(struct otto_l3_ctrl *ctrl, __be32 ip_addr, u64 int slot = priv->r->find_l3_slot(r, false); dev_info(ctrl->dev, "Got slot for route: %d\n", slot); - priv->r->host_route_write(slot, r); + ctrl->cfg->host_route_write(ctrl, slot, r); } else { ctrl->cfg->route_write(ctrl, r->id, r); r->pr.fwd_sel = true; @@ -667,7 +720,7 @@ static void otto_l3_route_remove(struct otto_l3_ctrl *ctrl, struct otto_l3_route id = priv->r->find_l3_slot(r, false); dev_dbg(ctrl->dev, "Got id for host route: %d\n", id); r->attr.valid = false; - priv->r->host_route_write(id, r); + ctrl->cfg->host_route_write(ctrl, id, r); clear_bit(r->id - MAX_ROUTES, ctrl->host_route_use_bm); } else { /* If there is a HW representation of the route, delete it */ @@ -812,7 +865,7 @@ static int otto_l3_fib_add_v4(struct otto_l3_ctrl *ctrl, struct fib_entry_notifi } /* Allocate route or host-route entry (if hardware supports this) */ - if (info->dst_len == 32 && priv->r->host_route_write) + if (info->dst_len == 32 && ctrl->cfg->host_route_write) route = otto_l3_host_route_alloc(ctrl, nh->fib_nh_gw4); else route = otto_l3_route_alloc(ctrl, nh->fib_nh_gw4); @@ -852,7 +905,7 @@ static int otto_l3_fib_add_v4(struct otto_l3_ctrl *ctrl, struct fib_entry_notifi slot = priv->r->find_l3_slot(route, false); dev_dbg(ctrl->dev, "Got slot for route: %d\n", slot); - priv->r->host_route_write(slot, route); + ctrl->cfg->host_route_write(ctrl, slot, route); } } @@ -1096,6 +1149,7 @@ 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 + .host_route_write = otto_l3_930x_host_route_write, .get_router_mac = otto_l3_930x_get_router_mac, .set_router_mac = otto_l3_930x_set_router_mac, .get_nexthop = otto_l3_930x_get_nexthop, diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/l3.h b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/l3.h index f780e6e4248..276c19a80bc 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/l3.h +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/l3.h @@ -28,6 +28,7 @@ struct otto_l3_router_mac { struct otto_l3_config { + void (*host_route_write)(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_route *rt); void (*get_router_mac)(struct otto_l3_ctrl *ctrl, u32 idx, struct otto_l3_router_mac *m); void (*set_router_mac)(struct otto_l3_ctrl *ctrl, u32 idx, struct otto_l3_router_mac *m); void (*get_nexthop)(struct otto_l3_ctrl *ctrl, int idx, u16 *dmac_id, u16 *interface); diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h index 4f172a4835d..dea01a6f727 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h @@ -1417,7 +1417,6 @@ struct rtldsa_config { void (*l2_learning_setup)(void); u32 (*packet_cntr_read)(int counter); void (*packet_cntr_clear)(int counter); - void (*host_route_write)(int idx, struct otto_l3_route *rt); int (*l3_setup)(struct rtl838x_switch_priv *priv); u64 (*get_l3_egress_mac)(u32 idx); void (*set_l3_egress_mac)(u32 idx, u64 mac); 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 a2acd1bf271..a07100cf9f4 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 @@ -1317,61 +1317,6 @@ out: rtl_table_release(r); } -/* Write a host route entry from the table using its index - * We currently only support IPv4 and IPv6 unicast route - */ -static void rtl930x_host_route_write(int idx, struct otto_l3_route *rt) -{ - u32 v; - /* Access L3_HOST_ROUTE_IPUC table (1) via register RTL9300_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 1); - /* The table has a size of 5 (for UC, 11 for MC) registers */ - - idx = ((idx / 6) * 8) + (idx % 6); - - pr_debug("%s: index %d is valid: %d\n", __func__, idx, rt->attr.valid); - pr_debug("%s: next_hop: %d, hit: %d, action :%d, ttl_dec %d, ttl_check %d, dst_null %d\n", - __func__, rt->nh.id, rt->attr.hit, rt->attr.action, rt->attr.ttl_dec, rt->attr.ttl_check, - rt->attr.dst_null); - pr_debug("%s: GW: %pI4, prefix_len: %d\n", __func__, &rt->dst_ip, rt->prefix_len); - - v = BIT(31); /* Entry is valid */ - v |= (rt->attr.type & 0x3) << 29; - v |= rt->attr.hit ? BIT(20) : 0; - v |= rt->attr.dst_null ? BIT(19) : 0; - v |= (rt->attr.action & 0x3) << 17; - v |= (rt->nh.id & 0x7ff) << 6; - v |= rt->attr.ttl_dec ? BIT(5) : 0; - v |= rt->attr.ttl_check ? BIT(4) : 0; - v |= rt->attr.qos_as ? BIT(3) : 0; - v |= rt->attr.qos_prio & 0x7; - - sw_w32(v, rtl_table_data(r, 0)); - switch (rt->attr.type) { - case 0: /* IPv4 Unicast route */ - sw_w32(0, rtl_table_data(r, 1)); - sw_w32(0, rtl_table_data(r, 2)); - sw_w32(0, rtl_table_data(r, 3)); - sw_w32(rt->dst_ip, rtl_table_data(r, 4)); - break; - case 2: /* IPv6 Unicast route */ - sw_w32(rt->dst_ip6.s6_addr32[0], rtl_table_data(r, 1)); - sw_w32(rt->dst_ip6.s6_addr32[1], rtl_table_data(r, 2)); - sw_w32(rt->dst_ip6.s6_addr32[2], rtl_table_data(r, 3)); - sw_w32(rt->dst_ip6.s6_addr32[3], rtl_table_data(r, 4)); - break; - case 1: /* IPv4 Multicast route */ - case 3: /* IPv6 Multicast route */ - pr_warn("%s: route type not supported\n", __func__); - goto out; - } - - rtl_table_write(r, idx); - -out: - rtl_table_release(r); -} - static int rtl930x_find_l3_slot(struct otto_l3_route *rt, bool must_exist) { int slot_width, algorithm, addr, idx; @@ -2574,7 +2519,6 @@ const struct rtldsa_config rtldsa_930x_cfg = { .packet_cntr_read = rtl930x_packet_cntr_read, .packet_cntr_clear = rtl930x_packet_cntr_clear, #ifdef CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD - .host_route_write = rtl930x_host_route_write, .l3_setup = rtl930x_l3_setup, .get_l3_egress_mac = rtl930x_get_l3_egress_mac, .set_l3_egress_mac = rtl930x_set_l3_egress_mac,