2009-06-15 20:00:41

by Andrey Yurovsky

[permalink] [raw]
Subject: [PATCH] libertas: Fix re-enabling IEEE PS with WPA/WPA2

With IEEE PS enabled, the driver will temporarily take the device out of
PS mode to issue commands and then re-enable PS once the commands have
completed. With WPA or WPA2 security, the driver fails to re-enable PS
mode because of a check for key lengths that are always zero.

This patch removes the key lengths check (the local copy of the keys is
not maintained) and fixes IEEE PS mode with WPA or WPA2 security.
Tested on GSPI and SDIO interfaces with V9 firmware.

Signed-off-by: Andrey Yurovsky <[email protected]>
---
drivers/net/wireless/libertas/cmd.c | 29 +++++++----------------------
1 files changed, 7 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 01db705..5825396 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1782,32 +1782,17 @@ int lbs_execute_next_command(struct lbs_private *priv)
lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
le16_to_cpu(cmd->command));
lbs_submit_command(priv, cmdnode);
- } else {
+ } else if ((priv->psmode != LBS802_11POWERMODECAM) &&
+ (priv->psstate == PS_STATE_FULL_POWER) &&
+ ((priv->connect_status == LBS_CONNECTED) ||
+ (priv->mesh_connect_status == LBS_CONNECTED))) {
/*
* check if in power save mode, if yes, put the device back
* to PS mode
*/
- if ((priv->psmode != LBS802_11POWERMODECAM) &&
- (priv->psstate == PS_STATE_FULL_POWER) &&
- ((priv->connect_status == LBS_CONNECTED) ||
- (priv->mesh_connect_status == LBS_CONNECTED))) {
- if (priv->secinfo.WPAenabled ||
- priv->secinfo.WPA2enabled) {
- /* check for valid WPA group keys */
- if (priv->wpa_mcast_key.len ||
- priv->wpa_unicast_key.len) {
- lbs_deb_host(
- "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
- " go back to PS_SLEEP");
- lbs_ps_sleep(priv, 0);
- }
- } else {
- lbs_deb_host(
- "EXEC_NEXT_CMD: cmdpendingq empty, "
- "go back to PS_SLEEP");
- lbs_ps_sleep(priv, 0);
- }
- }
+ lbs_deb_host("EXEC_NEXT_CMD: cmdpendingq empty, "
+ "go back to PS_SLEEP");
+ lbs_ps_sleep(priv, 0);
}

ret = 0;
--
1.5.6.3



2009-06-18 01:29:07

by Andrey Yurovsky

[permalink] [raw]
Subject: [PATCH] libertas: copy WPA keys to priv when associating

Libertas currently maintains a copy of the WPA unicast and group keys
when using WPA or WPA2. This copy is checked when deciding whether or
not to return to sleep in IEEE PS mode but the actual copying back to
priv was omitted, which breaks IEEE PS mode with WPA/WPA2 when one
issues commands that require temporarily keeping the device awake.

This patch introduces the omitted copy-back of the keys so that IEEE PS
functions correctly in WPA/WPA2 mode. Thanks to Dan Williams for
clearing up the issue.

Signed-off-by: Andrey Yurovsky <[email protected]>
---
drivers/net/wireless/libertas/assoc.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index b9b3741..b7c7cb0 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -1368,11 +1368,17 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv,
if (ret)
goto out;

+ memcpy(&priv->wpa_unicast_key, &assoc_req->wpa_mcast_key,
+ sizeof(struct enc_key));
+
if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);

ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
assoc_req->flags = flags;
+
+ memcpy(&priv->wpa_mcast_key, &assoc_req->wpa_mcast_key,
+ sizeof(struct enc_key));
}

out:
--
1.5.6.3


2009-06-16 21:07:18

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH] libertas: Fix re-enabling IEEE PS with WPA/WPA2

On Tue, 2009-06-16 at 13:03 -0700, Andrey Yurovsky wrote:
> On Tue, Jun 16, 2009 at 12:53 PM, Dan Williams<[email protected]> wrote:
> > On Mon, 2009-06-15 at 13:01 -0700, Andrey Yurovsky wrote:
> >> With IEEE PS enabled, the driver will temporarily take the device out of
> >> PS mode to issue commands and then re-enable PS once the commands have
> >> completed. With WPA or WPA2 security, the driver fails to re-enable PS
> >> mode because of a check for key lengths that are always zero.
> >>
> >> This patch removes the key lengths check (the local copy of the keys is
> >> not maintained) and fixes IEEE PS mode with WPA or WPA2 security.
> >> Tested on GSPI and SDIO interfaces with V9 firmware.
> >
> > I have no idea what this code was trying to do originally (I'm pretty
> > sure it's a left-over from the vendor driver), but it seems like maybe
> > it was ensuring that the adapter did *not* return to power-save mode
> > until the supplicant had set the GTK? There's a window where the GTK
> > won't be set, and we probably shouldn't be entering PS mode until that
> > window is closed. Old sd8385 code from a Motorola phone has:
> >
> > if ((Adapter->PSMode != Wlan802_11PowerModeCAM) &&
> > (Adapter->PSState == PS_STATE_FULL_POWER) &&
> > (Adapter->MediaConnectStatus ==
> > WlanMediaStateConnected)) {
> > if(Adapter->SecInfo.WPAEnabled
> > || Adapter->SecInfo.WPA2Enabled
> > ) {
> > if(Adapter->IsGTK_SET == TRUE) {
> > PRINTM(INFO, "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
> > " go back to PS_SLEEP");
> > PSSleep(priv, 0);
> > }
> > } else
> > {
> > PRINTM(INFO, "EXEC_NEXT_CMD: Command PendQ is empty,"
> > " go back to PS_SLEEP");
> > PSSleep(priv, 0);
> > }
> > }
> >
> > Says to me, "if WPA is enabled but the GTK hasn't been set yet, don't go
> > to sleep".
> >
> > Does that sound like a plausible explanation of what the original bits
> > intended to do? Like I said, it was inherited, but there might have
> > been a good reason for it.
>
> That might be the original intention, but assoc_helper_wpa_keys() sets
> both and lbs_cmd_802_11_key_material() then clears out the driver's
> copy, which is then (incorrectly) checked when deciding whether to go
> back to sleep. As I understand it, the execution path for WPA/WPA2
> association shouldn't cause this situation where WPA is enabled but
> the GTK isn't set yet and we're deciding to go back to sleep. Do you
> agree? Should we even be keeping the 'driver copy' of the keys? I
> don't see why we want to do that. Thanks,

It might be possible to remove the priv->... bits; but here's why they
exist.

We keep shadow copies of the WEP & WPA keys in the priv structure to
represent the "current" values there, so that we don't have to hit the
hardware up every time somebody does an iwconfig. That's somewhat bogus
because drivers don't actually guarantee that the current key will be
returned, but it's nice to have.

Second, we need to populate a new assoc_request with the "current" state
of the card when building up a change request. That involves copying
that current state into the new association request, same as all the
other "current" values get stuffed into the request. There are other
ways to do the association request stuff than this, like a list of
"change events", but some commands require more state than just the
particular thing to be changed, thus the assoc_request is trying to be a
picture of the adapter at the time it's created.

If we wanted to just hit the hardware up for the WEP & WPA keys when
doing 'iwconfig' then we could certainly just split up
lbs_cmd_802_11_key_material() into a getter and setter, which should
probably be done anway.

But that doesn't fix the issue of building up the assoc_request. This
*could* all go away if/when we convert to cfg80211's WEXT compat stuff.
At that point we ditch the assoc_request junk (which was only there to
ensure 'iwconfig key xxxxx; iwconfig essid foobar' and the supplicant's
WEXT driver worked correctly) and maybe the private key copies in the
driver.

I think the bug here is actually that the driver isn't copying the keys
from the assoc_req to priv in assoc_helper_wpa_keys(). Thus the only
way the priv->wpa* get set is by getting them explicitly.

Dan

> -Andrey
>
> >> Signed-off-by: Andrey Yurovsky <[email protected]>
> >> ---
> >> drivers/net/wireless/libertas/cmd.c | 29 +++++++----------------------
> >> 1 files changed, 7 insertions(+), 22 deletions(-)
> >>
> >> diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
> >> index 01db705..5825396 100644
> >> --- a/drivers/net/wireless/libertas/cmd.c
> >> +++ b/drivers/net/wireless/libertas/cmd.c
> >> @@ -1782,32 +1782,17 @@ int lbs_execute_next_command(struct lbs_private *priv)
> >> lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
> >> le16_to_cpu(cmd->command));
> >> lbs_submit_command(priv, cmdnode);
> >> - } else {
> >> + } else if ((priv->psmode != LBS802_11POWERMODECAM) &&
> >> + (priv->psstate == PS_STATE_FULL_POWER) &&
> >> + ((priv->connect_status == LBS_CONNECTED) ||
> >> + (priv->mesh_connect_status == LBS_CONNECTED))) {
> >> /*
> >> * check if in power save mode, if yes, put the device back
> >> * to PS mode
> >> */
> >> - if ((priv->psmode != LBS802_11POWERMODECAM) &&
> >> - (priv->psstate == PS_STATE_FULL_POWER) &&
> >> - ((priv->connect_status == LBS_CONNECTED) ||
> >> - (priv->mesh_connect_status == LBS_CONNECTED))) {
> >> - if (priv->secinfo.WPAenabled ||
> >> - priv->secinfo.WPA2enabled) {
> >> - /* check for valid WPA group keys */
> >> - if (priv->wpa_mcast_key.len ||
> >> - priv->wpa_unicast_key.len) {
> >> - lbs_deb_host(
> >> - "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
> >> - " go back to PS_SLEEP");
> >> - lbs_ps_sleep(priv, 0);
> >> - }
> >> - } else {
> >> - lbs_deb_host(
> >> - "EXEC_NEXT_CMD: cmdpendingq empty, "
> >> - "go back to PS_SLEEP");
> >> - lbs_ps_sleep(priv, 0);
> >> - }
> >> - }
> >> + lbs_deb_host("EXEC_NEXT_CMD: cmdpendingq empty, "
> >> + "go back to PS_SLEEP");
> >> + lbs_ps_sleep(priv, 0);
> >> }
> >>
> >> ret = 0;
> >
> >


2009-06-22 14:28:59

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH V2] libertas: copy WPA keys to priv when associating

On Wed, 2009-06-17 at 18:45 -0700, Andrey Yurovsky wrote:
> Libertas currently maintains a copy of the WPA unicast and group keys
> when using WPA or WPA2. This copy is checked when deciding whether or
> not to return to sleep in IEEE PS mode but the actual copying back to
> priv was omitted, which breaks IEEE PS mode with WPA/WPA2 when one
> issues commands that require temporarily keeping the device awake.
>
> This patch introduces the omitted copy-back of the keys so that IEEE PS
> functions correctly in WPA/WPA2 mode. Thanks to Dan Williams for
> clearing up the issue.
>
> V2: fix typo. Also, this has been tested on GSPI and SDIO with V9 firmware.
>
> Signed-off-by: Andrey Yurovsky <[email protected]>

Acked-by: Dan Williams <[email protected]>

Thanks!

> ---
> drivers/net/wireless/libertas/assoc.c | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
> index b9b3741..b7c7cb0 100644
> --- a/drivers/net/wireless/libertas/assoc.c
> +++ b/drivers/net/wireless/libertas/assoc.c
> @@ -1368,11 +1368,17 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv,
> if (ret)
> goto out;
>
> + memcpy(&priv->wpa_unicast_key, &assoc_req->wpa_unicast_key,
> + sizeof(struct enc_key));
> +
> if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
> clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
>
> ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
> assoc_req->flags = flags;
> +
> + memcpy(&priv->wpa_mcast_key, &assoc_req->wpa_mcast_key,
> + sizeof(struct enc_key));
> }
>
> out:


2009-06-18 01:44:15

by Andrey Yurovsky

[permalink] [raw]
Subject: [PATCH V2] libertas: copy WPA keys to priv when associating

Libertas currently maintains a copy of the WPA unicast and group keys
when using WPA or WPA2. This copy is checked when deciding whether or
not to return to sleep in IEEE PS mode but the actual copying back to
priv was omitted, which breaks IEEE PS mode with WPA/WPA2 when one
issues commands that require temporarily keeping the device awake.

This patch introduces the omitted copy-back of the keys so that IEEE PS
functions correctly in WPA/WPA2 mode. Thanks to Dan Williams for
clearing up the issue.

V2: fix typo. Also, this has been tested on GSPI and SDIO with V9 firmware.

Signed-off-by: Andrey Yurovsky <[email protected]>
---
drivers/net/wireless/libertas/assoc.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index b9b3741..b7c7cb0 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -1368,11 +1368,17 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv,
if (ret)
goto out;

+ memcpy(&priv->wpa_unicast_key, &assoc_req->wpa_unicast_key,
+ sizeof(struct enc_key));
+
if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);

ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
assoc_req->flags = flags;
+
+ memcpy(&priv->wpa_mcast_key, &assoc_req->wpa_mcast_key,
+ sizeof(struct enc_key));
}

out:
--
1.5.6.3


2009-06-16 20:10:10

by Andrey Yurovsky

[permalink] [raw]
Subject: Re: [PATCH] libertas: Fix re-enabling IEEE PS with WPA/WPA2

On Tue, Jun 16, 2009 at 12:53 PM, Dan Williams<[email protected]> wrote:
> On Mon, 2009-06-15 at 13:01 -0700, Andrey Yurovsky wrote:
>> With IEEE PS enabled, the driver will temporarily take the device out of
>> PS mode to issue commands and then re-enable PS once the commands have
>> completed. ?With WPA or WPA2 security, the driver fails to re-enable PS
>> mode because of a check for key lengths that are always zero.
>>
>> This patch removes the key lengths check (the local copy of the keys is
>> not maintained) and fixes IEEE PS mode with WPA or WPA2 security.
>> Tested on GSPI and SDIO interfaces with V9 firmware.
>
> I have no idea what this code was trying to do originally (I'm pretty
> sure it's a left-over from the vendor driver), but it seems like maybe
> it was ensuring that the adapter did *not* return to power-save mode
> until the supplicant had set the GTK? ?There's a window where the GTK
> won't be set, and we probably shouldn't be entering PS mode until that
> window is closed. ?Old sd8385 code from a Motorola phone has:
>
> ? ? ? ?if ((Adapter->PSMode != Wlan802_11PowerModeCAM) &&
> ? ? ? ? ? ? ? ? ? ? ? ?(Adapter->PSState == PS_STATE_FULL_POWER) &&
> ? ? ? ? ? ? ? ? ? ? ? ?(Adapter->MediaConnectStatus ==
> ? ? ? ? ? ? ? ? ? ? ? ? WlanMediaStateConnected)) {
> ? ? ? ? ? ? ? ?if(Adapter->SecInfo.WPAEnabled
> ? ? ? ? ? ? ? ? ? ? ? ?|| Adapter->SecInfo.WPA2Enabled
> ? ? ? ? ? ? ? ?) {
> ? ? ? ? ? ? ? ? ? ? ? ?if(Adapter->IsGTK_SET == TRUE) {
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PRINTM(INFO, "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" go back to PS_SLEEP");
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PSSleep(priv, 0);
> ? ? ? ? ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ?} else
> ? ? ? ? ? ? ? ?{
> ? ? ? ? ? ? ? ? ? ? ? ?PRINTM(INFO, "EXEC_NEXT_CMD: Command PendQ is empty,"
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" go back to PS_SLEEP");
> ? ? ? ? ? ? ? ? ? ? ? ?PSSleep(priv, 0);
> ? ? ? ? ? ? ? ?}
> ? ? ? ?}
>
> Says to me, "if WPA is enabled but the GTK hasn't been set yet, don't go
> to sleep".
>
> Does that sound like a plausible explanation of what the original bits
> intended to do? ?Like I said, it was inherited, but there might have
> been a good reason for it.

That might be the original intention, but assoc_helper_wpa_keys() sets
both and lbs_cmd_802_11_key_material() then clears out the driver's
copy, which is then (incorrectly) checked when deciding whether to go
back to sleep. As I understand it, the execution path for WPA/WPA2
association shouldn't cause this situation where WPA is enabled but
the GTK isn't set yet and we're deciding to go back to sleep. Do you
agree? Should we even be keeping the 'driver copy' of the keys? I
don't see why we want to do that. Thanks,

-Andrey

>> Signed-off-by: Andrey Yurovsky <[email protected]>
>> ---
>> ?drivers/net/wireless/libertas/cmd.c | ? 29 +++++++----------------------
>> ?1 files changed, 7 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
>> index 01db705..5825396 100644
>> --- a/drivers/net/wireless/libertas/cmd.c
>> +++ b/drivers/net/wireless/libertas/cmd.c
>> @@ -1782,32 +1782,17 @@ int lbs_execute_next_command(struct lbs_private *priv)
>> ? ? ? ? ? ? ? lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
>> ? ? ? ? ? ? ? ? ? ? ? ? ? le16_to_cpu(cmd->command));
>> ? ? ? ? ? ? ? lbs_submit_command(priv, cmdnode);
>> - ? ? } else {
>> + ? ? } else if ((priv->psmode != LBS802_11POWERMODECAM) &&
>> + ? ? ? ? ? ? ? ?(priv->psstate == PS_STATE_FULL_POWER) &&
>> + ? ? ? ? ? ? ? ?((priv->connect_status == LBS_CONNECTED) ||
>> + ? ? ? ? ? ? ? ?(priv->mesh_connect_status == LBS_CONNECTED))) {
>> ? ? ? ? ? ? ? /*
>> ? ? ? ? ? ? ? ?* check if in power save mode, if yes, put the device back
>> ? ? ? ? ? ? ? ?* to PS mode
>> ? ? ? ? ? ? ? ?*/
>> - ? ? ? ? ? ? if ((priv->psmode != LBS802_11POWERMODECAM) &&
>> - ? ? ? ? ? ? ? ? (priv->psstate == PS_STATE_FULL_POWER) &&
>> - ? ? ? ? ? ? ? ? ((priv->connect_status == LBS_CONNECTED) ||
>> - ? ? ? ? ? ? ? ? (priv->mesh_connect_status == LBS_CONNECTED))) {
>> - ? ? ? ? ? ? ? ? ? ? if (priv->secinfo.WPAenabled ||
>> - ? ? ? ? ? ? ? ? ? ? ? ? priv->secinfo.WPA2enabled) {
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* check for valid WPA group keys */
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (priv->wpa_mcast_key.len ||
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? priv->wpa_unicast_key.len) {
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lbs_deb_host(
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"EXEC_NEXT_CMD: WPA enabled and GTK_SET"
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" go back to PS_SLEEP");
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lbs_ps_sleep(priv, 0);
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
>> - ? ? ? ? ? ? ? ? ? ? } else {
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? lbs_deb_host(
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"EXEC_NEXT_CMD: cmdpendingq empty, "
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"go back to PS_SLEEP");
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? lbs_ps_sleep(priv, 0);
>> - ? ? ? ? ? ? ? ? ? ? }
>> - ? ? ? ? ? ? }
>> + ? ? ? ? ? ? lbs_deb_host("EXEC_NEXT_CMD: cmdpendingq empty, "
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? "go back to PS_SLEEP");
>> + ? ? ? ? ? ? lbs_ps_sleep(priv, 0);
>> ? ? ? }
>>
>> ? ? ? ret = 0;
>
>

2009-06-16 19:53:32

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH] libertas: Fix re-enabling IEEE PS with WPA/WPA2

On Mon, 2009-06-15 at 13:01 -0700, Andrey Yurovsky wrote:
> With IEEE PS enabled, the driver will temporarily take the device out of
> PS mode to issue commands and then re-enable PS once the commands have
> completed. With WPA or WPA2 security, the driver fails to re-enable PS
> mode because of a check for key lengths that are always zero.
>
> This patch removes the key lengths check (the local copy of the keys is
> not maintained) and fixes IEEE PS mode with WPA or WPA2 security.
> Tested on GSPI and SDIO interfaces with V9 firmware.

I have no idea what this code was trying to do originally (I'm pretty
sure it's a left-over from the vendor driver), but it seems like maybe
it was ensuring that the adapter did *not* return to power-save mode
until the supplicant had set the GTK? There's a window where the GTK
won't be set, and we probably shouldn't be entering PS mode until that
window is closed. Old sd8385 code from a Motorola phone has:

if ((Adapter->PSMode != Wlan802_11PowerModeCAM) &&
(Adapter->PSState == PS_STATE_FULL_POWER) &&
(Adapter->MediaConnectStatus ==
WlanMediaStateConnected)) {
if(Adapter->SecInfo.WPAEnabled
|| Adapter->SecInfo.WPA2Enabled
) {
if(Adapter->IsGTK_SET == TRUE) {
PRINTM(INFO, "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
" go back to PS_SLEEP");
PSSleep(priv, 0);
}
} else
{
PRINTM(INFO, "EXEC_NEXT_CMD: Command PendQ is empty,"
" go back to PS_SLEEP");
PSSleep(priv, 0);
}
}

Says to me, "if WPA is enabled but the GTK hasn't been set yet, don't go
to sleep".

Does that sound like a plausible explanation of what the original bits
intended to do? Like I said, it was inherited, but there might have
been a good reason for it.

Dan

> Signed-off-by: Andrey Yurovsky <[email protected]>
> ---
> drivers/net/wireless/libertas/cmd.c | 29 +++++++----------------------
> 1 files changed, 7 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
> index 01db705..5825396 100644
> --- a/drivers/net/wireless/libertas/cmd.c
> +++ b/drivers/net/wireless/libertas/cmd.c
> @@ -1782,32 +1782,17 @@ int lbs_execute_next_command(struct lbs_private *priv)
> lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
> le16_to_cpu(cmd->command));
> lbs_submit_command(priv, cmdnode);
> - } else {
> + } else if ((priv->psmode != LBS802_11POWERMODECAM) &&
> + (priv->psstate == PS_STATE_FULL_POWER) &&
> + ((priv->connect_status == LBS_CONNECTED) ||
> + (priv->mesh_connect_status == LBS_CONNECTED))) {
> /*
> * check if in power save mode, if yes, put the device back
> * to PS mode
> */
> - if ((priv->psmode != LBS802_11POWERMODECAM) &&
> - (priv->psstate == PS_STATE_FULL_POWER) &&
> - ((priv->connect_status == LBS_CONNECTED) ||
> - (priv->mesh_connect_status == LBS_CONNECTED))) {
> - if (priv->secinfo.WPAenabled ||
> - priv->secinfo.WPA2enabled) {
> - /* check for valid WPA group keys */
> - if (priv->wpa_mcast_key.len ||
> - priv->wpa_unicast_key.len) {
> - lbs_deb_host(
> - "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
> - " go back to PS_SLEEP");
> - lbs_ps_sleep(priv, 0);
> - }
> - } else {
> - lbs_deb_host(
> - "EXEC_NEXT_CMD: cmdpendingq empty, "
> - "go back to PS_SLEEP");
> - lbs_ps_sleep(priv, 0);
> - }
> - }
> + lbs_deb_host("EXEC_NEXT_CMD: cmdpendingq empty, "
> + "go back to PS_SLEEP");
> + lbs_ps_sleep(priv, 0);
> }
>
> ret = 0;