diff options
author | David S. Miller <davem@davemloft.net> | 2018-03-30 10:40:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-30 10:40:19 -0400 |
commit | caeeeda3444b1339dca8be22aa09e1441f90e6b7 (patch) | |
tree | aa8828a2e9f4807236056d98097c89e6c075a307 | |
parent | 64e828dfc4853a396d2c0b25c22a4c5066aab76a (diff) | |
parent | aa076e3d220a7d2e71ef0f5213bdbbcc7e351b86 (diff) |
Merge branch 'Implement-of_get_nvmem_mac_address-helper'
Mike Looijmans says:
====================
of_net: Implement of_get_nvmem_mac_address helper
Posted this as a small set now, with an (optional) second patch that shows
how the changes work and what I've used to test the code on a Topic Miami board.
I've taken the liberty to add appropriate "Acked" and "Review" tags.
v4: Replaced "6" with ETH_ALEN
v3: Add patch that implements mac in nvmem for the Cadence MACB controller
Remove the integrated of_get_mac_address call
v2: Use of_nvmem_cell_get to avoid needing the assiciated device
Use void* instead of char*
Add devicetree binding doc
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/devicetree/bindings/net/ethernet.txt | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/cadence/macb_main.c | 12 | ||||
-rw-r--r-- | drivers/of/of_net.c | 40 | ||||
-rw-r--r-- | include/linux/of_net.h | 6 |
4 files changed, 57 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt index 2974e63ba311..cfc376bc977a 100644 --- a/Documentation/devicetree/bindings/net/ethernet.txt +++ b/Documentation/devicetree/bindings/net/ethernet.txt | |||
@@ -10,6 +10,8 @@ Documentation/devicetree/bindings/phy/phy-bindings.txt. | |||
10 | the boot program; should be used in cases where the MAC address assigned to | 10 | the boot program; should be used in cases where the MAC address assigned to |
11 | the device by the boot program is different from the "local-mac-address" | 11 | the device by the boot program is different from the "local-mac-address" |
12 | property; | 12 | property; |
13 | - nvmem-cells: phandle, reference to an nvmem node for the MAC address; | ||
14 | - nvmem-cell-names: string, should be "mac-address" if nvmem is to be used; | ||
13 | - max-speed: number, specifies maximum speed in Mbit/s supported by the device; | 15 | - max-speed: number, specifies maximum speed in Mbit/s supported by the device; |
14 | - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than | 16 | - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than |
15 | the maximum frame size (there's contradiction in the Devicetree | 17 | the maximum frame size (there's contradiction in the Devicetree |
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index d09bd43680b3..b4c9268100bb 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c | |||
@@ -3952,10 +3952,16 @@ static int macb_probe(struct platform_device *pdev) | |||
3952 | dev->max_mtu = ETH_DATA_LEN; | 3952 | dev->max_mtu = ETH_DATA_LEN; |
3953 | 3953 | ||
3954 | mac = of_get_mac_address(np); | 3954 | mac = of_get_mac_address(np); |
3955 | if (mac) | 3955 | if (mac) { |
3956 | ether_addr_copy(bp->dev->dev_addr, mac); | 3956 | ether_addr_copy(bp->dev->dev_addr, mac); |
3957 | else | 3957 | } else { |
3958 | macb_get_hwaddr(bp); | 3958 | err = of_get_nvmem_mac_address(np, bp->dev->dev_addr); |
3959 | if (err) { | ||
3960 | if (err == -EPROBE_DEFER) | ||
3961 | goto err_out_free_netdev; | ||
3962 | macb_get_hwaddr(bp); | ||
3963 | } | ||
3964 | } | ||
3959 | 3965 | ||
3960 | err = of_get_phy_mode(np); | 3966 | err = of_get_phy_mode(np); |
3961 | if (err < 0) { | 3967 | if (err < 0) { |
diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c index d820f3edd431..53189d4022a6 100644 --- a/drivers/of/of_net.c +++ b/drivers/of/of_net.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | #include <linux/etherdevice.h> | 8 | #include <linux/etherdevice.h> |
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/nvmem-consumer.h> | ||
10 | #include <linux/of_net.h> | 11 | #include <linux/of_net.h> |
11 | #include <linux/phy.h> | 12 | #include <linux/phy.h> |
12 | #include <linux/export.h> | 13 | #include <linux/export.h> |
@@ -80,3 +81,42 @@ const void *of_get_mac_address(struct device_node *np) | |||
80 | return of_get_mac_addr(np, "address"); | 81 | return of_get_mac_addr(np, "address"); |
81 | } | 82 | } |
82 | EXPORT_SYMBOL(of_get_mac_address); | 83 | 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); | ||
diff --git a/include/linux/of_net.h b/include/linux/of_net.h index 9cd72aab76fe..90d81ee9e6a0 100644 --- a/include/linux/of_net.h +++ b/include/linux/of_net.h | |||
@@ -13,6 +13,7 @@ | |||
13 | struct net_device; | 13 | struct net_device; |
14 | extern int of_get_phy_mode(struct device_node *np); | 14 | extern int of_get_phy_mode(struct device_node *np); |
15 | extern const void *of_get_mac_address(struct device_node *np); | 15 | extern const void *of_get_mac_address(struct device_node *np); |
16 | extern int of_get_nvmem_mac_address(struct device_node *np, void *addr); | ||
16 | extern struct net_device *of_find_net_device_by_node(struct device_node *np); | 17 | extern struct net_device *of_find_net_device_by_node(struct device_node *np); |
17 | #else | 18 | #else |
18 | static inline int of_get_phy_mode(struct device_node *np) | 19 | static inline int of_get_phy_mode(struct device_node *np) |
@@ -25,6 +26,11 @@ static inline const void *of_get_mac_address(struct device_node *np) | |||
25 | return NULL; | 26 | return NULL; |
26 | } | 27 | } |
27 | 28 | ||
29 | static inline int of_get_nvmem_mac_address(struct device_node *np, void *addr) | ||
30 | { | ||
31 | return -ENODEV; | ||
32 | } | ||
33 | |||
28 | static inline struct net_device *of_find_net_device_by_node(struct device_node *np) | 34 | static inline struct net_device *of_find_net_device_by_node(struct device_node *np) |
29 | { | 35 | { |
30 | return NULL; | 36 | return NULL; |