From: Petko Manolov petko.manolov@konsulko.com
[ Upstream commit f30e25a9d1b25ac8d40071c4dc2679ad0fcdc55a ]
v2:
If reading the MAC address from eeprom fail don't throw an error, use randomly generated MAC instead. Either way the adapter will soldier on and the return type of set_ethernet_addr() can be reverted to void.
v1:
Fix a bug in set_ethernet_addr() which does not take into account possible errors (or partial reads) returned by its helpers. This can potentially lead to writing random data into device's MAC address registers.
Signed-off-by: Petko Manolov petko.manolov@konsulko.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/usb/pegasus.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 0ef7e1f443e33..2e7b67fc7e64d 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -360,28 +360,47 @@ fail: } #endif /* PEGASUS_WRITE_EEPROM */
-static inline void get_node_id(pegasus_t *pegasus, __u8 *id) +static inline int get_node_id(pegasus_t *pegasus, u8 *id) { - int i; - __u16 w16; + int i, ret; + u16 w16;
for (i = 0; i < 3; i++) { - read_eprom_word(pegasus, i, &w16); + ret = read_eprom_word(pegasus, i, &w16); + if (ret < 0) + return ret; ((__le16 *) id)[i] = cpu_to_le16(w16); } + + return 0; }
static void set_ethernet_addr(pegasus_t *pegasus) { - __u8 node_id[6]; + int ret; + u8 node_id[6];
if (pegasus->features & PEGASUS_II) { - get_registers(pegasus, 0x10, sizeof(node_id), node_id); + ret = get_registers(pegasus, 0x10, sizeof(node_id), node_id); + if (ret < 0) + goto err; } else { - get_node_id(pegasus, node_id); - set_registers(pegasus, EthID, sizeof(node_id), node_id); + ret = get_node_id(pegasus, node_id); + if (ret < 0) + goto err; + ret = set_registers(pegasus, EthID, sizeof(node_id), node_id); + if (ret < 0) + goto err; } + memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id)); + + return; +err: + eth_hw_addr_random(pegasus->net); + dev_info(&pegasus->intf->dev, "software assigned MAC address.\n"); + + return; }
static inline int reset_mac(pegasus_t *pegasus)