diff options
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r-- | net/mac80211/key.c | 82 |
1 files changed, 73 insertions, 9 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 2291cd730091..a907f2d5c12d 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -58,6 +58,22 @@ static void assert_key_lock(struct ieee80211_local *local) | |||
58 | lockdep_assert_held(&local->key_mtx); | 58 | lockdep_assert_held(&local->key_mtx); |
59 | } | 59 | } |
60 | 60 | ||
61 | static void | ||
62 | update_vlan_tailroom_need_count(struct ieee80211_sub_if_data *sdata, int delta) | ||
63 | { | ||
64 | struct ieee80211_sub_if_data *vlan; | ||
65 | |||
66 | if (sdata->vif.type != NL80211_IFTYPE_AP) | ||
67 | return; | ||
68 | |||
69 | mutex_lock(&sdata->local->mtx); | ||
70 | |||
71 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | ||
72 | vlan->crypto_tx_tailroom_needed_cnt += delta; | ||
73 | |||
74 | mutex_unlock(&sdata->local->mtx); | ||
75 | } | ||
76 | |||
61 | static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata) | 77 | static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata) |
62 | { | 78 | { |
63 | /* | 79 | /* |
@@ -79,6 +95,8 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata) | |||
79 | * http://mid.gmane.org/1308590980.4322.19.camel@jlt3.sipsolutions.net | 95 | * http://mid.gmane.org/1308590980.4322.19.camel@jlt3.sipsolutions.net |
80 | */ | 96 | */ |
81 | 97 | ||
98 | update_vlan_tailroom_need_count(sdata, 1); | ||
99 | |||
82 | if (!sdata->crypto_tx_tailroom_needed_cnt++) { | 100 | if (!sdata->crypto_tx_tailroom_needed_cnt++) { |
83 | /* | 101 | /* |
84 | * Flush all XMIT packets currently using HW encryption or no | 102 | * 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) | |||
88 | } | 106 | } |
89 | } | 107 | } |
90 | 108 | ||
109 | static void decrease_tailroom_need_count(struct ieee80211_sub_if_data *sdata, | ||
110 | int delta) | ||
111 | { | ||
112 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt < delta); | ||
113 | |||
114 | update_vlan_tailroom_need_count(sdata, -delta); | ||
115 | sdata->crypto_tx_tailroom_needed_cnt -= delta; | ||
116 | } | ||
117 | |||
91 | static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | 118 | static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) |
92 | { | 119 | { |
93 | struct ieee80211_sub_if_data *sdata; | 120 | struct ieee80211_sub_if_data *sdata; |
@@ -144,7 +171,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
144 | 171 | ||
145 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | 172 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
146 | (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) | 173 | (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) |
147 | sdata->crypto_tx_tailroom_needed_cnt--; | 174 | decrease_tailroom_need_count(sdata, 1); |
148 | 175 | ||
149 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && | 176 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && |
150 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)); | 177 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)); |
@@ -541,7 +568,7 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key, | |||
541 | schedule_delayed_work(&sdata->dec_tailroom_needed_wk, | 568 | schedule_delayed_work(&sdata->dec_tailroom_needed_wk, |
542 | HZ/2); | 569 | HZ/2); |
543 | } else { | 570 | } else { |
544 | sdata->crypto_tx_tailroom_needed_cnt--; | 571 | decrease_tailroom_need_count(sdata, 1); |
545 | } | 572 | } |
546 | } | 573 | } |
547 | 574 | ||
@@ -631,6 +658,7 @@ void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom) | |||
631 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) | 658 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) |
632 | { | 659 | { |
633 | struct ieee80211_key *key; | 660 | struct ieee80211_key *key; |
661 | struct ieee80211_sub_if_data *vlan; | ||
634 | 662 | ||
635 | ASSERT_RTNL(); | 663 | ASSERT_RTNL(); |
636 | 664 | ||
@@ -639,7 +667,14 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) | |||
639 | 667 | ||
640 | mutex_lock(&sdata->local->key_mtx); | 668 | mutex_lock(&sdata->local->key_mtx); |
641 | 669 | ||
642 | sdata->crypto_tx_tailroom_needed_cnt = 0; | 670 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || |
671 | sdata->crypto_tx_tailroom_pending_dec); | ||
672 | |||
673 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
674 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | ||
675 | WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt || | ||
676 | vlan->crypto_tx_tailroom_pending_dec); | ||
677 | } | ||
643 | 678 | ||
644 | list_for_each_entry(key, &sdata->key_list, list) { | 679 | list_for_each_entry(key, &sdata->key_list, list) { |
645 | increment_tailroom_need_count(sdata); | 680 | increment_tailroom_need_count(sdata); |
@@ -649,6 +684,22 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) | |||
649 | mutex_unlock(&sdata->local->key_mtx); | 684 | mutex_unlock(&sdata->local->key_mtx); |
650 | } | 685 | } |
651 | 686 | ||
687 | void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata) | ||
688 | { | ||
689 | struct ieee80211_sub_if_data *vlan; | ||
690 | |||
691 | mutex_lock(&sdata->local->key_mtx); | ||
692 | |||
693 | sdata->crypto_tx_tailroom_needed_cnt = 0; | ||
694 | |||
695 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
696 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | ||
697 | vlan->crypto_tx_tailroom_needed_cnt = 0; | ||
698 | } | ||
699 | |||
700 | mutex_unlock(&sdata->local->key_mtx); | ||
701 | } | ||
702 | |||
652 | void ieee80211_iter_keys(struct ieee80211_hw *hw, | 703 | void ieee80211_iter_keys(struct ieee80211_hw *hw, |
653 | struct ieee80211_vif *vif, | 704 | struct ieee80211_vif *vif, |
654 | void (*iter)(struct ieee80211_hw *hw, | 705 | void (*iter)(struct ieee80211_hw *hw, |
@@ -688,8 +739,8 @@ static void ieee80211_free_keys_iface(struct ieee80211_sub_if_data *sdata, | |||
688 | { | 739 | { |
689 | struct ieee80211_key *key, *tmp; | 740 | struct ieee80211_key *key, *tmp; |
690 | 741 | ||
691 | sdata->crypto_tx_tailroom_needed_cnt -= | 742 | decrease_tailroom_need_count(sdata, |
692 | sdata->crypto_tx_tailroom_pending_dec; | 743 | sdata->crypto_tx_tailroom_pending_dec); |
693 | sdata->crypto_tx_tailroom_pending_dec = 0; | 744 | sdata->crypto_tx_tailroom_pending_dec = 0; |
694 | 745 | ||
695 | ieee80211_debugfs_key_remove_mgmt_default(sdata); | 746 | ieee80211_debugfs_key_remove_mgmt_default(sdata); |
@@ -709,6 +760,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata, | |||
709 | { | 760 | { |
710 | struct ieee80211_local *local = sdata->local; | 761 | struct ieee80211_local *local = sdata->local; |
711 | struct ieee80211_sub_if_data *vlan; | 762 | struct ieee80211_sub_if_data *vlan; |
763 | struct ieee80211_sub_if_data *master; | ||
712 | struct ieee80211_key *key, *tmp; | 764 | struct ieee80211_key *key, *tmp; |
713 | LIST_HEAD(keys); | 765 | LIST_HEAD(keys); |
714 | 766 | ||
@@ -728,8 +780,20 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata, | |||
728 | list_for_each_entry_safe(key, tmp, &keys, list) | 780 | list_for_each_entry_safe(key, tmp, &keys, list) |
729 | __ieee80211_key_destroy(key, false); | 781 | __ieee80211_key_destroy(key, false); |
730 | 782 | ||
731 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || | 783 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { |
732 | sdata->crypto_tx_tailroom_pending_dec); | 784 | if (sdata->bss) { |
785 | master = container_of(sdata->bss, | ||
786 | struct ieee80211_sub_if_data, | ||
787 | u.ap); | ||
788 | |||
789 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt != | ||
790 | master->crypto_tx_tailroom_needed_cnt); | ||
791 | } | ||
792 | } else { | ||
793 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || | ||
794 | sdata->crypto_tx_tailroom_pending_dec); | ||
795 | } | ||
796 | |||
733 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 797 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
734 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | 798 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) |
735 | WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt || | 799 | WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt || |
@@ -793,8 +857,8 @@ void ieee80211_delayed_tailroom_dec(struct work_struct *wk) | |||
793 | */ | 857 | */ |
794 | 858 | ||
795 | mutex_lock(&sdata->local->key_mtx); | 859 | mutex_lock(&sdata->local->key_mtx); |
796 | sdata->crypto_tx_tailroom_needed_cnt -= | 860 | decrease_tailroom_need_count(sdata, |
797 | sdata->crypto_tx_tailroom_pending_dec; | 861 | sdata->crypto_tx_tailroom_pending_dec); |
798 | sdata->crypto_tx_tailroom_pending_dec = 0; | 862 | sdata->crypto_tx_tailroom_pending_dec = 0; |
799 | mutex_unlock(&sdata->local->key_mtx); | 863 | mutex_unlock(&sdata->local->key_mtx); |
800 | } | 864 | } |