Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c37fb15 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mv88r6xxx-eeprom-rework'



Vivien Didelot says:

====================
net: dsa: mv88e6xxx: rework EEPROM code

Some switches can access an optional external EEPROM via its registers.

The 88E6352 family of switches have 8-bit address / 16-bit data access.
The new 88E6390 family has 16-bit address / 8-bit data access.

This patchset cleans up the EEPROM code with 16-suffixed Global2 helpers
and makes it easy to add future support for 8-bit data EEPROM access.

It also removes unnecessary mutexes and a few locked access functions.

Changes in v2:
  - add missing Signed-off-by tag
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e6c044f5 8f6345b2
Loading
Loading
Loading
Loading
+239 −279
Original line number Diff line number Diff line
@@ -254,35 +254,12 @@ static int _mv88e6xxx_reg_read(struct mv88e6xxx_chip *chip, int addr, int reg)
	return val;
}

static int mv88e6xxx_reg_read(struct mv88e6xxx_chip *chip, int addr, int reg)
{
	int ret;

	mutex_lock(&chip->reg_lock);
	ret = _mv88e6xxx_reg_read(chip, addr, reg);
	mutex_unlock(&chip->reg_lock);

	return ret;
}

static int _mv88e6xxx_reg_write(struct mv88e6xxx_chip *chip, int addr,
				int reg, u16 val)
{
	return mv88e6xxx_write(chip, addr, reg, val);
}

static int mv88e6xxx_reg_write(struct mv88e6xxx_chip *chip, int addr,
			       int reg, u16 val)
{
	int ret;

	mutex_lock(&chip->reg_lock);
	ret = _mv88e6xxx_reg_write(chip, addr, reg, val);
	mutex_unlock(&chip->reg_lock);

	return ret;
}

static int mv88e6xxx_mdio_read_direct(struct mv88e6xxx_chip *chip,
				      int addr, int regnum)
{
@@ -861,259 +838,12 @@ static int _mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int reg, int offset,
	return -ETIMEDOUT;
}

static int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int reg,
			  int offset, u16 mask)
{
	int ret;

	mutex_lock(&chip->reg_lock);
	ret = _mv88e6xxx_wait(chip, reg, offset, mask);
	mutex_unlock(&chip->reg_lock);

	return ret;
}

static int mv88e6xxx_mdio_wait(struct mv88e6xxx_chip *chip)
{
	return _mv88e6xxx_wait(chip, REG_GLOBAL2, GLOBAL2_SMI_OP,
			       GLOBAL2_SMI_OP_BUSY);
}

static int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);

	return mv88e6xxx_wait(chip, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
			      GLOBAL2_EEPROM_OP_LOAD);
}

static int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);

	return mv88e6xxx_wait(chip, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
			      GLOBAL2_EEPROM_OP_BUSY);
}

static int mv88e6xxx_read_eeprom_word(struct dsa_switch *ds, int addr)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);
	int ret;

	mutex_lock(&chip->eeprom_mutex);

	ret = mv88e6xxx_reg_write(chip, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
				  GLOBAL2_EEPROM_OP_READ |
				  (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
	if (ret < 0)
		goto error;

	ret = mv88e6xxx_eeprom_busy_wait(ds);
	if (ret < 0)
		goto error;

	ret = mv88e6xxx_reg_read(chip, REG_GLOBAL2, GLOBAL2_EEPROM_DATA);
error:
	mutex_unlock(&chip->eeprom_mutex);
	return ret;
}

static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);

	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEPROM))
		return chip->eeprom_len;

	return 0;
}

static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
				struct ethtool_eeprom *eeprom, u8 *data)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);
	int offset;
	int len;
	int ret;

	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEPROM))
		return -EOPNOTSUPP;

	offset = eeprom->offset;
	len = eeprom->len;
	eeprom->len = 0;

	eeprom->magic = 0xc3ec4951;

	ret = mv88e6xxx_eeprom_load_wait(ds);
	if (ret < 0)
		return ret;

	if (offset & 1) {
		int word;

		word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
		if (word < 0)
			return word;

		*data++ = (word >> 8) & 0xff;

		offset++;
		len--;
		eeprom->len++;
	}

	while (len >= 2) {
		int word;

		word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
		if (word < 0)
			return word;

		*data++ = word & 0xff;
		*data++ = (word >> 8) & 0xff;

		offset += 2;
		len -= 2;
		eeprom->len += 2;
	}

	if (len) {
		int word;

		word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
		if (word < 0)
			return word;

		*data++ = word & 0xff;

		offset++;
		len--;
		eeprom->len++;
	}

	return 0;
}

static int mv88e6xxx_eeprom_is_readonly(struct dsa_switch *ds)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);
	int ret;

	ret = mv88e6xxx_reg_read(chip, REG_GLOBAL2, GLOBAL2_EEPROM_OP);
	if (ret < 0)
		return ret;

	if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN))
		return -EROFS;

	return 0;
}

static int mv88e6xxx_write_eeprom_word(struct dsa_switch *ds, int addr,
				       u16 data)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);
	int ret;

	mutex_lock(&chip->eeprom_mutex);

	ret = mv88e6xxx_reg_write(chip, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data);
	if (ret < 0)
		goto error;

	ret = mv88e6xxx_reg_write(chip, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
				  GLOBAL2_EEPROM_OP_WRITE |
				  (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
	if (ret < 0)
		goto error;

	ret = mv88e6xxx_eeprom_busy_wait(ds);
error:
	mutex_unlock(&chip->eeprom_mutex);
	return ret;
}

static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
				struct ethtool_eeprom *eeprom, u8 *data)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);
	int offset;
	int ret;
	int len;

	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEPROM))
		return -EOPNOTSUPP;

	if (eeprom->magic != 0xc3ec4951)
		return -EINVAL;

	ret = mv88e6xxx_eeprom_is_readonly(ds);
	if (ret)
		return ret;

	offset = eeprom->offset;
	len = eeprom->len;
	eeprom->len = 0;

	ret = mv88e6xxx_eeprom_load_wait(ds);
	if (ret < 0)
		return ret;

	if (offset & 1) {
		int word;

		word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
		if (word < 0)
			return word;

		word = (*data++ << 8) | (word & 0xff);

		ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word);
		if (ret < 0)
			return ret;

		offset++;
		len--;
		eeprom->len++;
	}

	while (len >= 2) {
		int word;

		word = *data++;
		word |= *data++ << 8;

		ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word);
		if (ret < 0)
			return ret;

		offset += 2;
		len -= 2;
		eeprom->len += 2;
	}

	if (len) {
		int word;

		word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
		if (word < 0)
			return word;

		word = (word & 0xff00) | *data++;

		ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word);
		if (ret < 0)
			return ret;

		offset++;
		len--;
		eeprom->len++;
	}

	return 0;
}

static int _mv88e6xxx_atu_wait(struct mv88e6xxx_chip *chip)
{
	return _mv88e6xxx_wait(chip, REG_GLOBAL, GLOBAL_ATU_OP,
@@ -2685,6 +2415,17 @@ static int mv88e6xxx_power_on_serdes(struct mv88e6xxx_chip *chip)
	return ret;
}

static int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port,
			       int reg, u16 *val)
{
	int addr = chip->info->port_base_addr + port;

	if (port >= chip->info->num_ports)
		return -EINVAL;

	return mv88e6xxx_read(chip, addr, reg, val);
}

static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
{
	struct dsa_switch *ds = chip->ds;
@@ -3261,6 +3002,58 @@ static int mv88e6xxx_g2_clear_pot(struct mv88e6xxx_chip *chip)
	return err;
}

static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
{
	return _mv88e6xxx_wait(chip, REG_GLOBAL2, GLOBAL2_EEPROM_CMD,
			       GLOBAL2_EEPROM_CMD_BUSY |
			       GLOBAL2_EEPROM_CMD_RUNNING);
}

static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
{
	int err;

	err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_EEPROM_CMD, cmd);
	if (err)
		return err;

	return mv88e6xxx_g2_eeprom_wait(chip);
}

static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
				      u8 addr, u16 *data)
{
	u16 cmd = GLOBAL2_EEPROM_CMD_OP_READ | addr;
	int err;

	err = mv88e6xxx_g2_eeprom_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
	if (err)
		return err;

	return mv88e6xxx_read(chip, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data);
}

static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
				       u8 addr, u16 data)
{
	u16 cmd = GLOBAL2_EEPROM_CMD_OP_WRITE | addr;
	int err;

	err = mv88e6xxx_g2_eeprom_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data);
	if (err)
		return err;

	return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
}

static int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
{
	u16 reg;
@@ -3345,9 +3138,6 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
	chip->ds = ds;
	ds->slave_mii_bus = chip->mdio_bus;

	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEPROM))
		mutex_init(&chip->eeprom_mutex);

	mutex_lock(&chip->reg_lock);

	err = mv88e6xxx_switch_reset(chip);
@@ -3670,6 +3460,173 @@ static int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
}
#endif /* CONFIG_NET_DSA_HWMON */

static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);

	return chip->eeprom_len;
}

static int mv88e6xxx_get_eeprom16(struct mv88e6xxx_chip *chip,
				  struct ethtool_eeprom *eeprom, u8 *data)
{
	unsigned int offset = eeprom->offset;
	unsigned int len = eeprom->len;
	u16 val;
	int err;

	eeprom->len = 0;

	if (offset & 1) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		*data++ = (val >> 8) & 0xff;

		offset++;
		len--;
		eeprom->len++;
	}

	while (len >= 2) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		*data++ = val & 0xff;
		*data++ = (val >> 8) & 0xff;

		offset += 2;
		len -= 2;
		eeprom->len += 2;
	}

	if (len) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		*data++ = val & 0xff;

		offset++;
		len--;
		eeprom->len++;
	}

	return 0;
}

static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
				struct ethtool_eeprom *eeprom, u8 *data)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);
	int err;

	mutex_lock(&chip->reg_lock);

	if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_EEPROM16))
		err = mv88e6xxx_get_eeprom16(chip, eeprom, data);
	else
		err = -EOPNOTSUPP;

	mutex_unlock(&chip->reg_lock);

	if (err)
		return err;

	eeprom->magic = 0xc3ec4951;

	return 0;
}

static int mv88e6xxx_set_eeprom16(struct mv88e6xxx_chip *chip,
				  struct ethtool_eeprom *eeprom, u8 *data)
{
	unsigned int offset = eeprom->offset;
	unsigned int len = eeprom->len;
	u16 val;
	int err;

	/* Ensure the RO WriteEn bit is set */
	err = mv88e6xxx_read(chip, REG_GLOBAL2, GLOBAL2_EEPROM_CMD, &val);
	if (err)
		return err;

	if (!(val & GLOBAL2_EEPROM_CMD_WRITE_EN))
		return -EROFS;

	eeprom->len = 0;

	if (offset & 1) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		val = (*data++ << 8) | (val & 0xff);

		err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
		if (err)
			return err;

		offset++;
		len--;
		eeprom->len++;
	}

	while (len >= 2) {
		val = *data++;
		val |= *data++ << 8;

		err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
		if (err)
			return err;

		offset += 2;
		len -= 2;
		eeprom->len += 2;
	}

	if (len) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		val = (val & 0xff00) | *data++;

		err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
		if (err)
			return err;

		offset++;
		len--;
		eeprom->len++;
	}

	return 0;
}

static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
				struct ethtool_eeprom *eeprom, u8 *data)
{
	struct mv88e6xxx_chip *chip = ds_to_priv(ds);
	int err;

	if (eeprom->magic != 0xc3ec4951)
		return -EINVAL;

	mutex_lock(&chip->reg_lock);

	if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_EEPROM16))
		err = mv88e6xxx_set_eeprom16(chip, eeprom, data);
	else
		err = -EOPNOTSUPP;

	mutex_unlock(&chip->reg_lock);

	return err;
}

static const struct mv88e6xxx_info mv88e6xxx_table[] = {
	[MV88E6085] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
@@ -3873,12 +3830,15 @@ static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
{
	const struct mv88e6xxx_info *info;
	int id, prod_num, rev;
	unsigned int prod_num, rev;
	u16 id;
	int err;

	id = mv88e6xxx_reg_read(chip, chip->info->port_base_addr,
				PORT_SWITCH_ID);
	if (id < 0)
		return id;
	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_port_read(chip, 0, PORT_SWITCH_ID, &id);
	mutex_unlock(&chip->reg_lock);
	if (err)
		return err;

	prod_num = (id & 0xfff0) >> 4;
	rev = id & 0x000f;
@@ -4063,7 +4023,7 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
	if (IS_ERR(chip->reset))
		return PTR_ERR(chip->reset);

	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEPROM) &&
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_EEPROM16) &&
	    !of_property_read_u32(np, "eeprom-length", &eeprom_len))
		chip->eeprom_len = eeprom_len;

+19 −26
Original line number Diff line number Diff line
@@ -318,13 +318,14 @@
#define GLOBAL2_PRIO_OVERRIDE_SNOOP_SHIFT	4
#define GLOBAL2_PRIO_OVERRIDE_FORCE_ARP		BIT(3)
#define GLOBAL2_PRIO_OVERRIDE_ARP_SHIFT		0
#define GLOBAL2_EEPROM_OP	0x14
#define GLOBAL2_EEPROM_OP_BUSY		BIT(15)
#define GLOBAL2_EEPROM_OP_WRITE		((3 << 12) | GLOBAL2_EEPROM_OP_BUSY)
#define GLOBAL2_EEPROM_OP_READ		((4 << 12) | GLOBAL2_EEPROM_OP_BUSY)
#define GLOBAL2_EEPROM_OP_LOAD		BIT(11)
#define GLOBAL2_EEPROM_OP_WRITE_EN	BIT(10)
#define GLOBAL2_EEPROM_OP_ADDR_MASK	0xff
#define GLOBAL2_EEPROM_CMD		0x14
#define GLOBAL2_EEPROM_CMD_BUSY		BIT(15)
#define GLOBAL2_EEPROM_CMD_OP_WRITE	((0x3 << 12) | GLOBAL2_EEPROM_CMD_BUSY)
#define GLOBAL2_EEPROM_CMD_OP_READ	((0x4 << 12) | GLOBAL2_EEPROM_CMD_BUSY)
#define GLOBAL2_EEPROM_CMD_OP_LOAD	((0x6 << 12) | GLOBAL2_EEPROM_CMD_BUSY)
#define GLOBAL2_EEPROM_CMD_RUNNING	BIT(11)
#define GLOBAL2_EEPROM_CMD_WRITE_EN	BIT(10)
#define GLOBAL2_EEPROM_CMD_ADDR_MASK	0xff
#define GLOBAL2_EEPROM_DATA	0x15
#define GLOBAL2_PTP_AVB_OP	0x16
#define GLOBAL2_PTP_AVB_DATA	0x17
@@ -387,11 +388,6 @@ enum mv88e6xxx_cap {
	 */
	MV88E6XXX_CAP_EEE,

	/* EEPROM Command and Data registers.
	 * See GLOBAL2_EEPROM_OP and GLOBAL2_EEPROM_DATA.
	 */
	MV88E6XXX_CAP_EEPROM,

	/* Switch Global 2 Registers.
	 * The device contains a second set of global 16-bit registers.
	 */
@@ -404,6 +400,8 @@ enum mv88e6xxx_cap {
	MV88E6XXX_CAP_G2_PVT_DATA,	/* (0x0c) Cross Chip Port VLAN Data */
	MV88E6XXX_CAP_G2_SWITCH_MAC,	/* (0x0d) Switch MAC/WoL/WoF */
	MV88E6XXX_CAP_G2_POT,		/* (0x0f) Priority Override Table */
	MV88E6XXX_CAP_G2_EEPROM_CMD,	/* (0x14) EEPROM Command */
	MV88E6XXX_CAP_G2_EEPROM_DATA,	/* (0x15) EEPROM Data */

	/* Multi-chip Addressing Mode.
	 * Some chips require an indirect SMI access when their SMI device
@@ -443,7 +441,6 @@ enum mv88e6xxx_cap {

/* Bitmask of capabilities */
#define MV88E6XXX_FLAG_EEE		BIT(MV88E6XXX_CAP_EEE)
#define MV88E6XXX_FLAG_EEPROM		BIT(MV88E6XXX_CAP_EEPROM)
#define MV88E6XXX_FLAG_GLOBAL2		BIT(MV88E6XXX_CAP_GLOBAL2)
#define MV88E6XXX_FLAG_G2_MGMT_EN_2X	BIT(MV88E6XXX_CAP_G2_MGMT_EN_2X)
#define MV88E6XXX_FLAG_G2_MGMT_EN_0X	BIT(MV88E6XXX_CAP_G2_MGMT_EN_0X)
@@ -453,6 +450,8 @@ enum mv88e6xxx_cap {
#define MV88E6XXX_FLAG_G2_PVT_DATA	BIT(MV88E6XXX_CAP_G2_PVT_DATA)
#define MV88E6XXX_FLAG_G2_SWITCH_MAC	BIT(MV88E6XXX_CAP_G2_SWITCH_MAC)
#define MV88E6XXX_FLAG_G2_POT		BIT(MV88E6XXX_CAP_G2_POT)
#define MV88E6XXX_FLAG_G2_EEPROM_CMD	BIT(MV88E6XXX_CAP_G2_EEPROM_CMD)
#define MV88E6XXX_FLAG_G2_EEPROM_DATA	BIT(MV88E6XXX_CAP_G2_EEPROM_DATA)
#define MV88E6XXX_FLAG_MULTI_CHIP	BIT(MV88E6XXX_CAP_MULTI_CHIP)
#define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
#define MV88E6XXX_FLAG_PPU_ACTIVE	BIT(MV88E6XXX_CAP_PPU_ACTIVE)
@@ -462,6 +461,11 @@ enum mv88e6xxx_cap {
#define MV88E6XXX_FLAG_TEMP_LIMIT	BIT(MV88E6XXX_CAP_TEMP_LIMIT)
#define MV88E6XXX_FLAG_VTU		BIT(MV88E6XXX_CAP_VTU)

/* EEPROM Programming via Global2 with 16-bit data */
#define MV88E6XXX_FLAGS_EEPROM16	\
	(MV88E6XXX_FLAG_G2_EEPROM_CMD |	\
	 MV88E6XXX_FLAG_G2_EEPROM_DATA)

/* Ingress Rate Limit unit */
#define MV88E6XXX_FLAGS_IRL		\
	(MV88E6XXX_FLAG_G2_IRL_CMD |	\
@@ -513,7 +517,6 @@ enum mv88e6xxx_cap {

#define MV88E6XXX_FLAGS_FAMILY_6320	\
	(MV88E6XXX_FLAG_EEE |		\
	 MV88E6XXX_FLAG_EEPROM |	\
	 MV88E6XXX_FLAG_GLOBAL2 |	\
	 MV88E6XXX_FLAG_G2_MGMT_EN_2X |	\
	 MV88E6XXX_FLAG_G2_MGMT_EN_0X |	\
@@ -525,6 +528,7 @@ enum mv88e6xxx_cap {
	 MV88E6XXX_FLAG_TEMP |		\
	 MV88E6XXX_FLAG_TEMP_LIMIT |	\
	 MV88E6XXX_FLAG_VTU |		\
	 MV88E6XXX_FLAGS_EEPROM16 |	\
	 MV88E6XXX_FLAGS_IRL |		\
	 MV88E6XXX_FLAGS_PVT)

@@ -545,7 +549,6 @@ enum mv88e6xxx_cap {

#define MV88E6XXX_FLAGS_FAMILY_6352	\
	(MV88E6XXX_FLAG_EEE |		\
	 MV88E6XXX_FLAG_EEPROM |	\
	 MV88E6XXX_FLAG_GLOBAL2 |	\
	 MV88E6XXX_FLAG_G2_MGMT_EN_2X |	\
	 MV88E6XXX_FLAG_G2_MGMT_EN_0X |	\
@@ -558,6 +561,7 @@ enum mv88e6xxx_cap {
	 MV88E6XXX_FLAG_TEMP |		\
	 MV88E6XXX_FLAG_TEMP_LIMIT |	\
	 MV88E6XXX_FLAG_VTU |		\
	 MV88E6XXX_FLAGS_EEPROM16 |	\
	 MV88E6XXX_FLAGS_IRL |		\
	 MV88E6XXX_FLAGS_PVT)

@@ -629,17 +633,6 @@ struct mv88e6xxx_chip {
	 */
	struct mutex	stats_mutex;

	/* This mutex serializes phy access for chips with
	 * indirect phy addressing. It is unused for chips
	 * with direct phy access.
	 */
	struct mutex	phy_mutex;

	/* This mutex serializes eeprom access for chips with
	 * eeprom support.
	 */
	struct mutex eeprom_mutex;

	struct mv88e6xxx_priv_port	ports[DSA_MAX_PORTS];

	/* A switch may have a GPIO line tied to its reset pin. Parse