aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2014-06-13 09:30:07 -0400
committerJohannes Berg <johannes.berg@intel.com>2014-06-23 08:22:29 -0400
commita46992b441f097a971cca39f49d07a0d16a1c0d8 (patch)
treed80aacded124a3add8691ada27deb47ce6722ae0
parent26da23b6950cd1aaae86caa541eb4befc9e96e1d (diff)
mac80211: stop only the queues assigned to the vif during channel switch
Instead of stopping all the hardware queues during channel switch, which is especially bad when we have large CSA counts, stop only the queues that are assigned to the vif that is performing the channel switch. Additionally, check for (sdata->csa_block_tx) instead of calling ieee80211_csa_needs_block_tx(), which can now be removed. Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/cfg.c52
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/iface.c10
-rw-r--r--net/mac80211/mlme.c36
4 files changed, 35 insertions, 64 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e920d48f0209..a0d7a0362f1f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -790,31 +790,6 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
790 return 0; 790 return 0;
791} 791}
792 792
793bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local)
794{
795 struct ieee80211_sub_if_data *sdata;
796
797 lockdep_assert_held(&local->mtx);
798
799 rcu_read_lock();
800 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
801 if (!ieee80211_sdata_running(sdata))
802 continue;
803
804 if (!sdata->vif.csa_active)
805 continue;
806
807 if (!sdata->csa_block_tx)
808 continue;
809
810 rcu_read_unlock();
811 return true;
812 }
813 rcu_read_unlock();
814
815 return false;
816}
817
818static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) 793static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
819{ 794{
820 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 795 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -834,11 +809,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
834 /* abort any running channel switch */ 809 /* abort any running channel switch */
835 mutex_lock(&local->mtx); 810 mutex_lock(&local->mtx);
836 sdata->vif.csa_active = false; 811 sdata->vif.csa_active = false;
837 if (!ieee80211_csa_needs_block_tx(local)) 812 if (sdata->csa_block_tx) {
838 ieee80211_wake_queues_by_reason(&local->hw, 813 ieee80211_wake_vif_queues(local, sdata,
839 IEEE80211_MAX_QUEUE_MAP, 814 IEEE80211_QUEUE_STOP_REASON_CSA);
840 IEEE80211_QUEUE_STOP_REASON_CSA, 815 sdata->csa_block_tx = false;
841 false); 816 }
817
842 mutex_unlock(&local->mtx); 818 mutex_unlock(&local->mtx);
843 819
844 kfree(sdata->u.ap.next_beacon); 820 kfree(sdata->u.ap.next_beacon);
@@ -2826,11 +2802,11 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2826 ieee80211_bss_info_change_notify(sdata, changed); 2802 ieee80211_bss_info_change_notify(sdata, changed);
2827 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); 2803 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
2828 2804
2829 if (!ieee80211_csa_needs_block_tx(local)) 2805 if (sdata->csa_block_tx) {
2830 ieee80211_wake_queues_by_reason(&local->hw, 2806 ieee80211_wake_vif_queues(local, sdata,
2831 IEEE80211_MAX_QUEUE_MAP, 2807 IEEE80211_QUEUE_STOP_REASON_CSA);
2832 IEEE80211_QUEUE_STOP_REASON_CSA, 2808 sdata->csa_block_tx = false;
2833 false); 2809 }
2834 2810
2835 return 0; 2811 return 0;
2836} 2812}
@@ -3060,10 +3036,8 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3060 sdata->vif.csa_active = true; 3036 sdata->vif.csa_active = true;
3061 3037
3062 if (sdata->csa_block_tx) 3038 if (sdata->csa_block_tx)
3063 ieee80211_stop_queues_by_reason(&local->hw, 3039 ieee80211_stop_vif_queues(local, sdata,
3064 IEEE80211_MAX_QUEUE_MAP, 3040 IEEE80211_QUEUE_STOP_REASON_CSA);
3065 IEEE80211_QUEUE_STOP_REASON_CSA,
3066 false);
3067 3041
3068 if (changed) { 3042 if (changed) {
3069 ieee80211_bss_info_change_notify(sdata, changed); 3043 ieee80211_bss_info_change_notify(sdata, changed);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b202df2aebe8..1fd50f173653 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1489,7 +1489,6 @@ void ieee80211_sw_roc_work(struct work_struct *work);
1489void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); 1489void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
1490 1490
1491/* channel switch handling */ 1491/* channel switch handling */
1492bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local);
1493void ieee80211_csa_finalize_work(struct work_struct *work); 1492void ieee80211_csa_finalize_work(struct work_struct *work);
1494int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, 1493int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
1495 struct cfg80211_csa_settings *params); 1494 struct cfg80211_csa_settings *params);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 1971d2418d44..2a12b8aa6aad 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -841,11 +841,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
841 sdata_lock(sdata); 841 sdata_lock(sdata);
842 mutex_lock(&local->mtx); 842 mutex_lock(&local->mtx);
843 sdata->vif.csa_active = false; 843 sdata->vif.csa_active = false;
844 if (!ieee80211_csa_needs_block_tx(local)) 844 if (sdata->csa_block_tx) {
845 ieee80211_wake_queues_by_reason(&local->hw, 845 ieee80211_wake_vif_queues(local, sdata,
846 IEEE80211_MAX_QUEUE_MAP, 846 IEEE80211_QUEUE_STOP_REASON_CSA);
847 IEEE80211_QUEUE_STOP_REASON_CSA, 847 sdata->csa_block_tx = false;
848 false); 848 }
849 mutex_unlock(&local->mtx); 849 mutex_unlock(&local->mtx);
850 sdata_unlock(sdata); 850 sdata_unlock(sdata);
851 851
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1ab1884eddbf..eccc8492a59c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -980,11 +980,11 @@ static void ieee80211_chswitch_work(struct work_struct *work)
980 mutex_lock(&local->mtx); 980 mutex_lock(&local->mtx);
981 sdata->vif.csa_active = false; 981 sdata->vif.csa_active = false;
982 /* XXX: wait for a beacon first? */ 982 /* XXX: wait for a beacon first? */
983 if (!ieee80211_csa_needs_block_tx(local)) 983 if (sdata->csa_block_tx) {
984 ieee80211_wake_queues_by_reason(&local->hw, 984 ieee80211_wake_vif_queues(local, sdata,
985 IEEE80211_MAX_QUEUE_MAP, 985 IEEE80211_QUEUE_STOP_REASON_CSA);
986 IEEE80211_QUEUE_STOP_REASON_CSA, 986 sdata->csa_block_tx = false;
987 false); 987 }
988 mutex_unlock(&local->mtx); 988 mutex_unlock(&local->mtx);
989 989
990 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 990 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
@@ -1114,10 +1114,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1114 sdata->csa_block_tx = csa_ie.mode; 1114 sdata->csa_block_tx = csa_ie.mode;
1115 1115
1116 if (sdata->csa_block_tx) 1116 if (sdata->csa_block_tx)
1117 ieee80211_stop_queues_by_reason(&local->hw, 1117 ieee80211_stop_vif_queues(local, sdata,
1118 IEEE80211_MAX_QUEUE_MAP, 1118 IEEE80211_QUEUE_STOP_REASON_CSA);
1119 IEEE80211_QUEUE_STOP_REASON_CSA,
1120 false);
1121 mutex_unlock(&local->mtx); 1119 mutex_unlock(&local->mtx);
1122 1120
1123 if (local->ops->channel_switch) { 1121 if (local->ops->channel_switch) {
@@ -1833,11 +1831,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1833 ieee80211_vif_release_channel(sdata); 1831 ieee80211_vif_release_channel(sdata);
1834 1832
1835 sdata->vif.csa_active = false; 1833 sdata->vif.csa_active = false;
1836 if (!ieee80211_csa_needs_block_tx(local)) 1834 if (sdata->csa_block_tx) {
1837 ieee80211_wake_queues_by_reason(&local->hw, 1835 ieee80211_wake_vif_queues(local, sdata,
1838 IEEE80211_MAX_QUEUE_MAP, 1836 IEEE80211_QUEUE_STOP_REASON_CSA);
1839 IEEE80211_QUEUE_STOP_REASON_CSA, 1837 sdata->csa_block_tx = false;
1840 false); 1838 }
1841 mutex_unlock(&local->mtx); 1839 mutex_unlock(&local->mtx);
1842 1840
1843 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 1841 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
@@ -2083,11 +2081,11 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2083 2081
2084 mutex_lock(&local->mtx); 2082 mutex_lock(&local->mtx);
2085 sdata->vif.csa_active = false; 2083 sdata->vif.csa_active = false;
2086 if (!ieee80211_csa_needs_block_tx(local)) 2084 if (sdata->csa_block_tx) {
2087 ieee80211_wake_queues_by_reason(&local->hw, 2085 ieee80211_wake_vif_queues(local, sdata,
2088 IEEE80211_MAX_QUEUE_MAP, 2086 IEEE80211_QUEUE_STOP_REASON_CSA);
2089 IEEE80211_QUEUE_STOP_REASON_CSA, 2087 sdata->csa_block_tx = false;
2090 false); 2088 }
2091 mutex_unlock(&local->mtx); 2089 mutex_unlock(&local->mtx);
2092 2090
2093 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 2091 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,