1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
arch/arm/mach-ixp4xx/ixdp425-setup.c | 115 ++++++++++++++++++++++++++++++++++-
1 file changed, 112 insertions(+), 3 deletions(-)
--- linux-nslu2.orig/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-02-10 18:03:51.000000000 +0100
+++ linux-nslu2/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-02-10 18:06:40.000000000 +0100
@@ -15,6 +15,7 @@
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>
+#include <linux/eeprom.h>
#include <asm/types.h>
#include <asm/setup.h>
@@ -25,6 +26,10 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
+#ifdef CONFIG_MACLIST
+#include <net/maclist.h>
+#endif
+
static struct flash_platform_data ixdp425_flash_data = {
.map_name = "cfi_probe",
.width = 2,
@@ -176,17 +181,122 @@ MACHINE_START(AVILA, "Gateworks Avila Ne
MACHINE_END
#endif
+#ifdef CONFIG_MACH_LOFT
/*
* Loft is functionally equivalent to Avila except that it has a
* different number for the maximum PCI devices. The MACHINE
- * structure below is identical to Avila except for the comment.
+ * structure below is derived from the Avila one (and may, in
+ * fact, be useful on Avila in general).
+ *
+ * The loft init registers a notifier on the on-board EEPROM to
+ * detect the MAC addresses.
+ * NOTE: this probably works for all Gateworks Avila boards and
+ * maybe the ixdp425 too.
+ *
+ * When the EEPROM is added the MAC address are read from it.
*/
-#ifdef CONFIG_MACH_LOFT
+
+#if defined(CONFIG_SENSORS_EEPROM) && defined(CONFIG_MACLIST)
+static void loft_eeprom_add(int address, int kind, struct kobject *kobj,
+ struct bin_attribute *eeprom_attr) {
+ /* The MACs are the first 12 bytes in the eeprom at address 0x51 */
+ if (address == 0x51) {
+ ssize_t retlen;
+ char data[12];
+
+ /* Two Macs, one at 0, the other at 6, maclist_add will
+ * complain if the ID is not a valid MAC.
+ */
+ retlen = eeprom_attr->read(kobj, data, 0, sizeof data);
+ if (retlen >= 6) {
+ u8 mac[6];
+ memcpy(mac, data+0, sizeof mac);
+ printk(KERN_INFO "LOFT MAC[0]: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ maclist_add(mac);
+ }
+ if (retlen >= 12) {
+ u8 mac[6];
+ memcpy(mac, data+6, sizeof mac);
+ printk(KERN_INFO "LOFT MAC[1]: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ maclist_add(mac);
+ }
+ }
+}
+
+static struct eeprom_notifier loft_eeprom_notifier = {
+ .add = loft_eeprom_add
+};
+#endif
+
+/*
+ * Loft bootstrap may pass in parameters, if these contain an
+ * ATAG_MEM and it appears valid (not the 16MByte one in the
+ * setup/kernel.c default) we use it, otherwise a 64MByte
+ * setting is forced here, this may be overridden on the
+ * command line.
+ */
+static void __init loft_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ char saved_command_line[COMMAND_LINE_SIZE];
+
+ /* Put Loft specific known-required-for-certain stuff here, leave
+ * a trailing space!
+ */
+ static char loft_command_line[] =
+ "root=/dev/mtdblock2 rw rootfstype=jffs2 init=/linuxrc "
+ "rtc-ds1672.probe=0,0x68 ";
+ const int len = (sizeof loft_command_line) - 1;
+ int memtag = 0;
+
+ /* The EEPROM has two ethernet MACs embedded in it which we need,
+ * that is all this notifier does.
+ */
+#ifdef CONFIG_SENSORS_EEPROM
+ register_eeprom_user(&loft_eeprom_notifier);
+#endif
+
+ /* The Loft typically has one bank of 64MByte memory.
+ * NOTE: setting nr_banks != 0 causes kernel/setup.c to remove
+ * the mem tags from the tag list, so if there is an entry
+ * there don't remove it!
+ */
+ if (tags->hdr.tag == ATAG_CORE) do {
+ tags = tag_next(tags);
+ printk(KERN_NOTICE "ATAG[0x%x] size %d\n", tags->hdr.tag, tags->hdr.size);
+ if (tags->hdr.tag == ATAG_MEM && tags->hdr.size == tag_size(tag_mem32) &&
+ (tags->u.mem.start != 0 || tags->u.mem.size != (16*1024*1024))) {
+ memtag = 1;
+ printk(KERN_NOTICE " ATAG_MEM base %x, size %dMB\n",
+ tags->u.mem.start,
+ tags->u.mem.size / (1024*1024));
+ }
+ } while (tags->hdr.size);
+
+ if (!memtag) {
+ mi->nr_banks = 1;
+ mi->bank[0].start = 0;
+ mi->bank[0].size = (64*1024*1024);
+ mi->bank[0].node = PHYS_TO_NID(0);
+ }
+
+ /* A command line in the ATAG list will override this one,
+ * as is intended.
+ */
+ memcpy(saved_command_line, *cmdline, COMMAND_LINE_SIZE);
+ memcpy(*cmdline, loft_command_line, len);
+ memcpy(*cmdline + len, saved_command_line, COMMAND_LINE_SIZE - len);
+ *cmdline[COMMAND_LINE_SIZE-1] = 0;
+}
+
MACHINE_START(LOFT, "Giant Shoulder Inc Loft board")
/* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */
.phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+ .fixup = loft_fixup,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
@@ -194,4 +304,3 @@ MACHINE_START(LOFT, "Giant Shoulder Inc
.init_machine = ixdp425_init,
MACHINE_END
#endif
-
|