Index | Thread | Search

From:
Kirill A. Korinsky <kirill@korins.ky>
Subject:
sys/cnmac: read HW address from DTS when available
To:
OpenBSD tech <tech@openbsd.org>, visa@openbsd.org
Date:
Mon, 27 Apr 2026 11:54:21 +0200

Download raw body.

Thread
  • Kirill A. Korinsky:

    sys/cnmac: read HW address from DTS when available

tech@,

I'd like to fix cnmac to read local-mac-address from the matching DTS
Ethernet port node, selected by the port reg.

When it is missing, it keeps the old fallback.

Tested on Unifi ER4 (CN70xx/CN71xx) and Unifi USG (CN50xx) without any
impact, and on Juniper SRX300 (CN70xx/CN71xx) where chandes are:

before diff:

octpip0 at simplebus0
octgmx0 at octpip0 interface 0
cnmac0 at octgmx0: port 0 SGMII, address d0:dd:49:e0:63:80
octgmx1 at octpip0 interface 1: no active ports found
octgmx2 at octpip0 interface 4
cnmac1 at octgmx2: port 24 AGL, address 00:00:00:00:00:00

after diff:

octpip0 at simplebus0
octgmx0 at octpip0 interface 0
cnmac0 at octgmx0: port 0 SGMII, address d0:dd:49:e0:63:80
octgmx1 at octpip0 interface 1: no active ports found
octgmx2 at octpip0 interface 4
cnmac1 at octgmx2: port 24 AGL, address d0:dd:49:e0:63:82

Here octgmx1 is a prot with cavium,sgmii-mac-phy-mode but without phy-handle

Ok?

Index: sys/arch/octeon/dev/cn30xxgmx.c
===================================================================
RCS file: /home/cvs/src/sys/arch/octeon/dev/cn30xxgmx.c,v
diff -u -p -r1.56 cn30xxgmx.c
--- sys/arch/octeon/dev/cn30xxgmx.c	22 Apr 2026 19:11:04 -0000	1.56
+++ sys/arch/octeon/dev/cn30xxgmx.c	27 Apr 2026 09:31:27 -0000
@@ -87,6 +87,7 @@ struct cn30xxgmx_port_ops {
 int	cn30xxgmx_match(struct device *, void *, void *);
 void	cn30xxgmx_attach(struct device *, struct device *, void *);
 int	cn30xxgmx_print(void *, const char *);
+int	cn30xxgmx_get_port_node(int, int);
 void	cn30xxgmx_init(struct cn30xxgmx_softc *);
 int	cn30xxgmx_rx_frm_ctl_xable(struct cn30xxgmx_port_softc *,
 	    uint64_t, int);
@@ -169,6 +170,22 @@ cn30xxgmx_match(struct device *parent, v
 }
 
 int
+cn30xxgmx_get_port_node(int node, int port)
+{
+	int child;
+
+	if (node == 0)
+		return 0;
+
+	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+		if (OF_getpropint(child, "reg", (uint32_t)-1) == port)
+			return child;
+	}
+
+	return 0;
+}
+
+int
 cn30xxgmx_get_phy_phandle(int interface, int port, int *port_1000x,
     int *disable_an)
 {
@@ -235,6 +252,7 @@ cn30xxgmx_attach(struct device *parent, 
 	struct cn30xxgmx_softc *sc = (void *)self;
 	struct cn30xxsmi_softc *smi;
 	int i;
+	int node;
 	int phandle;
 	int phy_addr;
 	int port;
@@ -268,6 +286,7 @@ cn30xxgmx_attach(struct device *parent, 
 
 	for (i = 0; i < sc->sc_nports; i++) {
 		port_sc = &sc->sc_ports[i];
+		node = cn30xxgmx_get_port_node(aa->aa_node, i);
 		if (sc->sc_port_types[i] == GMX_AGL_PORT)
 			port = 24;
 		else
@@ -330,6 +349,7 @@ cn30xxgmx_attach(struct device *parent, 
 		gmx_aa.ga_name = "cnmac";
 		gmx_aa.ga_portno = port_sc->sc_port_no;
 		gmx_aa.ga_port_type = sc->sc_port_types[i];
+		gmx_aa.ga_node = node;
 		gmx_aa.ga_gmx = sc;
 		gmx_aa.ga_gmx_port = port_sc;
 		gmx_aa.ga_phy_addr = phy_addr;
Index: sys/arch/octeon/dev/cn30xxgmxvar.h
===================================================================
RCS file: /home/cvs/src/sys/arch/octeon/dev/cn30xxgmxvar.h,v
diff -u -p -r1.15 cn30xxgmxvar.h
--- sys/arch/octeon/dev/cn30xxgmxvar.h	22 Apr 2026 19:11:04 -0000	1.15
+++ sys/arch/octeon/dev/cn30xxgmxvar.h	27 Apr 2026 09:31:27 -0000
@@ -95,6 +95,7 @@ struct cn30xxgmx_attach_args {
 	const char		*ga_name;
 	int			ga_portno;
 	int			ga_port_type;
+	int			ga_node;
 	struct cn30xxsmi_softc	*ga_smi;
 	int			ga_phy_addr;
 
Index: sys/arch/octeon/dev/if_cnmac.c
===================================================================
RCS file: /home/cvs/src/sys/arch/octeon/dev/if_cnmac.c,v
diff -u -p -r1.88 if_cnmac.c
--- sys/arch/octeon/dev/if_cnmac.c	22 Apr 2026 19:11:04 -0000	1.88
+++ sys/arch/octeon/dev/if_cnmac.c	27 Apr 2026 09:31:27 -0000
@@ -51,6 +51,8 @@
 #include <sys/endian.h>
 #include <sys/atomic.h>
 
+#include <dev/ofw/openfirm.h>
+
 #include <net/if.h>
 #include <net/if_media.h>
 #include <netinet/in.h>
@@ -120,6 +122,7 @@ void	cnmac_ipd_init(struct cnmac_softc *
 void	cnmac_pko_init(struct cnmac_softc *);
 
 void	cnmac_board_mac_addr(uint8_t *);
+int	cnmac_port_mac_addr(int, uint8_t *);
 
 int	cnmac_mii_readreg(struct device *, int, int);
 void	cnmac_mii_writereg(struct device *, int, int, int);
@@ -277,7 +280,8 @@ cnmac_attach(struct device *parent, stru
 	 */
 	sc->sc_ip_offset = 0/* XXX */;
 
-	cnmac_board_mac_addr(sc->sc_arpcom.ac_enaddr);
+	if (cnmac_port_mac_addr(ga->ga_node, sc->sc_arpcom.ac_enaddr) != 0)
+		cnmac_board_mac_addr(sc->sc_arpcom.ac_enaddr);
 	printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
 
 	ml_init(&sc->sc_sendq);
@@ -386,6 +390,17 @@ cnmac_pko_init(struct cnmac_softc *sc)
 }
 
 /* ---- XXX */
+
+int
+cnmac_port_mac_addr(int node, uint8_t *enaddr)
+{
+	if (node == 0)
+		return 1;
+	if (OF_getprop(node, "local-mac-address", enaddr, ETHER_ADDR_LEN) ==
+	    ETHER_ADDR_LEN)
+		return 0;
+	return 1;
+}
 
 void
 cnmac_board_mac_addr(uint8_t *enaddr)
Index: sys/arch/octeon/dev/iobusvar.h
===================================================================
RCS file: /home/cvs/src/sys/arch/octeon/dev/iobusvar.h,v
diff -u -p -r1.5 iobusvar.h
--- sys/arch/octeon/dev/iobusvar.h	20 May 2024 23:20:29 -0000	1.5
+++ sys/arch/octeon/dev/iobusvar.h	27 Apr 2026 09:31:27 -0000
@@ -36,6 +36,7 @@ extern bus_space_t iobus_tag;
 struct iobus_attach_args {
 	char		*aa_name;
 	int		aa_unitno;
+	int		aa_node;
 
 	bus_addr_t	aa_addr;
 	int		aa_irq;
Index: sys/arch/octeon/dev/octeon_iobus.c
===================================================================
RCS file: /home/cvs/src/sys/arch/octeon/dev/octeon_iobus.c,v
diff -u -p -r1.28 octeon_iobus.c
--- sys/arch/octeon/dev/octeon_iobus.c	20 May 2024 23:17:10 -0000	1.28
+++ sys/arch/octeon/dev/octeon_iobus.c	27 Apr 2026 09:31:27 -0000
@@ -231,6 +231,7 @@ iobussearch(struct device *parent, void 
 	aa.aa_addr = cf->cf_loc[0];
 	aa.aa_irq  = cf->cf_loc[1];
 	aa.aa_unitno = cf->cf_unit;
+	aa.aa_node = 0;
 
 	/* No address specified, try to look it up. */
 	if (aa.aa_addr == -1) {
Index: sys/arch/octeon/dev/octpip.c
===================================================================
RCS file: /home/cvs/src/sys/arch/octeon/dev/octpip.c,v
diff -u -p -r1.3 octpip.c
--- sys/arch/octeon/dev/octpip.c	8 Sep 2020 13:54:48 -0000	1.3
+++ sys/arch/octeon/dev/octpip.c	27 Apr 2026 09:31:27 -0000
@@ -82,6 +82,7 @@ octpip_attach(struct device *parent, str
 		iaa.aa_addr = addr;
 		iaa.aa_irq = -1;
 		iaa.aa_unitno = ifindex;
+		iaa.aa_node = node;
 		config_found(self, &iaa, octpip_print);
 	}
 }

-- 
wbr, Kirill