summaryrefslogtreecommitdiffstats
path: root/target/linux/ixp4xx/patches-2.6.24/300-avila_fetch_mac.patch
blob: cedeb846945f92e8da1304a2b611e1e2cc7f4183 (plain)
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
Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c
===================================================================
--- linux-2.6.24.2.orig/arch/arm/mach-ixp4xx/avila-setup.c
+++ linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c
@@ -14,10 +14,18 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/if_ether.h>
+#include <linux/socket.h>
+#include <linux/netdevice.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
 #include <linux/slab.h>
+#ifdef CONFIG_SENSORS_EEPROM
+# include <linux/i2c.h>
+# include <linux/eeprom.h>
+#endif
+
 #include <linux/i2c-gpio.h>
 
 #include <asm/types.h>
@@ -177,6 +185,118 @@ static struct platform_device *avila_eth
 	&avila_eth[1]
 };
 
+#ifdef CONFIG_SENSORS_EEPROM
+struct avila_board_info {
+	unsigned char *model;
+	int	npes_used;
+	int	npeb_phy;
+	int	npec_phy;
+};
+
+static struct avila_board_info avila_boards[] = {
+	{
+		.model		= "GW2342",
+		.npes_used	= 2,
+		.npeb_phy	= 0,
+		.npec_phy	= 1,
+	}, {
+		.model		= "GW2347",
+		.npes_used	= 1,
+		.npeb_phy	= 1,
+	}, {
+		.model		= "GW2348-2",
+		.npes_used	= 2,
+		.npeb_phy	= 0,
+		.npec_phy	= 1,
+	}, {
+		.model		= "GW2348-4",
+		.npes_used	= 2,
+		.npeb_phy	= 0,
+		.npec_phy	= 1,
+	}, {
+		.model		= "GW2353",
+		.npes_used	= 1,
+		.npeb_phy	= 1,
+	}, {
+		.model		= "GW2355",
+		.npes_used	= 2,
+		.npeb_phy	= -1,
+		.npec_phy	= 1,
+	}, {
+		.model		= "GW2357",
+		.npes_used	= 1,
+		.npeb_phy	= 1,
+	}
+};
+
+static struct avila_board_info *avila_find_board_info(char *model)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(avila_boards); i++) {
+		struct avila_board_info *info = &avila_boards[i];
+		if (strncmp(info->model, model, strlen(info->model)) == 0)
+			return info;
+	}
+
+	return NULL;
+}
+
+struct avila_eeprom_header {
+	unsigned char mac0[ETH_ALEN];
+	unsigned char mac1[ETH_ALEN];
+	unsigned char res0[4];
+	unsigned char magic[2];
+	unsigned char config[14];
+	unsigned char model[16];
+};
+
+static int avila_eeprom_notify(struct notifier_block *self,
+			unsigned long event, void *t)
+{
+	struct eeprom_data *ee = t;
+	struct avila_board_info *info = NULL;
+	struct avila_eeprom_header hdr;
+
+	/* The eeprom is at address 0x51 */
+	if (event != EEPROM_REGISTER || ee->client.addr != 0x51)
+		return NOTIFY_DONE;
+
+	ee->attr->read(&ee->client.dev.kobj, ee->attr, (char *)&hdr,
+		0, sizeof(hdr));
+
+	if (hdr.magic[0] != 'G' || hdr.magic[1] != 'W')
+		return NOTIFY_DONE;
+
+	memcpy(&avila_plat_eth[0].hwaddr, hdr.mac0, ETH_ALEN);
+	memcpy(&avila_plat_eth[1].hwaddr, hdr.mac1, ETH_ALEN);
+
+	info = avila_find_board_info(hdr.model);
+
+	if (info) {
+		printk(KERN_DEBUG "Running on Gateworks Avila %s\n",
+							info->model);
+		avila_plat_eth[0].phy = info->npeb_phy;
+		avila_plat_eth[1].phy = info->npec_phy;
+		platform_add_devices(avila_eth_devices,
+			info->npes_used);
+	} else {
+		printk(KERN_INFO "Unknown/missing Avila model number"
+					" -- defaults will be used\n");
+		platform_add_devices(avila_eth_devices,
+			ARRAY_SIZE(avila_eth_devices));
+	}
+
+	unregister_eeprom_notifier(self);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block avila_eeprom_notifier = {
+       .notifier_call = avila_eeprom_notify
+};
+#endif
+
 static void __init avila_init(void)
 {
 	ixp4xx_sys_init();
@@ -201,7 +321,11 @@ static void __init avila_init(void)
 
 	platform_device_register(&avila_pata);
 
+#ifdef CONFIG_SENSORS_EEPROM
+	register_eeprom_notifier(&avila_eeprom_notifier);
+#else
 	platform_add_devices(avila_eth_devices, ARRAY_SIZE(avila_eth_devices));
+#endif
 }
 
 MACHINE_START(AVILA, "Gateworks Avila Network Platform")