realtek: 6.6: refactor mac config and link up for RTL83xx
Since kernel commit c5714f68a76bcad3d ("net: phylink: explicitly invalidate
link_state members in mac_config") it should be clear that link data can
only be used in mac_link_up(). Refactor that for the RTL83xx targets.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
			
			
This commit is contained in:
		
				
					committed by
					
						
						Sander Vanheule
					
				
			
			
				
	
			
			
			
						parent
						
							dc9fca1fd1
						
					
				
				
					commit
					cd958d945b
				
			@@ -671,104 +671,31 @@ static void rtl83xx_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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct dsa_port *dp = dsa_to_port(ds, port);
 | 
				
			||||||
	struct rtl838x_switch_priv *priv = ds->priv;
 | 
						struct rtl838x_switch_priv *priv = ds->priv;
 | 
				
			||||||
	u32 reg;
 | 
						u32 mcr;
 | 
				
			||||||
	int speed_bit = priv->family_id == RTL8380_FAMILY_ID ? 4 : 3;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pr_debug("%s port %d, mode %x\n", __func__, port, mode);
 | 
						pr_debug("%s port %d, mode %x\n", __func__, port, mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (port == priv->cpu_port) {
 | 
						/* currently only needed for RTL8380 */
 | 
				
			||||||
		/* Set Speed, duplex, flow control
 | 
						if (priv->family_id != RTL8380_FAMILY_ID)
 | 
				
			||||||
		 * FORCE_EN | LINK_EN | NWAY_EN | DUP_SEL
 | 
							return;
 | 
				
			||||||
		 * | SPD_SEL = 0b10 | FORCE_FC_EN | PHY_MASTER_SLV_MANUAL_EN
 | 
					
 | 
				
			||||||
		 * | MEDIA_SEL
 | 
						if (dsa_port_is_cpu(dp)) {
 | 
				
			||||||
		 */
 | 
							/* allow CRC errors on CPU-port */
 | 
				
			||||||
		if (priv->family_id == RTL8380_FAMILY_ID) {
 | 
							sw_w32_mask(0, 0x8, priv->r->mac_port_ctrl(port));
 | 
				
			||||||
			sw_w32(0x6192F, priv->r->mac_force_mode_ctrl(priv->cpu_port));
 | 
					 | 
				
			||||||
			/* allow CRC errors on CPU-port */
 | 
					 | 
				
			||||||
			sw_w32_mask(0, 0x8, RTL838X_MAC_PORT_CTRL(priv->cpu_port));
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			sw_w32_mask(0, 3, priv->r->mac_force_mode_ctrl(priv->cpu_port));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
 | 
						mcr = sw_r32(priv->r->mac_force_mode_ctrl(port));
 | 
				
			||||||
	/* Auto-Negotiation does not work for MAC in RTL8390 */
 | 
						if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
 | 
				
			||||||
	if (priv->family_id == RTL8380_FAMILY_ID) {
 | 
							pr_debug("port %d PHY autonegotiates\n", port);
 | 
				
			||||||
		if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
 | 
							rtl83xx_config_interface(port, state->interface);
 | 
				
			||||||
			pr_debug("PHY autonegotiates\n");
 | 
							mcr |= RTL838X_NWAY_EN;
 | 
				
			||||||
			reg |= RTL838X_NWAY_EN;
 | 
						} else {
 | 
				
			||||||
			sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
 | 
							mcr &= ~RTL838X_NWAY_EN;
 | 
				
			||||||
			rtl83xx_config_interface(port, state->interface);
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						sw_w32(mcr, priv->r->mac_force_mode_ctrl(port));
 | 
				
			||||||
	if (mode != MLO_AN_FIXED)
 | 
					 | 
				
			||||||
		pr_debug("Fixed state.\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Clear id_mode_dis bit, and the existing port mode, let
 | 
					 | 
				
			||||||
		 * RGMII_MODE_EN bet set by mac_link_{up,down}  */
 | 
					 | 
				
			||||||
	if (priv->family_id == RTL8380_FAMILY_ID) {
 | 
					 | 
				
			||||||
		reg &= ~(RTL838X_RX_PAUSE_EN | RTL838X_TX_PAUSE_EN);
 | 
					 | 
				
			||||||
		if (state->pause & MLO_PAUSE_TXRX_MASK) {
 | 
					 | 
				
			||||||
			if (state->pause & MLO_PAUSE_TX)
 | 
					 | 
				
			||||||
				reg |= RTL838X_TX_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);
 | 
					 | 
				
			||||||
	switch (state->speed) {
 | 
					 | 
				
			||||||
	case SPEED_1000:
 | 
					 | 
				
			||||||
		reg |= 2 << speed_bit;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case SPEED_100:
 | 
					 | 
				
			||||||
		reg |= 1 << speed_bit;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break; /* Ignore, including 10MBit which has a speed value of 0 */
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (priv->family_id == RTL8380_FAMILY_ID) {
 | 
					 | 
				
			||||||
		reg &= ~(RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN);
 | 
					 | 
				
			||||||
		if (state->link)
 | 
					 | 
				
			||||||
			reg |= RTL838X_FORCE_LINK_EN;
 | 
					 | 
				
			||||||
		if (state->duplex == RTL838X_DUPLEX_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;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* LAG members must use DUPLEX and we need to enable the link */
 | 
					 | 
				
			||||||
	if (priv->lagmembers & BIT_ULL(port)) {
 | 
					 | 
				
			||||||
		switch(priv->family_id) {
 | 
					 | 
				
			||||||
		case RTL8380_FAMILY_ID:
 | 
					 | 
				
			||||||
			reg |= (RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
		case RTL8390_FAMILY_ID:
 | 
					 | 
				
			||||||
			reg |= (RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Disable AN */
 | 
					 | 
				
			||||||
	if (priv->family_id == RTL8380_FAMILY_ID)
 | 
					 | 
				
			||||||
		reg &= ~RTL838X_NWAY_EN;
 | 
					 | 
				
			||||||
	sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void rtl931x_phylink_mac_config(struct dsa_switch *ds, int port,
 | 
					static void rtl931x_phylink_mac_config(struct dsa_switch *ds, int port,
 | 
				
			||||||
@@ -916,12 +843,14 @@ static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
 | 
				
			|||||||
				     phy_interface_t interface)
 | 
									     phy_interface_t interface)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rtl838x_switch_priv *priv = ds->priv;
 | 
						struct rtl838x_switch_priv *priv = ds->priv;
 | 
				
			||||||
 | 
						int mask = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Stop TX/RX to port */
 | 
						/* Stop TX/RX to port */
 | 
				
			||||||
	sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
 | 
						sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* No longer force link */
 | 
						/* No longer force link */
 | 
				
			||||||
	sw_w32_mask(0x3, 0, priv->r->mac_force_mode_ctrl(port));
 | 
						mask = RTL83XX_FORCE_EN | RTL83XX_FORCE_LINK_EN;
 | 
				
			||||||
 | 
						sw_w32_mask(mask, 0, priv->r->mac_force_mode_ctrl(port));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void rtl93xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
 | 
					static void rtl93xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
 | 
				
			||||||
@@ -949,10 +878,60 @@ static void rtl83xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
 | 
				
			|||||||
				   int speed, int duplex,
 | 
									   int speed, int duplex,
 | 
				
			||||||
				   bool tx_pause, bool rx_pause)
 | 
									   bool tx_pause, bool rx_pause)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct dsa_port *dp = dsa_to_port(ds, port);
 | 
				
			||||||
	struct rtl838x_switch_priv *priv = ds->priv;
 | 
						struct rtl838x_switch_priv *priv = ds->priv;
 | 
				
			||||||
 | 
						u32 mcr, spdsel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (speed == SPEED_1000)
 | 
				
			||||||
 | 
							spdsel = RTL_SPEED_1000;
 | 
				
			||||||
 | 
						else if (speed == SPEED_100)
 | 
				
			||||||
 | 
							spdsel = RTL_SPEED_100;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							spdsel = RTL_SPEED_10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mcr = sw_r32(priv->r->mac_force_mode_ctrl(port));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (priv->family_id == RTL8380_FAMILY_ID) {
 | 
				
			||||||
 | 
							mcr &= ~RTL838X_RX_PAUSE_EN;
 | 
				
			||||||
 | 
							mcr &= ~RTL838X_TX_PAUSE_EN;
 | 
				
			||||||
 | 
							mcr &= ~RTL838X_DUPLEX_MODE;
 | 
				
			||||||
 | 
							mcr &= ~RTL838X_SPEED_MASK;
 | 
				
			||||||
 | 
							mcr |= RTL83XX_FORCE_LINK_EN;
 | 
				
			||||||
 | 
							mcr |= spdsel << RTL838X_SPEED_SHIFT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (tx_pause)
 | 
				
			||||||
 | 
								mcr |= RTL838X_TX_PAUSE_EN;
 | 
				
			||||||
 | 
							if (rx_pause)
 | 
				
			||||||
 | 
								mcr |= RTL838X_RX_PAUSE_EN;
 | 
				
			||||||
 | 
							if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
 | 
				
			||||||
 | 
								mcr |= RTL838X_DUPLEX_MODE;
 | 
				
			||||||
 | 
							if (dsa_port_is_cpu(dp))
 | 
				
			||||||
 | 
								mcr |= RTL83XX_FORCE_EN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						} else if (priv->family_id == RTL8390_FAMILY_ID) {
 | 
				
			||||||
 | 
							mcr &= ~RTL839X_RX_PAUSE_EN;
 | 
				
			||||||
 | 
							mcr &= ~RTL839X_TX_PAUSE_EN;
 | 
				
			||||||
 | 
							mcr &= ~RTL839X_DUPLEX_MODE;
 | 
				
			||||||
 | 
							mcr &= ~RTL839X_SPEED_MASK;
 | 
				
			||||||
 | 
							mcr |= RTL83XX_FORCE_LINK_EN;
 | 
				
			||||||
 | 
							mcr |= spdsel << RTL839X_SPEED_SHIFT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (tx_pause)
 | 
				
			||||||
 | 
								mcr |= RTL839X_TX_PAUSE_EN;
 | 
				
			||||||
 | 
							if (rx_pause)
 | 
				
			||||||
 | 
								mcr |= RTL839X_RX_PAUSE_EN;
 | 
				
			||||||
 | 
							if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
 | 
				
			||||||
 | 
								mcr |= RTL839X_DUPLEX_MODE;
 | 
				
			||||||
 | 
							if (dsa_port_is_cpu(dp))
 | 
				
			||||||
 | 
								mcr |= RTL83XX_FORCE_EN;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_debug("%s port %d, mode %x, speed %d, duplex %d, txpause %d, rxpause %d: set mcr=%08x\n",
 | 
				
			||||||
 | 
							__func__, port, mode, speed, duplex, tx_pause, rx_pause, mcr);
 | 
				
			||||||
 | 
						sw_w32(mcr, priv->r->mac_force_mode_ctrl(port));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Restart TX/RX to port */
 | 
						/* Restart TX/RX to port */
 | 
				
			||||||
	sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
 | 
						sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
 | 
				
			||||||
	/* TODO: Set speed/duplex/pauses */
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
 | 
					static void rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -144,17 +144,24 @@
 | 
				
			|||||||
#define RTL931X_MAC_LINK_MEDIA_STS		(0x0EC8)
 | 
					#define RTL931X_MAC_LINK_MEDIA_STS		(0x0EC8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* MAC link state bits */
 | 
					/* MAC link state bits */
 | 
				
			||||||
#define RTL838X_FORCE_EN			(1 << 0)
 | 
					#define RTL_SPEED_10				0
 | 
				
			||||||
#define RTL838X_FORCE_LINK_EN			(1 << 1)
 | 
					#define RTL_SPEED_100				1
 | 
				
			||||||
 | 
					#define RTL_SPEED_1000				2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define RTL83XX_FORCE_EN			(1 << 0)
 | 
				
			||||||
 | 
					#define RTL83XX_FORCE_LINK_EN			(1 << 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RTL838X_NWAY_EN				(1 << 2)
 | 
					#define RTL838X_NWAY_EN				(1 << 2)
 | 
				
			||||||
#define RTL838X_DUPLEX_MODE			(1 << 3)
 | 
					#define RTL838X_DUPLEX_MODE			(1 << 3)
 | 
				
			||||||
 | 
					#define RTL838X_SPEED_SHIFT			(4)
 | 
				
			||||||
 | 
					#define RTL838X_SPEED_MASK			(3 << RTL838X_SPEED_SHIFT)
 | 
				
			||||||
#define RTL838X_TX_PAUSE_EN			(1 << 6)
 | 
					#define RTL838X_TX_PAUSE_EN			(1 << 6)
 | 
				
			||||||
#define RTL838X_RX_PAUSE_EN			(1 << 7)
 | 
					#define RTL838X_RX_PAUSE_EN			(1 << 7)
 | 
				
			||||||
#define RTL838X_MAC_FORCE_FC_EN			(1 << 8)
 | 
					#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_DUPLEX_MODE			(1 << 2)
 | 
				
			||||||
 | 
					#define RTL839X_SPEED_SHIFT			(3)
 | 
				
			||||||
 | 
					#define RTL839X_SPEED_MASK			(3 << RTL839X_SPEED_SHIFT)
 | 
				
			||||||
#define RTL839X_TX_PAUSE_EN			(1 << 5)
 | 
					#define RTL839X_TX_PAUSE_EN			(1 << 5)
 | 
				
			||||||
#define RTL839X_RX_PAUSE_EN			(1 << 6)
 | 
					#define RTL839X_RX_PAUSE_EN			(1 << 6)
 | 
				
			||||||
#define RTL839X_MAC_FORCE_FC_EN			(1 << 7)
 | 
					#define RTL839X_MAC_FORCE_FC_EN			(1 << 7)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user