8849afb4d605b199083a052205edfeb247dc7a72
[openwrt/staging/mkresin.git] / target / linux / ath79 / patches-5.10 / 600-of_net-add-mac-address-ascii-support.patch
1 Index: linux-5.15.31/net/ethernet/eth.c
2 ===================================================================
3 --- linux-5.15.31.orig/net/ethernet/eth.c
4 +++ linux-5.15.31/net/ethernet/eth.c
5 @@ -544,6 +544,63 @@ int eth_platform_get_mac_address(struct
6 }
7 EXPORT_SYMBOL(eth_platform_get_mac_address);
8
9 +static void *nvmem_cell_get_mac_address(struct nvmem_cell *cell)
10 +{
11 + size_t len;
12 + void *mac;
13 +
14 + mac = nvmem_cell_read(cell, &len);
15 + if (IS_ERR(mac))
16 + return PTR_ERR(mac);
17 + if (len != ETH_ALEN) {
18 + kfree(mac);
19 + return ERR_PTR(-EINVAL);
20 + }
21 + return mac;
22 +}
23 +
24 +static void *nvmem_cell_get_mac_address_ascii(struct nvmem_cell *cell)
25 +{
26 + size_t len;
27 + int ret;
28 + void *mac_ascii;
29 + u8 *mac;
30 +
31 + mac_ascii = nvmem_cell_read(cell, &len);
32 + if (IS_ERR(mac_ascii))
33 + return PTR_ERR(mac_ascii);
34 + if (len != ETH_ALEN*2+5) {
35 + kfree(mac_ascii);
36 + return ERR_PTR(-EINVAL);
37 + }
38 + mac = kmalloc(ETH_ALEN, GFP_KERNEL);
39 + if (!mac) {
40 + kfree(mac_ascii);
41 + return ERR_PTR(-ENOMEM);
42 + }
43 + ret = sscanf(mac_ascii, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
44 + &mac[0], &mac[1], &mac[2],
45 + &mac[3], &mac[4], &mac[5]);
46 + kfree(mac_ascii);
47 + if (ret == ETH_ALEN)
48 + return mac;
49 + kfree(mac);
50 + return ERR_PTR(-EINVAL);
51 +}
52 +
53 +static struct nvmem_cell_mac_address_property {
54 + char *name;
55 + void *(*read)(struct nvmem_cell *);
56 +} nvmem_cell_mac_address_properties[] = {
57 + {
58 + .name = "mac-address",
59 + .read = nvmem_cell_get_mac_address,
60 + }, {
61 + .name = "mac-address-ascii",
62 + .read = nvmem_cell_get_mac_address_ascii,
63 + },
64 +};
65 +
66 /**
67 * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
68 * 'mac-address' associated with given device.
69 @@ -557,19 +614,23 @@ int nvmem_get_mac_address(struct device
70 {
71 struct nvmem_cell *cell;
72 const void *mac;
73 - size_t len;
74 + struct nvmem_cell_mac_address_property *property;
75 + int i;
76
77 - cell = nvmem_cell_get(dev, "mac-address");
78 - if (IS_ERR(cell))
79 - return PTR_ERR(cell);
80 -
81 - mac = nvmem_cell_read(cell, &len);
82 - nvmem_cell_put(cell);
83 -
84 - if (IS_ERR(mac))
85 - return PTR_ERR(mac);
86 + for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
87 + property = &nvmem_cell_mac_address_properties[i];
88 + cell = nvmem_cell_get(dev, property->name);
89 + if (IS_ERR(cell)) {
90 + if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1)
91 + return PTR_ERR(cell);
92 + continue;
93 + }
94 + mac = property->read(cell);
95 + nvmem_cell_put(cell);
96 + break;
97 + }
98
99 - if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
100 + if (!is_valid_ether_addr(mac)) {
101 kfree(mac);
102 return -EINVAL;
103 }