ath10k: fix static wep with more than 1 key in client mode
authorMichal Kazior <michal.kazior@tieto.com>
Wed, 1 Apr 2015 19:53:20 +0000 (22:53 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Thu, 9 Apr 2015 12:00:11 +0000 (15:00 +0300)
The default keyidx callback may be called after
more than 1 key is installed. This led to only 1
WEP key being reinstalled only. This caused Rxed
traffic encrypted with other WEP keys to be
dropped in client mode.

Tested-by: Bartosz Markowski <bartosz.markowski@tieto.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/mac.c

index db5a2c3..ab3301b 100644 (file)
@@ -360,39 +360,42 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
        return first_errno;
 }
 
-static int ath10k_mac_vif_sta_fix_wep_key(struct ath10k_vif *arvif)
+static int ath10k_mac_vif_sta_fix_wep_key(struct ath10k_vif *arvif, int keyidx)
 {
        struct ath10k *ar = arvif->ar;
        enum nl80211_iftype iftype = arvif->vif->type;
        struct ieee80211_key_conf *key;
-       u32 flags = 0;
-       int num = 0;
-       int i;
+       u32 flags;
        int ret;
+       int i;
 
        lockdep_assert_held(&ar->conf_mutex);
 
        if (iftype != NL80211_IFTYPE_STATION)
                return 0;
 
+       if (keyidx < 0)
+               return 0;
+
        for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
-               if (arvif->wep_keys[i]) {
-                       key = arvif->wep_keys[i];
-                       ++num;
-               }
-       }
+               if (!arvif->wep_keys[i])
+                       continue;
 
-       if (num != 1)
-               return 0;
+               key = arvif->wep_keys[i];
 
-       flags |= WMI_KEY_PAIRWISE;
-       flags |= WMI_KEY_TX_USAGE;
+               flags = 0;
+               flags |= WMI_KEY_PAIRWISE;
 
-       ret = ath10k_install_key(arvif, key, SET_KEY, arvif->bssid, flags);
-       if (ret) {
-               ath10k_warn(ar, "failed to install key %i on vdev %i: %d\n",
-                           key->keyidx, arvif->vdev_id, ret);
-               return ret;
+               if (key->keyidx == keyidx)
+                       flags |= WMI_KEY_TX_USAGE;
+
+               ret = ath10k_install_key(arvif, key, SET_KEY, arvif->bssid,
+                                        flags);
+               if (ret) {
+                       ath10k_warn(ar, "failed to install key %i on vdev %i: %d\n",
+                                   key->keyidx, arvif->vdev_id, ret);
+                       return ret;
+               }
        }
 
        return 0;
@@ -4846,7 +4849,7 @@ static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
 
        arvif->def_wep_key_idx = keyidx;
 
-       ret = ath10k_mac_vif_sta_fix_wep_key(arvif);
+       ret = ath10k_mac_vif_sta_fix_wep_key(arvif, keyidx);
        if (ret) {
                ath10k_warn(ar, "failed to fix sta wep key on vdev %i: %d\n",
                            arvif->vdev_id, ret);