Commit ae63a33e authored by Deepak Saxena's avatar Deepak Saxena Committed by John W. Linville

libertas: EHS_REMOVE_WAKEUP is not always supported

Certain firmware versions, particularly the 8388 found on the XO-1,
do not support the EHS_REMOVE_WAKEUP command that is used to disable
WOL. Sending this command to the card will return a failure that
would get propagated up the stack and cause suspend to fail.

Instead, fall back to an all-zero wakeup mask.

This fixes http://dev.laptop.org/ticket/9967Signed-off-by: default avatarDeepak Saxena <dsaxena@laptop.org>
Signed-off-by: default avatarDaniel Drake <dsd@laptop.org>
[includes fixups by Paul Fox]
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent cf432988
...@@ -177,6 +177,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, ...@@ -177,6 +177,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
struct cmd_ds_host_sleep cmd_config; struct cmd_ds_host_sleep cmd_config;
int ret; int ret;
/*
* Certain firmware versions do not support EHS_REMOVE_WAKEUP command
* and the card will return a failure. Since we need to be
* able to reset the mask, in those cases we set a 0 mask instead.
*/
if (criteria == EHS_REMOVE_WAKEUP && !priv->ehs_remove_supported)
criteria = 0;
cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config)); cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
cmd_config.criteria = cpu_to_le32(criteria); cmd_config.criteria = cpu_to_le32(criteria);
cmd_config.gpio = priv->wol_gpio; cmd_config.gpio = priv->wol_gpio;
......
...@@ -137,6 +137,7 @@ struct lbs_private { ...@@ -137,6 +137,7 @@ struct lbs_private {
uint32_t wol_criteria; uint32_t wol_criteria;
uint8_t wol_gpio; uint8_t wol_gpio;
uint8_t wol_gap; uint8_t wol_gap;
bool ehs_remove_supported;
/* Transmitting */ /* Transmitting */
int tx_pending_len; /* -1 while building packet */ int tx_pending_len; /* -1 while building packet */
......
...@@ -345,6 +345,13 @@ static int if_usb_probe(struct usb_interface *intf, ...@@ -345,6 +345,13 @@ static int if_usb_probe(struct usb_interface *intf,
if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2)) if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
lbs_pr_err("cannot register lbs_flash_boot2 attribute\n"); lbs_pr_err("cannot register lbs_flash_boot2 attribute\n");
/*
* EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
*/
priv->wol_criteria = EHS_REMOVE_WAKEUP;
if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
priv->ehs_remove_supported = false;
return 0; return 0;
err_start_card: err_start_card:
......
...@@ -844,9 +844,10 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) ...@@ -844,9 +844,10 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
priv->work_thread = create_singlethread_workqueue("lbs_worker"); priv->work_thread = create_singlethread_workqueue("lbs_worker");
INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
priv->wol_criteria = 0xffffffff; priv->wol_criteria = EHS_REMOVE_WAKEUP;
priv->wol_gpio = 0xff; priv->wol_gpio = 0xff;
priv->wol_gap = 20; priv->wol_gap = 20;
priv->ehs_remove_supported = true;
goto done; goto done;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment