[PATCH] libertas: keep mesh autostart enabled while asleep
authorLuis Carlos Cobo <luisca@cozybit.com>
Thu, 2 Aug 2007 17:16:02 +0000 (13:16 -0400)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:50:11 +0000 (16:50 -0700)
After loading the firmware, mesh autostart will be disabled. After that, the
user will still be able to enable or disable it at will. On suspend, it will be
always activated and later on resume it will go back to the state it had before
going to sleep.

Signed-off-by: Luis Carlos Cobo <luisca@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas/main.c

index f6b1402509f5883feaf2bb6d9dd4044d74713583..397c5fca0ff5788323ef6121aea05a0c91dac3d2 100644 (file)
@@ -103,6 +103,7 @@ struct _wlan_private {
        int open;
        int mesh_open;
        int infra_open;
+       int mesh_autostart_enabled;
 
        char name[DEV_NAME_LEN];
 
index 5efdeac6e2080e4d3566acc47c763f7ada618b35..670e1d23c0431ea55bcacd29ad77f76eb84c260d 100644 (file)
@@ -990,6 +990,19 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
        if (priv->adapter->psstate != PS_STATE_FULL_POWER)
                return -1;
 
+       if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
+               /* Mesh autostart must be activated while sleeping
+                * On resume it will go back to the current state
+                */
+               struct cmd_ds_mesh_access mesh_access;
+               memset(&mesh_access, 0, sizeof(mesh_access));
+               mesh_access.data[0] = cpu_to_le32(1);
+               libertas_prepare_and_send_command(priv,
+                               CMD_MESH_ACCESS,
+                               CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
+                               CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+       }
+
        netif_device_detach(cardp->eth_dev);
        netif_device_detach(priv->mesh_dev);
 
@@ -1017,6 +1030,19 @@ static int if_usb_resume(struct usb_interface *intf)
        netif_device_attach(cardp->eth_dev);
        netif_device_attach(priv->mesh_dev);
 
+       if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
+               /* Mesh autostart was activated while sleeping
+                * Disable it if appropriate
+                */
+               struct cmd_ds_mesh_access mesh_access;
+               memset(&mesh_access, 0, sizeof(mesh_access));
+               mesh_access.data[0] = cpu_to_le32(0);
+               libertas_prepare_and_send_command(priv,
+                               CMD_MESH_ACCESS,
+                               CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
+                               CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+       }
+
        lbs_deb_leave(LBS_DEB_USB);
        return 0;
 }
index 9ccc9524153bf149a4945fd856f5380d77a4b923..a3a17caae43997e6c2df4605deac195e46781170 100644 (file)
@@ -271,15 +271,20 @@ static ssize_t libertas_autostart_enabled_set(struct device * dev,
 {
        struct cmd_ds_mesh_access mesh_access;
        uint32_t datum;
+       wlan_private * priv = (to_net_dev(dev))->priv;
+       int ret;
 
        memset(&mesh_access, 0, sizeof(mesh_access));
        sscanf(buf, "%d", &datum);
        mesh_access.data[0] = cpu_to_le32(datum);
 
-       libertas_prepare_and_send_command((to_net_dev(dev))->priv,
+       ret = libertas_prepare_and_send_command(priv,
                        CMD_MESH_ACCESS,
                        CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
                        CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+       if (ret == 0)
+               priv->mesh_autostart_enabled = datum ? 1 : 0;
+
        return strlen(buf);
 }
 
@@ -853,6 +858,7 @@ static int wlan_setup_station_hw(wlan_private * priv)
 {
        int ret = -1;
        wlan_adapter *adapter = priv->adapter;
+       struct cmd_ds_mesh_access mesh_access;
 
        lbs_deb_enter(LBS_DEB_FW);
 
@@ -889,6 +895,21 @@ static int wlan_setup_station_hw(wlan_private * priv)
                goto done;
        }
 
+       /* Disable mesh autostart */
+       if (priv->mesh_dev) {
+               memset(&mesh_access, 0, sizeof(mesh_access));
+               mesh_access.data[0] = cpu_to_le32(0);
+               ret = libertas_prepare_and_send_command(priv,
+                               CMD_MESH_ACCESS,
+                               CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
+                               CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+               if (ret) {
+                       ret = -1;
+                       goto done;
+               }
+               priv->mesh_autostart_enabled = 0;
+       }
+
        ret = 0;
 done:
        lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);