Commit 28ae1e96 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: wait for AVB Busy bit



The AVB is not an indirect table using an Update bit, but a unit using
a Busy bit. This means that we must ensure that this bit is cleared
before setting it and wait until it gets cleared again after writing
an operation. Reflect that.

Signed-off-by: default avatarVivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 19fb7f69
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@
 *	Brandon Streiff <brandon.streiff@ni.com>
 */

#include <linux/bitfield.h>

#include "global2.h"

/* Offset 0x16: AVB Command Register
@@ -27,17 +29,33 @@
/* mv88e6xxx_g2_avb_read -- Read one or multiple 16-bit words.
 * The hardware supports snapshotting up to four contiguous registers.
 */
static int mv88e6xxx_g2_avb_wait(struct mv88e6xxx_chip *chip)
{
	int bit = __bf_shf(MV88E6352_G2_AVB_CMD_BUSY);

	return mv88e6xxx_g2_wait_bit(chip, MV88E6352_G2_AVB_CMD, bit, 0);
}

static int mv88e6xxx_g2_avb_read(struct mv88e6xxx_chip *chip, u16 readop,
				 u16 *data, int len)
{
	int err;
	int i;

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

	/* Hardware can only snapshot four words. */
	if (len > 4)
		return -E2BIG;

	err = mv88e6xxx_g2_update(chip, MV88E6352_G2_AVB_CMD, readop);
	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_CMD,
				 MV88E6352_G2_AVB_CMD_BUSY | readop);
	if (err)
		return err;

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

@@ -57,11 +75,18 @@ static int mv88e6xxx_g2_avb_write(struct mv88e6xxx_chip *chip, u16 writeop,
{
	int err;

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

	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_DATA, data);
	if (err)
		return err;

	return mv88e6xxx_g2_update(chip, MV88E6352_G2_AVB_CMD, writeop);
	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_CMD,
				 MV88E6352_G2_AVB_CMD_BUSY | writeop);

	return mv88e6xxx_g2_avb_wait(chip);
}

static int mv88e6352_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,