mbox series

[net-next,v2,00/11] net: pcs: Add support for devices probed in the "usual" manner

Message ID 20221103210650.2325784-1-sean.anderson@seco.com (mailing list archive)
Headers show
Series net: pcs: Add support for devices probed in the "usual" manner | expand

Message

Sean Anderson Nov. 3, 2022, 9:06 p.m. UTC
For a long time, PCSs have been tightly coupled with their MACs. For
this reason, the MAC creates the "phy" or mdio device, and then passes
it to the PCS to initialize. This has a few disadvantages:

- Each MAC must re-implement the same steps to look up/create a PCS
- The PCS cannot use functions tied to device lifetime, such as devm_*.
- Generally, the PCS does not have easy access to its device tree node

This series adds a PCS subsystem which MDIO drivers can use to register
PCSs. It then converts the Lynx PCS library to use this subsystem.

Several (later) patches in this series cannot be applied until a stable
release has occured containing the dts updates. The DTS updates are
fairly straightforward (and should not affect existing systems), so I
encourage them to be applied, even if the rest of the series still needs
review.

Changes in v2:
- Add compatibles for qoriq-fman3-0-10g-2/3.dtsi as well
- Fix export of _pcs_get_by_fwnode
- Add device links to ensure correct probe/removal ordering
- Remove module_get/put, since this is ensured by the device_get/put
- Reorganize some of the control flow for legibility
- Add basic documentation
- Call mdio_device_register
- Squash in lynx parts of "use pcs_get_by_provider to get PCS"
- Rewrite probe/remove functions to use create/destroy. This lets us
  convert existing drivers one at a time, instead of needing a flag day.
- Split off driver conversions into their own commits
- Reorder and rework commits for clarity

Sean Anderson (10):
  arm64: dts: Add compatible strings for Lynx PCSs
  powerpc: dts: Add compatible strings for Lynx PCSs
  net: pcs: Add subsystem
  net: pcs: lynx: Convert to an MDIO driver
  net: enetc: Convert to use PCS subsystem
  net: dsa: felix: Convert to use PCS driver
  of: property: Add device link support for PCS
  [DO NOT MERGE] net: dpaa: Convert to use PCS subsystem
  [DO NOT MERGE] net: dpaa2: Convert to use PCS subsystem
  [DO NOT MERGE] net: pcs: lynx: Remove non-device functionality

Vladimir Oltean (1):
  net: dsa: ocelot: suppress PHY device scanning on the internal MDIO
    bus

 Documentation/networking/index.rst            |   1 +
 Documentation/networking/pcs.rst              | 109 ++++++++
 MAINTAINERS                                   |   2 +
 .../arm64/boot/dts/freescale/fsl-ls208xa.dtsi |  48 ++--
 .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi |  54 ++--
 .../dts/freescale/qoriq-fman3-0-10g-0.dtsi    |   3 +-
 .../dts/freescale/qoriq-fman3-0-10g-1.dtsi    |   3 +-
 .../dts/freescale/qoriq-fman3-0-1g-0.dtsi     |   3 +-
 .../dts/freescale/qoriq-fman3-0-1g-1.dtsi     |   3 +-
 .../dts/freescale/qoriq-fman3-0-1g-2.dtsi     |   3 +-
 .../dts/freescale/qoriq-fman3-0-1g-3.dtsi     |   3 +-
 .../dts/freescale/qoriq-fman3-0-1g-4.dtsi     |   3 +-
 .../dts/freescale/qoriq-fman3-0-1g-5.dtsi     |   3 +-
 .../fsl/qoriq-fman3-0-10g-0-best-effort.dtsi  |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi     |   3 +-
 .../fsl/qoriq-fman3-0-10g-1-best-effort.dtsi  |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi     |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi     |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi     |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi     |   3 +-
 .../boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi     |   3 +-
 .../boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi      |   3 +-
 .../boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi      |   3 +-
 drivers/net/dsa/ocelot/Kconfig                |   2 +
 drivers/net/dsa/ocelot/felix_vsc9959.c        |  31 +--
 drivers/net/dsa/ocelot/seville_vsc9953.c      |  33 +--
 drivers/net/ethernet/freescale/dpaa2/Kconfig  |   1 +
 .../net/ethernet/freescale/dpaa2/dpaa2-mac.c  |  43 +---
 drivers/net/ethernet/freescale/enetc/Kconfig  |   1 +
 .../net/ethernet/freescale/enetc/enetc_pf.c   |  23 +-
 .../net/ethernet/freescale/fman/fman_memac.c  | 118 +++------
 drivers/net/pcs/Kconfig                       |  23 +-
 drivers/net/pcs/Makefile                      |   2 +
 drivers/net/pcs/core.c                        | 243 ++++++++++++++++++
 drivers/net/pcs/pcs-lynx.c                    |  76 ++++--
 drivers/of/property.c                         |   4 +
 include/linux/pcs-lynx.h                      |  12 +-
 include/linux/pcs.h                           | 111 ++++++++
 include/linux/phylink.h                       |   5 +
 49 files changed, 758 insertions(+), 268 deletions(-)
 create mode 100644 Documentation/networking/pcs.rst
 create mode 100644 drivers/net/pcs/core.c
 create mode 100644 include/linux/pcs.h

Comments

Vladimir Oltean Nov. 9, 2022, 10:41 p.m. UTC | #1
On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
> Several (later) patches in this series cannot be applied until a stable
> release has occured containing the dts updates.

New kernels must remain compatible with old device trees.
Vladimir Oltean Nov. 9, 2022, 10:59 p.m. UTC | #2
On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
> For a long time, PCSs have been tightly coupled with their MACs. For
> this reason, the MAC creates the "phy" or mdio device, and then passes
> it to the PCS to initialize. This has a few disadvantages:
> 
> - Each MAC must re-implement the same steps to look up/create a PCS
> - The PCS cannot use functions tied to device lifetime, such as devm_*.
> - Generally, the PCS does not have easy access to its device tree node

Is there a clear need to solve these disadvantages? There comes extra
runtime complexity with the PCS-as-device scheme (plus the extra
complexity needed to address the DT backwards compatibility problems
it causes; not addressed here).
Sean Anderson Nov. 10, 2022, 2:55 p.m. UTC | #3
On 11/9/22 17:41, Vladimir Oltean wrote:
> On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
>> Several (later) patches in this series cannot be applied until a stable
>> release has occured containing the dts updates.
> 
> New kernels must remain compatible with old device trees.

Well, this binding is not present in older device trees, so it needs to
be added before these patches can be applied. It also could be possible
to manually bind the driver using e.g. a helper function (like what is
done with lynx_pcs_create_on_bus). Of course this would be tricky,
because we would need to unbind any generic phy driver attached, but
avoid unbinding an existing Lynx PCS driver.

As I understand it, kernels must be compatible with device trees from a
few kernels before and after. There is not a permanent guarantee of
backwards compatibility (like userspace has) because otherwise we would
never be able to make internal changes (such as what is done in this
series). I have suggested deferring these patches until after an LTS
release as suggested by Rob last time [1].

--Sean

[1] https://lore.kernel.org/netdev/20220718194444.GA3377770-robh@kernel.org/
Sean Anderson Nov. 10, 2022, 3:15 p.m. UTC | #4
On 11/9/22 17:59, Vladimir Oltean wrote:
> On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
>> For a long time, PCSs have been tightly coupled with their MACs. For
>> this reason, the MAC creates the "phy" or mdio device, and then passes
>> it to the PCS to initialize. This has a few disadvantages:
>> 
>> - Each MAC must re-implement the same steps to look up/create a PCS
>> - The PCS cannot use functions tied to device lifetime, such as devm_*.
>> - Generally, the PCS does not have easy access to its device tree node
> 
> Is there a clear need to solve these disadvantages? There comes extra
> runtime complexity with the PCS-as-device scheme.

IMO this is actually simpler for driver implementers and consumers. You
can see this by looking at the diffstats for each of the patches. All of
the consumers are -30 or so. The driver is +30, but that's around the
length of lynx_pcs_create_on_bus (and of course the compatible strings
and driver).

> (plus the extra
> complexity needed to address the DT backwards compatibility problems
> it causes; not addressed here).

New drivers will not need to do this backwards-compatibility dance. They
can be written like almost every other driver in the kernel. There are
parallels here with how phy devices were implemented; first as a library
without drivers (or devices), and gradually converting to devices.

This is also motivated by Xilinx platforms where the PCS can be
implemented on an FPGA. Hard-coding the PCS for the MAC is not
desirable, since the device can change when the bitstream is changed.
Additionally, the devices may need to configure e.g. resets or clocks.

I plan to post a follow-up patch for [1] adding a Xilinx PCS/PMA driver
at some point.

--Sean

[1] https://lore.kernel.org/netdev/20211004191527.1610759-1-sean.anderson@seco.com/
Vladimir Oltean Nov. 10, 2022, 3:29 p.m. UTC | #5
On Thu, Nov 10, 2022 at 09:55:32AM -0500, Sean Anderson wrote:
> On 11/9/22 17:41, Vladimir Oltean wrote:
> > On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
> >> Several (later) patches in this series cannot be applied until a stable
> >> release has occured containing the dts updates.
> > 
> > New kernels must remain compatible with old device trees.
> 
> Well, this binding is not present in older device trees, so it needs to
> be added before these patches can be applied. It also could be possible
> to manually bind the driver using e.g. a helper function (like what is
> done with lynx_pcs_create_on_bus). Of course this would be tricky,
> because we would need to unbind any generic phy driver attached, but
> avoid unbinding an existing Lynx PCS driver.

If you know the value of the MII_PHYSID1 and MII_PHYSID2 registers for
these PCS devices, would it be possible to probe them in a generic way
as MDIO devices, if they lack a compatible string?

> As I understand it, kernels must be compatible with device trees from a
> few kernels before and after. There is not a permanent guarantee of
> backwards compatibility (like userspace has) because otherwise we would
> never be able to make internal changes (such as what is done in this
> series). I have suggested deferring these patches until after an LTS
> release as suggested by Rob last time [1].
> 
> --Sean
> 
> [1] https://lore.kernel.org/netdev/20220718194444.GA3377770-robh@kernel.org/

Internal changes limit themselves to what doesn't break compatibility
with device trees in circulation. DT bindings are ABI. Compared to the
lifetime of DPAA2 SoCs (and especially DPAA1), 1 LTS release is nothing,
sorry. The kernel has to continue probing them as Lynx PCS devices even
in lack of a compatible string.
Sean Anderson Nov. 10, 2022, 3:39 p.m. UTC | #6
On 11/10/22 10:29, Vladimir Oltean wrote:
> On Thu, Nov 10, 2022 at 09:55:32AM -0500, Sean Anderson wrote:
>> On 11/9/22 17:41, Vladimir Oltean wrote:
>> > On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
>> >> Several (later) patches in this series cannot be applied until a stable
>> >> release has occured containing the dts updates.
>> > 
>> > New kernels must remain compatible with old device trees.
>> 
>> Well, this binding is not present in older device trees, so it needs to
>> be added before these patches can be applied. It also could be possible
>> to manually bind the driver using e.g. a helper function (like what is
>> done with lynx_pcs_create_on_bus). Of course this would be tricky,
>> because we would need to unbind any generic phy driver attached, but
>> avoid unbinding an existing Lynx PCS driver.
> 
> If you know the value of the MII_PHYSID1 and MII_PHYSID2 registers for
> these PCS devices, would it be possible to probe them in a generic way
> as MDIO devices, if they lack a compatible string?

PCS devices are not PHYs, and they do not necessarily conform to the
standard PHY registers. Some PCS devices aren't even on MDIO busses (and
are instead memory-mapped). To implement this, I think we would need to be
very careful. There's also the issue where PCS devices might not be
accessable before their mode is selected by the MAC or SerDes.

>> As I understand it, kernels must be compatible with device trees from a
>> few kernels before and after. There is not a permanent guarantee of
>> backwards compatibility (like userspace has) because otherwise we would
>> never be able to make internal changes (such as what is done in this
>> series). I have suggested deferring these patches until after an LTS
>> release as suggested by Rob last time [1].
>> 
>> --Sean
>> 
>> [1] https://lore.kernel.org/netdev/20220718194444.GA3377770-robh@kernel.org/
> 
> Internal changes limit themselves to what doesn't break compatibility
> with device trees in circulation. DT bindings are ABI. Compared to the
> lifetime of DPAA2 SoCs (and especially DPAA1), 1 LTS release is nothing,
> sorry. The kernel has to continue probing them as Lynx PCS devices even
> in lack of a compatible string.

I believe the idea here is to allow some leeway when updating so that
the kernel and device tree don't have to always be in sync. However, we
don't have to support a situation where the kernel is constantly updated
but the device tree is never updated. As long as a reasonable effort is
made to update (or *not* update) both the kernel and device tree, there
is no problem.

--Sean
Vladimir Oltean Nov. 10, 2022, 4 p.m. UTC | #7
On Thu, Nov 10, 2022 at 10:39:30AM -0500, Sean Anderson wrote:
> On 11/10/22 10:29, Vladimir Oltean wrote:
> > On Thu, Nov 10, 2022 at 09:55:32AM -0500, Sean Anderson wrote:
> >> On 11/9/22 17:41, Vladimir Oltean wrote:
> >> > On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
> >> >> Several (later) patches in this series cannot be applied until a stable
> >> >> release has occured containing the dts updates.
> >> > 
> >> > New kernels must remain compatible with old device trees.
> >> 
> >> Well, this binding is not present in older device trees, so it needs to
> >> be added before these patches can be applied. It also could be possible
> >> to manually bind the driver using e.g. a helper function (like what is
> >> done with lynx_pcs_create_on_bus). Of course this would be tricky,
> >> because we would need to unbind any generic phy driver attached, but
> >> avoid unbinding an existing Lynx PCS driver.
> > 
> > If you know the value of the MII_PHYSID1 and MII_PHYSID2 registers for
> > these PCS devices, would it be possible to probe them in a generic way
> > as MDIO devices, if they lack a compatible string?
> 
> PCS devices are not PHYs, and they do not necessarily conform to the
> standard PHY registers. Some PCS devices aren't even on MDIO busses (and
> are instead memory-mapped). To implement this, I think we would need to be
> very careful. There's also the issue where PCS devices might not be
> accessable before their mode is selected by the MAC or SerDes.

I don't get where you're going with this. Does any of these arguments
apply to the Lynx PCS? If not, then what is the problem to using their
PHY ID register as a mechanism to auto-bind their PCS driver in lack of
a compatible string?

You already accept a compromise by having lynx_pcs_create_on_bus() be a
platform-specific way of instantiating a PCS. However, the only thing
that's platform-specific in the lynx_pcs_create_on_bus() implementation
is the modalias string:

struct phylink_pcs *lynx_pcs_create_on_bus(struct device *dev,
					   struct mii_bus *bus, int addr)
{
	struct mdio_device *mdio;
	struct phylink_pcs *pcs;
	int err;

	mdio = mdio_device_create(bus, addr);
	if (IS_ERR(mdio))
		return ERR_CAST(mdio);

	mdio->bus_match = mdio_device_bus_match;
	strncpy(mdio->modalias, "lynx-pcs", sizeof(mdio->modalias)); // <----- this
	err = mdio_device_register(mdio);
	if (err) {
		mdio_device_free(mdio);
		return ERR_PTR(err);
	}

	pcs = pcs_get_by_dev(dev, &mdio->dev);
	mdio_device_free(mdio);
	return pcs;
}
EXPORT_SYMBOL(lynx_pcs_create_on_bus);

Otherwise it could have been named just as well "pcs_create_on_bus()".

And this is what I'm saying. What if instead of probing based on
modalias, this function is made to bind the driver to the device based
on the PHY ID?

The point about this functionality being generic or not is totally moot,
since it's the driver who *decides* to call it (and wouldn't do so, if
it wasn't an MDIO device; see, there's an "mii_bus *bus" argument).

It could work both with LS1028A (enetc, felix, where there is no
pcs-handle), and it could also work with DPAA1/DPAA2, where there is a
pcs-handle but there is no compatible string for the PCS.

> >> As I understand it, kernels must be compatible with device trees from a
> >> few kernels before and after. There is not a permanent guarantee of
> >> backwards compatibility (like userspace has) because otherwise we would
> >> never be able to make internal changes (such as what is done in this
> >> series). I have suggested deferring these patches until after an LTS
> >> release as suggested by Rob last time [1].
> >> 
> >> --Sean
> >> 
> >> [1] https://lore.kernel.org/netdev/20220718194444.GA3377770-robh@kernel.org/
> > 
> > Internal changes limit themselves to what doesn't break compatibility
> > with device trees in circulation. DT bindings are ABI. Compared to the
> > lifetime of DPAA2 SoCs (and especially DPAA1), 1 LTS release is nothing,
> > sorry. The kernel has to continue probing them as Lynx PCS devices even
> > in lack of a compatible string.
> 
> I believe the idea here is to allow some leeway when updating so that
> the kernel and device tree don't have to always be in sync. However, we
> don't have to support a situation where the kernel is constantly updated
> but the device tree is never updated. As long as a reasonable effort is
> made to update (or *not* update) both the kernel and device tree, there
> is no problem.

I don't think you'd have this opinion if device trees were not
maintained in the same git tree as the kernel itself. You have to
consider the case where the device tree blob is provided by a firmware
(say U-Boot) which you don't update in lockstep with the kernel.
Has nothing to do with "reasonable" or not.
Andrew Lunn Nov. 10, 2022, 4:01 p.m. UTC | #8
On Thu, Nov 10, 2022 at 03:29:26PM +0000, Vladimir Oltean wrote:
> On Thu, Nov 10, 2022 at 09:55:32AM -0500, Sean Anderson wrote:
> > On 11/9/22 17:41, Vladimir Oltean wrote:
> > > On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
> > >> Several (later) patches in this series cannot be applied until a stable
> > >> release has occured containing the dts updates.
> > > 
> > > New kernels must remain compatible with old device trees.
> > 
> > Well, this binding is not present in older device trees, so it needs to
> > be added before these patches can be applied. It also could be possible
> > to manually bind the driver using e.g. a helper function (like what is
> > done with lynx_pcs_create_on_bus). Of course this would be tricky,
> > because we would need to unbind any generic phy driver attached, but
> > avoid unbinding an existing Lynx PCS driver.
> 
> If you know the value of the MII_PHYSID1 and MII_PHYSID2 registers for
> these PCS devices, would it be possible to probe them in a generic way
> as MDIO devices, if they lack a compatible string?

That is not how it currently works. If a device on an MDIO bus has a
compatible, it is assumed to be an mdio device, and it is probed in a
generic way as an sort of mdio device. It could be an Ethernet switch,
or Broadcom has some generic PHYs which are mdio devices, etc.

If there is no compatible, the ID registers are read and it is assumed
to be a PHY. It will be probed as a PHY. The probe() function will be
given a phydev etc.

It will need some core changes to allow an mdio device to be probed
via the ID registers.

    Andrew
Vladimir Oltean Nov. 10, 2022, 4:32 p.m. UTC | #9
On Thu, Nov 10, 2022 at 05:01:34PM +0100, Andrew Lunn wrote:
> On Thu, Nov 10, 2022 at 03:29:26PM +0000, Vladimir Oltean wrote:
> > On Thu, Nov 10, 2022 at 09:55:32AM -0500, Sean Anderson wrote:
> > > On 11/9/22 17:41, Vladimir Oltean wrote:
> > > > On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
> > > >> Several (later) patches in this series cannot be applied until a stable
> > > >> release has occured containing the dts updates.
> > > > 
> > > > New kernels must remain compatible with old device trees.
> > > 
> > > Well, this binding is not present in older device trees, so it needs to
> > > be added before these patches can be applied. It also could be possible
> > > to manually bind the driver using e.g. a helper function (like what is
> > > done with lynx_pcs_create_on_bus). Of course this would be tricky,
> > > because we would need to unbind any generic phy driver attached, but
> > > avoid unbinding an existing Lynx PCS driver.
> > 
> > If you know the value of the MII_PHYSID1 and MII_PHYSID2 registers for
> > these PCS devices, would it be possible to probe them in a generic way
> > as MDIO devices, if they lack a compatible string?
> 
> That is not how it currently works. If a device on an MDIO bus has a
> compatible, it is assumed to be an mdio device, and it is probed in a
> generic way as an sort of mdio device. It could be an Ethernet switch,
> or Broadcom has some generic PHYs which are mdio devices, etc.
> 
> If there is no compatible, the ID registers are read and it is assumed
> to be a PHY. It will be probed as a PHY. The probe() function will be
> given a phydev etc.
> 
> It will need some core changes to allow an mdio device to be probed
> via the ID registers.

Yes, it would require extending struct mdio_driver with something like
what struct phy_driver has (u32 phy_id, u32 phy_id_mask), or with a more
generic phy_id_match_table (similar to maybe of_match_table).

I don't see a conceptually simpler way though.
Sean Anderson Nov. 10, 2022, 4:56 p.m. UTC | #10
On 11/10/22 11:00, Vladimir Oltean wrote:
> On Thu, Nov 10, 2022 at 10:39:30AM -0500, Sean Anderson wrote:
>> On 11/10/22 10:29, Vladimir Oltean wrote:
>> > On Thu, Nov 10, 2022 at 09:55:32AM -0500, Sean Anderson wrote:
>> >> On 11/9/22 17:41, Vladimir Oltean wrote:
>> >> > On Thu, Nov 03, 2022 at 05:06:39PM -0400, Sean Anderson wrote:
>> >> >> Several (later) patches in this series cannot be applied until a stable
>> >> >> release has occured containing the dts updates.
>> >> > 
>> >> > New kernels must remain compatible with old device trees.
>> >> 
>> >> Well, this binding is not present in older device trees, so it needs to
>> >> be added before these patches can be applied. It also could be possible
>> >> to manually bind the driver using e.g. a helper function (like what is
>> >> done with lynx_pcs_create_on_bus). Of course this would be tricky,
>> >> because we would need to unbind any generic phy driver attached, but
>> >> avoid unbinding an existing Lynx PCS driver.
>> > 
>> > If you know the value of the MII_PHYSID1 and MII_PHYSID2 registers for
>> > these PCS devices, would it be possible to probe them in a generic way
>> > as MDIO devices, if they lack a compatible string?
>> 
>> PCS devices are not PHYs, and they do not necessarily conform to the
>> standard PHY registers. Some PCS devices aren't even on MDIO busses (and
>> are instead memory-mapped). To implement this, I think we would need to be
>> very careful. There's also the issue where PCS devices might not be
>> accessable before their mode is selected by the MAC or SerDes.
> 
> I don't get where you're going with this. Does any of these arguments
> apply to the Lynx PCS? If not, then what is the problem to using their
> PHY ID register as a mechanism to auto-bind their PCS driver in lack of
> a compatible string?
> 
> You already accept a compromise by having lynx_pcs_create_on_bus() be a
> platform-specific way of instantiating a PCS. However, the only thing
> that's platform-specific in the lynx_pcs_create_on_bus() implementation
> is the modalias string:
> 
> struct phylink_pcs *lynx_pcs_create_on_bus(struct device *dev,
> 					   struct mii_bus *bus, int addr)
> {
> 	struct mdio_device *mdio;
> 	struct phylink_pcs *pcs;
> 	int err;
> 
> 	mdio = mdio_device_create(bus, addr);
> 	if (IS_ERR(mdio))
> 		return ERR_CAST(mdio);
> 
> 	mdio->bus_match = mdio_device_bus_match;
> 	strncpy(mdio->modalias, "lynx-pcs", sizeof(mdio->modalias)); // <----- this
> 	err = mdio_device_register(mdio);
> 	if (err) {
> 		mdio_device_free(mdio);
> 		return ERR_PTR(err);
> 	}
> 
> 	pcs = pcs_get_by_dev(dev, &mdio->dev);
> 	mdio_device_free(mdio);
> 	return pcs;
> }
> EXPORT_SYMBOL(lynx_pcs_create_on_bus);
> 
> Otherwise it could have been named just as well "pcs_create_on_bus()".

Yes, this could be made generic when we convert other drivers. This
really is just intended for (non-dt) platform devices. It might even be
better to do this with swnodes...

> And this is what I'm saying. What if instead of probing based on
> modalias, this function is made to bind the driver to the device based
> on the PHY ID?
> 
> The point about this functionality being generic or not is totally moot,
> since it's the driver who *decides* to call it (and wouldn't do so, if
> it wasn't an MDIO device; see, there's an "mii_bus *bus" argument).
> 
> It could work both with LS1028A (enetc, felix, where there is no
> pcs-handle), and it could also work with DPAA1/DPAA2, where there is a
> pcs-handle but there is no compatible string for the PCS.

The crucial difference here is that if we have a pcs-handle property,
then the node it points to will have a device created by the MDIO
subsystem automatically. The reason for this create_on_bus stuff
is to make the process of

1. Create an MDIO bus with no firmware node
2. Create some MDIO devices on that bus
3. Bind them to the correct driver
4. Get the PCS from the driver

less error prone. But for pcs-handle stuff, this should be something
like

1. pcs_find_fwnode()
2. Look up the device for this node
3. Bind it to the correct driver (but taking care that we don't unbind
  an existing driver if it is correct).

And then the driver can call pcs_get().

With your suggestion to use PHY_ID, we wouldn't need that. But we would
still need driver involvement, since probing MDIO busses is not safe in
general (since as Andrew mentioned there are things on the busses which
don't have PHY ID registers). And IMO if we need the driver to go "yes,
it's OK to probe this non-phy on this bus," then we might as well do
what I described above. This could be a bus flag, which I think would
work with existing devices.

I'm worried that this could cause regressions and take a while to iron
out. My current approach is fairly conservative and doesn't require
changes to unaffected code.

>> >> As I understand it, kernels must be compatible with device trees from a
>> >> few kernels before and after. There is not a permanent guarantee of
>> >> backwards compatibility (like userspace has) because otherwise we would
>> >> never be able to make internal changes (such as what is done in this
>> >> series). I have suggested deferring these patches until after an LTS
>> >> release as suggested by Rob last time [1].
>> >> 
>> >> --Sean
>> >> 
>> >> [1] https://lore.kernel.org/netdev/20220718194444.GA3377770-robh@kernel.org/
>> > 
>> > Internal changes limit themselves to what doesn't break compatibility
>> > with device trees in circulation. DT bindings are ABI. Compared to the
>> > lifetime of DPAA2 SoCs (and especially DPAA1), 1 LTS release is nothing,
>> > sorry. The kernel has to continue probing them as Lynx PCS devices even
>> > in lack of a compatible string.
>> 
>> I believe the idea here is to allow some leeway when updating so that
>> the kernel and device tree don't have to always be in sync. However, we
>> don't have to support a situation where the kernel is constantly updated
>> but the device tree is never updated. As long as a reasonable effort is
>> made to update (or *not* update) both the kernel and device tree, there
>> is no problem.
> 
> I don't think you'd have this opinion if device trees were not
> maintained in the same git tree as the kernel itself. You have to
> consider the case where the device tree blob is provided by a firmware
> (say U-Boot) which you don't update in lockstep with the kernel.
> Has nothing to do with "reasonable" or not.

This is exactly the reason why I am saying that we need to have the
device tree updates in the kernel for a bit before these latter patches
can get merged. Actually, it is probably unlikely that these will make
it into the next LTS release (either 6.0 or 6.1), so these will probably
be in device trees for a year before the kernel starts using them.  But
once that is done, we are free to require them.

--Sean
Vladimir Oltean Nov. 14, 2022, 5:23 p.m. UTC | #11
On Thu, Nov 10, 2022 at 11:56:15AM -0500, Sean Anderson wrote:
> these will probably be in device trees for a year before the kernel
> starts using them. But once that is done, we are free to require them.

Sorry, you need to propose something that is not "we can break compatibility
with today's device trees one year from now".
Sean Anderson Nov. 14, 2022, 6:08 p.m. UTC | #12
On 11/14/22 12:23, Vladimir Oltean wrote:
> On Thu, Nov 10, 2022 at 11:56:15AM -0500, Sean Anderson wrote:
>> these will probably be in device trees for a year before the kernel
>> starts using them. But once that is done, we are free to require them.
> 
> Sorry, you need to propose something that is not "we can break compatibility
> with today's device trees one year from now".

But only if the kernel gets updated and not the device tree. When can
such a situation occur? Are we stuck with this for the next 10 years all
because someone may have a device tree which they compiled in 2017, and
*insist* on using the latest kernel with? Is this how you run your
systems?

We don't get the device tree from firmware on this platform; usually it
is bundled with the kernel in a FIT or loaded from the same disk
partition as the kernel. I can imagine that they might not always be
updated at exactly the same time, but this is nuts.

The original device tree is broken because it doesn't include compatible
strings for devices on a generic bus. There's no way to fix that other
than hard-coding the driver. This can be done for some buses, but this
is an MDIO bus and we already assume devices without compatibles are
PHYs.

In the next version of this series, I will include a compatibility
function which can bind a driver automatically if one is missing when
looking up a phy. But I would really like to have an exit strategy.

--Sean
Vladimir Oltean Nov. 14, 2022, 7:53 p.m. UTC | #13
On Mon, Nov 14, 2022 at 01:08:03PM -0500, Sean Anderson wrote:
> On 11/14/22 12:23, Vladimir Oltean wrote:
> > On Thu, Nov 10, 2022 at 11:56:15AM -0500, Sean Anderson wrote:
> >> these will probably be in device trees for a year before the kernel
> >> starts using them. But once that is done, we are free to require them.
> > 
> > Sorry, you need to propose something that is not "we can break compatibility
> > with today's device trees one year from now".
> 
> But only if the kernel gets updated and not the device tree. When can
> such a situation occur? Are we stuck with this for the next 10 years all
> because someone may have a device tree which they compiled in 2017, and
> *insist* on using the latest kernel with? Is this how you run your
> systems?

I'm a developer (and I work on other platforms than the ones you're
planning to break), so the answer to this question doesn't mean a thing.

> We don't get the device tree from firmware on this platform; usually it
> is bundled with the kernel in a FIT or loaded from the same disk
> partition as the kernel. I can imagine that they might not always be
> updated at exactly the same time, but this is nuts.

What does "this" platform mean exactly? There are many platforms to
which you've added compatible strings to keep things working assuming a
dtb update, many of them very old. And those to which you did are not by
far all that exist. There is no requirement that all platform device
trees are upstreamed to the Linux kernel.

> The original device tree is broken because it doesn't include compatible
> strings for devices on a generic bus. There's no way to fix that other
> than hard-coding the driver. This can be done for some buses, but this
> is an MDIO bus and we already assume devices without compatibles are
> PHYs.

Let's be clear about this. It's "broken" in the sense that you don't like
the way in which it works, not in the sense that it results in a system
that doesn't work. And not having a compatible string is just as broken
as it is for other devices with detectable device IDs, like Ethernet
PHYs in general, PCI devices, etc.

The way in which that works here, specifically, is that a generic PHY driver
is bound to the Lynx PCS devices, driver which does nothing since nobody
calls phy_attach_direct() to it. Then, using fwnode_mdio_find_device(),
you follow the pcsphy-handle and you get a reference to the mdio_device
(parent class of phy_device) object that resulted from the generic PHY
driver probing on the PCS, and you program the PCS to do what you want.

The PHY core does assume that mdio_devices without compatible strings
are phy_devices, but also makes exceptions (and warns about it) - see
commit ae461131960b ("of: of_mdio: Add a whitelist of PHY compatibilities.").
Maybe the reverse exception could also be made, and a warning for that
be added as well.

> In the next version of this series, I will include a compatibility
> function which can bind a driver automatically if one is missing when
> looking up a phy. But I would really like to have an exit strategy.

You'll have to get agreement from higher level maintainers than me that
the strategy "wait one year, break old device trees" is okay. Generally
we wouldn't have answers to this kind of questions that depend on whom
you ask. Otherwise.. we would all know whom to ask and whom not to ;)

Sadly I haven't found anything "official" in either Documentation/devicetree/usage-model.rst
or Documentation/process/submitting-patches.rst. Maybe I missed it?

I've added Arnd Bergmann for an ack, and also Marc Zyngier, not because
of any particular connection to what's being changed here, but because
I happen to know that he might have strong opinions on the topic :)

Full context here:
https://patchwork.kernel.org/project/netdevbpf/cover/20221103210650.2325784-1-sean.anderson@seco.com/

If I'm the only one opposing this, I guess I'll look elsewhere.
Rob Herring Nov. 17, 2022, 1:38 p.m. UTC | #14
On Mon, Nov 14, 2022 at 1:53 PM Vladimir Oltean <olteanv@gmail.com> wrote:
>
> On Mon, Nov 14, 2022 at 01:08:03PM -0500, Sean Anderson wrote:
> > On 11/14/22 12:23, Vladimir Oltean wrote:
> > > On Thu, Nov 10, 2022 at 11:56:15AM -0500, Sean Anderson wrote:
> > >> these will probably be in device trees for a year before the kernel
> > >> starts using them. But once that is done, we are free to require them.
> > >
> > > Sorry, you need to propose something that is not "we can break compatibility
> > > with today's device trees one year from now".
> >
> > But only if the kernel gets updated and not the device tree. When can
> > such a situation occur? Are we stuck with this for the next 10 years all
> > because someone may have a device tree which they compiled in 2017, and
> > *insist* on using the latest kernel with? Is this how you run your
> > systems?
>
> I'm a developer (and I work on other platforms than the ones you're
> planning to break), so the answer to this question doesn't mean a thing.
>
> > We don't get the device tree from firmware on this platform; usually it
> > is bundled with the kernel in a FIT or loaded from the same disk
> > partition as the kernel. I can imagine that they might not always be
> > updated at exactly the same time, but this is nuts.
>
> What does "this" platform mean exactly? There are many platforms to
> which you've added compatible strings to keep things working assuming a
> dtb update, many of them very old. And those to which you did are not by
> far all that exist. There is no requirement that all platform device
> trees are upstreamed to the Linux kernel.
>
> > The original device tree is broken because it doesn't include compatible
> > strings for devices on a generic bus. There's no way to fix that other
> > than hard-coding the driver. This can be done for some buses, but this
> > is an MDIO bus and we already assume devices without compatibles are
> > PHYs.
>
> Let's be clear about this. It's "broken" in the sense that you don't like
> the way in which it works, not in the sense that it results in a system
> that doesn't work. And not having a compatible string is just as broken
> as it is for other devices with detectable device IDs, like Ethernet
> PHYs in general, PCI devices, etc.
>
> The way in which that works here, specifically, is that a generic PHY driver
> is bound to the Lynx PCS devices, driver which does nothing since nobody
> calls phy_attach_direct() to it. Then, using fwnode_mdio_find_device(),
> you follow the pcsphy-handle and you get a reference to the mdio_device
> (parent class of phy_device) object that resulted from the generic PHY
> driver probing on the PCS, and you program the PCS to do what you want.
>
> The PHY core does assume that mdio_devices without compatible strings
> are phy_devices, but also makes exceptions (and warns about it) - see
> commit ae461131960b ("of: of_mdio: Add a whitelist of PHY compatibilities.").
> Maybe the reverse exception could also be made, and a warning for that
> be added as well.
>
> > In the next version of this series, I will include a compatibility
> > function which can bind a driver automatically if one is missing when
> > looking up a phy. But I would really like to have an exit strategy.
>
> You'll have to get agreement from higher level maintainers than me that
> the strategy "wait one year, break old device trees" is okay. Generally
> we wouldn't have answers to this kind of questions that depend on whom
> you ask. Otherwise.. we would all know whom to ask and whom not to ;)

A window of time can work, but only when there's other reasons
everyone must update the firmware/DT.

> Sadly I haven't found anything "official" in either Documentation/devicetree/usage-model.rst
> or Documentation/process/submitting-patches.rst. Maybe I missed it?

Documentation/devicetree/bindings/ABI.rst

The exact policy depends on the platform (or family of platforms). In
short, if *anyone* cares, then compatibility should not be broken.
Vladimir uses platforms in question and cares, so don't break the
platforms.

Rob