mbox series

[0/2] of: net: support non-platform devices in of_get_mac_address()

Message ID 20210405164643.21130-1-michael@walle.cc
Headers show
Series of: net: support non-platform devices in of_get_mac_address() | expand

Message

Michael Walle April 5, 2021, 4:46 p.m. UTC
of_get_mac_address() is commonly used to fetch the MAC address
from the device tree. It also supports reading it from a NVMEM
provider. But the latter is only possible for platform devices,
because only platform devices are searched for a matching device
node.

Add a second method to fetch the NVMEM cell by a device tree node
instead of a "struct device".

Moreover, the NVMEM subsystem will return dynamically allocated
data which has to be freed after use. Currently, this is handled
by allocating a device resource manged buffer to store the MAC
address. of_get_mac_address() then returns a pointer to this
buffer. Without a device, this trick is not possible anymore.
Thus, change the of_get_mac_address() API to have the caller
supply a buffer.

It was considered to use the network device to attach the buffer
to, but then the order matters and netdev_register() has to be
called before of_get_mac_address(). No driver does it this way.


Michael Walle (2):
  of: of_net: pass the dst buffer to of_get_mac_address()
  of: net: fix of_get_mac_address_nvmem() for PCI and DSA nodes

 arch/arm/mach-mvebu/kirkwood.c                |  3 +-
 arch/powerpc/sysdev/tsi108_dev.c              |  5 +-
 drivers/net/ethernet/aeroflex/greth.c         |  6 +-
 drivers/net/ethernet/allwinner/sun4i-emac.c   | 10 +--
 drivers/net/ethernet/altera/altera_tse_main.c |  7 +-
 drivers/net/ethernet/arc/emac_main.c          |  8 +-
 drivers/net/ethernet/atheros/ag71xx.c         |  7 +-
 drivers/net/ethernet/broadcom/bcm4908_enet.c  |  7 +-
 drivers/net/ethernet/broadcom/bcmsysport.c    |  7 +-
 drivers/net/ethernet/broadcom/bgmac-bcma.c    | 10 +--
 .../net/ethernet/broadcom/bgmac-platform.c    | 11 ++-
 drivers/net/ethernet/cadence/macb_main.c      | 11 +--
 .../net/ethernet/cavium/octeon/octeon_mgmt.c  |  8 +-
 .../net/ethernet/cavium/thunder/thunder_bgx.c |  5 +-
 drivers/net/ethernet/davicom/dm9000.c         | 10 +--
 drivers/net/ethernet/ethoc.c                  |  6 +-
 drivers/net/ethernet/ezchip/nps_enet.c        |  7 +-
 drivers/net/ethernet/freescale/fec_main.c     |  7 +-
 drivers/net/ethernet/freescale/fec_mpc52xx.c  |  7 +-
 drivers/net/ethernet/freescale/fman/mac.c     |  9 +-
 .../ethernet/freescale/fs_enet/fs_enet-main.c |  5 +-
 drivers/net/ethernet/freescale/gianfar.c      |  8 +-
 drivers/net/ethernet/freescale/ucc_geth.c     |  5 +-
 drivers/net/ethernet/hisilicon/hisi_femac.c   |  7 +-
 drivers/net/ethernet/hisilicon/hix5hd2_gmac.c |  7 +-
 drivers/net/ethernet/lantiq_xrx200.c          |  7 +-
 drivers/net/ethernet/marvell/mv643xx_eth.c    |  5 +-
 drivers/net/ethernet/marvell/mvneta.c         |  6 +-
 .../ethernet/marvell/prestera/prestera_main.c | 11 +--
 drivers/net/ethernet/marvell/pxa168_eth.c     |  9 +-
 drivers/net/ethernet/marvell/sky2.c           |  8 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 11 +--
 drivers/net/ethernet/micrel/ks8851_common.c   |  7 +-
 drivers/net/ethernet/microchip/lan743x_main.c |  5 +-
 drivers/net/ethernet/nxp/lpc_eth.c            |  4 +-
 drivers/net/ethernet/qualcomm/qca_spi.c       | 10 +--
 drivers/net/ethernet/qualcomm/qca_uart.c      |  9 +-
 drivers/net/ethernet/renesas/ravb_main.c      | 12 +--
 drivers/net/ethernet/renesas/sh_eth.c         |  5 +-
 .../ethernet/samsung/sxgbe/sxgbe_platform.c   | 13 +--
 drivers/net/ethernet/socionext/sni_ave.c      | 10 +--
 .../ethernet/stmicro/stmmac/dwmac-anarion.c   |  2 +-
 .../stmicro/stmmac/dwmac-dwc-qos-eth.c        |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-generic.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-imx.c   |  2 +-
 .../stmicro/stmmac/dwmac-intel-plat.c         |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-ipq806x.c   |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-lpc18xx.c   |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-meson.c |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-meson8b.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-oxnas.c |  2 +-
 .../stmicro/stmmac/dwmac-qcom-ethqos.c        |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-rk.c    |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-socfpga.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-sti.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-stm32.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-sunxi.c |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-visconti.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  2 +-
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  4 +-
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 12 +--
 .../ethernet/stmicro/stmmac/stmmac_platform.h |  2 +-
 drivers/net/ethernet/ti/am65-cpsw-nuss.c      | 19 ++---
 drivers/net/ethernet/ti/cpsw.c                |  7 +-
 drivers/net/ethernet/ti/cpsw_new.c            |  7 +-
 drivers/net/ethernet/ti/davinci_emac.c        |  8 +-
 drivers/net/ethernet/ti/netcp_core.c          |  7 +-
 drivers/net/ethernet/wiznet/w5100-spi.c       |  8 +-
 drivers/net/ethernet/wiznet/w5100.c           |  2 +-
 drivers/net/ethernet/xilinx/ll_temac_main.c   |  6 +-
 .../net/ethernet/xilinx/xilinx_axienet_main.c | 11 +--
 drivers/net/ethernet/xilinx/xilinx_emaclite.c |  8 +-
 drivers/net/wireless/ath/ath9k/init.c         |  5 +-
 drivers/net/wireless/mediatek/mt76/eeprom.c   |  9 +-
 .../net/wireless/ralink/rt2x00/rt2x00dev.c    |  6 +-
 drivers/of/of_net.c                           | 85 ++++++++++++-------
 drivers/staging/octeon/ethernet.c             | 10 +--
 drivers/staging/wfx/main.c                    |  7 +-
 include/linux/of_net.h                        |  6 +-
 include/net/dsa.h                             |  2 +-
 net/dsa/dsa2.c                                |  2 +-
 net/dsa/slave.c                               |  2 +-
 net/ethernet/eth.c                            | 11 +--
 85 files changed, 240 insertions(+), 361 deletions(-)

Comments

Andrew Lunn April 5, 2021, 9:34 p.m. UTC | #1
Hi Michael

> -static int of_get_mac_addr_nvmem(struct device_node *np, u8 addr)
> +static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
>  {
>  	struct platform_device *pdev = of_find_device_by_node(np);
> +	struct nvmem_cell *cell;
> +	const void *mac;
> +	size_t len;
>  	int ret;
>  
> -	if (!pdev)
> -		return -ENODEV;
> +	/* Try lookup by device first, there might be a nvmem_cell_lookup
> +	 * associated with a given device.
> +	 */
> +	if (pdev) {
> +		ret = nvmem_get_mac_address(&pdev->dev, addr);
> +		put_device(&pdev->dev);
> +		return ret;
> +	}

Can you think of any odd corner case where nvmem_get_mac_address()
would fail, but of_nvmem_cell_get(np, "mac-address") would work?

      Andrew
Andrew Lunn April 5, 2021, 10:13 p.m. UTC | #2
On Mon, Apr 05, 2021 at 11:46:04PM +0200, Michael Walle wrote:
> Hi Andrew,
> 
> Am 2021-04-05 23:34, schrieb Andrew Lunn:
> > > -static int of_get_mac_addr_nvmem(struct device_node *np, u8 addr)
> > > +static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
> > >  {
> > >  	struct platform_device *pdev = of_find_device_by_node(np);
> > > +	struct nvmem_cell *cell;
> > > +	const void *mac;
> > > +	size_t len;
> > >  	int ret;
> > > 
> > > -	if (!pdev)
> > > -		return -ENODEV;
> > > +	/* Try lookup by device first, there might be a nvmem_cell_lookup
> > > +	 * associated with a given device.
> > > +	 */
> > > +	if (pdev) {
> > > +		ret = nvmem_get_mac_address(&pdev->dev, addr);
> > > +		put_device(&pdev->dev);
> > > +		return ret;
> > > +	}
> > 
> > Can you think of any odd corner case where nvmem_get_mac_address()
> > would fail, but of_nvmem_cell_get(np, "mac-address") would work?
> 
> You mean, it might make sense to just return here when
> nvmem_get_mac_address() will succeed and fall back to the
> of_nvmem_cell_get() in case of an error?

I've not read the documentation for nvmem_get_mac_address(). I was
thinking we might want to return real errors, and -EPROBE_DEFER. But
maybe with -ENODEV we should try of_nvmem_cell_get()?

But i'm not sure if there are any real use cases? The only thing i can
think of is if np points to something deeper inside the device tree
than what pdev does?

     Andrew
Michael Walle April 6, 2021, 8:59 a.m. UTC | #3
Am 2021-04-06 00:13, schrieb Andrew Lunn:
> On Mon, Apr 05, 2021 at 11:46:04PM +0200, Michael Walle wrote:

>> Hi Andrew,

>> 

>> Am 2021-04-05 23:34, schrieb Andrew Lunn:

>> > > -static int of_get_mac_addr_nvmem(struct device_node *np, u8 addr)

>> > > +static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)

>> > >  {

>> > >  	struct platform_device *pdev = of_find_device_by_node(np);

>> > > +	struct nvmem_cell *cell;

>> > > +	const void *mac;

>> > > +	size_t len;

>> > >  	int ret;

>> > >

>> > > -	if (!pdev)

>> > > -		return -ENODEV;

>> > > +	/* Try lookup by device first, there might be a nvmem_cell_lookup

>> > > +	 * associated with a given device.

>> > > +	 */

>> > > +	if (pdev) {

>> > > +		ret = nvmem_get_mac_address(&pdev->dev, addr);

>> > > +		put_device(&pdev->dev);

>> > > +		return ret;

>> > > +	}

>> >

>> > Can you think of any odd corner case where nvmem_get_mac_address()

>> > would fail, but of_nvmem_cell_get(np, "mac-address") would work?

>> 

>> You mean, it might make sense to just return here when

>> nvmem_get_mac_address() will succeed and fall back to the

>> of_nvmem_cell_get() in case of an error?

> 

> I've not read the documentation for nvmem_get_mac_address(). I was

> thinking we might want to return real errors, and -EPROBE_DEFER.


I can't follow, nvmem_get_mac_address() should already return those.

> But maybe with -ENODEV we should try of_nvmem_cell_get()?


And if this happens - that is nvmem_get_mac_address(&pdev->dev) returns
-ENODEV - then of_nvmem_cell_get(np) will also return -ENODEV.

Because pdev->dev.of_node == np and nvmem_get_mac_address(&pdev->dev)
tries of_nvmem_cell_get(pdev->dev.of_node) first.

> But i'm not sure if there are any real use cases? The only thing i can

> think of is if np points to something deeper inside the device tree

> than what pdev does?


But then pdev will be NULL and nvmem_get_mac_address() won't be called
at all, no?

-michael
Andrew Lunn April 6, 2021, 12:40 p.m. UTC | #4
> But then pdev will be NULL and nvmem_get_mac_address() won't be called

> at all, no?


Forget it, it can be added later if there is a real use case.

       Andrew