summaryrefslogtreecommitdiffstats
path: root/net/eth.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2013-05-18 13:30:25 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2013-05-21 09:36:27 +0200
commit2995752d758df5ba5fc41f69e4a61ebb51e4366f (patch)
treef561fe94e04f4c7cc063dfcbdb28f7bced10e6c9 /net/eth.c
parent4cbec978bcc23c8c67eea713abdc2d132a9cd3dd (diff)
downloadbarebox-2995752d758df5ba5fc41f69e4a61ebb51e4366f.tar.gz
barebox-2995752d758df5ba5fc41f69e4a61ebb51e4366f.tar.xz
net: Add of_register_ethaddr
We already have a possibility to register a MAC address provider based on a ethernet device id. This adds a similar functionality for devices probed from devicetree. Code can register itself to be a MAC address provider for a certain devicetree node. This helps on i.MX to let the IIM unit provide a MAC address for the FEC. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'net/eth.c')
-rw-r--r--net/eth.c68
1 files changed, 56 insertions, 12 deletions
diff --git a/net/eth.c b/net/eth.c
index 4646dd8b89..bea7b12b41 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -36,16 +36,34 @@ struct eth_ethaddr {
struct list_head list;
u8 ethaddr[6];
int ethid;
+ struct device_node *node;
};
static LIST_HEAD(ethaddr_list);
-static int eth_get_registered_ethaddr(int ethid, void *buf)
+static void register_preset_mac_address(struct eth_device *edev, const char *ethaddr)
+{
+ unsigned char ethaddr_str[sizeof("xx:xx:xx:xx:xx:xx")];
+
+ ethaddr_to_string(ethaddr, ethaddr_str);
+
+ if (is_valid_ether_addr(ethaddr)) {
+ dev_info(&edev->dev, "got preset MAC address: %s\n", ethaddr_str);
+ dev_set_param(&edev->dev, "ethaddr", ethaddr_str);
+ }
+}
+
+static int eth_get_registered_ethaddr(struct eth_device *edev, void *buf)
{
struct eth_ethaddr *addr;
+ struct device_node *node = NULL;
+
+ if (edev->parent)
+ node = edev->parent->device_node;
list_for_each_entry(addr, &ethaddr_list, list) {
- if (addr->ethid == ethid) {
+ if ((node && node == addr->node) ||
+ addr->ethid == edev->dev.id) {
memcpy(buf, addr->ethaddr, 6);
return 0;
}
@@ -78,6 +96,38 @@ void eth_register_ethaddr(int ethid, const char *ethaddr)
list_add_tail(&addr->list, &ethaddr_list);
}
+static struct eth_device *eth_get_by_node(struct device_node *node)
+{
+ struct eth_device *edev;
+
+ list_for_each_entry(edev, &netdev_list, list) {
+ if (!edev->parent)
+ continue;
+ if (!edev->parent->device_node)
+ continue;
+ if (edev->parent->device_node == node)
+ return edev;
+ }
+ return NULL;
+}
+
+void of_eth_register_ethaddr(struct device_node *node, const char *ethaddr)
+{
+ struct eth_ethaddr *addr;
+ struct eth_device *edev;
+
+ edev = eth_get_by_node(node);
+ if (edev) {
+ register_preset_mac_address(edev, ethaddr);
+ return;
+ }
+
+ addr = xzalloc(sizeof(*addr));
+ addr->node = node;
+ memcpy(addr->ethaddr, ethaddr, 6);
+ list_add_tail(&addr->list, &ethaddr_list);
+}
+
void eth_set_current(struct eth_device *eth)
{
if (eth_current && eth_current->active) {
@@ -225,8 +275,7 @@ static int eth_set_ethaddr(struct device_d *dev, struct param_d *param, const ch
int eth_register(struct eth_device *edev)
{
- struct device_d *dev = &edev->dev;
- unsigned char ethaddr_str[20];
+ struct device_d *dev = &edev->dev;
unsigned char ethaddr[6];
int ret, found = 0;
@@ -254,7 +303,7 @@ int eth_register(struct eth_device *edev)
list_add_tail(&edev->list, &netdev_list);
- ret = eth_get_registered_ethaddr(dev->id, ethaddr);
+ ret = eth_get_registered_ethaddr(edev, ethaddr);
if (!ret)
found = 1;
@@ -264,13 +313,8 @@ int eth_register(struct eth_device *edev)
found = 1;
}
- if (found) {
- ethaddr_to_string(ethaddr, ethaddr_str);
- if (is_valid_ether_addr(ethaddr)) {
- dev_info(dev, "got preset MAC address: %s\n", ethaddr_str);
- dev_set_param(dev, "ethaddr", ethaddr_str);
- }
- }
+ if (found)
+ register_preset_mac_address(edev, ethaddr);
if (!eth_current)
eth_current = edev;