[PATCH v7 7/8] net: add MV88E6xxx DSA driver
Vladimir Oltean
vladimir.oltean at nxp.com
Wed Oct 26 21:55:33 CEST 2022
This patch looks much better to me. Only one comment.
On Wed, Oct 26, 2022 at 09:28:58AM -0700, Tim Harvey wrote:
> +static int mv88e6xxx_port_enable(struct udevice *dev, int port, struct phy_device *phy)
> +{
> + struct mv88e6xxx_priv *priv = dev_get_priv(dev);
> + int val, ret;
> +
> + dev_dbg(dev, "%s P%d phy:0x%08x %s\n", __func__, port,
> + phy->phy_id, phy_string_for_interface(phy->interface));
> +
> + if (phy->phy_id == PHY_FIXED_ID) {
> + /* Physical Control register: Table 62 */
> + val = mv88e6xxx_port_read(dev, port, PORT_REG_PHYS_CTRL);
> +
> + /* configure RGMII delays for fixed link */
> + switch (phy->interface) {
> + case PHY_INTERFACE_MODE_RGMII:
> + case PHY_INTERFACE_MODE_RGMII_ID:
> + case PHY_INTERFACE_MODE_RGMII_RXID:
> + case PHY_INTERFACE_MODE_RGMII_TXID:
> + dev_dbg(dev, "configure internal RGMII delays\n");
> +
> + /* RGMII delays */
> + val &= ~(PORT_REG_PHYS_CTRL_RGMII_DELAY_RXCLK ||
> + PORT_REG_PHYS_CTRL_RGMII_DELAY_TXCLK);
> + if (phy->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> + phy->interface == PHY_INTERFACE_MODE_RGMII_RXID)
> + val |= PORT_REG_PHYS_CTRL_RGMII_DELAY_RXCLK;
> + if (phy->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> + phy->interface == PHY_INTERFACE_MODE_RGMII_TXID)
> + val |= PORT_REG_PHYS_CTRL_RGMII_DELAY_TXCLK;
> + break;
> + default:
> + break;
> + }
> +
> + /* Force Link */
> + val |= PORT_REG_PHYS_CTRL_LINK_VALUE |
> + PORT_REG_PHYS_CTRL_LINK_FORCE;
> +
> + ret = mv88e6xxx_port_write(dev, port, PORT_REG_PHYS_CTRL, val);
> + if (ret < 0)
> + return ret;
> +
> + if (mv88e6xxx_6352_family(dev)) {
> + /* validate interface type */
> + dev_dbg(dev, "validate interface type\n");
> + val = mv88e6xxx_get_cmode(dev, port);
> + if (val < 0)
> + return val;
> + switch (phy->interface) {
> + case PHY_INTERFACE_MODE_RGMII:
> + case PHY_INTERFACE_MODE_RGMII_RXID:
> + case PHY_INTERFACE_MODE_RGMII_TXID:
> + case PHY_INTERFACE_MODE_RGMII_ID:
> + if (val != PORT_REG_STATUS_CMODE_RGMII)
> + goto mismatch;
> + break;
> + case PHY_INTERFACE_MODE_1000BASEX:
> + if (val != PORT_REG_STATUS_CMODE_1000BASE_X)
> + goto mismatch;
> + break;
> +mismatch:
> + default:
> + dev_err(dev, "Mismatched PHY mode %s on port %d!\n",
> + phy_string_for_interface(phy->interface), port);
> + break;
> + }
> + }
> + } else {
What I was saying was here. The phy_id is not PHY_FIXED_ID, okay, but
that doesn't necessarily imply this is an internal PHY port, as the code
below goes on to assume. Maybe this is the case for your setup, but I
would like to see some guarding in a generic driver such that internal
PHY configuration only gets done for ports where that PHY exists.
Which actually brings me to another, more important point. This
PHY_REG_CTRL1 access is the only PHY access that the DSA driver
performs. But we also have a driver for the internal PHY. Why doesn't
the Marvell PHY driver do this write? Also, what is the utility of
enabling energy-detect sense?
> + /* Enable energy-detect sensing on PHY */
> + dev_dbg(dev, "enabling energy-detect sense on PHY\n");
> + val = mv88e6xxx_phy_read(dev, port, PHY_REG_CTRL1);
> + if (val < 0)
> + return val;
> + switch (priv->id) {
> + case PORT_SWITCH_ID_6096:
> + case PORT_SWITCH_ID_6097:
> + case PORT_SWITCH_ID_6172:
> + case PORT_SWITCH_ID_6176:
> + case PORT_SWITCH_ID_6240:
> + case PORT_SWITCH_ID_6352:
> + val &= ~GENMASK(8, 2);
> + val |= (PHY_REG_CTRL1_ENERGY_DET_SENSE_XMIT << 8);
> + break;
> + default:
> + val &= ~GENMASK(14, 1);
> + val |= (PHY_REG_CTRL1_ENERGY_DET_SENSE_PULSE << 14);
> + break;
> + }
> + val = mv88e6xxx_phy_write(dev, port, PHY_REG_CTRL1, val);
> + if (val < 0)
> + return val;
> + }
> +
> + /* enable port */
> + val = mv88e6xxx_port_read(dev, port, PORT_REG_CTRL);
> + if (val < 0)
> + return val;
> + val &= ~(PORT_REG_CTRL_PSTATE_MASK << PORT_REG_CTRL_PSTATE_SHIFT);
> + val |= (PORT_REG_CTRL_PSTATE_FORWARD << PORT_REG_CTRL_PSTATE_SHIFT);
> + val = mv88e6xxx_port_write(dev, port, PORT_REG_CTRL, val);
> + if (val < 0)
> + return val;
> +
> + return phy_startup(phy);
> +}
More information about the U-Boot
mailing list