[PATCH] libertas: problems setting wpa keys
authorDan Williams <dcbw@redhat.com>
Wed, 3 Oct 2007 14:37:45 +0000 (10:37 -0400)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:55:18 +0000 (16:55 -0700)
The 88w8385 chip, using SDIO interface and firmware release 5.0.11p0,
has problems when both unicast and multicast WPA keys are set in one
command. This patch ensures the keys are set independently.

The original author of this patch is Marc Pignat <marc.pignat@hevs.ch>

Signed-off-by: Marc Pignat <marc.pignat@hevs.ch>
Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/libertas/assoc.c

index 2c6ddb1f0072c5abf80f51a3c0cc2ff39fb7c10b..b61b176e9d07a9e234f41444db7c618030772bb4 100644 (file)
@@ -374,15 +374,40 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
                                  struct assoc_request * assoc_req)
 {
        int ret = 0;
+       unsigned int flags = assoc_req->flags;
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
-       ret = libertas_prepare_and_send_command(priv,
-                                   CMD_802_11_KEY_MATERIAL,
-                                   CMD_ACT_SET,
-                                   CMD_OPTION_WAITFORRSP,
-                                   0, assoc_req);
+       /* Work around older firmware bug where WPA unicast and multicast
+        * keys must be set independently.  Seen in SDIO parts with firmware
+        * version 5.0.11p0.
+        */
 
+       if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
+               clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
+               ret = libertas_prepare_and_send_command(priv,
+                                       CMD_802_11_KEY_MATERIAL,
+                                       CMD_ACT_SET,
+                                       CMD_OPTION_WAITFORRSP,
+                                       0, assoc_req);
+               assoc_req->flags = flags;
+       }
+
+       if (ret)
+               goto out;
+
+       if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
+               clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
+
+               ret = libertas_prepare_and_send_command(priv,
+                                       CMD_802_11_KEY_MATERIAL,
+                                       CMD_ACT_SET,
+                                       CMD_OPTION_WAITFORRSP,
+                                       0, assoc_req);
+               assoc_req->flags = flags;
+       }
+
+out:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }