// SPDX-License-Identifier: GPL-2.0-or-later /* * Marvell 88E6xxx System Management Interface (SMI) support * * Copyright (c) 2008 Marvell Semiconductor * * Copyright (c) 2019 Vivien Didelot <vivien.didelot@gmail.com>
*/
#include"chip.h" #include"smi.h"
/* The switch ADDR[4:1] configuration pins define the chip SMI device address * (ADDR[0] is always zero, thus only even SMI addresses can be strapped). * * When ADDR is all zero, the chip uses Single-chip Addressing Mode, assuming it * is the only device connected to the SMI master. In this mode it responds to * all 32 possible SMI addresses, and thus maps directly the internal devices. * * When ADDR is non-zero, the chip uses Multi-chip Addressing Mode, allowing * multiple devices to share the SMI interface. In this mode it responds to only * 2 registers, used to indirectly access the internal SMI devices. * * Some chips use a different scheme: Only the ADDR4 pin is used for * configuration, and the device responds to 16 of the 32 SMI * addresses, allowing two to coexist on the same SMI interface.
*/
staticint mv88e6xxx_smi_direct_read(struct mv88e6xxx_chip *chip, int dev, int reg, u16 *data)
{ int ret;
ret = mdiobus_read_nested(chip->bus, dev, reg); if (ret < 0) return ret;
*data = ret & 0xffff;
return 0;
}
staticint mv88e6xxx_smi_direct_write(struct mv88e6xxx_chip *chip, int dev, int reg, u16 data)
{ int ret;
ret = mdiobus_write_nested(chip->bus, dev, reg, data); if (ret < 0) return ret;
return 0;
}
staticint mv88e6xxx_smi_direct_wait(struct mv88e6xxx_chip *chip, int dev, int reg, int bit, int val)
{ constunsignedlong timeout = jiffies + msecs_to_jiffies(50);
u16 data; int err; int i;
/* Even if the initial poll takes longer than 50ms, always do * at least one more attempt.
*/ for (i = 0; time_before(jiffies, timeout) || (i < 2); i++) {
err = mv88e6xxx_smi_direct_read(chip, dev, reg, &data); if (err) return err;
if (!!(data & BIT(bit)) == !!val) return 0;
if (i < 2)
cpu_relax(); else
usleep_range(1000, 2000);
}
staticint mv88e6xxx_smi_indirect_init(struct mv88e6xxx_chip *chip)
{ /* Ensure that the chip starts out in the ready state. As both * reads and writes always ensure this on return, they can * safely depend on the chip not being busy on entry.
*/ return mv88e6xxx_smi_direct_wait(chip, chip->sw_addr,
MV88E6XXX_SMI_CMD, 15, 0);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.