From: Kirill A. Korinsky Subject: sys/cnmac: read HW address from DTS when available To: OpenBSD tech , visa@openbsd.org Date: Mon, 27 Apr 2026 11:54:21 +0200 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 #include +#include + #include #include #include @@ -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