summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/dc/if_dc.c18
-rw-r--r--sys/pci/if_dc.c18
-rw-r--r--sys/sparc64/include/ofw_machdep.h1
-rw-r--r--sys/sparc64/sparc64/ofw_machdep.c17
4 files changed, 54 insertions, 0 deletions
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c
index 6068194eab7b..ac095cdc41fb 100644
--- a/sys/dev/dc/if_dc.c
+++ b/sys/dev/dc/if_dc.c
@@ -131,6 +131,11 @@ __FBSDID("$FreeBSD$");
#include <pci/if_dcreg.h>
+#ifdef __sparc64__
+#include <dev/ofw/openfirm.h>
+#include <machine/ofw_machdep.h>
+#endif
+
MODULE_DEPEND(dc, pci, 1, 1, 1);
MODULE_DEPEND(dc, ether, 1, 1, 1);
MODULE_DEPEND(dc, miibus, 1, 1, 1);
@@ -2106,6 +2111,19 @@ dc_attach(device_t dev)
dc_read_eeprom(sc, (caddr_t)&eaddr, 0, 3, 1);
break;
case DC_TYPE_DM9102:
+ dc_read_eeprom(sc, (caddr_t)&eaddr, DC_EE_NODEADDR, 3, 0);
+#ifdef __sparc64__
+ /*
+ * If this is an onboard dc(4) the station address read from
+ * the EEPROM is all zero and we have to get it from the fcode.
+ */
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ if (eaddr[i] != 0x00)
+ break;
+ if (i >= ETHER_ADDR_LEN && OF_getetheraddr2(dev, eaddr) == -1)
+ OF_getetheraddr(dev, eaddr);
+#endif
+ break;
case DC_TYPE_21143:
case DC_TYPE_ASIX:
dc_read_eeprom(sc, (caddr_t)&eaddr, DC_EE_NODEADDR, 3, 0);
diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c
index 6068194eab7b..ac095cdc41fb 100644
--- a/sys/pci/if_dc.c
+++ b/sys/pci/if_dc.c
@@ -131,6 +131,11 @@ __FBSDID("$FreeBSD$");
#include <pci/if_dcreg.h>
+#ifdef __sparc64__
+#include <dev/ofw/openfirm.h>
+#include <machine/ofw_machdep.h>
+#endif
+
MODULE_DEPEND(dc, pci, 1, 1, 1);
MODULE_DEPEND(dc, ether, 1, 1, 1);
MODULE_DEPEND(dc, miibus, 1, 1, 1);
@@ -2106,6 +2111,19 @@ dc_attach(device_t dev)
dc_read_eeprom(sc, (caddr_t)&eaddr, 0, 3, 1);
break;
case DC_TYPE_DM9102:
+ dc_read_eeprom(sc, (caddr_t)&eaddr, DC_EE_NODEADDR, 3, 0);
+#ifdef __sparc64__
+ /*
+ * If this is an onboard dc(4) the station address read from
+ * the EEPROM is all zero and we have to get it from the fcode.
+ */
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ if (eaddr[i] != 0x00)
+ break;
+ if (i >= ETHER_ADDR_LEN && OF_getetheraddr2(dev, eaddr) == -1)
+ OF_getetheraddr(dev, eaddr);
+#endif
+ break;
case DC_TYPE_21143:
case DC_TYPE_ASIX:
dc_read_eeprom(sc, (caddr_t)&eaddr, DC_EE_NODEADDR, 3, 0);
diff --git a/sys/sparc64/include/ofw_machdep.h b/sys/sparc64/include/ofw_machdep.h
index f7062f7f939a..c40a7bcdd32c 100644
--- a/sys/sparc64/include/ofw_machdep.h
+++ b/sys/sparc64/include/ofw_machdep.h
@@ -32,6 +32,7 @@
int OF_decode_addr(phandle_t, int *, bus_addr_t *);
void OF_getetheraddr(device_t, u_char *);
+int OF_getetheraddr2(device_t, u_char *);
void cpu_shutdown(void *);
void openfirmware_exit(void *);
diff --git a/sys/sparc64/sparc64/ofw_machdep.c b/sys/sparc64/sparc64/ofw_machdep.c
index b50b4dfc9900..c565a455a833 100644
--- a/sys/sparc64/sparc64/ofw_machdep.c
+++ b/sys/sparc64/sparc64/ofw_machdep.c
@@ -29,6 +29,8 @@
* Some OpenFirmware helper functions that are likely machine dependent.
*/
+#include "opt_ofw_pci.h"
+
#include <sys/param.h>
#include <sys/systm.h>
@@ -59,6 +61,21 @@ OF_getetheraddr(device_t dev, u_char *addr)
}
int
+OF_getetheraddr2(device_t dev, u_char *addr)
+{
+ phandle_t node;
+
+#ifdef OFW_NEWPCI
+ node = ofw_pci_get_node(dev);
+#else
+ node = ofw_pci_node(dev);
+#endif
+ if (node <= 0)
+ return (-1);
+ return (OF_getprop(node, "local-mac-address", addr, ETHER_ADDR_LEN));
+}
+
+int
OF_decode_addr(phandle_t node, int *space, bus_addr_t *addr)
{
char name[32];