libertas: EHS_REMOVE_WAKEUP is not always supported
authorDeepak Saxena <dsaxena@laptop.org>
Sun, 31 Oct 2010 13:40:33 +0000 (13:40 +0000)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 16 Nov 2010 21:37:02 +0000 (16:37 -0500)
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/9967

Signed-off-by: Deepak Saxena <dsaxena@laptop.org>
Signed-off-by: Daniel Drake <dsd@laptop.org>
[includes fixups by Paul Fox]
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas/main.c

index 70745928f3f86ed5f26eea3975133177d0b36e52..78c4da150a745d9cf6bf8db5de96054c9fb53b9b 100644 (file)
@@ -177,6 +177,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
        struct cmd_ds_host_sleep cmd_config;
        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.criteria = cpu_to_le32(criteria);
        cmd_config.gpio = priv->wol_gpio;
index f062ed5839016c4752d3f30922e27c7aa6dca2f8..f5a9851fc7ee79ca2960172d99d2f3bfe0faba52 100644 (file)
@@ -137,6 +137,7 @@ struct lbs_private {
        uint32_t wol_criteria;
        uint8_t wol_gpio;
        uint8_t wol_gap;
+       bool ehs_remove_supported;
 
        /* Transmitting */
        int tx_pending_len;             /* -1 while building packet */
index 35931cf4d6dbe8e7dd9acc620f98a5ec72819e10..6524c70363d9f507ac137c0482d3ff6094fd0ffd 100644 (file)
@@ -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))
                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;
 
 err_start_card:
index 47ce5a6ba120e9b9d707c56e93a79d35c1b5a3ea..6d7af91d52c27eeede1bd40f15c510f7070ebe7a 100644 (file)
@@ -844,9 +844,10 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
        priv->work_thread = create_singlethread_workqueue("lbs_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_gap = 20;
+       priv->ehs_remove_supported = true;
 
        goto done;