diff options
author | Luciano Coelho <luciano.coelho@intel.com> | 2014-06-13 09:30:06 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-06-23 08:22:27 -0400 |
commit | 26da23b6950cd1aaae86caa541eb4befc9e96e1d (patch) | |
tree | 416747bf14a3c29d5a44300c474435335396f12d /net | |
parent | cca07b00a56d6ddd339e457dfd1a229222b9acf5 (diff) |
mac80211: add functions to stop and wake all queues assigned to a vif
In some cases we may want to stop the queues of a single vif (for
instance during a channel-switch). Add a function that stops all the
queues that are assigned to a vif. If a queue is assigned to more
than one vif, the corresponding netdev subqueue of the other vif(s)
will also be stopped. If the HW doesn't set the
IEEE80211_HW_QUEUE_CONTROL flag, then all queues are stopped.
Also add a corresponding function to wake the queues of a vif back.
Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 6 | ||||
-rw-r--r-- | net/mac80211/util.c | 41 |
2 files changed, 41 insertions, 6 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a0c7da809744..b202df2aebe8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1720,6 +1720,12 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | |||
1720 | unsigned long queues, | 1720 | unsigned long queues, |
1721 | enum queue_stop_reason reason, | 1721 | enum queue_stop_reason reason, |
1722 | bool refcounted); | 1722 | bool refcounted); |
1723 | void ieee80211_stop_vif_queues(struct ieee80211_local *local, | ||
1724 | struct ieee80211_sub_if_data *sdata, | ||
1725 | enum queue_stop_reason reason); | ||
1726 | void ieee80211_wake_vif_queues(struct ieee80211_local *local, | ||
1727 | struct ieee80211_sub_if_data *sdata, | ||
1728 | enum queue_stop_reason reason); | ||
1723 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 1729 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
1724 | unsigned long queues, | 1730 | unsigned long queues, |
1725 | enum queue_stop_reason reason, | 1731 | enum queue_stop_reason reason, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 4e8513cfdae5..42d448d765b4 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -552,13 +552,11 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw) | |||
552 | } | 552 | } |
553 | EXPORT_SYMBOL(ieee80211_wake_queues); | 553 | EXPORT_SYMBOL(ieee80211_wake_queues); |
554 | 554 | ||
555 | void ieee80211_flush_queues(struct ieee80211_local *local, | 555 | static unsigned int |
556 | struct ieee80211_sub_if_data *sdata) | 556 | ieee80211_get_vif_queues(struct ieee80211_local *local, |
557 | struct ieee80211_sub_if_data *sdata) | ||
557 | { | 558 | { |
558 | u32 queues; | 559 | unsigned int queues; |
559 | |||
560 | if (!local->ops->flush) | ||
561 | return; | ||
562 | 560 | ||
563 | if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) { | 561 | if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) { |
564 | int ac; | 562 | int ac; |
@@ -574,6 +572,19 @@ void ieee80211_flush_queues(struct ieee80211_local *local, | |||
574 | queues = BIT(local->hw.queues) - 1; | 572 | queues = BIT(local->hw.queues) - 1; |
575 | } | 573 | } |
576 | 574 | ||
575 | return queues; | ||
576 | } | ||
577 | |||
578 | void ieee80211_flush_queues(struct ieee80211_local *local, | ||
579 | struct ieee80211_sub_if_data *sdata) | ||
580 | { | ||
581 | unsigned int queues; | ||
582 | |||
583 | if (!local->ops->flush) | ||
584 | return; | ||
585 | |||
586 | queues = ieee80211_get_vif_queues(local, sdata); | ||
587 | |||
577 | ieee80211_stop_queues_by_reason(&local->hw, queues, | 588 | ieee80211_stop_queues_by_reason(&local->hw, queues, |
578 | IEEE80211_QUEUE_STOP_REASON_FLUSH, | 589 | IEEE80211_QUEUE_STOP_REASON_FLUSH, |
579 | false); | 590 | false); |
@@ -585,6 +596,24 @@ void ieee80211_flush_queues(struct ieee80211_local *local, | |||
585 | false); | 596 | false); |
586 | } | 597 | } |
587 | 598 | ||
599 | void ieee80211_stop_vif_queues(struct ieee80211_local *local, | ||
600 | struct ieee80211_sub_if_data *sdata, | ||
601 | enum queue_stop_reason reason) | ||
602 | { | ||
603 | ieee80211_stop_queues_by_reason(&local->hw, | ||
604 | ieee80211_get_vif_queues(local, sdata), | ||
605 | reason, true); | ||
606 | } | ||
607 | |||
608 | void ieee80211_wake_vif_queues(struct ieee80211_local *local, | ||
609 | struct ieee80211_sub_if_data *sdata, | ||
610 | enum queue_stop_reason reason) | ||
611 | { | ||
612 | ieee80211_wake_queues_by_reason(&local->hw, | ||
613 | ieee80211_get_vif_queues(local, sdata), | ||
614 | reason, true); | ||
615 | } | ||
616 | |||
588 | static void __iterate_active_interfaces(struct ieee80211_local *local, | 617 | static void __iterate_active_interfaces(struct ieee80211_local *local, |
589 | u32 iter_flags, | 618 | u32 iter_flags, |
590 | void (*iterator)(void *data, u8 *mac, | 619 | void (*iterator)(void *data, u8 *mac, |