mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-14 02:19:06 +04:00
octeon: handle EPROBE_DEFER when reading MAC addresses
The octeon ethernet driver reads the MAC addresses from ndo_init(), far
too late to ask for a retry, and cvm_oct_probe() cannot unwind once it
started the packet I/O hardware. Check the port nodes at the top of the
probe instead, where returning an error is still free.
On the EdgeRouter the addresses sit in a fixed-layout cell on the SPI
flash, which since 6.18.45 is not readable that early, so all ports got
a random MAC address. Not upstream yet.
Refresh the octeon patches.
Assisted-by: Claude:claude-opus-5
Link: https://github.com/openwrt/openwrt/pull/24924
(cherry picked from commit fffaf972dd)
Link: https://github.com/openwrt/openwrt/pull/25055
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
1 parent
baa9c9a137
commit
c588728777
3 files changed
+69
-3
No files matched your search
+66
@@ -0,0 +1,66 @@
|
||||
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
Date: Thu, 27 Aug 2026 20:00:00 +0200
|
||||
Subject: [PATCH] staging: octeon: support EPROBE_DEFER when reading MAC
|
||||
addresses
|
||||
|
||||
The per port MAC addresses are read in cvm_oct_common_init(), which runs
|
||||
as ndo_init() from register_netdev(). When the NVMEM provider holding
|
||||
them is not available yet - on the Ubiquiti EdgeRouter it is an MTD
|
||||
partition on the SPI flash - of_get_ethdev_address() returns
|
||||
-EPROBE_DEFER and every port ends up with a random MAC address that
|
||||
changes on every boot.
|
||||
|
||||
Returning the error from ndo_init() does not help: it only makes
|
||||
register_netdev() fail and the interface disappear. cvm_oct_probe() has
|
||||
no unwind path either once it started to bring up the packet I/O
|
||||
hardware.
|
||||
|
||||
Look at all port nodes at the very beginning of cvm_oct_probe() instead,
|
||||
where returning an error is still free, and ask to be probed again later
|
||||
when one of them is not readable yet.
|
||||
|
||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
---
|
||||
drivers/staging/octeon/ethernet.c | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
--- a/drivers/staging/octeon/ethernet.c
|
||||
+++ b/drivers/staging/octeon/ethernet.c
|
||||
@@ -670,6 +670,27 @@ static void cvm_set_rgmii_delay(struct o
|
||||
priv->phy_mode = PHY_INTERFACE_MODE_RGMII;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * The per-port MAC addresses may live in an NVMEM provider that is not there
|
||||
+ * yet, for example an MTD partition on a SPI flash. The netdevs read them from
|
||||
+ * ndo_init(), which is far too late to ask for a retry: once cvm_oct_probe()
|
||||
+ * has begun to bring up the packet I/O hardware there is no way back. Look at
|
||||
+ * all of them here instead, while returning an error is still free.
|
||||
+ */
|
||||
+static bool cvm_oct_mac_addresses_deferred(struct device_node *pip)
|
||||
+{
|
||||
+ u8 mac[ETH_ALEN];
|
||||
+
|
||||
+ for_each_available_child_of_node_scoped(pip, interface) {
|
||||
+ for_each_available_child_of_node_scoped(interface, port) {
|
||||
+ if (of_get_mac_address(port, mac) == -EPROBE_DEFER)
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static int cvm_oct_probe(struct platform_device *pdev)
|
||||
{
|
||||
int num_interfaces;
|
||||
@@ -689,6 +710,9 @@ static int cvm_oct_probe(struct platform
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (cvm_oct_mac_addresses_deferred(pip))
|
||||
+ return -EPROBE_DEFER;
|
||||
+
|
||||
cvm_oct_configure_common_hw();
|
||||
|
||||
cvmx_helper_initialize_packet_io_global();
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/drivers/staging/octeon/ethernet.c
|
||||
+++ b/drivers/staging/octeon/ethernet.c
|
||||
@@ -676,6 +676,7 @@ static int cvm_oct_probe(struct platform
|
||||
@@ -697,6 +697,7 @@ static int cvm_oct_probe(struct platform
|
||||
int interface;
|
||||
int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
|
||||
int qos;
|
||||
@@ -8,7 +8,7 @@
|
||||
struct device_node *pip;
|
||||
int mtu_overhead = ETH_HLEN + ETH_FCS_LEN;
|
||||
|
||||
@@ -797,13 +798,19 @@ static int cvm_oct_probe(struct platform
|
||||
@@ -821,13 +822,19 @@ static int cvm_oct_probe(struct platform
|
||||
}
|
||||
|
||||
num_interfaces = cvmx_helper_get_number_of_interfaces();
|
||||
|
||||
@@ -12,7 +12,7 @@ Tested-by: Johannes Kimmel <fff@bareminimum.eu>
|
||||
Signed-off-by: Roman Kuzmitskii <damex.pp@icloud.com>
|
||||
--- a/drivers/staging/octeon/ethernet.c
|
||||
+++ b/drivers/staging/octeon/ethernet.c
|
||||
@@ -877,8 +877,10 @@ static int cvm_oct_probe(struct platform
|
||||
@@ -901,8 +901,10 @@ static int cvm_oct_probe(struct platform
|
||||
|
||||
case CVMX_HELPER_INTERFACE_MODE_SGMII:
|
||||
priv->phy_mode = PHY_INTERFACE_MODE_SGMII;
|
||||
|
||||
Reference in new issue
Block a user