Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+35 −16
Original line number Diff line number Diff line
@@ -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 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 {
			   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;
}
@@ -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;