diff options
Diffstat (limited to 'drivers/net/dsa/microchip')
| -rw-r--r-- | drivers/net/dsa/microchip/ksz9477_i2c.c | 4 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz_common.c | 10 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz_common.h | 7 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz_ptp.c | 2 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz_ptp.h | 2 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/lan937x_main.c | 32 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/lan937x_reg.h | 5 | 
7 files changed, 49 insertions, 13 deletions
| diff --git a/drivers/net/dsa/microchip/ksz9477_i2c.c b/drivers/net/dsa/microchip/ksz9477_i2c.c index 82bebee4615c..7d7560f23a73 100644 --- a/drivers/net/dsa/microchip/ksz9477_i2c.c +++ b/drivers/net/dsa/microchip/ksz9477_i2c.c @@ -72,8 +72,8 @@ static void ksz9477_i2c_shutdown(struct i2c_client *i2c)  }  static const struct i2c_device_id ksz9477_i2c_id[] = { -	{ "ksz9477-switch", 0 }, -	{}, +	{ "ksz9477-switch" }, +	{}  };  MODULE_DEVICE_TABLE(i2c, ksz9477_i2c_id); diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 0580b2fee21c..b074b4bb0629 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -3116,7 +3116,8 @@ static void ksz_set_xmii(struct ksz_device *dev, int port,  		/* On KSZ9893, disable RGMII in-band status support */  		if (dev->chip_id == KSZ9893_CHIP_ID ||  		    dev->chip_id == KSZ8563_CHIP_ID || -		    dev->chip_id == KSZ9563_CHIP_ID) +		    dev->chip_id == KSZ9563_CHIP_ID || +		    is_lan937x(dev))  			data8 &= ~P_MII_MAC_MODE;  		break;  	default: @@ -3917,6 +3918,13 @@ static int ksz_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr,  		return -EOPNOTSUPP;  	} +	/* KSZ9477 can only perform HSR offloading for up to two ports */ +	if (hweight8(dev->hsr_ports) >= 2) { +		NL_SET_ERR_MSG_MOD(extack, +				   "Cannot offload more than two ports - using software HSR"); +		return -EOPNOTSUPP; +	} +  	/* Self MAC address filtering, to avoid frames traversing  	 * the HSR ring more than once.  	 */ diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index ee7db46e469d..5f0a628b9849 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -22,6 +22,7 @@  /* all KSZ switches count ports from 1 */  #define KSZ_PORT_1 0  #define KSZ_PORT_2 1 +#define KSZ_PORT_4 3  struct ksz_device;  struct ksz_port; @@ -637,6 +638,12 @@ static inline int is_lan937x(struct ksz_device *dev)  		dev->chip_id == LAN9374_CHIP_ID;  } +static inline bool is_lan937x_tx_phy(struct ksz_device *dev, int port) +{ +	return (dev->chip_id == LAN9371_CHIP_ID || +		dev->chip_id == LAN9372_CHIP_ID) && port == KSZ_PORT_4; +} +  /* STP State Defines */  #define PORT_TX_ENABLE			BIT(2)  #define PORT_RX_ENABLE			BIT(1) diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c index 1fe105913c75..f0bd46e5d4ec 100644 --- a/drivers/net/dsa/microchip/ksz_ptp.c +++ b/drivers/net/dsa/microchip/ksz_ptp.c @@ -293,7 +293,7 @@ static int ksz_ptp_enable_mode(struct ksz_device *dev)  /* The function is return back the capability of timestamping feature when   * requested through ethtool -T <interface> utility   */ -int ksz_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *ts) +int ksz_get_ts_info(struct dsa_switch *ds, int port, struct kernel_ethtool_ts_info *ts)  {  	struct ksz_device *dev = ds->priv;  	struct ksz_ptp_data *ptp_data; diff --git a/drivers/net/dsa/microchip/ksz_ptp.h b/drivers/net/dsa/microchip/ksz_ptp.h index 0ca8ca4f804e..2f1783c0d723 100644 --- a/drivers/net/dsa/microchip/ksz_ptp.h +++ b/drivers/net/dsa/microchip/ksz_ptp.h @@ -38,7 +38,7 @@ int ksz_ptp_clock_register(struct dsa_switch *ds);  void ksz_ptp_clock_unregister(struct dsa_switch *ds);  int ksz_get_ts_info(struct dsa_switch *ds, int port, -		    struct ethtool_ts_info *ts); +		    struct kernel_ethtool_ts_info *ts);  int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr);  int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr);  void ksz_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index b479a628b1ae..824d9309a3d3 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -55,6 +55,9 @@ static int lan937x_vphy_ind_addr_wr(struct ksz_device *dev, int addr, int reg)  	u16 addr_base = REG_PORT_T1_PHY_CTRL_BASE;  	u16 temp; +	if (is_lan937x_tx_phy(dev, addr)) +		addr_base = REG_PORT_TX_PHY_CTRL_BASE; +  	/* get register address based on the logical port */  	temp = PORT_CTRL_ADDR(addr, (addr_base + (reg << 2))); @@ -320,6 +323,9 @@ void lan937x_phylink_get_caps(struct ksz_device *dev, int port,  		/* MII/RMII/RGMII ports */  		config->mac_capabilities |= MAC_ASYM_PAUSE | MAC_SYM_PAUSE |  					    MAC_100HD | MAC_10 | MAC_1000FD; +	} else if (is_lan937x_tx_phy(dev, port)) { +		config->mac_capabilities |= MAC_ASYM_PAUSE | MAC_SYM_PAUSE | +					    MAC_100HD | MAC_10;  	}  } @@ -370,23 +376,33 @@ int lan937x_setup(struct dsa_switch *ds)  	ds->vlan_filtering_is_global = true;  	/* Enable aggressive back off for half duplex & UNH mode */ -	lan937x_cfg(dev, REG_SW_MAC_CTRL_0, -		    (SW_PAUSE_UNH_MODE | SW_NEW_BACKOFF | SW_AGGR_BACKOFF), -		    true); +	ret = lan937x_cfg(dev, REG_SW_MAC_CTRL_0, (SW_PAUSE_UNH_MODE | +						   SW_NEW_BACKOFF | +						   SW_AGGR_BACKOFF), true); +	if (ret < 0) +		return ret;  	/* If NO_EXC_COLLISION_DROP bit is set, the switch will not drop  	 * packets when 16 or more collisions occur  	 */ -	lan937x_cfg(dev, REG_SW_MAC_CTRL_1, NO_EXC_COLLISION_DROP, true); +	ret = lan937x_cfg(dev, REG_SW_MAC_CTRL_1, NO_EXC_COLLISION_DROP, true); +	if (ret < 0) +		return ret;  	/* enable global MIB counter freeze function */ -	lan937x_cfg(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FREEZE, true); +	ret = lan937x_cfg(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FREEZE, true); +	if (ret < 0) +		return ret;  	/* disable CLK125 & CLK25, 1: disable, 0: enable */ -	lan937x_cfg(dev, REG_SW_GLOBAL_OUTPUT_CTRL__1, -		    (SW_CLK125_ENB | SW_CLK25_ENB), true); +	ret = lan937x_cfg(dev, REG_SW_GLOBAL_OUTPUT_CTRL__1, +			  (SW_CLK125_ENB | SW_CLK25_ENB), true); +	if (ret < 0) +		return ret; -	return 0; +	/* Disable global VPHY support. Related to CPU interface only? */ +	return ksz_rmw32(dev, REG_SW_CFG_STRAP_OVR, SW_VPHY_DISABLE, +			 SW_VPHY_DISABLE);  }  void lan937x_teardown(struct dsa_switch *ds) diff --git a/drivers/net/dsa/microchip/lan937x_reg.h b/drivers/net/dsa/microchip/lan937x_reg.h index 45b606b6429f..2f22a9d01de3 100644 --- a/drivers/net/dsa/microchip/lan937x_reg.h +++ b/drivers/net/dsa/microchip/lan937x_reg.h @@ -37,6 +37,10 @@  #define SW_CLK125_ENB			BIT(1)  #define SW_CLK25_ENB			BIT(0) +/* 2 - PHY Control */ +#define REG_SW_CFG_STRAP_OVR		0x0214 +#define SW_VPHY_DISABLE			BIT(31) +  /* 3 - Operation Control */  #define REG_SW_OPERATION		0x0300 @@ -147,6 +151,7 @@  /* 1 - Phy */  #define REG_PORT_T1_PHY_CTRL_BASE	0x0100 +#define REG_PORT_TX_PHY_CTRL_BASE	0x0280  /* 3 - xMII */  #define PORT_SGMII_SEL			BIT(7) |