diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/phy/mv88e61xx.c | 42 | 
1 files changed, 28 insertions, 14 deletions
| diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c index 9aba04253c4..63675e4e687 100644 --- a/drivers/net/phy/mv88e61xx.c +++ b/drivers/net/phy/mv88e61xx.c @@ -84,11 +84,7 @@  #define GLOBAL1_MON_CTRL_CPUDEST_SHIFT	4  #define GLOBAL1_MON_CTRL_CPUDEST_WIDTH	4 -#define PORT_REG_STATUS_LINK		BIT(11) -#define PORT_REG_STATUS_DUPLEX		BIT(10) -  #define PORT_REG_STATUS_SPEED_SHIFT	8 -#define PORT_REG_STATUS_SPEED_WIDTH	2  #define PORT_REG_STATUS_SPEED_10	0  #define PORT_REG_STATUS_SPEED_100	1  #define PORT_REG_STATUS_SPEED_1000	2 @@ -107,6 +103,7 @@  #define PORT_REG_PHYS_CTRL_DUPLEX_VALUE	BIT(3)  #define PORT_REG_PHYS_CTRL_DUPLEX_FORCE	BIT(2)  #define PORT_REG_PHYS_CTRL_SPD1000	BIT(1) +#define PORT_REG_PHYS_CTRL_SPD100	BIT(0)  #define PORT_REG_PHYS_CTRL_SPD_MASK	(BIT(1) | BIT(0))  #define PORT_REG_CTRL_PSTATE_SHIFT	0 @@ -196,6 +193,9 @@ struct mv88e61xx_phy_priv {  	int id;  	int port_count;		/* Number of switch ports */  	int port_reg_base;	/* Base of the switch port registers */ +	u16 port_stat_link_mask;/* Bitmask for port link status bits */ +	u16 port_stat_dup_mask; /* Bitmask for port duplex status bits */ +	u8 port_stat_speed_width;/* Width of speed status bitfield */  	u8 global1;	/* Offset of Switch Global 1 registers */  	u8 global2;	/* Offset of Switch Global 2 registers */  }; @@ -644,6 +644,7 @@ static int mv88e61xx_port_set_vlan(struct phy_device *phydev, u8 port,  static int mv88e61xx_read_port_config(struct phy_device *phydev, u8 port)  { +	struct mv88e61xx_phy_priv *priv = phydev->priv;  	int res;  	int val;  	bool forced = false; @@ -651,7 +652,7 @@ static int mv88e61xx_read_port_config(struct phy_device *phydev, u8 port)  	val = mv88e61xx_port_read(phydev, port, PORT_REG_STATUS);  	if (val < 0)  		return val; -	if (!(val & PORT_REG_STATUS_LINK)) { +	if (!(val & priv->port_stat_link_mask)) {  		/* Temporarily force link to read port configuration */  		u32 timeout = 100;  		forced = true; @@ -674,7 +675,7 @@ static int mv88e61xx_read_port_config(struct phy_device *phydev, u8 port)  				res = -EIO;  				goto unforce;  			} -			if (val & PORT_REG_STATUS_LINK) +			if (val & priv->port_stat_link_mask)  				break;  		} while (--timeout); @@ -684,13 +685,13 @@ static int mv88e61xx_read_port_config(struct phy_device *phydev, u8 port)  		}  	} -	if (val & PORT_REG_STATUS_DUPLEX) +	if (val & priv->port_stat_dup_mask)  		phydev->duplex = DUPLEX_FULL;  	else  		phydev->duplex = DUPLEX_HALF;  	val = bitfield_extract(val, PORT_REG_STATUS_SPEED_SHIFT, -			       PORT_REG_STATUS_SPEED_WIDTH); +			       priv->port_stat_speed_width);  	switch (val) {  	case PORT_REG_STATUS_SPEED_1000:  		phydev->speed = SPEED_1000; @@ -723,6 +724,7 @@ unforce:  static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port)  { +	struct mv88e61xx_phy_priv *priv = phydev->priv;  	int val;  	val = mv88e61xx_port_read(phydev, port, PORT_REG_PHYS_CTRL); @@ -730,13 +732,19 @@ static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port)  		return val;  	val &= ~(PORT_REG_PHYS_CTRL_SPD_MASK | -		 PORT_REG_PHYS_CTRL_FC_VALUE); -	val |= PORT_REG_PHYS_CTRL_PCS_AN_EN | -	       PORT_REG_PHYS_CTRL_PCS_AN_RST | -	       PORT_REG_PHYS_CTRL_FC_FORCE | +		 PORT_REG_PHYS_CTRL_FC_VALUE | +		 PORT_REG_PHYS_CTRL_FC_FORCE); +	val |= PORT_REG_PHYS_CTRL_FC_FORCE |  	       PORT_REG_PHYS_CTRL_DUPLEX_VALUE | -	       PORT_REG_PHYS_CTRL_DUPLEX_FORCE | -	       PORT_REG_PHYS_CTRL_SPD1000; +	       PORT_REG_PHYS_CTRL_DUPLEX_FORCE; + +	if (priv->id == PORT_SWITCH_ID_6071) { +		val |= PORT_REG_PHYS_CTRL_SPD100; +	} else { +		val |= PORT_REG_PHYS_CTRL_PCS_AN_EN | +		       PORT_REG_PHYS_CTRL_PCS_AN_RST | +		       PORT_REG_PHYS_CTRL_SPD1000; +	}  	if (port == CONFIG_MV88E61XX_CPU_PORT)  		val |= PORT_REG_PHYS_CTRL_LINK_VALUE | @@ -983,6 +991,9 @@ static int mv88e61xx_probe(struct phy_device *phydev)  	case PORT_SWITCH_ID_6240:  	case PORT_SWITCH_ID_6352:  		priv->port_count = 11; +		priv->port_stat_link_mask = BIT(11); +		priv->port_stat_dup_mask = BIT(10); +		priv->port_stat_speed_width = 2;  		break;  	case PORT_SWITCH_ID_6020:  	case PORT_SWITCH_ID_6070: @@ -990,6 +1001,9 @@ static int mv88e61xx_probe(struct phy_device *phydev)  	case PORT_SWITCH_ID_6220:  	case PORT_SWITCH_ID_6250:  		priv->port_count = 7; +		priv->port_stat_link_mask = BIT(12); +		priv->port_stat_dup_mask = BIT(9); +		priv->port_stat_speed_width = 1;  		break;  	default:  		free(priv); | 
