Commit afdb3df2 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents d1edc085 25766271
......@@ -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 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa)
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment