summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-3.0/beagle/0008-HACK-OMAP2-BeagleBoard-Fix-up-random-or-missing-MAC-.patch
blob: 210c38c148c9bd4bec41d042c1fc7fc5ed7c9607 (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
155
156
From 67f39ef3d73d377b13dbf34bd5170d94f00cc2c2 Mon Sep 17 00:00:00 2001
From: Jason Kridner <jdk@ti.com>
Date: Thu, 15 Sep 2011 18:23:02 -0400
Subject: [PATCH 8/8] HACK: OMAP2+: BeagleBoard: Fix up random or missing MAC addresses for eth0 and wlan0

This was borrowed from the Panda implementation at http://patches.linaro.org/777/

This patch registers a network device notifier callback to set the mac
addresses for the onboard network assets of the BeagleBoard correctly, despite the
drivers involved have used a random or all-zeros MAC address.

The technique was suggested by Alan Cox on lkml.

It works by device path so it corrects the MAC addresses even if the
drivers are in modules loaded in an order that changes their interface
name from usual (eg, the onboard module might be "wlan1" if there is a
USB wireless stick plugged in and its module is inserted first.)

Cc: Andy Green <andy@warmcat.com>
---
 arch/arm/mach-omap2/board-omap3beagle.c |   90 +++++++++++++++++++++++++++++++
 1 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 5e1d9f9..9712099 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -33,6 +33,8 @@
 
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
+#include <linux/netdevice.h>
+#include <linux/if_ether.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -42,6 +44,7 @@
 
 #include <plat/board.h>
 #include <plat/common.h>
+#include <mach/id.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
 #include <plat/gpmc.h>
@@ -91,6 +94,90 @@ static struct {
 	.usr_button_gpio = 4,
 };
 
+/*
+ * This device path represents the onboard USB <-> Ethernet bridge
+ * on the BeagleBoard-xM which needs a random or all-zeros
+ * mac address replaced with a per-cpu stable generated one
+ */
+
+static const char * const xm_fixup_mac_device_paths[] = {
+	"usb1/1-2/1-2.1/1-2.1:1.0",
+};
+
+static int beagle_device_path_need_mac(struct device *dev)
+{
+	const char **try = (const char **) xm_fixup_mac_device_paths;
+	const char *path;
+	int count = ARRAY_SIZE(xm_fixup_mac_device_paths);
+	const char *p;
+	int len;
+	struct device *devn;
+
+	while (count--) {
+
+		p = *try + strlen(*try);
+		devn = dev;
+
+		while (devn) {
+
+			path = dev_name(devn);
+			len = strlen(path);
+
+			if ((p - *try) < len) {
+				devn = NULL;
+				continue;
+			}
+
+			p -= len;
+
+			if (strncmp(path, p, len)) {
+				devn = NULL;
+				continue;
+			}
+
+			devn = devn->parent;
+			if (p == *try)
+				return count;
+
+			if (devn != NULL && (p - *try) < 2)
+				devn = NULL;
+
+			p--;
+			if (devn != NULL && *p != '/')
+				devn = NULL;
+		}
+
+		try++;
+	}
+
+	return -ENOENT;
+}
+
+static int omap_beagle_netdev_event(struct notifier_block *this,
+						 unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+	struct sockaddr sa;
+	int n;
+
+	if (event != NETDEV_REGISTER)
+		return NOTIFY_DONE;
+
+	n = beagle_device_path_need_mac(dev->dev.parent);
+	if (n >= 0) {
+		sa.sa_family = dev->type;
+		omap2_die_id_to_ethernet_mac(sa.sa_data, n);
+		dev->netdev_ops->ndo_set_mac_address(dev, &sa);
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block omap_beagle_netdev_notifier = {
+	.notifier_call = omap_beagle_netdev_event,
+	.priority = 1,
+};
+
 static struct gpio omap3_beagle_rev_gpios[] __initdata = {
 	{ 171, GPIOF_IN, "rev_id_0"    },
 	{ 172, GPIOF_IN, "rev_id_1" },
@@ -146,14 +233,17 @@ static void __init omap3_beagle_init_rev(void)
 		printk(KERN_INFO "OMAP3 Beagle Rev: xM Ax/Bx\n");
 		omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
 		beagle_config.usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+		register_netdevice_notifier(&omap_beagle_netdev_notifier);
 		break;
 	case 2:
 		printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
 		omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+		register_netdevice_notifier(&omap_beagle_netdev_notifier);
 		break;
 	default:
 		printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
 		omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+		register_netdevice_notifier(&omap_beagle_netdev_notifier);
 	}
 }
 
-- 
1.7.4.1