From marc.pignat at hevs.ch  Wed Oct  1 04:43:33 2008
From: marc.pignat at hevs.ch (Marc Pignat)
Date: Wed, 1 Oct 2008 10:43:33 +0200
Subject: [RFC, PATCH v2] libertas: unify request_firmware failure
In-Reply-To: <1222792480.27374.25.camel@localhost.localdomain>
References: <200809301625.40554.marc.pignat@hevs.ch>
	<1222792480.27374.25.camel@localhost.localdomain>
Message-ID: <200810011043.34229.marc.pignat@hevs.ch>

Use almost the same string for all interfaces (USB, compact flash and SDIO)
when request_firmware fails.

Signed-off-by: Marc Pignat <marc.pignat at hevs.ch>
---

Hi all!

This patch is an attemp to clarify the message "firmware not found, please fix
your userspace (== this is not a libertas bug)".

changes from v1:
	* replaced %#x with %d because "ret" is supposed to be a negative
	  integer (suggested by Dan Williams).

Best regards

Marc




patch agaisnt 2.6.27-rc7:

diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 8941919..5f8e68b 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -553,7 +553,8 @@ static int if_cs_prog_helper(struct if_cs_card *card)
 	ret = request_firmware(&fw, "libertas_cs_helper.fw",
 		&handle_to_dev(card->p_dev));
 	if (ret) {
-		lbs_pr_err("can't load helper firmware\n");
+		lbs_pr_err("request_firmware() failed with %d\n", ret);
+		lbs_pr_err("helper firmware libertas_cs_helper.fw not found\n");
 		ret = -ENODEV;
 		goto done;
 	}
@@ -626,7 +627,8 @@ static int if_cs_prog_real(struct if_cs_card *card)
 	ret = request_firmware(&fw, "libertas_cs.fw",
 		&handle_to_dev(card->p_dev));
 	if (ret) {
-		lbs_pr_err("can't load firmware\n");
+		lbs_pr_err("request_firmware() failed with %d\n", ret);
+		lbs_pr_err("firmware libertas_cs.fw not found\n");
 		ret = -ENODEV;
 		goto done;
 	}
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index b54e2ea..319e211 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -396,7 +396,8 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
 
 	ret = request_firmware(&fw, card->helper, &card->func->dev);
 	if (ret) {
-		lbs_pr_err("can't load helper firmware\n");
+		lbs_pr_err("request_firmware() failed with %d\n", ret);
+		lbs_pr_err("helper firmware %s not found\n", card->helper);
 		goto out;
 	}
 
@@ -512,7 +513,8 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
 
 	ret = request_firmware(&fw, card->firmware, &card->func->dev);
 	if (ret) {
-		lbs_pr_err("can't load firmware\n");
+		lbs_pr_err("request_firmware() failed with %d\n", ret);
+		lbs_pr_err("firmware %s not found\n", card->firmware);
 		goto out;
 	}
 
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 632c291..285be43 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -819,7 +819,7 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp)
 
 	if ((ret = request_firmware(&cardp->fw, lbs_fw_name,
 				    &cardp->udev->dev)) < 0) {
-		lbs_pr_err("request_firmware() failed with %#x\n", ret);
+		lbs_pr_err("request_firmware() failed with %d\n", ret);
 		lbs_pr_err("firmware %s not found\n", lbs_fw_name);
 		goto done;
 	}


From hs4233 at mail.mn-solutions.de  Wed Oct  1 09:02:32 2008
From: hs4233 at mail.mn-solutions.de (Holger Schurig)
Date: Wed, 1 Oct 2008 15:02:32 +0200
Subject: [RFC, PATCH v2] libertas: unify request_firmware failure
In-Reply-To: <200810011043.34229.marc.pignat@hevs.ch>
References: <200809301625.40554.marc.pignat@hevs.ch>
	<1222792480.27374.25.camel@localhost.localdomain>
	<200810011043.34229.marc.pignat@hevs.ch>
Message-ID: <200810011502.32427.hs4233@mail.mn-solutions.de>

> -		lbs_pr_err("can't load helper firmware\n");
> +		lbs_pr_err("request_firmware() failed with %d\n", ret);
> +		lbs_pr_err("helper firmware libertas_cs_helper.fw not found\n"); ret = -ENODEV;

While I don't have a problem with the idea per
se, I don't like it outputting two error lines now.

So for if_cs.c, I like the original code better.

I don't care to emit the error number, won't be usable to most
people anyway. And I don't care about outputting the filename,
because udev will already show you the filename if it doesn't
find what was requested.


From jeffs at fomsystems.com  Thu Oct  2 10:17:30 2008
From: jeffs at fomsystems.com (Jeff Sutherland)
Date: Thu, 2 Oct 2008 10:17:30 -0400
Subject: problem with libertas driver, Marvell W8686, and PXA270 on 2.6.27-rc7
Message-ID: <200810021017.31310.jeffs@fomsystems.com>

I'm seeking some insight into the structure of the command flow when 
communicating with a Murata wifi module using the W8686 chip connected via 
SDIO on a PXA270-based system.  On about 2 out of 3 boot ups, and 
occasionally when configuring the network interface by hand after the system 
is up and running, the kernel will oops from the BUG() instruction at line 
147 of drivers/net/wireless/libertas/if_sdio.c.  When this happens, the value 
of priv->resp_len[resp_idx] is always sitting at 142.  It's almost as if the 
command processing in drivers/net/wireless/libertas/main.c is missing a 
command somehow.  Curiously, this only seems to happen when the interface is 
configured to use WEP or WPA security.  I haven't seen the problem occur when 
trying to configure an interface associated with an open A/P.  Also I note 
from my a/p's web page that the module does in fact associate fine every 
time, as key loading and other configuration occurs early on, and the a/p is 
currently using WEP plus mac filtering.  It's just things go belly up when 
the startup scripts try to bring up the interface.  This happens regardless 
of the firmware version used.  I've tried v7, v8, and v9 firmware with 
several different kernels from 2.6.25 through to the latest dev stuff from 
John Linville's wireless-testing git repo.

There are some issues with the pxa mmc controller hardware as we are painfully 
aware of, but note that once the interface is successfully configured the 
network stays up solidly, there don't appear to be any problems once it is 
configured.  From looking at the code, I suspect a race condition somewhere 
in the SDIO layer that's causing things to get out of sequence when it comes 
time to configure the network interface.  A printk placed in certain places 
causes the driver to fail 100% of the time at that same point in the code 
with the same value of response length, so something must be on the hairy 
edge someplace when it does work.

Regards,
-Jeff
-- 
FOM Systems Inc.   www.fomsystems.com



From dcbw at redhat.com  Thu Oct  2 17:40:01 2008
From: dcbw at redhat.com (Dan Williams)
Date: Thu, 02 Oct 2008 17:40:01 -0400
Subject: problem with libertas driver, Marvell W8686, and PXA270 on
	2.6.27-rc7
In-Reply-To: <200810021017.31310.jeffs@fomsystems.com>
References: <200810021017.31310.jeffs@fomsystems.com>
Message-ID: <1222983601.12505.44.camel@72-58-93-37.area3.spcsdns.net>

On Thu, 2008-10-02 at 10:17 -0400, Jeff Sutherland wrote:
> I'm seeking some insight into the structure of the command flow when 
> communicating with a Murata wifi module using the W8686 chip connected via 
> SDIO on a PXA270-based system.  On about 2 out of 3 boot ups, and 
> occasionally when configuring the network interface by hand after the system 
> is up and running, the kernel will oops from the BUG() instruction at line 
> 147 of drivers/net/wireless/libertas/if_sdio.c.  When this happens, the value 
> of priv->resp_len[resp_idx] is always sitting at 142.  It's almost as if the 
> command processing in drivers/net/wireless/libertas/main.c is missing a 
> command somehow.  Curiously, this only seems to happen when the interface is 

Hmm, could well be.  The flow is supposed to be that the interface code
puts responses into the unused slot and wakes up the main thread, and
the main thread processes the response.  Could be that if a second
command response comes back from the card too soon the main thread
wouldn't be woken up to process it yet.

Everything I've seen and read indicates that commands are serialized and
thus we can only have one command outstanding at any one time.  Thus we
can probably rule out fundamental problems with the implementation, but
instead focus on bugs and/or quirks.

Could you by any chance minimally parse the command response in
if_sdio_handle_cmd() with something like:

diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index b54e2ea..024a81e 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -144,6 +144,18 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card,
        spin_lock_irqsave(&priv->driver_lock, flags);
 
        i = (priv->resp_idx == 0) ? 1 : 0;
+
+if (priv->resp_len[i])
+{
+struct cmd_header *resp = (void *) buffer;
+uint16_t respcmd = le16_to_cpu(resp->command);
+uint16_t result = le16_to_cpu(resp->result);
+uint16_t seqnum = le16_to_cpu(resp->seqnum);
+
+lbs_deb_sdio("CMD_RESP: response 0x%04x, result 0x%04x, seq %d, size %d\n",
+            respcmd, result, seqnum, size);
+}
+
        BUG_ON(priv->resp_len[i]);
        priv->resp_len[i] = size;
        memcpy(priv->resp_buf[i], buffer, size);

that coupled with turning on LBS_DEB_CMD and LBS_DEB_SDIO would be quite
interesting to see the results of and should help narrow down what's
going on.  I'm especially interested in the sequence number to see if if
the before-BUG_ON response is the same sequence # as the BUG_ON
response.

Dan

> configured to use WEP or WPA security.  I haven't seen the problem occur when 
> trying to configure an interface associated with an open A/P.  Also I note 
> from my a/p's web page that the module does in fact associate fine every 
> time, as key loading and other configuration occurs early on, and the a/p is 
> currently using WEP plus mac filtering.  It's just things go belly up when 
> the startup scripts try to bring up the interface.  This happens regardless 
> of the firmware version used.  I've tried v7, v8, and v9 firmware with 
> several different kernels from 2.6.25 through to the latest dev stuff from 
> John Linville's wireless-testing git repo.
> 
> There are some issues with the pxa mmc controller hardware as we are painfully 
> aware of, but note that once the interface is successfully configured the 
> network stays up solidly, there don't appear to be any problems once it is 
> configured.  From looking at the code, I suspect a race condition somewhere 
> in the SDIO layer that's causing things to get out of sequence when it comes 
> time to configure the network interface.  A printk placed in certain places 
> causes the driver to fail 100% of the time at that same point in the code 
> with the same value of response length, so something must be on the hairy 
> edge someplace when it does work.
> 
> Regards,
> -Jeff



From jeffs at fomsystems.com  Thu Oct  2 21:56:30 2008
From: jeffs at fomsystems.com (Jeff Sutherland)
Date: Thu, 2 Oct 2008 21:56:30 -0400
Subject: problem with libertas driver, Marvell W8686,
	and PXA270 on 2.6.27-rc7
In-Reply-To: <1222983601.12505.44.camel@72-58-93-37.area3.spcsdns.net>
References: <200810021017.31310.jeffs@fomsystems.com>
	<1222983601.12505.44.camel@72-58-93-37.area3.spcsdns.net>
Message-ID: <200810022156.32282.jeffs@fomsystems.com>

On Thursday 02 October 2008, Dan Williams wrote:
> On Thu, 2008-10-02 at 10:17 -0400, Jeff Sutherland wrote:
> > I'm seeking some insight into the structure of the command flow when
> > communicating with a Murata wifi module using the W8686 chip connected
> > via SDIO on a PXA270-based system.  On about 2 out of 3 boot ups, and
> > occasionally when configuring the network interface by hand after the
> > system is up and running, the kernel will oops from the BUG() instruction
> > at line 147 of drivers/net/wireless/libertas/if_sdio.c.  When this
> > happens, the value of priv->resp_len[resp_idx] is always sitting at 142. 
> > It's almost as if the command processing in
> > drivers/net/wireless/libertas/main.c is missing a command somehow. 
> > Curiously, this only seems to happen when the interface is
>
> Hmm, could well be.  The flow is supposed to be that the interface code
> puts responses into the unused slot and wakes up the main thread, and
> the main thread processes the response.  Could be that if a second
> command response comes back from the card too soon the main thread
> wouldn't be woken up to process it yet.
>
> Everything I've seen and read indicates that commands are serialized and
> thus we can only have one command outstanding at any one time.  Thus we
> can probably rule out fundamental problems with the implementation, but
> instead focus on bugs and/or quirks.
>
> Could you by any chance minimally parse the command response in
> if_sdio_handle_cmd() with something like:
>
> diff --git a/drivers/net/wireless/libertas/if_sdio.c
> b/drivers/net/wireless/libertas/if_sdio.c index b54e2ea..024a81e 100644
> --- a/drivers/net/wireless/libertas/if_sdio.c
> +++ b/drivers/net/wireless/libertas/if_sdio.c
> @@ -144,6 +144,18 @@ static int if_sdio_handle_cmd(struct if_sdio_card
> *card, spin_lock_irqsave(&priv->driver_lock, flags);
>
>         i = (priv->resp_idx == 0) ? 1 : 0;
> +
> +if (priv->resp_len[i])
> +{
> +struct cmd_header *resp = (void *) buffer;
> +uint16_t respcmd = le16_to_cpu(resp->command);
> +uint16_t result = le16_to_cpu(resp->result);
> +uint16_t seqnum = le16_to_cpu(resp->seqnum);
> +
> +lbs_deb_sdio("CMD_RESP: response 0x%04x, result 0x%04x, seq %d, size
> %d\n", +            respcmd, result, seqnum, size);
> +}
> +
>         BUG_ON(priv->resp_len[i]);
>         priv->resp_len[i] = size;
>         memcpy(priv->resp_buf[i], buffer, size);
>
> that coupled with turning on LBS_DEB_CMD and LBS_DEB_SDIO would be quite
> interesting to see the results of and should help narrow down what's
> going on.  I'm especially interested in the sequence number to see if if
> the before-BUG_ON response is the same sequence # as the BUG_ON
> response.
>
> Dan

Well, as luck would have it, instrumenting the code has fixed the problem.  I 
can not get to fail anymore.  Not once, no way.  See the transcript below.  
Before, when things went bad it was always somewhere around sequence number 
25 or 26.  I'll try fiddling with the debug level to see if I can get it to 
fail whilst also producing something that might be informative.

Thanks!
-Jeff

Setting up IP spoofing protection: rp_filter.
Configuring network interfaces...
libertas cmd: DNLD_CMD: command 0x0010, seq 7, size 18
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas cmd: CMD_RESP: response 0x8010, seq 7, size 18
libertas cmd: DNLD_CMD: command 0x0028, seq 8, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x8028, seq 8, size 12
libertas cmd: DNLD_CMD: command 0x001e, seq 9, size 14
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 18 bytes
libertas cmd: CMD_RESP: response 0x801e, seq 9, size 14
libertas cmd: SET_WEP: add key 0 (104 bit)
libertas cmd: DNLD_CMD: command 0x0013, seq 10, size 80
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 84 bytes
libertas cmd: CMD_RESP: response 0x8013, seq 10, size 80
libertas cmd: DNLD_CMD: command 0x0028, seq 11, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x8028, seq 11, size 12
libertas cmd: DNLD_CMD: command 0x0028, seq 12, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x8028, seq 12, size 12
libertas cmd: DNLD_CMD: command 0x002f, seq 13, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x802f, seq 13, size 12
libertas cmd: DNLD_CMD: command 0x0016, seq 14, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 14, size 142
libertas cmd: DNLD_CMD: command 0x0006, seq 15, size 75
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 15 bytes
libertas cmd: CMD_RESP: response 0x8006, seq 15, size 11
libertas cmd: DNLD_CMD: command 0x0016, seq 16, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 16, size 142
libertas cmd: DNLD_CMD: command 0x0006, seq 17, size 75
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 15 bytes
libertas cmd: CMD_RESP: response 0x8006, seq 17, size 11
libertas cmd: DNLD_CMD: command 0x0016, seq 18, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 18, size 142
libertas cmd: DNLD_CMD: command 0x0006, seq 19, size 68
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 94 bytes
libertas cmd: CMD_RESP: response 0x8006, seq 19, size 90
libertas cmd: DNLD_CMD: command 0x0011, seq 20, size 25
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 29 bytes
libertas cmd: CMD_RESP: response 0x8011, seq 20, size 25
libertas cmd: RADIO_CONTROL: radio ON, preamble 0
libertas cmd: DNLD_CMD: command 0x001c, seq 21, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x801c, seq 21, size 12
libertas cmd: DNLD_CMD: command 0x0050, seq 22, size 64
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 45 bytes
libertas cmd: CMD_RESP: response 0x8012, seq 22, size 41
libertas cmd: DNLD_CMD: command 0x001f, seq 23, size 16
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 20 bytes
libertas cmd: CMD_RESP: response 0x801f, seq 23, size 16
libertas cmd: RSSI: beacon 217, avg 0
libertas cmd: DNLD_CMD: command 0x000b, seq 24, size 60
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 64 bytes
libertas cmd: CMD_RESP: response 0x800b, seq 24, size 60
libertas cmd: DNLD_CMD: command 0x001f, seq 25, size 16
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 20 bytes
libertas cmd: CMD_RESP: response 0x801f, seq 25, size 16
libertas cmd: RSSI: beacon 218, avg 0
libertas cmd: DNLD_CMD: command 0x001e, seq 26, size 14
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 18 bytes
libertas cmd: CMD_RESP: response 0x801e, seq 26, size 14
libertas cmd: DNLD_CMD: command 0x0016, seq 27, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 27, size 142
libertas cmd: DNLD_CMD: command 0x0016, seq 28, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 28, size 142
libertas cmd: DNLD_CMD: command 0x0016, seq 29, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 29, size 142
udhcpc (v1.2.1) started
udhcpc[1502]: udhcpc (v1.2.1) started
run-parts: /etc/udhcpc.d/00avahi-autoipd exited with return code 1: Success
libertas cmd: DNLD_CMD: command 0x0010, seq 30, size 18
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas cmd: CMD_RESP: response 0x8010, seq 30, size 18
Sending discover...
udhcpc[1502]: Sending discover...
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 92 bytes
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 390 bytes
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 92 bytes
Sending select for 192.168.13.49...
udhcpc[1502]: Sending select for 192.168.13.49...
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 92 bytes
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 390 bytes
Lease of 192.168.13.49 obtained, lease time 999999
udhcpc[1502]: Lease of 192.168.13.49 obtained, lease time 999999
run-parts: /etc/udhcpc.d/00avahi-autoipd exited with return code 1: Success
libertas cmd: DNLD_CMD: command 0x0010, seq 31, size 18
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas cmd: CMD_RESP: response 0x8010, seq 31, size 18
libertas cmd: DNLD_CMD: command 0x0010, seq 32, size 18
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas cmd: CMD_RESP: response 0x8010, seq 32, size 18
adding dns 192.168.13.200
adding dns 192.168.13.1
done.
Starting portmap daemon: portmap.

-- 
FOM Systems Inc.   www.fomsystems.com


From jeffs at fomsystems.com  Thu Oct  2 22:25:14 2008
From: jeffs at fomsystems.com (Jeff Sutherland)
Date: Thu, 2 Oct 2008 22:25:14 -0400
Subject: problem with libertas driver, Marvell W8686,
	and PXA270 on 2.6.27-rc7
In-Reply-To: <1222983601.12505.44.camel@72-58-93-37.area3.spcsdns.net>
References: <200810021017.31310.jeffs@fomsystems.com>
	<1222983601.12505.44.camel@72-58-93-37.area3.spcsdns.net>
Message-ID: <200810022225.15453.jeffs@fomsystems.com>

On Thursday 02 October 2008, Dan Williams wrote:
> On Thu, 2008-10-02 at 10:17 -0400, Jeff Sutherland wrote:
> > I'm seeking some insight into the structure of the command flow when
> > communicating with a Murata wifi module using the W8686 chip connected
> > via SDIO on a PXA270-based system.  On about 2 out of 3 boot ups, and
> > occasionally when configuring the network interface by hand after the
> > system is up and running, the kernel will oops from the BUG() instruction
> > at line 147 of drivers/net/wireless/libertas/if_sdio.c.  When this
> > happens, the value of priv->resp_len[resp_idx] is always sitting at 142. 
> > It's almost as if the command processing in
> > drivers/net/wireless/libertas/main.c is missing a command somehow. 
> > Curiously, this only seems to happen when the interface is
>
> Hmm, could well be.  The flow is supposed to be that the interface code
> puts responses into the unused slot and wakes up the main thread, and
> the main thread processes the response.  Could be that if a second
> command response comes back from the card too soon the main thread
> wouldn't be woken up to process it yet.
>
> Everything I've seen and read indicates that commands are serialized and
> thus we can only have one command outstanding at any one time.  Thus we
> can probably rule out fundamental problems with the implementation, but
> instead focus on bugs and/or quirks.
>
> Could you by any chance minimally parse the command response in
> if_sdio_handle_cmd() with something like:
>
> diff --git a/drivers/net/wireless/libertas/if_sdio.c
> b/drivers/net/wireless/libertas/if_sdio.c index b54e2ea..024a81e 100644
> --- a/drivers/net/wireless/libertas/if_sdio.c
> +++ b/drivers/net/wireless/libertas/if_sdio.c
> @@ -144,6 +144,18 @@ static int if_sdio_handle_cmd(struct if_sdio_card
> *card, spin_lock_irqsave(&priv->driver_lock, flags);
>
>         i = (priv->resp_idx == 0) ? 1 : 0;
> +
> +if (priv->resp_len[i])
> +{
> +struct cmd_header *resp = (void *) buffer;
> +uint16_t respcmd = le16_to_cpu(resp->command);
> +uint16_t result = le16_to_cpu(resp->result);
> +uint16_t seqnum = le16_to_cpu(resp->seqnum);
> +
> +lbs_deb_sdio("CMD_RESP: response 0x%04x, result 0x%04x, seq %d, size
> %d\n", +            respcmd, result, seqnum, size);
> +}
> +
>         BUG_ON(priv->resp_len[i]);
>         priv->resp_len[i] = size;
>         memcpy(priv->resp_buf[i], buffer, size);
>
> that coupled with turning on LBS_DEB_CMD and LBS_DEB_SDIO would be quite
> interesting to see the results of and should help narrow down what's
> going on.  I'm especially interested in the sequence number to see if if
> the before-BUG_ON response is the same sequence # as the BUG_ON
> response.
>
> Dan

Well I've had a bit of luck here.  The driver will not BUG() with LBS_DEB_CMD 
and LBS_DEB_SDIO enabled at the same time, but WILL bug pretty regularly if 
these are enabled singly in turn.  The transcript is getting pretty long so 
please see attached log file.

Regards,
-Jeff
-- 
FOM Systems Inc.   www.fomsystems.com
-------------- next part --------------
libertas_debug=0x404000:

Setting up IP spoofing protection: rp_filter.
Configuring network interfaces... libertas cmd: DNLD_CMD: command 0x0010, seq 7, size 18
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas cmd: CMD_RESP: response 0x8010, seq 7, size 18
libertas cmd: DNLD_CMD: command 0x0028, seq 8, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x8028, seq 8, size 12
libertas cmd: DNLD_CMD: command 0x001e, seq 9, size 14
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 18 bytes
libertas cmd: CMD_RESP: response 0x801e, seq 9, size 14
libertas cmd: SET_WEP: add key 0 (104 bit)
libertas cmd: DNLD_CMD: command 0x0013, seq 10, size 80
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 84 bytes
libertas cmd: CMD_RESP: response 0x8013, seq 10, size 80
libertas cmd: DNLD_CMD: command 0x0028, seq 11, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x8028, seq 11, size 12
libertas cmd: DNLD_CMD: command 0x0028, seq 12, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x8028, seq 12, size 12
libertas cmd: DNLD_CMD: command 0x002f, seq 13, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x802f, seq 13, size 12
libertas cmd: DNLD_CMD: command 0x0016, seq 14, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 14, size 142
libertas cmd: DNLD_CMD: command 0x0006, seq 15, size 75
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 15 bytes
libertas cmd: CMD_RESP: response 0x8006, seq 15, size 11
libertas cmd: DNLD_CMD: command 0x0016, seq 16, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 16, size 142
libertas cmd: DNLD_CMD: command 0x0006, seq 17, size 75
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 15 bytes
libertas cmd: CMD_RESP: response 0x8006, seq 17, size 11
libertas cmd: DNLD_CMD: command 0x0016, seq 18, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 18, size 142
libertas cmd: DNLD_CMD: command 0x0006, seq 19, size 68
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 94 bytes
libertas cmd: CMD_RESP: response 0x8006, seq 19, size 90
libertas cmd: DNLD_CMD: command 0x0011, seq 20, size 25
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 29 bytes
libertas cmd: CMD_RESP: response 0x8011, seq 20, size 25
libertas cmd: RADIO_CONTROL: radio ON, preamble 0
libertas cmd: DNLD_CMD: command 0x001c, seq 21, size 12
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas cmd: CMD_RESP: response 0x801c, seq 21, size 12
libertas cmd: DNLD_CMD: command 0x0050, seq 22, size 64
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 45 bytes
libertas cmd: CMD_RESP: response 0x8012, seq 22, size 41
libertas cmd: DNLD_CMD: command 0x001f, seq 23, size 16
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 20 bytes
libertas cmd: CMD_RESP: response 0x801f, seq 23, size 16
libertas cmd: RSSI: beacon 217, avg 0
libertas cmd: DNLD_CMD: command 0x000b, seq 24, size 60
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 64 bytes
libertas cmd: CMD_RESP: response 0x800b, seq 24, size 60
libertas cmd: DNLD_CMD: command 0x001f, seq 25, size 16
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 20 bytes
libertas cmd: CMD_RESP: response 0x801f, seq 25, size 16
libertas cmd: RSSI: beacon 218, avg 0
libertas cmd: DNLD_CMD: command 0x001e, seq 26, size 14
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 18 bytes
libertas cmd: CMD_RESP: response 0x801e, seq 26, size 14
libertas cmd: DNLD_CMD: command 0x0016, seq 27, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 27, size 142
libertas cmd: DNLD_CMD: command 0x0016, seq 28, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 28, size 142
libertas cmd: DNLD_CMD: command 0x0016, seq 29, size 142
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas cmd: CMD_RESP: response 0x8016, seq 29, size 142
udhcpc (v1.2.1) started
udhcpc[1502]: udhcpc (v1.2.1) started
run-parts: /etc/udhcpc.d/00avahi-autoipd exited with return code 1: Success
libertas cmd: DNLD_CMD: command 0x0010, seq 30, size 18
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas cmd: CMD_RESP: response 0x8010, seq 30, size 18
Sending discover...
udhcpc[1502]: Sending discover...
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 92 bytes
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 390 bytes
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 92 bytes
Sending select for 192.168.13.49...
udhcpc[1502]: Sending select for 192.168.13.49...
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 92 bytes
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 390 bytes
Lease of 192.168.13.49 obtained, lease time 999999
udhcpc[1502]: Lease of 192.168.13.49 obtained, lease time 999999
run-parts: /etc/udhcpc.d/00avahi-autoipd exited with return code 1: Success
libertas cmd: DNLD_CMD: command 0x0010, seq 31, size 18
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas cmd: CMD_RESP: response 0x8010, seq 31, size 18
libertas cmd: DNLD_CMD: command 0x0010, seq 32, size 18
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas cmd: CMD_RESP: response 0x8010, seq 32, size 18
adding dns 192.168.13.200
adding dns 192.168.13.1
done.
Starting portmap daemon: portmap.


With debug level set to 0x400000 instead of 0x404000:

Setting up IP spoofing protection: rp_filter.
Configuring network interfaces... libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 18 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 84 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 15 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 15 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 94 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 18 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 29 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 45 bytes
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#1)
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#2)
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#3)
libertas: command 0x0016 timed out
libertas: Excessive timeouts submitting command 0x0016
libertas: PREP_CMD: command 0x0016 failed: -110
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas: Received CMD_RESP with invalid sequence 26 (expected 27)
libertas sdio: packet of type 1 and size 146 bytes
libertas: Received CMD_RESP with invalid sequence 26 (expected 27)
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 20 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 64 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 20 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 18 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
udhcpc (v1.2.1) started
udhcpc[1502]: udhcpc (v1.2.1) started
run-parts: /etc/udhcpc.d/00avahi-autoipd exited with return code 1: Success
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
Sending discover...
udhcpc[1502]: Sending discover...
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 92 bytes
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 390 bytes
Sending select for 192.168.13.49...
udhcpc[1502]: Sending select for 192.168.13.49...
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 390 bytes
Lease of 192.168.13.49 obtained, lease time 999999
udhcpc[1502]: Lease of 192.168.13.49 obtained, lease time 999999
run-parts: /etc/udhcpc.d/00avahi-autoipd exited with return code 1: Success
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
adding dns 192.168.13.200
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 92 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 94 bytes
libertas sdio: interrupt: 0x2
adding dns 192.168.13.1
done.
Starting portmap daemon: portmap.


and finally, here is an oops with libertas_debug set to 0x400000:

Setting up IP spoofing protection: rp_filter.
Configuring network interfaces...
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 22 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 18 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 84 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 15 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 15 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 94 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 18 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 29 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 16 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 45 bytes
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#1)
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#2)
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#3)
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 0 and size 92 bytes
libertas: command 0x0016 timed out
libertas: Excessive timeouts submitting command 0x0016
libertas: PREP_CMD: command 0x0016 failed: -110
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 146 bytes
libertas sdio: interrupt: 0x2
libertas sdio: interrupt: 0x1
libertas sdio: packet of type 1 and size 20 bytes
libertas sdio: CMD_RESP: response 0x801f, result 0x0000, seq 27, size 16
kernel BUG at drivers/net/wireless/libertas/if_sdio.c:159!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 817 [#1]
Modules linked in: snd_soc_phreedom snd_soc_wm9713 snd_soc_pxa2xx_ac97
snd_soc_pxa2xx snd_soc_core snd_pcm snd_timer snd
_page_alloc ac97_bus libertas_sdio libertas pxamci i2c_pxa mmc_core i2c_core
pxa27x_keypad gpio_keys
CPU: 0    Not tainted  (2.6.27-rc7 #92)
PC is at __bug+0x20/0x2c
LR is at log_wait+0x0/0x8
pc : [<c002ad2c>]    lr : [<c0303154>]    psr: 60000093
sp : c79e5f30  ip : c0303154  fp : c79e5f3c
r10: 00000010  r9 : bf049ca0  r8 : c78f8380
r7 : 00000000  r6 : 80000013  r5 : c714001c  r4 : 0000008e
r3 : 00000000  r2 : 20000093  r1 : 00000001  r0 : 0000003e
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 0000397f  Table: a7980000  DAC: 00000017
Process ksdiorqd (pid: 1328, stack limit = 0xc79e4270)
Stack: (0xc79e5f30 to 0xc79e6000)
5f20:                                     c79e5f8c c79e5f40 bf04c5f0 c002ad18
5f40: 0000001b 00000010 00000000 c7140018 00000034 00000195 00000000 00000000
5f60: 00000000 00000000 c79aac00 c71b0e00 c71b0e00 00000001 7fffffff 00000000
5f80: c79e5fd4 c79e5f90 bf0129bc bf04c140 00000000 c79e5fa7 00000001 c79e4000
5fa0: 00000001 029e5fb0 c02590f0 c79e4000 c79aac00 bf0128c4 00000000 00000000
5fc0: 00000000 00000000 c79e5ff4 c79e5fd8 c004c1c4 bf0128d0 00000000 00000000
5fe0: 00000000 00000000 00000000 c79e5ff8 c003b384 c004c174 00001496 0014a60b
Backtrace:
[<c002ad0c>] (__bug+0x0/0x2c) from [<bf04c5f0>] (if_sdio_interrupt+0x4bc/0x9c8
[libertas_sdio])
[<bf04c134>] (if_sdio_interrupt+0x0/0x9c8 [libertas_sdio]) from [<bf0129bc>]
(sdio_irq_thread+0xf8/0x1f8 [mmc_core])
[<bf0128c4>] (sdio_irq_thread+0x0/0x1f8 [mmc_core]) from [<c004c1c4>]
(kthread+0x5c/0x94)
[<c004c168>] (kthread+0x0/0x94) from [<c003b384>] (do_exit+0x0/0x6ec)
 r6:00000000 r5:00000000 r4:00000000
 Code: e1a01000 e59f000c eb003a2a e3a03000 (e5833000)
 ---[ end trace 59b42b1d9f381fc4 ]---


Here is an oops with libertas_debug=0x4000:

Configuring network interfaces...
libertas cmd: DNLD_CMD: command 0x0010, seq 7, size 18
libertas cmd: CMD_RESP: response 0x8010, seq 7, size 18
libertas cmd: DNLD_CMD: command 0x0028, seq 8, size 12
libertas cmd: CMD_RESP: response 0x8028, seq 8, size 12
libertas cmd: DNLD_CMD: command 0x001e, seq 9, size 14
libertas cmd: CMD_RESP: response 0x801e, seq 9, size 14
libertas cmd: DNLD_CMD: command 0x0016, seq 10, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 10, size 142
libertas cmd: DNLD_CMD: command 0x0016, seq 11, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 11, size 142
libertas cmd: SET_WEP: add key 0 (104 bit)
libertas cmd: DNLD_CMD: command 0x0013, seq 12, size 80
libertas cmd: CMD_RESP: response 0x8013, seq 12, size 80
libertas cmd: DNLD_CMD: command 0x0016, seq 13, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 13, size 142
libertas cmd: DNLD_CMD: command 0x0028, seq 14, size 12
libertas cmd: CMD_RESP: response 0x8028, seq 14, size 12
libertas cmd: DNLD_CMD: command 0x0028, seq 15, size 12
libertas cmd: CMD_RESP: response 0x8028, seq 15, size 12
libertas cmd: DNLD_CMD: command 0x002f, seq 16, size 12
libertas cmd: CMD_RESP: response 0x802f, seq 16, size 12
libertas cmd: DNLD_CMD: command 0x0006, seq 17, size 75
libertas cmd: CMD_RESP: response 0x8006, seq 17, size 11
libertas cmd: DNLD_CMD: command 0x0006, seq 18, size 75
libertas cmd: CMD_RESP: response 0x8006, seq 18, size 11
libertas cmd: DNLD_CMD: command 0x0006, seq 19, size 68
libertas cmd: CMD_RESP: response 0x8006, seq 19, size 90
libertas cmd: DNLD_CMD: command 0x001e, seq 20, size 14
libertas cmd: CMD_RESP: response 0x801e, seq 20, size 14
libertas cmd: DNLD_CMD: command 0x0011, seq 21, size 25
libertas cmd: CMD_RESP: response 0x8011, seq 21, size 25
libertas cmd: DNLD_CMD: command 0x0016, seq 22, size 142
libertas cmd: RADIO_CONTROL: radio ON, preamble 0
libertas cmd: CMD_RESP: response 0x8016, seq 22, size 142
libertas cmd: DNLD_CMD: command 0x001c, seq 23, size 12
libertas cmd: CMD_RESP: response 0x801c, seq 23, size 12
libertas cmd: DNLD_CMD: command 0x0016, seq 24, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 24, size 142
libertas cmd: DNLD_CMD: command 0x0050, seq 25, size 64
libertas cmd: CMD_RESP: response 0x8012, seq 25, size 41
libertas cmd: DNLD_CMD: command 0x0016, seq 26, size 142
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#1)
libertas cmd: DNLD_CMD: command 0x0016, seq 26, size 142
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#2)
libertas cmd: DNLD_CMD: command 0x0016, seq 26, size 142
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#3)
libertas cmd: DNLD_CMD: command 0x0016, seq 26, size 142
libertas: command 0x0016 timed out
libertas: Excessive timeouts submitting command 0x0016
libertas: PREP_CMD: command 0x0016 failed: -110
libertas cmd: DNLD_CMD: command 0x001f, seq 27, size 16
libertas cmd: CMD_RESP: response 0x8016, seq 26, size 142
libertas: Received CMD_RESP with invalid sequence 26 (expected 27)
kernel BUG at drivers/net/wireless/libertas/if_sdio.c:159!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 817 [#1]
Modules linked in: snd_soc_phreedom snd_soc_wm9713 snd_soc_pxa2xx_ac97
snd_soc_pxa2xx snd_soc_core snd_pcm snd_timer snd
_page_alloc ac97_bus libertas_sdio libertas pxamci i2c_pxa mmc_core i2c_core
pxa27x_keypad gpio_keys
CPU: 0    Not tainted  (2.6.27-rc7 #92)
PC is at __bug+0x20/0x2c
LR is at log_wait+0x0/0x8
pc : [<c002ad2c>]    lr : [<c0303154>]    psr: 60000093
sp : c731df30  ip : c0303154  fp : c731df3c
r10: 00000010  r9 : bf049ca0  r8 : c791c380
r7 : 00000000  r6 : 80000013  r5 : c79e001c  r4 : 0000008e
r3 : 00000000  r2 : 20000093  r1 : 00000001  r0 : 0000003e
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 0000397f  Table: a78d8000  DAC: 00000017
Process ksdiorqd (pid: 1352, stack limit = 0xc731c270)
Stack: (0xc731df30 to 0xc731e000)
df20:                                     c731df8c c731df40 bf04c5f0 c002ad18
df40: 00000a00 00001002 00000000 c79e0018 00000034 00000195 00000000 00000000
df60: 00000000 00000000 c79cac00 c78cce00 c78cce00 00000001 7fffffff 00000000
df80: c731dfd4 c731df90 bf0129bc bf04c140 00000000 c731dfa7 00000001 c731c000
dfa0: 00000001 0231dfb0 c02590f0 c731c000 c79cac00 bf0128c4 00000000 00000000
dfc0: 00000000 00000000 c731dff4 c731dfd8 c004c1c4 bf0128d0 00000000 00000000
dfe0: 00000000 00000000 00000000 c731dff8 c003b384 c004c174 961a01eb 23020000
Backtrace:
[<c002ad0c>] (__bug+0x0/0x2c) from [<bf04c5f0>] (if_sdio_interrupt+0x4bc/0x9c8
[libertas_sdio])
[<bf04c134>] (if_sdio_interrupt+0x0/0x9c8 [libertas_sdio]) from [<bf0129bc>]
(sdio_irq_thread+0xf8/0x1f8 [mmc_core])
[<bf0128c4>] (sdio_irq_thread+0x0/0x1f8 [mmc_core]) from [<c004c1c4>]
(kthread+0x5c/0x94)
[<c004c168>] (kthread+0x0/0x94) from [<c003b384>] (do_exit+0x0/0x6ec)
 r6:00000000 r5:00000000 r4:00000000
 Code: e1a01000 e59f000c eb003a2a e3a03000 (e5833000)
 ---[ end trace 59b42b1d9f381fc4 ]---
 libertas: command 0x001f timed out
 libertas: requeueing command 0x001f due to timeout (#1)
 libertas cmd: DNLD_CMD: command 0x001f, seq 27, size 16
 libertas: command 0x001f timed out
 libertas: requeueing command 0x001f due to timeout (#2)
 libertas cmd: DNLD_CMD: command 0x001f, seq 27, size 16
 libertas: command 0x001f timed out
 libertas: requeueing command 0x001f due to timeout (#3)
 libertas cmd: DNLD_CMD: command 0x001f, seq 27, size 16
 libertas: command 0x001f timed out
 libertas: Excessive timeouts submitting command 0x001f
(kernel locked up at this point)

From angel.roman at mdesystems.com  Fri Oct  3 14:50:48 2008
From: angel.roman at mdesystems.com (Angel Roman)
Date: Fri, 03 Oct 2008 14:50:48 -0400
Subject: GSPI Support
Message-ID: <48E66988.1060109@mdesystems.com>

Hi Everyone,

I successfully ported the marvell bulverde gspi driver to the mx31 
processor using the linux spi implementation and using a GPIO as the 
chip select - the MX31 has some issues with keeping the chip select 
signal active for longer than 8 spi word transfers.

Unfortunately, this work cannot be open sourced due the licensing 
agreements. However, after searching the web, looking at the libertas 
source code and the documentation from the module vendor, I was able to 
gather all the information to implement a GSPI extension to the libertas 
driver.

Currently, I have TX/RX data going to and from the chip as well as CMDs 
under linux 2.6.24.4 and I am able to establish an association with a 
local access points. Unfortunately, I had to uncomment the DATA_RATE 
command since non of the firmware versions available from marvell (gspi 
8.70.8, 9.45.3, and 0.70.3) support it.

The current status of my driver is:
- ability to read write to all registers in the GSPI module
- ability to send and receive data
- ability to send commands and receive command responses.
- ability to scan for local access points and associate with them (at 
least the associate command is successful and it the SSID shows up in 
the iwconfig information).

Unfortunately, I am unable to receive a DHCPOFFER from my wireless 
router At this point, I plan to get 2.6.26.5 running on my board to test 
and work with a later version of libertas.  In the meantime, does anyone 
have any suggested workarounds for firmware that does not support the 
DATA_RATE command? Is this still a requirement of the latest libertas 
driver? I assume we can do something via the RATE_ADAPT_RATESET command. 
Any thoughts?

Regards,
Angel Roman


From jeffs at fomsystems.com  Mon Oct  6 11:38:46 2008
From: jeffs at fomsystems.com (Jeff Sutherland)
Date: Mon, 6 Oct 2008 11:38:46 -0400
Subject: problem with libertas driver, Marvell W8686,
	and PXA270 on 2.6.27-rc7
In-Reply-To: <200810022225.15453.jeffs@fomsystems.com>
References: <200810021017.31310.jeffs@fomsystems.com>
	<1222983601.12505.44.camel@72-58-93-37.area3.spcsdns.net>
	<200810022225.15453.jeffs@fomsystems.com>
Message-ID: <200810061138.47667.jeffs@fomsystems.com>

On Thursday 02 October 2008, Jeff Sutherland wrote:
> On Thursday 02 October 2008, Dan Williams wrote:
> > On Thu, 2008-10-02 at 10:17 -0400, Jeff Sutherland wrote:
> > > I'm seeking some insight into the structure of the command flow when
> > > communicating with a Murata wifi module using the W8686 chip connected
> > > via SDIO on a PXA270-based system.  On about 2 out of 3 boot ups, and
> > > occasionally when configuring the network interface by hand after the
> > > system is up and running, the kernel will oops from the BUG()
> > > instruction at line 147 of drivers/net/wireless/libertas/if_sdio.c. 
> > > When this happens, the value of priv->resp_len[resp_idx] is always
> > > sitting at 142. It's almost as if the command processing in
> > > drivers/net/wireless/libertas/main.c is missing a command somehow.
> > > Curiously, this only seems to happen when the interface is
> >
> > Hmm, could well be.  The flow is supposed to be that the interface code
> > puts responses into the unused slot and wakes up the main thread, and
> > the main thread processes the response.  Could be that if a second
> > command response comes back from the card too soon the main thread
> > wouldn't be woken up to process it yet.
> >
> > Everything I've seen and read indicates that commands are serialized and
> > thus we can only have one command outstanding at any one time.  Thus we
> > can probably rule out fundamental problems with the implementation, but
> > instead focus on bugs and/or quirks.
> >
> > Could you by any chance minimally parse the command response in
> > if_sdio_handle_cmd() with something like:
> >
> > diff --git a/drivers/net/wireless/libertas/if_sdio.c
> > b/drivers/net/wireless/libertas/if_sdio.c index b54e2ea..024a81e 100644
> > --- a/drivers/net/wireless/libertas/if_sdio.c
> > +++ b/drivers/net/wireless/libertas/if_sdio.c
> > @@ -144,6 +144,18 @@ static int if_sdio_handle_cmd(struct if_sdio_card
> > *card, spin_lock_irqsave(&priv->driver_lock, flags);
> >
> >         i = (priv->resp_idx == 0) ? 1 : 0;
> > +
> > +if (priv->resp_len[i])
> > +{
> > +struct cmd_header *resp = (void *) buffer;
> > +uint16_t respcmd = le16_to_cpu(resp->command);
> > +uint16_t result = le16_to_cpu(resp->result);
> > +uint16_t seqnum = le16_to_cpu(resp->seqnum);
> > +
> > +lbs_deb_sdio("CMD_RESP: response 0x%04x, result 0x%04x, seq %d, size
> > %d\n", +            respcmd, result, seqnum, size);
> > +}
> > +
> >         BUG_ON(priv->resp_len[i]);
> >         priv->resp_len[i] = size;
> >         memcpy(priv->resp_buf[i], buffer, size);
> >
> > that coupled with turning on LBS_DEB_CMD and LBS_DEB_SDIO would be quite
> > interesting to see the results of and should help narrow down what's
> > going on.  I'm especially interested in the sequence number to see if if
> > the before-BUG_ON response is the same sequence # as the BUG_ON
> > response.
> >
> > Dan
>
> Well I've had a bit of luck here.  The driver will not BUG() with
> LBS_DEB_CMD and LBS_DEB_SDIO enabled at the same time, but WILL bug pretty
> regularly if these are enabled singly in turn.  The transcript is getting
> pretty long so please see attached log file.

Continuing to pursue this (Thanks Dan for that code snippet), I've made the 
following observations.  With libertas_debug=0x404000 the system will boot 
and the wifi module will associate and acquire an ip address using WEP 
encryption just fine every single time. However, with libertas_debug=0x4000 
most of the time it will not boot.  But what's really interesting here is the 
command sequence to the radio module changes depending on what debug levels 
are set.  I think that's the real problem, since it appears that a command 
0x0016 (CMD_802_11_SNMP_MIB) following a command 0x0050 
(CMD_802_11_ASSOCIATE) must cockup the firmware in the radio module.  In the 
normal startup a command 0x001f (CMD_802_11_RSSI) follows command 0x0050 and 
everything appears to work fine.  Note how command 0x0016 will time out, but 
that the driver (provided the kernel doesn't oops) will recover and continue 
with module initialization.  How is it that command execution order gets 
shuffled depending on the setting of debug levels?  That seems to be the real 
problem here.  If the data in columns below gets munged by the mailers, see 
attached file for the same thing in (hopefully) readable form.  Data is 
[sequence number]:[abbreviated hex command code].

Command sequences on system startup:
libertas_debug=	    libertas_debug=	    libertas_debug=0x4000
0x00404000	    0x4000
Good startup:	    Oops occured:	                  Timeouts but no oops:
7:10		    7:10		                  7:10
8:28		    8:28		                  8:28
9:1e		    9:1e		                  9:1e
10:13		    10:16		                  10:16
11:28		    11:16		                  11:16
12:28		    12:13		                  12:13
13:2F		    13:16		                  13:16
14:16		    14:28		                  14:28
15:06		    15:28		                  15:28
16:16		    16:2f		                  16:2f
17:06		    17:06		                  17:06
18:16		    18:06		                  18:06
19:06		    19:06		                  19:06
20:11		    20:1e		                  20:1e
21:1C		    21:11		                  21:11
22:50 (resp: 8012)   22:16		                  22:16
23:1F		    23:1C		                  23:1C
24:0B		    24:16		                  24:16
25:1F		    25:50 (resp:8012)	    25:50 (resp:8012)
26:1E		    26:16 (cmd timed out)   26:16 (cmd timed out)
27:16	      (makes 3 attempts at seq. 26,   (makes 3 attempts at seq. 26,
28:16	       then error -110, cmd failed)       then PREP_CMD: cmd 0016 failed
29:16	       27:1F (resp:8016, len 142)      27:1F (resp 8016, seq 26,size142)
30:10	    Received CMD_RESP with invalid    Received CMD_RESP with invalid
Sending          sequence 26 (expected 27)         sequence 26 (expected 27)
discover	         BUG() 		                then Received response 801f, seq 27
					    28:0b
					    29:1F
					    30:1e
					    31:16
					    32:16
					    33:16
					    34:10
					    Sending discover

-- 
FOM Systems Inc.   www.fomsystems.com
phone:  (USA) +1-330-628-2102 or 800-936-0561, (UK) +44-161-408-3072
mobile: (USA) +1-330-802-1364, (World) +44-7793-827386, Skype: Adekguru
=+=+=+=+=+=+=+=+=+=+=+=+=+=
And He saith unto them, "Follow me, and I will make you fishers of men."
(Matthew 4:19)
-------------- next part --------------
libertas_debug=	    libertas_debug=	    libertas_debug=0x4000
0x00404000	    0x4000
Good startup:	    Oops occured:	    Timeouts but no oops:
7:10		    7:10		    7:10
8:28		    8:28		    8:28
9:1e		    9:1e		    9:1e
10:13		    10:16		    10:16
11:28		    11:16		    11:16
12:28		    12:13		    12:13
13:2F		    13:16		    13:16
14:16		    14:28		    14:28
15:06		    15:28		    15:28
16:16		    16:2f		    16:2f
17:06		    17:06		    17:06
18:16		    18:06		    18:06
19:06		    19:06		    19:06
20:11		    20:1e		    20:1e
21:1C		    21:11		    21:11
22:50 (resp: 8012)  22:16		    22:16
23:1F		    23:1C		    23:1C
24:0B		    24:16		    24:16
25:1F		    25:50 (resp:8012)	    25:50 (resp:8012)
26:1E		    26:16 (cmd timed out)   26:16 (cmd timed out)
27:16	      (makes 3 attempts at seq. 26, (makes 3 attempts at seq. 26,
28:16	       then error -110, cmd failed)  then PREP_CMD: cmd 0016 failed
29:16		 27:1F (resp:8016, len 142) 27:1F (resp 8016, seq 26, size 142)
30:10	    Received CMD_RESP with invalid  Received CMD_RESP with invalid
Sending          sequence 26 (expected 27)  sequence 26 (expected 27)
discover	 BUG()			    then Received response 801f, seq 27
					    28:0b
					    29:1F
					    30:1e
					    31:16
					    32:16
					    33:16
					    34:10
					    Sending discover
-------------- next part --------------
libertas_sdio: Libertas SDIO driver
libertas_sdio: Copyright Pierre Ossman
firmware: requesting sd8686_helper.bin
PM: Adding info for No Bus:mmc0:0001:1
PM: Removing info for No Bus:mmc0:0001:1
firmware: requesting sd8686.bin
PM: Adding info for No Bus:mmc0:0001:1
PM: Removing info for No Bus:mmc0:0001:1
libertas cmd: DNLD_CMD: command 0x0003, seq 1, size 46
libertas cmd: CMD_RESP: response 0x8003, seq 1, size 46
libertas: 00:13:e0:ab:6e:a7, fw 9.70.3p30, cap 0x00000303
libertas cmd: GET_HW_SPEC: hardware interface 0x2, hardware spec 0x0011
libertas: unidentified region code; using the default (USA)
libertas cmd: DNLD_CMD: command 0x001e, seq 2, size 14
libertas cmd: CMD_RESP: response 0x801e, seq 2, size 14
PM: Adding info for No Bus:eth0
libertas cmd: DNLD_CMD: command 0x0028, seq 3, size 12
libertas cmd: CMD_RESP: response 0x8028, seq 3, size 12
libertas cmd: DNLD_CMD: command 0x001d, seq 4, size 48
libertas cmd: CMD_RESP: response 0x801d, seq 4, size 48
libertas cmd: current radio channel is 1
libertas cmd: mesh config action 1 type 223 channel 1 SSID mesh
libertas cmd: DNLD_CMD: command 0x00a3, seq 5, size 144
libertas cmd: CMD_RESP: response 0x80a3, seq 5, size 144
libertas: PREP_CMD: command 0x00a3 failed: 2
libertas cmd: mesh config action 1 type 125 channel 1 SSID mesh
libertas cmd: DNLD_CMD: command 0x00a3, seq 6, size 144
libertas cmd: CMD_RESP: response 0x80a3, seq 6, size 144
libertas: PREP_CMD: command 0x00a3 failed: 2
libertas: eth0: Marvell WLAN 802.11 adapter
PM: Adding info for No Bus:timer
ASoC version 0.13.2
PM: Adding info for platform:soc-audio
WM9713/WM9714 SoC Audio Codec 0.15
asoc: AC97 HiFi <-> pxa2xx-ac97 mapping ok
asoc: AC97 Aux <-> pxa2xx-ac97-aux mapping ok
pxa2xx_ac97_cold_reset: cold reset timeout (GSR=0x0)
pxa2xx_ac97_read: read error (ac97_reg=0 GSR=0x44)
dapm: WM9713: configuring unknown pin RXP
dapm: WM9713: configuring unknown pin RXN
PM: Adding info for No Bus:pcmC0D1p
PM: Adding info for No Bus:pcmC0D0p
PM: Adding info for No Bus:pcmC0D0c
PM: Adding info for No Bus:controlC0
PM: Adding info for ac97:0-0:WM9713
Setting up IP spoofing protection: rp_filter.
Configuring network interfaces... libertas cmd: DNLD_CMD: command 0x0010, seq
7, size 18
libertas cmd: CMD_RESP: response 0x8010, seq 7, size 18
libertas cmd: DNLD_CMD: command 0x0028, seq 8, size 12
libertas cmd: CMD_RESP: response 0x8028, seq 8, size 12
libertas cmd: DNLD_CMD: command 0x001e, seq 9, size 14
libertas cmd: CMD_RESP: response 0x801e, seq 9, size 14
libertas cmd: DNLD_CMD: command 0x0016, seq 10, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 10, size 142
libertas cmd: DNLD_CMD: command 0x0016, seq 11, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 11, size 142
libertas cmd: SET_WEP: add key 0 (104 bit)
libertas cmd: DNLD_CMD: command 0x0013, seq 12, size 80
libertas cmd: CMD_RESP: response 0x8013, seq 12, size 80
libertas cmd: DNLD_CMD: command 0x0016, seq 13, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 13, size 142
libertas cmd: DNLD_CMD: command 0x0028, seq 14, size 12
libertas cmd: CMD_RESP: response 0x8028, seq 14, size 12
libertas cmd: DNLD_CMD: command 0x0028, seq 15, size 12
libertas cmd: CMD_RESP: response 0x8028, seq 15, size 12
libertas cmd: DNLD_CMD: command 0x002f, seq 16, size 12
libertas cmd: CMD_RESP: response 0x802f, seq 16, size 12
libertas cmd: DNLD_CMD: command 0x0006, seq 17, size 75
libertas cmd: CMD_RESP: response 0x8006, seq 17, size 11
libertas cmd: DNLD_CMD: command 0x0006, seq 18, size 75
libertas cmd: CMD_RESP: response 0x8006, seq 18, size 11
libertas cmd: DNLD_CMD: command 0x0006, seq 19, size 68
libertas cmd: CMD_RESP: response 0x8006, seq 19, size 90
libertas cmd: DNLD_CMD: command 0x001e, seq 20, size 14
libertas cmd: CMD_RESP: response 0x801e, seq 20, size 14
libertas cmd: DNLD_CMD: command 0x0011, seq 21, size 25
libertas cmd: CMD_RESP: response 0x8011, seq 21, size 25
libertas cmd: DNLD_CMD: command 0x0016, seq 22, size 142
libertas cmd: RADIO_CONTROL: radio ON, preamble 0
libertas cmd: CMD_RESP: response 0x8016, seq 22, size 142
libertas cmd: DNLD_CMD: command 0x001c, seq 23, size 12
libertas cmd: CMD_RESP: response 0x801c, seq 23, size 12
libertas cmd: DNLD_CMD: command 0x0016, seq 24, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 24, size 142
libertas cmd: DNLD_CMD: command 0x0050, seq 25, size 64
libertas cmd: CMD_RESP: response 0x8012, seq 25, size 41
libertas cmd: DNLD_CMD: command 0x0016, seq 26, size 142
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#1)
libertas cmd: DNLD_CMD: command 0x0016, seq 26, size 142
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#2)
libertas cmd: DNLD_CMD: command 0x0016, seq 26, size 142
libertas: command 0x0016 timed out
libertas: requeueing command 0x0016 due to timeout (#3)
libertas cmd: DNLD_CMD: command 0x0016, seq 26, size 142
libertas: command 0x0016 timed out
libertas: Excessive timeouts submitting command 0x0016
libertas: PREP_CMD: command 0x0016 failed: -110
libertas cmd: DNLD_CMD: command 0x001f, seq 27, size 16
libertas cmd: CMD_RESP: response 0x8016, seq 26, size 142
libertas: Received CMD_RESP with invalid sequence 26 (expected 27)
libertas cmd: CMD_RESP: response 0x801f, seq 27, size 16
libertas cmd: RSSI: beacon 226, avg 0
libertas cmd: DNLD_CMD: command 0x000b, seq 28, size 60
libertas cmd: CMD_RESP: response 0x800b, seq 28, size 60
libertas cmd: DNLD_CMD: command 0x001f, seq 29, size 16
libertas cmd: CMD_RESP: response 0x801f, seq 29, size 16
libertas cmd: RSSI: beacon 220, avg 0
libertas cmd: DNLD_CMD: command 0x001e, seq 30, size 14
libertas cmd: CMD_RESP: response 0x801e, seq 30, size 14
libertas cmd: DNLD_CMD: command 0x0016, seq 31, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 31, size 142
libertas cmd: DNLD_CMD: command 0x0016, seq 32, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 32, size 142
libertas cmd: DNLD_CMD: command 0x0016, seq 33, size 142
libertas cmd: CMD_RESP: response 0x8016, seq 33, size 142
udhcpc (v1.2.1) started
udhcpc[1502]: udhcpc (v1.2.1) started
run-parts: /etc/udhcpc.d/00avahi-autoipd exited with return code 1: Success
libertas cmd: DNLD_CMD: command 0x0010, seq 34, size 18
libertas cmd: CMD_RESP: response 0x8010, seq 34, size 18
Sending discover...
udhcpc[1502]: Sending discover...
Sending select for 192.168.13.49...
udhcpc[1502]: Sending select for 192.168.13.49...
Lease of 192.168.13.49 obtained, lease time 999999
udhcpc[1502]: Lease of 192.168.13.49 obtained, lease time 999999
run-parts: /etc/udhcpc.d/00avahi-autoipd exited with return code 1: Success
libertas cmd: DNLD_CMD: command 0x0010, seq 35, size 18
libertas cmd: CMD_RESP: response 0x8010, seq 35, size 18
libertas cmd: DNLD_CMD: command 0x0010, seq 36, size 18
libertas cmd: CMD_RESP: response 0x8010, seq 36, size 18
adding dns 192.168.13.200
adding dns 192.168.13.1
done.
Starting portmap daemon: portmap.
Fri Oct  3 02:11:00 UTC 2008
Nothing to be done
INIT: Entering runlevel: 5
ALSA: Restoring mixer settings...
Starting Dropbear SSH server: dropbear.
Starting system message bus: dbus.
Starting syslogd/klogd: done
 * Starting Avahi mDNS/DNS-SD Daemon: avahi-daemon
 libertas cmd: DNLD_CMD: command 0x0010, seq 37, size 24
 libertas cmd: CMD_RESP: response 0x8010, seq 37, size 24
 [ ok ]
 PM: Adding info for No Bus:vcs1
 PM: Adding info for No Bus:vcsa1


From dcbw at redhat.com  Wed Oct  8 17:06:55 2008
From: dcbw at redhat.com (Dan Williams)
Date: Wed, 08 Oct 2008 17:06:55 -0400
Subject: GSPI Support
In-Reply-To: <48E66988.1060109@mdesystems.com>
References: <48E66988.1060109@mdesystems.com>
Message-ID: <1223500015.29127.11.camel@localhost.localdomain>

On Fri, 2008-10-03 at 14:50 -0400, Angel Roman wrote:
> Hi Everyone,
> 
> I successfully ported the marvell bulverde gspi driver to the mx31 
> processor using the linux spi implementation and using a GPIO as the 
> chip select - the MX31 has some issues with keeping the chip select 
> signal active for longer than 8 spi word transfers.
> 
> Unfortunately, this work cannot be open sourced due the licensing 
> agreements. However, after searching the web, looking at the libertas 
> source code and the documentation from the module vendor, I was able to 
> gather all the information to implement a GSPI extension to the libertas 
> driver.
> 
> Currently, I have TX/RX data going to and from the chip as well as CMDs 
> under linux 2.6.24.4 and I am able to establish an association with a 
> local access points. Unfortunately, I had to uncomment the DATA_RATE 
> command since non of the firmware versions available from marvell (gspi 
> 8.70.8, 9.45.3, and 0.70.3) support it.

Sorry for the lag... but

Awesome!  Note that latest libertas drivers in 2.6.26 and 2.6.27 don't
issue data rate for newer firmware (I think).

> The current status of my driver is:
> - ability to read write to all registers in the GSPI module
> - ability to send and receive data
> - ability to send commands and receive command responses.
> - ability to scan for local access points and associate with them (at 
> least the associate command is successful and it the SSID shows up in 
> the iwconfig information).

Excellent.

> Unfortunately, I am unable to receive a DHCPOFFER from my wireless 
> router At this point, I plan to get 2.6.26.5 running on my board to test 
> and work with a later version of libertas.  In the meantime, does anyone 
> have any suggested workarounds for firmware that does not support the 
> DATA_RATE command? Is this still a requirement of the latest libertas 
> driver? I assume we can do something via the RATE_ADAPT_RATESET command. 
> Any thoughts?

Latest code already uses ADAPT_RATESET and if that returns an error,
falls back to DATA_RATE.  That should be sufficient, though we should
really protect the DATA_RATE with a firmware version check.

If you could pull down the latest code from 2.6.27 (shouldn't be hard to
backport, I can certainly help with issues you might have doing that)
and check the results, I'd be quite interested to hear about them.

Thanks!
Dan




From dcbw at redhat.com  Sun Oct 12 22:01:50 2008
From: dcbw at redhat.com (Dan Williams)
Date: Sun, 12 Oct 2008 22:01:50 -0400
Subject: problem with libertas driver, Marvell W8686, and PXA270 on
	2.6.27-rc7
In-Reply-To: <200810061138.47667.jeffs@fomsystems.com>
References: <200810021017.31310.jeffs@fomsystems.com>
	<1222983601.12505.44.camel@72-58-93-37.area3.spcsdns.net>
	<200810022225.15453.jeffs@fomsystems.com>
	<200810061138.47667.jeffs@fomsystems.com>
Message-ID: <1223863310.11068.2.camel@localhost.localdomain>

On Mon, 2008-10-06 at 11:38 -0400, Jeff Sutherland wrote:
> On Thursday 02 October 2008, Jeff Sutherland wrote:
> > On Thursday 02 October 2008, Dan Williams wrote:
> > > On Thu, 2008-10-02 at 10:17 -0400, Jeff Sutherland wrote:
> > > > I'm seeking some insight into the structure of the command flow when
> > > > communicating with a Murata wifi module using the W8686 chip connected
> > > > via SDIO on a PXA270-based system.  On about 2 out of 3 boot ups, and
> > > > occasionally when configuring the network interface by hand after the
> > > > system is up and running, the kernel will oops from the BUG()
> > > > instruction at line 147 of drivers/net/wireless/libertas/if_sdio.c. 
> > > > When this happens, the value of priv->resp_len[resp_idx] is always
> > > > sitting at 142. It's almost as if the command processing in
> > > > drivers/net/wireless/libertas/main.c is missing a command somehow.
> > > > Curiously, this only seems to happen when the interface is
> > >
> > > Hmm, could well be.  The flow is supposed to be that the interface code
> > > puts responses into the unused slot and wakes up the main thread, and
> > > the main thread processes the response.  Could be that if a second
> > > command response comes back from the card too soon the main thread
> > > wouldn't be woken up to process it yet.
> > >
> > > Everything I've seen and read indicates that commands are serialized and
> > > thus we can only have one command outstanding at any one time.  Thus we
> > > can probably rule out fundamental problems with the implementation, but
> > > instead focus on bugs and/or quirks.
> > >
> > > Could you by any chance minimally parse the command response in
> > > if_sdio_handle_cmd() with something like:
> > >
> > > diff --git a/drivers/net/wireless/libertas/if_sdio.c
> > > b/drivers/net/wireless/libertas/if_sdio.c index b54e2ea..024a81e 100644
> > > --- a/drivers/net/wireless/libertas/if_sdio.c
> > > +++ b/drivers/net/wireless/libertas/if_sdio.c
> > > @@ -144,6 +144,18 @@ static int if_sdio_handle_cmd(struct if_sdio_card
> > > *card, spin_lock_irqsave(&priv->driver_lock, flags);
> > >
> > >         i = (priv->resp_idx == 0) ? 1 : 0;
> > > +
> > > +if (priv->resp_len[i])
> > > +{
> > > +struct cmd_header *resp = (void *) buffer;
> > > +uint16_t respcmd = le16_to_cpu(resp->command);
> > > +uint16_t result = le16_to_cpu(resp->result);
> > > +uint16_t seqnum = le16_to_cpu(resp->seqnum);
> > > +
> > > +lbs_deb_sdio("CMD_RESP: response 0x%04x, result 0x%04x, seq %d, size
> > > %d\n", +            respcmd, result, seqnum, size);
> > > +}
> > > +
> > >         BUG_ON(priv->resp_len[i]);
> > >         priv->resp_len[i] = size;
> > >         memcpy(priv->resp_buf[i], buffer, size);
> > >
> > > that coupled with turning on LBS_DEB_CMD and LBS_DEB_SDIO would be quite
> > > interesting to see the results of and should help narrow down what's
> > > going on.  I'm especially interested in the sequence number to see if if
> > > the before-BUG_ON response is the same sequence # as the BUG_ON
> > > response.
> > >
> > > Dan
> >
> > Well I've had a bit of luck here.  The driver will not BUG() with
> > LBS_DEB_CMD and LBS_DEB_SDIO enabled at the same time, but WILL bug pretty
> > regularly if these are enabled singly in turn.  The transcript is getting
> > pretty long so please see attached log file.
> 
> Continuing to pursue this (Thanks Dan for that code snippet), I've made the 
> following observations.  With libertas_debug=0x404000 the system will boot 
> and the wifi module will associate and acquire an ip address using WEP 
> encryption just fine every single time. However, with libertas_debug=0x4000 
> most of the time it will not boot.  But what's really interesting here is the 
> command sequence to the radio module changes depending on what debug levels 
> are set.  I think that's the real problem, since it appears that a command 
> 0x0016 (CMD_802_11_SNMP_MIB) following a command 0x0050 
> (CMD_802_11_ASSOCIATE) must cockup the firmware in the radio module.  In the 
> normal startup a command 0x001f (CMD_802_11_RSSI) follows command 0x0050 and 
> everything appears to work fine.  Note how command 0x0016 will time out, but 
> that the driver (provided the kernel doesn't oops) will recover and continue 
> with module initialization.  How is it that command execution order gets 
> shuffled depending on the setting of debug levels?  That seems to be the real 
> problem here.  If the data in columns below gets munged by the mailers, see 
> attached file for the same thing in (hopefully) readable form.  Data is 
> [sequence number]:[abbreviated hex command code].

Great info, looking at it.  Were you running 'iwconfig' periodically by
any chance?  Just trying to figure out what might cause the command
sequences below.  SNMP_MIB is used for a number of things, but only one
of which (set infra/adhoc mode) is in the normal association path.  The
rest (rts threshold, frag threshold, retry limits) could be triggered by
a plain 'iwconfig'.

Dan

> Command sequences on system startup:
> libertas_debug=	    libertas_debug=	    libertas_debug=0x4000
> 0x00404000	    0x4000
> Good startup:	    Oops occured:	                  Timeouts but no oops:
> 7:10		    7:10		                  7:10
> 8:28		    8:28		                  8:28
> 9:1e		    9:1e		                  9:1e
> 10:13		    10:16		                  10:16
> 11:28		    11:16		                  11:16
> 12:28		    12:13		                  12:13
> 13:2F		    13:16		                  13:16
> 14:16		    14:28		                  14:28
> 15:06		    15:28		                  15:28
> 16:16		    16:2f		                  16:2f
> 17:06		    17:06		                  17:06
> 18:16		    18:06		                  18:06
> 19:06		    19:06		                  19:06
> 20:11		    20:1e		                  20:1e
> 21:1C		    21:11		                  21:11
> 22:50 (resp: 8012)   22:16		                  22:16
> 23:1F		    23:1C		                  23:1C
> 24:0B		    24:16		                  24:16
> 25:1F		    25:50 (resp:8012)	    25:50 (resp:8012)
> 26:1E		    26:16 (cmd timed out)   26:16 (cmd timed out)
> 27:16	      (makes 3 attempts at seq. 26,   (makes 3 attempts at seq. 26,
> 28:16	       then error -110, cmd failed)       then PREP_CMD: cmd 0016 failed
> 29:16	       27:1F (resp:8016, len 142)      27:1F (resp 8016, seq 26,size142)
> 30:10	    Received CMD_RESP with invalid    Received CMD_RESP with invalid
> Sending          sequence 26 (expected 27)         sequence 26 (expected 27)
> discover	         BUG() 		                then Received response 801f, seq 27
> 					    28:0b
> 					    29:1F
> 					    30:1e
> 					    31:16
> 					    32:16
> 					    33:16
> 					    34:10
> 					    Sending discover
> 
> _______________________________________________
> libertas-dev mailing list
> libertas-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libertas-dev



From reachanadi at gmail.com  Mon Oct 13 06:38:11 2008
From: reachanadi at gmail.com (Anadi Mishra)
Date: Mon, 13 Oct 2008 16:08:11 +0530
Subject: Change of CWmin value in libertas USB8388
Message-ID: <e001a6370810130338p70c0f174k1df3d0f0aaefad9@mail.gmail.com>

Hi Dan,
            I am using libertas USB8388 for my work where I need to
modify the CWmin values based on some parameters like rssi(which will
be obtained from the driver).
            How can I do it. I found that the CW values are set in

linux/net/mac80211/mlme.c ::   ieee80211_sta_def_wmm_params(struct
net_device *dev,	 struct ieee80211_sta_bss *bss,int ibss)

Do i need to change this code or writing a kernel module will do ?
Any help would be great.Thanks.


-- 
Thanks and Regards,
Anadi Mishra,
Mumbai,
9987388960.


From mkatiyar at gmail.com  Mon Oct 13 06:52:42 2008
From: mkatiyar at gmail.com (Manish Katiyar)
Date: Mon, 13 Oct 2008 16:22:42 +0530
Subject: [PATCH] libertas : Remove unused variable warning "old_channel" from
	drivers/net/wireless/libertas/cmd.c
Message-ID: <ea11fea30810130352i3cea0579g9950289254c8e628@mail.gmail.com>

Below patch removes the following warning during compilation.

drivers/net/wireless/libertas/cmd.c:826: warning: unused variable 'old_channel'


Signed-off-by : Manish Katiyar <mkatiyar at gmail.com>
---
 drivers/net/wireless/libertas/cmd.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/libertas/cmd.c
b/drivers/net/wireless/libertas/cmd.c
index a912fb6..297696d 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -823,7 +823,9 @@ int lbs_update_channel(struct lbs_private *priv)
 int lbs_set_channel(struct lbs_private *priv, u8 channel)
 {
 	struct cmd_ds_802_11_rf_channel cmd;
+#ifdef DEBUG
 	u8 old_channel = priv->curbssparams.channel;
+#endif
 	int ret = 0;

 	lbs_deb_enter(LBS_DEB_CMD);
-- 
1.5.4.3


Thanks -
Manish


From dcbw at redhat.com  Mon Oct 13 07:57:14 2008
From: dcbw at redhat.com (Dan Williams)
Date: Mon, 13 Oct 2008 07:57:14 -0400
Subject: Change of CWmin value in libertas USB8388
In-Reply-To: <e001a6370810130338p70c0f174k1df3d0f0aaefad9@mail.gmail.com>
References: <e001a6370810130338p70c0f174k1df3d0f0aaefad9@mail.gmail.com>
Message-ID: <1223899034.17906.4.camel@localhost.localdomain>

On Mon, 2008-10-13 at 16:08 +0530, Anadi Mishra wrote:
> Hi Dan,
>             I am using libertas USB8388 for my work where I need to
> modify the CWmin values based on some parameters like rssi(which will
> be obtained from the driver).
>             How can I do it. I found that the CW values are set in
> 
> linux/net/mac80211/mlme.c ::   ieee80211_sta_def_wmm_params(struct
> net_device *dev,	 struct ieee80211_sta_bss *bss,int ibss)
> 
> Do i need to change this code or writing a kernel module will do ?
> Any help would be great.Thanks.

Are you using the libertas driver, or the libertas_tf driver?

Dan



From reachanadi at gmail.com  Mon Oct 13 08:50:42 2008
From: reachanadi at gmail.com (Anadi Mishra)
Date: Mon, 13 Oct 2008 18:20:42 +0530
Subject: Change of CWmin value in libertas USB8388
In-Reply-To: <1223899034.17906.4.camel@localhost.localdomain>
References: <e001a6370810130338p70c0f174k1df3d0f0aaefad9@mail.gmail.com>
	<1223899034.17906.4.camel@localhost.localdomain>
Message-ID: <e001a6370810130550o52ee4ee0ka9b3b4ffd3027474@mail.gmail.com>

On Mon, Oct 13, 2008 at 5:27 PM, Dan Williams <dcbw at redhat.com> wrote:
> On Mon, 2008-10-13 at 16:08 +0530, Anadi Mishra wrote:
>> Hi Dan,
>>             I am using libertas USB8388 for my work where I need to
>> modify the CWmin values based on some parameters like rssi(which will
>> be obtained from the driver).
>>             How can I do it. I found that the CW values are set in
>>
>> linux/net/mac80211/mlme.c ::   ieee80211_sta_def_wmm_params(struct
>> net_device *dev,       struct ieee80211_sta_bss *bss,int ibss)
>>
>> Do i need to change this code or writing a kernel module will do ?
>> Any help would be great.Thanks.
>
> Are you using the libertas driver, or the libertas_tf driver?
>
> Dan
>
>
I am using libertas driver.


-- 
Thanks and Regards,
Anadi Mishra,
Mumbai,
9987388960.


From dcbw at redhat.com  Mon Oct 13 15:00:20 2008
From: dcbw at redhat.com (Dan Williams)
Date: Mon, 13 Oct 2008 15:00:20 -0400
Subject: Change of CWmin value in libertas USB8388
In-Reply-To: <e001a6370810130550o52ee4ee0ka9b3b4ffd3027474@mail.gmail.com>
References: <e001a6370810130338p70c0f174k1df3d0f0aaefad9@mail.gmail.com>
	<1223899034.17906.4.camel@localhost.localdomain>
	<e001a6370810130550o52ee4ee0ka9b3b4ffd3027474@mail.gmail.com>
Message-ID: <1223924420.6158.32.camel@68-245-182-147.area3.spcsdns.net>

On Mon, 2008-10-13 at 18:20 +0530, Anadi Mishra wrote: 
> On Mon, Oct 13, 2008 at 5:27 PM, Dan Williams <dcbw at redhat.com> wrote:
> > On Mon, 2008-10-13 at 16:08 +0530, Anadi Mishra wrote:
> >> Hi Dan,
> >>             I am using libertas USB8388 for my work where I need to
> >> modify the CWmin values based on some parameters like rssi(which will
> >> be obtained from the driver).
> >>             How can I do it. I found that the CW values are set in
> >>
> >> linux/net/mac80211/mlme.c ::   ieee80211_sta_def_wmm_params(struct
> >> net_device *dev,       struct ieee80211_sta_bss *bss,int ibss)
> >>
> >> Do i need to change this code or writing a kernel module will do ?
> >> Any help would be great.Thanks.
> >
> > Are you using the libertas driver, or the libertas_tf driver?
> >
> > Dan
> >
> >
> I am using libertas driver.

Ok, then nothing in linux/net/mac80211/* is going to help you, because
that's for the softmac cards (like atheros, broadcom, intel, etc) that
do most of the processing on the host CPU.

The Libertas 8x8x cards with standard firmware are "fullmac" where most
of the work is done on the libertas device's CPU instead, and thus they
don't use the mac80211 stack.

The current libertas driver doesn't yet support WMM at this time.  The
code wouldn't be really hard to do since it's existed for a while in
various forms, but the core issues would be:

1) turning WMM on/off in the firmware
2) Implementing multiple queues, though we should use the new 2.6.27
generic multiqueue infrastructure if at all possible
3) parsing WMM IEs from the beacons and setting internal values based on
those beacon values

Dan



From angel.roman at mdesystems.com  Mon Oct 13 17:41:24 2008
From: angel.roman at mdesystems.com (Angel Roman)
Date: Mon, 13 Oct 2008 17:41:24 -0400
Subject: GSPI Support
In-Reply-To: <1223500015.29127.11.camel@localhost.localdomain>
References: <48E66988.1060109@mdesystems.com>
	<1223500015.29127.11.camel@localhost.localdomain>
Message-ID: <48F3C084.10001@mdesystems.com>

Dan,

I've back ported 2.6.27-rc8 libertas as you suggested. This corrects the 
"DATA_RATE command not supported" issue with the GSPI firmwares.

The shift to the latest libertas driver (using 2.6.24.4) allowed me to 
continue trouble-shooting my GSPI implementation and I have made some 
good progress.

The status of the GSPI Driver is as follows:
- ability to read write to all registers in the GSPI module
- ability to send and receive data
- ability to send commands and receive command responses.
- ability to scan for local access points and associate with them (only 
tested wide-open networks).
- ability to ping,  ssh.  and transfer files.

Since I am using a custom board interface which include SPI and the GSPI 
Interrupt, I plan to separate the custom board stuff as much as possible 
to make it into a clean GSPI implementation with hooks for other custom 
board implementations.

Thanks for your assistance.

Regards,
Angel Roman

Dan Williams wrote:
> On Fri, 2008-10-03 at 14:50 -0400, Angel Roman wrote:
>> Hi Everyone,
>>
>> I successfully ported the marvell bulverde gspi driver to the mx31
>> processor using the linux spi implementation and using a GPIO as the
>> chip select - the MX31 has some issues with keeping the chip select
>> signal active for longer than 8 spi word transfers.
>>
>> Unfortunately, this work cannot be open sourced due the licensing
>> agreements. However, after searching the web, looking at the libertas
>> source code and the documentation from the module vendor, I was able to
>> gather all the information to implement a GSPI extension to the libertas
>> driver.
>>
>> Currently, I have TX/RX data going to and from the chip as well as CMDs
>> under linux 2.6.24.4 and I am able to establish an association with a
>> local access points. Unfortunately, I had to uncomment the DATA_RATE
>> command since non of the firmware versions available from marvell (gspi
>> 8.70.8, 9.45.3, and 0.70.3) support it.
>
> Sorry for the lag... but
>
> Awesome! Note that latest libertas drivers in 2.6.26 and 2.6.27 don't
> issue data rate for newer firmware (I think).
>
>> The current status of my driver is:
>> - ability to read write to all registers in the GSPI module
>> - ability to send and receive data
>> - ability to send commands and receive command responses.
>> - ability to scan for local access points and associate with them (at
>> least the associate command is successful and it the SSID shows up in
>> the iwconfig information).
>
> Excellent.
>
>> Unfortunately, I am unable to receive a DHCPOFFER from my wireless
>> router At this point, I plan to get 2.6.26.5 running on my board to test
>> and work with a later version of libertas. In the meantime, does anyone
>> have any suggested workarounds for firmware that does not support the
>> DATA_RATE command? Is this still a requirement of the latest libertas
>> driver? I assume we can do something via the RATE_ADAPT_RATESET command.
>> Any thoughts?
>
> Latest code already uses ADAPT_RATESET and if that returns an error,
> falls back to DATA_RATE. That should be sufficient, though we should
> really protect the DATA_RATE with a firmware version check.
>
> If you could pull down the latest code from 2.6.27 (shouldn't be hard to
> backport, I can certainly help with issues you might have doing that)
> and check the results, I'd be quite interested to hear about them.
>
> Thanks!
> Dan
>
>
>
> _______________________________________________
> libertas-dev mailing list
> libertas-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libertas-dev
>


From reachanadi at gmail.com  Tue Oct 14 00:18:43 2008
From: reachanadi at gmail.com (Anadi Mishra)
Date: Tue, 14 Oct 2008 09:48:43 +0530
Subject: Change of CWmin value in libertas USB8388
In-Reply-To: <1223924420.6158.32.camel@68-245-182-147.area3.spcsdns.net>
References: <e001a6370810130338p70c0f174k1df3d0f0aaefad9@mail.gmail.com>
	<1223899034.17906.4.camel@localhost.localdomain>
	<e001a6370810130550o52ee4ee0ka9b3b4ffd3027474@mail.gmail.com>
	<1223924420.6158.32.camel@68-245-182-147.area3.spcsdns.net>
Message-ID: <e001a6370810132118y6a3b7d28hc42ced4e3ab8feca@mail.gmail.com>

On Tue, Oct 14, 2008 at 12:30 AM, Dan Williams <dcbw at redhat.com> wrote:
> On Mon, 2008-10-13 at 18:20 +0530, Anadi Mishra wrote:
>> On Mon, Oct 13, 2008 at 5:27 PM, Dan Williams <dcbw at redhat.com> wrote:
>> > On Mon, 2008-10-13 at 16:08 +0530, Anadi Mishra wrote:
>> >> Hi Dan,
>> >>             I am using libertas USB8388 for my work where I need to
>> >> modify the CWmin values based on some parameters like rssi(which will
>> >> be obtained from the driver).
>> >>             How can I do it. I found that the CW values are set in
>> >>
>> >> linux/net/mac80211/mlme.c ::   ieee80211_sta_def_wmm_params(struct
>> >> net_device *dev,       struct ieee80211_sta_bss *bss,int ibss)
>> >>
>> >> Do i need to change this code or writing a kernel module will do ?
>> >> Any help would be great.Thanks.
>> >
>> > Are you using the libertas driver, or the libertas_tf driver?
>> >
>> > Dan
>> >
>> >
>> I am using libertas driver.
>
> Ok, then nothing in linux/net/mac80211/* is going to help you, because
> that's for the softmac cards (like atheros, broadcom, intel, etc) that
> do most of the processing on the host CPU.
>
> The Libertas 8x8x cards with standard firmware are "fullmac" where most
> of the work is done on the libertas device's CPU instead, and thus they
> don't use the mac80211 stack.

Okay that makes things clear, but can I use the "libertas_tf"
firmware & driver
on the same card and then play with MAC params without much trouble?
Currently when I use "iwpriv"  it says "no private ioctls".

Do some other cards support such a feature? Which one do you
suggest(Atheros with Madwifi??).

>
> The current libertas driver doesn't yet support WMM at this time.  The
> code wouldn't be really hard to do since it's existed for a while in
> various forms, but the core issues would be:
>
> 1) turning WMM on/off in the firmware
> 2) Implementing multiple queues, though we should use the new 2.6.27
> generic multiqueue infrastructure if at all possible
> 3) parsing WMM IEs from the beacons and setting internal values based on
> those beacon values

Didn't quite get this point. Why do we need WMM in my  case?
>
> Dan
>
>



-- 
Thanks and Regards,
Anadi Mishra,
Mumbai,
9987388960.


From HigginsEdward at gmail.com  Wed Oct 15 04:36:25 2008
From: HigginsEdward at gmail.com (Tackett J Pat)
Date: Wed, 15 Oct 2008 13:36:25 +0500
Subject: Medical profession data, many different specialties
Message-ID: <500294b0ncw0$e5760nq0$5575p2e0@Delldim5150




Marketing a targeted campaign to promote your business to MDs

Board Certified MDs in the US 

788,525 in total * 17,551 emails

Coverage in many different areas of medicine such as Endocrinology, Pathology, Urology, Neurology, Plastic Surgery, Psychiatry, Cardiology and much more 

you can sort by many different fields 


Mailing List of American Pharma Companies
47,000 personal emails and names of decision makers

American Hospitals
Complete contact information for the important jobs held at the hospitals

American Dentists
Virtually every dentist in the USA with full contact details

American Chiropractors Marketing List
Over than 100k chiropractors practicing in the US


Cost just slashed -  
$397 for all listed above

send and email to:      MargueriteGarner at dynamedlist.com

  

only until this Friday


To invoke no further correspondence status please send an email to revoked at dynamedlist.com


From reachanadi at gmail.com  Tue Oct 14 05:18:04 2008
From: reachanadi at gmail.com (Anadi Mishra)
Date: Tue, 14 Oct 2008 14:48:04 +0530
Subject: Change of CWmin value in libertas USB8388
In-Reply-To: <e001a6370810132118y6a3b7d28hc42ced4e3ab8feca@mail.gmail.com>
References: <e001a6370810130338p70c0f174k1df3d0f0aaefad9@mail.gmail.com>
	<1223899034.17906.4.camel@localhost.localdomain>
	<e001a6370810130550o52ee4ee0ka9b3b4ffd3027474@mail.gmail.com>
	<1223924420.6158.32.camel@68-245-182-147.area3.spcsdns.net>
	<e001a6370810132118y6a3b7d28hc42ced4e3ab8feca@mail.gmail.com>
Message-ID: <e001a6370810140218h9c97833mc69592b802a3e510@mail.gmail.com>

Okay that was my mistake...........this card supports only
fullmac..........can you please elaborate on the WMM point or point me
to some document which will help?

Thanks.


On Tue, Oct 14, 2008 at 9:48 AM, Anadi Mishra <reachanadi at gmail.com> wrote:
> On Tue, Oct 14, 2008 at 12:30 AM, Dan Williams <dcbw at redhat.com> wrote:
>> On Mon, 2008-10-13 at 18:20 +0530, Anadi Mishra wrote:
>>> On Mon, Oct 13, 2008 at 5:27 PM, Dan Williams <dcbw at redhat.com> wrote:
>>> > On Mon, 2008-10-13 at 16:08 +0530, Anadi Mishra wrote:
>>> >> Hi Dan,
>>> >>             I am using libertas USB8388 for my work where I need to
>>> >> modify the CWmin values based on some parameters like rssi(which will
>>> >> be obtained from the driver).
>>> >>             How can I do it. I found that the CW values are set in
>>> >>
>>> >> linux/net/mac80211/mlme.c ::   ieee80211_sta_def_wmm_params(struct
>>> >> net_device *dev,       struct ieee80211_sta_bss *bss,int ibss)
>>> >>
>>> >> Do i need to change this code or writing a kernel module will do ?
>>> >> Any help would be great.Thanks.
>>> >
>>> > Are you using the libertas driver, or the libertas_tf driver?
>>> >
>>> > Dan
>>> >
>>> >
>>> I am using libertas driver.
>>
>> Ok, then nothing in linux/net/mac80211/* is going to help you, because
>> that's for the softmac cards (like atheros, broadcom, intel, etc) that
>> do most of the processing on the host CPU.
>>
>> The Libertas 8x8x cards with standard firmware are "fullmac" where most
>> of the work is done on the libertas device's CPU instead, and thus they
>> don't use the mac80211 stack.
>
> Okay that makes things clear, but can I use the "libertas_tf"
> firmware & driver
> on the same card and then play with MAC params without much trouble?
> Currently when I use "iwpriv"  it says "no private ioctls".
>
> Do some other cards support such a feature? Which one do you
> suggest(Atheros with Madwifi??).
>
>>
>> The current libertas driver doesn't yet support WMM at this time.  The
>> code wouldn't be really hard to do since it's existed for a while in
>> various forms, but the core issues would be:
>>
>> 1) turning WMM on/off in the firmware
>> 2) Implementing multiple queues, though we should use the new 2.6.27
>> generic multiqueue infrastructure if at all possible
>> 3) parsing WMM IEs from the beacons and setting internal values based on
>> those beacon values
>
> Didn't quite get this point. Why do we need WMM in my  case?
>>
>> Dan
>>
>>
>
>
>
> --
> Thanks and Regards,
> Anadi Mishra,
> Mumbai,
> 9987388960.
>



-- 
Thanks and Regards,
Anadi Mishra,
Mumbai,
9987388960.


From grib at billgribble.com  Tue Oct 14 10:26:52 2008
From: grib at billgribble.com (Bill Gribble)
Date: Tue, 14 Oct 2008 10:26:52 -0400
Subject: Identify mystery libertas firmware?
Message-ID: <1223994412.7642.3.camel@grib>

I came across a firmware file on my hard drive that was different than
the ones I had been trying on my Raon Everun (SD8686 internal), and
plopped it into /lib/firmware to see what happened.

Imagine my surprise when it worked!  Under kernel 2.6.27, I get an eth0
device and can join and use WPA networks with no problems. 

Unfortunately I don't know where this particular firmware file came
from.  Can anyone in libertas-land identify it based on its md5sum? 

1656e7ca9077a75be9dc866df97f56a2  sd8686.bin

Thanks,
Bill Gribble





From dcbw at redhat.com  Tue Oct 14 11:08:51 2008
From: dcbw at redhat.com (Dan Williams)
Date: Tue, 14 Oct 2008 11:08:51 -0400
Subject: Identify mystery libertas firmware?
In-Reply-To: <1223994412.7642.3.camel@grib>
References: <1223994412.7642.3.camel@grib>
Message-ID: <1223996931.3936.12.camel@localhost.localdomain>

On Tue, 2008-10-14 at 10:26 -0400, Bill Gribble wrote:
> I came across a firmware file on my hard drive that was different than
> the ones I had been trying on my Raon Everun (SD8686 internal), and
> plopped it into /lib/firmware to see what happened.
> 
> Imagine my surprise when it worked!  Under kernel 2.6.27, I get an eth0
> device and can join and use WPA networks with no problems. 
> 
> Unfortunately I don't know where this particular firmware file came
> from.  Can anyone in libertas-land identify it based on its md5sum? 

What does the driver print out in the kernel logs when you load the part
with this firmware?  It should print out the firmware version in the
first few lines after the card is inserted.

dan

> 1656e7ca9077a75be9dc866df97f56a2  sd8686.bin
> 
> Thanks,
> Bill Gribble
> 
> 
> 
> 
> _______________________________________________
> libertas-dev mailing list
> libertas-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libertas-dev



From dcbw at redhat.com  Tue Oct 14 11:11:48 2008
From: dcbw at redhat.com (Dan Williams)
Date: Tue, 14 Oct 2008 11:11:48 -0400
Subject: Change of CWmin value in libertas USB8388
In-Reply-To: <e001a6370810140218h9c97833mc69592b802a3e510@mail.gmail.com>
References: <e001a6370810130338p70c0f174k1df3d0f0aaefad9@mail.gmail.com>
	<1223899034.17906.4.camel@localhost.localdomain>
	<e001a6370810130550o52ee4ee0ka9b3b4ffd3027474@mail.gmail.com>
	<1223924420.6158.32.camel@68-245-182-147.area3.spcsdns.net>
	<e001a6370810132118y6a3b7d28hc42ced4e3ab8feca@mail.gmail.com>
	<e001a6370810140218h9c97833mc69592b802a3e510@mail.gmail.com>
Message-ID: <1223997108.3936.16.camel@localhost.localdomain>

On Tue, 2008-10-14 at 14:48 +0530, Anadi Mishra wrote:
> Okay that was my mistake...........this card supports only
> fullmac..........can you please elaborate on the WMM point or point me
> to some document which will help?

The card actually supports softmac operation through the use of the thin
libertas firmware you can get from the OLPC project.

The usb8388 is _normally_ fullmac, but the libertas fullmac firmware has
WMM capability, it's just not turned on and isn't fully implemented in
the current driver.

The reason I'm talking about WMM is that the only references I can find
to cwmin and cwmax are in conjunction with WMM, thus I believe you need
to enable and use WMM before you can start tweaking these values.

Dan

> Thanks.
> 
> 
> On Tue, Oct 14, 2008 at 9:48 AM, Anadi Mishra <reachanadi at gmail.com> wrote:
> > On Tue, Oct 14, 2008 at 12:30 AM, Dan Williams <dcbw at redhat.com> wrote:
> >> On Mon, 2008-10-13 at 18:20 +0530, Anadi Mishra wrote:
> >>> On Mon, Oct 13, 2008 at 5:27 PM, Dan Williams <dcbw at redhat.com> wrote:
> >>> > On Mon, 2008-10-13 at 16:08 +0530, Anadi Mishra wrote:
> >>> >> Hi Dan,
> >>> >>             I am using libertas USB8388 for my work where I need to
> >>> >> modify the CWmin values based on some parameters like rssi(which will
> >>> >> be obtained from the driver).
> >>> >>             How can I do it. I found that the CW values are set in
> >>> >>
> >>> >> linux/net/mac80211/mlme.c ::   ieee80211_sta_def_wmm_params(struct
> >>> >> net_device *dev,       struct ieee80211_sta_bss *bss,int ibss)
> >>> >>
> >>> >> Do i need to change this code or writing a kernel module will do ?
> >>> >> Any help would be great.Thanks.
> >>> >
> >>> > Are you using the libertas driver, or the libertas_tf driver?
> >>> >
> >>> > Dan
> >>> >
> >>> >
> >>> I am using libertas driver.
> >>
> >> Ok, then nothing in linux/net/mac80211/* is going to help you, because
> >> that's for the softmac cards (like atheros, broadcom, intel, etc) that
> >> do most of the processing on the host CPU.
> >>
> >> The Libertas 8x8x cards with standard firmware are "fullmac" where most
> >> of the work is done on the libertas device's CPU instead, and thus they
> >> don't use the mac80211 stack.
> >
> > Okay that makes things clear, but can I use the "libertas_tf"
> > firmware & driver
> > on the same card and then play with MAC params without much trouble?
> > Currently when I use "iwpriv"  it says "no private ioctls".
> >
> > Do some other cards support such a feature? Which one do you
> > suggest(Atheros with Madwifi??).
> >
> >>
> >> The current libertas driver doesn't yet support WMM at this time.  The
> >> code wouldn't be really hard to do since it's existed for a while in
> >> various forms, but the core issues would be:
> >>
> >> 1) turning WMM on/off in the firmware
> >> 2) Implementing multiple queues, though we should use the new 2.6.27
> >> generic multiqueue infrastructure if at all possible
> >> 3) parsing WMM IEs from the beacons and setting internal values based on
> >> those beacon values
> >
> > Didn't quite get this point. Why do we need WMM in my  case?
> >>
> >> Dan
> >>
> >>
> >
> >
> >
> > --
> > Thanks and Regards,
> > Anadi Mishra,
> > Mumbai,
> > 9987388960.
> >
> 
> 
> 



From mkatiyar at gmail.com  Tue Oct 14 12:00:56 2008
From: mkatiyar at gmail.com (Manish Katiyar)
Date: Tue, 14 Oct 2008 21:30:56 +0530
Subject: [PATCH] libertas : Remove unused variable warning "old_channel"
	from drivers/net/wireless/libertas/cmd.c
In-Reply-To: <ea11fea30810130352i3cea0579g9950289254c8e628@mail.gmail.com>
References: <ea11fea30810130352i3cea0579g9950289254c8e628@mail.gmail.com>
Message-ID: <ea11fea30810140900n572c326r938fa88fdb5843d8@mail.gmail.com>

On Mon, Oct 13, 2008 at 4:22 PM, Manish Katiyar <mkatiyar at gmail.com> wrote:
> Below patch removes the following warning during compilation.
>
> drivers/net/wireless/libertas/cmd.c:826: warning: unused variable 'old_channel'

Any ack/nack on this ??

Thanks -
Manish

>
>
> Signed-off-by : Manish Katiyar <mkatiyar at gmail.com>
> ---
>  drivers/net/wireless/libertas/cmd.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/libertas/cmd.c
> b/drivers/net/wireless/libertas/cmd.c
> index a912fb6..297696d 100644
> --- a/drivers/net/wireless/libertas/cmd.c
> +++ b/drivers/net/wireless/libertas/cmd.c
> @@ -823,7 +823,9 @@ int lbs_update_channel(struct lbs_private *priv)
>  int lbs_set_channel(struct lbs_private *priv, u8 channel)
>  {
>        struct cmd_ds_802_11_rf_channel cmd;
> +#ifdef DEBUG
>        u8 old_channel = priv->curbssparams.channel;
> +#endif
>        int ret = 0;
>
>        lbs_deb_enter(LBS_DEB_CMD);
> --
> 1.5.4.3
>
>
> Thanks -
> Manish
>


From dcbw at redhat.com  Tue Oct 14 12:36:53 2008
From: dcbw at redhat.com (Dan Williams)
Date: Tue, 14 Oct 2008 12:36:53 -0400
Subject: [PATCH] libertas : Remove unused variable warning
	"old_channel" from drivers/net/wireless/libertas/cmd.c
In-Reply-To: <ea11fea30810130352i3cea0579g9950289254c8e628@mail.gmail.com>
References: <ea11fea30810130352i3cea0579g9950289254c8e628@mail.gmail.com>
Message-ID: <1224002213.1799.2.camel@localhost.localdomain>

On Mon, 2008-10-13 at 16:22 +0530, Manish Katiyar wrote:
> Below patch removes the following warning during compilation.
> 
> drivers/net/wireless/libertas/cmd.c:826: warning: unused variable 'old_channel'
> 
> 
> Signed-off-by : Manish Katiyar <mkatiyar at gmail.com>

Acked-by: Dan Williams <dcbw at redhat.com>

> ---
>  drivers/net/wireless/libertas/cmd.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/net/wireless/libertas/cmd.c
> b/drivers/net/wireless/libertas/cmd.c
> index a912fb6..297696d 100644
> --- a/drivers/net/wireless/libertas/cmd.c
> +++ b/drivers/net/wireless/libertas/cmd.c
> @@ -823,7 +823,9 @@ int lbs_update_channel(struct lbs_private *priv)
>  int lbs_set_channel(struct lbs_private *priv, u8 channel)
>  {
>  	struct cmd_ds_802_11_rf_channel cmd;
> +#ifdef DEBUG
>  	u8 old_channel = priv->curbssparams.channel;
> +#endif
>  	int ret = 0;
> 
>  	lbs_deb_enter(LBS_DEB_CMD);



From ryan at bluewatersys.com  Tue Oct 14 16:29:45 2008
From: ryan at bluewatersys.com (Ryan Mallon)
Date: Wed, 15 Oct 2008 09:29:45 +1300
Subject: [PATCH] Fix cs firmware loading
Message-ID: <48F50139.9050608@bluewatersys.com>

The function if_cs_poll_while_fw_download returns the number of 
iterations through the loop on success. This value is returned by
the functions if_cs_prog_helper and if_cs_prog_real, however they
should return zero on success. This patch corrects that. An 
alternative would be to just return zero on success from 
if_cs_poll_while_fw_download.

Signed-off-by: Ryan Mallon <ryan at bluewatersys.com>

diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 842a08d..13e1f59 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -598,8 +598,10 @@ static int if_cs_prog_helper(struct if_cs_card *card)
 			goto err_release;
 		}
 
-		if (count == 0)
+		if (count == 0) {
+			ret = 0;
 			break;
+		}
 
 		sent += count;
 	}
@@ -677,6 +679,8 @@ static int if_cs_prog_real(struct if_cs_card *card)
 	ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
 	if (ret < 0)
 		lbs_pr_err("firmware download failed\n");
+	else
+		ret = 0;
 
 err_release:
 	release_firmware(fw);

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

       Ryan Mallon                              Unit 5, Amuri Park
       Phone: +64 3 3779127                     404 Barbadoes St
       Fax:   +64 3 3779135                     PO Box 13 889
       Email: ryan at bluewatersys.com             Christchurch, 8013
       Web:   http://www.bluewatersys.com       New Zealand
       Freecall Australia  1800 148 751         USA 1800 261 2934



From mkatiyar at gmail.com  Wed Oct 15 04:10:03 2008
From: mkatiyar at gmail.com (Manish Katiyar)
Date: Wed, 15 Oct 2008 13:40:03 +0530
Subject: [PATCH] libertas : Remove unused variable warning "old_channel"
	from drivers/net/wireless/libertas/cmd.c
In-Reply-To: <1224002213.1799.2.camel@localhost.localdomain>
References: <ea11fea30810130352i3cea0579g9950289254c8e628@mail.gmail.com>
	<1224002213.1799.2.camel@localhost.localdomain>
Message-ID: <ea11fea30810150110s772b740fv38cc37645da53201@mail.gmail.com>

On Tue, Oct 14, 2008 at 10:06 PM, Dan Williams <dcbw at redhat.com> wrote:
> On Mon, 2008-10-13 at 16:22 +0530, Manish Katiyar wrote:
>> Below patch removes the following warning during compilation.
>>
>> drivers/net/wireless/libertas/cmd.c:826: warning: unused variable 'old_channel'
>>
>>
>> Signed-off-by : Manish Katiyar <mkatiyar at gmail.com>
>
> Acked-by: Dan Williams <dcbw at redhat.com>

Hi Dan,

A newbie question. Will you merge this patch or will I have to send it
to Andrew again acked by you ?

Thanks -
Manish


>
>> ---
>>  drivers/net/wireless/libertas/cmd.c |    2 ++
>>  1 files changed, 2 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/net/wireless/libertas/cmd.c
>> b/drivers/net/wireless/libertas/cmd.c
>> index a912fb6..297696d 100644
>> --- a/drivers/net/wireless/libertas/cmd.c
>> +++ b/drivers/net/wireless/libertas/cmd.c
>> @@ -823,7 +823,9 @@ int lbs_update_channel(struct lbs_private *priv)
>>  int lbs_set_channel(struct lbs_private *priv, u8 channel)
>>  {
>>       struct cmd_ds_802_11_rf_channel cmd;
>> +#ifdef DEBUG
>>       u8 old_channel = priv->curbssparams.channel;
>> +#endif
>>       int ret = 0;
>>
>>       lbs_deb_enter(LBS_DEB_CMD);
>
>


From dcbw at redhat.com  Wed Oct 15 11:08:41 2008
From: dcbw at redhat.com (Dan Williams)
Date: Wed, 15 Oct 2008 11:08:41 -0400
Subject: [PATCH] Fix cs firmware loading
In-Reply-To: <48F50139.9050608@bluewatersys.com>
References: <48F50139.9050608@bluewatersys.com>
Message-ID: <1224083321.31882.17.camel@dhcp-100-3-195.bos.redhat.com>

On Wed, 2008-10-15 at 09:29 +1300, Ryan Mallon wrote:
> The function if_cs_poll_while_fw_download returns the number of 
> iterations through the loop on success. This value is returned by
> the functions if_cs_prog_helper and if_cs_prog_real, however they
> should return zero on success. This patch corrects that. An 
> alternative would be to just return zero on success from 
> if_cs_poll_while_fw_download.

Yeah, just have if_cs_poll_while_fw_download() return 0 on success,
since nowhere acutally cares how many iterations were used.

BTW, I assume you guys are using 8335 hardware version b2 and later,
right?

Thanks!
Dan


> Signed-off-by: Ryan Mallon <ryan at bluewatersys.com>
> 
> diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
> index 842a08d..13e1f59 100644
> --- a/drivers/net/wireless/libertas/if_cs.c
> +++ b/drivers/net/wireless/libertas/if_cs.c
> @@ -598,8 +598,10 @@ static int if_cs_prog_helper(struct if_cs_card *card)
>  			goto err_release;
>  		}
>  
> -		if (count == 0)
> +		if (count == 0) {
> +			ret = 0;
>  			break;
> +		}
>  
>  		sent += count;
>  	}
> @@ -677,6 +679,8 @@ static int if_cs_prog_real(struct if_cs_card *card)
>  	ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
>  	if (ret < 0)
>  		lbs_pr_err("firmware download failed\n");
> +	else
> +		ret = 0;
>  
>  err_release:
>  	release_firmware(fw);
> 



From ryan at bluewatersys.com  Wed Oct 15 16:06:32 2008
From: ryan at bluewatersys.com (Ryan Mallon)
Date: Thu, 16 Oct 2008 09:06:32 +1300
Subject: [PATCH] Fix cs firmware loading
In-Reply-To: <1224083321.31882.17.camel@dhcp-100-3-195.bos.redhat.com>
References: <48F50139.9050608@bluewatersys.com>
	<1224083321.31882.17.camel@dhcp-100-3-195.bos.redhat.com>
Message-ID: <48F64D48.7080404@bluewatersys.com>

Dan Williams wrote:
> On Wed, 2008-10-15 at 09:29 +1300, Ryan Mallon wrote:
>   
>> The function if_cs_poll_while_fw_download returns the number of 
>> iterations through the loop on success. This value is returned by
>> the functions if_cs_prog_helper and if_cs_prog_real, however they
>> should return zero on success. This patch corrects that. An 
>> alternative would be to just return zero on success from 
>> if_cs_poll_while_fw_download.
>>     
>
> Yeah, just have if_cs_poll_while_fw_download() return 0 on success,
> since nowhere acutally cares how many iterations were used.
>   
Okay. Updated patch at bottom.

> BTW, I assume you guys are using 8335 hardware version b2 and later,
> right?
>
>   
We are using the Wistron Neweb DRCM 81 module, which uses the Marvell
8385. We have mostly been using it with the 2.6.20 kernel (we patched
the Libertas driver into our kernel at the time). One of our 
customers who uses the wireless on their board quite heavily has 
noticed some problems with scanning, which we believe may be related 
to the older code, hence I am doing some testing with the newest 
driver. Some prelim testing shows the that driver is still working
fine (with my patch applied) on the hardware that I have. 

--

Change the return value of if_cs_poll_while_fw_download to zero on 
success, so that the firmware loading functions also correctly 
return zero on success.

Signed-off-by: Ryan Mallon <ryan at bluewatersys.com>

diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 842a08d..8f8934a 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -151,7 +151,7 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
 	for (i = 0; i < 100000; i++) {
 		u8 val = if_cs_read8(card, addr);
 		if (val == reg)
-			return i;
+			return 0;
 		udelay(5);
 	}
 	return -ETIME;

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

       Ryan Mallon                              Unit 5, Amuri Park
       Phone: +64 3 3779127                     404 Barbadoes St
       Fax:   +64 3 3779135                     PO Box 13 889
       Email: ryan at bluewatersys.com             Christchurch, 8013
       Web:   http://www.bluewatersys.com       New Zealand
       Freecall Australia  1800 148 751         USA 1800 261 2934



From dcbw at redhat.com  Wed Oct 15 18:55:21 2008
From: dcbw at redhat.com (Dan Williams)
Date: Wed, 15 Oct 2008 18:55:21 -0400
Subject: [PATCH] Fix cs firmware loading
In-Reply-To: <48F64D48.7080404@bluewatersys.com>
References: <48F50139.9050608@bluewatersys.com>
	<1224083321.31882.17.camel@dhcp-100-3-195.bos.redhat.com>
	<48F64D48.7080404@bluewatersys.com>
Message-ID: <1224111321.22537.6.camel@70-4-70-178.area3.spcsdns.net>

On Thu, 2008-10-16 at 09:06 +1300, Ryan Mallon wrote:
> Dan Williams wrote:
> > On Wed, 2008-10-15 at 09:29 +1300, Ryan Mallon wrote:
> >   
> >> The function if_cs_poll_while_fw_download returns the number of 
> >> iterations through the loop on success. This value is returned by
> >> the functions if_cs_prog_helper and if_cs_prog_real, however they
> >> should return zero on success. This patch corrects that. An 
> >> alternative would be to just return zero on success from 
> >> if_cs_poll_while_fw_download.
> >>     
> >
> > Yeah, just have if_cs_poll_while_fw_download() return 0 on success,
> > since nowhere acutally cares how many iterations were used.
> >   
> Okay. Updated patch at bottom.
> 
> > BTW, I assume you guys are using 8335 hardware version b2 and later,
> > right?
> >
> >   
> We are using the Wistron Neweb DRCM 81 module, which uses the Marvell
> 8385. We have mostly been using it with the 2.6.20 kernel (we patched

Sorry, I mean 8385 b2, not 8335.  The hardware version is the important
part, because previous versions had hardware bugs in the CF interface.
Just wondering if you'd worked around those somehow, or if you were
using up-to-date hardware versions.

> the Libertas driver into our kernel at the time). One of our 
> customers who uses the wireless on their board quite heavily has 
> noticed some problems with scanning, which we believe may be related 
> to the older code, hence I am doing some testing with the newest 
> driver. Some prelim testing shows the that driver is still working
> fine (with my patch applied) on the hardware that I have. 
> 
> --
> 
> Change the return value of if_cs_poll_while_fw_download to zero on 
> success, so that the firmware loading functions also correctly 
> return zero on success.
> 
> Signed-off-by: Ryan Mallon <ryan at bluewatersys.com>
> 
> diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
> index 842a08d..8f8934a 100644
> --- a/drivers/net/wireless/libertas/if_cs.c
> +++ b/drivers/net/wireless/libertas/if_cs.c
> @@ -151,7 +151,7 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
>  	for (i = 0; i < 100000; i++) {
>  		u8 val = if_cs_read8(card, addr);
>  		if (val == reg)
> -			return i;
> +			return 0;
>  		udelay(5);
>  	}
>  	return -ETIME;

Looks good to me, care to post to linux-wireless or would you like me to
do that for you?

Dan




From ryan at bluewatersys.com  Wed Oct 15 19:07:58 2008
From: ryan at bluewatersys.com (Ryan Mallon)
Date: Thu, 16 Oct 2008 12:07:58 +1300
Subject: [PATCH] Fix cs firmware loading
In-Reply-To: <1224111321.22537.6.camel@70-4-70-178.area3.spcsdns.net>
References: <48F50139.9050608@bluewatersys.com>	
	<1224083321.31882.17.camel@dhcp-100-3-195.bos.redhat.com>	
	<48F64D48.7080404@bluewatersys.com>
	<1224111321.22537.6.camel@70-4-70-178.area3.spcsdns.net>
Message-ID: <48F677CE.10307@bluewatersys.com>

Dan Williams wrote:

>>> BTW, I assume you guys are using 8335 hardware version b2 and later,
>>> right?
>>>
>>>   
>> We are using the Wistron Neweb DRCM 81 module, which uses the Marvell
>> 8385. We have mostly been using it with the 2.6.20 kernel (we patched
> 
> Sorry, I mean 8385 b2, not 8335.  The hardware version is the important
> part, because previous versions had hardware bugs in the CF interface.
> Just wondering if you'd worked around those somehow, or if you were
> using up-to-date hardware versions.

I'm not actually sure what the hardware version is. I get the following
in Linux:

root at snapper:~$ pccardctl insert
pcmcia_socket pcmcia_socket0: pccard: PCMCIA card inserted into slot 0
pcmcia 0.0: pcmcia: registering new device pcmcia0.0
firmware: requesting libertas_cs_helper.fw
firmware: requesting libertas_cs.fw
libertas: 00:0b:6b:0c:b8:cb, fw 5.0.11p0, cap 0x00000393
libertas: eth1: Marvell WLAN 802.11 adapter

root at snapper:~$ pccardctl ident
Socket 0:
  product info: "Marvell", "802.11 CF", "ID: 04", ""
  manfid: 0x02df, 0x8103
  function: 6 (network)

We aren't doing any particular work arounds. What were the hardware
problems with the compact flash 8385?

> 
>> the Libertas driver into our kernel at the time). One of our 
>> customers who uses the wireless on their board quite heavily has 
>> noticed some problems with scanning, which we believe may be related 
>> to the older code, hence I am doing some testing with the newest 
>> driver. Some prelim testing shows the that driver is still working
>> fine (with my patch applied) on the hardware that I have. 
>>
>> --
>>
>> Change the return value of if_cs_poll_while_fw_download to zero on 
>> success, so that the firmware loading functions also correctly 
>> return zero on success.
>>
>> Signed-off-by: Ryan Mallon <ryan at bluewatersys.com>
>>
>> diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
>> index 842a08d..8f8934a 100644
>> --- a/drivers/net/wireless/libertas/if_cs.c
>> +++ b/drivers/net/wireless/libertas/if_cs.c
>> @@ -151,7 +151,7 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
>>  	for (i = 0; i < 100000; i++) {
>>  		u8 val = if_cs_read8(card, addr);
>>  		if (val == reg)
>> -			return i;
>> +			return 0;
>>  		udelay(5);
>>  	}
>>  	return -ETIME;
> 
> Looks good to me, care to post to linux-wireless or would you like me to
> do that for you?

I'm not on the linux-wireless list, so can you push it through for me.
Thanks.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

       Ryan Mallon                              Unit 5, Amuri Park
       Phone: +64 3 3779127                     404 Barbadoes St
       Fax:   +64 3 3779135                     PO Box 13 889
       Email: ryan at bluewatersys.com             Christchurch, 8013
       Web:   http://www.bluewatersys.com       New Zealand
       Freecall Australia  1800 148 751         USA 1800 261 2934


From dcbw at redhat.com  Thu Oct 16 11:21:03 2008
From: dcbw at redhat.com (Dan Williams)
Date: Thu, 16 Oct 2008 11:21:03 -0400
Subject: [PATCH] Fix cs firmware loading
In-Reply-To: <48F677CE.10307@bluewatersys.com>
References: <48F50139.9050608@bluewatersys.com>
	<1224083321.31882.17.camel@dhcp-100-3-195.bos.redhat.com>
	<48F64D48.7080404@bluewatersys.com>
	<1224111321.22537.6.camel@70-4-70-178.area3.spcsdns.net>
	<48F677CE.10307@bluewatersys.com>
Message-ID: <1224170463.3430.27.camel@localhost.localdomain>

On Thu, 2008-10-16 at 12:07 +1300, Ryan Mallon wrote:
> Dan Williams wrote:
> 
> >>> BTW, I assume you guys are using 8335 hardware version b2 and later,
> >>> right?
> >>>
> >>>   
> >> We are using the Wistron Neweb DRCM 81 module, which uses the Marvell
> >> 8385. We have mostly been using it with the 2.6.20 kernel (we patched
> > 
> > Sorry, I mean 8385 b2, not 8335.  The hardware version is the important
> > part, because previous versions had hardware bugs in the CF interface.
> > Just wondering if you'd worked around those somehow, or if you were
> > using up-to-date hardware versions.
> 
> I'm not actually sure what the hardware version is. I get the following
> in Linux:
> 
> root at snapper:~$ pccardctl insert
> pcmcia_socket pcmcia_socket0: pccard: PCMCIA card inserted into slot 0
> pcmcia 0.0: pcmcia: registering new device pcmcia0.0
> firmware: requesting libertas_cs_helper.fw
> firmware: requesting libertas_cs.fw
> libertas: 00:0b:6b:0c:b8:cb, fw 5.0.11p0, cap 0x00000393
> libertas: eth1: Marvell WLAN 802.11 adapter
> 
> root at snapper:~$ pccardctl ident
> Socket 0:
>   product info: "Marvell", "802.11 CF", "ID: 04", ""
>   manfid: 0x02df, 0x8103
>   function: 6 (network)
> 
> We aren't doing any particular work arounds. What were the hardware
> problems with the compact flash 8385?

B1 and earlier HW versions (AmbiCom WL54-CF for example) will eventually
time out and stop responding to commands because the hardware gets
interrupt confirmations mixed up or something.  Holger had prototyped a
workaround that used polling instead, and there are references to the
issue in the gumstix driver.  If you're not having problems, then you're
probably using b2 or later hardware.

> > 
> >> the Libertas driver into our kernel at the time). One of our 
> >> customers who uses the wireless on their board quite heavily has 
> >> noticed some problems with scanning, which we believe may be related 
> >> to the older code, hence I am doing some testing with the newest 
> >> driver. Some prelim testing shows the that driver is still working
> >> fine (with my patch applied) on the hardware that I have. 
> >>
> >> --
> >>
> >> Change the return value of if_cs_poll_while_fw_download to zero on 
> >> success, so that the firmware loading functions also correctly 
> >> return zero on success.
> >>
> >> Signed-off-by: Ryan Mallon <ryan at bluewatersys.com>
> >>
> >> diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
> >> index 842a08d..8f8934a 100644
> >> --- a/drivers/net/wireless/libertas/if_cs.c
> >> +++ b/drivers/net/wireless/libertas/if_cs.c
> >> @@ -151,7 +151,7 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
> >>  	for (i = 0; i < 100000; i++) {
> >>  		u8 val = if_cs_read8(card, addr);
> >>  		if (val == reg)
> >> -			return i;
> >> +			return 0;
> >>  		udelay(5);
> >>  	}
> >>  	return -ETIME;
> > 
> > Looks good to me, care to post to linux-wireless or would you like me to
> > do that for you?
> 
> I'm not on the linux-wireless list, so can you push it through for me.
> Thanks.

Sure.

Dan



From grib at billgribble.com  Thu Oct 16 12:33:36 2008
From: grib at billgribble.com (Bill Gribble)
Date: Thu, 16 Oct 2008 12:33:36 -0400
Subject: Identify mystery libertas firmware?
In-Reply-To: <1223996931.3936.12.camel@localhost.localdomain>
References: <1223994412.7642.3.camel@grib>
	<1223996931.3936.12.camel@localhost.localdomain>
Message-ID: <1224174816.22524.31.camel@grib>

On Tue, 2008-10-14 at 11:08 -0400, Dan Williams wrote:
> On Tue, 2008-10-14 at 10:26 -0400, Bill Gribble wrote:
> > I came across a firmware file on my hard drive that was different than
> > the ones I had been trying on my Raon Everun (SD8686 internal), and
> > plopped it into /lib/firmware to see what happened.
> > 
> > Imagine my surprise when it worked!  Under kernel 2.6.27, I get an eth0
> > device and can join and use WPA networks with no problems. 
> > 
> > Unfortunately I don't know where this particular firmware file came
> > from.  Can anyone in libertas-land identify it based on its md5sum? 
> 
> What does the driver print out in the kernel logs when you load the part
> with this firmware?  It should print out the firmware version in the
> first few lines after the card is inserted.

Ah, ok.  Found it: 

   libertas: 00:19:88:xx:xx:xx, fw 8.73.7p3, cap 0x00000393

Works great, I see a few messages like this in the logs: 

   libertas: PREP_CMD: command 0x00a3 failed: 2

but they don't appear to do any harm. 

Thanks,
Bill Gribble






From dcbw at redhat.com  Thu Oct 16 13:14:39 2008
From: dcbw at redhat.com (Dan Williams)
Date: Thu, 16 Oct 2008 13:14:39 -0400
Subject: Identify mystery libertas firmware?
In-Reply-To: <1224174816.22524.31.camel@grib>
References: <1223994412.7642.3.camel@grib>
	<1223996931.3936.12.camel@localhost.localdomain>
	<1224174816.22524.31.camel@grib>
Message-ID: <1224177279.29029.1.camel@localhost.localdomain>

On Thu, 2008-10-16 at 12:33 -0400, Bill Gribble wrote:
> On Tue, 2008-10-14 at 11:08 -0400, Dan Williams wrote:
> > On Tue, 2008-10-14 at 10:26 -0400, Bill Gribble wrote:
> > > I came across a firmware file on my hard drive that was different than
> > > the ones I had been trying on my Raon Everun (SD8686 internal), and
> > > plopped it into /lib/firmware to see what happened.
> > > 
> > > Imagine my surprise when it worked!  Under kernel 2.6.27, I get an eth0
> > > device and can join and use WPA networks with no problems. 
> > > 
> > > Unfortunately I don't know where this particular firmware file came
> > > from.  Can anyone in libertas-land identify it based on its md5sum? 
> > 
> > What does the driver print out in the kernel logs when you load the part
> > with this firmware?  It should print out the firmware version in the
> > first few lines after the card is inserted.
> 
> Ah, ok.  Found it: 
> 
>    libertas: 00:19:88:xx:xx:xx, fw 8.73.7p3, cap 0x00000393

Yeah, I think thats pretty standard 8.x firmware for the SDIO parts.
There are a few references to people using it successfully elsewhere.
At least you picked a good one :)

> Works great, I see a few messages like this in the logs: 
> 
>    libertas: PREP_CMD: command 0x00a3 failed: 2
> 
> but they don't appear to do any harm. 

Yeah, MESH_CONFIG, which is normal.  The firmware will say it doesn't
know about the command and nothing abnormal should happen.

Dan




From ryan at bluewatersys.com  Thu Oct 16 15:52:38 2008
From: ryan at bluewatersys.com (Ryan Mallon)
Date: Fri, 17 Oct 2008 08:52:38 +1300
Subject: [PATCH] Fix cs firmware loading
In-Reply-To: <1224170463.3430.27.camel@localhost.localdomain>
References: <48F50139.9050608@bluewatersys.com>	
	<1224083321.31882.17.camel@dhcp-100-3-195.bos.redhat.com>	
	<48F64D48.7080404@bluewatersys.com>	
	<1224111321.22537.6.camel@70-4-70-178.area3.spcsdns.net>	
	<48F677CE.10307@bluewatersys.com>
	<1224170463.3430.27.camel@localhost.localdomain>
Message-ID: <48F79B86.4080109@bluewatersys.com>

Dan Williams wrote:
> On Thu, 2008-10-16 at 12:07 +1300, Ryan Mallon wrote:
>>
>> We aren't doing any particular work arounds. What were the hardware
>> problems with the compact flash 8385?
> 
> B1 and earlier HW versions (AmbiCom WL54-CF for example) will eventually
> time out and stop responding to commands because the hardware gets
> interrupt confirmations mixed up or something.  Holger had prototyped a
> workaround that used polling instead, and there are references to the
> issue in the gumstix driver.  If you're not having problems, then you're
> probably using b2 or later hardware.

Hmm, this sounds somewhat like the issue that our customer is having
with their boards. Our customer reported the following:

  iw_get_ext(wifi_fd, ifname, SIOCGIWTXPOW, &wrq)

could sometimes cause their system to hang. Removing this call stopped
their system from hanging, but scanning for networks would eventually
either stop returning anything, or constantly send the same results
(APs, signal strengths, etc). Doing:

  pccardctl eject; pccardctl insert

temporarily fixes the problem. We have been unable to replicate the
problem at our office, so it's possible that our customer has gotten a
batch of modules from the earlier hardware version, and we are using the
newer one.

We can't see any markings on the modules themselves for the hardware
revision. Is there a way to query it from software?

Holger, do you have a link to a patchset for your work around code for
the buggy hardware?

Cheers,
~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

       Ryan Mallon                              Unit 5, Amuri Park
       Phone: +64 3 3779127                     404 Barbadoes St
       Fax:   +64 3 3779135                     PO Box 13 889
       Email: ryan at bluewatersys.com             Christchurch, 8013
       Web:   http://www.bluewatersys.com       New Zealand
       Freecall Australia  1800 148 751         USA 1800 261 2934


From seomarine at yahoo.com  Thu Oct 16 20:02:25 2008
From: seomarine at yahoo.com (Jeong-Hwan Seo)
Date: Fri, 17 Oct 2008 09:02:25 +0900 (KST)
Subject: Changing ESSID in ad-hoc mode make kernel bug
Message-ID: <91112.53563.qm@web70802.mail.kr3.yahoo.com>

Hi all, 

I found some problems in libertas driver.
The initial command setting essid succeeds.
But following command changing essid makes kernel bug.

I find that it happens only in adhoc mode.

operation : 
# iwconfig eth0 mode ad-hoc
# iwconfig eth0 essid HI
# iwconfig eth0 essid HELLO

BUG: scheduling while atomic: iwconfig/801/0x00000002
[<c002a2e0>] (dump_stack+0x0/0x14) from [<c00395ec>]
(__schedule_bug+0x4c/0x58)
[<c00395a0>] (__schedule_bug+0x0/0x58) from
[<c02845f4>] (schedule+0x74/0x314)
 r4:c7a39240
[<c0284580>] (schedule+0x0/0x314) from [<c0186744>]
(__lbs_cmd+0x11c/0x210)
[<c0186628>] (__lbs_cmd+0x0/0x210) from [<c0181ed8>]
(lbs_get_wireless_stats+0x1a8/0x350)
[<c0181d30>] (lbs_get_wireless_stats+0x0/0x350) from
[<c025d018>] (get_wireless_stats+0x2c/0x38)
 r8:00000001 r7:4001e000 r6:000000a2 r5:c7a4d2e0
r4:c709c000
[<c025cfec>] (get_wireless_stats+0x0/0x38) from
[<c025ded0>] (wireless_seq_show+0x38/0x108)
[<c025de98>] (wireless_seq_show+0x0/0x108) from
[<c00ac874>] (seq_read+0x240/0x394)
[<c00ac634>] (seq_read+0x0/0x394) from [<c00c4894>]
(proc_reg_read+0xb4/0xc8)
[<c00c47e0>] (proc_reg_read+0x0/0xc8) from
[<c008eefc>] (vfs_read+0xb0/0xd8)
[<c008ee4c>] (vfs_read+0x0/0xd8) from [<c008f2d8>]
(sys_read+0x44/0x70)
 r6:00000000 r5:fffffff7 r4:c782a8a0
[<c008f294>] (sys_read+0x0/0x70) from [<c0025ae0>]
(ret_fast_syscall+0x0/0x2c)
 r7:00000003 r6:000003ff r5:00015008 r4:00015008

After Bug message : 
# iwconfig
lo        no wireless extensions.

eth0      IEEE 802.11b/g  ESSID:"HELLO"
          Mode:Ad-Hoc  Frequency:2.412 GHz  Cell:
02:2D:2D:60:D2:55
          Bit Rate:0 kb/s   Tx-Power=18 dBm
          Retry limit:8   RTS thr=2347 B   Fragment
thr=2346 B
          Encryption key:off
          Power Management:off
          Link Quality=0/100  Signal level=-11 dBm 
Noise level=-11 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx
invalid frag:0
          Tx excessive retries:0  Invalid misc:0  
Missed beacon:0

I investigated the libertas code and I found
something.
lbs_get_wireless_stats calls lbs_cmd_with_response
lbs_cmd_with_response(__lbs_cmd) calls
wait_event_interruptible
During wait_event_interruptible(schedule()), kernel
bug is checked.
Finally, __schedule_bug function prints
"BUG:Scheduling while atomic".

I tested it under 2.6.26 version with Marvell sd8686
chipset.
I will appreciate your help.
===================================
Jase.
SW center Samsung Electronics CO., LTD.
Mobile : 010-7322-5759 TEL : 031-279-8028
E-mail : jh2931.seo at samsung.com
seomarine at yahoo.com
===================================



      ________________________________________________________ 
180? ??? ??! ?? - ??! ??? ??! ????? ???? ???? ??? ?? ? ????.
http://kr.content.mail.yahoo.com/cgland


From hs4233 at mail.mn-solutions.de  Fri Oct 17 03:36:59 2008
From: hs4233 at mail.mn-solutions.de (Holger Schurig)
Date: Fri, 17 Oct 2008 09:36:59 +0200
Subject: [PATCH] libertas: handle hardware events outside ISR
In-Reply-To: <48F79B86.4080109@bluewatersys.com>
References: <48F50139.9050608@bluewatersys.com>
	<1224170463.3430.27.camel@localhost.localdomain>
	<48F79B86.4080109@bluewatersys.com>
Message-ID: <200810170937.00052.hs4233@mail.mn-solutions.de>

This is the code that I'm using since some months, but which I 
didn't post so far because I see some obvious problems:

* it produces a considerable amount of latency on my device,
  e.g. while scanning or associating
* it's not completely cleaned up, e.g. remove all lines in
  #ifdef WITH_TASKLET, that is a remnant of a test I made

But on the other side it showed to be rock-solid in day-to-day
use, e.g. with a GUI application that calls the equivalent of
"iwconfig eth1" every second.

In case you want to massage this patch and put it into the
Kernel, here is my:

Signed-off-by: Holger Schurig <hs4233 at mail.mn-solutions.de>

--- linux.orig/drivers/net/wireless/libertas/dev.h
+++ linux/drivers/net/wireless/libertas/dev.h
@@ -154,6 +154,7 @@
 	/** Hardware access */
 	int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 
*payload, u16 nb);
 	void (*reset_card) (struct lbs_private *priv);
+	void (*poll_card) (struct lbs_private *priv);
 
 	/* Wake On LAN */
 	uint32_t wol_criteria;
@@ -195,6 +196,8 @@
 
 	/* Events sent from hardware to driver */
 	struct kfifo *event_fifo;
+#define LBS_EVENT_MASK 0xff0000
+#define LBS_EVENT_WAKE 0xff0001
 
 	/* nickname */
 	u8 nodename[16];
--- linux.orig/drivers/net/wireless/libertas/if_cs.c
+++ linux/drivers/net/wireless/libertas/if_cs.c
@@ -55,10 +55,17 @@
 /* Data structures                                                  
*/
 /********************************************************************/
 
+/* #define WITH_TASKLET */
+
 struct if_cs_card {
 	struct pcmcia_device *p_dev;
 	struct lbs_private *priv;
 	void __iomem *iobase;
+	spinlock_t lock;
+	u16 int_cause;
+#ifdef WITH_TASKLET
+	struct tasklet_struct tasklet;
+#endif
 };
 
 
@@ -238,6 +245,7 @@
  */
 #define IF_CS_CARD_STATUS		0x00000020
 #define IF_CS_CARD_STATUS_MASK		0x7f00
+#define IF_CS_CARD_STATUS_EVENT	(IF_CS_CARD_STATUS_MASK | 
IF_CS_BIT_EVENT)
 
 /*
  * The card int cause register is used by the card/firmware to 
notify us
@@ -304,22 +312,8 @@
 {
 	struct if_cs_card *card = (struct if_cs_card *)priv->card;
 	int ret = -1;
-	int loops = 0;
 
 	lbs_deb_enter(LBS_DEB_CS);
-	if_cs_disable_ints(card);
-
-	/* Is hardware ready? */
-	while (1) {
-		u16 status = if_cs_read16(card, IF_CS_CARD_STATUS);
-		if (status & IF_CS_BIT_COMMAND)
-			break;
-		if (++loops > 100) {
-			lbs_pr_err("card not ready for commands\n");
-			goto done;
-		}
-		mdelay(1);
-	}
 
 	if_cs_write16(card, IF_CS_CMD_LEN, nb);
 
@@ -337,8 +331,6 @@
 	if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
 	ret = 0;
 
-done:
-	if_cs_enable_ints(card);
 	lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
 	return ret;
 }
@@ -349,13 +341,8 @@
 static void if_cs_send_data(struct lbs_private *priv, u8 *buf, 
u16 nb)
 {
 	struct if_cs_card *card = (struct if_cs_card *)priv->card;
-	u16 status;
 
 	lbs_deb_enter(LBS_DEB_CS);
-	if_cs_disable_ints(card);
-
-	status = if_cs_read16(card, IF_CS_CARD_STATUS);
-	BUG_ON((status & IF_CS_BIT_TX) == 0);
 
 	if_cs_write16(card, IF_CS_WRITE_LEN, nb);
 
@@ -366,30 +353,20 @@
 
 	if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_TX);
 	if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_TX);
-	if_cs_enable_ints(card);
 
 	lbs_deb_leave(LBS_DEB_CS);
 }
 
 /*
- * Get the command result out of the card.
+ * Get the command response out of the card.
  */
-static int if_cs_receive_cmdres(struct lbs_private *priv, u8 
*data, u32 *len)
+static int if_cs_receive_resp(struct lbs_private *priv, u8 
*data, u32 *len)
 {
 	unsigned long flags;
 	int ret = -1;
-	u16 status;
 
 	lbs_deb_enter(LBS_DEB_CS);
 
-	/* is hardware ready? */
-	status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
-	if ((status & IF_CS_BIT_RESP) == 0) {
-		lbs_pr_err("no cmd response in card\n");
-		*len = 0;
-		goto out;
-	}
-
 	*len = if_cs_read16(priv->card, IF_CS_RESP_LEN);
 	if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
 		lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", 
*len);
@@ -425,6 +402,7 @@
 	lbs_deb_enter(LBS_DEB_CS);
 
 	len = if_cs_read16(priv->card, IF_CS_READ_LEN);
+	//lbs_deb_cs("rx %d\n", len);
 	if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
 		lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", 
len);
 		priv->stats.rx_dropped++;
@@ -455,74 +433,138 @@
 static irqreturn_t if_cs_interrupt(int irq, void *data)
 {
 	struct if_cs_card *card = data;
-	struct lbs_private *priv = card->priv;
-	u16 cause;
+	//struct lbs_private *priv = card->priv;
+	unsigned long flags;
+	u16 cause, status;
 
 	lbs_deb_enter(LBS_DEB_CS);
 
-	/* Ask card interrupt cause register if there is something for 
us */
+	if_cs_disable_ints(card);
+
 	cause = if_cs_read16(card, IF_CS_CARD_INT_CAUSE);
 	lbs_deb_cs("cause 0x%04x\n", cause);
 
 	if (cause == 0) {
 		/* Not for us */
+		if_cs_enable_ints(card);
 		return IRQ_NONE;
 	}
 
 	if (cause == 0xffff) {
 		/* Read in junk, the card has probably been removed */
 		card->priv->surpriseremoved = 1;
+		if_cs_enable_ints(card);
 		return IRQ_HANDLED;
 	}
 
+	/* read card status to clear event bit */
+	status = if_cs_read16(card, IF_CS_CARD_STATUS);
+	lbs_deb_cs("status 0x%04x\n", status);
+
+	cause &= IF_CS_BIT_MASK;
+
+	/* Store the interupt cause in our shadow */
+	spin_lock_irqsave(&card->lock, flags);
+	card->int_cause |= cause;
+	if (!(cause && IF_CS_BIT_RX) && status & IF_CS_BIT_RX) {
+		/* We sometimes miss an RX interrupt, but we can deduce this
+		 * fact from the status */
+		lbs_deb_cs("forcing IF_CS_BIT_RX\n");
+		card->int_cause |= IF_CS_BIT_RX;
+	}
+	if (status & IF_CS_BIT_EVENT) {
+		/* Store the event bit and the event code into our
+		 * int_cause shadow */
+		lbs_deb_cs("transferring event\n");
+		card->int_cause |= (status & IF_CS_CARD_STATUS_EVENT);
+	}
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	/* Clear interrupt cause */
+	if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause);
+
+#ifdef WITH_TASKLET
+	/* Simple way to keep the main thread from sleeping :-) */
+	tasklet_schedule(&card->tasklet);
+#else
+	lbs_queue_event(card->priv, LBS_EVENT_WAKE);
+#endif
+
+	if_cs_enable_ints(card);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef WITH_TASKLET
+static void if_cs_poll_status(unsigned long data)
+{
+	struct if_cs_card *card = (struct if_cs_card *)data;
+	struct lbs_private *priv = card->priv;
+#else
+static void if_cs_poll_status(struct lbs_private *priv)
+{
+	struct if_cs_card *card = (struct if_cs_card *)priv->card;
+#endif
+	unsigned long flags;
+	u16 cause;
+
+	lbs_deb_enter(LBS_DEB_CS);
+
+	if (priv->surpriseremoved)
+		return;
+
+	spin_lock_irqsave(&card->lock, flags);
+	cause = card->int_cause;
+	card->int_cause = 0;
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	lbs_deb_cs("int_cause 0x%04x\n", cause);
+
+	if (!cause)
+		return;
+
+	if (cause & IF_CS_BIT_TX) {
+		lbs_deb_cs("tx\n");
+		lbs_host_to_card_done(priv);
+	}
+
 	if (cause & IF_CS_BIT_RX) {
 		struct sk_buff *skb;
-		lbs_deb_cs("rx packet\n");
 		skb = if_cs_receive_data(priv);
 		if (skb)
 			lbs_process_rxed_packet(priv, skb);
 	}
 
-	if (cause & IF_CS_BIT_TX) {
-		lbs_deb_cs("tx done\n");
-		lbs_host_to_card_done(priv);
-	}
-
 	if (cause & IF_CS_BIT_RESP) {
-		unsigned long flags;
+		unsigned long driver_flags;
 		u8 i;
 
-		lbs_deb_cs("cmd resp\n");
-		spin_lock_irqsave(&priv->driver_lock, flags);
+		lbs_deb_cs("resp\n");
+		spin_lock_irqsave(&priv->driver_lock, driver_flags);
 		i = (priv->resp_idx == 0) ? 1 : 0;
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
+		spin_unlock_irqrestore(&priv->driver_lock, driver_flags);
 
 		BUG_ON(priv->resp_len[i]);
-		if_cs_receive_cmdres(priv, priv->resp_buf[i],
+		if_cs_receive_resp(priv, priv->resp_buf[i],
 			&priv->resp_len[i]);
 
-		spin_lock_irqsave(&priv->driver_lock, flags);
+		spin_lock_irqsave(&priv->driver_lock, driver_flags);
 		lbs_notify_command_response(priv, i);
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
+		spin_unlock_irqrestore(&priv->driver_lock, driver_flags);
 	}
 
 	if (cause & IF_CS_BIT_EVENT) {
-		u16 status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
 		if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE,
 			IF_CS_BIT_EVENT);
-		lbs_queue_event(priv, (status & IF_CS_CARD_STATUS_MASK) >> 8);
+		lbs_queue_event(priv, (cause & IF_CS_CARD_STATUS_MASK) >> 8);
 	}
 
-	/* Clear interrupt cause */
-	if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & 
IF_CS_BIT_MASK);
-
+	if_cs_enable_ints(card);
 	lbs_deb_leave(LBS_DEB_CS);
-	return IRQ_HANDLED;
 }
 
 
 
-
 /********************************************************************/
 /* Firmware                                                         
*/
 /********************************************************************/
@@ -847,6 +889,11 @@
 		}
 	}
 
+	spin_lock_init(&card->lock);
+#ifdef WITH_TASKLET
+	tasklet_init(&card->tasklet, if_cs_poll_status, (unsigned 
long)card);
+#endif
+
 	/* Initialize io access */
 	card->iobase = ioport_map(p_dev->io.BasePort1, 
p_dev->io.NumPorts1);
 	if (!card->iobase) {
@@ -903,6 +950,9 @@
 	card->priv = priv;
 	priv->card = card;
 	priv->hw_host_to_card = if_cs_host_to_card;
+#ifndef WITH_TASKLET
+	priv->poll_card = if_cs_poll_status;
+#endif
 	priv->fw_ready = 1;
 
 	/* Now actually get the IRQ */
--- linux.orig/drivers/net/wireless/libertas/main.c
+++ linux/drivers/net/wireless/libertas/main.c
@@ -706,6 +706,10 @@
 
 		add_wait_queue(&priv->waitq, &wait);
 		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (priv->poll_card)
+			priv->poll_card(priv);
+
 		spin_lock_irq(&priv->driver_lock);
 
 		if (kthread_should_stop())
@@ -812,9 +816,12 @@
 
 			__kfifo_get(priv->event_fifo, (unsigned char *) &event,
 				sizeof(event));
-			spin_unlock_irq(&priv->driver_lock);
-			lbs_process_event(priv, event);
-			spin_lock_irq(&priv->driver_lock);
+			/* ignore LBS_EVENT_xxx events */
+			if (!(event & LBS_EVENT_MASK)) {
+				spin_unlock_irq(&priv->driver_lock);
+				lbs_process_event(priv, event);
+				spin_lock_irq(&priv->driver_lock);
+			}
 		}
 		spin_unlock_irq(&priv->driver_lock);
 


From hs4233 at mail.mn-solutions.de  Fri Oct 17 03:38:32 2008
From: hs4233 at mail.mn-solutions.de (Holger Schurig)
Date: Fri, 17 Oct 2008 09:38:32 +0200
Subject: [PATCH] Fix cs firmware loading
In-Reply-To: <48F79B86.4080109@bluewatersys.com>
References: <48F50139.9050608@bluewatersys.com>
	<1224170463.3430.27.camel@localhost.localdomain>
	<48F79B86.4080109@bluewatersys.com>
Message-ID: <200810170938.32684.hs4233@mail.mn-solutions.de>

Here again, with line-wrapping off:

[PATCH] libertas: handle hardware events outside ISR

Signed-off-by: Holger Schurig <hs4233 at mail.mn-solutions.de>

--- linux.orig/drivers/net/wireless/libertas/dev.h
+++ linux/drivers/net/wireless/libertas/dev.h
@@ -154,6 +154,7 @@
 	/** Hardware access */
 	int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
 	void (*reset_card) (struct lbs_private *priv);
+	void (*poll_card) (struct lbs_private *priv);
 
 	/* Wake On LAN */
 	uint32_t wol_criteria;
@@ -195,6 +196,8 @@
 
 	/* Events sent from hardware to driver */
 	struct kfifo *event_fifo;
+#define LBS_EVENT_MASK 0xff0000
+#define LBS_EVENT_WAKE 0xff0001
 
 	/* nickname */
 	u8 nodename[16];
--- linux.orig/drivers/net/wireless/libertas/if_cs.c
+++ linux/drivers/net/wireless/libertas/if_cs.c
@@ -55,10 +55,17 @@
 /* Data structures                                                  */
 /********************************************************************/
 
+/* #define WITH_TASKLET */
+
 struct if_cs_card {
 	struct pcmcia_device *p_dev;
 	struct lbs_private *priv;
 	void __iomem *iobase;
+	spinlock_t lock;
+	u16 int_cause;
+#ifdef WITH_TASKLET
+	struct tasklet_struct tasklet;
+#endif
 };
 
 
@@ -238,6 +245,7 @@
  */
 #define IF_CS_CARD_STATUS		0x00000020
 #define IF_CS_CARD_STATUS_MASK		0x7f00
+#define IF_CS_CARD_STATUS_EVENT	(IF_CS_CARD_STATUS_MASK | IF_CS_BIT_EVENT)
 
 /*
  * The card int cause register is used by the card/firmware to notify us
@@ -304,22 +312,8 @@
 {
 	struct if_cs_card *card = (struct if_cs_card *)priv->card;
 	int ret = -1;
-	int loops = 0;
 
 	lbs_deb_enter(LBS_DEB_CS);
-	if_cs_disable_ints(card);
-
-	/* Is hardware ready? */
-	while (1) {
-		u16 status = if_cs_read16(card, IF_CS_CARD_STATUS);
-		if (status & IF_CS_BIT_COMMAND)
-			break;
-		if (++loops > 100) {
-			lbs_pr_err("card not ready for commands\n");
-			goto done;
-		}
-		mdelay(1);
-	}
 
 	if_cs_write16(card, IF_CS_CMD_LEN, nb);
 
@@ -337,8 +331,6 @@
 	if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
 	ret = 0;
 
-done:
-	if_cs_enable_ints(card);
 	lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
 	return ret;
 }
@@ -349,13 +341,8 @@
 static void if_cs_send_data(struct lbs_private *priv, u8 *buf, u16 nb)
 {
 	struct if_cs_card *card = (struct if_cs_card *)priv->card;
-	u16 status;
 
 	lbs_deb_enter(LBS_DEB_CS);
-	if_cs_disable_ints(card);
-
-	status = if_cs_read16(card, IF_CS_CARD_STATUS);
-	BUG_ON((status & IF_CS_BIT_TX) == 0);
 
 	if_cs_write16(card, IF_CS_WRITE_LEN, nb);
 
@@ -366,30 +353,20 @@
 
 	if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_TX);
 	if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_TX);
-	if_cs_enable_ints(card);
 
 	lbs_deb_leave(LBS_DEB_CS);
 }
 
 /*
- * Get the command result out of the card.
+ * Get the command response out of the card.
  */
-static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
+static int if_cs_receive_resp(struct lbs_private *priv, u8 *data, u32 *len)
 {
 	unsigned long flags;
 	int ret = -1;
-	u16 status;
 
 	lbs_deb_enter(LBS_DEB_CS);
 
-	/* is hardware ready? */
-	status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
-	if ((status & IF_CS_BIT_RESP) == 0) {
-		lbs_pr_err("no cmd response in card\n");
-		*len = 0;
-		goto out;
-	}
-
 	*len = if_cs_read16(priv->card, IF_CS_RESP_LEN);
 	if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
 		lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);
@@ -425,6 +402,7 @@
 	lbs_deb_enter(LBS_DEB_CS);
 
 	len = if_cs_read16(priv->card, IF_CS_READ_LEN);
+	//lbs_deb_cs("rx %d\n", len);
 	if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
 		lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len);
 		priv->stats.rx_dropped++;
@@ -455,74 +433,138 @@
 static irqreturn_t if_cs_interrupt(int irq, void *data)
 {
 	struct if_cs_card *card = data;
-	struct lbs_private *priv = card->priv;
-	u16 cause;
+	//struct lbs_private *priv = card->priv;
+	unsigned long flags;
+	u16 cause, status;
 
 	lbs_deb_enter(LBS_DEB_CS);
 
-	/* Ask card interrupt cause register if there is something for us */
+	if_cs_disable_ints(card);
+
 	cause = if_cs_read16(card, IF_CS_CARD_INT_CAUSE);
 	lbs_deb_cs("cause 0x%04x\n", cause);
 
 	if (cause == 0) {
 		/* Not for us */
+		if_cs_enable_ints(card);
 		return IRQ_NONE;
 	}
 
 	if (cause == 0xffff) {
 		/* Read in junk, the card has probably been removed */
 		card->priv->surpriseremoved = 1;
+		if_cs_enable_ints(card);
 		return IRQ_HANDLED;
 	}
 
+	/* read card status to clear event bit */
+	status = if_cs_read16(card, IF_CS_CARD_STATUS);
+	lbs_deb_cs("status 0x%04x\n", status);
+
+	cause &= IF_CS_BIT_MASK;
+
+	/* Store the interupt cause in our shadow */
+	spin_lock_irqsave(&card->lock, flags);
+	card->int_cause |= cause;
+	if (!(cause && IF_CS_BIT_RX) && status & IF_CS_BIT_RX) {
+		/* We sometimes miss an RX interrupt, but we can deduce this
+		 * fact from the status */
+		lbs_deb_cs("forcing IF_CS_BIT_RX\n");
+		card->int_cause |= IF_CS_BIT_RX;
+	}
+	if (status & IF_CS_BIT_EVENT) {
+		/* Store the event bit and the event code into our
+		 * int_cause shadow */
+		lbs_deb_cs("transferring event\n");
+		card->int_cause |= (status & IF_CS_CARD_STATUS_EVENT);
+	}
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	/* Clear interrupt cause */
+	if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause);
+
+#ifdef WITH_TASKLET
+	/* Simple way to keep the main thread from sleeping :-) */
+	tasklet_schedule(&card->tasklet);
+#else
+	lbs_queue_event(card->priv, LBS_EVENT_WAKE);
+#endif
+
+	if_cs_enable_ints(card);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef WITH_TASKLET
+static void if_cs_poll_status(unsigned long data)
+{
+	struct if_cs_card *card = (struct if_cs_card *)data;
+	struct lbs_private *priv = card->priv;
+#else
+static void if_cs_poll_status(struct lbs_private *priv)
+{
+	struct if_cs_card *card = (struct if_cs_card *)priv->card;
+#endif
+	unsigned long flags;
+	u16 cause;
+
+	lbs_deb_enter(LBS_DEB_CS);
+
+	if (priv->surpriseremoved)
+		return;
+
+	spin_lock_irqsave(&card->lock, flags);
+	cause = card->int_cause;
+	card->int_cause = 0;
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	lbs_deb_cs("int_cause 0x%04x\n", cause);
+
+	if (!cause)
+		return;
+
+	if (cause & IF_CS_BIT_TX) {
+		lbs_deb_cs("tx\n");
+		lbs_host_to_card_done(priv);
+	}
+
 	if (cause & IF_CS_BIT_RX) {
 		struct sk_buff *skb;
-		lbs_deb_cs("rx packet\n");
 		skb = if_cs_receive_data(priv);
 		if (skb)
 			lbs_process_rxed_packet(priv, skb);
 	}
 
-	if (cause & IF_CS_BIT_TX) {
-		lbs_deb_cs("tx done\n");
-		lbs_host_to_card_done(priv);
-	}
-
 	if (cause & IF_CS_BIT_RESP) {
-		unsigned long flags;
+		unsigned long driver_flags;
 		u8 i;
 
-		lbs_deb_cs("cmd resp\n");
-		spin_lock_irqsave(&priv->driver_lock, flags);
+		lbs_deb_cs("resp\n");
+		spin_lock_irqsave(&priv->driver_lock, driver_flags);
 		i = (priv->resp_idx == 0) ? 1 : 0;
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
+		spin_unlock_irqrestore(&priv->driver_lock, driver_flags);
 
 		BUG_ON(priv->resp_len[i]);
-		if_cs_receive_cmdres(priv, priv->resp_buf[i],
+		if_cs_receive_resp(priv, priv->resp_buf[i],
 			&priv->resp_len[i]);
 
-		spin_lock_irqsave(&priv->driver_lock, flags);
+		spin_lock_irqsave(&priv->driver_lock, driver_flags);
 		lbs_notify_command_response(priv, i);
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
+		spin_unlock_irqrestore(&priv->driver_lock, driver_flags);
 	}
 
 	if (cause & IF_CS_BIT_EVENT) {
-		u16 status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
 		if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE,
 			IF_CS_BIT_EVENT);
-		lbs_queue_event(priv, (status & IF_CS_CARD_STATUS_MASK) >> 8);
+		lbs_queue_event(priv, (cause & IF_CS_CARD_STATUS_MASK) >> 8);
 	}
 
-	/* Clear interrupt cause */
-	if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & IF_CS_BIT_MASK);
-
+	if_cs_enable_ints(card);
 	lbs_deb_leave(LBS_DEB_CS);
-	return IRQ_HANDLED;
 }
 
 
 
-
 /********************************************************************/
 /* Firmware                                                         */
 /********************************************************************/
@@ -847,6 +889,11 @@
 		}
 	}
 
+	spin_lock_init(&card->lock);
+#ifdef WITH_TASKLET
+	tasklet_init(&card->tasklet, if_cs_poll_status, (unsigned long)card);
+#endif
+
 	/* Initialize io access */
 	card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1);
 	if (!card->iobase) {
@@ -903,6 +950,9 @@
 	card->priv = priv;
 	priv->card = card;
 	priv->hw_host_to_card = if_cs_host_to_card;
+#ifndef WITH_TASKLET
+	priv->poll_card = if_cs_poll_status;
+#endif
 	priv->fw_ready = 1;
 
 	/* Now actually get the IRQ */
--- linux.orig/drivers/net/wireless/libertas/main.c
+++ linux/drivers/net/wireless/libertas/main.c
@@ -706,6 +706,10 @@
 
 		add_wait_queue(&priv->waitq, &wait);
 		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (priv->poll_card)
+			priv->poll_card(priv);
+
 		spin_lock_irq(&priv->driver_lock);
 
 		if (kthread_should_stop())
@@ -812,9 +816,12 @@
 
 			__kfifo_get(priv->event_fifo, (unsigned char *) &event,
 				sizeof(event));
-			spin_unlock_irq(&priv->driver_lock);
-			lbs_process_event(priv, event);
-			spin_lock_irq(&priv->driver_lock);
+			/* ignore LBS_EVENT_xxx events */
+			if (!(event & LBS_EVENT_MASK)) {
+				spin_unlock_irq(&priv->driver_lock);
+				lbs_process_event(priv, event);
+				spin_lock_irq(&priv->driver_lock);
+			}
 		}
 		spin_unlock_irq(&priv->driver_lock);
 


From seomarine at yahoo.com  Fri Oct 17 05:55:28 2008
From: seomarine at yahoo.com (Jeong-Hwan Seo)
Date: Fri, 17 Oct 2008 18:55:28 +0900 (KST)
Subject: Reloading problem
Message-ID: <946091.54320.qm@web70801.mail.kr3.yahoo.com>

Hi everybody.
I already read post about reloading problem of
libertas driver module.
(Reloading of libertas driver module make kernel
broken.)
Has anybody found solution about the problem?

This is log messages about the problem
=======================================================================================
# insmod libertas_sdio.ko
libertas_sdio: Libertas SDIO driver
libertas_sdio: Copyright Pierre Ossman
firmware: requesting helper_sd.bin
firmware: requesting sd8686.bin
libertas: 00:50:43:02:fe:01, fw 9.70.2p1, cap
0x0000030b
libertas: eth0: Marvell WLAN 802.11 adapter
# rmmod libertas_sdio
# insmod libertas_sdio.ko
libertas_sdio: Libertas SDIO driver
libertas_sdio: Copyright Pierre Ossman
firmware: requesting helper_sd.bin
firmware: requesting sd8686.bin
Unable to handle kernel NULL pointer dereference at
virtual address 00000b18
pgd = c0004000
[00000b18] *pgd=00000000
Internal error: Oops: 17 [#1] PREEMPT
Modules linked in: libertas_sdio(+) [last unloaded:
libertas_sdio]
CPU: 0    Not tainted  (2.6.26-00186-g76fe58a-dirty
#50)
PC is at lbs_host_to_card_done+0x70/0x134
LR is at lbs_host_to_card_done+0x70/0x134
pc : [<c017c6b0>]    lr : [<c017c6b0>]    psr:
80000193
sp : c7111f38  ip : c7111f38  fp : c7111f4c
r10: 00000000  r9 : 00000002  r8 : 00400001
r7 : c03b1878  r6 : c7111f5c  r5 : 00000000  r4 :
80000113
r3 : 00000000  r2 : c7110000  r1 : 00000001  r0 :
00000001
Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM 
Segment kernel
Control: 00c5387f  Table: 57100008  DAC: 00000017
Process ksdiorqd (pid: 802, stack limit = 0xc7110260)
Stack: (0xc7111f38 to 0xc7112000)
1f20:                                                 
     00000002 c70e0000
1f40: c7111f8c c7111f50 bf00125c c017c64c 00000000
00000195 00000000 00000000
1f60: 00000000 00000000 c7989000 c7a41e00 c7a41e00
00000001 00000002 00000000
1f80: c7111fd4 c7111f90 c01d56bc bf001168 00000000
c7111fa7 00000002 c7110000
1fa0: 00000001 020392ac c7111fd4 c7110000 c7989000
c01d55c4 00000000 00000000
1fc0: 00000000 00000000 c7111ff4 c7111fd8 c0054df8
c01d55d0 00000000 00000000
1fe0: 00000000 00000000 00000000 c7111ff8 c0042ca0
c0054da8 c0000bd8 c0000b70
Backtrace:
[<c017c640>] (lbs_host_to_card_done+0x0/0x134) from
[<bf00125c>] (if_sdio_interrupt+0x100/0x958
[libertas_sdio])
 r5:c70e0000 r4:00000002
[<bf00115c>] (if_sdio_interrupt+0x0/0x958
[libertas_sdio]) from [<c01d56bc>]
(sdio_irq_thread+0xf8/0x1f8)
[<c01d55c4>] (sdio_irq_thread+0x0/0x1f8) from
[<c0054df8>] (kthread+0x5c/0x94)


What I find out is card->priv is NULL pointer.
In, if_sdio.c if_sdio_interrupt calls
lbs_host_tocard_done(card->priv)
Here, card->priv is NULL pointer.
And, when kernel try to access priv it crashes.
I hope somebody could solve this problem.

I appreciate your help.




__________________________________________________
? ? ??!?
????? ?????? ??! ??? ?? ?? ??? ??? ????? 
http://mail.yahoo.co.kr


From raghavendra.akkasali at gmail.com  Tue Oct 21 02:12:49 2008
From: raghavendra.akkasali at gmail.com (Raghavendra. S)
Date: Tue, 21 Oct 2008 11:42:49 +0530
Subject: Need marvell GSPI 8686 spec
Message-ID: <58a444250810202312h25e26286od05d800f0b6eb984@mail.gmail.com>

Hi,

 Any body has marell GSPI 8686 wifi chipset specification. please
share it with me?

 Also I have few doubts

How many clients can be connected in Ad-Hoc mode
Whether this chipset has router functionality, I mean can we make it a AP?

-- 
Regards & Thanks
Raghavendra. S


From dcbw at redhat.com  Tue Oct 21 09:08:11 2008
From: dcbw at redhat.com (Dan Williams)
Date: Tue, 21 Oct 2008 09:08:11 -0400
Subject: Need marvell GSPI 8686 spec
In-Reply-To: <58a444250810202312h25e26286od05d800f0b6eb984@mail.gmail.com>
References: <58a444250810202312h25e26286od05d800f0b6eb984@mail.gmail.com>
Message-ID: <1224594491.24581.6.camel@localhost.localdomain>

On Tue, 2008-10-21 at 11:42 +0530, Raghavendra. S wrote:
> Hi,
> 
>  Any body has marell GSPI 8686 wifi chipset specification. please
> share it with me?
> 
>  Also I have few doubts
> 
> How many clients can be connected in Ad-Hoc mode
> Whether this chipset has router functionality, I mean can we make it a AP?

See my replies on the hostap list...

Dan




From anna at cozybit.com  Mon Oct 20 19:49:58 2008
From: anna at cozybit.com (Anna Neal)
Date: Mon, 20 Oct 2008 16:49:58 -0700
Subject: [RFC] libertas: iwpriv commands to configure fine grained
	wake-on-(w)lan
Message-ID: <48fe2917.131e640a.7efb.7d0b@mx.google.com>

View README for new API.

This patch implements the userspace interface for fine-grained configuration of
wake-on-(w)lan.  We are aware that iwpriv's are discouraged, but this is a
vendor-specific feature that's currently being used in the OLPC project.

We are aware that all iwprivs were removed from this driver.  These used the old
API for iwprivs.  We've implemented this iwpriv as a private handler which relies
on wireless extensions to do bounds checking and copying to/from user memory.
Specific suggestions on how to make this more palatable for upstream inclusion
are welcome.  If iwprivs are completely unacceptable then this can serve as a
public reference for interfacing with these features.

Signed-off-by: Anna Neal <anna at cozybit.com>
Signed-off-by: Javier Cardona <javier at cozybit.com>
---
 drivers/net/wireless/libertas/README |   71 ++++++++
 drivers/net/wireless/libertas/wext.c |  323 ++++++++++++++++++++++++++++++++++
 2 files changed, 394 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
index d860fc3..6eb30a3 100644
--- a/drivers/net/wireless/libertas/README
+++ b/drivers/net/wireless/libertas/README
@@ -28,6 +28,77 @@ DRIVER LOADING
 
 		insmod usb8388.ko [fw_name=usb8388.bin]
 
+=====================
+IWPRIV COMMAND
+=====================
+
+Wake On Lan Commands:
+
+	The Wake On Lan (wol) commands are used to configure wol rules outside
+	of the constraints of ethtool. the following commands are supported:
+
+
+	iwpriv ethX set_wol_rule
+	iwpriv ethX get_wol_rule
+	iwpriv ethX reset_wol_rule
+
+
+set_wol_rule
+
+	Usage:
+
+	    $iwpriv msh0 set_wol_rule "<b|m|u> 0x<signature>{.<mask>}@<offset>"
+
+
+	1. The first digit is the traffic type:
+		b - broadcast
+		m - multicast
+		u - unicast
+
+	2. The pattern signature used for comparison to the incoming frame.
+	   This can be from 1-4 bytes and must be in the standard hex format
+	   with a leading '0x'.
+
+	3. An optional '.' may be added to specify a mask you wish to use. By
+	   default it will be 0xf for the length of your signature.
+
+	4. An offset after the '@' is mandatory this will specify the offset
+	   into the payload of an 802.3 frame at which the signature will be
+	   compared.
+
+	5. In addition, you may 'and' multiple rules separated by '&&' in the
+	   same call.
+
+	Note:
+		Every iwpriv, as shown above, will add new wol rules and 'or'
+		them to any previous rules entered.
+		At most 16 rules may be applied.
+
+	Examples:
+
+	1. Wake from an arp request received over the mesh at 192.168.0.1.
+
+		iwpriv msh0 set_wol_rule "b 0x0806 at 06 && 0xC0A80001 at 16"
+
+	2. Set to wake from any arp request or any multicast traffic from
+	   192.168.0.1.
+
+		iwpriv eth0 set_wol_rule "b 0x0806 at 06"
+		iwpriv eth0 set_wol_rule "m 0xC0A80001 at 16"
+
+	3. Set to wake from an arp or IPv4 broadcast (ethertypes 0x0806 and
+	   0x0806)
+
+		iwpriv eth0 set_wol_rule "b 0x0800.fff9 at 06"
+
+get_wol_rule
+
+	This will return a list of all the wol rules set.
+
+reset_wol_rule
+
+        This will delete/reset any rules entered using this interface.
+
 =========================
 ETHTOOL
 =========================
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 82c3e5a..90032a9 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -2135,6 +2135,301 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
 	return ret;
 }
 
+/**
+ * ascii_to_be32() - Convert an hex ascii string into a be32 integer.
+ * @dst:        Pointer to destination big endiand 32 bit integer.
+ * @pptr:       Input string. On exit points past the last converted character.
+*
+ * Returns the number of converted characters.
+ **/
+static int ascii_to_be32(__be32 *dst, unsigned char **pptr)
+{
+	uint32_t value;
+	unsigned char *start;
+	int char_count;
+
+	start = *pptr;
+	if (**pptr == '0' && tolower(*(*pptr+1)) == 'x')
+		start += 2;
+	value = simple_strtoul((char *)*pptr, (char **) pptr, 16);
+	*dst = cpu_to_be32(value);
+
+	char_count = (*pptr - start);
+
+	return (char_count > 8) ? -EINVAL : char_count;
+}
+
+static int set_wol_rule_type(unsigned char *ptr, struct wol_config
+		*wol_rule)
+{
+	if (tolower(*ptr) == 'b')
+		wol_rule->pattern |= WOL_RULE_ADDR_TYPE_BCAST;
+	else if (tolower(*ptr) == 'm')
+		wol_rule->pattern |= WOL_RULE_ADDR_TYPE_MCAST;
+	else if (tolower(*ptr) == 'u')
+		wol_rule->pattern |= WOL_RULE_ADDR_TYPE_UCAST;
+	else
+		return -EINVAL;
+	return 0;
+}
+
+static int config_set_wol_rule(unsigned char *ptr, struct wol_config *rules)
+{
+	unsigned short sig_offset;
+	int sig_len, msk_len;
+	int n, ret;
+
+	ptr = strstrip(ptr);
+	if (*ptr == '\0')
+		return -EINVAL;
+
+	ret = set_wol_rule_type(ptr, rules);
+	if (ret)
+		return ret;
+
+	lbs_deb_ioctl("Received WOL pattern %X\n", rules->pattern);
+	ptr++;
+
+	for (n = 0; *ptr != '\0' || n < MAX_WOL_RULES; ptr++, n++) {
+
+		ptr = strstrip(ptr);
+		if (*ptr == '\0')
+			return -EINVAL;
+
+		rules->rule[n].rule_no = n;
+		sig_len = ascii_to_be32(&rules->rule[n].signature, &ptr);
+
+		if (sig_len <= 0)
+			return -EINVAL;
+
+		/* No signature mask, build a default one */
+		if (*ptr == '@') {
+			uint32_t defmask;
+			defmask = (0xffffffff >> 4*(8-sig_len));
+			rules->rule[n].sig_mask = cpu_to_be32(defmask);
+			msk_len = sig_len;
+		} else if (*ptr == '.') {
+			ptr++;
+			msk_len = ascii_to_be32(&rules->rule[n].sig_mask, &ptr);
+			if (msk_len <= 0)
+				return -EINVAL;
+		} else
+			return -EINVAL;
+
+		if (*ptr == '@')
+			ptr++;
+		else
+			return -EINVAL;
+
+		/* assume a prefix of zeroes if mask is bigger than signature */
+		if (sig_len < msk_len)
+			sig_len = msk_len;
+
+		rules->rule[n].sig_length = cpu_to_le16((__u16)
+				(sig_len + 1)/2);
+		sig_offset = (uint16_t) simple_strtoul(ptr, (char **)&ptr, 16);
+
+		if (sig_offset > (IEEE80211_DATA_LEN - 4))
+			return -EINVAL;
+
+		rules->rule[n].sig_offset = cpu_to_le16(sig_offset);
+
+		ptr = strstrip(ptr);
+		if (*ptr == '\0') {
+			rules->rule[n].rule_ops = WOL_RULE_OP_INVALID;
+			n++;
+			break;
+		}
+
+		if ((*ptr == '&') && (*(ptr+1) == '&')) {
+			rules->rule[n].rule_ops = WOL_RULE_OP_AND;
+			ptr += 2;
+		} else
+			return -EINVAL;
+
+	}
+	rules->no_rules_in_cmd = n;
+	return 0;
+}
+
+
+static int lbs_wol_set_config_ioctl(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *u, char *data)
+{
+	int ret;
+	struct wol_config wol_rule;
+	struct wol_config *wol_ptr;
+	struct lbs_private *priv = dev->priv;
+
+	wol_ptr = &wol_rule;
+	memset(&wol_rule, 0, sizeof(struct wol_config));
+
+	lbs_deb_enter(LBS_DEB_IOCTL);
+
+	if (dev == priv->mesh_dev)
+		wol_rule.pattern |= WOL_RULE_NET_TYPE_MESH;
+	else
+		wol_rule.pattern |= WOL_RULE_NET_TYPE_INFRA_OR_IBSS;
+
+	ret = config_set_wol_rule(data, wol_ptr);
+	if (ret)
+		goto error;
+
+	wol_rule.action = CMD_ACT_SET_WOL_RULE;
+	lbs_deb_ioctl("Sending wol_set_rule for pattern %02x with %03d rules\n",
+			wol_rule.pattern, wol_rule.no_rules_in_cmd);
+	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
+	switch (wol_rule.result) {
+	case WOL_RESULT_VALID_CMD:
+		break;
+	case WOL_RESULT_NOSPC_ERR:
+		ret = -ENOSPC;
+		break;
+	case WOL_RESULT_EEXIST_ERR:
+		ret = -EEXIST;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+error:
+	lbs_deb_leave(LBS_DEB_IOCTL);
+	return ret;
+}
+
+static unsigned char *sprint_get_wol_result(unsigned char *ptr,
+				struct wol_config *wol_rule, int ret)
+{
+	struct host_wol_rule *p_rule;
+	int i;
+	unsigned short sig_len;
+
+	if (wol_rule) {
+		switch (wol_rule->pattern & 0x0F) {
+		case WOL_RULE_ADDR_TYPE_BCAST:
+			ptr += sprintf(ptr, "\nBroadcast Rules\n");
+			break;
+		case WOL_RULE_ADDR_TYPE_MCAST:
+			ptr += sprintf(ptr, "\nMulticast Rules\n");
+			break;
+		case WOL_RULE_ADDR_TYPE_UCAST:
+			ptr += sprintf(ptr, "\nUnicast Rules\n");
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (wol_rule->result) {
+		ptr += sprintf(ptr, " No rules found.\n");
+		return ptr;
+	}
+
+	ptr += sprintf(ptr, "Total %d Rules  found for",
+			wol_rule->no_rules_in_cmd);
+	switch (wol_rule->pattern & 0xF0) {
+	case WOL_RULE_NET_TYPE_INFRA_OR_IBSS:
+		ptr += sprintf(ptr, " Infra or Ibss\n");
+		break;
+	case WOL_RULE_NET_TYPE_MESH:
+		ptr += sprintf(ptr, " Mesh\n");
+		break;
+	default:
+		break;
+	}
+
+	ptr += sprintf(ptr, "Signature\tSig Mask\t");
+	ptr += sprintf(ptr, "Offset\tRule Op\n");
+	wol_rule->no_rules_in_cmd = min(wol_rule->no_rules_in_cmd,
+			(uint8_t) MAX_WOL_RULES);
+
+	for (i = 0; i < wol_rule->no_rules_in_cmd; i++) {
+		p_rule = &wol_rule->rule[i];
+		sig_len = le16_to_cpu(p_rule->sig_length);
+		ptr += sprintf(ptr, "0x%08x", be32_to_cpu(p_rule->signature));
+		ptr += sprintf(ptr, "\t");
+		ptr += sprintf(ptr, "0x%08x", be32_to_cpu(p_rule->sig_mask));
+		ptr += sprintf(ptr, "\t0x%03x\t",
+				le16_to_cpu(p_rule->sig_offset));
+
+		if (p_rule->rule_ops == 2)
+			ptr += sprintf(ptr, "OR\n");
+		else if (p_rule->rule_ops == 1)
+			ptr += sprintf(ptr, "AND\n");
+		else
+			ptr += sprintf(ptr, "LAST\n");
+	}
+	return ptr;
+}
+
+static int lbs_wol_get_config_ioctl(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *u, char *data)
+{
+	int ret;
+	struct wol_config wol_rule;
+	struct wol_config *wol_ptr;
+	struct lbs_private *priv = dev->priv;
+	char *ptr = data;
+
+	wol_ptr = &wol_rule;
+	memset(&wol_rule, 0, sizeof(struct wol_config));
+
+	if (dev == priv->mesh_dev)
+		wol_rule.pattern |= WOL_RULE_NET_TYPE_MESH;
+	else
+		wol_rule.pattern |= WOL_RULE_NET_TYPE_INFRA_OR_IBSS;
+
+	wol_rule.action = CMD_ACT_GET_WOL_RULE;
+	wol_rule.pattern |= WOL_RULE_ADDR_TYPE_BCAST;
+	lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
+	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
+	ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
+	if (ret)
+		goto done;
+
+	wol_rule.pattern &= ~WOL_RULE_ADDR_TYPE_BCAST;
+	wol_rule.pattern |= WOL_RULE_ADDR_TYPE_MCAST;
+	lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
+	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
+	ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
+	if (ret)
+		goto done;
+
+	wol_rule.pattern &= ~WOL_RULE_ADDR_TYPE_MCAST;
+	wol_rule.pattern |= WOL_RULE_ADDR_TYPE_UCAST;
+	lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
+	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
+	ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
+
+	u->data.length = strlen(data);
+done:
+	lbs_deb_leave(LBS_DEB_IOCTL);
+	return ret;
+}
+
+static int lbs_wol_reset_config_ioctl(struct net_device *dev,
+				      struct iw_request_info *info,
+				      struct iw_point *u, char *data)
+{
+	int ret;
+	struct wol_config wol_rule;
+	struct lbs_private *priv = dev->priv;
+
+	memset(&wol_rule, 0, sizeof(struct wol_config));
+
+	lbs_deb_enter(LBS_DEB_IOCTL);
+	wol_rule.action = CMD_ACT_RESET_WOL_RULE;
+	lbs_deb_ioctl("Sending wol_reset command\n");
+	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
+	if (!ret && wol_rule.result)
+		ret = -EIO;
+
+	lbs_deb_leave(LBS_DEB_IOCTL);
+	return ret;
+}
+
 /*
  * iwconfig settable callbacks
  */
@@ -2253,14 +2548,42 @@ static const iw_handler mesh_wlan_handler[] = {
 	(iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
 	(iw_handler) NULL,		/* SIOCSIWPMKSA */
 };
+
+#define LBS_SET_WOL_RULE 	SIOCIWFIRSTPRIV
+#define LBS_GET_WOL_RULE 	(SIOCIWFIRSTPRIV+1)
+#define LBS_RESET_WOL_RULE 	(SIOCIWFIRSTPRIV+2)
+
+static const iw_handler lbs_private_handler[] = {
+	(iw_handler) lbs_wol_set_config_ioctl,   /* LBS_SET_WOL_RULE */
+	(iw_handler) lbs_wol_get_config_ioctl,	 /* LBS_GET_WOL_RULE */
+	(iw_handler) lbs_wol_reset_config_ioctl, /* LBS_RESET_WOL_RULE */
+
+};
+
+#define CHAR1024_PARAM		   (IW_PRIV_TYPE_CHAR | 1024)
+static const struct iw_priv_args lbs_private_args[] = {
+	/* { cmd, set_args, get_args, name } */
+	{ LBS_SET_WOL_RULE, CHAR1024_PARAM, 0, "set_wol_rule"},
+	{ LBS_GET_WOL_RULE, 0, CHAR1024_PARAM, "get_wol_rule"},
+	{ LBS_RESET_WOL_RULE, 0, 0, "reset_wol_rule"},
+};
+
 struct iw_handler_def lbs_handler_def = {
 	.num_standard	= ARRAY_SIZE(lbs_handler),
+	.num_private	= ARRAY_SIZE(lbs_private_handler),
 	.standard	= (iw_handler *) lbs_handler,
+	.private	= (iw_handler *) lbs_private_handler,
 	.get_wireless_stats = lbs_get_wireless_stats,
+	.num_private_args = ARRAY_SIZE(lbs_private_args),
+	.private_args	= lbs_private_args,
 };
 
 struct iw_handler_def mesh_handler_def = {
 	.num_standard	= ARRAY_SIZE(mesh_wlan_handler),
+	.num_private	= ARRAY_SIZE(lbs_private_handler),
 	.standard	= (iw_handler *) mesh_wlan_handler,
+	.private	= (iw_handler *) lbs_private_handler,
 	.get_wireless_stats = lbs_get_wireless_stats,
+	.num_private_args = ARRAY_SIZE(lbs_private_args),
+	.private_args	= lbs_private_args,
 };
-- 
1.5.4.3





From anna at cozybit.com  Mon Oct 20 19:46:56 2008
From: anna at cozybit.com (Anna Neal)
Date: Mon, 20 Oct 2008 16:46:56 -0700
Subject: [PATCH] libertas: Fine grained configuration of wake-on-lan.
Message-ID: <48fe28f5.1f588c0a.6115.ffffe7a8@mx.google.com>

Based on a patch from Shailendra Govardhan <shailen at marvell.com>.
This patch allows implementation of more specific wake-on-lan rules than those
of ethtool.

Please note that only firmware 5.110.22.p20 and above supports this feature.

This patch only implements the driver/firmware interface, not the
userspace/driver interface.

Signed-off-by: Anna Neal <anna at cozybit.com>
Signed-off-by: Javier Cardona <javier at cozybit.com>
---
 drivers/net/wireless/libertas/cmd.c     |   19 ++++++++++++++++---
 drivers/net/wireless/libertas/cmd.h     |    3 ++-
 drivers/net/wireless/libertas/defs.h    |   12 ++++++++++++
 drivers/net/wireless/libertas/ethtool.c |    2 +-
 drivers/net/wireless/libertas/host.h    |    8 ++++++++
 drivers/net/wireless/libertas/hostcmd.h |   26 +++++++++++++++++++++++++-
 drivers/net/wireless/libertas/if_usb.c  |    3 ++-
 7 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index aee19fa..6ffdf00 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -160,7 +160,8 @@ out:
 	return ret;
 }
 
-int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
+		struct wol_config *p_wol_config)
 {
 	struct cmd_ds_host_sleep cmd_config;
 	int ret;
@@ -170,10 +171,21 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
 	cmd_config.gpio = priv->wol_gpio;
 	cmd_config.gap = priv->wol_gap;
 
+	if (p_wol_config != NULL)
+		memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
+				sizeof(struct wol_config));
+	else
+		cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
+
 	ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
 	if (!ret) {
-		lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
-		priv->wol_criteria = criteria;
+		if (criteria) {
+			lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
+			priv->wol_criteria = criteria;
+		} else
+			memcpy((uint8_t *) p_wol_config,
+					(uint8_t *)&cmd_config.wol_conf,
+					sizeof(struct wol_config));
 	} else {
 		lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
 	}
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 36be4c9..392e578 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -56,7 +56,8 @@ int lbs_mesh_config_send(struct lbs_private *priv,
 			 uint16_t action, uint16_t type);
 int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
 
-int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
+		struct wol_config *p_wol_config);
 int lbs_suspend(struct lbs_private *priv);
 void lbs_resume(struct lbs_private *priv);
 
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index d21bb4e..e4771f6 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -149,6 +149,18 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 #define EHS_WAKE_ON_MAC_EVENT		0x0004
 #define EHS_WAKE_ON_MULTICAST_DATA	0x0008
 #define EHS_REMOVE_WAKEUP		0xFFFFFFFF
+/* Wake rules for Host_Sleep_CFG command */
+#define WOL_RULE_NET_TYPE_INFRA_OR_IBSS	0x00
+#define WOL_RULE_NET_TYPE_MESH		0x10
+#define WOL_RULE_ADDR_TYPE_BCAST	0x01
+#define WOL_RULE_ADDR_TYPE_MCAST	0x08
+#define WOL_RULE_ADDR_TYPE_UCAST	0x02
+#define WOL_RULE_OP_AND			0x01
+#define WOL_RULE_OP_OR			0x02
+#define WOL_RULE_OP_INVALID		0xFF
+#define WOL_RESULT_VALID_CMD		0
+#define WOL_RESULT_NOSPC_ERR		1
+#define WOL_RESULT_EEXIST_ERR		2
 
 /** Misc constants */
 /* This section defines 802.11 specific contants */
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 688d60d..73b414f 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -180,7 +180,7 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
 	if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
 	if (wol->wolopts & WAKE_PHY)   criteria |= EHS_WAKE_ON_MAC_EVENT;
 
-	return lbs_host_sleep_cfg(priv, criteria);
+	return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
 }
 
 struct ethtool_ops lbs_ethtool_ops = {
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 5004d76..a17b778 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -220,6 +220,14 @@ enum cmd_fwt_access_opts {
 	CMD_ACT_FWT_ACCESS_TIME,
 };
 
+/* Define action or option for CMD_802_11_HOST_SLEEP_CFG */
+enum cmd_wol_cfg_opts {
+	CMD_ACT_ACTION_NONE = 0,
+	CMD_ACT_SET_WOL_RULE,
+	CMD_ACT_GET_WOL_RULE,
+	CMD_ACT_RESET_WOL_RULE,
+};
+
 /* Define action or option for CMD_MESH_ACCESS */
 enum cmd_mesh_access_opts {
 	CMD_ACT_MESH_GET_TTL = 1,
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index d9f9a12..e173b1b 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -580,13 +580,37 @@ struct MrvlIEtype_keyParamSet {
 	u8 key[32];
 };
 
+#define MAX_WOL_RULES 		16
+
+struct host_wol_rule {
+	uint8_t rule_no;
+	uint8_t rule_ops;
+	__le16 sig_offset;
+	__le16 sig_length;
+	__le16 reserve;
+	__be32 sig_mask;
+	__be32 signature;
+};
+
+struct wol_config {
+	uint8_t action;
+	uint8_t pattern;
+	uint8_t no_rules_in_cmd;
+	uint8_t result;
+	struct host_wol_rule rule[MAX_WOL_RULES];
+};
+
+
 struct cmd_ds_host_sleep {
 	struct cmd_header hdr;
 	__le32 criteria;
 	uint8_t gpio;
-	uint8_t gap;
+	uint16_t gap;
+	struct wol_config wol_conf;
 } __attribute__ ((packed));
 
+
+
 struct cmd_ds_802_11_key_material {
 	struct cmd_header hdr;
 
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index cafbccb..fcd3fe6 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -178,7 +178,8 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
 
 	priv->wol_gpio = 2; /* Wake via GPIO2... */
 	priv->wol_gap = 20; /* ... after 20ms    */
-	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
+	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA,
+			(struct wol_config *) NULL);
 
 	wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
 	wake_method.action = cpu_to_le16(CMD_ACT_GET);
-- 
1.5.4.3





From dcbw at redhat.com  Tue Oct 21 16:13:47 2008
From: dcbw at redhat.com (Dan Williams)
Date: Tue, 21 Oct 2008 16:13:47 -0400
Subject: [RFC] libertas: iwpriv commands to configure fine grained
	wake-on-(w)lan
In-Reply-To: <48fe2917.131e640a.7efb.7d0b@mx.google.com>
References: <48fe2917.131e640a.7efb.7d0b@mx.google.com>
Message-ID: <1224620028.15561.10.camel@localhost.localdomain>

On Mon, 2008-10-20 at 16:49 -0700, Anna Neal wrote:
> View README for new API.
> 
> This patch implements the userspace interface for fine-grained configuration of
> wake-on-(w)lan.  We are aware that iwpriv's are discouraged, but this is a
> vendor-specific feature that's currently being used in the OLPC project.
> 
> We are aware that all iwprivs were removed from this driver.  These used the old
> API for iwprivs.  We've implemented this iwpriv as a private handler which relies
> on wireless extensions to do bounds checking and copying to/from user memory.
> Specific suggestions on how to make this more palatable for upstream inclusion
> are welcome.  If iwprivs are completely unacceptable then this can serve as a
> public reference for interfacing with these features.

IMHO we should be adding the functionality where's it's needed, which is
that ethtool, which doesn't have a verbose enough syntax for it's WOL
support.  If ethtool's existing WOL got fixed up to support these
use-cases, then we wouldn't need iwpriv commands, we wouldn't have
duplicate functionality running around, and everyone gets a pony.  Lets
kick off that discussion...

Jeff: could something like this syntax be added to ethtool, or maybe
discreet commands instead of one?  Thoughts?

Dan


> Signed-off-by: Anna Neal <anna at cozybit.com>
> Signed-off-by: Javier Cardona <javier at cozybit.com>
> ---
>  drivers/net/wireless/libertas/README |   71 ++++++++
>  drivers/net/wireless/libertas/wext.c |  323 ++++++++++++++++++++++++++++++++++
>  2 files changed, 394 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
> index d860fc3..6eb30a3 100644
> --- a/drivers/net/wireless/libertas/README
> +++ b/drivers/net/wireless/libertas/README
> @@ -28,6 +28,77 @@ DRIVER LOADING
>  
>  		insmod usb8388.ko [fw_name=usb8388.bin]
>  
> +=====================
> +IWPRIV COMMAND
> +=====================
> +
> +Wake On Lan Commands:
> +
> +	The Wake On Lan (wol) commands are used to configure wol rules outside
> +	of the constraints of ethtool. the following commands are supported:
> +
> +
> +	iwpriv ethX set_wol_rule
> +	iwpriv ethX get_wol_rule
> +	iwpriv ethX reset_wol_rule
> +
> +
> +set_wol_rule
> +
> +	Usage:
> +
> +	    $iwpriv msh0 set_wol_rule "<b|m|u> 0x<signature>{.<mask>}@<offset>"
> +
> +
> +	1. The first digit is the traffic type:
> +		b - broadcast
> +		m - multicast
> +		u - unicast
> +
> +	2. The pattern signature used for comparison to the incoming frame.
> +	   This can be from 1-4 bytes and must be in the standard hex format
> +	   with a leading '0x'.
> +
> +	3. An optional '.' may be added to specify a mask you wish to use. By
> +	   default it will be 0xf for the length of your signature.
> +
> +	4. An offset after the '@' is mandatory this will specify the offset
> +	   into the payload of an 802.3 frame at which the signature will be
> +	   compared.
> +
> +	5. In addition, you may 'and' multiple rules separated by '&&' in the
> +	   same call.
> +
> +	Note:
> +		Every iwpriv, as shown above, will add new wol rules and 'or'
> +		them to any previous rules entered.
> +		At most 16 rules may be applied.
> +
> +	Examples:
> +
> +	1. Wake from an arp request received over the mesh at 192.168.0.1.
> +
> +		iwpriv msh0 set_wol_rule "b 0x0806 at 06 && 0xC0A80001 at 16"
> +
> +	2. Set to wake from any arp request or any multicast traffic from
> +	   192.168.0.1.
> +
> +		iwpriv eth0 set_wol_rule "b 0x0806 at 06"
> +		iwpriv eth0 set_wol_rule "m 0xC0A80001 at 16"
> +
> +	3. Set to wake from an arp or IPv4 broadcast (ethertypes 0x0806 and
> +	   0x0806)
> +
> +		iwpriv eth0 set_wol_rule "b 0x0800.fff9 at 06"
> +
> +get_wol_rule
> +
> +	This will return a list of all the wol rules set.
> +
> +reset_wol_rule
> +
> +        This will delete/reset any rules entered using this interface.
> +
>  =========================
>  ETHTOOL
>  =========================
> diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
> index 82c3e5a..90032a9 100644
> --- a/drivers/net/wireless/libertas/wext.c
> +++ b/drivers/net/wireless/libertas/wext.c
> @@ -2135,6 +2135,301 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
>  	return ret;
>  }
>  
> +/**
> + * ascii_to_be32() - Convert an hex ascii string into a be32 integer.
> + * @dst:        Pointer to destination big endiand 32 bit integer.
> + * @pptr:       Input string. On exit points past the last converted character.
> +*
> + * Returns the number of converted characters.
> + **/
> +static int ascii_to_be32(__be32 *dst, unsigned char **pptr)
> +{
> +	uint32_t value;
> +	unsigned char *start;
> +	int char_count;
> +
> +	start = *pptr;
> +	if (**pptr == '0' && tolower(*(*pptr+1)) == 'x')
> +		start += 2;
> +	value = simple_strtoul((char *)*pptr, (char **) pptr, 16);
> +	*dst = cpu_to_be32(value);
> +
> +	char_count = (*pptr - start);
> +
> +	return (char_count > 8) ? -EINVAL : char_count;
> +}
> +
> +static int set_wol_rule_type(unsigned char *ptr, struct wol_config
> +		*wol_rule)
> +{
> +	if (tolower(*ptr) == 'b')
> +		wol_rule->pattern |= WOL_RULE_ADDR_TYPE_BCAST;
> +	else if (tolower(*ptr) == 'm')
> +		wol_rule->pattern |= WOL_RULE_ADDR_TYPE_MCAST;
> +	else if (tolower(*ptr) == 'u')
> +		wol_rule->pattern |= WOL_RULE_ADDR_TYPE_UCAST;
> +	else
> +		return -EINVAL;
> +	return 0;
> +}
> +
> +static int config_set_wol_rule(unsigned char *ptr, struct wol_config *rules)
> +{
> +	unsigned short sig_offset;
> +	int sig_len, msk_len;
> +	int n, ret;
> +
> +	ptr = strstrip(ptr);
> +	if (*ptr == '\0')
> +		return -EINVAL;
> +
> +	ret = set_wol_rule_type(ptr, rules);
> +	if (ret)
> +		return ret;
> +
> +	lbs_deb_ioctl("Received WOL pattern %X\n", rules->pattern);
> +	ptr++;
> +
> +	for (n = 0; *ptr != '\0' || n < MAX_WOL_RULES; ptr++, n++) {
> +
> +		ptr = strstrip(ptr);
> +		if (*ptr == '\0')
> +			return -EINVAL;
> +
> +		rules->rule[n].rule_no = n;
> +		sig_len = ascii_to_be32(&rules->rule[n].signature, &ptr);
> +
> +		if (sig_len <= 0)
> +			return -EINVAL;
> +
> +		/* No signature mask, build a default one */
> +		if (*ptr == '@') {
> +			uint32_t defmask;
> +			defmask = (0xffffffff >> 4*(8-sig_len));
> +			rules->rule[n].sig_mask = cpu_to_be32(defmask);
> +			msk_len = sig_len;
> +		} else if (*ptr == '.') {
> +			ptr++;
> +			msk_len = ascii_to_be32(&rules->rule[n].sig_mask, &ptr);
> +			if (msk_len <= 0)
> +				return -EINVAL;
> +		} else
> +			return -EINVAL;
> +
> +		if (*ptr == '@')
> +			ptr++;
> +		else
> +			return -EINVAL;
> +
> +		/* assume a prefix of zeroes if mask is bigger than signature */
> +		if (sig_len < msk_len)
> +			sig_len = msk_len;
> +
> +		rules->rule[n].sig_length = cpu_to_le16((__u16)
> +				(sig_len + 1)/2);
> +		sig_offset = (uint16_t) simple_strtoul(ptr, (char **)&ptr, 16);
> +
> +		if (sig_offset > (IEEE80211_DATA_LEN - 4))
> +			return -EINVAL;
> +
> +		rules->rule[n].sig_offset = cpu_to_le16(sig_offset);
> +
> +		ptr = strstrip(ptr);
> +		if (*ptr == '\0') {
> +			rules->rule[n].rule_ops = WOL_RULE_OP_INVALID;
> +			n++;
> +			break;
> +		}
> +
> +		if ((*ptr == '&') && (*(ptr+1) == '&')) {
> +			rules->rule[n].rule_ops = WOL_RULE_OP_AND;
> +			ptr += 2;
> +		} else
> +			return -EINVAL;
> +
> +	}
> +	rules->no_rules_in_cmd = n;
> +	return 0;
> +}
> +
> +
> +static int lbs_wol_set_config_ioctl(struct net_device *dev,
> +				    struct iw_request_info *info,
> +				    union iwreq_data *u, char *data)
> +{
> +	int ret;
> +	struct wol_config wol_rule;
> +	struct wol_config *wol_ptr;
> +	struct lbs_private *priv = dev->priv;
> +
> +	wol_ptr = &wol_rule;
> +	memset(&wol_rule, 0, sizeof(struct wol_config));
> +
> +	lbs_deb_enter(LBS_DEB_IOCTL);
> +
> +	if (dev == priv->mesh_dev)
> +		wol_rule.pattern |= WOL_RULE_NET_TYPE_MESH;
> +	else
> +		wol_rule.pattern |= WOL_RULE_NET_TYPE_INFRA_OR_IBSS;
> +
> +	ret = config_set_wol_rule(data, wol_ptr);
> +	if (ret)
> +		goto error;
> +
> +	wol_rule.action = CMD_ACT_SET_WOL_RULE;
> +	lbs_deb_ioctl("Sending wol_set_rule for pattern %02x with %03d rules\n",
> +			wol_rule.pattern, wol_rule.no_rules_in_cmd);
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	switch (wol_rule.result) {
> +	case WOL_RESULT_VALID_CMD:
> +		break;
> +	case WOL_RESULT_NOSPC_ERR:
> +		ret = -ENOSPC;
> +		break;
> +	case WOL_RESULT_EEXIST_ERR:
> +		ret = -EEXIST;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +error:
> +	lbs_deb_leave(LBS_DEB_IOCTL);
> +	return ret;
> +}
> +
> +static unsigned char *sprint_get_wol_result(unsigned char *ptr,
> +				struct wol_config *wol_rule, int ret)
> +{
> +	struct host_wol_rule *p_rule;
> +	int i;
> +	unsigned short sig_len;
> +
> +	if (wol_rule) {
> +		switch (wol_rule->pattern & 0x0F) {
> +		case WOL_RULE_ADDR_TYPE_BCAST:
> +			ptr += sprintf(ptr, "\nBroadcast Rules\n");
> +			break;
> +		case WOL_RULE_ADDR_TYPE_MCAST:
> +			ptr += sprintf(ptr, "\nMulticast Rules\n");
> +			break;
> +		case WOL_RULE_ADDR_TYPE_UCAST:
> +			ptr += sprintf(ptr, "\nUnicast Rules\n");
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	if (wol_rule->result) {
> +		ptr += sprintf(ptr, " No rules found.\n");
> +		return ptr;
> +	}
> +
> +	ptr += sprintf(ptr, "Total %d Rules  found for",
> +			wol_rule->no_rules_in_cmd);
> +	switch (wol_rule->pattern & 0xF0) {
> +	case WOL_RULE_NET_TYPE_INFRA_OR_IBSS:
> +		ptr += sprintf(ptr, " Infra or Ibss\n");
> +		break;
> +	case WOL_RULE_NET_TYPE_MESH:
> +		ptr += sprintf(ptr, " Mesh\n");
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	ptr += sprintf(ptr, "Signature\tSig Mask\t");
> +	ptr += sprintf(ptr, "Offset\tRule Op\n");
> +	wol_rule->no_rules_in_cmd = min(wol_rule->no_rules_in_cmd,
> +			(uint8_t) MAX_WOL_RULES);
> +
> +	for (i = 0; i < wol_rule->no_rules_in_cmd; i++) {
> +		p_rule = &wol_rule->rule[i];
> +		sig_len = le16_to_cpu(p_rule->sig_length);
> +		ptr += sprintf(ptr, "0x%08x", be32_to_cpu(p_rule->signature));
> +		ptr += sprintf(ptr, "\t");
> +		ptr += sprintf(ptr, "0x%08x", be32_to_cpu(p_rule->sig_mask));
> +		ptr += sprintf(ptr, "\t0x%03x\t",
> +				le16_to_cpu(p_rule->sig_offset));
> +
> +		if (p_rule->rule_ops == 2)
> +			ptr += sprintf(ptr, "OR\n");
> +		else if (p_rule->rule_ops == 1)
> +			ptr += sprintf(ptr, "AND\n");
> +		else
> +			ptr += sprintf(ptr, "LAST\n");
> +	}
> +	return ptr;
> +}
> +
> +static int lbs_wol_get_config_ioctl(struct net_device *dev,
> +				    struct iw_request_info *info,
> +				    union iwreq_data *u, char *data)
> +{
> +	int ret;
> +	struct wol_config wol_rule;
> +	struct wol_config *wol_ptr;
> +	struct lbs_private *priv = dev->priv;
> +	char *ptr = data;
> +
> +	wol_ptr = &wol_rule;
> +	memset(&wol_rule, 0, sizeof(struct wol_config));
> +
> +	if (dev == priv->mesh_dev)
> +		wol_rule.pattern |= WOL_RULE_NET_TYPE_MESH;
> +	else
> +		wol_rule.pattern |= WOL_RULE_NET_TYPE_INFRA_OR_IBSS;
> +
> +	wol_rule.action = CMD_ACT_GET_WOL_RULE;
> +	wol_rule.pattern |= WOL_RULE_ADDR_TYPE_BCAST;
> +	lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
> +	if (ret)
> +		goto done;
> +
> +	wol_rule.pattern &= ~WOL_RULE_ADDR_TYPE_BCAST;
> +	wol_rule.pattern |= WOL_RULE_ADDR_TYPE_MCAST;
> +	lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
> +	if (ret)
> +		goto done;
> +
> +	wol_rule.pattern &= ~WOL_RULE_ADDR_TYPE_MCAST;
> +	wol_rule.pattern |= WOL_RULE_ADDR_TYPE_UCAST;
> +	lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
> +
> +	u->data.length = strlen(data);
> +done:
> +	lbs_deb_leave(LBS_DEB_IOCTL);
> +	return ret;
> +}
> +
> +static int lbs_wol_reset_config_ioctl(struct net_device *dev,
> +				      struct iw_request_info *info,
> +				      struct iw_point *u, char *data)
> +{
> +	int ret;
> +	struct wol_config wol_rule;
> +	struct lbs_private *priv = dev->priv;
> +
> +	memset(&wol_rule, 0, sizeof(struct wol_config));
> +
> +	lbs_deb_enter(LBS_DEB_IOCTL);
> +	wol_rule.action = CMD_ACT_RESET_WOL_RULE;
> +	lbs_deb_ioctl("Sending wol_reset command\n");
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	if (!ret && wol_rule.result)
> +		ret = -EIO;
> +
> +	lbs_deb_leave(LBS_DEB_IOCTL);
> +	return ret;
> +}
> +
>  /*
>   * iwconfig settable callbacks
>   */
> @@ -2253,14 +2548,42 @@ static const iw_handler mesh_wlan_handler[] = {
>  	(iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
>  	(iw_handler) NULL,		/* SIOCSIWPMKSA */
>  };
> +
> +#define LBS_SET_WOL_RULE 	SIOCIWFIRSTPRIV
> +#define LBS_GET_WOL_RULE 	(SIOCIWFIRSTPRIV+1)
> +#define LBS_RESET_WOL_RULE 	(SIOCIWFIRSTPRIV+2)
> +
> +static const iw_handler lbs_private_handler[] = {
> +	(iw_handler) lbs_wol_set_config_ioctl,   /* LBS_SET_WOL_RULE */
> +	(iw_handler) lbs_wol_get_config_ioctl,	 /* LBS_GET_WOL_RULE */
> +	(iw_handler) lbs_wol_reset_config_ioctl, /* LBS_RESET_WOL_RULE */
> +
> +};
> +
> +#define CHAR1024_PARAM		   (IW_PRIV_TYPE_CHAR | 1024)
> +static const struct iw_priv_args lbs_private_args[] = {
> +	/* { cmd, set_args, get_args, name } */
> +	{ LBS_SET_WOL_RULE, CHAR1024_PARAM, 0, "set_wol_rule"},
> +	{ LBS_GET_WOL_RULE, 0, CHAR1024_PARAM, "get_wol_rule"},
> +	{ LBS_RESET_WOL_RULE, 0, 0, "reset_wol_rule"},
> +};
> +
>  struct iw_handler_def lbs_handler_def = {
>  	.num_standard	= ARRAY_SIZE(lbs_handler),
> +	.num_private	= ARRAY_SIZE(lbs_private_handler),
>  	.standard	= (iw_handler *) lbs_handler,
> +	.private	= (iw_handler *) lbs_private_handler,
>  	.get_wireless_stats = lbs_get_wireless_stats,
> +	.num_private_args = ARRAY_SIZE(lbs_private_args),
> +	.private_args	= lbs_private_args,
>  };
>  
>  struct iw_handler_def mesh_handler_def = {
>  	.num_standard	= ARRAY_SIZE(mesh_wlan_handler),
> +	.num_private	= ARRAY_SIZE(lbs_private_handler),
>  	.standard	= (iw_handler *) mesh_wlan_handler,
> +	.private	= (iw_handler *) lbs_private_handler,
>  	.get_wireless_stats = lbs_get_wireless_stats,
> +	.num_private_args = ARRAY_SIZE(lbs_private_args),
> +	.private_args	= lbs_private_args,
>  };



From hs4233 at mail.mn-solutions.de  Wed Oct 22 02:26:18 2008
From: hs4233 at mail.mn-solutions.de (Holger Schurig)
Date: Wed, 22 Oct 2008 08:26:18 +0200
Subject: [PATCH] Fix cs firmware loading
In-Reply-To: <200810170938.32684.hs4233@mail.mn-solutions.de>
References: <48F50139.9050608@bluewatersys.com>
	<48F79B86.4080109@bluewatersys.com>
	<200810170938.32684.hs4233@mail.mn-solutions.de>
Message-ID: <200810220826.18891.hs4233@mail.mn-solutions.de>

Ryan, did you try my patch?  Any results from your side?


From dcbw at redhat.com  Fri Oct 24 17:04:10 2008
From: dcbw at redhat.com (Dan Williams)
Date: Fri, 24 Oct 2008 17:04:10 -0400
Subject: [RFC] libertas: iwpriv commands to configure fine grained
	wake-on-(w)lan
In-Reply-To: <48fe2917.131e640a.7efb.7d0b@mx.google.com>
References: <48fe2917.131e640a.7efb.7d0b@mx.google.com>
Message-ID: <1224882250.31336.2.camel@localhost.localdomain>

On Mon, 2008-10-20 at 16:49 -0700, Anna Neal wrote:
> View README for new API.
> 
> This patch implements the userspace interface for fine-grained configuration of
> wake-on-(w)lan.  We are aware that iwpriv's are discouraged, but this is a
> vendor-specific feature that's currently being used in the OLPC project.
> 
> We are aware that all iwprivs were removed from this driver.  These used the old
> API for iwprivs.  We've implemented this iwpriv as a private handler which relies
> on wireless extensions to do bounds checking and copying to/from user memory.
> Specific suggestions on how to make this more palatable for upstream inclusion
> are welcome.  If iwprivs are completely unacceptable then this can serve as a
> public reference for interfacing with these features.

One thought I just had.  For multicast, why can't libertas use
dev->mc_list as the list of multicast addresses you'd want to WOL on?
Why would you want to have a separate list of WOL multicast addresses,
which may or may not intersect with dev->mc_list?

Dan

> Signed-off-by: Anna Neal <anna at cozybit.com>
> Signed-off-by: Javier Cardona <javier at cozybit.com>
> ---
>  drivers/net/wireless/libertas/README |   71 ++++++++
>  drivers/net/wireless/libertas/wext.c |  323 ++++++++++++++++++++++++++++++++++
>  2 files changed, 394 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
> index d860fc3..6eb30a3 100644
> --- a/drivers/net/wireless/libertas/README
> +++ b/drivers/net/wireless/libertas/README
> @@ -28,6 +28,77 @@ DRIVER LOADING
>  
>  		insmod usb8388.ko [fw_name=usb8388.bin]
>  
> +=====================
> +IWPRIV COMMAND
> +=====================
> +
> +Wake On Lan Commands:
> +
> +	The Wake On Lan (wol) commands are used to configure wol rules outside
> +	of the constraints of ethtool. the following commands are supported:
> +
> +
> +	iwpriv ethX set_wol_rule
> +	iwpriv ethX get_wol_rule
> +	iwpriv ethX reset_wol_rule
> +
> +
> +set_wol_rule
> +
> +	Usage:
> +
> +	    $iwpriv msh0 set_wol_rule "<b|m|u> 0x<signature>{.<mask>}@<offset>"
> +
> +
> +	1. The first digit is the traffic type:
> +		b - broadcast
> +		m - multicast
> +		u - unicast
> +
> +	2. The pattern signature used for comparison to the incoming frame.
> +	   This can be from 1-4 bytes and must be in the standard hex format
> +	   with a leading '0x'.
> +
> +	3. An optional '.' may be added to specify a mask you wish to use. By
> +	   default it will be 0xf for the length of your signature.
> +
> +	4. An offset after the '@' is mandatory this will specify the offset
> +	   into the payload of an 802.3 frame at which the signature will be
> +	   compared.
> +
> +	5. In addition, you may 'and' multiple rules separated by '&&' in the
> +	   same call.
> +
> +	Note:
> +		Every iwpriv, as shown above, will add new wol rules and 'or'
> +		them to any previous rules entered.
> +		At most 16 rules may be applied.
> +
> +	Examples:
> +
> +	1. Wake from an arp request received over the mesh at 192.168.0.1.
> +
> +		iwpriv msh0 set_wol_rule "b 0x0806 at 06 && 0xC0A80001 at 16"
> +
> +	2. Set to wake from any arp request or any multicast traffic from
> +	   192.168.0.1.
> +
> +		iwpriv eth0 set_wol_rule "b 0x0806 at 06"
> +		iwpriv eth0 set_wol_rule "m 0xC0A80001 at 16"
> +
> +	3. Set to wake from an arp or IPv4 broadcast (ethertypes 0x0806 and
> +	   0x0806)
> +
> +		iwpriv eth0 set_wol_rule "b 0x0800.fff9 at 06"
> +
> +get_wol_rule
> +
> +	This will return a list of all the wol rules set.
> +
> +reset_wol_rule
> +
> +        This will delete/reset any rules entered using this interface.
> +
>  =========================
>  ETHTOOL
>  =========================
> diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
> index 82c3e5a..90032a9 100644
> --- a/drivers/net/wireless/libertas/wext.c
> +++ b/drivers/net/wireless/libertas/wext.c
> @@ -2135,6 +2135,301 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
>  	return ret;
>  }
>  
> +/**
> + * ascii_to_be32() - Convert an hex ascii string into a be32 integer.
> + * @dst:        Pointer to destination big endiand 32 bit integer.
> + * @pptr:       Input string. On exit points past the last converted character.
> +*
> + * Returns the number of converted characters.
> + **/
> +static int ascii_to_be32(__be32 *dst, unsigned char **pptr)
> +{
> +	uint32_t value;
> +	unsigned char *start;
> +	int char_count;
> +
> +	start = *pptr;
> +	if (**pptr == '0' && tolower(*(*pptr+1)) == 'x')
> +		start += 2;
> +	value = simple_strtoul((char *)*pptr, (char **) pptr, 16);
> +	*dst = cpu_to_be32(value);
> +
> +	char_count = (*pptr - start);
> +
> +	return (char_count > 8) ? -EINVAL : char_count;
> +}
> +
> +static int set_wol_rule_type(unsigned char *ptr, struct wol_config
> +		*wol_rule)
> +{
> +	if (tolower(*ptr) == 'b')
> +		wol_rule->pattern |= WOL_RULE_ADDR_TYPE_BCAST;
> +	else if (tolower(*ptr) == 'm')
> +		wol_rule->pattern |= WOL_RULE_ADDR_TYPE_MCAST;
> +	else if (tolower(*ptr) == 'u')
> +		wol_rule->pattern |= WOL_RULE_ADDR_TYPE_UCAST;
> +	else
> +		return -EINVAL;
> +	return 0;
> +}
> +
> +static int config_set_wol_rule(unsigned char *ptr, struct wol_config *rules)
> +{
> +	unsigned short sig_offset;
> +	int sig_len, msk_len;
> +	int n, ret;
> +
> +	ptr = strstrip(ptr);
> +	if (*ptr == '\0')
> +		return -EINVAL;
> +
> +	ret = set_wol_rule_type(ptr, rules);
> +	if (ret)
> +		return ret;
> +
> +	lbs_deb_ioctl("Received WOL pattern %X\n", rules->pattern);
> +	ptr++;
> +
> +	for (n = 0; *ptr != '\0' || n < MAX_WOL_RULES; ptr++, n++) {
> +
> +		ptr = strstrip(ptr);
> +		if (*ptr == '\0')
> +			return -EINVAL;
> +
> +		rules->rule[n].rule_no = n;
> +		sig_len = ascii_to_be32(&rules->rule[n].signature, &ptr);
> +
> +		if (sig_len <= 0)
> +			return -EINVAL;
> +
> +		/* No signature mask, build a default one */
> +		if (*ptr == '@') {
> +			uint32_t defmask;
> +			defmask = (0xffffffff >> 4*(8-sig_len));
> +			rules->rule[n].sig_mask = cpu_to_be32(defmask);
> +			msk_len = sig_len;
> +		} else if (*ptr == '.') {
> +			ptr++;
> +			msk_len = ascii_to_be32(&rules->rule[n].sig_mask, &ptr);
> +			if (msk_len <= 0)
> +				return -EINVAL;
> +		} else
> +			return -EINVAL;
> +
> +		if (*ptr == '@')
> +			ptr++;
> +		else
> +			return -EINVAL;
> +
> +		/* assume a prefix of zeroes if mask is bigger than signature */
> +		if (sig_len < msk_len)
> +			sig_len = msk_len;
> +
> +		rules->rule[n].sig_length = cpu_to_le16((__u16)
> +				(sig_len + 1)/2);
> +		sig_offset = (uint16_t) simple_strtoul(ptr, (char **)&ptr, 16);
> +
> +		if (sig_offset > (IEEE80211_DATA_LEN - 4))
> +			return -EINVAL;
> +
> +		rules->rule[n].sig_offset = cpu_to_le16(sig_offset);
> +
> +		ptr = strstrip(ptr);
> +		if (*ptr == '\0') {
> +			rules->rule[n].rule_ops = WOL_RULE_OP_INVALID;
> +			n++;
> +			break;
> +		}
> +
> +		if ((*ptr == '&') && (*(ptr+1) == '&')) {
> +			rules->rule[n].rule_ops = WOL_RULE_OP_AND;
> +			ptr += 2;
> +		} else
> +			return -EINVAL;
> +
> +	}
> +	rules->no_rules_in_cmd = n;
> +	return 0;
> +}
> +
> +
> +static int lbs_wol_set_config_ioctl(struct net_device *dev,
> +				    struct iw_request_info *info,
> +				    union iwreq_data *u, char *data)
> +{
> +	int ret;
> +	struct wol_config wol_rule;
> +	struct wol_config *wol_ptr;
> +	struct lbs_private *priv = dev->priv;
> +
> +	wol_ptr = &wol_rule;
> +	memset(&wol_rule, 0, sizeof(struct wol_config));
> +
> +	lbs_deb_enter(LBS_DEB_IOCTL);
> +
> +	if (dev == priv->mesh_dev)
> +		wol_rule.pattern |= WOL_RULE_NET_TYPE_MESH;
> +	else
> +		wol_rule.pattern |= WOL_RULE_NET_TYPE_INFRA_OR_IBSS;
> +
> +	ret = config_set_wol_rule(data, wol_ptr);
> +	if (ret)
> +		goto error;
> +
> +	wol_rule.action = CMD_ACT_SET_WOL_RULE;
> +	lbs_deb_ioctl("Sending wol_set_rule for pattern %02x with %03d rules\n",
> +			wol_rule.pattern, wol_rule.no_rules_in_cmd);
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	switch (wol_rule.result) {
> +	case WOL_RESULT_VALID_CMD:
> +		break;
> +	case WOL_RESULT_NOSPC_ERR:
> +		ret = -ENOSPC;
> +		break;
> +	case WOL_RESULT_EEXIST_ERR:
> +		ret = -EEXIST;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +error:
> +	lbs_deb_leave(LBS_DEB_IOCTL);
> +	return ret;
> +}
> +
> +static unsigned char *sprint_get_wol_result(unsigned char *ptr,
> +				struct wol_config *wol_rule, int ret)
> +{
> +	struct host_wol_rule *p_rule;
> +	int i;
> +	unsigned short sig_len;
> +
> +	if (wol_rule) {
> +		switch (wol_rule->pattern & 0x0F) {
> +		case WOL_RULE_ADDR_TYPE_BCAST:
> +			ptr += sprintf(ptr, "\nBroadcast Rules\n");
> +			break;
> +		case WOL_RULE_ADDR_TYPE_MCAST:
> +			ptr += sprintf(ptr, "\nMulticast Rules\n");
> +			break;
> +		case WOL_RULE_ADDR_TYPE_UCAST:
> +			ptr += sprintf(ptr, "\nUnicast Rules\n");
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	if (wol_rule->result) {
> +		ptr += sprintf(ptr, " No rules found.\n");
> +		return ptr;
> +	}
> +
> +	ptr += sprintf(ptr, "Total %d Rules  found for",
> +			wol_rule->no_rules_in_cmd);
> +	switch (wol_rule->pattern & 0xF0) {
> +	case WOL_RULE_NET_TYPE_INFRA_OR_IBSS:
> +		ptr += sprintf(ptr, " Infra or Ibss\n");
> +		break;
> +	case WOL_RULE_NET_TYPE_MESH:
> +		ptr += sprintf(ptr, " Mesh\n");
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	ptr += sprintf(ptr, "Signature\tSig Mask\t");
> +	ptr += sprintf(ptr, "Offset\tRule Op\n");
> +	wol_rule->no_rules_in_cmd = min(wol_rule->no_rules_in_cmd,
> +			(uint8_t) MAX_WOL_RULES);
> +
> +	for (i = 0; i < wol_rule->no_rules_in_cmd; i++) {
> +		p_rule = &wol_rule->rule[i];
> +		sig_len = le16_to_cpu(p_rule->sig_length);
> +		ptr += sprintf(ptr, "0x%08x", be32_to_cpu(p_rule->signature));
> +		ptr += sprintf(ptr, "\t");
> +		ptr += sprintf(ptr, "0x%08x", be32_to_cpu(p_rule->sig_mask));
> +		ptr += sprintf(ptr, "\t0x%03x\t",
> +				le16_to_cpu(p_rule->sig_offset));
> +
> +		if (p_rule->rule_ops == 2)
> +			ptr += sprintf(ptr, "OR\n");
> +		else if (p_rule->rule_ops == 1)
> +			ptr += sprintf(ptr, "AND\n");
> +		else
> +			ptr += sprintf(ptr, "LAST\n");
> +	}
> +	return ptr;
> +}
> +
> +static int lbs_wol_get_config_ioctl(struct net_device *dev,
> +				    struct iw_request_info *info,
> +				    union iwreq_data *u, char *data)
> +{
> +	int ret;
> +	struct wol_config wol_rule;
> +	struct wol_config *wol_ptr;
> +	struct lbs_private *priv = dev->priv;
> +	char *ptr = data;
> +
> +	wol_ptr = &wol_rule;
> +	memset(&wol_rule, 0, sizeof(struct wol_config));
> +
> +	if (dev == priv->mesh_dev)
> +		wol_rule.pattern |= WOL_RULE_NET_TYPE_MESH;
> +	else
> +		wol_rule.pattern |= WOL_RULE_NET_TYPE_INFRA_OR_IBSS;
> +
> +	wol_rule.action = CMD_ACT_GET_WOL_RULE;
> +	wol_rule.pattern |= WOL_RULE_ADDR_TYPE_BCAST;
> +	lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
> +	if (ret)
> +		goto done;
> +
> +	wol_rule.pattern &= ~WOL_RULE_ADDR_TYPE_BCAST;
> +	wol_rule.pattern |= WOL_RULE_ADDR_TYPE_MCAST;
> +	lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
> +	if (ret)
> +		goto done;
> +
> +	wol_rule.pattern &= ~WOL_RULE_ADDR_TYPE_MCAST;
> +	wol_rule.pattern |= WOL_RULE_ADDR_TYPE_UCAST;
> +	lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
> +
> +	u->data.length = strlen(data);
> +done:
> +	lbs_deb_leave(LBS_DEB_IOCTL);
> +	return ret;
> +}
> +
> +static int lbs_wol_reset_config_ioctl(struct net_device *dev,
> +				      struct iw_request_info *info,
> +				      struct iw_point *u, char *data)
> +{
> +	int ret;
> +	struct wol_config wol_rule;
> +	struct lbs_private *priv = dev->priv;
> +
> +	memset(&wol_rule, 0, sizeof(struct wol_config));
> +
> +	lbs_deb_enter(LBS_DEB_IOCTL);
> +	wol_rule.action = CMD_ACT_RESET_WOL_RULE;
> +	lbs_deb_ioctl("Sending wol_reset command\n");
> +	ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
> +	if (!ret && wol_rule.result)
> +		ret = -EIO;
> +
> +	lbs_deb_leave(LBS_DEB_IOCTL);
> +	return ret;
> +}
> +
>  /*
>   * iwconfig settable callbacks
>   */
> @@ -2253,14 +2548,42 @@ static const iw_handler mesh_wlan_handler[] = {
>  	(iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
>  	(iw_handler) NULL,		/* SIOCSIWPMKSA */
>  };
> +
> +#define LBS_SET_WOL_RULE 	SIOCIWFIRSTPRIV
> +#define LBS_GET_WOL_RULE 	(SIOCIWFIRSTPRIV+1)
> +#define LBS_RESET_WOL_RULE 	(SIOCIWFIRSTPRIV+2)
> +
> +static const iw_handler lbs_private_handler[] = {
> +	(iw_handler) lbs_wol_set_config_ioctl,   /* LBS_SET_WOL_RULE */
> +	(iw_handler) lbs_wol_get_config_ioctl,	 /* LBS_GET_WOL_RULE */
> +	(iw_handler) lbs_wol_reset_config_ioctl, /* LBS_RESET_WOL_RULE */
> +
> +};
> +
> +#define CHAR1024_PARAM		   (IW_PRIV_TYPE_CHAR | 1024)
> +static const struct iw_priv_args lbs_private_args[] = {
> +	/* { cmd, set_args, get_args, name } */
> +	{ LBS_SET_WOL_RULE, CHAR1024_PARAM, 0, "set_wol_rule"},
> +	{ LBS_GET_WOL_RULE, 0, CHAR1024_PARAM, "get_wol_rule"},
> +	{ LBS_RESET_WOL_RULE, 0, 0, "reset_wol_rule"},
> +};
> +
>  struct iw_handler_def lbs_handler_def = {
>  	.num_standard	= ARRAY_SIZE(lbs_handler),
> +	.num_private	= ARRAY_SIZE(lbs_private_handler),
>  	.standard	= (iw_handler *) lbs_handler,
> +	.private	= (iw_handler *) lbs_private_handler,
>  	.get_wireless_stats = lbs_get_wireless_stats,
> +	.num_private_args = ARRAY_SIZE(lbs_private_args),
> +	.private_args	= lbs_private_args,
>  };
>  
>  struct iw_handler_def mesh_handler_def = {
>  	.num_standard	= ARRAY_SIZE(mesh_wlan_handler),
> +	.num_private	= ARRAY_SIZE(lbs_private_handler),
>  	.standard	= (iw_handler *) mesh_wlan_handler,
> +	.private	= (iw_handler *) lbs_private_handler,
>  	.get_wireless_stats = lbs_get_wireless_stats,
> +	.num_private_args = ARRAY_SIZE(lbs_private_args),
> +	.private_args	= lbs_private_args,
>  };



From sergio at larces.uece.br  Sun Oct 26 03:16:47 2008
From: sergio at larces.uece.br (Sergio Luis)
Date: Sun, 26 Oct 2008 04:16:47 -0300
Subject: [patch 2/2] libertas: free sk_buff with kfree_skb
Message-ID: <4904195F.1050508@larces.uece.br>

free sk_buff with kfree_skb, instead of kree
 
Signed-off-by: Sergio Luis <sergio at larces.uece.br>
Cc: Dan Williams <dcbw at redhat.com>

drivers/net/wireless/libertas/rx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 5749f22..079e6aa 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -328,7 +328,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
 		lbs_deb_rx("rx err: frame received with bad length\n");
 		priv->stats.rx_length_errors++;
 		ret = -EINVAL;
-		kfree(skb);
+		kfree_skb(skb);
 		goto done;
 	}
 


From davem at davemloft.net  Mon Oct 27 02:09:38 2008
From: davem at davemloft.net (David Miller)
Date: Sun, 26 Oct 2008 23:09:38 -0700 (PDT)
Subject: [patch 2/2] libertas: free sk_buff with kfree_skb
In-Reply-To: <4904195F.1050508@larces.uece.br>
References: <4904195F.1050508@larces.uece.br>
Message-ID: <20081026.230938.205512927.davem@davemloft.net>

From: Sergio Luis <sergio at larces.uece.br>
Date: Sun, 26 Oct 2008 04:16:47 -0300

> free sk_buff with kfree_skb, instead of kree
>  
> Signed-off-by: Sergio Luis <sergio at larces.uece.br>

Also applied, thanks Sergio.


From javier at cozybit.com  Mon Oct 27 15:58:47 2008
From: javier at cozybit.com (Javier Cardona)
Date: Mon, 27 Oct 2008 12:58:47 -0700
Subject: [RFC] libertas: iwpriv commands to configure fine grained
	wake-on-(w)lan
In-Reply-To: <1224882250.31336.2.camel@localhost.localdomain>
References: <48fe2917.131e640a.7efb.7d0b@mx.google.com>
	<1224882250.31336.2.camel@localhost.localdomain>
Message-ID: <445f43ac0810271258i292b06che51db7aef9d121ae@mail.gmail.com>

Dan,

On Fri, Oct 24, 2008 at 2:04 PM, Dan Williams <dcbw at redhat.com> wrote:
> On Mon, 2008-10-20 at 16:49 -0700, Anna Neal wrote:
>> View README for new API.
>>
>> This patch implements the userspace interface for fine-grained configuration of
>> wake-on-(w)lan.  We are aware that iwpriv's are discouraged, but this is a
>> vendor-specific feature that's currently being used in the OLPC project.
>>
>> We are aware that all iwprivs were removed from this driver.  These used the old
>> API for iwprivs.  We've implemented this iwpriv as a private handler which relies
>> on wireless extensions to do bounds checking and copying to/from user memory.
>> Specific suggestions on how to make this more palatable for upstream inclusion
>> are welcome.  If iwprivs are completely unacceptable then this can serve as a
>> public reference for interfacing with these features.
>
> One thought I just had.  For multicast, why can't libertas use
> dev->mc_list as the list of multicast addresses you'd want to WOL on?
> Why would you want to have a separate list of WOL multicast addresses,
> which may or may not intersect with dev->mc_list?

Thanks for the feedback.

The wol rules are patterns that are checked against the frame payload
and not against its (L2) address.
This feature allows users to configure the wireless hardware to wake
up the host in response to specific types of traffic.

For instance, consider the following scenario:  a user is listening to
a multicast RTP stream and has IPv6 enabled.  If the user wants 1) to
wake up any multicast traffic, she would have to issue:

  ethtool -s eth0 wol m		# wake up on any multicast traffic we're
currently listening to

On the other hand, if the user wants 2) to wake up only on IPv6
neighbor solicitation messages but not on the RTP stream, she could
do:

  iwpriv eth0 set_wol_rule "m 0x86dd at 6 && 0x87 at 30"   # wake up on IPv6
NS traffic from any multicast address currently subscribed to

Finally, if the user just wants 3) to decouple networking from power
management entirely, she doesn't need to issue any iwpriv:  she'll
only receive multicast traffic while the host is awake, but will not
wake up on it.

Is your suggestion to always assume that the user wants (1) and have
the driver to silently configure the hardware like that?

Cheers,

Javier


>> Signed-off-by: Anna Neal <anna at cozybit.com>
>> Signed-off-by: Javier Cardona <javier at cozybit.com>
>> ---
>>  drivers/net/wireless/libertas/README |   71 ++++++++
>>  drivers/net/wireless/libertas/wext.c |  323 ++++++++++++++++++++++++++++++++++
>>  2 files changed, 394 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
>> index d860fc3..6eb30a3 100644
>> --- a/drivers/net/wireless/libertas/README
>> +++ b/drivers/net/wireless/libertas/README
>> @@ -28,6 +28,77 @@ DRIVER LOADING
>>
>>               insmod usb8388.ko [fw_name=usb8388.bin]
>>
>> +=====================
>> +IWPRIV COMMAND
>> +=====================
>> +
>> +Wake On Lan Commands:
>> +
>> +     The Wake On Lan (wol) commands are used to configure wol rules outside
>> +     of the constraints of ethtool. the following commands are supported:
>> +
>> +
>> +     iwpriv ethX set_wol_rule
>> +     iwpriv ethX get_wol_rule
>> +     iwpriv ethX reset_wol_rule
>> +
>> +
>> +set_wol_rule
>> +
>> +     Usage:
>> +
>> +         $iwpriv msh0 set_wol_rule "<b|m|u> 0x<signature>{.<mask>}@<offset>"
>> +
>> +
>> +     1. The first digit is the traffic type:
>> +             b - broadcast
>> +             m - multicast
>> +             u - unicast
>> +
>> +     2. The pattern signature used for comparison to the incoming frame.
>> +        This can be from 1-4 bytes and must be in the standard hex format
>> +        with a leading '0x'.
>> +
>> +     3. An optional '.' may be added to specify a mask you wish to use. By
>> +        default it will be 0xf for the length of your signature.
>> +
>> +     4. An offset after the '@' is mandatory this will specify the offset
>> +        into the payload of an 802.3 frame at which the signature will be
>> +        compared.
>> +
>> +     5. In addition, you may 'and' multiple rules separated by '&&' in the
>> +        same call.
>> +
>> +     Note:
>> +             Every iwpriv, as shown above, will add new wol rules and 'or'
>> +             them to any previous rules entered.
>> +             At most 16 rules may be applied.
>> +
>> +     Examples:
>> +
>> +     1. Wake from an arp request received over the mesh at 192.168.0.1.
>> +
>> +             iwpriv msh0 set_wol_rule "b 0x0806 at 06 && 0xC0A80001 at 16"
>> +
>> +     2. Set to wake from any arp request or any multicast traffic from
>> +        192.168.0.1.
>> +
>> +             iwpriv eth0 set_wol_rule "b 0x0806 at 06"
>> +             iwpriv eth0 set_wol_rule "m 0xC0A80001 at 16"
>> +
>> +     3. Set to wake from an arp or IPv4 broadcast (ethertypes 0x0806 and
>> +        0x0806)
>> +
>> +             iwpriv eth0 set_wol_rule "b 0x0800.fff9 at 06"
>> +
>> +get_wol_rule
>> +
>> +     This will return a list of all the wol rules set.
>> +
>> +reset_wol_rule
>> +
>> +        This will delete/reset any rules entered using this interface.
>> +
>>  =========================
>>  ETHTOOL
>>  =========================
>> diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
>> index 82c3e5a..90032a9 100644
>> --- a/drivers/net/wireless/libertas/wext.c
>> +++ b/drivers/net/wireless/libertas/wext.c
>> @@ -2135,6 +2135,301 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
>>       return ret;
>>  }
>>
>> +/**
>> + * ascii_to_be32() - Convert an hex ascii string into a be32 integer.
>> + * @dst:        Pointer to destination big endiand 32 bit integer.
>> + * @pptr:       Input string. On exit points past the last converted character.
>> +*
>> + * Returns the number of converted characters.
>> + **/
>> +static int ascii_to_be32(__be32 *dst, unsigned char **pptr)
>> +{
>> +     uint32_t value;
>> +     unsigned char *start;
>> +     int char_count;
>> +
>> +     start = *pptr;
>> +     if (**pptr == '0' && tolower(*(*pptr+1)) == 'x')
>> +             start += 2;
>> +     value = simple_strtoul((char *)*pptr, (char **) pptr, 16);
>> +     *dst = cpu_to_be32(value);
>> +
>> +     char_count = (*pptr - start);
>> +
>> +     return (char_count > 8) ? -EINVAL : char_count;
>> +}
>> +
>> +static int set_wol_rule_type(unsigned char *ptr, struct wol_config
>> +             *wol_rule)
>> +{
>> +     if (tolower(*ptr) == 'b')
>> +             wol_rule->pattern |= WOL_RULE_ADDR_TYPE_BCAST;
>> +     else if (tolower(*ptr) == 'm')
>> +             wol_rule->pattern |= WOL_RULE_ADDR_TYPE_MCAST;
>> +     else if (tolower(*ptr) == 'u')
>> +             wol_rule->pattern |= WOL_RULE_ADDR_TYPE_UCAST;
>> +     else
>> +             return -EINVAL;
>> +     return 0;
>> +}
>> +
>> +static int config_set_wol_rule(unsigned char *ptr, struct wol_config *rules)
>> +{
>> +     unsigned short sig_offset;
>> +     int sig_len, msk_len;
>> +     int n, ret;
>> +
>> +     ptr = strstrip(ptr);
>> +     if (*ptr == '\0')
>> +             return -EINVAL;
>> +
>> +     ret = set_wol_rule_type(ptr, rules);
>> +     if (ret)
>> +             return ret;
>> +
>> +     lbs_deb_ioctl("Received WOL pattern %X\n", rules->pattern);
>> +     ptr++;
>> +
>> +     for (n = 0; *ptr != '\0' || n < MAX_WOL_RULES; ptr++, n++) {
>> +
>> +             ptr = strstrip(ptr);
>> +             if (*ptr == '\0')
>> +                     return -EINVAL;
>> +
>> +             rules->rule[n].rule_no = n;
>> +             sig_len = ascii_to_be32(&rules->rule[n].signature, &ptr);
>> +
>> +             if (sig_len <= 0)
>> +                     return -EINVAL;
>> +
>> +             /* No signature mask, build a default one */
>> +             if (*ptr == '@') {
>> +                     uint32_t defmask;
>> +                     defmask = (0xffffffff >> 4*(8-sig_len));
>> +                     rules->rule[n].sig_mask = cpu_to_be32(defmask);
>> +                     msk_len = sig_len;
>> +             } else if (*ptr == '.') {
>> +                     ptr++;
>> +                     msk_len = ascii_to_be32(&rules->rule[n].sig_mask, &ptr);
>> +                     if (msk_len <= 0)
>> +                             return -EINVAL;
>> +             } else
>> +                     return -EINVAL;
>> +
>> +             if (*ptr == '@')
>> +                     ptr++;
>> +             else
>> +                     return -EINVAL;
>> +
>> +             /* assume a prefix of zeroes if mask is bigger than signature */
>> +             if (sig_len < msk_len)
>> +                     sig_len = msk_len;
>> +
>> +             rules->rule[n].sig_length = cpu_to_le16((__u16)
>> +                             (sig_len + 1)/2);
>> +             sig_offset = (uint16_t) simple_strtoul(ptr, (char **)&ptr, 16);
>> +
>> +             if (sig_offset > (IEEE80211_DATA_LEN - 4))
>> +                     return -EINVAL;
>> +
>> +             rules->rule[n].sig_offset = cpu_to_le16(sig_offset);
>> +
>> +             ptr = strstrip(ptr);
>> +             if (*ptr == '\0') {
>> +                     rules->rule[n].rule_ops = WOL_RULE_OP_INVALID;
>> +                     n++;
>> +                     break;
>> +             }
>> +
>> +             if ((*ptr == '&') && (*(ptr+1) == '&')) {
>> +                     rules->rule[n].rule_ops = WOL_RULE_OP_AND;
>> +                     ptr += 2;
>> +             } else
>> +                     return -EINVAL;
>> +
>> +     }
>> +     rules->no_rules_in_cmd = n;
>> +     return 0;
>> +}
>> +
>> +
>> +static int lbs_wol_set_config_ioctl(struct net_device *dev,
>> +                                 struct iw_request_info *info,
>> +                                 union iwreq_data *u, char *data)
>> +{
>> +     int ret;
>> +     struct wol_config wol_rule;
>> +     struct wol_config *wol_ptr;
>> +     struct lbs_private *priv = dev->priv;
>> +
>> +     wol_ptr = &wol_rule;
>> +     memset(&wol_rule, 0, sizeof(struct wol_config));
>> +
>> +     lbs_deb_enter(LBS_DEB_IOCTL);
>> +
>> +     if (dev == priv->mesh_dev)
>> +             wol_rule.pattern |= WOL_RULE_NET_TYPE_MESH;
>> +     else
>> +             wol_rule.pattern |= WOL_RULE_NET_TYPE_INFRA_OR_IBSS;
>> +
>> +     ret = config_set_wol_rule(data, wol_ptr);
>> +     if (ret)
>> +             goto error;
>> +
>> +     wol_rule.action = CMD_ACT_SET_WOL_RULE;
>> +     lbs_deb_ioctl("Sending wol_set_rule for pattern %02x with %03d rules\n",
>> +                     wol_rule.pattern, wol_rule.no_rules_in_cmd);
>> +     ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
>> +     switch (wol_rule.result) {
>> +     case WOL_RESULT_VALID_CMD:
>> +             break;
>> +     case WOL_RESULT_NOSPC_ERR:
>> +             ret = -ENOSPC;
>> +             break;
>> +     case WOL_RESULT_EEXIST_ERR:
>> +             ret = -EEXIST;
>> +             break;
>> +     default:
>> +             ret = -EINVAL;
>> +             break;
>> +     }
>> +error:
>> +     lbs_deb_leave(LBS_DEB_IOCTL);
>> +     return ret;
>> +}
>> +
>> +static unsigned char *sprint_get_wol_result(unsigned char *ptr,
>> +                             struct wol_config *wol_rule, int ret)
>> +{
>> +     struct host_wol_rule *p_rule;
>> +     int i;
>> +     unsigned short sig_len;
>> +
>> +     if (wol_rule) {
>> +             switch (wol_rule->pattern & 0x0F) {
>> +             case WOL_RULE_ADDR_TYPE_BCAST:
>> +                     ptr += sprintf(ptr, "\nBroadcast Rules\n");
>> +                     break;
>> +             case WOL_RULE_ADDR_TYPE_MCAST:
>> +                     ptr += sprintf(ptr, "\nMulticast Rules\n");
>> +                     break;
>> +             case WOL_RULE_ADDR_TYPE_UCAST:
>> +                     ptr += sprintf(ptr, "\nUnicast Rules\n");
>> +                     break;
>> +             default:
>> +                     break;
>> +             }
>> +     }
>> +
>> +     if (wol_rule->result) {
>> +             ptr += sprintf(ptr, " No rules found.\n");
>> +             return ptr;
>> +     }
>> +
>> +     ptr += sprintf(ptr, "Total %d Rules  found for",
>> +                     wol_rule->no_rules_in_cmd);
>> +     switch (wol_rule->pattern & 0xF0) {
>> +     case WOL_RULE_NET_TYPE_INFRA_OR_IBSS:
>> +             ptr += sprintf(ptr, " Infra or Ibss\n");
>> +             break;
>> +     case WOL_RULE_NET_TYPE_MESH:
>> +             ptr += sprintf(ptr, " Mesh\n");
>> +             break;
>> +     default:
>> +             break;
>> +     }
>> +
>> +     ptr += sprintf(ptr, "Signature\tSig Mask\t");
>> +     ptr += sprintf(ptr, "Offset\tRule Op\n");
>> +     wol_rule->no_rules_in_cmd = min(wol_rule->no_rules_in_cmd,
>> +                     (uint8_t) MAX_WOL_RULES);
>> +
>> +     for (i = 0; i < wol_rule->no_rules_in_cmd; i++) {
>> +             p_rule = &wol_rule->rule[i];
>> +             sig_len = le16_to_cpu(p_rule->sig_length);
>> +             ptr += sprintf(ptr, "0x%08x", be32_to_cpu(p_rule->signature));
>> +             ptr += sprintf(ptr, "\t");
>> +             ptr += sprintf(ptr, "0x%08x", be32_to_cpu(p_rule->sig_mask));
>> +             ptr += sprintf(ptr, "\t0x%03x\t",
>> +                             le16_to_cpu(p_rule->sig_offset));
>> +
>> +             if (p_rule->rule_ops == 2)
>> +                     ptr += sprintf(ptr, "OR\n");
>> +             else if (p_rule->rule_ops == 1)
>> +                     ptr += sprintf(ptr, "AND\n");
>> +             else
>> +                     ptr += sprintf(ptr, "LAST\n");
>> +     }
>> +     return ptr;
>> +}
>> +
>> +static int lbs_wol_get_config_ioctl(struct net_device *dev,
>> +                                 struct iw_request_info *info,
>> +                                 union iwreq_data *u, char *data)
>> +{
>> +     int ret;
>> +     struct wol_config wol_rule;
>> +     struct wol_config *wol_ptr;
>> +     struct lbs_private *priv = dev->priv;
>> +     char *ptr = data;
>> +
>> +     wol_ptr = &wol_rule;
>> +     memset(&wol_rule, 0, sizeof(struct wol_config));
>> +
>> +     if (dev == priv->mesh_dev)
>> +             wol_rule.pattern |= WOL_RULE_NET_TYPE_MESH;
>> +     else
>> +             wol_rule.pattern |= WOL_RULE_NET_TYPE_INFRA_OR_IBSS;
>> +
>> +     wol_rule.action = CMD_ACT_GET_WOL_RULE;
>> +     wol_rule.pattern |= WOL_RULE_ADDR_TYPE_BCAST;
>> +     lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
>> +     ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
>> +     ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
>> +     if (ret)
>> +             goto done;
>> +
>> +     wol_rule.pattern &= ~WOL_RULE_ADDR_TYPE_BCAST;
>> +     wol_rule.pattern |= WOL_RULE_ADDR_TYPE_MCAST;
>> +     lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
>> +     ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
>> +     ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
>> +     if (ret)
>> +             goto done;
>> +
>> +     wol_rule.pattern &= ~WOL_RULE_ADDR_TYPE_MCAST;
>> +     wol_rule.pattern |= WOL_RULE_ADDR_TYPE_UCAST;
>> +     lbs_deb_ioctl("Sending get_wol_rule, pattern %02x\n", wol_rule.pattern);
>> +     ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
>> +     ptr = sprint_get_wol_result(ptr, wol_ptr, ret);
>> +
>> +     u->data.length = strlen(data);
>> +done:
>> +     lbs_deb_leave(LBS_DEB_IOCTL);
>> +     return ret;
>> +}
>> +
>> +static int lbs_wol_reset_config_ioctl(struct net_device *dev,
>> +                                   struct iw_request_info *info,
>> +                                   struct iw_point *u, char *data)
>> +{
>> +     int ret;
>> +     struct wol_config wol_rule;
>> +     struct lbs_private *priv = dev->priv;
>> +
>> +     memset(&wol_rule, 0, sizeof(struct wol_config));
>> +
>> +     lbs_deb_enter(LBS_DEB_IOCTL);
>> +     wol_rule.action = CMD_ACT_RESET_WOL_RULE;
>> +     lbs_deb_ioctl("Sending wol_reset command\n");
>> +     ret = lbs_host_sleep_cfg(priv, 0, &wol_rule);
>> +     if (!ret && wol_rule.result)
>> +             ret = -EIO;
>> +
>> +     lbs_deb_leave(LBS_DEB_IOCTL);
>> +     return ret;
>> +}
>> +
>>  /*
>>   * iwconfig settable callbacks
>>   */
>> @@ -2253,14 +2548,42 @@ static const iw_handler mesh_wlan_handler[] = {
>>       (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
>>       (iw_handler) NULL,              /* SIOCSIWPMKSA */
>>  };
>> +
>> +#define LBS_SET_WOL_RULE     SIOCIWFIRSTPRIV
>> +#define LBS_GET_WOL_RULE     (SIOCIWFIRSTPRIV+1)
>> +#define LBS_RESET_WOL_RULE   (SIOCIWFIRSTPRIV+2)
>> +
>> +static const iw_handler lbs_private_handler[] = {
>> +     (iw_handler) lbs_wol_set_config_ioctl,   /* LBS_SET_WOL_RULE */
>> +     (iw_handler) lbs_wol_get_config_ioctl,   /* LBS_GET_WOL_RULE */
>> +     (iw_handler) lbs_wol_reset_config_ioctl, /* LBS_RESET_WOL_RULE */
>> +
>> +};
>> +
>> +#define CHAR1024_PARAM                  (IW_PRIV_TYPE_CHAR | 1024)
>> +static const struct iw_priv_args lbs_private_args[] = {
>> +     /* { cmd, set_args, get_args, name } */
>> +     { LBS_SET_WOL_RULE, CHAR1024_PARAM, 0, "set_wol_rule"},
>> +     { LBS_GET_WOL_RULE, 0, CHAR1024_PARAM, "get_wol_rule"},
>> +     { LBS_RESET_WOL_RULE, 0, 0, "reset_wol_rule"},
>> +};
>> +
>>  struct iw_handler_def lbs_handler_def = {
>>       .num_standard   = ARRAY_SIZE(lbs_handler),
>> +     .num_private    = ARRAY_SIZE(lbs_private_handler),
>>       .standard       = (iw_handler *) lbs_handler,
>> +     .private        = (iw_handler *) lbs_private_handler,
>>       .get_wireless_stats = lbs_get_wireless_stats,
>> +     .num_private_args = ARRAY_SIZE(lbs_private_args),
>> +     .private_args   = lbs_private_args,
>>  };
>>
>>  struct iw_handler_def mesh_handler_def = {
>>       .num_standard   = ARRAY_SIZE(mesh_wlan_handler),
>> +     .num_private    = ARRAY_SIZE(lbs_private_handler),
>>       .standard       = (iw_handler *) mesh_wlan_handler,
>> +     .private        = (iw_handler *) lbs_private_handler,
>>       .get_wireless_stats = lbs_get_wireless_stats,
>> +     .num_private_args = ARRAY_SIZE(lbs_private_args),
>> +     .private_args   = lbs_private_args,
>>  };
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Javier Cardona
cozybit Inc.


From phillipmurray at relay.gordi.com  Wed Oct 29 21:29:41 2008
From: phillipmurray at relay.gordi.com (Conley E Katina)
Date: Thu, 30 Oct 2008 06:29:41 +0500
Subject: Lists of MDs and Dentists
Message-ID: <645372j3twx0$x1364vl0$3427f2e0@Delldim5150




There's currently a good deal on lists for the medical and dental profession. Just email me Hugo at rexdata.net for more details and samples.























cancel at rexdata.net to cancel from this letter


From linville at tuxdriver.com  Fri Oct 31 15:35:04 2008
From: linville at tuxdriver.com (John W. Linville)
Date: Fri, 31 Oct 2008 15:35:04 -0400
Subject: [RFC] libertas: iwpriv commands to configure fine grained
	wake-on-(w)lan
In-Reply-To: <1224620028.15561.10.camel@localhost.localdomain>
References: <48fe2917.131e640a.7efb.7d0b@mx.google.com>
	<1224620028.15561.10.camel@localhost.localdomain>
Message-ID: <20081031193504.GF4310@tuxdriver.com>

On Tue, Oct 21, 2008 at 04:13:47PM -0400, Dan Williams wrote:
> On Mon, 2008-10-20 at 16:49 -0700, Anna Neal wrote:
> > View README for new API.
> > 
> > This patch implements the userspace interface for fine-grained configuration of
> > wake-on-(w)lan.  We are aware that iwpriv's are discouraged, but this is a
> > vendor-specific feature that's currently being used in the OLPC project.
> > 
> > We are aware that all iwprivs were removed from this driver.  These used the old
> > API for iwprivs.  We've implemented this iwpriv as a private handler which relies
> > on wireless extensions to do bounds checking and copying to/from user memory.
> > Specific suggestions on how to make this more palatable for upstream inclusion
> > are welcome.  If iwprivs are completely unacceptable then this can serve as a
> > public reference for interfacing with these features.
> 
> IMHO we should be adding the functionality where's it's needed, which is
> that ethtool, which doesn't have a verbose enough syntax for it's WOL
> support.  If ethtool's existing WOL got fixed up to support these
> use-cases, then we wouldn't need iwpriv commands, we wouldn't have
> duplicate functionality running around, and everyone gets a pony.  Lets
> kick off that discussion...
> 
> Jeff: could something like this syntax be added to ethtool, or maybe
> discreet commands instead of one?  Thoughts?

Did anything come out of this discussion?  I'd prefer not to add new
iwpriv stuff...

John
-- 
John W. Linville		Linux should be at the core
linville at tuxdriver.com			of your literate lifestyle.


