aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/agg-tx.c8
-rw-r--r--net/mac80211/cfg.c9
-rw-r--r--net/mac80211/ieee80211_i.h15
-rw-r--r--net/mac80211/iface.c3
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mlme.c15
-rw-r--r--net/mac80211/offchannel.c6
-rw-r--r--net/mac80211/pm.c6
-rw-r--r--net/mac80211/tx.c3
-rw-r--r--net/mac80211/util.c76
10 files changed, 98 insertions, 46 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index ce9633a3cfb0..d6986f3aa5c4 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -170,10 +170,13 @@ ieee80211_stop_queue_agg(struct ieee80211_sub_if_data *sdata, int tid)
170{ 170{
171 int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)]; 171 int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)];
172 172
173 /* we do refcounting here, so don't use the queue reason refcounting */
174
173 if (atomic_inc_return(&sdata->local->agg_queue_stop[queue]) == 1) 175 if (atomic_inc_return(&sdata->local->agg_queue_stop[queue]) == 1)
174 ieee80211_stop_queue_by_reason( 176 ieee80211_stop_queue_by_reason(
175 &sdata->local->hw, queue, 177 &sdata->local->hw, queue,
176 IEEE80211_QUEUE_STOP_REASON_AGGREGATION); 178 IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
179 false);
177 __acquire(agg_queue); 180 __acquire(agg_queue);
178} 181}
179 182
@@ -185,7 +188,8 @@ ieee80211_wake_queue_agg(struct ieee80211_sub_if_data *sdata, int tid)
185 if (atomic_dec_return(&sdata->local->agg_queue_stop[queue]) == 0) 188 if (atomic_dec_return(&sdata->local->agg_queue_stop[queue]) == 0)
186 ieee80211_wake_queue_by_reason( 189 ieee80211_wake_queue_by_reason(
187 &sdata->local->hw, queue, 190 &sdata->local->hw, queue,
188 IEEE80211_QUEUE_STOP_REASON_AGGREGATION); 191 IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
192 false);
189 __release(agg_queue); 193 __release(agg_queue);
190} 194}
191 195
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index af3eac482acd..e920d48f0209 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -837,7 +837,8 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
837 if (!ieee80211_csa_needs_block_tx(local)) 837 if (!ieee80211_csa_needs_block_tx(local))
838 ieee80211_wake_queues_by_reason(&local->hw, 838 ieee80211_wake_queues_by_reason(&local->hw,
839 IEEE80211_MAX_QUEUE_MAP, 839 IEEE80211_MAX_QUEUE_MAP,
840 IEEE80211_QUEUE_STOP_REASON_CSA); 840 IEEE80211_QUEUE_STOP_REASON_CSA,
841 false);
841 mutex_unlock(&local->mtx); 842 mutex_unlock(&local->mtx);
842 843
843 kfree(sdata->u.ap.next_beacon); 844 kfree(sdata->u.ap.next_beacon);
@@ -2828,7 +2829,8 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2828 if (!ieee80211_csa_needs_block_tx(local)) 2829 if (!ieee80211_csa_needs_block_tx(local))
2829 ieee80211_wake_queues_by_reason(&local->hw, 2830 ieee80211_wake_queues_by_reason(&local->hw,
2830 IEEE80211_MAX_QUEUE_MAP, 2831 IEEE80211_MAX_QUEUE_MAP,
2831 IEEE80211_QUEUE_STOP_REASON_CSA); 2832 IEEE80211_QUEUE_STOP_REASON_CSA,
2833 false);
2832 2834
2833 return 0; 2835 return 0;
2834} 2836}
@@ -3060,7 +3062,8 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3060 if (sdata->csa_block_tx) 3062 if (sdata->csa_block_tx)
3061 ieee80211_stop_queues_by_reason(&local->hw, 3063 ieee80211_stop_queues_by_reason(&local->hw,
3062 IEEE80211_MAX_QUEUE_MAP, 3064 IEEE80211_MAX_QUEUE_MAP,
3063 IEEE80211_QUEUE_STOP_REASON_CSA); 3065 IEEE80211_QUEUE_STOP_REASON_CSA,
3066 false);
3064 3067
3065 if (changed) { 3068 if (changed) {
3066 ieee80211_bss_info_change_notify(sdata, changed); 3069 ieee80211_bss_info_change_notify(sdata, changed);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d9af7ef3c11a..a0c7da809744 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -922,6 +922,8 @@ enum queue_stop_reason {
922 IEEE80211_QUEUE_STOP_REASON_SKB_ADD, 922 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
923 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, 923 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
924 IEEE80211_QUEUE_STOP_REASON_FLUSH, 924 IEEE80211_QUEUE_STOP_REASON_FLUSH,
925
926 IEEE80211_QUEUE_STOP_REASONS,
925}; 927};
926 928
927#ifdef CONFIG_MAC80211_LEDS 929#ifdef CONFIG_MAC80211_LEDS
@@ -1018,6 +1020,7 @@ struct ieee80211_local {
1018 struct workqueue_struct *workqueue; 1020 struct workqueue_struct *workqueue;
1019 1021
1020 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; 1022 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
1023 int q_stop_reasons[IEEE80211_MAX_QUEUES][IEEE80211_QUEUE_STOP_REASONS];
1021 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ 1024 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
1022 spinlock_t queue_stop_reason_lock; 1025 spinlock_t queue_stop_reason_lock;
1023 1026
@@ -1715,14 +1718,18 @@ void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1715 1718
1716void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1719void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1717 unsigned long queues, 1720 unsigned long queues,
1718 enum queue_stop_reason reason); 1721 enum queue_stop_reason reason,
1722 bool refcounted);
1719void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 1723void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
1720 unsigned long queues, 1724 unsigned long queues,
1721 enum queue_stop_reason reason); 1725 enum queue_stop_reason reason,
1726 bool refcounted);
1722void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 1727void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
1723 enum queue_stop_reason reason); 1728 enum queue_stop_reason reason,
1729 bool refcounted);
1724void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 1730void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
1725 enum queue_stop_reason reason); 1731 enum queue_stop_reason reason,
1732 bool refcounted);
1726void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); 1733void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue);
1727void ieee80211_add_pending_skb(struct ieee80211_local *local, 1734void ieee80211_add_pending_skb(struct ieee80211_local *local,
1728 struct sk_buff *skb); 1735 struct sk_buff *skb);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index db5afc7faa22..1971d2418d44 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -844,7 +844,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
844 if (!ieee80211_csa_needs_block_tx(local)) 844 if (!ieee80211_csa_needs_block_tx(local))
845 ieee80211_wake_queues_by_reason(&local->hw, 845 ieee80211_wake_queues_by_reason(&local->hw,
846 IEEE80211_MAX_QUEUE_MAP, 846 IEEE80211_MAX_QUEUE_MAP,
847 IEEE80211_QUEUE_STOP_REASON_CSA); 847 IEEE80211_QUEUE_STOP_REASON_CSA,
848 false);
848 mutex_unlock(&local->mtx); 849 mutex_unlock(&local->mtx);
849 sdata_unlock(sdata); 850 sdata_unlock(sdata);
850 851
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0512a5096f0f..e0ab4320a078 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -272,7 +272,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
272 272
273 /* use this reason, ieee80211_reconfig will unblock it */ 273 /* use this reason, ieee80211_reconfig will unblock it */
274 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 274 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
275 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 275 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
276 false);
276 277
277 /* 278 /*
278 * Stop all Rx during the reconfig. We don't want state changes 279 * Stop all Rx during the reconfig. We don't want state changes
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 3345401be1b3..1ab1884eddbf 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -983,7 +983,8 @@ static void ieee80211_chswitch_work(struct work_struct *work)
983 if (!ieee80211_csa_needs_block_tx(local)) 983 if (!ieee80211_csa_needs_block_tx(local))
984 ieee80211_wake_queues_by_reason(&local->hw, 984 ieee80211_wake_queues_by_reason(&local->hw,
985 IEEE80211_MAX_QUEUE_MAP, 985 IEEE80211_MAX_QUEUE_MAP,
986 IEEE80211_QUEUE_STOP_REASON_CSA); 986 IEEE80211_QUEUE_STOP_REASON_CSA,
987 false);
987 mutex_unlock(&local->mtx); 988 mutex_unlock(&local->mtx);
988 989
989 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 990 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
@@ -1115,7 +1116,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1115 if (sdata->csa_block_tx) 1116 if (sdata->csa_block_tx)
1116 ieee80211_stop_queues_by_reason(&local->hw, 1117 ieee80211_stop_queues_by_reason(&local->hw,
1117 IEEE80211_MAX_QUEUE_MAP, 1118 IEEE80211_MAX_QUEUE_MAP,
1118 IEEE80211_QUEUE_STOP_REASON_CSA); 1119 IEEE80211_QUEUE_STOP_REASON_CSA,
1120 false);
1119 mutex_unlock(&local->mtx); 1121 mutex_unlock(&local->mtx);
1120 1122
1121 if (local->ops->channel_switch) { 1123 if (local->ops->channel_switch) {
@@ -1385,7 +1387,8 @@ void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
1385 1387
1386 ieee80211_wake_queues_by_reason(&local->hw, 1388 ieee80211_wake_queues_by_reason(&local->hw,
1387 IEEE80211_MAX_QUEUE_MAP, 1389 IEEE80211_MAX_QUEUE_MAP,
1388 IEEE80211_QUEUE_STOP_REASON_PS); 1390 IEEE80211_QUEUE_STOP_REASON_PS,
1391 false);
1389} 1392}
1390 1393
1391void ieee80211_dynamic_ps_enable_work(struct work_struct *work) 1394void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
@@ -1833,7 +1836,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1833 if (!ieee80211_csa_needs_block_tx(local)) 1836 if (!ieee80211_csa_needs_block_tx(local))
1834 ieee80211_wake_queues_by_reason(&local->hw, 1837 ieee80211_wake_queues_by_reason(&local->hw,
1835 IEEE80211_MAX_QUEUE_MAP, 1838 IEEE80211_MAX_QUEUE_MAP,
1836 IEEE80211_QUEUE_STOP_REASON_CSA); 1839 IEEE80211_QUEUE_STOP_REASON_CSA,
1840 false);
1837 mutex_unlock(&local->mtx); 1841 mutex_unlock(&local->mtx);
1838 1842
1839 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 1843 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
@@ -2082,7 +2086,8 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2082 if (!ieee80211_csa_needs_block_tx(local)) 2086 if (!ieee80211_csa_needs_block_tx(local))
2083 ieee80211_wake_queues_by_reason(&local->hw, 2087 ieee80211_wake_queues_by_reason(&local->hw,
2084 IEEE80211_MAX_QUEUE_MAP, 2088 IEEE80211_MAX_QUEUE_MAP,
2085 IEEE80211_QUEUE_STOP_REASON_CSA); 2089 IEEE80211_QUEUE_STOP_REASON_CSA,
2090 false);
2086 mutex_unlock(&local->mtx); 2091 mutex_unlock(&local->mtx);
2087 2092
2088 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 2093 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 7a17decd27f9..ff20b2ebdb30 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -119,7 +119,8 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
119 * before sending nullfunc to enable powersave at the AP. 119 * before sending nullfunc to enable powersave at the AP.
120 */ 120 */
121 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, 121 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); 122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
123 false);
123 ieee80211_flush_queues(local, NULL); 124 ieee80211_flush_queues(local, NULL);
124 125
125 mutex_lock(&local->iflist_mtx); 126 mutex_lock(&local->iflist_mtx);
@@ -182,7 +183,8 @@ void ieee80211_offchannel_return(struct ieee80211_local *local)
182 mutex_unlock(&local->iflist_mtx); 183 mutex_unlock(&local->iflist_mtx);
183 184
184 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, 185 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
185 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); 186 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
187 false);
186} 188}
187 189
188void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) 190void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index d478b880a0af..4c5192e0d66c 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -35,7 +35,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
35 35
36 ieee80211_stop_queues_by_reason(hw, 36 ieee80211_stop_queues_by_reason(hw,
37 IEEE80211_MAX_QUEUE_MAP, 37 IEEE80211_MAX_QUEUE_MAP,
38 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 38 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
39 false);
39 40
40 /* flush out all packets */ 41 /* flush out all packets */
41 synchronize_net(); 42 synchronize_net();
@@ -74,7 +75,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
74 } 75 }
75 ieee80211_wake_queues_by_reason(hw, 76 ieee80211_wake_queues_by_reason(hw,
76 IEEE80211_MAX_QUEUE_MAP, 77 IEEE80211_MAX_QUEUE_MAP,
77 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 78 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
79 false);
78 return err; 80 return err;
79 } else if (err > 0) { 81 } else if (err > 0) {
80 WARN_ON(err != 1); 82 WARN_ON(err != 1);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 9b3d94e7c4be..f6018178f33c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -250,7 +250,8 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
250 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 250 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
251 ieee80211_stop_queues_by_reason(&local->hw, 251 ieee80211_stop_queues_by_reason(&local->hw,
252 IEEE80211_MAX_QUEUE_MAP, 252 IEEE80211_MAX_QUEUE_MAP,
253 IEEE80211_QUEUE_STOP_REASON_PS); 253 IEEE80211_QUEUE_STOP_REASON_PS,
254 false);
254 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 255 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
255 ieee80211_queue_work(&local->hw, 256 ieee80211_queue_work(&local->hw,
256 &local->dynamic_ps_disable_work); 257 &local->dynamic_ps_disable_work);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 6d29e40538ad..4e8513cfdae5 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -317,7 +317,8 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
317} 317}
318 318
319static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, 319static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
320 enum queue_stop_reason reason) 320 enum queue_stop_reason reason,
321 bool refcounted)
321{ 322{
322 struct ieee80211_local *local = hw_to_local(hw); 323 struct ieee80211_local *local = hw_to_local(hw);
323 324
@@ -329,7 +330,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
329 if (!test_bit(reason, &local->queue_stop_reasons[queue])) 330 if (!test_bit(reason, &local->queue_stop_reasons[queue]))
330 return; 331 return;
331 332
332 __clear_bit(reason, &local->queue_stop_reasons[queue]); 333 if (!refcounted)
334 local->q_stop_reasons[queue][reason] = 0;
335 else
336 local->q_stop_reasons[queue][reason]--;
337
338 if (local->q_stop_reasons[queue][reason] == 0)
339 __clear_bit(reason, &local->queue_stop_reasons[queue]);
333 340
334 if (local->queue_stop_reasons[queue] != 0) 341 if (local->queue_stop_reasons[queue] != 0)
335 /* someone still has this queue stopped */ 342 /* someone still has this queue stopped */
@@ -344,25 +351,28 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
344} 351}
345 352
346void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 353void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
347 enum queue_stop_reason reason) 354 enum queue_stop_reason reason,
355 bool refcounted)
348{ 356{
349 struct ieee80211_local *local = hw_to_local(hw); 357 struct ieee80211_local *local = hw_to_local(hw);
350 unsigned long flags; 358 unsigned long flags;
351 359
352 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 360 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
353 __ieee80211_wake_queue(hw, queue, reason); 361 __ieee80211_wake_queue(hw, queue, reason, refcounted);
354 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 362 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
355} 363}
356 364
357void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) 365void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
358{ 366{
359 ieee80211_wake_queue_by_reason(hw, queue, 367 ieee80211_wake_queue_by_reason(hw, queue,
360 IEEE80211_QUEUE_STOP_REASON_DRIVER); 368 IEEE80211_QUEUE_STOP_REASON_DRIVER,
369 false);
361} 370}
362EXPORT_SYMBOL(ieee80211_wake_queue); 371EXPORT_SYMBOL(ieee80211_wake_queue);
363 372
364static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, 373static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
365 enum queue_stop_reason reason) 374 enum queue_stop_reason reason,
375 bool refcounted)
366{ 376{
367 struct ieee80211_local *local = hw_to_local(hw); 377 struct ieee80211_local *local = hw_to_local(hw);
368 struct ieee80211_sub_if_data *sdata; 378 struct ieee80211_sub_if_data *sdata;
@@ -373,10 +383,13 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
373 if (WARN_ON(queue >= hw->queues)) 383 if (WARN_ON(queue >= hw->queues))
374 return; 384 return;
375 385
376 if (test_bit(reason, &local->queue_stop_reasons[queue])) 386 if (!refcounted)
377 return; 387 local->q_stop_reasons[queue][reason] = 1;
388 else
389 local->q_stop_reasons[queue][reason]++;
378 390
379 __set_bit(reason, &local->queue_stop_reasons[queue]); 391 if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue]))
392 return;
380 393
381 if (local->hw.queues < IEEE80211_NUM_ACS) 394 if (local->hw.queues < IEEE80211_NUM_ACS)
382 n_acs = 1; 395 n_acs = 1;
@@ -398,20 +411,22 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
398} 411}
399 412
400void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 413void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
401 enum queue_stop_reason reason) 414 enum queue_stop_reason reason,
415 bool refcounted)
402{ 416{
403 struct ieee80211_local *local = hw_to_local(hw); 417 struct ieee80211_local *local = hw_to_local(hw);
404 unsigned long flags; 418 unsigned long flags;
405 419
406 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 420 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
407 __ieee80211_stop_queue(hw, queue, reason); 421 __ieee80211_stop_queue(hw, queue, reason, refcounted);
408 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 422 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
409} 423}
410 424
411void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) 425void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
412{ 426{
413 ieee80211_stop_queue_by_reason(hw, queue, 427 ieee80211_stop_queue_by_reason(hw, queue,
414 IEEE80211_QUEUE_STOP_REASON_DRIVER); 428 IEEE80211_QUEUE_STOP_REASON_DRIVER,
429 false);
415} 430}
416EXPORT_SYMBOL(ieee80211_stop_queue); 431EXPORT_SYMBOL(ieee80211_stop_queue);
417 432
@@ -429,9 +444,11 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
429 } 444 }
430 445
431 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 446 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
432 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 447 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
448 false);
433 __skb_queue_tail(&local->pending[queue], skb); 449 __skb_queue_tail(&local->pending[queue], skb);
434 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 450 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
451 false);
435 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 452 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
436} 453}
437 454
@@ -455,20 +472,23 @@ void ieee80211_add_pending_skbs(struct ieee80211_local *local,
455 queue = info->hw_queue; 472 queue = info->hw_queue;
456 473
457 __ieee80211_stop_queue(hw, queue, 474 __ieee80211_stop_queue(hw, queue,
458 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 475 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
476 false);
459 477
460 __skb_queue_tail(&local->pending[queue], skb); 478 __skb_queue_tail(&local->pending[queue], skb);
461 } 479 }
462 480
463 for (i = 0; i < hw->queues; i++) 481 for (i = 0; i < hw->queues; i++)
464 __ieee80211_wake_queue(hw, i, 482 __ieee80211_wake_queue(hw, i,
465 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 483 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
484 false);
466 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 485 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
467} 486}
468 487
469void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 488void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
470 unsigned long queues, 489 unsigned long queues,
471 enum queue_stop_reason reason) 490 enum queue_stop_reason reason,
491 bool refcounted)
472{ 492{
473 struct ieee80211_local *local = hw_to_local(hw); 493 struct ieee80211_local *local = hw_to_local(hw);
474 unsigned long flags; 494 unsigned long flags;
@@ -477,7 +497,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
477 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 497 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
478 498
479 for_each_set_bit(i, &queues, hw->queues) 499 for_each_set_bit(i, &queues, hw->queues)
480 __ieee80211_stop_queue(hw, i, reason); 500 __ieee80211_stop_queue(hw, i, reason, refcounted);
481 501
482 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 502 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
483} 503}
@@ -485,7 +505,8 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
485void ieee80211_stop_queues(struct ieee80211_hw *hw) 505void ieee80211_stop_queues(struct ieee80211_hw *hw)
486{ 506{
487 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 507 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
488 IEEE80211_QUEUE_STOP_REASON_DRIVER); 508 IEEE80211_QUEUE_STOP_REASON_DRIVER,
509 false);
489} 510}
490EXPORT_SYMBOL(ieee80211_stop_queues); 511EXPORT_SYMBOL(ieee80211_stop_queues);
491 512
@@ -508,7 +529,8 @@ EXPORT_SYMBOL(ieee80211_queue_stopped);
508 529
509void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 530void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
510 unsigned long queues, 531 unsigned long queues,
511 enum queue_stop_reason reason) 532 enum queue_stop_reason reason,
533 bool refcounted)
512{ 534{
513 struct ieee80211_local *local = hw_to_local(hw); 535 struct ieee80211_local *local = hw_to_local(hw);
514 unsigned long flags; 536 unsigned long flags;
@@ -517,7 +539,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
517 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 539 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
518 540
519 for_each_set_bit(i, &queues, hw->queues) 541 for_each_set_bit(i, &queues, hw->queues)
520 __ieee80211_wake_queue(hw, i, reason); 542 __ieee80211_wake_queue(hw, i, reason, refcounted);
521 543
522 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 544 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
523} 545}
@@ -525,7 +547,8 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
525void ieee80211_wake_queues(struct ieee80211_hw *hw) 547void ieee80211_wake_queues(struct ieee80211_hw *hw)
526{ 548{
527 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 549 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
528 IEEE80211_QUEUE_STOP_REASON_DRIVER); 550 IEEE80211_QUEUE_STOP_REASON_DRIVER,
551 false);
529} 552}
530EXPORT_SYMBOL(ieee80211_wake_queues); 553EXPORT_SYMBOL(ieee80211_wake_queues);
531 554
@@ -552,12 +575,14 @@ void ieee80211_flush_queues(struct ieee80211_local *local,
552 } 575 }
553 576
554 ieee80211_stop_queues_by_reason(&local->hw, queues, 577 ieee80211_stop_queues_by_reason(&local->hw, queues,
555 IEEE80211_QUEUE_STOP_REASON_FLUSH); 578 IEEE80211_QUEUE_STOP_REASON_FLUSH,
579 false);
556 580
557 drv_flush(local, sdata, queues, false); 581 drv_flush(local, sdata, queues, false);
558 582
559 ieee80211_wake_queues_by_reason(&local->hw, queues, 583 ieee80211_wake_queues_by_reason(&local->hw, queues,
560 IEEE80211_QUEUE_STOP_REASON_FLUSH); 584 IEEE80211_QUEUE_STOP_REASON_FLUSH,
585 false);
561} 586}
562 587
563static void __iterate_active_interfaces(struct ieee80211_local *local, 588static void __iterate_active_interfaces(struct ieee80211_local *local,
@@ -1797,7 +1822,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1797 } 1822 }
1798 1823
1799 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 1824 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
1800 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1825 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
1826 false);
1801 1827
1802 /* 1828 /*
1803 * Reconfigure sched scan if it was interrupted by FW restart or 1829 * Reconfigure sched scan if it was interrupted by FW restart or