mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
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>
This commit is contained in:
commit
afdb3df292
1 changed files with 45 additions and 26 deletions
|
@ -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,39 +1220,51 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int determine_ethernet_addr(struct r8152 *tp, struct sockaddr *sa)
|
||||
{
|
||||
struct net_device *dev = tp->netdev;
|
||||
int ret;
|
||||
|
||||
if (tp->version == RTL_VER_01) {
|
||||
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);
|
||||
if (ret < 0)
|
||||
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)) {
|
||||
netif_err(tp, probe, dev, "Invalid ether addr %pM\n",
|
||||
sa->sa_data);
|
||||
eth_hw_addr_random(dev);
|
||||
ether_addr_copy(sa->sa_data, dev->dev_addr);
|
||||
netif_info(tp, probe, dev, "Random ether addr %pM\n",
|
||||
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;
|
||||
|
||||
if (tp->version == RTL_VER_01) {
|
||||
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);
|
||||
if (ret < 0)
|
||||
ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data);
|
||||
}
|
||||
ret = determine_ethernet_addr(tp, &sa);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret < 0) {
|
||||
netif_err(tp, probe, dev, "Get ether addr fail\n");
|
||||
} else if (!is_valid_ether_addr(sa.sa_data)) {
|
||||
netif_err(tp, probe, dev, "Invalid ether addr %pM\n",
|
||||
sa.sa_data);
|
||||
eth_hw_addr_random(dev);
|
||||
ether_addr_copy(sa.sa_data, dev->dev_addr);
|
||||
if (tp->version == RTL_VER_01)
|
||||
ether_addr_copy(dev->dev_addr, sa.sa_data);
|
||||
else
|
||||
ret = rtl8152_set_mac_address(dev, &sa);
|
||||
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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue