Commit 50505316 authored by Justin Chen's avatar Justin Chen Committed by Jakub Kicinski
Browse files

net: usb: ax88179_178a: wol optimizations



- Check if wol is supported on reset instead of everytime get_wol
is called.
- Save wolopts in private data instead of relying on the HW to save it.
- Defer enabling WoL until suspend instead of enabling it everytime
set_wol is called.

Signed-off-by: default avatarJustin Chen <justinpopo6@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 2bcbd3d8
Loading
Loading
Loading
Loading
+28 −24
Original line number Diff line number Diff line
@@ -171,6 +171,8 @@ struct ax88179_data {
	u8  eee_active;
	u16 rxctl;
	u8 in_pm;
	u32 wol_supported;
	u32 wolopts;
};

struct ax88179_int_data {
@@ -400,6 +402,7 @@ ax88179_phy_write_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad,
static int ax88179_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct usbnet *dev = usb_get_intfdata(intf);
	struct ax88179_data *priv = dev->driver_priv;
	u16 tmp16;
	u8 tmp8;

@@ -407,6 +410,19 @@ static int ax88179_suspend(struct usb_interface *intf, pm_message_t message)

	usbnet_suspend(intf, message);

	/* Enable WoL */
	if (priv->wolopts) {
		ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
				 1, 1, &tmp8);
		if (priv->wolopts & WAKE_PHY)
			tmp8 |= AX_MONITOR_MODE_RWLC;
		if (priv->wolopts & WAKE_MAGIC)
			tmp8 |= AX_MONITOR_MODE_RWMP;

		ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
				  1, 1, &tmp8);
	}

	/* Disable RX path */
	ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
			 2, 2, &tmp16);
@@ -480,40 +496,22 @@ static void
ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{
	struct usbnet *dev = netdev_priv(net);
	u8 opt;

	if (ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
			     1, 1, &opt) < 0) {
		wolinfo->supported = 0;
		wolinfo->wolopts = 0;
		return;
	}
	struct ax88179_data *priv = dev->driver_priv;

	wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
	wolinfo->wolopts = 0;
	if (opt & AX_MONITOR_MODE_RWLC)
		wolinfo->wolopts |= WAKE_PHY;
	if (opt & AX_MONITOR_MODE_RWMP)
		wolinfo->wolopts |= WAKE_MAGIC;
	wolinfo->supported = priv->wol_supported;
	wolinfo->wolopts = priv->wolopts;
}

static int
ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{
	struct usbnet *dev = netdev_priv(net);
	u8 opt = 0;
	struct ax88179_data *priv = dev->driver_priv;

	if (wolinfo->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
	if (wolinfo->wolopts & ~(priv->wol_supported))
		return -EINVAL;

	if (wolinfo->wolopts & WAKE_PHY)
		opt |= AX_MONITOR_MODE_RWLC;
	if (wolinfo->wolopts & WAKE_MAGIC)
		opt |= AX_MONITOR_MODE_RWMP;

	if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
			      1, 1, &opt) < 0)
		return -EINVAL;
	priv->wolopts = wolinfo->wolopts;

	return 0;
}
@@ -1636,6 +1634,12 @@ static int ax88179_reset(struct usbnet *dev)
	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
			  2, 2, tmp16);

	/* Check if WoL is supported */
	ax179_data->wol_supported = 0;
	if (ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
			     1, 1, &tmp) > 0)
		ax179_data->wol_supported = WAKE_MAGIC | WAKE_PHY;

	ax88179_led_setting(dev);

	ax179_data->eee_enabled = 0;