aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Neal <anna@cozybit.com>2008-10-20 19:46:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-11-21 11:06:03 -0500
commit582c1b538fb47a2d6a41dbdadb031086c49446c1 (patch)
tree04c84b61e6af5256e685c69bc195aee0b948adc5
parent50da3ead624d46f1b9f1007a184691bbb841eba7 (diff)
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>
-rw-r--r--drivers/net/wireless/libertas/cmd.c18
-rw-r--r--drivers/net/wireless/libertas/cmd.h3
-rw-r--r--drivers/net/wireless/libertas/defs.h12
-rw-r--r--drivers/net/wireless/libertas/ethtool.c2
-rw-r--r--drivers/net/wireless/libertas/host.h8
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h26
-rw-r--r--drivers/net/wireless/libertas/if_usb.c3
7 files changed, 65 insertions, 7 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 957fd5a10a8d..639dd02d3d31 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -159,7 +159,8 @@ out:
159 return ret; 159 return ret;
160} 160}
161 161
162int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria) 162int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
163 struct wol_config *p_wol_config)
163{ 164{
164 struct cmd_ds_host_sleep cmd_config; 165 struct cmd_ds_host_sleep cmd_config;
165 int ret; 166 int ret;
@@ -169,10 +170,21 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
169 cmd_config.gpio = priv->wol_gpio; 170 cmd_config.gpio = priv->wol_gpio;
170 cmd_config.gap = priv->wol_gap; 171 cmd_config.gap = priv->wol_gap;
171 172
173 if (p_wol_config != NULL)
174 memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
175 sizeof(struct wol_config));
176 else
177 cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
178
172 ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config); 179 ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
173 if (!ret) { 180 if (!ret) {
174 lbs_deb_cmd("Set WOL criteria to %x\n", criteria); 181 if (criteria) {
175 priv->wol_criteria = criteria; 182 lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
183 priv->wol_criteria = criteria;
184 } else
185 memcpy((uint8_t *) p_wol_config,
186 (uint8_t *)&cmd_config.wol_conf,
187 sizeof(struct wol_config));
176 } else { 188 } else {
177 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret); 189 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
178 } 190 }
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 36be4c9703e0..392e578ca095 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -56,7 +56,8 @@ int lbs_mesh_config_send(struct lbs_private *priv,
56 uint16_t action, uint16_t type); 56 uint16_t action, uint16_t type);
57int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan); 57int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
58 58
59int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria); 59int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
60 struct wol_config *p_wol_config);
60int lbs_suspend(struct lbs_private *priv); 61int lbs_suspend(struct lbs_private *priv);
61void lbs_resume(struct lbs_private *priv); 62void lbs_resume(struct lbs_private *priv);
62 63
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 2d4666f26808..c364e4c01d1b 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -149,6 +149,18 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
149#define EHS_WAKE_ON_MAC_EVENT 0x0004 149#define EHS_WAKE_ON_MAC_EVENT 0x0004
150#define EHS_WAKE_ON_MULTICAST_DATA 0x0008 150#define EHS_WAKE_ON_MULTICAST_DATA 0x0008
151#define EHS_REMOVE_WAKEUP 0xFFFFFFFF 151#define EHS_REMOVE_WAKEUP 0xFFFFFFFF
152/* Wake rules for Host_Sleep_CFG command */
153#define WOL_RULE_NET_TYPE_INFRA_OR_IBSS 0x00
154#define WOL_RULE_NET_TYPE_MESH 0x10
155#define WOL_RULE_ADDR_TYPE_BCAST 0x01
156#define WOL_RULE_ADDR_TYPE_MCAST 0x08
157#define WOL_RULE_ADDR_TYPE_UCAST 0x02
158#define WOL_RULE_OP_AND 0x01
159#define WOL_RULE_OP_OR 0x02
160#define WOL_RULE_OP_INVALID 0xFF
161#define WOL_RESULT_VALID_CMD 0
162#define WOL_RESULT_NOSPC_ERR 1
163#define WOL_RESULT_EEXIST_ERR 2
152 164
153/** Misc constants */ 165/** Misc constants */
154/* This section defines 802.11 specific contants */ 166/* This section defines 802.11 specific contants */
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 156f471217bb..61d2f50470c8 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -180,7 +180,7 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
180 if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA; 180 if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
181 if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT; 181 if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT;
182 182
183 return lbs_host_sleep_cfg(priv, criteria); 183 return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
184} 184}
185 185
186struct ethtool_ops lbs_ethtool_ops = { 186struct ethtool_ops lbs_ethtool_ops = {
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 5004d7679c02..a17b778c172c 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -220,6 +220,14 @@ enum cmd_fwt_access_opts {
220 CMD_ACT_FWT_ACCESS_TIME, 220 CMD_ACT_FWT_ACCESS_TIME,
221}; 221};
222 222
223/* Define action or option for CMD_802_11_HOST_SLEEP_CFG */
224enum cmd_wol_cfg_opts {
225 CMD_ACT_ACTION_NONE = 0,
226 CMD_ACT_SET_WOL_RULE,
227 CMD_ACT_GET_WOL_RULE,
228 CMD_ACT_RESET_WOL_RULE,
229};
230
223/* Define action or option for CMD_MESH_ACCESS */ 231/* Define action or option for CMD_MESH_ACCESS */
224enum cmd_mesh_access_opts { 232enum cmd_mesh_access_opts {
225 CMD_ACT_MESH_GET_TTL = 1, 233 CMD_ACT_MESH_GET_TTL = 1,
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index d9f9a12a739e..e173b1b46c23 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -580,13 +580,37 @@ struct MrvlIEtype_keyParamSet {
580 u8 key[32]; 580 u8 key[32];
581}; 581};
582 582
583#define MAX_WOL_RULES 16
584
585struct host_wol_rule {
586 uint8_t rule_no;
587 uint8_t rule_ops;
588 __le16 sig_offset;
589 __le16 sig_length;
590 __le16 reserve;
591 __be32 sig_mask;
592 __be32 signature;
593};
594
595struct wol_config {
596 uint8_t action;
597 uint8_t pattern;
598 uint8_t no_rules_in_cmd;
599 uint8_t result;
600 struct host_wol_rule rule[MAX_WOL_RULES];
601};
602
603
583struct cmd_ds_host_sleep { 604struct cmd_ds_host_sleep {
584 struct cmd_header hdr; 605 struct cmd_header hdr;
585 __le32 criteria; 606 __le32 criteria;
586 uint8_t gpio; 607 uint8_t gpio;
587 uint8_t gap; 608 uint16_t gap;
609 struct wol_config wol_conf;
588} __attribute__ ((packed)); 610} __attribute__ ((packed));
589 611
612
613
590struct cmd_ds_802_11_key_material { 614struct cmd_ds_802_11_key_material {
591 struct cmd_header hdr; 615 struct cmd_header hdr;
592 616
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index cafbccb74143..fcd3fe6abe8c 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -178,7 +178,8 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
178 178
179 priv->wol_gpio = 2; /* Wake via GPIO2... */ 179 priv->wol_gpio = 2; /* Wake via GPIO2... */
180 priv->wol_gap = 20; /* ... after 20ms */ 180 priv->wol_gap = 20; /* ... after 20ms */
181 lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA); 181 lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA,
182 (struct wol_config *) NULL);
182 183
183 wake_method.hdr.size = cpu_to_le16(sizeof(wake_method)); 184 wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
184 wake_method.action = cpu_to_le16(CMD_ACT_GET); 185 wake_method.action = cpu_to_le16(CMD_ACT_GET);