* Re: [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
@ 2018-07-19 8:48 ` Dan Carpenter
0 siblings, 0 replies; 24+ messages in thread
From: Dan Carpenter @ 2018-07-19 8:48 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Sekhar Nori, Kevin Hilman, Russell King, Grygorii Strashko,
David S . Miller, Srinivas Kandagatla, Lukas Wunner, Rob Herring,
Florian Fainelli, Ivan Khoronzhuk, David Lechner,
Greg Kroah-Hartman, Andrew Lunn, linux-arm-kernel, linux-kernel,
linux-omap, netdev, Bartosz Golaszewski
On Thu, Jul 19, 2018 at 10:20:27AM +0200, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
> Many non-DT platforms read the MAC address from EEPROM. Usually it's
> either done with callbacks defined in board files or from SoC-specific
> ethernet drivers.
>
> In order to generalize this, try to read the MAC from nvmem in
> eth_platform_get_mac_address() using a standard lookup name:
> "mac-address".
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
> net/ethernet/eth.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index 39af03894598..af3b4b1b77eb 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -54,6 +54,7 @@
> #include <linux/if_ether.h>
> #include <linux/of_net.h>
> #include <linux/pci.h>
> +#include <linux/nvmem-consumer.h>
> #include <net/dst.h>
> #include <net/arp.h>
> #include <net/sock.h>
> @@ -527,8 +528,11 @@ unsigned char * __weak arch_get_platform_mac_address(void)
>
> int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> {
> + unsigned char addrbuf[ETH_ALEN];
> const unsigned char *addr;
> + struct nvmem_cell *nvmem;
> struct device_node *dp;
> + size_t alen;
>
> if (dev_is_pci(dev))
> dp = pci_device_to_OF_node(to_pci_dev(dev));
> @@ -541,6 +545,29 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> if (!addr)
> addr = arch_get_platform_mac_address();
>
> + if (!addr) {
> + nvmem = nvmem_cell_get(dev, "mac-address");
> + if (IS_ERR(nvmem) && PTR_ERR(nvmem) == -EPROBE_DEFER)
> + /* We may have a lookup registered for MAC address but
> + * the corresponding nvmem provider hasn't been
> + * registered yet.
> + */
> + return -EPROBE_DEFER;
> +
> + if (!IS_ERR(nvmem)) {
> + addr = nvmem_cell_read(nvmem, &alen);
> + if (!IS_ERR(addr)) {
^^^^
Never do success handling. Always error handling. Otherwise the code
is indent a lot and the error handling is far from the call.
> + if (alen == ETH_ALEN)
> + ether_addr_copy(addrbuf, addr);
> +
> + kfree(addr);
> + addr = alen == ETH_ALEN ? addrbuf : NULL;
> + }
> +
> + nvmem_cell_put(nvmem);
> + }
> + }
> +
> if (!addr || !is_valid_ether_addr(addr))
^^^^
Instead of handling the error we dereference the error pointer here.
*frowny face*
> return -ENODEV;
>
> --
Maybe this?
if (!addr) {
nvmem = nvmem_cell_get(dev, "mac-address");
if (PTR_ERR(nvmem) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (IS_ERR(nvmem))
return -ENODEV;
addr = nvmem_cell_read(nvmem, &alen);
if (IS_ERR(addr))
return PTR_ERR(addr);
if (alen != ETH_ALEN) {
kfree(addr);
return -ENODEV;
}
ether_addr_copy(addrbuf, addr);
kfree(addr);
addr = addrbuf;
}
if (!is_valid_ether_addr(addr))
return -ENODEV;
ether_addr_copy(mac_addr, addr);
return 0;
regards,
dan carpenter
^ permalink raw reply [flat|nested] 24+ messages in thread* [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
@ 2018-07-19 8:48 ` Dan Carpenter
0 siblings, 0 replies; 24+ messages in thread
From: Dan Carpenter @ 2018-07-19 8:48 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jul 19, 2018 at 10:20:27AM +0200, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
> Many non-DT platforms read the MAC address from EEPROM. Usually it's
> either done with callbacks defined in board files or from SoC-specific
> ethernet drivers.
>
> In order to generalize this, try to read the MAC from nvmem in
> eth_platform_get_mac_address() using a standard lookup name:
> "mac-address".
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
> net/ethernet/eth.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index 39af03894598..af3b4b1b77eb 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -54,6 +54,7 @@
> #include <linux/if_ether.h>
> #include <linux/of_net.h>
> #include <linux/pci.h>
> +#include <linux/nvmem-consumer.h>
> #include <net/dst.h>
> #include <net/arp.h>
> #include <net/sock.h>
> @@ -527,8 +528,11 @@ unsigned char * __weak arch_get_platform_mac_address(void)
>
> int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> {
> + unsigned char addrbuf[ETH_ALEN];
> const unsigned char *addr;
> + struct nvmem_cell *nvmem;
> struct device_node *dp;
> + size_t alen;
>
> if (dev_is_pci(dev))
> dp = pci_device_to_OF_node(to_pci_dev(dev));
> @@ -541,6 +545,29 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> if (!addr)
> addr = arch_get_platform_mac_address();
>
> + if (!addr) {
> + nvmem = nvmem_cell_get(dev, "mac-address");
> + if (IS_ERR(nvmem) && PTR_ERR(nvmem) == -EPROBE_DEFER)
> + /* We may have a lookup registered for MAC address but
> + * the corresponding nvmem provider hasn't been
> + * registered yet.
> + */
> + return -EPROBE_DEFER;
> +
> + if (!IS_ERR(nvmem)) {
> + addr = nvmem_cell_read(nvmem, &alen);
> + if (!IS_ERR(addr)) {
^^^^
Never do success handling. Always error handling. Otherwise the code
is indent a lot and the error handling is far from the call.
> + if (alen == ETH_ALEN)
> + ether_addr_copy(addrbuf, addr);
> +
> + kfree(addr);
> + addr = alen == ETH_ALEN ? addrbuf : NULL;
> + }
> +
> + nvmem_cell_put(nvmem);
> + }
> + }
> +
> if (!addr || !is_valid_ether_addr(addr))
^^^^
Instead of handling the error we dereference the error pointer here.
*frowny face*
> return -ENODEV;
>
> --
Maybe this?
if (!addr) {
nvmem = nvmem_cell_get(dev, "mac-address");
if (PTR_ERR(nvmem) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (IS_ERR(nvmem))
return -ENODEV;
addr = nvmem_cell_read(nvmem, &alen);
if (IS_ERR(addr))
return PTR_ERR(addr);
if (alen != ETH_ALEN) {
kfree(addr);
return -ENODEV;
}
ether_addr_copy(addrbuf, addr);
kfree(addr);
addr = addrbuf;
}
if (!is_valid_ether_addr(addr))
return -ENODEV;
ether_addr_copy(mac_addr, addr);
return 0;
regards,
dan carpenter
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
2018-07-19 8:48 ` Dan Carpenter
@ 2018-07-19 8:57 ` Bartosz Golaszewski
-1 siblings, 0 replies; 24+ messages in thread
From: Bartosz Golaszewski @ 2018-07-19 8:57 UTC (permalink / raw)
To: Dan Carpenter
Cc: Bartosz Golaszewski, Sekhar Nori, Kevin Hilman, Russell King,
Grygorii Strashko, David S . Miller, Srinivas Kandagatla,
Lukas Wunner, Rob Herring, Florian Fainelli, Ivan Khoronzhuk,
David Lechner, Greg Kroah-Hartman, Andrew Lunn, arm-soc, LKML,
Linux-OMAP, netdev
2018-07-19 10:48 GMT+02:00 Dan Carpenter <dan.carpenter@oracle.com>:
> On Thu, Jul 19, 2018 at 10:20:27AM +0200, Bartosz Golaszewski wrote:
>> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>>
>> Many non-DT platforms read the MAC address from EEPROM. Usually it's
>> either done with callbacks defined in board files or from SoC-specific
>> ethernet drivers.
>>
>> In order to generalize this, try to read the MAC from nvmem in
>> eth_platform_get_mac_address() using a standard lookup name:
>> "mac-address".
>>
>> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>> ---
>> net/ethernet/eth.c | 27 +++++++++++++++++++++++++++
>> 1 file changed, 27 insertions(+)
>>
>> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
>> index 39af03894598..af3b4b1b77eb 100644
>> --- a/net/ethernet/eth.c
>> +++ b/net/ethernet/eth.c
>> @@ -54,6 +54,7 @@
>> #include <linux/if_ether.h>
>> #include <linux/of_net.h>
>> #include <linux/pci.h>
>> +#include <linux/nvmem-consumer.h>
>> #include <net/dst.h>
>> #include <net/arp.h>
>> #include <net/sock.h>
>> @@ -527,8 +528,11 @@ unsigned char * __weak arch_get_platform_mac_address(void)
>>
>> int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
>> {
>> + unsigned char addrbuf[ETH_ALEN];
>> const unsigned char *addr;
>> + struct nvmem_cell *nvmem;
>> struct device_node *dp;
>> + size_t alen;
>>
>> if (dev_is_pci(dev))
>> dp = pci_device_to_OF_node(to_pci_dev(dev));
>> @@ -541,6 +545,29 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
>> if (!addr)
>> addr = arch_get_platform_mac_address();
>>
>> + if (!addr) {
>> + nvmem = nvmem_cell_get(dev, "mac-address");
>> + if (IS_ERR(nvmem) && PTR_ERR(nvmem) == -EPROBE_DEFER)
>> + /* We may have a lookup registered for MAC address but
>> + * the corresponding nvmem provider hasn't been
>> + * registered yet.
>> + */
>> + return -EPROBE_DEFER;
>> +
>> + if (!IS_ERR(nvmem)) {
>> + addr = nvmem_cell_read(nvmem, &alen);
>> + if (!IS_ERR(addr)) {
> ^^^^
> Never do success handling. Always error handling. Otherwise the code
> is indent a lot and the error handling is far from the call.
>
>> + if (alen == ETH_ALEN)
>> + ether_addr_copy(addrbuf, addr);
>> +
>> + kfree(addr);
>> + addr = alen == ETH_ALEN ? addrbuf : NULL;
>> + }
>> +
>> + nvmem_cell_put(nvmem);
>> + }
>> + }
>> +
>> if (!addr || !is_valid_ether_addr(addr))
> ^^^^
> Instead of handling the error we dereference the error pointer here.
>
True - we should add a check for IS_ERR(addr) here.
> *frowny face*
>
>> return -ENODEV;
>>
>> --
>
> Maybe this?
>
> if (!addr) {
> nvmem = nvmem_cell_get(dev, "mac-address");
> if (PTR_ERR(nvmem) == -EPROBE_DEFER)
> return -EPROBE_DEFER;
> if (IS_ERR(nvmem))
> return -ENODEV;
> addr = nvmem_cell_read(nvmem, &alen);
> if (IS_ERR(addr))
> return PTR_ERR(addr);
> if (alen != ETH_ALEN) {
> kfree(addr);
> return -ENODEV;
> }
> ether_addr_copy(addrbuf, addr);
> kfree(addr);
> addr = addrbuf;
> }
> if (!is_valid_ether_addr(addr))
> return -ENODEV;
> ether_addr_copy(mac_addr, addr);
> return 0;
>
I would normally go this way but here we don't want to bail out when
we encounter an error but rather continue on to the next possible
source of a MAC address. We'll get -ENODEV from nvmem_cell_get() if
the lookup fails for "mac-address" but instead of returning an error
code we should then check if we can read the MAC from MTD.
Bart
^ permalink raw reply [flat|nested] 24+ messages in thread* [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
@ 2018-07-19 8:57 ` Bartosz Golaszewski
0 siblings, 0 replies; 24+ messages in thread
From: Bartosz Golaszewski @ 2018-07-19 8:57 UTC (permalink / raw)
To: linux-arm-kernel
2018-07-19 10:48 GMT+02:00 Dan Carpenter <dan.carpenter@oracle.com>:
> On Thu, Jul 19, 2018 at 10:20:27AM +0200, Bartosz Golaszewski wrote:
>> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>>
>> Many non-DT platforms read the MAC address from EEPROM. Usually it's
>> either done with callbacks defined in board files or from SoC-specific
>> ethernet drivers.
>>
>> In order to generalize this, try to read the MAC from nvmem in
>> eth_platform_get_mac_address() using a standard lookup name:
>> "mac-address".
>>
>> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>> ---
>> net/ethernet/eth.c | 27 +++++++++++++++++++++++++++
>> 1 file changed, 27 insertions(+)
>>
>> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
>> index 39af03894598..af3b4b1b77eb 100644
>> --- a/net/ethernet/eth.c
>> +++ b/net/ethernet/eth.c
>> @@ -54,6 +54,7 @@
>> #include <linux/if_ether.h>
>> #include <linux/of_net.h>
>> #include <linux/pci.h>
>> +#include <linux/nvmem-consumer.h>
>> #include <net/dst.h>
>> #include <net/arp.h>
>> #include <net/sock.h>
>> @@ -527,8 +528,11 @@ unsigned char * __weak arch_get_platform_mac_address(void)
>>
>> int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
>> {
>> + unsigned char addrbuf[ETH_ALEN];
>> const unsigned char *addr;
>> + struct nvmem_cell *nvmem;
>> struct device_node *dp;
>> + size_t alen;
>>
>> if (dev_is_pci(dev))
>> dp = pci_device_to_OF_node(to_pci_dev(dev));
>> @@ -541,6 +545,29 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
>> if (!addr)
>> addr = arch_get_platform_mac_address();
>>
>> + if (!addr) {
>> + nvmem = nvmem_cell_get(dev, "mac-address");
>> + if (IS_ERR(nvmem) && PTR_ERR(nvmem) == -EPROBE_DEFER)
>> + /* We may have a lookup registered for MAC address but
>> + * the corresponding nvmem provider hasn't been
>> + * registered yet.
>> + */
>> + return -EPROBE_DEFER;
>> +
>> + if (!IS_ERR(nvmem)) {
>> + addr = nvmem_cell_read(nvmem, &alen);
>> + if (!IS_ERR(addr)) {
> ^^^^
> Never do success handling. Always error handling. Otherwise the code
> is indent a lot and the error handling is far from the call.
>
>> + if (alen == ETH_ALEN)
>> + ether_addr_copy(addrbuf, addr);
>> +
>> + kfree(addr);
>> + addr = alen == ETH_ALEN ? addrbuf : NULL;
>> + }
>> +
>> + nvmem_cell_put(nvmem);
>> + }
>> + }
>> +
>> if (!addr || !is_valid_ether_addr(addr))
> ^^^^
> Instead of handling the error we dereference the error pointer here.
>
True - we should add a check for IS_ERR(addr) here.
> *frowny face*
>
>> return -ENODEV;
>>
>> --
>
> Maybe this?
>
> if (!addr) {
> nvmem = nvmem_cell_get(dev, "mac-address");
> if (PTR_ERR(nvmem) == -EPROBE_DEFER)
> return -EPROBE_DEFER;
> if (IS_ERR(nvmem))
> return -ENODEV;
> addr = nvmem_cell_read(nvmem, &alen);
> if (IS_ERR(addr))
> return PTR_ERR(addr);
> if (alen != ETH_ALEN) {
> kfree(addr);
> return -ENODEV;
> }
> ether_addr_copy(addrbuf, addr);
> kfree(addr);
> addr = addrbuf;
> }
> if (!is_valid_ether_addr(addr))
> return -ENODEV;
> ether_addr_copy(mac_addr, addr);
> return 0;
>
I would normally go this way but here we don't want to bail out when
we encounter an error but rather continue on to the next possible
source of a MAC address. We'll get -ENODEV from nvmem_cell_get() if
the lookup fails for "mac-address" but instead of returning an error
code we should then check if we can read the MAC from MTD.
Bart
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
2018-07-19 8:57 ` Bartosz Golaszewski
@ 2018-07-19 9:09 ` Dan Carpenter
-1 siblings, 0 replies; 24+ messages in thread
From: Dan Carpenter @ 2018-07-19 9:09 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Bartosz Golaszewski, Sekhar Nori, Kevin Hilman, Russell King,
Grygorii Strashko, David S . Miller, Srinivas Kandagatla,
Lukas Wunner, Rob Herring, Florian Fainelli, Ivan Khoronzhuk,
David Lechner, Greg Kroah-Hartman, Andrew Lunn, arm-soc, LKML,
Linux-OMAP, netdev
Maybe it would be simpler as three separate functions:
int of_eth_get_mac_address() <- rename existing function to this
int nvmem_eth_get_mac_address() <- patch 2
int mtd_eth_nvmem_get_mac_address() patch 3
int ret;
ret = of_eth_get_mac_address(dev, mac_addr);
if (!ret)
return 0;
ret = nvmem_eth_get_mac_address(dev, mac_addr);
if (ret == -EPROBEDEFER)
return ret;
if (!ret)
return 0;
ret = mtd_eth_nvmem_get_mac_address(dev, mac_addr);
if (!ret)
return 0;
return -ENODEV;
regards,
dan carpenter
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
@ 2018-07-19 9:09 ` Dan Carpenter
0 siblings, 0 replies; 24+ messages in thread
From: Dan Carpenter @ 2018-07-19 9:09 UTC (permalink / raw)
To: linux-arm-kernel
Maybe it would be simpler as three separate functions:
int of_eth_get_mac_address() <- rename existing function to this
int nvmem_eth_get_mac_address() <- patch 2
int mtd_eth_nvmem_get_mac_address() patch 3
int ret;
ret = of_eth_get_mac_address(dev, mac_addr);
if (!ret)
return 0;
ret = nvmem_eth_get_mac_address(dev, mac_addr);
if (ret == -EPROBEDEFER)
return ret;
if (!ret)
return 0;
ret = mtd_eth_nvmem_get_mac_address(dev, mac_addr);
if (!ret)
return 0;
return -ENODEV;
regards,
dan carpenter
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
2018-07-19 9:09 ` Dan Carpenter
@ 2018-07-19 10:06 ` Bartosz Golaszewski
-1 siblings, 0 replies; 24+ messages in thread
From: Bartosz Golaszewski @ 2018-07-19 10:06 UTC (permalink / raw)
To: Dan Carpenter
Cc: Bartosz Golaszewski, Sekhar Nori, Kevin Hilman, Russell King,
Grygorii Strashko, David S . Miller, Srinivas Kandagatla,
Lukas Wunner, Rob Herring, Florian Fainelli, Ivan Khoronzhuk,
David Lechner, Greg Kroah-Hartman, Andrew Lunn, arm-soc, LKML,
Linux-OMAP, netdev
2018-07-19 11:09 GMT+02:00 Dan Carpenter <dan.carpenter@oracle.com>:
>
> Maybe it would be simpler as three separate functions:
>
> int of_eth_get_mac_address() <- rename existing function to this
> int nvmem_eth_get_mac_address() <- patch 2
> int mtd_eth_nvmem_get_mac_address() patch 3
>
> int ret;
>
> ret = of_eth_get_mac_address(dev, mac_addr);
> if (!ret)
> return 0;
> ret = nvmem_eth_get_mac_address(dev, mac_addr);
> if (ret == -EPROBEDEFER)
> return ret;
> if (!ret)
> return 0;
> ret = mtd_eth_nvmem_get_mac_address(dev, mac_addr);
> if (!ret)
> return 0;
>
> return -ENODEV;
>
> regards,
> dan carpenter
It looks simpler as long as you don't add all the new routines
resulting from this approach. I've just tried to quickly implement
this solution and it resulted in much bigger and duplicated code
(checking the validity of mac_addr, copying it etc.). I would prefer
the current approach and would like to read someone else's opinion on
that.
Thanks,
Bart
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
@ 2018-07-19 10:06 ` Bartosz Golaszewski
0 siblings, 0 replies; 24+ messages in thread
From: Bartosz Golaszewski @ 2018-07-19 10:06 UTC (permalink / raw)
To: linux-arm-kernel
2018-07-19 11:09 GMT+02:00 Dan Carpenter <dan.carpenter@oracle.com>:
>
> Maybe it would be simpler as three separate functions:
>
> int of_eth_get_mac_address() <- rename existing function to this
> int nvmem_eth_get_mac_address() <- patch 2
> int mtd_eth_nvmem_get_mac_address() patch 3
>
> int ret;
>
> ret = of_eth_get_mac_address(dev, mac_addr);
> if (!ret)
> return 0;
> ret = nvmem_eth_get_mac_address(dev, mac_addr);
> if (ret == -EPROBEDEFER)
> return ret;
> if (!ret)
> return 0;
> ret = mtd_eth_nvmem_get_mac_address(dev, mac_addr);
> if (!ret)
> return 0;
>
> return -ENODEV;
>
> regards,
> dan carpenter
It looks simpler as long as you don't add all the new routines
resulting from this approach. I've just tried to quickly implement
this solution and it resulted in much bigger and duplicated code
(checking the validity of mac_addr, copying it etc.). I would prefer
the current approach and would like to read someone else's opinion on
that.
Thanks,
Bart
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
2018-07-19 10:06 ` Bartosz Golaszewski
(?)
@ 2018-07-19 12:37 ` Dan Carpenter
-1 siblings, 0 replies; 24+ messages in thread
From: Dan Carpenter @ 2018-07-19 12:37 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Rob Herring, Grygorii Strashko, David Lechner, Ivan Khoronzhuk,
Kevin Hilman, Greg Kroah-Hartman, Sekhar Nori, Russell King, LKML,
Andrew Lunn, Bartosz Golaszewski, Lukas Wunner,
Srinivas Kandagatla, netdev, Florian Fainelli, Linux-OMAP,
David S . Miller, arm-soc
On Thu, Jul 19, 2018 at 12:06:51PM +0200, Bartosz Golaszewski wrote:
> It looks simpler as long as you don't add all the new routines
> resulting from this approach. I've just tried to quickly implement
> this solution and it resulted in much bigger and duplicated code
> (checking the validity of mac_addr, copying it etc.). I would prefer
> the current approach and would like to read someone else's opinion on
> that.
It's not too bad. There is two extra ether_addr_copy() calls and one
extra is_valid_ether_addr(). There are two extra alen declarations and
one extra addr declaration. The functions don't share *that* much code.
regards,
dan carpenter
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index fd8faa0dfa61..8ab7289a5069 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -54,6 +54,8 @@
#include <linux/if_ether.h>
#include <linux/of_net.h>
#include <linux/pci.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/mtd/mtd.h>
#include <net/dst.h>
#include <net/arp.h>
#include <net/sock.h>
@@ -525,7 +527,7 @@ unsigned char * __weak arch_get_platform_mac_address(void)
return NULL;
}
-int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+static int of_eth_get_mac_address(struct device *dev, u8 *mac_addr)
{
const unsigned char *addr;
struct device_node *dp;
@@ -547,4 +549,82 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
ether_addr_copy(mac_addr, addr);
return 0;
}
+
+static int nvmem_eth_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ struct nvmem_cell *nvmem;
+ unsigned char *addr;
+ size_t alen;
+ int ret = 0;
+
+ nvmem = nvmem_cell_get(dev, "mac-address");
+ if (PTR_ERR(nvmem) == -EPROBE_DEFER)
+ /* We may have a lookup registered for MAC address but the
+ * corresponding nvmem provider hasn't been registered yet.
+ */
+ return -EPROBE_DEFER;
+ if (IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
+ addr = nvmem_cell_read(nvmem, &alen);
+ if (IS_ERR(addr)) {
+ ret = PTR_ERR(addr);
+ goto put_nvmem;
+ }
+ if (alen != ETH_ALEN || !is_valid_ether_addr(addr)) {
+ ret = -EINVAL;
+ goto free_addr;
+ }
+ ether_addr_copy(mac_addr, addr);
+free_addr:
+ kfree(addr);
+put_nvmem:
+ nvmem_cell_put(nvmem);
+ return ret;
+}
+
+static int mtd_eth_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ struct mtd_info *mtd;
+ u8 addrbuf[ETH_ALEN];
+ size_t alen;
+ int ret;
+
+ /* This function should go away as soon as MTD gets nvmem support. */
+ if (!IS_ENABLED(CONFIG_MTD))
+ return -ENODEV;
+
+ mtd = get_mtd_device_nm("MAC-Address");
+ if (IS_ERR(mtd))
+ return PTR_ERR(mtd);
+ ret = mtd_read(mtd, 0, ETH_ALEN, &alen, addrbuf);
+ if (ret)
+ goto put_mtd;
+ if (!is_valid_ether_addr(addrbuf)) {
+ ret = -EINVAL;
+ goto put_mtd;
+ }
+ ether_addr_copy(mac_addr, addrbuf);
+put_mtd:
+ put_mtd_device(mtd);
+ return ret;
+}
+
+int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ int ret;
+
+ ret = of_eth_get_mac_address(dev, mac_addr);
+ if (!ret)
+ return 0;
+ ret = nvmem_eth_get_mac_address(dev, mac_addr);
+ if (ret == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ if (!ret)
+ return 0;
+ ret = mtd_eth_get_mac_address(dev, mac_addr);
+ if (!ret)
+ return 0;
+
+ return -ENODEV;
+}
EXPORT_SYMBOL(eth_platform_get_mac_address);
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
@ 2018-07-19 12:37 ` Dan Carpenter
0 siblings, 0 replies; 24+ messages in thread
From: Dan Carpenter @ 2018-07-19 12:37 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Bartosz Golaszewski, Sekhar Nori, Kevin Hilman, Russell King,
Grygorii Strashko, David S . Miller, Srinivas Kandagatla,
Lukas Wunner, Rob Herring, Florian Fainelli, Ivan Khoronzhuk,
David Lechner, Greg Kroah-Hartman, Andrew Lunn, arm-soc, LKML,
Linux-OMAP, netdev
On Thu, Jul 19, 2018 at 12:06:51PM +0200, Bartosz Golaszewski wrote:
> It looks simpler as long as you don't add all the new routines
> resulting from this approach. I've just tried to quickly implement
> this solution and it resulted in much bigger and duplicated code
> (checking the validity of mac_addr, copying it etc.). I would prefer
> the current approach and would like to read someone else's opinion on
> that.
It's not too bad. There is two extra ether_addr_copy() calls and one
extra is_valid_ether_addr(). There are two extra alen declarations and
one extra addr declaration. The functions don't share *that* much code.
regards,
dan carpenter
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index fd8faa0dfa61..8ab7289a5069 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -54,6 +54,8 @@
#include <linux/if_ether.h>
#include <linux/of_net.h>
#include <linux/pci.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/mtd/mtd.h>
#include <net/dst.h>
#include <net/arp.h>
#include <net/sock.h>
@@ -525,7 +527,7 @@ unsigned char * __weak arch_get_platform_mac_address(void)
return NULL;
}
-int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+static int of_eth_get_mac_address(struct device *dev, u8 *mac_addr)
{
const unsigned char *addr;
struct device_node *dp;
@@ -547,4 +549,82 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
ether_addr_copy(mac_addr, addr);
return 0;
}
+
+static int nvmem_eth_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ struct nvmem_cell *nvmem;
+ unsigned char *addr;
+ size_t alen;
+ int ret = 0;
+
+ nvmem = nvmem_cell_get(dev, "mac-address");
+ if (PTR_ERR(nvmem) == -EPROBE_DEFER)
+ /* We may have a lookup registered for MAC address but the
+ * corresponding nvmem provider hasn't been registered yet.
+ */
+ return -EPROBE_DEFER;
+ if (IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
+ addr = nvmem_cell_read(nvmem, &alen);
+ if (IS_ERR(addr)) {
+ ret = PTR_ERR(addr);
+ goto put_nvmem;
+ }
+ if (alen != ETH_ALEN || !is_valid_ether_addr(addr)) {
+ ret = -EINVAL;
+ goto free_addr;
+ }
+ ether_addr_copy(mac_addr, addr);
+free_addr:
+ kfree(addr);
+put_nvmem:
+ nvmem_cell_put(nvmem);
+ return ret;
+}
+
+static int mtd_eth_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ struct mtd_info *mtd;
+ u8 addrbuf[ETH_ALEN];
+ size_t alen;
+ int ret;
+
+ /* This function should go away as soon as MTD gets nvmem support. */
+ if (!IS_ENABLED(CONFIG_MTD))
+ return -ENODEV;
+
+ mtd = get_mtd_device_nm("MAC-Address");
+ if (IS_ERR(mtd))
+ return PTR_ERR(mtd);
+ ret = mtd_read(mtd, 0, ETH_ALEN, &alen, addrbuf);
+ if (ret)
+ goto put_mtd;
+ if (!is_valid_ether_addr(addrbuf)) {
+ ret = -EINVAL;
+ goto put_mtd;
+ }
+ ether_addr_copy(mac_addr, addrbuf);
+put_mtd:
+ put_mtd_device(mtd);
+ return ret;
+}
+
+int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ int ret;
+
+ ret = of_eth_get_mac_address(dev, mac_addr);
+ if (!ret)
+ return 0;
+ ret = nvmem_eth_get_mac_address(dev, mac_addr);
+ if (ret == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ if (!ret)
+ return 0;
+ ret = mtd_eth_get_mac_address(dev, mac_addr);
+ if (!ret)
+ return 0;
+
+ return -ENODEV;
+}
EXPORT_SYMBOL(eth_platform_get_mac_address);
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
@ 2018-07-19 12:37 ` Dan Carpenter
0 siblings, 0 replies; 24+ messages in thread
From: Dan Carpenter @ 2018-07-19 12:37 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jul 19, 2018 at 12:06:51PM +0200, Bartosz Golaszewski wrote:
> It looks simpler as long as you don't add all the new routines
> resulting from this approach. I've just tried to quickly implement
> this solution and it resulted in much bigger and duplicated code
> (checking the validity of mac_addr, copying it etc.). I would prefer
> the current approach and would like to read someone else's opinion on
> that.
It's not too bad. There is two extra ether_addr_copy() calls and one
extra is_valid_ether_addr(). There are two extra alen declarations and
one extra addr declaration. The functions don't share *that* much code.
regards,
dan carpenter
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index fd8faa0dfa61..8ab7289a5069 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -54,6 +54,8 @@
#include <linux/if_ether.h>
#include <linux/of_net.h>
#include <linux/pci.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/mtd/mtd.h>
#include <net/dst.h>
#include <net/arp.h>
#include <net/sock.h>
@@ -525,7 +527,7 @@ unsigned char * __weak arch_get_platform_mac_address(void)
return NULL;
}
-int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+static int of_eth_get_mac_address(struct device *dev, u8 *mac_addr)
{
const unsigned char *addr;
struct device_node *dp;
@@ -547,4 +549,82 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
ether_addr_copy(mac_addr, addr);
return 0;
}
+
+static int nvmem_eth_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ struct nvmem_cell *nvmem;
+ unsigned char *addr;
+ size_t alen;
+ int ret = 0;
+
+ nvmem = nvmem_cell_get(dev, "mac-address");
+ if (PTR_ERR(nvmem) == -EPROBE_DEFER)
+ /* We may have a lookup registered for MAC address but the
+ * corresponding nvmem provider hasn't been registered yet.
+ */
+ return -EPROBE_DEFER;
+ if (IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
+ addr = nvmem_cell_read(nvmem, &alen);
+ if (IS_ERR(addr)) {
+ ret = PTR_ERR(addr);
+ goto put_nvmem;
+ }
+ if (alen != ETH_ALEN || !is_valid_ether_addr(addr)) {
+ ret = -EINVAL;
+ goto free_addr;
+ }
+ ether_addr_copy(mac_addr, addr);
+free_addr:
+ kfree(addr);
+put_nvmem:
+ nvmem_cell_put(nvmem);
+ return ret;
+}
+
+static int mtd_eth_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ struct mtd_info *mtd;
+ u8 addrbuf[ETH_ALEN];
+ size_t alen;
+ int ret;
+
+ /* This function should go away as soon as MTD gets nvmem support. */
+ if (!IS_ENABLED(CONFIG_MTD))
+ return -ENODEV;
+
+ mtd = get_mtd_device_nm("MAC-Address");
+ if (IS_ERR(mtd))
+ return PTR_ERR(mtd);
+ ret = mtd_read(mtd, 0, ETH_ALEN, &alen, addrbuf);
+ if (ret)
+ goto put_mtd;
+ if (!is_valid_ether_addr(addrbuf)) {
+ ret = -EINVAL;
+ goto put_mtd;
+ }
+ ether_addr_copy(mac_addr, addrbuf);
+put_mtd:
+ put_mtd_device(mtd);
+ return ret;
+}
+
+int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ int ret;
+
+ ret = of_eth_get_mac_address(dev, mac_addr);
+ if (!ret)
+ return 0;
+ ret = nvmem_eth_get_mac_address(dev, mac_addr);
+ if (ret == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ if (!ret)
+ return 0;
+ ret = mtd_eth_get_mac_address(dev, mac_addr);
+ if (!ret)
+ return 0;
+
+ return -ENODEV;
+}
EXPORT_SYMBOL(eth_platform_get_mac_address);
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
2018-07-19 12:37 ` Dan Carpenter
@ 2018-07-19 15:35 ` Bartosz Golaszewski
-1 siblings, 0 replies; 24+ messages in thread
From: Bartosz Golaszewski @ 2018-07-19 15:35 UTC (permalink / raw)
To: Dan Carpenter
Cc: Bartosz Golaszewski, Sekhar Nori, Kevin Hilman, Russell King,
Grygorii Strashko, David S . Miller, Srinivas Kandagatla,
Lukas Wunner, Rob Herring, Florian Fainelli, Ivan Khoronzhuk,
David Lechner, Greg Kroah-Hartman, Andrew Lunn, arm-soc, LKML,
Linux-OMAP, netdev
2018-07-19 14:37 GMT+02:00 Dan Carpenter <dan.carpenter@oracle.com>:
> On Thu, Jul 19, 2018 at 12:06:51PM +0200, Bartosz Golaszewski wrote:
>> It looks simpler as long as you don't add all the new routines
>> resulting from this approach. I've just tried to quickly implement
>> this solution and it resulted in much bigger and duplicated code
>> (checking the validity of mac_addr, copying it etc.). I would prefer
>> the current approach and would like to read someone else's opinion on
>> that.
>
> It's not too bad. There is two extra ether_addr_copy() calls and one
> extra is_valid_ether_addr(). There are two extra alen declarations and
> one extra addr declaration. The functions don't share *that* much code.
>
> regards,
> dan carpenter
>
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index fd8faa0dfa61..8ab7289a5069 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -54,6 +54,8 @@
> #include <linux/if_ether.h>
> #include <linux/of_net.h>
> #include <linux/pci.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/mtd/mtd.h>
> #include <net/dst.h>
> #include <net/arp.h>
> #include <net/sock.h>
> @@ -525,7 +527,7 @@ unsigned char * __weak arch_get_platform_mac_address(void)
> return NULL;
> }
>
> -int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> +static int of_eth_get_mac_address(struct device *dev, u8 *mac_addr)
> {
> const unsigned char *addr;
> struct device_node *dp;
> @@ -547,4 +549,82 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> ether_addr_copy(mac_addr, addr);
> return 0;
> }
> +
> +static int nvmem_eth_get_mac_address(struct device *dev, u8 *mac_addr)
> +{
> + struct nvmem_cell *nvmem;
> + unsigned char *addr;
> + size_t alen;
> + int ret = 0;
> +
> + nvmem = nvmem_cell_get(dev, "mac-address");
> + if (PTR_ERR(nvmem) == -EPROBE_DEFER)
> + /* We may have a lookup registered for MAC address but the
> + * corresponding nvmem provider hasn't been registered yet.
> + */
> + return -EPROBE_DEFER;
> + if (IS_ERR(nvmem))
> + return PTR_ERR(nvmem);
> + addr = nvmem_cell_read(nvmem, &alen);
> + if (IS_ERR(addr)) {
> + ret = PTR_ERR(addr);
> + goto put_nvmem;
> + }
> + if (alen != ETH_ALEN || !is_valid_ether_addr(addr)) {
> + ret = -EINVAL;
> + goto free_addr;
> + }
> + ether_addr_copy(mac_addr, addr);
> +free_addr:
> + kfree(addr);
> +put_nvmem:
> + nvmem_cell_put(nvmem);
> + return ret;
> +}
> +
> +static int mtd_eth_get_mac_address(struct device *dev, u8 *mac_addr)
> +{
> + struct mtd_info *mtd;
> + u8 addrbuf[ETH_ALEN];
> + size_t alen;
> + int ret;
> +
> + /* This function should go away as soon as MTD gets nvmem support. */
> + if (!IS_ENABLED(CONFIG_MTD))
> + return -ENODEV;
> +
> + mtd = get_mtd_device_nm("MAC-Address");
> + if (IS_ERR(mtd))
> + return PTR_ERR(mtd);
> + ret = mtd_read(mtd, 0, ETH_ALEN, &alen, addrbuf);
> + if (ret)
> + goto put_mtd;
> + if (!is_valid_ether_addr(addrbuf)) {
> + ret = -EINVAL;
> + goto put_mtd;
> + }
> + ether_addr_copy(mac_addr, addrbuf);
> +put_mtd:
> + put_mtd_device(mtd);
> + return ret;
> +}
> +
> +int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> +{
> + int ret;
> +
> + ret = of_eth_get_mac_address(dev, mac_addr);
> + if (!ret)
> + return 0;
> + ret = nvmem_eth_get_mac_address(dev, mac_addr);
> + if (ret == -EPROBE_DEFER)
> + return -EPROBE_DEFER;
> + if (!ret)
> + return 0;
> + ret = mtd_eth_get_mac_address(dev, mac_addr);
> + if (!ret)
> + return 0;
> +
> + return -ENODEV;
> +}
> EXPORT_SYMBOL(eth_platform_get_mac_address);
Please take a look at v3 - I did it a bit differently but the idea is the same.
Bart
^ permalink raw reply [flat|nested] 24+ messages in thread* [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
@ 2018-07-19 15:35 ` Bartosz Golaszewski
0 siblings, 0 replies; 24+ messages in thread
From: Bartosz Golaszewski @ 2018-07-19 15:35 UTC (permalink / raw)
To: linux-arm-kernel
2018-07-19 14:37 GMT+02:00 Dan Carpenter <dan.carpenter@oracle.com>:
> On Thu, Jul 19, 2018 at 12:06:51PM +0200, Bartosz Golaszewski wrote:
>> It looks simpler as long as you don't add all the new routines
>> resulting from this approach. I've just tried to quickly implement
>> this solution and it resulted in much bigger and duplicated code
>> (checking the validity of mac_addr, copying it etc.). I would prefer
>> the current approach and would like to read someone else's opinion on
>> that.
>
> It's not too bad. There is two extra ether_addr_copy() calls and one
> extra is_valid_ether_addr(). There are two extra alen declarations and
> one extra addr declaration. The functions don't share *that* much code.
>
> regards,
> dan carpenter
>
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index fd8faa0dfa61..8ab7289a5069 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -54,6 +54,8 @@
> #include <linux/if_ether.h>
> #include <linux/of_net.h>
> #include <linux/pci.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/mtd/mtd.h>
> #include <net/dst.h>
> #include <net/arp.h>
> #include <net/sock.h>
> @@ -525,7 +527,7 @@ unsigned char * __weak arch_get_platform_mac_address(void)
> return NULL;
> }
>
> -int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> +static int of_eth_get_mac_address(struct device *dev, u8 *mac_addr)
> {
> const unsigned char *addr;
> struct device_node *dp;
> @@ -547,4 +549,82 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> ether_addr_copy(mac_addr, addr);
> return 0;
> }
> +
> +static int nvmem_eth_get_mac_address(struct device *dev, u8 *mac_addr)
> +{
> + struct nvmem_cell *nvmem;
> + unsigned char *addr;
> + size_t alen;
> + int ret = 0;
> +
> + nvmem = nvmem_cell_get(dev, "mac-address");
> + if (PTR_ERR(nvmem) == -EPROBE_DEFER)
> + /* We may have a lookup registered for MAC address but the
> + * corresponding nvmem provider hasn't been registered yet.
> + */
> + return -EPROBE_DEFER;
> + if (IS_ERR(nvmem))
> + return PTR_ERR(nvmem);
> + addr = nvmem_cell_read(nvmem, &alen);
> + if (IS_ERR(addr)) {
> + ret = PTR_ERR(addr);
> + goto put_nvmem;
> + }
> + if (alen != ETH_ALEN || !is_valid_ether_addr(addr)) {
> + ret = -EINVAL;
> + goto free_addr;
> + }
> + ether_addr_copy(mac_addr, addr);
> +free_addr:
> + kfree(addr);
> +put_nvmem:
> + nvmem_cell_put(nvmem);
> + return ret;
> +}
> +
> +static int mtd_eth_get_mac_address(struct device *dev, u8 *mac_addr)
> +{
> + struct mtd_info *mtd;
> + u8 addrbuf[ETH_ALEN];
> + size_t alen;
> + int ret;
> +
> + /* This function should go away as soon as MTD gets nvmem support. */
> + if (!IS_ENABLED(CONFIG_MTD))
> + return -ENODEV;
> +
> + mtd = get_mtd_device_nm("MAC-Address");
> + if (IS_ERR(mtd))
> + return PTR_ERR(mtd);
> + ret = mtd_read(mtd, 0, ETH_ALEN, &alen, addrbuf);
> + if (ret)
> + goto put_mtd;
> + if (!is_valid_ether_addr(addrbuf)) {
> + ret = -EINVAL;
> + goto put_mtd;
> + }
> + ether_addr_copy(mac_addr, addrbuf);
> +put_mtd:
> + put_mtd_device(mtd);
> + return ret;
> +}
> +
> +int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> +{
> + int ret;
> +
> + ret = of_eth_get_mac_address(dev, mac_addr);
> + if (!ret)
> + return 0;
> + ret = nvmem_eth_get_mac_address(dev, mac_addr);
> + if (ret == -EPROBE_DEFER)
> + return -EPROBE_DEFER;
> + if (!ret)
> + return 0;
> + ret = mtd_eth_get_mac_address(dev, mac_addr);
> + if (!ret)
> + return 0;
> +
> + return -ENODEV;
> +}
> EXPORT_SYMBOL(eth_platform_get_mac_address);
Please take a look at v3 - I did it a bit differently but the idea is the same.
Bart
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
2018-07-19 8:48 ` Dan Carpenter
@ 2018-07-19 12:23 ` Russell King - ARM Linux
-1 siblings, 0 replies; 24+ messages in thread
From: Russell King - ARM Linux @ 2018-07-19 12:23 UTC (permalink / raw)
To: Dan Carpenter
Cc: Bartosz Golaszewski, Sekhar Nori, Kevin Hilman, Grygorii Strashko,
David S . Miller, Srinivas Kandagatla, Lukas Wunner, Rob Herring,
Florian Fainelli, Ivan Khoronzhuk, David Lechner,
Greg Kroah-Hartman, Andrew Lunn, linux-arm-kernel, linux-kernel,
linux-omap, netdev, Bartosz Golaszewski
On Thu, Jul 19, 2018 at 11:48:37AM +0300, Dan Carpenter wrote:
> On Thu, Jul 19, 2018 at 10:20:27AM +0200, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> >
> > Many non-DT platforms read the MAC address from EEPROM. Usually it's
> > either done with callbacks defined in board files or from SoC-specific
> > ethernet drivers.
> >
> > In order to generalize this, try to read the MAC from nvmem in
> > eth_platform_get_mac_address() using a standard lookup name:
> > "mac-address".
> >
> > Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> > ---
> > net/ethernet/eth.c | 27 +++++++++++++++++++++++++++
> > 1 file changed, 27 insertions(+)
> >
> > diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> > index 39af03894598..af3b4b1b77eb 100644
> > --- a/net/ethernet/eth.c
> > +++ b/net/ethernet/eth.c
> > @@ -54,6 +54,7 @@
> > #include <linux/if_ether.h>
> > #include <linux/of_net.h>
> > #include <linux/pci.h>
> > +#include <linux/nvmem-consumer.h>
> > #include <net/dst.h>
> > #include <net/arp.h>
> > #include <net/sock.h>
> > @@ -527,8 +528,11 @@ unsigned char * __weak arch_get_platform_mac_address(void)
> >
> > int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> > {
> > + unsigned char addrbuf[ETH_ALEN];
> > const unsigned char *addr;
> > + struct nvmem_cell *nvmem;
> > struct device_node *dp;
> > + size_t alen;
> >
> > if (dev_is_pci(dev))
> > dp = pci_device_to_OF_node(to_pci_dev(dev));
> > @@ -541,6 +545,29 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> > if (!addr)
> > addr = arch_get_platform_mac_address();
> >
> > + if (!addr) {
> > + nvmem = nvmem_cell_get(dev, "mac-address");
> > + if (IS_ERR(nvmem) && PTR_ERR(nvmem) == -EPROBE_DEFER)
> > + /* We may have a lookup registered for MAC address but
> > + * the corresponding nvmem provider hasn't been
> > + * registered yet.
> > + */
> > + return -EPROBE_DEFER;
> > +
> > + if (!IS_ERR(nvmem)) {
> > + addr = nvmem_cell_read(nvmem, &alen);
> > + if (!IS_ERR(addr)) {
> ^^^^
> Never do success handling. Always error handling. Otherwise the code
> is indent a lot and the error handling is far from the call.
>
> > + if (alen == ETH_ALEN)
> > + ether_addr_copy(addrbuf, addr);
> > +
> > + kfree(addr);
> > + addr = alen == ETH_ALEN ? addrbuf : NULL;
> > + }
> > +
> > + nvmem_cell_put(nvmem);
> > + }
> > + }
> > +
> > if (!addr || !is_valid_ether_addr(addr))
> ^^^^
> Instead of handling the error we dereference the error pointer here.
>
> *frowny face*
>
> > return -ENODEV;
> >
> > --
>
> Maybe this?
>
> if (!addr) {
> nvmem = nvmem_cell_get(dev, "mac-address");
> if (PTR_ERR(nvmem) == -EPROBE_DEFER)
> return -EPROBE_DEFER;
> if (IS_ERR(nvmem))
> return -ENODEV;
> addr = nvmem_cell_read(nvmem, &alen);
> if (IS_ERR(addr))
> return PTR_ERR(addr);
The problem with doing it this way is... error handling is Hard(tm).
You missed the call to nvmem_cell_put() here.
> if (alen != ETH_ALEN) {
> kfree(addr);
and again here.
> return -ENODEV;
> }
> ether_addr_copy(addrbuf, addr);
> kfree(addr);
> addr = addrbuf;
and here.
> }
> if (!is_valid_ether_addr(addr))
> return -ENODEV;
> ether_addr_copy(mac_addr, addr);
> return 0;
Without checking the semantics, a possible solution to that could be:
if (!addr) {
nvmem = nvmem_cell_get(dev, "mac-address");
if (PTR_ERR(nvmem) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (IS_ERR(nvmem))
return -ENODEV;
addr = nvmem_cell_read(nvmem, &alen);
+ nvmem_cell_put(nvmem);
if (IS_ERR(addr))
return PTR_ERR(addr);
if (alen != ETH_ALEN) {
kfree(addr);
return -ENODEV;
}
ether_addr_copy(addrbuf, addr);
kfree(addr);
addr = addrbuf;
}
if (!is_valid_ether_addr(addr))
return -ENODEV;
ether_addr_copy(mac_addr, addr);
return 0;
A potential better solution would be to put this code in a separate
function, and then do:
if (!addr)
addr = eth_platform_get_nvmem_mac_address(dev, addrbuf);
which returns either NULL or addrbuf depending on whether it failed or
succeeded, which would probably end up with cleaner code.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up
According to speedtest.net: 13Mbps down 490kbps up
^ permalink raw reply [flat|nested] 24+ messages in thread* [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
@ 2018-07-19 12:23 ` Russell King - ARM Linux
0 siblings, 0 replies; 24+ messages in thread
From: Russell King - ARM Linux @ 2018-07-19 12:23 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jul 19, 2018 at 11:48:37AM +0300, Dan Carpenter wrote:
> On Thu, Jul 19, 2018 at 10:20:27AM +0200, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> >
> > Many non-DT platforms read the MAC address from EEPROM. Usually it's
> > either done with callbacks defined in board files or from SoC-specific
> > ethernet drivers.
> >
> > In order to generalize this, try to read the MAC from nvmem in
> > eth_platform_get_mac_address() using a standard lookup name:
> > "mac-address".
> >
> > Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> > ---
> > net/ethernet/eth.c | 27 +++++++++++++++++++++++++++
> > 1 file changed, 27 insertions(+)
> >
> > diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> > index 39af03894598..af3b4b1b77eb 100644
> > --- a/net/ethernet/eth.c
> > +++ b/net/ethernet/eth.c
> > @@ -54,6 +54,7 @@
> > #include <linux/if_ether.h>
> > #include <linux/of_net.h>
> > #include <linux/pci.h>
> > +#include <linux/nvmem-consumer.h>
> > #include <net/dst.h>
> > #include <net/arp.h>
> > #include <net/sock.h>
> > @@ -527,8 +528,11 @@ unsigned char * __weak arch_get_platform_mac_address(void)
> >
> > int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> > {
> > + unsigned char addrbuf[ETH_ALEN];
> > const unsigned char *addr;
> > + struct nvmem_cell *nvmem;
> > struct device_node *dp;
> > + size_t alen;
> >
> > if (dev_is_pci(dev))
> > dp = pci_device_to_OF_node(to_pci_dev(dev));
> > @@ -541,6 +545,29 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
> > if (!addr)
> > addr = arch_get_platform_mac_address();
> >
> > + if (!addr) {
> > + nvmem = nvmem_cell_get(dev, "mac-address");
> > + if (IS_ERR(nvmem) && PTR_ERR(nvmem) == -EPROBE_DEFER)
> > + /* We may have a lookup registered for MAC address but
> > + * the corresponding nvmem provider hasn't been
> > + * registered yet.
> > + */
> > + return -EPROBE_DEFER;
> > +
> > + if (!IS_ERR(nvmem)) {
> > + addr = nvmem_cell_read(nvmem, &alen);
> > + if (!IS_ERR(addr)) {
> ^^^^
> Never do success handling. Always error handling. Otherwise the code
> is indent a lot and the error handling is far from the call.
>
> > + if (alen == ETH_ALEN)
> > + ether_addr_copy(addrbuf, addr);
> > +
> > + kfree(addr);
> > + addr = alen == ETH_ALEN ? addrbuf : NULL;
> > + }
> > +
> > + nvmem_cell_put(nvmem);
> > + }
> > + }
> > +
> > if (!addr || !is_valid_ether_addr(addr))
> ^^^^
> Instead of handling the error we dereference the error pointer here.
>
> *frowny face*
>
> > return -ENODEV;
> >
> > --
>
> Maybe this?
>
> if (!addr) {
> nvmem = nvmem_cell_get(dev, "mac-address");
> if (PTR_ERR(nvmem) == -EPROBE_DEFER)
> return -EPROBE_DEFER;
> if (IS_ERR(nvmem))
> return -ENODEV;
> addr = nvmem_cell_read(nvmem, &alen);
> if (IS_ERR(addr))
> return PTR_ERR(addr);
The problem with doing it this way is... error handling is Hard(tm).
You missed the call to nvmem_cell_put() here.
> if (alen != ETH_ALEN) {
> kfree(addr);
and again here.
> return -ENODEV;
> }
> ether_addr_copy(addrbuf, addr);
> kfree(addr);
> addr = addrbuf;
and here.
> }
> if (!is_valid_ether_addr(addr))
> return -ENODEV;
> ether_addr_copy(mac_addr, addr);
> return 0;
Without checking the semantics, a possible solution to that could be:
if (!addr) {
nvmem = nvmem_cell_get(dev, "mac-address");
if (PTR_ERR(nvmem) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (IS_ERR(nvmem))
return -ENODEV;
addr = nvmem_cell_read(nvmem, &alen);
+ nvmem_cell_put(nvmem);
if (IS_ERR(addr))
return PTR_ERR(addr);
if (alen != ETH_ALEN) {
kfree(addr);
return -ENODEV;
}
ether_addr_copy(addrbuf, addr);
kfree(addr);
addr = addrbuf;
}
if (!is_valid_ether_addr(addr))
return -ENODEV;
ether_addr_copy(mac_addr, addr);
return 0;
A potential better solution would be to put this code in a separate
function, and then do:
if (!addr)
addr = eth_platform_get_nvmem_mac_address(dev, addrbuf);
which returns either NULL or addrbuf depending on whether it failed or
succeeded, which would probably end up with cleaner code.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up
According to speedtest.net: 13Mbps down 490kbps up
^ permalink raw reply [flat|nested] 24+ messages in thread