From: Markus Stockhausen Date: Sat, 27 Jun 2026 19:39:23 +0000 (+0200) Subject: realtek: l3: move route_lookup_hw over to layer 3 structure X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0738b151eb30bbf6f166dab45cc40c60aef882db;p=thirdparty%2Fopenwrt.git realtek: l3: move route_lookup_hw over to layer 3 structure Another layer 3 function that needs a new home. As always convert the code to dev_...() logging. Link: https://github.com/openwrt/openwrt/pull/23963 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 9083ffe0b21..f6b9d0f10a4 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 @@ -222,6 +222,52 @@ static void otto_l3_930x_net6_mask(int prefix_len, struct in6_addr *ip6_m) ip6_m->s6_addr[o] |= b ? 0xff00 >> b : 0x00; } +/* + * 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) +{ + struct in6_addr ip6_m; + u32 ip4_m, v; + + if (rt->attr.type == 1 || rt->attr.type == 3) /* Hardware only supports UC routes */ + return -1; + + sw_w32_mask(0x3 << 19, rt->attr.type, RTL930X_L3_HW_LU_KEY_CTRL); + if (rt->attr.type) { /* IPv6 */ + otto_l3_930x_net6_mask(rt->prefix_len, &ip6_m); + for (int i = 0; i < 4; i++) + sw_w32(rt->dst_ip6.s6_addr32[0] & ip6_m.s6_addr32[0], + RTL930X_L3_HW_LU_KEY_IP_CTRL + (i << 2)); + } else { /* IPv4 */ + ip4_m = inet_make_mask(rt->prefix_len); + sw_w32(0, RTL930X_L3_HW_LU_KEY_IP_CTRL); + sw_w32(0, RTL930X_L3_HW_LU_KEY_IP_CTRL + 4); + sw_w32(0, RTL930X_L3_HW_LU_KEY_IP_CTRL + 8); + v = rt->dst_ip & ip4_m; + dev_dbg(ctrl->dev, "searching for %pI4\n", &v); + sw_w32(v, RTL930X_L3_HW_LU_KEY_IP_CTRL + 12); + } + + /* Execute CAM lookup in SoC */ + sw_w32(BIT(15), RTL930X_L3_HW_LU_CTRL); + + /* Wait until execute bit clears and result is ready */ + do { + v = sw_r32(RTL930X_L3_HW_LU_CTRL); + } while (v & BIT(15)); + + dev_dbg(ctrl->dev, "found: %d, index: %d\n", !!(v & BIT(14)), v & 0x1ff); + + /* Test if search successful (BIT 14 set) */ + if (v & BIT(14)) + return v & 0x1ff; + + return -1; +} + /* Write a prefix route into the routing table CAM at position idx * Currently only IPv4 and IPv6 unicast routes are supported */ @@ -551,8 +597,8 @@ static void otto_l3_route_remove(struct otto_l3_ctrl *ctrl, struct otto_l3_route clear_bit(r->id - MAX_ROUTES, priv->host_route_use_bm); } else { /* If there is a HW representation of the route, delete it */ - if (priv->r->route_lookup_hw) { - id = priv->r->route_lookup_hw(r); + if (ctrl->cfg->route_lookup_hw) { + id = ctrl->cfg->route_lookup_hw(ctrl, r); dev_info(ctrl->dev, "Got id for prefix route: %d\n", id); r->attr.valid = false; ctrl->cfg->route_write(ctrl, id, r); @@ -978,6 +1024,7 @@ const struct otto_l3_config otto_l3_930x_cfg = { #ifdef CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD .get_nexthop = otto_l3_930x_get_nexthop, .set_nexthop = otto_l3_930x_set_nexthop, + .route_lookup_hw = otto_l3_930x_route_lookup_hw, .route_read = otto_l3_930x_route_read, .route_write = otto_l3_930x_route_write, #endif 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 6c8d0e730bb..78c2c4d5bd4 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 @@ -8,6 +8,7 @@ struct otto_l3_config { void (*get_nexthop)(struct otto_l3_ctrl *ctrl, int idx, u16 *dmac_id, u16 *interface); void (*set_nexthop)(struct otto_l3_ctrl *ctrl, int idx, u16 dmac_id, u16 interface); + int (*route_lookup_hw)(struct otto_l3_ctrl *ctrl, struct otto_l3_route *rt); void (*route_read)(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_route *rt); void (*route_write)(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_route *rt); }; 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 36a6641b8bb..02732b241ef 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 @@ -1442,7 +1442,6 @@ struct rtldsa_config { u64 (*get_l3_egress_mac)(u32 idx); void (*set_l3_egress_mac)(u32 idx, u64 mac); int (*find_l3_slot)(struct otto_l3_route *rt, bool must_exist); - int (*route_lookup_hw)(struct otto_l3_route *rt); void (*get_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m); void (*set_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m); void (*set_l3_egress_intf)(int idx, struct rtl838x_l3_intf *intf); 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 fd11e3adfe8..2e09d091f66 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 @@ -1265,16 +1265,6 @@ static u32 rtl930x_l3_hash4(u32 ip, int algorithm, bool move_dip) // return hash; // } -static void rtl930x_net6_mask(int prefix_len, struct in6_addr *ip6_m) -{ - int o, b; - /* Define network mask */ - o = prefix_len >> 3; - b = prefix_len & 0x7; - memset(ip6_m->s6_addr, 0xff, o); - ip6_m->s6_addr[o] |= b ? 0xff00 >> b : 0x00; -} - /* Read a host route entry from the table using its index * We currently only support IPv4 and IPv6 unicast route */ @@ -1382,50 +1372,6 @@ out: rtl_table_release(r); } -/* Look up the index of a prefix route in the routing table CAM for unicast IPv4/6 routes - * using hardware offload. - */ -static int rtl930x_route_lookup_hw(struct otto_l3_route *rt) -{ - u32 ip4_m, v; - struct in6_addr ip6_m; - - if (rt->attr.type == 1 || rt->attr.type == 3) /* Hardware only supports UC routes */ - return -1; - - sw_w32_mask(0x3 << 19, rt->attr.type, RTL930X_L3_HW_LU_KEY_CTRL); - if (rt->attr.type) { /* IPv6 */ - rtl930x_net6_mask(rt->prefix_len, &ip6_m); - for (int i = 0; i < 4; i++) - sw_w32(rt->dst_ip6.s6_addr32[0] & ip6_m.s6_addr32[0], - RTL930X_L3_HW_LU_KEY_IP_CTRL + (i << 2)); - } else { /* IPv4 */ - ip4_m = inet_make_mask(rt->prefix_len); - sw_w32(0, RTL930X_L3_HW_LU_KEY_IP_CTRL); - sw_w32(0, RTL930X_L3_HW_LU_KEY_IP_CTRL + 4); - sw_w32(0, RTL930X_L3_HW_LU_KEY_IP_CTRL + 8); - v = rt->dst_ip & ip4_m; - pr_debug("%s: searching for %pI4\n", __func__, &v); - sw_w32(v, RTL930X_L3_HW_LU_KEY_IP_CTRL + 12); - } - - /* Execute CAM lookup in SoC */ - sw_w32(BIT(15), RTL930X_L3_HW_LU_CTRL); - - /* Wait until execute bit clears and result is ready */ - do { - v = sw_r32(RTL930X_L3_HW_LU_CTRL); - } while (v & BIT(15)); - - pr_debug("%s: found: %d, index: %d\n", __func__, !!(v & BIT(14)), v & 0x1ff); - - /* Test if search successful (BIT 14 set) */ - if (v & BIT(14)) - return v & 0x1ff; - - return -1; -} - static int rtl930x_find_l3_slot(struct otto_l3_route *rt, bool must_exist) { int slot_width, algorithm, addr, idx; @@ -2706,7 +2652,6 @@ const struct rtldsa_config rtldsa_930x_cfg = { .get_l3_egress_mac = rtl930x_get_l3_egress_mac, .set_l3_egress_mac = rtl930x_set_l3_egress_mac, .find_l3_slot = rtl930x_find_l3_slot, - .route_lookup_hw = rtl930x_route_lookup_hw, .get_l3_router_mac = rtl930x_get_l3_router_mac, .set_l3_router_mac = rtl930x_set_l3_router_mac, .set_l3_egress_intf = rtl930x_set_l3_egress_intf,