summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authorraj <raj@FreeBSD.org>2008-03-12 16:32:08 +0000
committerraj <raj@FreeBSD.org>2008-03-12 16:32:08 +0000
commit8e81cff1fea20b1d0d53988daff826286c50640c (patch)
treebee3dfa13f4fb01fa9d5de6630099aac13d777f4 /sys/powerpc
parent054d727b12bc095749d9c28ef9354f5aab773391 (diff)
downloadFreeBSD-src-8e81cff1fea20b1d0d53988daff826286c50640c.zip
FreeBSD-src-8e81cff1fea20b1d0d53988daff826286c50640c.tar.gz
Obtain TSEC h/w address from the parent bus (OCP) and not rely blindly on what
might be currently programmed into the registers. Underlying firmware (U-Boot) would typically program MAC address into the first unit only, and others are left uninitialized. It is now possible to retrieve and program MAC address for all units properly, provided they were passed on in the bootinfo metadata. Reviewed by: imp, marcel Approved by: cognet (mentor)
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/booke/machdep.c25
-rw-r--r--sys/powerpc/include/bootinfo.h3
-rw-r--r--sys/powerpc/include/ocpbus.h1
-rw-r--r--sys/powerpc/mpc85xx/ocpbus.c9
4 files changed, 37 insertions, 1 deletions
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index f5a1e06..98d1b77 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -313,6 +313,29 @@ print_kernel_section_addr(void)
debugf(" _end = 0x%08x\n", (u_int32_t)_end);
}
+struct bi_mem_region *
+bootinfo_mr(void)
+{
+
+ return((struct bi_mem_region *)bootinfo->bi_data);
+}
+
+struct bi_eth_addr *
+bootinfo_eth(void)
+{
+ struct bi_mem_region *mr;
+ struct bi_eth_addr *eth;
+ int i;
+
+ /* Advance to the eth section */
+ mr = bootinfo_mr();
+ for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++)
+ ;
+
+ eth = (struct bi_eth_addr *)mr;
+ return (eth);
+}
+
void
e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp)
{
@@ -358,7 +381,7 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp)
}
/* Initialize memory regions table */
- mr = (struct bi_mem_region *)bootinfo->bi_data;
+ mr = bootinfo_mr();
for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++) {
if (i == MEM_REGIONS)
break;
diff --git a/sys/powerpc/include/bootinfo.h b/sys/powerpc/include/bootinfo.h
index 0125465..599516e 100644
--- a/sys/powerpc/include/bootinfo.h
+++ b/sys/powerpc/include/bootinfo.h
@@ -64,6 +64,9 @@ struct bootinfo {
};
extern struct bootinfo *bootinfo;
+
+struct bi_mem_region *bootinfo_mr(void);
+struct bi_eth_addr *bootinfo_eth(void);
#endif
#endif /* _MACHINE_BOOTINFO_H_ */
diff --git a/sys/powerpc/include/ocpbus.h b/sys/powerpc/include/ocpbus.h
index 6cd7f9e..cbe4cf9 100644
--- a/sys/powerpc/include/ocpbus.h
+++ b/sys/powerpc/include/ocpbus.h
@@ -32,6 +32,7 @@
#define OCPBUS_IVAR_DEVTYPE 1
#define OCPBUS_IVAR_CLOCK 2
#define OCPBUS_IVAR_HWUNIT 3
+#define OCPBUS_IVAR_MACADDR 4
/* Device types. */
#define OCPBUS_DEVTYPE_PIC 1
diff --git a/sys/powerpc/mpc85xx/ocpbus.c b/sys/powerpc/mpc85xx/ocpbus.c
index a62e78b..cf86eed 100644
--- a/sys/powerpc/mpc85xx/ocpbus.c
+++ b/sys/powerpc/mpc85xx/ocpbus.c
@@ -555,6 +555,8 @@ static int
ocpbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
{
struct ocp_devinfo *dinfo;
+ struct bi_eth_addr *eth;
+ int unit;
if (device_get_parent(child) != dev)
return (EINVAL);
@@ -571,6 +573,13 @@ ocpbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
case OCPBUS_IVAR_HWUNIT:
*result = dinfo->ocp_unit;
return (0);
+ case OCPBUS_IVAR_MACADDR:
+ unit = device_get_unit(child);
+ if (unit > bootinfo->bi_eth_addr_no - 1)
+ return (EINVAL);
+ eth = bootinfo_eth() + unit;
+ *result = (uintptr_t)eth;
+ return (0);
}
return (EINVAL);
OpenPOWER on IntegriCloud