target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl930x.c
static void rtl930x_route_write(int idx, struct rtl83xx_route *rt)
{
	u32 v, ip4_m;
	struct in6_addr ip6_m;
	// Access L3_PREFIX_ROUTE_IPUC table (2) via register RTL9300_TBL_1
	// The table has a size of 11 registers (20 for MC)
	struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 2);

	pr_debug("%s: index %d is valid: %d\n", __func__, idx, rt->attr.valid);
	pr_debug("%s: nexthop: %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 = rt->attr.valid ? BIT(31) : 0;
	v |= (rt->attr.type & 0x3) << 29;
	sw_w32(v, rtl_table_data(r, 0));

	v = rt->attr.hit ? BIT(22) : 0;
	v |= (rt->attr.action & 0x3) << 18;
	v |= (rt->nh.id & 0x7ff) << 7;
	v |= rt->attr.ttl_dec ? BIT(6) : 0;
	v |= rt->attr.ttl_check ? BIT(5) : 0;
	v |= rt->attr.dst_null ? BIT(6) : 0;
	v |= rt->attr.qos_as ? BIT(6) : 0;
	v |= rt->attr.qos_prio & 0x7;
	v |= rt->prefix_len == 0 ? BIT(20) : 0; // set default route bit

	// set bit mask for entry type always to 0x3
	sw_w32(0x3 << 29, rtl_table_data(r, 5));

	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));

		v |= rt->prefix_len == 32 ? BIT(21) : 0; // set host-route bit
		ip4_m = inet_make_mask(rt->prefix_len);
		sw_w32(0, rtl_table_data(r, 6));
		sw_w32(0, rtl_table_data(r, 7));
		sw_w32(0, rtl_table_data(r, 8));
		sw_w32(ip4_m, rtl_table_data(r, 9));
		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));

		v |= rt->prefix_len == 128 ? BIT(21) : 0; // set host-route bit

		rtl930x_net6_mask(rt->prefix_len, &ip6_m);

		sw_w32(ip6_m.s6_addr32[0], rtl_table_data(r, 6));
		sw_w32(ip6_m.s6_addr32[1], rtl_table_data(r, 7));
		sw_w32(ip6_m.s6_addr32[2], rtl_table_data(r, 8));
		sw_w32(ip6_m.s6_addr32[3], rtl_table_data(r, 9));
		break;
	case 1: // IPv4 Multicast route
	case 3: // IPv6 Multicast route
		pr_warn("%s: route type not supported\n", __func__);
		rtl_table_release(r);
		return;
	}
	sw_w32(v, rtl_table_data(r, 10));

	pr_debug("%s: %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", __func__,
		sw_r32(rtl_table_data(r, 0)), sw_r32(rtl_table_data(r, 1)), sw_r32(rtl_table_data(r, 2)),
		sw_r32(rtl_table_data(r, 3)), sw_r32(rtl_table_data(r, 4)), sw_r32(rtl_table_data(r, 5)),
		sw_r32(rtl_table_data(r, 6)), sw_r32(rtl_table_data(r, 7)), sw_r32(rtl_table_data(r, 8)),
		sw_r32(rtl_table_data(r, 9)), sw_r32(rtl_table_data(r, 10)));

	rtl_table_write(r, idx);
	rtl_table_release(r);
}
/*
 * Write a prefix route into the routing table CAM at position idx
 * Currently only IPv4 and IPv6 unicast routes are supported
 */
Write a prefix route into the routing table CAM at position idx
Currently only IPv4 and IPv6 unicast routes are supported
Write a prefix route into the routing table CAM at position idx Currently only IPv4 and IPv6 unicast routes are supported
static void rtl930x_route_write(int idx, struct rtl83xx_route *rt)
{
	u32 v, ip4_m;
	struct in6_addr ip6_m;
	struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 2);
	pr_debug("%s: index %d is valid: %d\n", __func__, idx, rt->attr.valid);
	pr_debug("%s: nexthop: %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 = rt->attr.valid ? BIT(31) : 0;
	v |= (rt->attr.type & 0x3) << 29;
	sw_w32(v, rtl_table_data(r, 0));
	v = rt->attr.hit ? BIT(22) : 0;
	v |= (rt->attr.action & 0x3) << 18;
	v |= (rt->nh.id & 0x7ff) << 7;
	v |= rt->attr.ttl_dec ? BIT(6) : 0;
	v |= rt->attr.ttl_check ? BIT(5) : 0;
	v |= rt->attr.dst_null ? BIT(6) : 0;
	v |= rt->attr.qos_as ? BIT(6) : 0;
	v |= rt->attr.qos_prio & 0x7;
	v |= rt->prefix_len == 0 ? BIT(20) : 0; 
	sw_w32(0x3 << 29, rtl_table_data(r, 5));
	switch (rt->attr.type) {
	case 0: 
		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));
		v |= rt->prefix_len == 32 ? BIT(21) : 0; 
		ip4_m = inet_make_mask(rt->prefix_len);
		sw_w32(0, rtl_table_data(r, 6));
		sw_w32(0, rtl_table_data(r, 7));
		sw_w32(0, rtl_table_data(r, 8));
		sw_w32(ip4_m, rtl_table_data(r, 9));
		break;
	case 2: 
		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));
		v |= rt->prefix_len == 128 ? BIT(21) : 0; 
		rtl930x_net6_mask(rt->prefix_len, &ip6_m);
		sw_w32(ip6_m.s6_addr32[0], rtl_table_data(r, 6));
		sw_w32(ip6_m.s6_addr32[1], rtl_table_data(r, 7));
		sw_w32(ip6_m.s6_addr32[2], rtl_table_data(r, 8));
		sw_w32(ip6_m.s6_addr32[3], rtl_table_data(r, 9));
		break;
	case 1: 
	case 3: 
		pr_warn("%s: route type not supported\n", __func__);
		rtl_table_release(r);
		return;
	}
	sw_w32(v, rtl_table_data(r, 10));
	pr_debug("%s: %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", __func__,
		sw_r32(rtl_table_data(r, 0)), sw_r32(rtl_table_data(r, 1)), sw_r32(rtl_table_data(r, 2)),
		sw_r32(rtl_table_data(r, 3)), sw_r32(rtl_table_data(r, 4)), sw_r32(rtl_table_data(r, 5)),
		sw_r32(rtl_table_data(r, 6)), sw_r32(rtl_table_data(r, 7)), sw_r32(rtl_table_data(r, 8)),
		sw_r32(rtl_table_data(r, 9)), sw_r32(rtl_table_data(r, 10)));
	rtl_table_write(r, idx);
	rtl_table_release(r);
}
static void rtl930x_route_write ( int idx , struct rtl83xx_route * rt ) { u32 v , ip4_m ; struct in6_addr ip6_m ; struct table_reg * r = rtl_table_get ( RTL9300_TBL_1 , 2 ) ; pr_debug ( " \n " , __func__ , idx , rt -> attr . valid ) ; pr_debug ( " \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 ( " \n " , __func__ , & rt -> dst_ip , rt -> prefix_len ) ; v = rt -> attr . valid ? BIT ( 31 ) : 0 ; v |= ( rt -> attr . type & 0x3 ) << 29 ; sw_w32 ( v , rtl_table_data ( r , 0 ) ) ; v = rt -> attr . hit ? BIT ( 22 ) : 0 ; v |= ( rt -> attr . action & 0x3 ) << 18 ; v |= ( rt -> nh . id & 0x7ff ) << 7 ; v |= rt -> attr . ttl_dec ? BIT ( 6 ) : 0 ; v |= rt -> attr . ttl_check ? BIT ( 5 ) : 0 ; v |= rt -> attr . dst_null ? BIT ( 6 ) : 0 ; v |= rt -> attr . qos_as ? BIT ( 6 ) : 0 ; v |= rt -> attr . qos_prio & 0x7 ; v |= rt -> prefix_len == 0 ? BIT ( 20 ) : 0 ; sw_w32 ( 0x3 << 29 , rtl_table_data ( r , 5 ) ) ; switch ( rt -> attr . type ) { case 0 : 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 ) ) ; v |= rt -> prefix_len == 32 ? BIT ( 21 ) : 0 ; ip4_m = inet_make_mask ( rt -> prefix_len ) ; sw_w32 ( 0 , rtl_table_data ( r , 6 ) ) ; sw_w32 ( 0 , rtl_table_data ( r , 7 ) ) ; sw_w32 ( 0 , rtl_table_data ( r , 8 ) ) ; sw_w32 ( ip4_m , rtl_table_data ( r , 9 ) ) ; break ; case 2 : 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 ) ) ; v |= rt -> prefix_len == 128 ? BIT ( 21 ) : 0 ; rtl930x_net6_mask ( rt -> prefix_len , & ip6_m ) ; sw_w32 ( ip6_m . s6_addr32 [ 0 ] , rtl_table_data ( r , 6 ) ) ; sw_w32 ( ip6_m . s6_addr32 [ 1 ] , rtl_table_data ( r , 7 ) ) ; sw_w32 ( ip6_m . s6_addr32 [ 2 ] , rtl_table_data ( r , 8 ) ) ; sw_w32 ( ip6_m . s6_addr32 [ 3 ] , rtl_table_data ( r , 9 ) ) ; break ; case 1 : case 3 : pr_warn ( " \n " , __func__ ) ; rtl_table_release ( r ) ; return ; } sw_w32 ( v , rtl_table_data ( r , 10 ) ) ; pr_debug ( " \n " , __func__ , sw_r32 ( rtl_table_data ( r , 0 ) ) , sw_r32 ( rtl_table_data ( r , 1 ) ) , sw_r32 ( rtl_table_data ( r , 2 ) ) , sw_r32 ( rtl_table_data ( r , 3 ) ) , sw_r32 ( rtl_table_data ( r , 4 ) ) , sw_r32 ( rtl_table_data ( r , 5 ) ) , sw_r32 ( rtl_table_data ( r , 6 ) ) , sw_r32 ( rtl_table_data ( r , 7 ) ) , sw_r32 ( rtl_table_data ( r , 8 ) ) , sw_r32 ( rtl_table_data ( r , 9 ) ) , sw_r32 ( rtl_table_data ( r , 10 ) ) ) ; rtl_table_write ( r , idx ) ; rtl_table_release ( r ) ; }
Write a prefix route into the routing table CAM at position idx
 Currently only IPv4 and IPv6 unicast routes are supported
Write a prefix route into the routing table CAM at position idx Currently only IPv4 and IPv6 unicast routes are supported
// Access L3_PREFIX_ROUTE_IPUC table (2) via register RTL9300_TBL_1 // The table has a size of 11 registers (20 for MC) // set default route bit // set bit mask for entry type always to 0x3 // IPv4 Unicast route // set host-route bit // IPv6 Unicast route // set host-route bit // IPv4 Multicast route // IPv6 Multicast route