hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/of/of_net.c
....@@ -1,29 +1,33 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * OF helpers for network devices.
3
- *
4
- * This file is released under the GPLv2
54 *
65 * Initially copied out of arch/powerpc/kernel/prom_parse.c
76 */
87 #include <linux/etherdevice.h>
98 #include <linux/kernel.h>
10
-#include <linux/nvmem-consumer.h>
119 #include <linux/of_net.h>
10
+#include <linux/of_platform.h>
1211 #include <linux/phy.h>
1312 #include <linux/export.h>
13
+#include <linux/device.h>
1414
1515 /**
1616 * of_get_phy_mode - Get phy mode for given device_node
1717 * @np: Pointer to the given device_node
18
+ * @interface: Pointer to the result
1819 *
1920 * The function gets phy interface string from property 'phy-mode' or
20
- * 'phy-connection-type', and return its index in phy_modes table, or errno in
21
- * error case.
21
+ * 'phy-connection-type'. The index in phy_modes table is set in
22
+ * interface and 0 returned. In case of error interface is set to
23
+ * PHY_INTERFACE_MODE_NA and an errno is returned, e.g. -ENODEV.
2224 */
23
-int of_get_phy_mode(struct device_node *np)
25
+int of_get_phy_mode(struct device_node *np, phy_interface_t *interface)
2426 {
2527 const char *pm;
2628 int err, i;
29
+
30
+ *interface = PHY_INTERFACE_MODE_NA;
2731
2832 err = of_property_read_string(np, "phy-mode", &pm);
2933 if (err < 0)
....@@ -32,8 +36,10 @@
3236 return err;
3337
3438 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
35
- if (!strcasecmp(pm, phy_modes(i)))
36
- return i;
39
+ if (!strcasecmp(pm, phy_modes(i))) {
40
+ *interface = i;
41
+ return 0;
42
+ }
3743
3844 return -ENODEV;
3945 }
....@@ -48,12 +54,38 @@
4854 return NULL;
4955 }
5056
57
+static const void *of_get_mac_addr_nvmem(struct device_node *np)
58
+{
59
+ int ret;
60
+ const void *mac;
61
+ u8 nvmem_mac[ETH_ALEN];
62
+ struct platform_device *pdev = of_find_device_by_node(np);
63
+
64
+ if (!pdev)
65
+ return ERR_PTR(-ENODEV);
66
+
67
+ ret = nvmem_get_mac_address(&pdev->dev, &nvmem_mac);
68
+ if (ret) {
69
+ put_device(&pdev->dev);
70
+ return ERR_PTR(ret);
71
+ }
72
+
73
+ mac = devm_kmemdup(&pdev->dev, nvmem_mac, ETH_ALEN, GFP_KERNEL);
74
+ put_device(&pdev->dev);
75
+ if (!mac)
76
+ return ERR_PTR(-ENOMEM);
77
+
78
+ return mac;
79
+}
80
+
5181 /**
5282 * Search the device tree for the best MAC address to use. 'mac-address' is
5383 * checked first, because that is supposed to contain to "most recent" MAC
5484 * address. If that isn't set, then 'local-mac-address' is checked next,
55
- * because that is the default address. If that isn't set, then the obsolete
56
- * 'address' is checked, just in case we're using an old device tree.
85
+ * because that is the default address. If that isn't set, then the obsolete
86
+ * 'address' is checked, just in case we're using an old device tree. If any
87
+ * of the above isn't set, then try to get MAC address from nvmem cell named
88
+ * 'mac-address'.
5789 *
5890 * Note that the 'address' property is supposed to contain a virtual address of
5991 * the register set, but some DTS files have redefined that property to be the
....@@ -65,6 +97,8 @@
6597 * addresses. Some older U-Boots only initialized 'local-mac-address'. In
6698 * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
6799 * but is all zeros.
100
+ *
101
+ * Return: Will be a valid pointer on success and ERR_PTR in case of error.
68102 */
69103 const void *of_get_mac_address(struct device_node *np)
70104 {
....@@ -78,45 +112,10 @@
78112 if (addr)
79113 return addr;
80114
81
- return of_get_mac_addr(np, "address");
115
+ addr = of_get_mac_addr(np, "address");
116
+ if (addr)
117
+ return addr;
118
+
119
+ return of_get_mac_addr_nvmem(np);
82120 }
83121 EXPORT_SYMBOL(of_get_mac_address);
84
-
85
-/**
86
- * Obtain the MAC address from an nvmem provider named 'mac-address' through
87
- * device tree.
88
- * On success, copies the new address into memory pointed to by addr and
89
- * returns 0. Returns a negative error code otherwise.
90
- * @np: Device tree node containing the nvmem-cells phandle
91
- * @addr: Pointer to receive the MAC address using ether_addr_copy()
92
- */
93
-int of_get_nvmem_mac_address(struct device_node *np, void *addr)
94
-{
95
- struct nvmem_cell *cell;
96
- const void *mac;
97
- size_t len;
98
- int ret;
99
-
100
- cell = of_nvmem_cell_get(np, "mac-address");
101
- if (IS_ERR(cell))
102
- return PTR_ERR(cell);
103
-
104
- mac = nvmem_cell_read(cell, &len);
105
-
106
- nvmem_cell_put(cell);
107
-
108
- if (IS_ERR(mac))
109
- return PTR_ERR(mac);
110
-
111
- if (len < ETH_ALEN || !is_valid_ether_addr(mac)) {
112
- ret = -EINVAL;
113
- } else {
114
- ether_addr_copy(addr, mac);
115
- ret = 0;
116
- }
117
-
118
- kfree(mac);
119
-
120
- return ret;
121
-}
122
-EXPORT_SYMBOL(of_get_nvmem_mac_address);