Download raw body.
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
sys/cnmac: read HW address from DTS when available