aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-12-12 20:06:06 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:07:05 -0500
commit506e9025e030c441679fb1ae77fb0d6266c34443 (patch)
tree9869587068fae691b9bdee93c6b9df85ef786023 /drivers/net
parentd1f7a5b8cfefdb443a05a9e3d636fe7fef57459a (diff)
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: David Woodhouse <dwmw2@infradead.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/libertas/cmd.c14
-rw-r--r--drivers/net/wireless/libertas/cmd.h3
-rw-r--r--drivers/net/wireless/libertas/dev.h5
-rw-r--r--drivers/net/wireless/libertas/ethtool.c47
-rw-r--r--drivers/net/wireless/libertas/if_usb.c6
-rw-r--r--drivers/net/wireless/libertas/main.c8
6 files changed, 72 insertions, 11 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index f87cecb4c579..ddf15271244f 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -111,21 +111,23 @@ out:
111 return ret; 111 return ret;
112} 112}
113 113
114int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, 114int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
115 uint8_t gpio, uint8_t gap)
116{ 115{
117 struct cmd_ds_host_sleep cmd_config; 116 struct cmd_ds_host_sleep cmd_config;
118 int ret; 117 int ret;
119 118
120 cmd_config.criteria = cpu_to_le32(criteria); 119 cmd_config.criteria = cpu_to_le32(criteria);
121 cmd_config.gpio = gpio; 120 cmd_config.gpio = priv->wol_gpio;
122 cmd_config.gap = gap; 121 cmd_config.gap = priv->wol_gap;
123 122
124 ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config); 123 ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
125 if (ret) { 124 if (!ret) {
125 lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
126 priv->wol_criteria = criteria;
127 } else {
126 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret); 128 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
127 return ret;
128 } 129 }
130
129 return ret; 131 return ret;
130} 132}
131EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); 133EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index e44a0db50487..55f2436574df 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -33,8 +33,7 @@ int lbs_set_channel(struct lbs_private *priv, u8 channel);
33 33
34int lbs_mesh_config(struct lbs_private *priv, int enable); 34int lbs_mesh_config(struct lbs_private *priv, int enable);
35 35
36int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, 36int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
37 uint8_t gpio, uint8_t gap);
38int lbs_suspend(struct lbs_private *priv); 37int lbs_suspend(struct lbs_private *priv);
39int lbs_resume(struct lbs_private *priv); 38int lbs_resume(struct lbs_private *priv);
40 39
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 86b45a471fc6..60a6a51d0dcb 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -153,6 +153,11 @@ struct lbs_private {
153 int (*hw_get_int_status) (struct lbs_private *priv, u8 *); 153 int (*hw_get_int_status) (struct lbs_private *priv, u8 *);
154 int (*hw_read_event_cause) (struct lbs_private *); 154 int (*hw_read_event_cause) (struct lbs_private *);
155 155
156 /* Wake On LAN */
157 uint32_t wol_criteria;
158 uint8_t wol_gpio;
159 uint8_t wol_gap;
160
156 /* was struct lbs_adapter from here... */ 161 /* was struct lbs_adapter from here... */
157 162
158 /** Wlan adapter data structure*/ 163 /** Wlan adapter data structure*/
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index a54b4f406af2..21e6f988ea81 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -8,6 +8,8 @@
8#include "dev.h" 8#include "dev.h"
9#include "join.h" 9#include "join.h"
10#include "wext.h" 10#include "wext.h"
11#include "cmd.h"
12
11static const char * mesh_stat_strings[]= { 13static const char * mesh_stat_strings[]= {
12 "drop_duplicate_bcast", 14 "drop_duplicate_bcast",
13 "drop_ttl_zero", 15 "drop_ttl_zero",
@@ -172,6 +174,49 @@ static void lbs_ethtool_get_strings(struct net_device *dev,
172 lbs_deb_enter(LBS_DEB_ETHTOOL); 174 lbs_deb_enter(LBS_DEB_ETHTOOL);
173} 175}
174 176
177static void lbs_ethtool_get_wol(struct net_device *dev,
178 struct ethtool_wolinfo *wol)
179{
180 struct lbs_private *priv = dev->priv;
181
182 if (priv->wol_criteria == 0xffffffff) {
183 /* Interface driver didn't configure wake */
184 wol->supported = wol->wolopts = 0;
185 return;
186 }
187
188 wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY;
189
190 if (priv->wol_criteria & EHS_WAKE_ON_UNICAST_DATA)
191 wol->wolopts |= WAKE_UCAST;
192 if (priv->wol_criteria & EHS_WAKE_ON_MULTICAST_DATA)
193 wol->wolopts |= WAKE_MCAST;
194 if (priv->wol_criteria & EHS_WAKE_ON_BROADCAST_DATA)
195 wol->wolopts |= WAKE_BCAST;
196 if (priv->wol_criteria & EHS_WAKE_ON_MAC_EVENT)
197 wol->wolopts |= WAKE_PHY;
198}
199
200static int lbs_ethtool_set_wol(struct net_device *dev,
201 struct ethtool_wolinfo *wol)
202{
203 struct lbs_private *priv = dev->priv;
204 uint32_t criteria = 0;
205
206 if (priv->wol_criteria == 0xffffffff && wol->wolopts)
207 return -EOPNOTSUPP;
208
209 if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
210 return -EOPNOTSUPP;
211
212 if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA;
213 if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA;
214 if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
215 if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT;
216
217 return lbs_host_sleep_cfg(priv, criteria);
218}
219
175struct ethtool_ops lbs_ethtool_ops = { 220struct ethtool_ops lbs_ethtool_ops = {
176 .get_drvinfo = lbs_ethtool_get_drvinfo, 221 .get_drvinfo = lbs_ethtool_get_drvinfo,
177 .get_eeprom = lbs_ethtool_get_eeprom, 222 .get_eeprom = lbs_ethtool_get_eeprom,
@@ -179,5 +224,7 @@ struct ethtool_ops lbs_ethtool_ops = {
179 .get_sset_count = lbs_ethtool_get_sset_count, 224 .get_sset_count = lbs_ethtool_get_sset_count,
180 .get_ethtool_stats = lbs_ethtool_get_stats, 225 .get_ethtool_stats = lbs_ethtool_get_stats,
181 .get_strings = lbs_ethtool_get_strings, 226 .get_strings = lbs_ethtool_get_strings,
227 .get_wol = lbs_ethtool_get_wol,
228 .set_wol = lbs_ethtool_set_wol,
182}; 229};
183 230
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 15715a6b59e0..819141652599 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -242,9 +242,9 @@ static int if_usb_probe(struct usb_interface *intf,
242 242
243 if_usb_set_boot2_ver(priv); 243 if_usb_set_boot2_ver(priv);
244 244
245 /* Set suspend/resume configuration: 245 priv->wol_gpio = 2; /* Wake via GPIO2... */
246 wake via GPIO2 after a 20ms delay */ 246 priv->wol_gap = 20; /* ... after 20ms */
247 lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA, 2, 20); 247 lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
248 248
249 usb_get_dev(udev); 249 usb_get_dev(udev);
250 usb_set_intfdata(intf, cardp); 250 usb_set_intfdata(intf, cardp);
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 1ea119ed3d22..5e2f3296be34 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -839,6 +839,11 @@ int lbs_suspend(struct lbs_private *priv)
839 struct cmd_header cmd; 839 struct cmd_header cmd;
840 int ret; 840 int ret;
841 841
842 if (priv->wol_criteria == 0xffffffff) {
843 lbs_pr_info("Suspend attempt without configuring wake params!\n");
844 return -EINVAL;
845 }
846
842 memset(&cmd, 0, sizeof(cmd)); 847 memset(&cmd, 0, sizeof(cmd));
843 848
844 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd, 849 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
@@ -1088,6 +1093,9 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1088 sprintf(priv->mesh_ssid, "mesh"); 1093 sprintf(priv->mesh_ssid, "mesh");
1089 priv->mesh_ssid_len = 4; 1094 priv->mesh_ssid_len = 4;
1090 1095
1096 priv->wol_criteria = 0xffffffff;
1097 priv->wol_gpio = 0xff;
1098
1091 goto done; 1099 goto done;
1092 1100
1093err_init_adapter: 1101err_init_adapter: