summaryrefslogtreecommitdiffstats
path: root/net/eth.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/eth.c')
-rw-r--r--net/eth.c111
1 files changed, 75 insertions, 36 deletions
diff --git a/net/eth.c b/net/eth.c
index bc641dc8e4..28961e868b 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -10,6 +10,7 @@
#include <dhcp.h>
#include <net.h>
#include <dma.h>
+#include <machine_id.h>
#include <of.h>
#include <of_net.h>
#include <linux/phy.h>
@@ -20,8 +21,6 @@
#include <linux/ctype.h>
#include <linux/stat.h>
-static uint64_t last_link_check;
-
LIST_HEAD(netdev_list);
struct eth_ethaddr {
@@ -33,6 +32,14 @@ struct eth_ethaddr {
static LIST_HEAD(ethaddr_list);
+int eth_set_promisc(struct eth_device *edev, bool enable)
+{
+ if (!edev->set_promisc)
+ return -EOPNOTSUPP;
+
+ return edev->set_promisc(edev, enable);
+}
+
int eth_set_ethaddr(struct eth_device *edev, const char *ethaddr)
{
int ret;
@@ -48,11 +55,8 @@ int eth_set_ethaddr(struct eth_device *edev, const char *ethaddr)
static void register_preset_mac_address(struct eth_device *edev, const char *ethaddr)
{
- unsigned char ethaddr_str[sizeof("xx:xx:xx:xx:xx:xx")];
-
if (is_valid_ether_addr(ethaddr)) {
- ethaddr_to_string(ethaddr, ethaddr_str);
- dev_info(&edev->dev, "got preset MAC address: %s\n", ethaddr_str);
+ dev_info(&edev->dev, "got preset MAC address: %pM\n", ethaddr);
eth_set_ethaddr(edev, ethaddr);
}
}
@@ -63,7 +67,7 @@ static int eth_get_registered_ethaddr(struct eth_device *edev, void *buf)
struct device_node *node = NULL;
if (edev->parent)
- node = edev->parent->device_node;
+ node = edev->parent->of_node;
list_for_each_entry(addr, &ethaddr_list, list) {
if ((node && node == addr->node) ||
@@ -115,9 +119,9 @@ static struct eth_device *eth_get_by_node(struct device_node *node)
for_each_netdev(edev) {
if (!edev->parent)
continue;
- if (!edev->parent->device_node)
+ if (!edev->parent->of_node)
continue;
- if (edev->parent->device_node == node)
+ if (edev->parent->of_node == node)
return edev;
}
return NULL;
@@ -170,28 +174,42 @@ int eth_complete(struct string_list *sl, char *instr)
}
#endif
+int eth_carrier_poll_once(struct eth_device *edev)
+{
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_PHYLIB))
+ return 0;
+
+ if (!edev->phydev)
+ return 0;
+
+ ret = phy_update_status(edev->phydev);
+ if (ret)
+ return ret;
+
+ edev->last_link_check = get_time_ns();
+ return edev->phydev->link ? 0 : -ENETDOWN;
+}
+
/*
* Check for link if we haven't done so for longer.
*/
-static int eth_carrier_check(struct eth_device *edev, int force)
+static int eth_carrier_check(struct eth_device *edev, bool may_wait)
{
- int ret;
-
if (!IS_ENABLED(CONFIG_PHYLIB))
return 0;
if (!edev->phydev)
return 0;
- if (force)
- phy_wait_aneg_done(edev->phydev);
+ if (!edev->last_link_check ||
+ is_timeout(edev->last_link_check, 5 * SECOND))
+ eth_carrier_poll_once(edev);
- if (force || is_timeout(last_link_check, 5 * SECOND) ||
- !edev->phydev->link) {
- ret = phy_update_status(edev->phydev);
- if (ret)
- return ret;
- last_link_check = get_time_ns();
+ if (may_wait && !edev->phydev->link) {
+ phy_wait_aneg_done(edev->phydev);
+ edev->last_link_check = get_time_ns();
}
return edev->phydev->link ? 0 : -ENETDOWN;
@@ -237,7 +255,7 @@ int eth_send(struct eth_device *edev, void *packet, int length)
if (slice_acquired(eth_device_slice(edev)))
return eth_queue(edev, packet, length);
- ret = eth_carrier_check(edev, 0);
+ ret = eth_carrier_check(edev, true);
if (ret)
return ret;
@@ -258,7 +276,7 @@ static void eth_do_work(struct eth_device *edev)
int ret;
if (!phy_acquired(edev->phydev)) {
- ret = eth_carrier_check(edev, 0);
+ ret = eth_carrier_check(edev, false);
if (ret)
return;
}
@@ -377,7 +395,7 @@ static const char * const eth_mode_names[] = {
int eth_register(struct eth_device *edev)
{
- struct device_d *dev = &edev->dev;
+ struct device *dev = &edev->dev;
unsigned char ethaddr[ETH_ALEN];
int ret, found = 0;
@@ -391,8 +409,9 @@ int eth_register(struct eth_device *edev)
if (edev->parent)
edev->dev.parent = edev->parent;
- if (edev->dev.parent && edev->dev.parent->device_node) {
- edev->dev.id = of_alias_get_id(edev->dev.parent->device_node, "ethernet");
+ if (edev->dev.parent && edev->dev.parent->of_node) {
+ edev->dev.id = of_alias_get_id(edev->dev.parent->of_node,
+ "ethernet");
if (edev->dev.id < 0)
edev->dev.id = DEVICE_ID_DYNAMIC;
} else {
@@ -442,8 +461,8 @@ int eth_register(struct eth_device *edev)
register_preset_mac_address(edev, ethaddr);
if (IS_ENABLED(CONFIG_OFDEVICE) && edev->parent &&
- edev->parent->device_node)
- edev->nodepath = xstrdup(edev->parent->device_node->full_name);
+ edev->parent->of_node)
+ edev->nodepath = xstrdup(edev->parent->of_node->full_name);
return 0;
}
@@ -455,12 +474,12 @@ int eth_open(struct eth_device *edev)
if (edev->active)
return 0;
+ edev->last_link_check = 0;
+
ret = edev->open(edev);
if (!ret)
edev->active = 1;
- eth_carrier_check(edev, 1);
-
return ret;
}
@@ -516,31 +535,51 @@ struct eth_device *of_find_eth_device_by_node(struct device_node *np)
return NULL;
list_for_each_entry(edev, &netdev_list, list)
- if (edev->parent->device_node == np)
+ if (edev->parent->of_node == np)
return edev;
return NULL;
}
EXPORT_SYMBOL(of_find_eth_device_by_node);
-static int of_populate_ethaddr(void)
+void eth_open_all(void)
{
- char str[sizeof("xx:xx:xx:xx:xx:xx")];
struct eth_device *edev;
+
+ list_for_each_entry(edev, &netdev_list, list) {
+ if (edev->global_mode == ETH_MODE_DISABLED)
+ continue;
+ eth_open(edev);
+ }
+}
+
+static int populate_ethaddr(void)
+{
+ struct eth_device *edev;
+ bool generated = false;
int ret;
list_for_each_entry(edev, &netdev_list, list) {
if (!edev->parent || is_valid_ether_addr(edev->ethaddr))
continue;
- ret = of_get_mac_addr_nvmem(edev->parent->device_node, edev->ethaddr);
+ ret = of_get_mac_addr_nvmem(edev->parent->of_node,
+ edev->ethaddr);
+ if (IS_ENABLED(CONFIG_NET_ETHADDR_FROM_MACHINE_ID) && ret) {
+ ret = generate_ether_addr(edev->ethaddr, edev->dev.id);
+ generated = true;
+ }
if (ret)
continue;
- ethaddr_to_string(edev->ethaddr, str);
- dev_info(&edev->dev, "Got preset MAC address from device tree: %s\n", str);
+ if (generated)
+ dev_notice(&edev->dev, "Generated MAC address from unique id: %pM\n",
+ edev->ethaddr);
+ else
+ dev_info(&edev->dev, "Got preset MAC address from NVMEM: %pM\n",
+ edev->ethaddr);
eth_set_ethaddr(edev, edev->ethaddr);
}
return 0;
}
-postenvironment_initcall(of_populate_ethaddr);
+postenvironment_initcall(populate_ethaddr);