ath10k: fix broken traffic for static WEP in IBSS
authorMichal Kazior <michal.kazior@tieto.com>
Wed, 18 Feb 2015 13:02:27 +0000 (14:02 +0100)
committerKalle Valo <kvalo@qca.qualcomm.com>
Sat, 7 Mar 2015 07:50:57 +0000 (09:50 +0200)
When WEP keys are uploaded it's possible that
there are stations associated already (e.g. when
merging) without any keys. Static WEP needs an
explicit per-peer key upload.

Make sure to re-upload wep keys if necessary.

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 722ff38b042b122806f0b07306c08904ceae2e65..32b4ce6ec35694b2d3272780ca4167d2cd0a182d 100644 (file)
@@ -297,6 +297,39 @@ static int ath10k_mac_vif_sta_fix_wep_key(struct ath10k_vif *arvif)
        return 0;
 }
 
+static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
+                                        struct ieee80211_key_conf *key)
+{
+       struct ath10k *ar = arvif->ar;
+       struct ath10k_peer *peer;
+       int ret;
+
+       lockdep_assert_held(&ar->conf_mutex);
+
+       list_for_each_entry(peer, &ar->peers, list) {
+               if (!memcmp(peer->addr, arvif->vif->addr, ETH_ALEN))
+                       continue;
+
+               if (!memcmp(peer->addr, arvif->bssid, ETH_ALEN))
+                       continue;
+
+               if (peer->keys[key->keyidx] == key)
+                       continue;
+
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
+                          arvif->vdev_id, key->keyidx);
+
+               ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
+               if (ret) {
+                       ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
+                                   arvif->vdev_id, peer->addr, ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
 /*********************/
 /* General utilities */
 /*********************/
@@ -3967,6 +4000,14 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                if (cmd == DISABLE_KEY)
                        ath10k_clear_vdev_key(arvif, key);
 
+               /* When WEP keys are uploaded it's possible that there are
+                * stations associated already (e.g. when merging) without any
+                * keys. Static WEP needs an explicit per-peer key upload.
+                */
+               if (vif->type == NL80211_IFTYPE_ADHOC &&
+                   cmd == SET_KEY)
+                       ath10k_mac_vif_update_wep_key(arvif, key);
+
                /* 802.1x never sets the def_wep_key_idx so each set_key()
                 * call changes default tx key.
                 *