realtek: Improve MAC config handling for all SoCs
Adds a rtl931x_phylink_mac_config for the RTL931X and improve the handling of the RTL930X phylink configuration. Add separate handling of the RTL839x since some configurations are different from the RTL838X. 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
						
							c7cc4e95a5
						
					
				
				
					commit
					51c8f76612
				
			| @@ -38,7 +38,7 @@ static void rtl83xx_enable_phy_polling(struct rtl838x_switch_priv *priv) | |||||||
| 			v |= BIT_ULL(i); | 			v |= BIT_ULL(i); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pr_debug("%s: %16llx\n", __func__, v); | 	pr_info("%s: %16llx\n", __func__, v); | ||||||
| 	priv->r->set_port_reg_le(v, priv->r->smi_poll_ctrl); | 	priv->r->set_port_reg_le(v, priv->r->smi_poll_ctrl); | ||||||
|  |  | ||||||
| 	/* PHY update complete, there is no global PHY polling enable bit on the 9300 */ | 	/* PHY update complete, there is no global PHY polling enable bit on the 9300 */ | ||||||
| @@ -131,6 +131,11 @@ static void rtl83xx_vlan_setup(struct rtl838x_switch_priv *priv) | |||||||
| 	info.hash_mc_fid = false;	// Do the same for Multicast packets | 	info.hash_mc_fid = false;	// Do the same for Multicast packets | ||||||
| 	info.profile_id = 0;		// Use default Vlan Profile 0 | 	info.profile_id = 0;		// Use default Vlan Profile 0 | ||||||
| 	info.tagged_ports = 0;		// Initially no port members | 	info.tagged_ports = 0;		// Initially no port members | ||||||
|  | 	if (priv->family_id == RTL9310_FAMILY_ID) { | ||||||
|  | 		info.if_id = 0; | ||||||
|  | 		info.multicast_grp_mask = 0; | ||||||
|  | 		info.l2_tunnel_list_id = -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Initialize all vlans 0-4095 | 	// Initialize all vlans 0-4095 | ||||||
| 	for (i = 0; i < MAX_VLANS; i ++) | 	for (i = 0; i < MAX_VLANS; i ++) | ||||||
| @@ -195,7 +200,7 @@ static int rtl83xx_setup(struct dsa_switch *ds) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int rtl930x_setup(struct dsa_switch *ds) | static int rtl93xx_setup(struct dsa_switch *ds) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
| 	struct rtl838x_switch_priv *priv = ds->priv; | 	struct rtl838x_switch_priv *priv = ds->priv; | ||||||
| @@ -203,12 +208,15 @@ static int rtl930x_setup(struct dsa_switch *ds) | |||||||
|  |  | ||||||
| 	pr_info("%s called\n", __func__); | 	pr_info("%s called\n", __func__); | ||||||
|  |  | ||||||
| 	// Enable CSTI STP mode |  | ||||||
| //	sw_w32(1, RTL930X_ST_CTRL); |  | ||||||
|  |  | ||||||
| 	/* Disable MAC polling the PHY so that we can start configuration */ | 	/* Disable MAC polling the PHY so that we can start configuration */ | ||||||
|  | 	if (priv->family_id == RTL9300_FAMILY_ID) | ||||||
| 		sw_w32(0, RTL930X_SMI_POLL_CTRL); | 		sw_w32(0, RTL930X_SMI_POLL_CTRL); | ||||||
|  |  | ||||||
|  | 	if (priv->family_id == RTL9310_FAMILY_ID) { | ||||||
|  | 		sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL); | ||||||
|  | 		sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL + 4); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Disable all ports except CPU port | 	// Disable all ports except CPU port | ||||||
| 	for (i = 0; i < ds->num_ports; i++) | 	for (i = 0; i < ds->num_ports; i++) | ||||||
| 		priv->ports[i].enable = false; | 		priv->ports[i].enable = false; | ||||||
| @@ -322,6 +330,7 @@ static void rtl93xx_phylink_validate(struct dsa_switch *ds, int port, | |||||||
| 				     unsigned long *supported, | 				     unsigned long *supported, | ||||||
| 				     struct phylink_link_state *state) | 				     struct phylink_link_state *state) | ||||||
| { | { | ||||||
|  | 	struct rtl838x_switch_priv *priv = ds->priv; | ||||||
| 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||||||
|  |  | ||||||
| 	pr_debug("In %s port %d, state is %d (%s)", __func__, port, state->interface, | 	pr_debug("In %s port %d, state is %d (%s)", __func__, port, state->interface, | ||||||
| @@ -362,11 +371,24 @@ static void rtl93xx_phylink_validate(struct dsa_switch *ds, int port, | |||||||
| 		phylink_set(mask, 1000baseT_Half); | 		phylink_set(mask, 1000baseT_Half); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* On the RTL9300 family of SoCs, ports 26 to 27 may be SFP ports TODO: take out of .dts */ | 	// Internal phys of the RTL93xx family provide 10G | ||||||
| 	if (port >= 26 && port <= 27) | 	if (priv->ports[port].phy_is_integrated | ||||||
|  | 		&& state->interface == PHY_INTERFACE_MODE_1000BASEX) { | ||||||
|  | 		phylink_set(mask, 1000baseX_Full); | ||||||
|  | 	} else if (priv->ports[port].phy_is_integrated) { | ||||||
| 		phylink_set(mask, 1000baseX_Full); | 		phylink_set(mask, 1000baseX_Full); | ||||||
| 	if (port >= 26 && port <= 27) |  | ||||||
| 		phylink_set(mask, 10000baseKR_Full); | 		phylink_set(mask, 10000baseKR_Full); | ||||||
|  | 		phylink_set(mask, 10000baseSR_Full); | ||||||
|  | 		phylink_set(mask, 10000baseCR_Full); | ||||||
|  | 	} | ||||||
|  | 	if (state->interface == PHY_INTERFACE_MODE_INTERNAL) { | ||||||
|  | 		phylink_set(mask, 1000baseX_Full); | ||||||
|  | 		phylink_set(mask, 1000baseT_Full); | ||||||
|  | 		phylink_set(mask, 10000baseKR_Full); | ||||||
|  | 		phylink_set(mask, 10000baseT_Full); | ||||||
|  | 		phylink_set(mask, 10000baseSR_Full); | ||||||
|  | 		phylink_set(mask, 10000baseCR_Full); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	phylink_set(mask, 10baseT_Half); | 	phylink_set(mask, 10baseT_Half); | ||||||
| 	phylink_set(mask, 10baseT_Full); | 	phylink_set(mask, 10baseT_Full); | ||||||
| @@ -377,6 +399,7 @@ static void rtl93xx_phylink_validate(struct dsa_switch *ds, int port, | |||||||
| 		   __ETHTOOL_LINK_MODE_MASK_NBITS); | 		   __ETHTOOL_LINK_MODE_MASK_NBITS); | ||||||
| 	bitmap_and(state->advertising, state->advertising, mask, | 	bitmap_and(state->advertising, state->advertising, mask, | ||||||
| 		   __ETHTOOL_LINK_MODE_MASK_NBITS); | 		   __ETHTOOL_LINK_MODE_MASK_NBITS); | ||||||
|  | 	pr_debug("%s leaving supported: %*pb", __func__, __ETHTOOL_LINK_MODE_MASK_NBITS, supported); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port, | static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port, | ||||||
| @@ -482,6 +505,13 @@ static int rtl93xx_phylink_mac_link_state(struct dsa_switch *ds, int port, | |||||||
| 		pr_err("%s: unknown speed: %d\n", __func__, (u32)speed & 0xf); | 		pr_err("%s: unknown speed: %d\n", __func__, (u32)speed & 0xf); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (priv->family_id == RTL9310_FAMILY_ID | ||||||
|  | 		&& (port >= 52 || port <= 55)) { /* Internal serdes */ | ||||||
|  | 			state->speed = SPEED_10000; | ||||||
|  | 			state->link = 1; | ||||||
|  | 			state->duplex = 1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	pr_debug("%s: speed is: %d %d\n", __func__, (u32)speed & 0xf, state->speed); | 	pr_debug("%s: speed is: %d %d\n", __func__, (u32)speed & 0xf, state->speed); | ||||||
| 	state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX); | 	state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX); | ||||||
| 	if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port)) | 	if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port)) | ||||||
| @@ -559,7 +589,7 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port, | |||||||
| 	if (priv->family_id == RTL8380_FAMILY_ID) { | 	if (priv->family_id == RTL8380_FAMILY_ID) { | ||||||
| 		if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) { | 		if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) { | ||||||
| 			pr_debug("PHY autonegotiates\n"); | 			pr_debug("PHY autonegotiates\n"); | ||||||
| 			reg |= BIT(2); | 			reg |= RTL838X_NWAY_EN; | ||||||
| 			sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); | 			sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); | ||||||
| 			rtl83xx_config_interface(port, state->interface); | 			rtl83xx_config_interface(port, state->interface); | ||||||
| 			return; | 			return; | ||||||
| @@ -569,19 +599,25 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port, | |||||||
| 	if (mode != MLO_AN_FIXED) | 	if (mode != MLO_AN_FIXED) | ||||||
| 		pr_debug("Fixed state.\n"); | 		pr_debug("Fixed state.\n"); | ||||||
|  |  | ||||||
| 	if (priv->family_id == RTL8380_FAMILY_ID) { |  | ||||||
| 	/* Clear id_mode_dis bit, and the existing port mode, let | 	/* Clear id_mode_dis bit, and the existing port mode, let | ||||||
| 		 * RGMII_MODE_EN bet set by mac_link_{up,down} | 		 * RGMII_MODE_EN bet set by mac_link_{up,down}  */ | ||||||
| 		 */ | 	if (priv->family_id == RTL8380_FAMILY_ID) { | ||||||
| 		reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN); | 		reg &= ~(RTL838X_RX_PAUSE_EN | RTL838X_TX_PAUSE_EN); | ||||||
|  |  | ||||||
| 		if (state->pause & MLO_PAUSE_TXRX_MASK) { | 		if (state->pause & MLO_PAUSE_TXRX_MASK) { | ||||||
| 			if (state->pause & MLO_PAUSE_TX) | 			if (state->pause & MLO_PAUSE_TX) | ||||||
| 				reg |= TX_PAUSE_EN; | 				reg |= RTL838X_TX_PAUSE_EN; | ||||||
| 			reg |= RX_PAUSE_EN; | 			reg |= RTL838X_RX_PAUSE_EN; | ||||||
|  | 		} | ||||||
|  | 	} else if (priv->family_id == RTL8390_FAMILY_ID) { | ||||||
|  | 		reg &= ~(RTL839X_RX_PAUSE_EN | RTL839X_TX_PAUSE_EN); | ||||||
|  | 		if (state->pause & MLO_PAUSE_TXRX_MASK) { | ||||||
|  | 			if (state->pause & MLO_PAUSE_TX) | ||||||
|  | 				reg |= RTL839X_TX_PAUSE_EN; | ||||||
|  | 			reg |= RTL839X_RX_PAUSE_EN; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	reg &= ~(3 << speed_bit); | 	reg &= ~(3 << speed_bit); | ||||||
| 	switch (state->speed) { | 	switch (state->speed) { | ||||||
| 	case SPEED_1000: | 	case SPEED_1000: | ||||||
| @@ -590,22 +626,98 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port, | |||||||
| 	case SPEED_100: | 	case SPEED_100: | ||||||
| 		reg |= 1 << speed_bit; | 		reg |= 1 << speed_bit; | ||||||
| 		break; | 		break; | ||||||
|  | 	default: | ||||||
|  | 		break; // Ignore, including 10MBit which has a speed value of 0 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (priv->family_id == RTL8380_FAMILY_ID) { | 	if (priv->family_id == RTL8380_FAMILY_ID) { | ||||||
| 		reg &= ~(DUPLEX_FULL | FORCE_LINK_EN); | 		reg &= ~(RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN); | ||||||
| 		if (state->link) | 		if (state->link) | ||||||
| 			reg |= FORCE_LINK_EN; | 			reg |= RTL838X_FORCE_LINK_EN; | ||||||
| 		if (state->duplex == DUPLEX_FULL) | 		if (state->duplex == RTL838X_DUPLEX_MODE) | ||||||
| 			reg |= DUPLX_MODE; | 			reg |= RTL838X_DUPLEX_MODE; | ||||||
|  | 	} else if (priv->family_id == RTL8390_FAMILY_ID) { | ||||||
|  | 		reg &= ~(RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN); | ||||||
|  | 		if (state->link) | ||||||
|  | 			reg |= RTL839X_FORCE_LINK_EN; | ||||||
|  | 		if (state->duplex == RTL839X_DUPLEX_MODE) | ||||||
|  | 			reg |= RTL839X_DUPLEX_MODE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Disable AN | 	// Disable AN | ||||||
| 	if (priv->family_id == RTL8380_FAMILY_ID) | 	if (priv->family_id == RTL8380_FAMILY_ID) | ||||||
| 		reg &= ~BIT(2); | 		reg &= ~RTL838X_NWAY_EN; | ||||||
| 	sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); | 	sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void rtl931x_phylink_mac_config(struct dsa_switch *ds, int port, | ||||||
|  | 					unsigned int mode, | ||||||
|  | 					const struct phylink_link_state *state) | ||||||
|  | { | ||||||
|  | 	struct rtl838x_switch_priv *priv = ds->priv; | ||||||
|  | 	int sds_num; | ||||||
|  | 	u32 reg, band; | ||||||
|  |  | ||||||
|  | 	sds_num = priv->ports[port].sds_num; | ||||||
|  | 	pr_info("%s: speed %d sds_num %d\n", __func__, state->speed, sds_num); | ||||||
|  |  | ||||||
|  | 	switch (state->interface) { | ||||||
|  | 	case PHY_INTERFACE_MODE_HSGMII: | ||||||
|  | 		pr_info("%s setting mode PHY_INTERFACE_MODE_HSGMII\n", __func__); | ||||||
|  | 		band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_HSGMII); | ||||||
|  | 		rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_HSGMII); | ||||||
|  | 		band = rtl931x_sds_cmu_band_set(sds_num, true, 62, PHY_INTERFACE_MODE_HSGMII); | ||||||
|  | 		break; | ||||||
|  | 	case PHY_INTERFACE_MODE_1000BASEX: | ||||||
|  | 		band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_1000BASEX); | ||||||
|  | 		rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_1000BASEX); | ||||||
|  | 		break; | ||||||
|  | 	case PHY_INTERFACE_MODE_XGMII: | ||||||
|  | 		band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_XGMII); | ||||||
|  | 		rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_XGMII); | ||||||
|  | 		break; | ||||||
|  | 	case PHY_INTERFACE_MODE_10GBASER: | ||||||
|  | 	case PHY_INTERFACE_MODE_10GKR: | ||||||
|  | 		band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_10GBASER); | ||||||
|  | 		rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_10GBASER); | ||||||
|  | 		break; | ||||||
|  | 	case PHY_INTERFACE_MODE_USXGMII: | ||||||
|  | 		// Translates to MII_USXGMII_10GSXGMII | ||||||
|  | 		band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_USXGMII); | ||||||
|  | 		rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_USXGMII); | ||||||
|  | 		break; | ||||||
|  | 	case PHY_INTERFACE_MODE_SGMII: | ||||||
|  | 		pr_info("%s setting mode PHY_INTERFACE_MODE_SGMII\n", __func__); | ||||||
|  | 		band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_SGMII); | ||||||
|  | 		rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_SGMII); | ||||||
|  | 		band = rtl931x_sds_cmu_band_set(sds_num, true, 62, PHY_INTERFACE_MODE_SGMII); | ||||||
|  | 		break; | ||||||
|  | 	case PHY_INTERFACE_MODE_QSGMII: | ||||||
|  | 		band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_QSGMII); | ||||||
|  | 		rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_QSGMII); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		pr_err("%s: unknown serdes mode: %s\n", | ||||||
|  | 			__func__, phy_modes(state->interface)); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	reg = sw_r32(priv->r->mac_force_mode_ctrl(port)); | ||||||
|  | 	pr_info("%s reading FORCE_MODE_CTRL: %08x\n", __func__, reg); | ||||||
|  |  | ||||||
|  | 	reg &= ~(RTL931X_DUPLEX_MODE | RTL931X_FORCE_EN | RTL931X_FORCE_LINK_EN); | ||||||
|  |  | ||||||
|  | 	reg &= ~(0xf << 12); | ||||||
|  | 	reg |= 0x2 << 12; // Set SMI speed to 0x2 | ||||||
|  |  | ||||||
|  | 	reg |= BIT(17) | BIT(16); // Enable RX pause and TX pause | ||||||
|  |  | ||||||
|  | 	if (state->duplex == DUPLEX_FULL) | ||||||
|  | 		reg |= RTL931X_DUPLEX_MODE; | ||||||
|  |  | ||||||
|  | 	sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port, | static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port, | ||||||
| 					unsigned int mode, | 					unsigned int mode, | ||||||
| 					const struct phylink_link_state *state) | 					const struct phylink_link_state *state) | ||||||
| @@ -621,6 +733,9 @@ static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port, | |||||||
| 	if (port == priv->cpu_port) | 	if (port == priv->cpu_port) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
|  | 	if (priv->family_id == RTL9310_FAMILY_ID) | ||||||
|  | 		return rtl931x_phylink_mac_config(ds, port, mode, state); | ||||||
|  |  | ||||||
| 	reg = sw_r32(priv->r->mac_force_mode_ctrl(port)); | 	reg = sw_r32(priv->r->mac_force_mode_ctrl(port)); | ||||||
| 	reg &= ~(0xf << 3); | 	reg &= ~(0xf << 3); | ||||||
|  |  | ||||||
| @@ -672,12 +787,16 @@ static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port, | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (state->link) | 	if (state->link) | ||||||
| 		reg |= FORCE_LINK_EN; | 		reg |= RTL930X_FORCE_LINK_EN; | ||||||
|  |  | ||||||
| 	if (state->duplex == DUPLEX_FULL) | 	if (state->duplex == DUPLEX_FULL) | ||||||
| 			reg |= BIT(2); | 		reg |= RTL930X_DUPLEX_MODE; | ||||||
|  |  | ||||||
|  | 	if (priv->ports[port].phy_is_integrated) | ||||||
|  | 		reg &= ~RTL930X_FORCE_EN; // Clear MAC_FORCE_EN to allow SDS-MAC link | ||||||
|  | 	else | ||||||
|  | 		reg |= RTL930X_FORCE_EN; | ||||||
|  |  | ||||||
| 	reg |= 1; // Force Link up |  | ||||||
| 	sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); | 	sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1799,7 +1918,7 @@ const struct dsa_switch_ops rtl83xx_switch_ops = { | |||||||
|  |  | ||||||
| const struct dsa_switch_ops rtl930x_switch_ops = { | const struct dsa_switch_ops rtl930x_switch_ops = { | ||||||
| 	.get_tag_protocol	= rtl83xx_get_tag_protocol, | 	.get_tag_protocol	= rtl83xx_get_tag_protocol, | ||||||
| 	.setup			= rtl930x_setup, | 	.setup			= rtl93xx_setup, | ||||||
|  |  | ||||||
| 	.phy_read		= dsa_phy_read, | 	.phy_read		= dsa_phy_read, | ||||||
| 	.phy_write		= dsa_phy_write, | 	.phy_write		= dsa_phy_write, | ||||||
|   | |||||||
| @@ -147,12 +147,34 @@ | |||||||
| #define RTL930X_MAC_LINK_MEDIA_STS		(0xCB14) | #define RTL930X_MAC_LINK_MEDIA_STS		(0xCB14) | ||||||
|  |  | ||||||
| /* MAC link state bits */ | /* MAC link state bits */ | ||||||
| #define FORCE_EN				(1 << 0) | #define RTL838X_FORCE_EN			(1 << 0) | ||||||
| #define FORCE_LINK_EN				(1 << 1) | #define RTL838X_FORCE_LINK_EN			(1 << 1) | ||||||
| #define NWAY_EN					(1 << 2) | #define RTL838X_NWAY_EN				(1 << 2) | ||||||
| #define DUPLX_MODE				(1 << 3) | #define RTL838X_DUPLEX_MODE			(1 << 3) | ||||||
| #define TX_PAUSE_EN				(1 << 6) | #define RTL838X_TX_PAUSE_EN			(1 << 6) | ||||||
| #define RX_PAUSE_EN				(1 << 7) | #define RTL838X_RX_PAUSE_EN			(1 << 7) | ||||||
|  | #define RTL838X_MAC_FORCE_FC_EN			(1 << 8) | ||||||
|  |  | ||||||
|  | #define RTL839X_FORCE_EN			(1 << 0) | ||||||
|  | #define RTL839X_FORCE_LINK_EN			(1 << 1) | ||||||
|  | #define RTL839X_DUPLEX_MODE			(1 << 2) | ||||||
|  | #define RTL839X_TX_PAUSE_EN			(1 << 5) | ||||||
|  | #define RTL839X_RX_PAUSE_EN			(1 << 6) | ||||||
|  | #define RTL839X_MAC_FORCE_FC_EN			(1 << 7) | ||||||
|  |  | ||||||
|  | #define RTL930X_FORCE_EN			(1 << 0) | ||||||
|  | #define RTL930X_FORCE_LINK_EN			(1 << 1) | ||||||
|  | #define RTL930X_DUPLEX_MODE			(1 << 2) | ||||||
|  | #define RTL930X_TX_PAUSE_EN			(1 << 7) | ||||||
|  | #define RTL930X_RX_PAUSE_EN			(1 << 8) | ||||||
|  | #define RTL930X_MAC_FORCE_FC_EN			(1 << 9) | ||||||
|  |  | ||||||
|  | #define RTL931X_FORCE_EN			(1 << 9) | ||||||
|  | #define RTL931X_FORCE_LINK_EN			(1 << 0) | ||||||
|  | #define RTL931X_DUPLEX_MODE			(1 << 2) | ||||||
|  | #define RTL931X_MAC_FORCE_FC_EN			(1 << 4) | ||||||
|  | #define RTL931X_TX_PAUSE_EN			(1 << 16) | ||||||
|  | #define RTL931X_RX_PAUSE_EN			(1 << 17) | ||||||
|  |  | ||||||
| /* EEE */ | /* EEE */ | ||||||
| #define RTL838X_MAC_EEE_ABLTY			(0xa1a8) | #define RTL838X_MAC_EEE_ABLTY			(0xa1a8) | ||||||
| @@ -433,6 +455,7 @@ enum phy_type { | |||||||
| 	PHY_RTL8218B_EXT = 3, | 	PHY_RTL8218B_EXT = 3, | ||||||
| 	PHY_RTL8214FC = 4, | 	PHY_RTL8214FC = 4, | ||||||
| 	PHY_RTL839X_SDS = 5, | 	PHY_RTL839X_SDS = 5, | ||||||
|  | 	PHY_RTL930X_SDS = 6, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct rtl838x_port { | struct rtl838x_port { | ||||||
| @@ -441,6 +464,7 @@ struct rtl838x_port { | |||||||
| 	u16 pvid; | 	u16 pvid; | ||||||
| 	bool eee_enabled; | 	bool eee_enabled; | ||||||
| 	enum phy_type phy; | 	enum phy_type phy; | ||||||
|  | 	bool phy_is_integrated; | ||||||
| 	bool is10G; | 	bool is10G; | ||||||
| 	bool is2G5; | 	bool is2G5; | ||||||
| 	int sds_num; | 	int sds_num; | ||||||
| @@ -453,7 +477,12 @@ struct rtl838x_vlan_info { | |||||||
| 	u8 profile_id; | 	u8 profile_id; | ||||||
| 	bool hash_mc_fid; | 	bool hash_mc_fid; | ||||||
| 	bool hash_uc_fid; | 	bool hash_uc_fid; | ||||||
| 	u8 fid; | 	u8 fid; // AKA MSTI | ||||||
|  |  | ||||||
|  | 	// The following fields are used only by the RTL931X | ||||||
|  | 	int if_id;		// Interface (index in L3_EGR_INTF_IDX) | ||||||
|  | 	u16 multicast_grp_mask; | ||||||
|  | 	int l2_tunnel_list_id; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum l2_entry_type { | enum l2_entry_type { | ||||||
| @@ -488,6 +517,15 @@ struct rtl838x_l2_entry { | |||||||
| 	u16 mc_mac_index; | 	u16 mc_mac_index; | ||||||
| 	u16 nh_route_id; | 	u16 nh_route_id; | ||||||
| 	bool nh_vlan_target;  // Only RTL83xx: VLAN used for next hop | 	bool nh_vlan_target;  // Only RTL83xx: VLAN used for next hop | ||||||
|  |  | ||||||
|  | 	// The following is only valid on RTL931x | ||||||
|  | 	bool is_open_flow; | ||||||
|  | 	bool is_pe_forward; | ||||||
|  | 	bool is_local_forward; | ||||||
|  | 	bool is_remote_forward; | ||||||
|  | 	bool is_l2_tunnel; | ||||||
|  | 	int l2_tunnel_id; | ||||||
|  | 	int l2_tunnel_list_id; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum fwd_rule_action { | enum fwd_rule_action { | ||||||
| @@ -500,6 +538,17 @@ enum pie_phase { | |||||||
| 	PHASE_IACL = 1, | 	PHASE_IACL = 1, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | enum igr_filter { | ||||||
|  | 	IGR_FORWARD = 0, | ||||||
|  | 	IGR_DROP = 1, | ||||||
|  | 	IGR_TRAP = 2, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum egr_filter { | ||||||
|  | 	EGR_DISABLE = 0, | ||||||
|  | 	EGR_ENABLE = 1, | ||||||
|  | }; | ||||||
|  |  | ||||||
| /* Intermediate representation of a  Packet Inspection Engine Rule | /* Intermediate representation of a  Packet Inspection Engine Rule | ||||||
|  * as suggested by the Kernel's tc flower offload subsystem |  * as suggested by the Kernel's tc flower offload subsystem | ||||||
|  * Field meaning is universal across SoC families, but data content is specific |  * Field meaning is universal across SoC families, but data content is specific | ||||||
|   | |||||||
| @@ -125,6 +125,9 @@ void rtl930x_print_matrix(void); | |||||||
|  |  | ||||||
| /* RTL931x-specific */ | /* RTL931x-specific */ | ||||||
| irqreturn_t rtl931x_switch_irq(int irq, void *dev_id); | irqreturn_t rtl931x_switch_irq(int irq, void *dev_id); | ||||||
|  | int rtl931x_sds_cmu_band_get(int sds, phy_interface_t mode); | ||||||
|  | int rtl931x_sds_cmu_band_set(int sds, bool enable, u32 band, phy_interface_t mode); | ||||||
|  | void rtl931x_sds_init(u32 sds, phy_interface_t mode); | ||||||
|  |  | ||||||
| #endif /* _NET_DSA_RTL83XX_H */ | #endif /* _NET_DSA_RTL83XX_H */ | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user