|
@@ -58,6 +58,22 @@ static void assert_key_lock(struct ieee80211_local *local)
|
|
|
lockdep_assert_held(&local->key_mtx);
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+update_vlan_tailroom_need_count(struct ieee80211_sub_if_data *sdata, int delta)
|
|
|
+{
|
|
|
+ struct ieee80211_sub_if_data *vlan;
|
|
|
+
|
|
|
+ if (sdata->vif.type != NL80211_IFTYPE_AP)
|
|
|
+ return;
|
|
|
+
|
|
|
+ mutex_lock(&sdata->local->mtx);
|
|
|
+
|
|
|
+ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
|
|
+ vlan->crypto_tx_tailroom_needed_cnt += delta;
|
|
|
+
|
|
|
+ mutex_unlock(&sdata->local->mtx);
|
|
|
+}
|
|
|
+
|
|
|
static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
|
|
|
{
|
|
|
/*
|
|
@@ -79,6 +95,8 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
|
|
|
* http://mid.gmane.org/1308590980.4322.19.camel@jlt3.sipsolutions.net
|
|
|
*/
|
|
|
|
|
|
+ update_vlan_tailroom_need_count(sdata, 1);
|
|
|
+
|
|
|
if (!sdata->crypto_tx_tailroom_needed_cnt++) {
|
|
|
/*
|
|
|
* Flush all XMIT packets currently using HW encryption or no
|
|
@@ -88,6 +106,15 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void decrease_tailroom_need_count(struct ieee80211_sub_if_data *sdata,
|
|
|
+ int delta)
|
|
|
+{
|
|
|
+ WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt < delta);
|
|
|
+
|
|
|
+ update_vlan_tailroom_need_count(sdata, -delta);
|
|
|
+ sdata->crypto_tx_tailroom_needed_cnt -= delta;
|
|
|
+}
|
|
|
+
|
|
|
static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
|
|
{
|
|
|
struct ieee80211_sub_if_data *sdata;
|
|
@@ -144,7 +171,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
|
|
|
|
|
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
|
|
(key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM)))
|
|
|
- sdata->crypto_tx_tailroom_needed_cnt--;
|
|
|
+ decrease_tailroom_need_count(sdata, 1);
|
|
|
|
|
|
WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
|
|
|
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));
|
|
@@ -541,7 +568,7 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
|
|
|
schedule_delayed_work(&sdata->dec_tailroom_needed_wk,
|
|
|
HZ/2);
|
|
|
} else {
|
|
|
- sdata->crypto_tx_tailroom_needed_cnt--;
|
|
|
+ decrease_tailroom_need_count(sdata, 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -631,6 +658,7 @@ void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
|
|
|
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
|
|
|
{
|
|
|
struct ieee80211_key *key;
|
|
|
+ struct ieee80211_sub_if_data *vlan;
|
|
|
|
|
|
ASSERT_RTNL();
|
|
|
|
|
@@ -639,7 +667,14 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
|
|
|
|
|
|
mutex_lock(&sdata->local->key_mtx);
|
|
|
|
|
|
- sdata->crypto_tx_tailroom_needed_cnt = 0;
|
|
|
+ WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
|
|
|
+ sdata->crypto_tx_tailroom_pending_dec);
|
|
|
+
|
|
|
+ if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
|
|
+ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
|
|
+ WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt ||
|
|
|
+ vlan->crypto_tx_tailroom_pending_dec);
|
|
|
+ }
|
|
|
|
|
|
list_for_each_entry(key, &sdata->key_list, list) {
|
|
|
increment_tailroom_need_count(sdata);
|
|
@@ -649,6 +684,22 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
|
|
|
mutex_unlock(&sdata->local->key_mtx);
|
|
|
}
|
|
|
|
|
|
+void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata)
|
|
|
+{
|
|
|
+ struct ieee80211_sub_if_data *vlan;
|
|
|
+
|
|
|
+ mutex_lock(&sdata->local->key_mtx);
|
|
|
+
|
|
|
+ sdata->crypto_tx_tailroom_needed_cnt = 0;
|
|
|
+
|
|
|
+ if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
|
|
+ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
|
|
+ vlan->crypto_tx_tailroom_needed_cnt = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_unlock(&sdata->local->key_mtx);
|
|
|
+}
|
|
|
+
|
|
|
void ieee80211_iter_keys(struct ieee80211_hw *hw,
|
|
|
struct ieee80211_vif *vif,
|
|
|
void (*iter)(struct ieee80211_hw *hw,
|
|
@@ -688,8 +739,8 @@ static void ieee80211_free_keys_iface(struct ieee80211_sub_if_data *sdata,
|
|
|
{
|
|
|
struct ieee80211_key *key, *tmp;
|
|
|
|
|
|
- sdata->crypto_tx_tailroom_needed_cnt -=
|
|
|
- sdata->crypto_tx_tailroom_pending_dec;
|
|
|
+ decrease_tailroom_need_count(sdata,
|
|
|
+ sdata->crypto_tx_tailroom_pending_dec);
|
|
|
sdata->crypto_tx_tailroom_pending_dec = 0;
|
|
|
|
|
|
ieee80211_debugfs_key_remove_mgmt_default(sdata);
|
|
@@ -709,6 +760,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
|
|
|
{
|
|
|
struct ieee80211_local *local = sdata->local;
|
|
|
struct ieee80211_sub_if_data *vlan;
|
|
|
+ struct ieee80211_sub_if_data *master;
|
|
|
struct ieee80211_key *key, *tmp;
|
|
|
LIST_HEAD(keys);
|
|
|
|
|
@@ -728,8 +780,20 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
|
|
|
list_for_each_entry_safe(key, tmp, &keys, list)
|
|
|
__ieee80211_key_destroy(key, false);
|
|
|
|
|
|
- WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
|
|
|
- sdata->crypto_tx_tailroom_pending_dec);
|
|
|
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
|
|
|
+ if (sdata->bss) {
|
|
|
+ master = container_of(sdata->bss,
|
|
|
+ struct ieee80211_sub_if_data,
|
|
|
+ u.ap);
|
|
|
+
|
|
|
+ WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt !=
|
|
|
+ master->crypto_tx_tailroom_needed_cnt);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
|
|
|
+ sdata->crypto_tx_tailroom_pending_dec);
|
|
|
+ }
|
|
|
+
|
|
|
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
|
|
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
|
|
WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt ||
|
|
@@ -793,8 +857,8 @@ void ieee80211_delayed_tailroom_dec(struct work_struct *wk)
|
|
|
*/
|
|
|
|
|
|
mutex_lock(&sdata->local->key_mtx);
|
|
|
- sdata->crypto_tx_tailroom_needed_cnt -=
|
|
|
- sdata->crypto_tx_tailroom_pending_dec;
|
|
|
+ decrease_tailroom_need_count(sdata,
|
|
|
+ sdata->crypto_tx_tailroom_pending_dec);
|
|
|
sdata->crypto_tx_tailroom_pending_dec = 0;
|
|
|
mutex_unlock(&sdata->local->key_mtx);
|
|
|
}
|