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

Commit 506e9025 authored by David Woodhouse's avatar David Woodhouse Committed by David S. Miller
Browse files

libertas: add ethtool support for wake-on-lan configuration



Also, check that suspend is refused if HOST_SLEEP_CFG hasn't been done.

Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent d1f7a5b8
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -111,21 +111,23 @@ int lbs_update_hw_spec(struct lbs_private *priv)
	return ret;
}

int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
		       uint8_t gpio, uint8_t gap)
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
{
	struct cmd_ds_host_sleep cmd_config;
	int ret;

	cmd_config.criteria = cpu_to_le32(criteria);
	cmd_config.gpio = gpio;
	cmd_config.gap = gap;
	cmd_config.gpio = priv->wol_gpio;
	cmd_config.gap = priv->wol_gap;

	ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
	if (ret) {
	if (!ret) {
		lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
		priv->wol_criteria = criteria;
	} else {
		lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
		return ret;
	}

	return ret;
}
EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
+1 −2
Original line number Diff line number Diff line
@@ -33,8 +33,7 @@ int lbs_set_channel(struct lbs_private *priv, u8 channel);

int lbs_mesh_config(struct lbs_private *priv, int enable);

int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
		       uint8_t gpio, uint8_t gap);
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
int lbs_suspend(struct lbs_private *priv);
int lbs_resume(struct lbs_private *priv);

+5 −0
Original line number Diff line number Diff line
@@ -153,6 +153,11 @@ struct lbs_private {
	int (*hw_get_int_status) (struct lbs_private *priv, u8 *);
	int (*hw_read_event_cause) (struct lbs_private *);

	/* Wake On LAN */
	uint32_t wol_criteria;
	uint8_t wol_gpio;
	uint8_t wol_gap;

	/* was struct lbs_adapter from here... */

	/** Wlan adapter data structure*/
+47 −0
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@
#include "dev.h"
#include "join.h"
#include "wext.h"
#include "cmd.h"

static const char * mesh_stat_strings[]= {
			"drop_duplicate_bcast",
			"drop_ttl_zero",
@@ -172,6 +174,49 @@ static void lbs_ethtool_get_strings(struct net_device *dev,
	lbs_deb_enter(LBS_DEB_ETHTOOL);
}

static void lbs_ethtool_get_wol(struct net_device *dev,
				struct ethtool_wolinfo *wol)
{
	struct lbs_private *priv = dev->priv;

	if (priv->wol_criteria == 0xffffffff) {
		/* Interface driver didn't configure wake */
		wol->supported = wol->wolopts = 0;
		return;
	}

	wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY;

	if (priv->wol_criteria & EHS_WAKE_ON_UNICAST_DATA)
		wol->wolopts |= WAKE_UCAST;
	if (priv->wol_criteria & EHS_WAKE_ON_MULTICAST_DATA)
		wol->wolopts |= WAKE_MCAST;
	if (priv->wol_criteria & EHS_WAKE_ON_BROADCAST_DATA)
		wol->wolopts |= WAKE_BCAST;
	if (priv->wol_criteria & EHS_WAKE_ON_MAC_EVENT)
		wol->wolopts |= WAKE_PHY;
}

static int lbs_ethtool_set_wol(struct net_device *dev,
			       struct ethtool_wolinfo *wol)
{
	struct lbs_private *priv = dev->priv;
	uint32_t criteria = 0;

	if (priv->wol_criteria == 0xffffffff && wol->wolopts)
		return -EOPNOTSUPP;

	if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
		return -EOPNOTSUPP;

	if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA;
	if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA;
	if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
	if (wol->wolopts & WAKE_PHY)   criteria |= EHS_WAKE_ON_MAC_EVENT;

	return lbs_host_sleep_cfg(priv, criteria);
}

struct ethtool_ops lbs_ethtool_ops = {
	.get_drvinfo = lbs_ethtool_get_drvinfo,
	.get_eeprom =  lbs_ethtool_get_eeprom,
@@ -179,5 +224,7 @@ struct ethtool_ops lbs_ethtool_ops = {
	.get_sset_count = lbs_ethtool_get_sset_count,
	.get_ethtool_stats = lbs_ethtool_get_stats,
	.get_strings = lbs_ethtool_get_strings,
	.get_wol = lbs_ethtool_get_wol,
	.set_wol = lbs_ethtool_set_wol,
};
+3 −3
Original line number Diff line number Diff line
@@ -242,9 +242,9 @@ static int if_usb_probe(struct usb_interface *intf,

	if_usb_set_boot2_ver(priv);

	/* Set suspend/resume configuration:
	   wake via GPIO2 after a 20ms delay */
	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA, 2, 20);
	priv->wol_gpio = 2; /* Wake via GPIO2... */
	priv->wol_gap = 20; /* ... after 20ms    */
	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);

	usb_get_dev(udev);
	usb_set_intfdata(intf, cardp);
Loading