Skip to content

Commit

Permalink
of: net: pass the dst buffer to of_get_mac_address()
Browse files Browse the repository at this point in the history
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: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
mwalle authored and davem330 committed Apr 13, 2021
1 parent 40b5d2f commit 83216e3
Show file tree
Hide file tree
Showing 85 changed files with 218 additions and 364 deletions.
3 changes: 2 additions & 1 deletion arch/arm/mach-mvebu/kirkwood.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
5 changes: 1 addition & 4 deletions arch/powerpc/sysdev/tsi108_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/aeroflex/greth.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 3 additions & 7 deletions drivers/net/ethernet/allwinner/sun4i-emac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 2 additions & 5 deletions drivers/net/ethernet/altera/altera_tse_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 */
Expand Down
8 changes: 2 additions & 6 deletions drivers/net/ethernet/arc/emac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,6 @@ int arc_emac_probe(struct net_device *ndev, int interface)
struct device_node *phy_node;
struct phy_device *phydev = NULL;
struct arc_emac_priv *priv;
const char *mac_addr;
unsigned int id, clock_frequency, irq;
int err;

Expand Down Expand Up @@ -942,11 +941,8 @@ int arc_emac_probe(struct net_device *ndev, int interface)
}

/* Get MAC address from device tree */
mac_addr = of_get_mac_address(dev->of_node);

if (!IS_ERR(mac_addr))
ether_addr_copy(ndev->dev_addr, mac_addr);
else
err = of_get_mac_address(dev->of_node, ndev->dev_addr);
if (err)
eth_hw_addr_random(ndev);

arc_emac_set_address_internal(ndev);
Expand Down
7 changes: 2 additions & 5 deletions drivers/net/ethernet/atheros/ag71xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1856,7 +1856,6 @@ static int ag71xx_probe(struct platform_device *pdev)
const struct ag71xx_dcfg *dcfg;
struct net_device *ndev;
struct resource *res;
const void *mac_addr;
int tx_size, err, i;
struct ag71xx *ag;

Expand Down Expand Up @@ -1957,10 +1956,8 @@ static int ag71xx_probe(struct platform_device *pdev)
ag->stop_desc->ctrl = 0;
ag->stop_desc->next = (u32)ag->stop_desc_dma;

mac_addr = of_get_mac_address(np);
if (!IS_ERR(mac_addr))
memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
if (IS_ERR(mac_addr) || !is_valid_ether_addr(ndev->dev_addr)) {
err = of_get_mac_address(np, ndev->dev_addr);
if (err) {
netif_err(ag, probe, ndev, "invalid MAC address, using random address\n");
eth_random_addr(ndev->dev_addr);
}
Expand Down
7 changes: 2 additions & 5 deletions drivers/net/ethernet/broadcom/bcm4908_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,6 @@ static int bcm4908_enet_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct net_device *netdev;
struct bcm4908_enet *enet;
const u8 *mac;
int err;

netdev = devm_alloc_etherdev(dev, sizeof(*enet));
Expand Down Expand Up @@ -716,10 +715,8 @@ static int bcm4908_enet_probe(struct platform_device *pdev)
return err;

SET_NETDEV_DEV(netdev, &pdev->dev);
mac = of_get_mac_address(dev->of_node);
if (!IS_ERR(mac))
ether_addr_copy(netdev->dev_addr, mac);
else
err = of_get_mac_address(dev->of_node, netdev->dev_addr);
if (err)
eth_hw_addr_random(netdev);
netdev->netdev_ops = &bcm4908_enet_netdev_ops;
netdev->min_mtu = ETH_ZLEN;
Expand Down
7 changes: 2 additions & 5 deletions drivers/net/ethernet/broadcom/bcmsysport.c
Original file line number Diff line number Diff line change
Expand Up @@ -2457,7 +2457,6 @@ static int bcm_sysport_probe(struct platform_device *pdev)
struct bcm_sysport_priv *priv;
struct device_node *dn;
struct net_device *dev;
const void *macaddr;
u32 txq, rxq;
int ret;

Expand Down Expand Up @@ -2552,12 +2551,10 @@ static int bcm_sysport_probe(struct platform_device *pdev)
}

/* Initialize netdevice members */
macaddr = of_get_mac_address(dn);
if (IS_ERR(macaddr)) {
ret = of_get_mac_address(dn, dev->dev_addr);
if (ret) {
dev_warn(&pdev->dev, "using random Ethernet MAC\n");
eth_hw_addr_random(dev);
} else {
ether_addr_copy(dev->dev_addr, macaddr);
}

SET_NETDEV_DEV(dev, &pdev->dev);
Expand Down
10 changes: 4 additions & 6 deletions drivers/net/ethernet/broadcom/bgmac-bcma.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ static int bgmac_probe(struct bcma_device *core)
struct ssb_sprom *sprom = &core->bus->sprom;
struct mii_bus *mii_bus;
struct bgmac *bgmac;
const u8 *mac = NULL;
const u8 *mac;
int err;

bgmac = bgmac_alloc(&core->dev);
Expand All @@ -128,11 +128,10 @@ static int bgmac_probe(struct bcma_device *core)

bcma_set_drvdata(core, bgmac);

if (bgmac->dev->of_node)
mac = of_get_mac_address(bgmac->dev->of_node);
err = of_get_mac_address(bgmac->dev->of_node, bgmac->net_dev->dev_addr);

/* If no MAC address assigned via device tree, check SPROM */
if (IS_ERR_OR_NULL(mac)) {
if (err) {
switch (core->core_unit) {
case 0:
mac = sprom->et0mac;
Expand All @@ -149,10 +148,9 @@ static int bgmac_probe(struct bcma_device *core)
err = -ENOTSUPP;
goto err;
}
ether_addr_copy(bgmac->net_dev->dev_addr, mac);
}

ether_addr_copy(bgmac->net_dev->dev_addr, mac);

/* On BCM4706 we need common core to access PHY */
if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
!core->bus->drv_gmac_cmn.core) {
Expand Down
11 changes: 5 additions & 6 deletions drivers/net/ethernet/broadcom/bgmac-platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ static int bgmac_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct bgmac *bgmac;
struct resource *regs;
const u8 *mac_addr;
int ret;

bgmac = bgmac_alloc(&pdev->dev);
if (!bgmac)
Expand All @@ -192,11 +192,10 @@ static int bgmac_probe(struct platform_device *pdev)
bgmac->dev = &pdev->dev;
bgmac->dma_dev = &pdev->dev;

mac_addr = of_get_mac_address(np);
if (!IS_ERR(mac_addr))
ether_addr_copy(bgmac->net_dev->dev_addr, mac_addr);
else
dev_warn(&pdev->dev, "MAC address not present in device tree\n");
ret = of_get_mac_address(np, bgmac->net_dev->dev_addr);
if (ret)
dev_warn(&pdev->dev,
"MAC address not present in device tree\n");

bgmac->irq = platform_get_irq(pdev, 0);
if (bgmac->irq < 0)
Expand Down
11 changes: 3 additions & 8 deletions drivers/net/ethernet/cadence/macb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4649,7 +4649,6 @@ static int macb_probe(struct platform_device *pdev)
struct net_device *dev;
struct resource *regs;
void __iomem *mem;
const char *mac;
struct macb *bp;
int err, val;

Expand Down Expand Up @@ -4764,15 +4763,11 @@ static int macb_probe(struct platform_device *pdev)
if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR)
bp->rx_intr_mask |= MACB_BIT(RXUBR);

mac = of_get_mac_address(np);
if (PTR_ERR(mac) == -EPROBE_DEFER) {
err = -EPROBE_DEFER;
err = of_get_mac_address(np, bp->dev->dev_addr);
if (err == -EPROBE_DEFER)
goto err_out_free_netdev;
} else if (!IS_ERR_OR_NULL(mac)) {
ether_addr_copy(bp->dev->dev_addr, mac);
} else {
else if (err)
macb_get_hwaddr(bp);
}

err = of_get_phy_mode(np, &interface);
if (err)
Expand Down
8 changes: 2 additions & 6 deletions drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1385,7 +1385,6 @@ static int octeon_mgmt_probe(struct platform_device *pdev)
struct net_device *netdev;
struct octeon_mgmt *p;
const __be32 *data;
const u8 *mac;
struct resource *res_mix;
struct resource *res_agl;
struct resource *res_agl_prt_ctl;
Expand Down Expand Up @@ -1502,11 +1501,8 @@ static int octeon_mgmt_probe(struct platform_device *pdev)
netdev->min_mtu = 64 - OCTEON_MGMT_RX_HEADROOM;
netdev->max_mtu = 16383 - OCTEON_MGMT_RX_HEADROOM - VLAN_HLEN;

mac = of_get_mac_address(pdev->dev.of_node);

if (!IS_ERR(mac))
ether_addr_copy(netdev->dev_addr, mac);
else
result = of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
if (result)
eth_hw_addr_random(netdev);

p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
Expand Down
5 changes: 1 addition & 4 deletions drivers/net/ethernet/cavium/thunder/thunder_bgx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1474,7 +1474,6 @@ static int bgx_init_of_phy(struct bgx *bgx)
device_for_each_child_node(&bgx->pdev->dev, fwn) {
struct phy_device *pd;
struct device_node *phy_np;
const char *mac;

/* Should always be an OF node. But if it is not, we
* cannot handle it, so exit the loop.
Expand All @@ -1483,9 +1482,7 @@ static int bgx_init_of_phy(struct bgx *bgx)
if (!node)
break;

mac = of_get_mac_address(node);
if (!IS_ERR(mac))
ether_addr_copy(bgx->lmac[lmac].mac, mac);
of_get_mac_address(node, bgx->lmac[lmac].mac);

SET_NETDEV_DEV(&bgx->lmac[lmac].netdev, &bgx->pdev->dev);
bgx->lmac[lmac].lmacid = lmac;
Expand Down
10 changes: 4 additions & 6 deletions drivers/net/ethernet/davicom/dm9000.c
Original file line number Diff line number Diff line change
Expand Up @@ -1385,7 +1385,7 @@ static struct dm9000_plat_data *dm9000_parse_dt(struct device *dev)
{
struct dm9000_plat_data *pdata;
struct device_node *np = dev->of_node;
const void *mac_addr;
int ret;

if (!IS_ENABLED(CONFIG_OF) || !np)
return ERR_PTR(-ENXIO);
Expand All @@ -1399,11 +1399,9 @@ static struct dm9000_plat_data *dm9000_parse_dt(struct device *dev)
if (of_find_property(np, "davicom,no-eeprom", NULL))
pdata->flags |= DM9000_PLATF_NO_EEPROM;

mac_addr = of_get_mac_address(np);
if (!IS_ERR(mac_addr))
ether_addr_copy(pdata->dev_addr, mac_addr);
else if (PTR_ERR(mac_addr) == -EPROBE_DEFER)
return ERR_CAST(mac_addr);
ret = of_get_mac_address(np, pdata->dev_addr);
if (ret == -EPROBE_DEFER)
return ERR_PTR(ret);

return pdata;
}
Expand Down
6 changes: 1 addition & 5 deletions drivers/net/ethernet/ethoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1151,11 +1151,7 @@ static int ethoc_probe(struct platform_device *pdev)
ether_addr_copy(netdev->dev_addr, pdata->hwaddr);
priv->phy_id = pdata->phy_id;
} else {
const void *mac;

mac = of_get_mac_address(pdev->dev.of_node);
if (!IS_ERR(mac))
ether_addr_copy(netdev->dev_addr, mac);
of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
priv->phy_id = -1;
}

Expand Down
7 changes: 2 additions & 5 deletions drivers/net/ethernet/ezchip/nps_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,6 @@ static s32 nps_enet_probe(struct platform_device *pdev)
struct net_device *ndev;
struct nps_enet_priv *priv;
s32 err = 0;
const char *mac_addr;

if (!dev->of_node)
return -ENODEV;
Expand All @@ -602,10 +601,8 @@ static s32 nps_enet_probe(struct platform_device *pdev)
dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs_base);

/* set kernel MAC address to dev */
mac_addr = of_get_mac_address(dev->of_node);
if (!IS_ERR(mac_addr))
ether_addr_copy(ndev->dev_addr, mac_addr);
else
err = of_get_mac_address(dev->of_node, ndev->dev_addr);
if (err)
eth_hw_addr_random(ndev);

/* Get IRQ number */
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/ethernet/freescale/fec_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1665,6 +1665,7 @@ static void fec_get_mac(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
unsigned char *iap, tmpaddr[ETH_ALEN];
int ret;

/*
* try to get mac address in following order:
Expand All @@ -1680,9 +1681,9 @@ static void fec_get_mac(struct net_device *ndev)
if (!is_valid_ether_addr(iap)) {
struct device_node *np = fep->pdev->dev.of_node;
if (np) {
const char *mac = of_get_mac_address(np);
if (!IS_ERR(mac))
iap = (unsigned char *) mac;
ret = of_get_mac_address(np, tmpaddr);
if (!ret)
iap = tmpaddr;
}
}

Expand Down
Loading

0 comments on commit 83216e3

Please sign in to comment.