diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2019-07-02 21:46:09 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-03 01:28:19 +0300 |
commit | c782e204f7343b6f4527e953a5ad265be4abd627 (patch) | |
tree | 4427127f8e095f8124325f90b17799c5e3e4cfe6 /drivers/net/ethernet/realtek | |
parent | 7424edbb559036ddf63eb7c655b3305d91b12dc9 (diff) | |
download | linux-c782e204f7343b6f4527e953a5ad265be4abd627.tar.xz |
r8169: add random MAC address fallback
It was reported that the GPD MicroPC is broken in a way that no valid
MAC address can be read from the network chip. The vendor driver deals
with this by assigning a random MAC address as fallback. So let's do
the same.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/realtek')
-rw-r--r-- | drivers/net/ethernet/realtek/r8169_main.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 22b2f3dcb41d..495d40c8f20e 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -6650,13 +6650,36 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp) return rc; } +static void rtl_init_mac_address(struct rtl8169_private *tp) +{ + struct net_device *dev = tp->dev; + u8 *mac_addr = dev->dev_addr; + int rc, i; + + rc = eth_platform_get_mac_address(tp_to_dev(tp), mac_addr); + if (!rc) + goto done; + + rtl_read_mac_address(tp, mac_addr); + if (is_valid_ether_addr(mac_addr)) + goto done; + + for (i = 0; i < ETH_ALEN; i++) + mac_addr[i] = RTL_R8(tp, MAC0 + i); + if (is_valid_ether_addr(mac_addr)) + goto done; + + eth_hw_addr_random(dev); + dev_warn(tp_to_dev(tp), "can't read MAC address, setting random one\n"); +done: + rtl_rar_set(tp, mac_addr); +} + static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - /* align to u16 for is_valid_ether_addr() */ - u8 mac_addr[ETH_ALEN] __aligned(2) = {}; struct rtl8169_private *tp; struct net_device *dev; - int chipset, region, i; + int chipset, region; int jumbo_max, rc; dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp)); @@ -6748,16 +6771,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) u64_stats_init(&tp->rx_stats.syncp); u64_stats_init(&tp->tx_stats.syncp); - /* get MAC address */ - rc = eth_platform_get_mac_address(&pdev->dev, mac_addr); - if (rc) - rtl_read_mac_address(tp, mac_addr); - - if (is_valid_ether_addr(mac_addr)) - rtl_rar_set(tp, mac_addr); - - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[i] = RTL_R8(tp, MAC0 + i); + rtl_init_mac_address(tp); dev->ethtool_ops = &rtl8169_ethtool_ops; |