Commit 83216e39 authored by Michael Walle's avatar Michael Walle Committed by David S. Miller
Browse files

of: net: pass the dst buffer to of_get_mac_address()



of_get_mac_address() returns a "const void*" pointer to a MAC address.
Lately, support to fetch the MAC address by an NVMEM provider was added.
But this will only work with platform devices. It will not work with
PCI devices (e.g. of an integrated root complex) and esp. not with DSA
ports.

There is an of_* variant of the nvmem binding which works without
devices. The returned data of a nvmem_cell_read() has to be freed after
use. On the other hand the return of_get_mac_address() points to some
static data without a lifetime. The trick for now, was to allocate a
device resource managed buffer which is then returned. This will only
work if we have an actual device.

Change it, so that the caller of of_get_mac_address() has to supply a
buffer where the MAC address is written to. Unfortunately, this will
touch all drivers which use the of_get_mac_address().

Usually the code looks like:

  const char *addr;
  addr = of_get_mac_address(np);
  if (!IS_ERR(addr))
    ether_addr_copy(ndev->dev_addr, addr);

This can then be simply rewritten as:

  of_get_mac_address(np, ndev->dev_addr);

Sometimes is_valid_ether_addr() is used to test the MAC address.
of_get_mac_address() already makes sure, it just returns a valid MAC
address. Thus we can just test its return code. But we have to be
careful if there are still other sources for the MAC address before the
of_get_mac_address(). In this case we have to keep the
is_valid_ether_addr() call.

The following coccinelle patch was used to convert common cases to the
new style. Afterwards, I've manually gone over the drivers and fixed the
return code variable: either used a new one or if one was already
available use that. Mansour Moufid, thanks for that coccinelle patch!

<spml>
@a@
identifier x;
expression y, z;
@@
- x = of_get_mac_address(y);
+ x = of_get_mac_address(y, z);
  <...
- ether_addr_copy(z, x);
  ...>

@@
identifier a.x;
@@
- if (<+... x ...+>) {}

@@
identifier a.x;
@@
  if (<+... x ...+>) {
      ...
  }
- else {}

@@
identifier a.x;
expression e;
@@
- if (<+... x ...+>@e)
-     {}
- else
+ if (!(e))
      {...}

@@
expression x, y, z;
@@
- x = of_get_mac_address(y, z);
+ of_get_mac_address(y, z);
  ... when != x
</spml>

All drivers, except drivers/net/ethernet/aeroflex/greth.c, were
compile-time tested.

Suggested-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarMichael Walle <michael@walle.cc>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 40b5d2f1
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ static void __init kirkwood_dt_eth_fixup(void)
		struct device_node *pnp = of_get_parent(np);
		struct clk *clk;
		struct property *pmac;
		u8 tmpmac[ETH_ALEN];
		void __iomem *io;
		u8 *macaddr;
		u32 reg;
@@ -93,7 +94,7 @@ static void __init kirkwood_dt_eth_fixup(void)

		/* skip disabled nodes or nodes with valid MAC address*/
		if (!of_device_is_available(pnp) ||
		    !IS_ERR(of_get_mac_address(np)))
		    !of_get_mac_address(np, tmpmac))
			goto eth_fixup_skip;

		clk = of_clk_get(pnp, 0);
+1 −4
Original line number Diff line number Diff line
@@ -73,7 +73,6 @@ static int __init tsi108_eth_of_init(void)
		struct device_node *phy, *mdio;
		hw_info tsi_eth_data;
		const unsigned int *phy_id;
		const void *mac_addr;
		const phandle *ph;

		memset(r, 0, sizeof(r));
@@ -101,9 +100,7 @@ static int __init tsi108_eth_of_init(void)
			goto err;
		}

		mac_addr = of_get_mac_address(np);
		if (!IS_ERR(mac_addr))
			ether_addr_copy(tsi_eth_data.mac_addr, mac_addr);
		of_get_mac_address(np, tsi_eth_data.mac_addr);

		ph = of_get_property(np, "mdio-handle", NULL);
		mdio = of_find_node_by_phandle(*ph);
+3 −3
Original line number Diff line number Diff line
@@ -1449,10 +1449,10 @@ static int greth_of_probe(struct platform_device *ofdev)
			break;
	}
	if (i == 6) {
		const u8 *addr;
		u8 addr[ETH_ALEN];

		addr = of_get_mac_address(ofdev->dev.of_node);
		if (!IS_ERR(addr)) {
		err = of_get_mac_address(ofdev->dev.of_node, addr);
		if (!err) {
			for (i = 0; i < 6; i++)
				macaddr[i] = (unsigned int) addr[i];
		} else {
+3 −7
Original line number Diff line number Diff line
@@ -790,7 +790,6 @@ static int emac_probe(struct platform_device *pdev)
	struct emac_board_info *db;
	struct net_device *ndev;
	int ret = 0;
	const char *mac_addr;

	ndev = alloc_etherdev(sizeof(struct emac_board_info));
	if (!ndev) {
@@ -853,12 +852,9 @@ static int emac_probe(struct platform_device *pdev)
	}

	/* Read MAC-address from DT */
	mac_addr = of_get_mac_address(np);
	if (!IS_ERR(mac_addr))
		ether_addr_copy(ndev->dev_addr, mac_addr);

	/* Check if the MAC address is valid, if not get a random one */
	if (!is_valid_ether_addr(ndev->dev_addr)) {
	ret = of_get_mac_address(np, ndev->dev_addr);
	if (ret) {
		/* if the MAC address is invalid get a random one */
		eth_hw_addr_random(ndev);
		dev_warn(&pdev->dev, "using random MAC address %pM\n",
			 ndev->dev_addr);
+2 −5
Original line number Diff line number Diff line
@@ -1351,7 +1351,6 @@ static int altera_tse_probe(struct platform_device *pdev)
	struct resource *control_port;
	struct resource *dma_res;
	struct altera_tse_private *priv;
	const unsigned char *macaddr;
	void __iomem *descmap;
	const struct of_device_id *of_id = NULL;

@@ -1525,10 +1524,8 @@ static int altera_tse_probe(struct platform_device *pdev)
	priv->rx_dma_buf_sz = ALTERA_RXDMABUFFER_SIZE;

	/* get default MAC address from device tree */
	macaddr = of_get_mac_address(pdev->dev.of_node);
	if (!IS_ERR(macaddr))
		ether_addr_copy(ndev->dev_addr, macaddr);
	else
	ret = of_get_mac_address(pdev->dev.of_node, ndev->dev_addr);
	if (ret)
		eth_hw_addr_random(ndev);

	/* get phy addr and create mdio */
Loading