#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_net.h>
#include <linux/of_platform.h>
#include <linux/property.h>
#include <linux/regmap.h>
.val_bits = 32,
};
+/*
+ * The conduit is a DMA engine behind the switch and has no address of its
+ * own, so boards describe none: fall back to the switch this conduit serves,
+ * whose ports carry the board's addresses either from DT or patched in by
+ * the bootloader. DSA user ports without one of their own inherit whatever
+ * ends up here.
+ */
+static int edma_get_mac_address(struct net_device *netdev,
+ struct device_node *np)
+{
+ struct device_node *cpu_port;
+ int ret;
+
+ ret = of_get_ethdev_address(np, netdev);
+ if (!ret || ret == -EPROBE_DEFER)
+ return ret;
+
+ for_each_node_with_property(cpu_port, "ethernet") {
+ struct device_node *conduit __free(device_node) =
+ of_parse_phandle(cpu_port, "ethernet", 0);
+
+ if (conduit != np)
+ continue;
+
+ for_each_available_child_of_node_scoped(cpu_port->parent, port) {
+ ret = of_get_ethdev_address(port, netdev);
+ if (!ret || ret == -EPROBE_DEFER) {
+ of_node_put(cpu_port);
+ return ret;
+ }
+ }
+ }
+
+ return -ENODEV;
+}
+
static int edma_probe(struct platform_device *pdev)
{
struct clk_bulk_data *clks;
priv->pdev = pdev;
priv->soc = device_get_match_data(dev);
+ ret = edma_get_mac_address(netdev, dev->of_node);
+ if (ret == -EPROBE_DEFER)
+ return dev_err_probe(dev, ret, "failed to get MAC address\n");
+ if (ret)
+ eth_hw_addr_random(netdev);
+
ret = edma_page_pool_create(priv);
if (ret)
return ret;
SET_NETDEV_DEV(netdev, dev);
netdev->dev.of_node = dev->of_node;
- eth_hw_addr_random(netdev);
netdev->netdev_ops = &edma_netdev_ops;
netdev->features = NETIF_F_GRO;
netdev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;