realtek: Add L2 aging configuration functions for all SoC families
Instead of a generic L2 aging configuration function with complex logic, we implement an individual function for all SoC types. Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com> Signed-off-by: Birger Koblitz <git@birger-koblitz.de>
This commit is contained in:
		 Birger Koblitz
					Birger Koblitz
				
			
				
					committed by
					
						 Daniel Golle
						Daniel Golle
					
				
			
			
				
	
			
			
			 Daniel Golle
						Daniel Golle
					
				
			
						parent
						
							f3c5e7ddcc
						
					
				
				
					commit
					9d396fc1e8
				
			| @@ -1039,25 +1039,11 @@ static int rtl93xx_get_mac_eee(struct dsa_switch *ds, int port, | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | static int rtl83xx_set_ageing_time(struct dsa_switch *ds, unsigned int msec) | ||||||
|  * Set Switch L2 Aging time, t is time in milliseconds |  | ||||||
|  * t = 0: aging is disabled |  | ||||||
|  */ |  | ||||||
| static int rtl83xx_set_l2aging(struct dsa_switch *ds, u32 t) |  | ||||||
| { | { | ||||||
| 	struct rtl838x_switch_priv *priv = ds->priv; | 	struct rtl838x_switch_priv *priv = ds->priv; | ||||||
| 	int t_max = priv->family_id == RTL8380_FAMILY_ID ? 0x7fffff : 0x1FFFFF; |  | ||||||
|  |  | ||||||
| 	/* Convert time in mseconds to internal value */ | 	priv->r->set_ageing_time(msec); | ||||||
| 	if (t > 0x10000000) { /* Set to maximum */ |  | ||||||
| 		t = t_max; |  | ||||||
| 	} else { |  | ||||||
| 		if (priv->family_id == RTL8380_FAMILY_ID) |  | ||||||
| 			t = ((t * 625) / 1000 + 127) / 128; |  | ||||||
| 		else |  | ||||||
| 			t = (t * 5 + 2) / 3; |  | ||||||
| 	} |  | ||||||
| 	sw_w32(t, priv->r->l2_ctrl_1); |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -2137,7 +2123,7 @@ const struct dsa_switch_ops rtl83xx_switch_ops = { | |||||||
| 	.get_mac_eee		= rtl83xx_get_mac_eee, | 	.get_mac_eee		= rtl83xx_get_mac_eee, | ||||||
| 	.set_mac_eee		= rtl83xx_set_mac_eee, | 	.set_mac_eee		= rtl83xx_set_mac_eee, | ||||||
|  |  | ||||||
| 	.set_ageing_time	= rtl83xx_set_l2aging, | 	.set_ageing_time	= rtl83xx_set_ageing_time, | ||||||
| 	.port_bridge_join	= rtl83xx_port_bridge_join, | 	.port_bridge_join	= rtl83xx_port_bridge_join, | ||||||
| 	.port_bridge_leave	= rtl83xx_port_bridge_leave, | 	.port_bridge_leave	= rtl83xx_port_bridge_leave, | ||||||
| 	.port_stp_state_set	= rtl83xx_port_stp_state_set, | 	.port_stp_state_set	= rtl83xx_port_stp_state_set, | ||||||
| @@ -2190,7 +2176,7 @@ const struct dsa_switch_ops rtl930x_switch_ops = { | |||||||
| 	.get_mac_eee		= rtl93xx_get_mac_eee, | 	.get_mac_eee		= rtl93xx_get_mac_eee, | ||||||
| 	.set_mac_eee		= rtl83xx_set_mac_eee, | 	.set_mac_eee		= rtl83xx_set_mac_eee, | ||||||
|  |  | ||||||
| 	.set_ageing_time	= rtl83xx_set_l2aging, | 	.set_ageing_time	= rtl83xx_set_ageing_time, | ||||||
| 	.port_bridge_join	= rtl83xx_port_bridge_join, | 	.port_bridge_join	= rtl83xx_port_bridge_join, | ||||||
| 	.port_bridge_leave	= rtl83xx_port_bridge_leave, | 	.port_bridge_leave	= rtl83xx_port_bridge_leave, | ||||||
| 	.port_stp_state_set	= rtl83xx_port_stp_state_set, | 	.port_stp_state_set	= rtl83xx_port_stp_state_set, | ||||||
|   | |||||||
| @@ -1637,6 +1637,22 @@ void rtl838x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid) | |||||||
| 		sw_w32_mask(0xfff << 16, pvid << 16, RTL838X_VLAN_PORT_PB_VLAN + (port << 2)); | 		sw_w32_mask(0xfff << 16, pvid << 16, RTL838X_VLAN_PORT_PB_VLAN + (port << 2)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int rtl838x_set_ageing_time(unsigned long msec) | ||||||
|  | { | ||||||
|  | 	int t = sw_r32(RTL838X_L2_CTRL_1); | ||||||
|  |  | ||||||
|  | 	t &= 0x7FFFFF; | ||||||
|  | 	t = t * 128 / 625; /* Aging time in seconds. 0: L2 aging disabled */ | ||||||
|  | 	pr_debug("L2 AGING time: %d sec\n", t); | ||||||
|  |  | ||||||
|  | 	t = (msec * 625 + 127000) / 128000; | ||||||
|  | 	t = t > 0x7FFFFF ? 0x7FFFFF : t; | ||||||
|  | 	sw_w32_mask(0x7FFFFF, t, RTL838X_L2_CTRL_1); | ||||||
|  | 	pr_debug("Dynamic aging for ports: %x\n", sw_r32(RTL838X_L2_PORT_AGING_OUT)); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static void rtl838x_set_igr_filter(int port, enum igr_filter state) | static void rtl838x_set_igr_filter(int port, enum igr_filter state) | ||||||
| { | { | ||||||
| 	sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), | 	sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), | ||||||
| @@ -1675,6 +1691,7 @@ const struct rtl838x_reg rtl838x_reg = { | |||||||
| 	.l2_ctrl_0 = RTL838X_L2_CTRL_0, | 	.l2_ctrl_0 = RTL838X_L2_CTRL_0, | ||||||
| 	.l2_ctrl_1 = RTL838X_L2_CTRL_1, | 	.l2_ctrl_1 = RTL838X_L2_CTRL_1, | ||||||
| 	.l2_port_aging_out = RTL838X_L2_PORT_AGING_OUT, | 	.l2_port_aging_out = RTL838X_L2_PORT_AGING_OUT, | ||||||
|  | 	.set_ageing_time = rtl838x_set_ageing_time, | ||||||
| 	.smi_poll_ctrl = RTL838X_SMI_POLL_CTRL, | 	.smi_poll_ctrl = RTL838X_SMI_POLL_CTRL, | ||||||
| 	.l2_tbl_flush_ctrl = RTL838X_L2_TBL_FLUSH_CTRL, | 	.l2_tbl_flush_ctrl = RTL838X_L2_TBL_FLUSH_CTRL, | ||||||
| 	.exec_tbl0_cmd = rtl838x_exec_tbl0_cmd, | 	.exec_tbl0_cmd = rtl838x_exec_tbl0_cmd, | ||||||
|   | |||||||
| @@ -851,8 +851,8 @@ struct rtl838x_reg { | |||||||
| 	u64 (*traffic_get)(int source); | 	u64 (*traffic_get)(int source); | ||||||
| 	int l2_ctrl_0; | 	int l2_ctrl_0; | ||||||
| 	int l2_ctrl_1; | 	int l2_ctrl_1; | ||||||
| 	int l2_port_aging_out; |  | ||||||
| 	int smi_poll_ctrl; | 	int smi_poll_ctrl; | ||||||
|  | 	u32 l2_port_aging_out; | ||||||
| 	int l2_tbl_flush_ctrl; | 	int l2_tbl_flush_ctrl; | ||||||
| 	void (*exec_tbl0_cmd)(u32 cmd); | 	void (*exec_tbl0_cmd)(u32 cmd); | ||||||
| 	void (*exec_tbl1_cmd)(u32 cmd); | 	void (*exec_tbl1_cmd)(u32 cmd); | ||||||
| @@ -880,6 +880,7 @@ struct rtl838x_reg { | |||||||
| 	int  (*mac_port_ctrl)(int port); | 	int  (*mac_port_ctrl)(int port); | ||||||
| 	int  (*l2_port_new_salrn)(int port); | 	int  (*l2_port_new_salrn)(int port); | ||||||
| 	int  (*l2_port_new_sa_fwd)(int port); | 	int  (*l2_port_new_sa_fwd)(int port); | ||||||
|  | 	int (*set_ageing_time)(unsigned long msec); | ||||||
| 	int mir_ctrl; | 	int mir_ctrl; | ||||||
| 	int mir_dpm; | 	int mir_dpm; | ||||||
| 	int mir_spm; | 	int mir_spm; | ||||||
|   | |||||||
| @@ -1762,6 +1762,22 @@ void rtl839x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid) | |||||||
| 		sw_w32_mask(0xfff << 16, pvid << 16, RTL839X_VLAN_PORT_PB_VLAN + (port << 2)); | 		sw_w32_mask(0xfff << 16, pvid << 16, RTL839X_VLAN_PORT_PB_VLAN + (port << 2)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int rtl839x_set_ageing_time(unsigned long msec) | ||||||
|  | { | ||||||
|  | 	int t = sw_r32(RTL839X_L2_CTRL_1); | ||||||
|  |  | ||||||
|  | 	t &= 0x1FFFFF; | ||||||
|  | 	t = t * 3 / 5; /* Aging time in seconds. 0: L2 aging disabled */ | ||||||
|  | 	pr_debug("L2 AGING time: %d sec\n", t); | ||||||
|  |  | ||||||
|  | 	t = (msec * 5 + 2000) / 3000; | ||||||
|  | 	t = t > 0x1FFFFF ? 0x1FFFFF : t; | ||||||
|  | 	sw_w32_mask(0x1FFFFF, t, RTL839X_L2_CTRL_1); | ||||||
|  | 	pr_debug("Dynamic aging for ports: %x\n", sw_r32(RTL839X_L2_PORT_AGING_OUT)); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static void rtl839x_set_igr_filter(int port,  enum igr_filter state) | static void rtl839x_set_igr_filter(int port,  enum igr_filter state) | ||||||
| { | { | ||||||
| 	sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), | 	sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), | ||||||
| @@ -1799,6 +1815,7 @@ const struct rtl838x_reg rtl839x_reg = { | |||||||
| 	.l2_ctrl_0 = RTL839X_L2_CTRL_0, | 	.l2_ctrl_0 = RTL839X_L2_CTRL_0, | ||||||
| 	.l2_ctrl_1 = RTL839X_L2_CTRL_1, | 	.l2_ctrl_1 = RTL839X_L2_CTRL_1, | ||||||
| 	.l2_port_aging_out = RTL839X_L2_PORT_AGING_OUT, | 	.l2_port_aging_out = RTL839X_L2_PORT_AGING_OUT, | ||||||
|  | 	.set_ageing_time = rtl839x_set_ageing_time, | ||||||
| 	.smi_poll_ctrl = RTL839X_SMI_PORT_POLLING_CTRL, | 	.smi_poll_ctrl = RTL839X_SMI_PORT_POLLING_CTRL, | ||||||
| 	.l2_tbl_flush_ctrl = RTL839X_L2_TBL_FLUSH_CTRL, | 	.l2_tbl_flush_ctrl = RTL839X_L2_TBL_FLUSH_CTRL, | ||||||
| 	.exec_tbl0_cmd = rtl839x_exec_tbl0_cmd, | 	.exec_tbl0_cmd = rtl839x_exec_tbl0_cmd, | ||||||
|   | |||||||
| @@ -2332,6 +2332,22 @@ void rtl930x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid) | |||||||
| 		sw_w32_mask(0xfff << 16, pvid << 16, RTL930X_VLAN_PORT_PB_VLAN + (port << 2)); | 		sw_w32_mask(0xfff << 16, pvid << 16, RTL930X_VLAN_PORT_PB_VLAN + (port << 2)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int rtl930x_set_ageing_time(unsigned long msec) | ||||||
|  | { | ||||||
|  | 	int t = sw_r32(RTL930X_L2_AGE_CTRL); | ||||||
|  |  | ||||||
|  | 	t &= 0x1FFFFF; | ||||||
|  | 	t = (t * 7) / 10; | ||||||
|  | 	pr_debug("L2 AGING time: %d sec\n", t); | ||||||
|  |  | ||||||
|  | 	t = (msec / 100 + 6) / 7; | ||||||
|  | 	t = t > 0x1FFFFF ? 0x1FFFFF : t; | ||||||
|  | 	sw_w32_mask(0x1FFFFF, t, RTL930X_L2_AGE_CTRL); | ||||||
|  | 	pr_debug("Dynamic aging for ports: %x\n", sw_r32(RTL930X_L2_PORT_AGE_CTRL)); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static void rtl930x_set_igr_filter(int port,  enum igr_filter state) | static void rtl930x_set_igr_filter(int port,  enum igr_filter state) | ||||||
| { | { | ||||||
| 	sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), | 	sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), | ||||||
| @@ -2401,6 +2417,7 @@ const struct rtl838x_reg rtl930x_reg = { | |||||||
| 	.l2_ctrl_0 = RTL930X_L2_CTRL, | 	.l2_ctrl_0 = RTL930X_L2_CTRL, | ||||||
| 	.l2_ctrl_1 = RTL930X_L2_AGE_CTRL, | 	.l2_ctrl_1 = RTL930X_L2_AGE_CTRL, | ||||||
| 	.l2_port_aging_out = RTL930X_L2_PORT_AGE_CTRL, | 	.l2_port_aging_out = RTL930X_L2_PORT_AGE_CTRL, | ||||||
|  | 	.set_ageing_time = rtl930x_set_ageing_time, | ||||||
| 	.smi_poll_ctrl = RTL930X_SMI_POLL_CTRL, // TODO: Difference to RTL9300_SMI_PRVTE_POLLING_CTRL | 	.smi_poll_ctrl = RTL930X_SMI_POLL_CTRL, // TODO: Difference to RTL9300_SMI_PRVTE_POLLING_CTRL | ||||||
| 	.l2_tbl_flush_ctrl = RTL930X_L2_TBL_FLUSH_CTRL, | 	.l2_tbl_flush_ctrl = RTL930X_L2_TBL_FLUSH_CTRL, | ||||||
| 	.exec_tbl0_cmd = rtl930x_exec_tbl0_cmd, | 	.exec_tbl0_cmd = rtl930x_exec_tbl0_cmd, | ||||||
|   | |||||||
| @@ -439,6 +439,7 @@ const struct rtl838x_reg rtl931x_reg = { | |||||||
| 	.l2_ctrl_0 = RTL931X_L2_CTRL, | 	.l2_ctrl_0 = RTL931X_L2_CTRL, | ||||||
| 	.l2_ctrl_1 = RTL931X_L2_AGE_CTRL, | 	.l2_ctrl_1 = RTL931X_L2_AGE_CTRL, | ||||||
| 	.l2_port_aging_out = RTL931X_L2_PORT_AGE_CTRL, | 	.l2_port_aging_out = RTL931X_L2_PORT_AGE_CTRL, | ||||||
|  | 	.set_ageing_time = rtl931x_set_ageing_time, | ||||||
| 	// .smi_poll_ctrl does not exist | 	// .smi_poll_ctrl does not exist | ||||||
| 	.l2_tbl_flush_ctrl = RTL931X_L2_TBL_FLUSH_CTRL, | 	.l2_tbl_flush_ctrl = RTL931X_L2_TBL_FLUSH_CTRL, | ||||||
| 	.exec_tbl0_cmd = rtl931x_exec_tbl0_cmd, | 	.exec_tbl0_cmd = rtl931x_exec_tbl0_cmd, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user