diff options
| -rw-r--r-- | net/mac80211/iface.c | 6 | ||||
| -rw-r--r-- | net/mac80211/key.c | 82 | ||||
| -rw-r--r-- | net/mac80211/key.h | 1 | ||||
| -rw-r--r-- | net/mac80211/util.c | 3 |
4 files changed, 83 insertions, 9 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index bab5c63c0bad..84cef600c573 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -522,6 +522,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
| 522 | memcpy(sdata->vif.hw_queue, master->vif.hw_queue, | 522 | memcpy(sdata->vif.hw_queue, master->vif.hw_queue, |
| 523 | sizeof(sdata->vif.hw_queue)); | 523 | sizeof(sdata->vif.hw_queue)); |
| 524 | sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef; | 524 | sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef; |
| 525 | |||
| 526 | mutex_lock(&local->key_mtx); | ||
| 527 | sdata->crypto_tx_tailroom_needed_cnt += | ||
| 528 | master->crypto_tx_tailroom_needed_cnt; | ||
| 529 | mutex_unlock(&local->key_mtx); | ||
| 530 | |||
| 525 | break; | 531 | break; |
| 526 | } | 532 | } |
| 527 | case NL80211_IFTYPE_AP: | 533 | case NL80211_IFTYPE_AP: |
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 | } |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index c5a31835be0e..96557dd1e77d 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
| @@ -161,6 +161,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata, | |||
| 161 | void ieee80211_free_sta_keys(struct ieee80211_local *local, | 161 | void ieee80211_free_sta_keys(struct ieee80211_local *local, |
| 162 | struct sta_info *sta); | 162 | struct sta_info *sta); |
| 163 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); | 163 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); |
| 164 | void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata); | ||
| 164 | 165 | ||
| 165 | #define key_mtx_dereference(local, ref) \ | 166 | #define key_mtx_dereference(local, ref) \ |
| 166 | rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx))) | 167 | rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx))) |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 79412f16b61d..b864ebc6ab8f 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -2023,6 +2023,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 2023 | 2023 | ||
| 2024 | /* add back keys */ | 2024 | /* add back keys */ |
| 2025 | list_for_each_entry(sdata, &local->interfaces, list) | 2025 | list_for_each_entry(sdata, &local->interfaces, list) |
| 2026 | ieee80211_reset_crypto_tx_tailroom(sdata); | ||
| 2027 | |||
| 2028 | list_for_each_entry(sdata, &local->interfaces, list) | ||
| 2026 | if (ieee80211_sdata_running(sdata)) | 2029 | if (ieee80211_sdata_running(sdata)) |
| 2027 | ieee80211_enable_keys(sdata); | 2030 | ieee80211_enable_keys(sdata); |
| 2028 | 2031 | ||
