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

Commit 683f2244 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: introduce wait mask routine



The current mv88e6xxx_wait routine is used to wait for a given mask
to be cleared to zero. However in some cases, the driver may have
to wait for a given mask to be of a certain non-zero value.

Thus provide a generic wait mask routine that will be used to implement
the current mv88e6xxx_wait function, and use it to wait for 88E6185
PPU states.

Signed-off-by: default avatarVivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 92993853
Loading
Loading
Loading
Loading
+24 −18
Original line number Diff line number Diff line
@@ -80,6 +80,29 @@ int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
	return 0;
}

int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
			u16 mask, u16 val)
{
	u16 data;
	int err;
	int i;

	/* There's no bus specific operation to wait for a mask */
	for (i = 0; i < 16; i++) {
		err = mv88e6xxx_read(chip, addr, reg, &data);
		if (err)
			return err;

		if ((data & mask) == val)
			return 0;

		usleep_range(1000, 2000);
	}

	dev_err(chip->dev, "Timeout while waiting for switch\n");
	return -ETIMEDOUT;
}

struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
{
	struct mv88e6xxx_mdio_bus *mdio_bus;
@@ -365,24 +388,7 @@ static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)

int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
{
	int i;

	for (i = 0; i < 16; i++) {
		u16 val;
		int err;

		err = mv88e6xxx_read(chip, addr, reg, &val);
		if (err)
			return err;

		if (!(val & mask))
			return 0;

		usleep_range(1000, 2000);
	}

	dev_err(chip->dev, "Timeout while waiting for switch\n");
	return -ETIMEDOUT;
	return mv88e6xxx_wait_mask(chip, addr, reg, mask, 0x0000);
}

/* Indirect write to single pointer-data register with an Update bit */
+2 −0
Original line number Diff line number Diff line
@@ -588,6 +588,8 @@ static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int po

int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
			u16 mask, u16 val);
int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg,
		     u16 update);
int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask);
+13 −34
Original line number Diff line number Diff line
@@ -32,48 +32,27 @@ int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
	return mv88e6xxx_wait(chip, chip->info->global1_addr, reg, mask);
}

int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip *chip, int reg,
			   u16 mask, u16 val)
{
	return mv88e6xxx_wait_mask(chip, chip->info->global1_addr, reg,
				   mask, val);
}

/* Offset 0x00: Switch Global Status Register */

static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip)
{
	u16 state;
	int i, err;

	for (i = 0; i < 16; i++) {
		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state);
		if (err)
			return err;

		/* Check the value of the PPUState bits 15:14 */
		state &= MV88E6185_G1_STS_PPU_STATE_MASK;
		if (state == MV88E6185_G1_STS_PPU_STATE_DISABLED)
			return 0;

		usleep_range(1000, 2000);
	}

	return -ETIMEDOUT;
	return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
				      MV88E6185_G1_STS_PPU_STATE_MASK,
				      MV88E6185_G1_STS_PPU_STATE_DISABLED);
}

static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
{
	u16 state;
	int i, err;

	for (i = 0; i < 16; ++i) {
		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state);
		if (err)
			return err;

		/* Check the value of the PPUState bits 15:14 */
		state &= MV88E6185_G1_STS_PPU_STATE_MASK;
		if (state == MV88E6185_G1_STS_PPU_STATE_POLLING)
			return 0;

		usleep_range(1000, 2000);
	}

	return -ETIMEDOUT;
	return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
				      MV88E6185_G1_STS_PPU_STATE_MASK,
				      MV88E6185_G1_STS_PPU_STATE_POLLING);
}

static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
+2 −0
Original line number Diff line number Diff line
@@ -250,6 +250,8 @@
int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val);
int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val);
int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask);
int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip *chip, int reg,
			   u16 mask, u16 val);

int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr);