diff options
author | David S. Miller <davem@davemloft.net> | 2019-04-06 18:21:46 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-06 18:21:46 -0700 |
commit | afdb3df2925a240fd6e73ca53fdb885e90da88ba (patch) | |
tree | cd4ed0320a87ab3634d276cbd0c4160f56721935 | |
parent | d1edc085559744fbda7a55e97eeae8bd6135a11b (diff) | |
parent | 25766271e42f6b15b72ba156cb42a3fea91b5b21 (diff) | |
download | linux-afdb3df2925a240fd6e73ca53fdb885e90da88ba.tar.gz linux-afdb3df2925a240fd6e73ca53fdb885e90da88ba.tar.bz2 linux-afdb3df2925a240fd6e73ca53fdb885e90da88ba.zip |
Merge branch 'r8152-runtime-mac-changes'
Mario Limonciello says:
====================
r8152: Support runtime changes of vendor mac passthu policy
On some platforms ACPI method `\\_SB.AMAC` is dynamic and changes to it can
influence changing the behavior of MAC pass through and what MAC address is used.
When running USB reset, re-read the MAC address to use to support tools that
change the policy.
This is quite similar to using `SIOCSIFHWADDR` except that the actual MAC to use
comes from ASL rather than from userspace.
Changes from v1:
* Remove an extra unneeded `ether_addr_copy` call
* Use `dev_set_mac_address` to ensure all notifiers are called
* Shuffle functions to allow code re-use.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/usb/r8152.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 86c8c64fbb0f..6d63dcb73b26 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1212,7 +1212,6 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) goto amacout; } memcpy(sa->sa_data, buf, 6); - ether_addr_copy(tp->netdev->dev_addr, sa->sa_data); netif_info(tp, probe, tp->netdev, "Using pass-thru MAC addr %pM\n", sa->sa_data); @@ -1221,43 +1220,55 @@ amacout: return ret; } -static int set_ethernet_addr(struct r8152 *tp) +static int determine_ethernet_addr(struct r8152 *tp, struct sockaddr *sa) { struct net_device *dev = tp->netdev; - struct sockaddr sa; int ret; if (tp->version == RTL_VER_01) { - ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data); + ret = pla_ocp_read(tp, PLA_IDR, 8, sa->sa_data); } else { /* if device doesn't support MAC pass through this will * be expected to be non-zero */ - ret = vendor_mac_passthru_addr_read(tp, &sa); + ret = vendor_mac_passthru_addr_read(tp, sa); if (ret < 0) - ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data); + ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa->sa_data); } if (ret < 0) { netif_err(tp, probe, dev, "Get ether addr fail\n"); - } else if (!is_valid_ether_addr(sa.sa_data)) { + } else if (!is_valid_ether_addr(sa->sa_data)) { netif_err(tp, probe, dev, "Invalid ether addr %pM\n", - sa.sa_data); + sa->sa_data); eth_hw_addr_random(dev); - ether_addr_copy(sa.sa_data, dev->dev_addr); - ret = rtl8152_set_mac_address(dev, &sa); + ether_addr_copy(sa->sa_data, dev->dev_addr); netif_info(tp, probe, dev, "Random ether addr %pM\n", - sa.sa_data); - } else { - if (tp->version == RTL_VER_01) - ether_addr_copy(dev->dev_addr, sa.sa_data); - else - ret = rtl8152_set_mac_address(dev, &sa); + sa->sa_data); + return 0; } return ret; } +static int set_ethernet_addr(struct r8152 *tp) +{ + struct net_device *dev = tp->netdev; + struct sockaddr sa; + int ret; + + ret = determine_ethernet_addr(tp, &sa); + if (ret < 0) + return ret; + + if (tp->version == RTL_VER_01) + ether_addr_copy(dev->dev_addr, sa.sa_data); + else + ret = rtl8152_set_mac_address(dev, &sa); + + return ret; +} + static void read_bulk_callback(struct urb *urb) { struct net_device *netdev; @@ -4264,10 +4275,18 @@ static int rtl8152_post_reset(struct usb_interface *intf) { struct r8152 *tp = usb_get_intfdata(intf); struct net_device *netdev; + struct sockaddr sa; if (!tp) return 0; + /* reset the MAC adddress in case of policy change */ + if (determine_ethernet_addr(tp, &sa) >= 0) { + rtnl_lock(); + dev_set_mac_address (tp->netdev, &sa, NULL); + rtnl_unlock(); + } + netdev = tp->netdev; if (!netif_running(netdev)) return 0; |