diff options
author | Anna Neal <anna@cozybit.com> | 2008-10-20 19:46:56 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-21 11:06:03 -0500 |
commit | 582c1b538fb47a2d6a41dbdadb031086c49446c1 (patch) | |
tree | 04c84b61e6af5256e685c69bc195aee0b948adc5 /drivers/net | |
parent | 50da3ead624d46f1b9f1007a184691bbb841eba7 (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>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/libertas/cmd.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmd.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/defs.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/host.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/hostcmd.h | 26 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/if_usb.c | 3 |
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 | ||
162 | int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria) | 162 | int 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); |
57 | int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan); | 57 | int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan); |
58 | 58 | ||
59 | int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria); | 59 | int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, |
60 | struct wol_config *p_wol_config); | ||
60 | int lbs_suspend(struct lbs_private *priv); | 61 | int lbs_suspend(struct lbs_private *priv); |
61 | void lbs_resume(struct lbs_private *priv); | 62 | void 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 | ||
186 | struct ethtool_ops lbs_ethtool_ops = { | 186 | struct 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 */ | ||
224 | enum 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 */ |
224 | enum cmd_mesh_access_opts { | 232 | enum 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 | |||
585 | struct 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 | |||
595 | struct 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 | |||
583 | struct cmd_ds_host_sleep { | 604 | struct 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 | |||
590 | struct cmd_ds_802_11_key_material { | 614 | struct 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); |