libertas: Fine grained configuration of wake-on-lan.
Based on a patch from Shailendra Govardhan <shailen@marvell.com>. This patch allows implementation of more specific wake-on-lan rules than those of ethtool. Please note that only firmware 5.110.22.p20 and above supports this feature. This patch only implements the driver/firmware interface, not the userspace/driver interface. Signed-off-by: Anna Neal <anna@cozybit.com> Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
50da3ead62
commit
582c1b538f
@@ -159,7 +159,8 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
|
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
|
||||||
|
struct wol_config *p_wol_config)
|
||||||
{
|
{
|
||||||
struct cmd_ds_host_sleep cmd_config;
|
struct cmd_ds_host_sleep cmd_config;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -169,10 +170,21 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
|
|||||||
cmd_config.gpio = priv->wol_gpio;
|
cmd_config.gpio = priv->wol_gpio;
|
||||||
cmd_config.gap = priv->wol_gap;
|
cmd_config.gap = priv->wol_gap;
|
||||||
|
|
||||||
|
if (p_wol_config != NULL)
|
||||||
|
memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
|
||||||
|
sizeof(struct wol_config));
|
||||||
|
else
|
||||||
|
cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
|
||||||
|
|
||||||
ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
|
ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
if (criteria) {
|
||||||
lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
|
lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
|
||||||
priv->wol_criteria = criteria;
|
priv->wol_criteria = criteria;
|
||||||
|
} else
|
||||||
|
memcpy((uint8_t *) p_wol_config,
|
||||||
|
(uint8_t *)&cmd_config.wol_conf,
|
||||||
|
sizeof(struct wol_config));
|
||||||
} else {
|
} else {
|
||||||
lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
|
lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
|
||||||
}
|
}
|
||||||
|
@@ -56,7 +56,8 @@ int lbs_mesh_config_send(struct lbs_private *priv,
|
|||||||
uint16_t action, uint16_t type);
|
uint16_t action, uint16_t type);
|
||||||
int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
|
int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
|
||||||
|
|
||||||
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
|
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
|
||||||
|
struct wol_config *p_wol_config);
|
||||||
int lbs_suspend(struct lbs_private *priv);
|
int lbs_suspend(struct lbs_private *priv);
|
||||||
void lbs_resume(struct lbs_private *priv);
|
void lbs_resume(struct lbs_private *priv);
|
||||||
|
|
||||||
|
@@ -149,6 +149,18 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
|||||||
#define EHS_WAKE_ON_MAC_EVENT 0x0004
|
#define EHS_WAKE_ON_MAC_EVENT 0x0004
|
||||||
#define EHS_WAKE_ON_MULTICAST_DATA 0x0008
|
#define EHS_WAKE_ON_MULTICAST_DATA 0x0008
|
||||||
#define EHS_REMOVE_WAKEUP 0xFFFFFFFF
|
#define EHS_REMOVE_WAKEUP 0xFFFFFFFF
|
||||||
|
/* Wake rules for Host_Sleep_CFG command */
|
||||||
|
#define WOL_RULE_NET_TYPE_INFRA_OR_IBSS 0x00
|
||||||
|
#define WOL_RULE_NET_TYPE_MESH 0x10
|
||||||
|
#define WOL_RULE_ADDR_TYPE_BCAST 0x01
|
||||||
|
#define WOL_RULE_ADDR_TYPE_MCAST 0x08
|
||||||
|
#define WOL_RULE_ADDR_TYPE_UCAST 0x02
|
||||||
|
#define WOL_RULE_OP_AND 0x01
|
||||||
|
#define WOL_RULE_OP_OR 0x02
|
||||||
|
#define WOL_RULE_OP_INVALID 0xFF
|
||||||
|
#define WOL_RESULT_VALID_CMD 0
|
||||||
|
#define WOL_RESULT_NOSPC_ERR 1
|
||||||
|
#define WOL_RESULT_EEXIST_ERR 2
|
||||||
|
|
||||||
/** Misc constants */
|
/** Misc constants */
|
||||||
/* This section defines 802.11 specific contants */
|
/* This section defines 802.11 specific contants */
|
||||||
|
@@ -180,7 +180,7 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
|
|||||||
if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
|
if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
|
||||||
if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT;
|
if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT;
|
||||||
|
|
||||||
return lbs_host_sleep_cfg(priv, criteria);
|
return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ethtool_ops lbs_ethtool_ops = {
|
struct ethtool_ops lbs_ethtool_ops = {
|
||||||
|
@@ -220,6 +220,14 @@ enum cmd_fwt_access_opts {
|
|||||||
CMD_ACT_FWT_ACCESS_TIME,
|
CMD_ACT_FWT_ACCESS_TIME,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Define action or option for CMD_802_11_HOST_SLEEP_CFG */
|
||||||
|
enum cmd_wol_cfg_opts {
|
||||||
|
CMD_ACT_ACTION_NONE = 0,
|
||||||
|
CMD_ACT_SET_WOL_RULE,
|
||||||
|
CMD_ACT_GET_WOL_RULE,
|
||||||
|
CMD_ACT_RESET_WOL_RULE,
|
||||||
|
};
|
||||||
|
|
||||||
/* Define action or option for CMD_MESH_ACCESS */
|
/* Define action or option for CMD_MESH_ACCESS */
|
||||||
enum cmd_mesh_access_opts {
|
enum cmd_mesh_access_opts {
|
||||||
CMD_ACT_MESH_GET_TTL = 1,
|
CMD_ACT_MESH_GET_TTL = 1,
|
||||||
|
@@ -580,13 +580,37 @@ struct MrvlIEtype_keyParamSet {
|
|||||||
u8 key[32];
|
u8 key[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_WOL_RULES 16
|
||||||
|
|
||||||
|
struct host_wol_rule {
|
||||||
|
uint8_t rule_no;
|
||||||
|
uint8_t rule_ops;
|
||||||
|
__le16 sig_offset;
|
||||||
|
__le16 sig_length;
|
||||||
|
__le16 reserve;
|
||||||
|
__be32 sig_mask;
|
||||||
|
__be32 signature;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wol_config {
|
||||||
|
uint8_t action;
|
||||||
|
uint8_t pattern;
|
||||||
|
uint8_t no_rules_in_cmd;
|
||||||
|
uint8_t result;
|
||||||
|
struct host_wol_rule rule[MAX_WOL_RULES];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct cmd_ds_host_sleep {
|
struct cmd_ds_host_sleep {
|
||||||
struct cmd_header hdr;
|
struct cmd_header hdr;
|
||||||
__le32 criteria;
|
__le32 criteria;
|
||||||
uint8_t gpio;
|
uint8_t gpio;
|
||||||
uint8_t gap;
|
uint16_t gap;
|
||||||
|
struct wol_config wol_conf;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct cmd_ds_802_11_key_material {
|
struct cmd_ds_802_11_key_material {
|
||||||
struct cmd_header hdr;
|
struct cmd_header hdr;
|
||||||
|
|
||||||
|
@@ -178,7 +178,8 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
|
|||||||
|
|
||||||
priv->wol_gpio = 2; /* Wake via GPIO2... */
|
priv->wol_gpio = 2; /* Wake via GPIO2... */
|
||||||
priv->wol_gap = 20; /* ... after 20ms */
|
priv->wol_gap = 20; /* ... after 20ms */
|
||||||
lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
|
lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA,
|
||||||
|
(struct wol_config *) NULL);
|
||||||
|
|
||||||
wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
|
wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
|
||||||
wake_method.action = cpu_to_le16(CMD_ACT_GET);
|
wake_method.action = cpu_to_le16(CMD_ACT_GET);
|
||||||
|
Reference in New Issue
Block a user