mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net: dsa: Add support for switch EEPROM access
On some chips it is possible to access the switch eeprom. Add infrastructure support for it. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									87e5f66b37
								
							
						
					
					
						commit
						6793abb4e8
					
				
					 3 changed files with 55 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -38,6 +38,9 @@ struct dsa_chip_data {
 | 
			
		|||
	struct device	*host_dev;
 | 
			
		||||
	int		sw_addr;
 | 
			
		||||
 | 
			
		||||
	/* set to size of eeprom if supported by the switch */
 | 
			
		||||
	int		eeprom_len;
 | 
			
		||||
 | 
			
		||||
	/* Device tree node pointer for this specific switch chip
 | 
			
		||||
	 * used during switch setup in case additional properties
 | 
			
		||||
	 * and resources needs to be used
 | 
			
		||||
| 
						 | 
				
			
			@ -258,6 +261,13 @@ struct dsa_switch_driver {
 | 
			
		|||
	int	(*set_temp_limit)(struct dsa_switch *ds, int temp);
 | 
			
		||||
	int	(*get_temp_alarm)(struct dsa_switch *ds, bool *alarm);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* EEPROM access */
 | 
			
		||||
	int	(*get_eeprom_len)(struct dsa_switch *ds);
 | 
			
		||||
	int	(*get_eeprom)(struct dsa_switch *ds,
 | 
			
		||||
			      struct ethtool_eeprom *eeprom, u8 *data);
 | 
			
		||||
	int	(*set_eeprom)(struct dsa_switch *ds,
 | 
			
		||||
			      struct ethtool_eeprom *eeprom, u8 *data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void register_switch_driver(struct dsa_switch_driver *type);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -575,6 +575,7 @@ static int dsa_of_probe(struct platform_device *pdev)
 | 
			
		|||
	const char *port_name;
 | 
			
		||||
	int chip_index, port_index;
 | 
			
		||||
	const unsigned int *sw_addr, *port_reg;
 | 
			
		||||
	u32 eeprom_len;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	mdio = of_parse_phandle(np, "dsa,mii-bus", 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -626,6 +627,9 @@ static int dsa_of_probe(struct platform_device *pdev)
 | 
			
		|||
		if (cd->sw_addr > PHY_MAX_ADDR)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (!of_property_read_u32(np, "eeprom-length", &eeprom_len))
 | 
			
		||||
			cd->eeprom_len = eeprom_len;
 | 
			
		||||
 | 
			
		||||
		for_each_available_child_of_node(child, port) {
 | 
			
		||||
			port_reg = of_get_property(port, "reg", NULL);
 | 
			
		||||
			if (!port_reg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -271,6 +271,44 @@ static u32 dsa_slave_get_link(struct net_device *dev)
 | 
			
		|||
	return -EOPNOTSUPP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dsa_slave_get_eeprom_len(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct dsa_slave_priv *p = netdev_priv(dev);
 | 
			
		||||
	struct dsa_switch *ds = p->parent;
 | 
			
		||||
 | 
			
		||||
	if (ds->pd->eeprom_len)
 | 
			
		||||
		return ds->pd->eeprom_len;
 | 
			
		||||
 | 
			
		||||
	if (ds->drv->get_eeprom_len)
 | 
			
		||||
		return ds->drv->get_eeprom_len(ds);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dsa_slave_get_eeprom(struct net_device *dev,
 | 
			
		||||
				struct ethtool_eeprom *eeprom, u8 *data)
 | 
			
		||||
{
 | 
			
		||||
	struct dsa_slave_priv *p = netdev_priv(dev);
 | 
			
		||||
	struct dsa_switch *ds = p->parent;
 | 
			
		||||
 | 
			
		||||
	if (ds->drv->get_eeprom)
 | 
			
		||||
		return ds->drv->get_eeprom(ds, eeprom, data);
 | 
			
		||||
 | 
			
		||||
	return -EOPNOTSUPP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dsa_slave_set_eeprom(struct net_device *dev,
 | 
			
		||||
				struct ethtool_eeprom *eeprom, u8 *data)
 | 
			
		||||
{
 | 
			
		||||
	struct dsa_slave_priv *p = netdev_priv(dev);
 | 
			
		||||
	struct dsa_switch *ds = p->parent;
 | 
			
		||||
 | 
			
		||||
	if (ds->drv->set_eeprom)
 | 
			
		||||
		return ds->drv->set_eeprom(ds, eeprom, data);
 | 
			
		||||
 | 
			
		||||
	return -EOPNOTSUPP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dsa_slave_get_strings(struct net_device *dev,
 | 
			
		||||
				  uint32_t stringset, uint8_t *data)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -387,6 +425,9 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
 | 
			
		|||
	.get_drvinfo		= dsa_slave_get_drvinfo,
 | 
			
		||||
	.nway_reset		= dsa_slave_nway_reset,
 | 
			
		||||
	.get_link		= dsa_slave_get_link,
 | 
			
		||||
	.get_eeprom_len		= dsa_slave_get_eeprom_len,
 | 
			
		||||
	.get_eeprom		= dsa_slave_get_eeprom,
 | 
			
		||||
	.set_eeprom		= dsa_slave_set_eeprom,
 | 
			
		||||
	.get_strings		= dsa_slave_get_strings,
 | 
			
		||||
	.get_ethtool_stats	= dsa_slave_get_ethtool_stats,
 | 
			
		||||
	.get_sset_count		= dsa_slave_get_sset_count,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue