Module Name:    src
Committed By:   phx
Date:           Sun May 16 11:27:50 UTC 2010

Modified Files:
        src/sys/arch/sandpoint/include: bootinfo.h
        src/sys/arch/sandpoint/sandpoint: autoconf.c
        src/sys/arch/sandpoint/stand/netboot: brdsetup.c globals.h main.c skg.c
        src/sys/dev/pci: if_sk.c

Log Message:
Make netboot generate a BTINFO_NET bootinfo node for the Synology sk(4) NIC.
It will pass the MAC address, which is read from Flash ROM, into the kernel.
The kernel creates a "mac-address" device-property, which is used by sk(4),
when given, before reading the MAC from its EEPROM.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/sandpoint/include/bootinfo.h
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/sandpoint/sandpoint/autoconf.c
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/sandpoint/stand/netboot/brdsetup.c
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/sandpoint/stand/netboot/globals.h
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/sandpoint/stand/netboot/main.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/sandpoint/stand/netboot/skg.c
cvs rdiff -u -r1.66 -r1.67 src/sys/dev/pci/if_sk.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sandpoint/include/bootinfo.h
diff -u src/sys/arch/sandpoint/include/bootinfo.h:1.4 src/sys/arch/sandpoint/include/bootinfo.h:1.5
--- src/sys/arch/sandpoint/include/bootinfo.h:1.4	Wed Oct 17 19:56:56 2007
+++ src/sys/arch/sandpoint/include/bootinfo.h	Sun May 16 11:27:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: bootinfo.h,v 1.4 2007/10/17 19:56:56 garbled Exp $	*/
+/*	$NetBSD: bootinfo.h,v 1.5 2010/05/16 11:27:49 phx Exp $	*/
 
 /*
  * Copyright (c) 1997
@@ -42,6 +42,7 @@
 #define BTINFO_CLOCK		4
 #define BTINFO_BOOTPATH		5
 #define BTINFO_ROOTDEVICE	6
+#define BTINFO_NET		7
 
 struct btinfo_magic {
 	struct btinfo_common common;
@@ -76,6 +77,12 @@
 	unsigned cookie;
 };
 
+struct btinfo_net {
+	struct btinfo_common common;
+	char devname[16];
+	uint8_t mac_address[6];
+};
+
 #define BOOTINFO_MAXSIZE 4096
 
 #ifdef _KERNEL

Index: src/sys/arch/sandpoint/sandpoint/autoconf.c
diff -u src/sys/arch/sandpoint/sandpoint/autoconf.c:1.19 src/sys/arch/sandpoint/sandpoint/autoconf.c:1.20
--- src/sys/arch/sandpoint/sandpoint/autoconf.c:1.19	Wed Mar 18 10:22:35 2009
+++ src/sys/arch/sandpoint/sandpoint/autoconf.c	Sun May 16 11:27:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.19 2009/03/18 10:22:35 cegger Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.20 2010/05/16 11:27:49 phx Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -35,22 +35,25 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.19 2009/03/18 10:22:35 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.20 2010/05/16 11:27:49 phx Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <sys/device.h>
+
+#include <dev/cons.h>
 #include <dev/pci/pcivar.h>
 
+#include <net/if.h>
+#include <net/if_ether.h>
+
 #include <machine/bootinfo.h>
+#include <machine/pio.h>
 
 static struct btinfo_rootdevice *bi_rdev;
 static struct btinfo_bootpath *bi_path;
-
-#include <dev/cons.h>
-#include <machine/pio.h>
-
+static struct btinfo_net *bi_net;
 
 /*
  * Determine i/o configuration for a machine.
@@ -61,6 +64,7 @@
 
 	bi_rdev = lookup_bootinfo(BTINFO_ROOTDEVICE);
 	bi_path = lookup_bootinfo(BTINFO_BOOTPATH);
+	bi_net = lookup_bootinfo(BTINFO_NET);
 
 	if (config_rootfound("mainbus", NULL) == NULL)
 		panic("configure: mainbus not configured");
@@ -85,18 +89,28 @@
 void
 device_register(struct device *dev, void *aux)
 {
+	struct pci_attach_args *pa;
 
-	if (bi_rdev == NULL)
-		return; /* no clue to determine */
-
-	if (dev->dv_class == DV_IFNET
-	    && device_is_a(dev, bi_rdev->devname)) {
-		struct pci_attach_args *pa = aux;
-
-		if (bi_rdev->cookie == pa->pa_tag)
+	if (dev->dv_class == DV_IFNET) {
+		pa = aux;
+		if (bi_rdev != NULL && device_is_a(dev, bi_rdev->devname)
+		    && bi_rdev->cookie == pa->pa_tag)
 			booted_device = dev;
+		if (bi_net != NULL && device_is_a(dev, bi_net->devname)) {
+			prop_data_t pd;
+
+			pd = prop_data_create_data_nocopy(bi_net->mac_address,
+			    ETHER_ADDR_LEN);
+			KASSERT(pd != NULL);
+			if (prop_dictionary_set(device_properties(dev),
+			    "mac-address", pd) == false)
+				printf("WARNING: unable to set mac-addr "
+				    "property for %s\n", dev->dv_xname);
+			prop_object_release(pd);
+			bi_net = NULL;	/* do it just once */
+		}
 	}
-	if (dev->dv_class == DV_DISK
+	if (bi_rdev != NULL && dev->dv_class == DV_DISK
 	    && device_is_a(dev, bi_rdev->devname)) {
 		booted_device = dev;
 		booted_partition = 0;

Index: src/sys/arch/sandpoint/stand/netboot/brdsetup.c
diff -u src/sys/arch/sandpoint/stand/netboot/brdsetup.c:1.13 src/sys/arch/sandpoint/stand/netboot/brdsetup.c:1.14
--- src/sys/arch/sandpoint/stand/netboot/brdsetup.c:1.13	Thu May 13 10:40:02 2010
+++ src/sys/arch/sandpoint/stand/netboot/brdsetup.c	Sun May 16 11:27:49 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: brdsetup.c,v 1.13 2010/05/13 10:40:02 phx Exp $ */
+/* $NetBSD: brdsetup.c,v 1.14 2010/05/16 11:27:49 phx Exp $ */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -707,3 +707,77 @@
 		break;
 	}
 }
+
+struct fis_dir_entry {
+	char		name[16];
+	uint32_t	startaddr;
+	uint32_t	loadaddr;
+	uint32_t	flashsize;
+	uint32_t	entryaddr;
+	uint32_t	filesize;
+	char		pad[256 - (16 + 5 * sizeof(uint32_t))];
+};
+
+#define FIS_LOWER_LIMIT	0xfff00000
+
+/*
+ * Look for a Redboot-style Flash Image System FIS-directory and
+ * return a pointer to the start address of the requested file.
+ */
+static void *
+redboot_fis_lookup(const char *filename)
+{
+	static const char FISdirname[16] = {
+	    'F', 'I', 'S', ' ',
+	    'd', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 0, 0, 0
+	};
+	struct fis_dir_entry *dir;
+
+	/*
+	 * The FIS directory is usually in the last sector of the flash.
+	 * But we do not know the sector size (erase size), so start
+	 * at 0xffffff00 and scan backwards in steps of the FIS directory
+	 * entry size (0x100).
+	 */
+	for (dir = (struct fis_dir_entry *)0xffffff00;
+	    (uint32_t)dir >= FIS_LOWER_LIMIT; dir--)
+		if (memcmp(dir->name, FISdirname, sizeof(FISdirname)) == 0)
+			break;
+	if ((uint32_t)dir < FIS_LOWER_LIMIT) {
+		printf("No FIS directory found!\n");
+		return NULL;
+	}
+
+	/* Now find filename by scanning the directory from beginning. */
+	dir = (struct fis_dir_entry *)dir->startaddr;
+	while (dir->name[0] != 0xff && (uint32_t)dir < 0xffffff00) {
+		if (strcmp(dir->name, filename) == 0)
+			return (void *)dir->startaddr;	/* found */
+		dir++;
+	}
+	printf("\"%s\" not found in FIS directory!\n", filename);
+	return NULL;
+}
+
+/*
+ * For cost saving reasons some NAS boxes are missing the ROM for the
+ * NIC's ethernet address and keep it in their Flash memory.
+ */
+void
+read_mac_from_flash(uint8_t *mac)
+{
+	uint8_t *p;
+
+	if (brdtype == BRD_SYNOLOGY) {
+		p = redboot_fis_lookup("vendor");
+		if (p != NULL) {
+			memcpy(mac, p, 6);
+			return;
+		}
+	} else
+		printf("Warning: This board has no known method defined "
+		    "to determine its MAC address!\n");
+
+	/* set to 00:00:00:00:00:00 in case of error */
+	memset(mac, 0, 6);
+}

Index: src/sys/arch/sandpoint/stand/netboot/globals.h
diff -u src/sys/arch/sandpoint/stand/netboot/globals.h:1.14 src/sys/arch/sandpoint/stand/netboot/globals.h:1.15
--- src/sys/arch/sandpoint/stand/netboot/globals.h:1.14	Sat May  8 19:41:07 2010
+++ src/sys/arch/sandpoint/stand/netboot/globals.h	Sun May 16 11:27:49 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: globals.h,v 1.14 2010/05/08 19:41:07 phx Exp $ */
+/* $NetBSD: globals.h,v 1.15 2010/05/16 11:27:49 phx Exp $ */
 
 /* clock feed */
 #ifndef EXT_CLK_FREQ
@@ -23,6 +23,7 @@
 extern uint32_t cpuclock, busclock;
 
 unsigned mpc107memsize(void);
+void read_mac_from_flash(uint8_t *);
 
 /* PPC processor ctl */
 void __syncicache(void *, size_t);

Index: src/sys/arch/sandpoint/stand/netboot/main.c
diff -u src/sys/arch/sandpoint/stand/netboot/main.c:1.28 src/sys/arch/sandpoint/stand/netboot/main.c:1.29
--- src/sys/arch/sandpoint/stand/netboot/main.c:1.28	Thu May 13 10:40:02 2010
+++ src/sys/arch/sandpoint/stand/netboot/main.c	Sun May 16 11:27:49 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.28 2010/05/13 10:40:02 phx Exp $ */
+/* $NetBSD: main.c,v 1.29 2010/05/16 11:27:49 phx Exp $ */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -69,6 +69,7 @@
 	struct btinfo_clock bi_clk;
 	struct btinfo_bootpath bi_path;
 	struct btinfo_rootdevice bi_rdev;
+	struct btinfo_net bi_net;
 	unsigned long marks[MARK_MAX];
 	unsigned lata[1][2], lnif[1][2];
 	unsigned memsize, tag;
@@ -158,12 +159,19 @@
 	snprintf(bi_path.bootpath, sizeof(bi_path.bootpath), bootfile);
 	snprintf(bi_rdev.devname, sizeof(bi_rdev.devname), rootdev);
 	bi_rdev.cookie = tag; /* PCI tag for fxp netboot case */
+	if (brdtype == BRD_SYNOLOGY) {
+		/* need to set MAC address for Marvell-SKnet */
+		strcpy(bi_net.devname, "sk");
+		memcpy(bi_net.mac_address, en, sizeof(en));
+	}
 
 	bi_add(&bi_cons, BTINFO_CONSOLE, sizeof(bi_cons));
 	bi_add(&bi_mem, BTINFO_MEMORY, sizeof(bi_mem));
 	bi_add(&bi_clk, BTINFO_CLOCK, sizeof(bi_clk));
 	bi_add(&bi_path, BTINFO_BOOTPATH, sizeof(bi_path));
 	bi_add(&bi_rdev, BTINFO_ROOTDEVICE, sizeof(bi_rdev));
+	if (brdtype == BRD_SYNOLOGY)
+		bi_add(&bi_net, BTINFO_NET, sizeof(bi_net));
 
 	printf("entry=%p, ssym=%p, esym=%p\n",
 	    (void *)marks[MARK_ENTRY],

Index: src/sys/arch/sandpoint/stand/netboot/skg.c
diff -u src/sys/arch/sandpoint/stand/netboot/skg.c:1.2 src/sys/arch/sandpoint/stand/netboot/skg.c:1.3
--- src/sys/arch/sandpoint/stand/netboot/skg.c:1.2	Mon May  3 18:55:09 2010
+++ src/sys/arch/sandpoint/stand/netboot/skg.c	Sun May 16 11:27:49 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: skg.c,v 1.2 2010/05/03 18:55:09 phx Exp $ */
+/* $NetBSD: skg.c,v 1.3 2010/05/16 11:27:49 phx Exp $ */
 
 /*-
  * Copyright (c) 2010 Frank Wille.
@@ -227,25 +227,20 @@
 
 	/* read ethernet address */
 	en = data;
-	for (i = 0; i < 6; i++)
-		en[i] = CSR_READ_1(l, SK_MAC0 + i);
+	if (brdtype == BRD_SYNOLOGY)
+		read_mac_from_flash(en);
+	else
+		for (i = 0; i < 6; i++)
+			en[i] = CSR_READ_1(l, SK_MAC0 + i);
 	printf("MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
 	    en[0], en[1], en[2], en[3], en[4], en[5]);
 	printf("PHY %d (%04x.%04x)\n", l->phy,
 	    mii_read(l, l->phy, 2), mii_read(l, l->phy, 3));
 
 	/* set station address */
-	for (i = 0; i < 3; i++) {
-#if 0
-		CSR_WRITE_2(l, YUKON_SA1 + i * 4,
-		    CSR_READ_2(l, SK_MAC0 + i * 2));
-		CSR_WRITE_2(l, YUKON_SA2 + i * 4,
-		    CSR_READ_2(l, SK_MAC1 + i * 2));
-#else
+	for (i = 0; i < 3; i++)
 		CSR_WRITE_2(l, YUKON_SA1 + i * 4,
 		    (en[i * 2] << 8) | en[i * 2 + 1]);
-#endif
-	}
 
 	/* configure RX and TX MAC FIFO */
 	CSR_WRITE_1(l, SK_RXMF1_CTRL_TEST, RFCTL_RESET_CLEAR);

Index: src/sys/dev/pci/if_sk.c
diff -u src/sys/dev/pci/if_sk.c:1.66 src/sys/dev/pci/if_sk.c:1.67
--- src/sys/dev/pci/if_sk.c:1.66	Mon Apr  5 07:20:27 2010
+++ src/sys/dev/pci/if_sk.c	Sun May 16 11:27:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_sk.c,v 1.66 2010/04/05 07:20:27 joerg Exp $	*/
+/*	$NetBSD: if_sk.c,v 1.67 2010/05/16 11:27:49 phx Exp $	*/
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -115,7 +115,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_sk.c,v 1.66 2010/04/05 07:20:27 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_sk.c,v 1.67 2010/05/16 11:27:49 phx Exp $");
 
 #include "rnd.h"
 
@@ -1209,6 +1209,7 @@
 	struct ifnet *ifp;
 	bus_dma_segment_t seg;
 	bus_dmamap_t dmamap;
+	prop_data_t data;
 	void *kva;
 	int i, rseg;
 	int mii_flags = 0;
@@ -1236,10 +1237,20 @@
 	 * are operating in failover mode. Currently we don't
 	 * use this extra address.
 	 */
-	for (i = 0; i < ETHER_ADDR_LEN; i++)
-		sc_if->sk_enaddr[i] =
-			sk_win_read_1(sc, SK_MAC0_0 + (sa->skc_port * 8) + i);
-
+	data = prop_dictionary_get(device_properties(self), "mac-address");
+	if (data != NULL) {
+		/*
+		 * Try to get the station address from device properties
+		 * first, in case the ROM is missing.
+		 */
+		KASSERT(prop_object_type(data) == PROP_TYPE_DATA);
+		KASSERT(prop_data_size(data) == ETHER_ADDR_LEN);
+		memcpy(sc_if->sk_enaddr, prop_data_data_nocopy(data),
+		    ETHER_ADDR_LEN);
+	} else
+		for (i = 0; i < ETHER_ADDR_LEN; i++)
+			sc_if->sk_enaddr[i] = sk_win_read_1(sc,
+			    SK_MAC0_0 + (sa->skc_port * 8) + i);
 
 	aprint_normal(": Ethernet address %s\n",
 	    ether_sprintf(sc_if->sk_enaddr));

Reply via email to