state of CF suspend / resume

Holger Schurig hs4233 at mail.mn-solutions.de
Tue Apr 29 10:13:24 EDT 2008


Forgot the actual state:

# lbsdebug +host +cmd +main +thread
# pccardctl suspend
libertas_cs enter: if_cs_suspend()
libertas enter: __lbs_cmd()
libertas enter: __lbs_cmd_async()
libertas enter: lbs_get_cmd_ctrl_node()
libertas host: PREP_CMD: command 0x0045
libertas enter: lbs_queue_cmd()
libertas host: QUEUE_CMD: inserted command 0x0045 into cmdpendingq
libertas thread: 2: currenttxskb 00000000, dnld_send 0
libertas thread: 3: currenttxskb 00000000, dnld_sent 0
libertas thread: 4: currenttxskb 00000000, dnld_sent 0
libertas enter: lbs_execute_next_command()
libertas host: EXEC_NEXT_CMD: sending command 0x0045
libertas enter: lbs_submit_command()
libertas cmd: DNLD_CMD: command 0x0045, seq 7, size 8
libertas DNLD_CMD: 45 00 08 00 07 00 00 00
libertas_cs enter: if_cs_host_to_card(type 1, bytes 8)
libertas_cs enter: if_cs_send_cmd()
libertas thread: 1: currenttxskb 00000000, dnld_sent 2
libertas thread: sleeping, connect_status 1, ps_mode 0, ps_state 0
libertas enter (INT): command_timer_fn()
libertas: Command 45 timed out
libertas thread: 2: currenttxskb 00000000, dnld_send 2
libertas thread: 3: currenttxskb 00000000, dnld_sent 2
libertas thread: 4: currenttxskb 00000000, dnld_sent 2
libertas: requeueing command 45 due to timeout (#1)
libertas thread: 1: currenttxskb 00000000, dnld_sent 2
libertas thread: sleeping, connect_status 1, ps_mode 0, ps_state 0


So it seems that the card immediately goes to sleep, without
even responding with the command result ...





[WIP] libertas: support suspend/resume on CF

Doesn't work at all, but still ... (if someone can continue)
Signed-off-by: Holger Schurig <hs4233 at mail.mn-solutions.de>

Index: wireless-testing/drivers/net/wireless/libertas/if_cs.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/if_cs.c	2008-04-29 15:04:15.000000000 +0200
+++ wireless-testing/drivers/net/wireless/libertas/if_cs.c	2008-04-29 15:04:27.000000000 +0200
@@ -39,6 +39,8 @@
 #include "decl.h"
 #include "defs.h"
 #include "dev.h"
+#include "cmd.h"      /* for lbs_suspend, lbs_resume */
+#include "host.h"     /* for CMD_ACT_GET etc */
 
 
 /********************************************************************/
@@ -635,6 +637,28 @@ done:
 
 
 
+static void if_cs_setup_firmware(struct lbs_private *priv)
+{
+	struct cmd_ds_802_11_fw_wake_method wake_method;
+
+	lbs_deb_enter(LBS_DEB_CS)
+
+	/* define wake-on-lan data for CMD_801_11_HOST_SLEEP_CFG */
+	priv->wol_gpio = 2;      /* don't use a GPIO for wake up */
+	priv->wol_gap  = 20;     /* delay this 20 ms */
+	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_MAC_EVENT);
+
+	wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
+	wake_method.action = cpu_to_le16(CMD_ACT_SET);
+	wake_method.method = cpu_to_le16(CMD_WAKE_METHOD_GPIO);
+	lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method);
+
+	/* The firmware for the CF card supports powersave */
+	priv->ps_supported = 1;
+	lbs_deb_leave(LBS_DEB_CS)
+}
+
+
 /********************************************************************/
 /* Callback functions for libertas.ko                               */
 /********************************************************************/
@@ -845,8 +869,7 @@ static int if_cs_probe(struct pcmcia_dev
 		goto out3;
 	}
 
-	/* The firmware for the CF card supports powersave */
-	priv->ps_supported = 1;
+	if_cs_setup_firmware(priv);
 
 	ret = 0;
 	goto out;
@@ -887,6 +910,57 @@ static void if_cs_detach(struct pcmcia_d
 
 
 /********************************************************************/
+/* Suspend/resume                                                   */
+/********************************************************************/
+
+#ifdef CONFIG_PM
+static int if_cs_suspend(struct pcmcia_device *p_dev)
+{
+	struct if_cs_card *card = p_dev->priv;
+	struct lbs_private *priv = card->priv;
+	int ret;
+
+	lbs_deb_enter(LBS_DEB_CS);
+
+	if (priv->psstate != PS_STATE_FULL_POWER) {
+		ret = -1;
+		goto out;
+	}
+
+	ret = lbs_suspend(priv);
+	if (ret)
+		goto out;
+
+	/* TODO: do local stuff
+	 * if_usb: usb_kill_urb(cardp->tx_urb) */
+out:
+	lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
+	return ret;
+}
+
+
+static int if_cs_resume(struct pcmcia_device *p_dev)
+{
+	struct if_cs_card *card = p_dev->priv;
+	struct lbs_private *priv = card->priv;
+
+	lbs_deb_enter(LBS_DEB_CS);
+
+	/* TODO: do local stuff
+	 * if_usb: if_usb_submit_rx_urb(cardp); */
+
+	lbs_resume(priv);
+
+	lbs_deb_leave(LBS_DEB_CS);
+	return 0;
+}
+#else
+#define if_cs_suspend NULL
+#define if_cs_resume NULL
+#endif
+
+
+/********************************************************************/
 /* Module initialization                                            */
 /********************************************************************/
 
@@ -905,6 +979,8 @@ static struct pcmcia_driver lbs_driver =
 	.probe		= if_cs_probe,
 	.remove		= if_cs_detach,
 	.id_table       = if_cs_ids,
+	.suspend        = if_cs_suspend,
+	.resume         = if_cs_resume,
 };
 
 
Index: wireless-testing/drivers/net/wireless/libertas/main.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/main.c	2008-04-29 15:04:15.000000000 +0200
+++ wireless-testing/drivers/net/wireless/libertas/main.c	2008-04-29 15:04:27.000000000 +0200
@@ -702,7 +702,7 @@ static int lbs_thread(void *data)
 
 		if (shouldsleep) {
 			lbs_deb_thread("sleeping, connect_status %d, "
-				"ps_mode %d, ps_state %d\n",
+				"psmode %d, psstate %d\n",
 				priv->connect_status,
 				priv->psmode, priv->psstate);
 			spin_unlock_irq(&priv->driver_lock);



More information about the libertas-dev mailing list