0001
0002
0003
0004
0005
0006
0007 #include <linux/etherdevice.h>
0008 #include <linux/kernel.h>
0009 #include <linux/of_net.h>
0010 #include <linux/of_platform.h>
0011 #include <linux/phy.h>
0012 #include <linux/export.h>
0013 #include <linux/device.h>
0014 #include <linux/nvmem-consumer.h>
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 int of_get_phy_mode(struct device_node *np, phy_interface_t *interface)
0027 {
0028 const char *pm;
0029 int err, i;
0030
0031 *interface = PHY_INTERFACE_MODE_NA;
0032
0033 err = of_property_read_string(np, "phy-mode", &pm);
0034 if (err < 0)
0035 err = of_property_read_string(np, "phy-connection-type", &pm);
0036 if (err < 0)
0037 return err;
0038
0039 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
0040 if (!strcasecmp(pm, phy_modes(i))) {
0041 *interface = i;
0042 return 0;
0043 }
0044
0045 return -ENODEV;
0046 }
0047 EXPORT_SYMBOL_GPL(of_get_phy_mode);
0048
0049 static int of_get_mac_addr(struct device_node *np, const char *name, u8 *addr)
0050 {
0051 struct property *pp = of_find_property(np, name, NULL);
0052
0053 if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value)) {
0054 memcpy(addr, pp->value, ETH_ALEN);
0055 return 0;
0056 }
0057 return -ENODEV;
0058 }
0059
0060 static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
0061 {
0062 struct platform_device *pdev = of_find_device_by_node(np);
0063 struct nvmem_cell *cell;
0064 const void *mac;
0065 size_t len;
0066 int ret;
0067
0068
0069
0070
0071 if (pdev) {
0072 ret = nvmem_get_mac_address(&pdev->dev, addr);
0073 put_device(&pdev->dev);
0074 return ret;
0075 }
0076
0077 cell = of_nvmem_cell_get(np, "mac-address");
0078 if (IS_ERR(cell))
0079 return PTR_ERR(cell);
0080
0081 mac = nvmem_cell_read(cell, &len);
0082 nvmem_cell_put(cell);
0083
0084 if (IS_ERR(mac))
0085 return PTR_ERR(mac);
0086
0087 if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
0088 kfree(mac);
0089 return -EINVAL;
0090 }
0091
0092 memcpy(addr, mac, ETH_ALEN);
0093 kfree(mac);
0094
0095 return 0;
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 int of_get_mac_address(struct device_node *np, u8 *addr)
0125 {
0126 int ret;
0127
0128 if (!np)
0129 return -ENODEV;
0130
0131 ret = of_get_mac_addr(np, "mac-address", addr);
0132 if (!ret)
0133 return 0;
0134
0135 ret = of_get_mac_addr(np, "local-mac-address", addr);
0136 if (!ret)
0137 return 0;
0138
0139 ret = of_get_mac_addr(np, "address", addr);
0140 if (!ret)
0141 return 0;
0142
0143 return of_get_mac_addr_nvmem(np, addr);
0144 }
0145 EXPORT_SYMBOL(of_get_mac_address);
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 int of_get_ethdev_address(struct device_node *np, struct net_device *dev)
0161 {
0162 u8 addr[ETH_ALEN];
0163 int ret;
0164
0165 ret = of_get_mac_address(np, addr);
0166 if (!ret)
0167 eth_hw_addr_set(dev, addr);
0168 return ret;
0169 }
0170 EXPORT_SYMBOL(of_get_ethdev_address);