Re: [PATCH v3 net-next 05/10] net: dsa: microchip: add DSA support for microchip lan937x

From: Andrew Lunn
Date: Sat Jul 31 2021 - 18:05:41 EST


> > +void lan937x_mac_config(struct ksz_device *dev, int port,
> > + phy_interface_t interface)
> > +{
> > + u8 data8;
> > +
> > + lan937x_pread8(dev, port, REG_PORT_XMII_CTRL_1, &data8);
> > +
> > + /* clear MII selection & set it based on interface later */
> > + data8 &= ~PORT_MII_SEL_M;
> > +
> > + /* configure MAC based on interface */
> > + switch (interface) {
> > + case PHY_INTERFACE_MODE_MII:
> > + lan937x_config_gbit(dev, false, &data8);
> > + data8 |= PORT_MII_SEL;
> > + break;
> > + case PHY_INTERFACE_MODE_RMII:
> > + lan937x_config_gbit(dev, false, &data8);
> > + data8 |= PORT_RMII_SEL;
> > + break;
> > + case PHY_INTERFACE_MODE_RGMII:
> > + case PHY_INTERFACE_MODE_RGMII_ID:
> > + case PHY_INTERFACE_MODE_RGMII_TXID:
> > + case PHY_INTERFACE_MODE_RGMII_RXID:
> > + lan937x_config_gbit(dev, true, &data8);
> > + data8 |= PORT_RGMII_SEL;
> > +
> > + /* Add RGMII internal delay for cpu port*/
> > + if (dsa_is_cpu_port(dev->ds, port)) {
>
> Why only for the CPU port? I would like Andrew/Florian to have a look
> here, I guess the assumption is that if the port has a phy-handle, the
> RGMII delays should be dealt with by the PHY, but the logic seems to be
> "is a CPU port <=> has a phy-handle / isn't a CPU port <=> doesn't have
> a phy-handle"? What if it's a fixed-link port connected to a downstream
> switch, for which this one is a DSA master?

The marvell driver applies delays unconditionally. And as far as i
remember, it is only used in the use case you suggest, a DSA link,
which is using RGMII. For marvell switches, that is pretty unusual,
most boards use 1000BaseX or higher SERDES speeds for links between
switches.

I'm not sure if we have the case of an external PHY using RGMII. I
suspect it might actually be broken, because i think both the MAC and
the PHY might add the same delay. For phylib in general, if the MAC
applies the delays, it needs to manipulate the value passed to the PHY
so it also does not add delays. And i'm not sure DSA does that.

So limiting RGMII delays to only the CPU port is not
unreasonable. However, i suspect you are correct about chained
switches not working.

We might need to look at this at a higher level, when the PHY is
connected to the MAC and what mode gets passed to it.

> > + if (interface == PHY_INTERFACE_MODE_RGMII_ID ||
> > + interface == PHY_INTERFACE_MODE_RGMII_RXID)
> > + data8 |= PORT_RGMII_ID_IG_ENABLE;
> > +
> > + if (interface == PHY_INTERFACE_MODE_RGMII_ID ||
> > + interface == PHY_INTERFACE_MODE_RGMII_TXID)
> > + data8 |= PORT_RGMII_ID_EG_ENABLE;
> > + }
> > + break;
> > + default:
> > + dev_err(dev->dev, "Unsupported interface '%s' for port %d\n",
> > + phy_modes(interface), port);
> > + return;
> > + }
> > +
> > + /* Write the updated value */
> > + lan937x_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8);
> > +}
>
> > +static int lan937x_mdio_register(struct dsa_switch *ds)
> > +{
> > + struct ksz_device *dev = ds->priv;
> > + int ret;
> > +
> > + dev->mdio_np = of_get_child_by_name(ds->dev->of_node, "mdio");
>
> So you support both the cases where an internal PHY is described using
> OF bindings, and where the internal PHY is implicitly accessed using the
> slave_mii_bus of the switch, at a PHY address equal to the port number,
> and with no phy-handle or fixed-link device tree property for that port?
>
> Do you need both alternatives? The first is already more flexible than
> the second.

The first is also much more verbose in DT, and the second generally
just works without any DT. What can be tricky with the second is
getting PHY interrupts to work, but it is possible, the mv88e6xxx does
it.

Andrew