Remove prefetch() from <linux/skbuff.h> and "netlabel_addrlist.h"
[pandora-kernel.git] / net / mac80211 / key.c
index af3c564..31afd71 100644 (file)
@@ -101,6 +101,11 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 
        if (!ret) {
                key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
+
+               if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
+                     (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
+                       key->local->crypto_tx_tailroom_needed_cnt--;
+
                return 0;
        }
 
@@ -156,6 +161,10 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
                          key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
 
        key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
+
+       if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
+             (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
+               key->local->crypto_tx_tailroom_needed_cnt++;
 }
 
 void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
@@ -186,7 +195,7 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
        assert_key_lock(sdata->local);
 
        if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
-               key = sdata->keys[idx];
+               key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
 
        if (uni)
                rcu_assign_pointer(sdata->default_unicast_key, key);
@@ -213,7 +222,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
 
        if (idx >= NUM_DEFAULT_KEYS &&
            idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
-               key = sdata->keys[idx];
+               key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
 
        rcu_assign_pointer(sdata->default_mgmt_key, key);
 
@@ -257,9 +266,15 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
                else
                        idx = new->conf.keyidx;
 
-               defunikey = old && sdata->default_unicast_key == old;
-               defmultikey = old && sdata->default_multicast_key == old;
-               defmgmtkey = old && sdata->default_mgmt_key == old;
+               defunikey = old &&
+                       old == key_mtx_dereference(sdata->local,
+                                               sdata->default_unicast_key);
+               defmultikey = old &&
+                       old == key_mtx_dereference(sdata->local,
+                                               sdata->default_multicast_key);
+               defmgmtkey = old &&
+                       old == key_mtx_dereference(sdata->local,
+                                               sdata->default_mgmt_key);
 
                if (defunikey && !new)
                        __ieee80211_set_default_key(sdata, -1, true, false);
@@ -388,8 +403,10 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
                ieee80211_aes_key_free(key->u.ccmp.tfm);
        if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
                ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
-       if (key->local)
+       if (key->local) {
                ieee80211_debugfs_key_remove(key);
+               key->local->crypto_tx_tailroom_needed_cnt--;
+       }
 
        kfree(key);
 }
@@ -440,17 +457,19 @@ int ieee80211_key_link(struct ieee80211_key *key,
        mutex_lock(&sdata->local->key_mtx);
 
        if (sta && pairwise)
-               old_key = sta->ptk;
+               old_key = key_mtx_dereference(sdata->local, sta->ptk);
        else if (sta)
-               old_key = sta->gtk[idx];
+               old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
        else
-               old_key = sdata->keys[idx];
+               old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
 
        __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
        __ieee80211_key_destroy(old_key);
 
        ieee80211_debugfs_key_add(key);
 
+       key->local->crypto_tx_tailroom_needed_cnt++;
+
        ret = ieee80211_key_enable_hw_accel(key);
 
        mutex_unlock(&sdata->local->key_mtx);
@@ -458,8 +477,11 @@ int ieee80211_key_link(struct ieee80211_key *key,
        return ret;
 }
 
-static void __ieee80211_key_free(struct ieee80211_key *key)
+void __ieee80211_key_free(struct ieee80211_key *key)
 {
+       if (!key)
+               return;
+
        /*
         * Replace key with nothingness if it was ever used.
         */
@@ -473,9 +495,6 @@ static void __ieee80211_key_free(struct ieee80211_key *key)
 void ieee80211_key_free(struct ieee80211_local *local,
                        struct ieee80211_key *key)
 {
-       if (!key)
-               return;
-
        mutex_lock(&local->key_mtx);
        __ieee80211_key_free(key);
        mutex_unlock(&local->key_mtx);
@@ -492,8 +511,12 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
 
        mutex_lock(&sdata->local->key_mtx);
 
-       list_for_each_entry(key, &sdata->key_list, list)
+       sdata->local->crypto_tx_tailroom_needed_cnt = 0;
+
+       list_for_each_entry(key, &sdata->key_list, list) {
+               sdata->local->crypto_tx_tailroom_needed_cnt++;
                ieee80211_key_enable_hw_accel(key);
+       }
 
        mutex_unlock(&sdata->local->key_mtx);
 }