Openwrt/target/linux/generic/pending-4.19/681-NET-add-of_get_mac_address_mtd.patch
Hauke Mehrtens 52a82ce3dd kernel: Copy patches from kernel 4.14 to 4.19
This just copies the files from the kernel 4.14 specific folders into
the kernel 4.19 specific folder, no changes are done to the files in
this commit.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2018-12-15 12:50:06 +01:00

134 lines
3.5 KiB
Diff

From: John Crispin <blogic@openwrt.org>
Subject: NET: add mtd-mac-address support to of_get_mac_address()
Many embedded devices have information such as mac addresses stored inside mtd
devices. This patch allows us to add a property inside a node describing a
network interface. The new property points at a mtd partition with an offset
where the mac address can be found.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/of/of_net.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/of_net.h | 1 +
2 files changed, 38 insertions(+)
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -10,6 +10,7 @@
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/export.h>
+#include <linux/mtd/mtd.h>
/**
* of_get_phy_mode - Get phy mode for given device_node
@@ -38,7 +39,7 @@ int of_get_phy_mode(struct device_node *
}
EXPORT_SYMBOL_GPL(of_get_phy_mode);
-static const void *of_get_mac_addr(struct device_node *np, const char *name)
+static void *of_get_mac_addr(struct device_node *np, const char *name)
{
struct property *pp = of_find_property(np, name, NULL);
@@ -47,6 +48,79 @@ static const void *of_get_mac_addr(struc
return NULL;
}
+static const void *of_get_mac_address_mtd(struct device_node *np)
+{
+#ifdef CONFIG_MTD
+ struct device_node *mtd_np = NULL;
+ struct property *prop;
+ size_t retlen;
+ int size, ret;
+ struct mtd_info *mtd;
+ const char *part;
+ const __be32 *list;
+ phandle phandle;
+ u32 mac_inc = 0;
+ u8 mac[ETH_ALEN];
+ void *addr;
+ u32 inc_idx;
+
+ list = of_get_property(np, "mtd-mac-address", &size);
+ if (!list || (size != (2 * sizeof(*list))))
+ return NULL;
+
+ phandle = be32_to_cpup(list++);
+ if (phandle)
+ mtd_np = of_find_node_by_phandle(phandle);
+
+ if (!mtd_np)
+ return NULL;
+
+ part = of_get_property(mtd_np, "label", NULL);
+ if (!part)
+ part = mtd_np->name;
+
+ mtd = get_mtd_device_nm(part);
+ if (IS_ERR(mtd))
+ return NULL;
+
+ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, mac);
+ put_mtd_device(mtd);
+
+ if (of_property_read_u32(np, "mtd-mac-address-increment-byte", &inc_idx))
+ inc_idx = 5;
+ if (inc_idx > 5)
+ return NULL;
+
+ if (!of_property_read_u32(np, "mtd-mac-address-increment", &mac_inc))
+ mac[inc_idx] += mac_inc;
+
+ if (!is_valid_ether_addr(mac))
+ return NULL;
+
+ addr = of_get_mac_addr(np, "mac-address");
+ if (addr) {
+ memcpy(addr, mac, ETH_ALEN);
+ return addr;
+ }
+
+ prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+ if (!prop)
+ return NULL;
+
+ prop->name = "mac-address";
+ prop->length = ETH_ALEN;
+ prop->value = kmemdup(mac, ETH_ALEN, GFP_KERNEL);
+ if (!prop->value || of_add_property(np, prop))
+ goto free;
+
+ return prop->value;
+free:
+ kfree(prop->value);
+ kfree(prop);
+#endif
+ return NULL;
+}
+
/**
* Search the device tree for the best MAC address to use. 'mac-address' is
* checked first, because that is supposed to contain to "most recent" MAC
@@ -64,11 +138,18 @@ static const void *of_get_mac_addr(struc
* addresses. Some older U-Boots only initialized 'local-mac-address'. In
* this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
* but is all zeros.
+ *
+ * If a mtd-mac-address property exists, try to fetch the MAC address from the
+ * specified mtd device, and store it as a 'mac-address' property
*/
const void *of_get_mac_address(struct device_node *np)
{
const void *addr;
+ addr = of_get_mac_address_mtd(np);
+ if (addr)
+ return addr;
+
addr = of_get_mac_addr(np, "mac-address");
if (addr)
return addr;