diff options
-rw-r--r-- | net/mac80211/ieee80211_i.h | 10 | ||||
-rw-r--r-- | net/mac80211/rx.c | 7 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 32 | ||||
-rw-r--r-- | net/mac80211/util.c | 8 |
4 files changed, 25 insertions, 32 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3701930c6649..5e44e3179e02 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1692,14 +1692,8 @@ void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | |||
1692 | void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); | 1692 | void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); |
1693 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | 1693 | void ieee80211_add_pending_skb(struct ieee80211_local *local, |
1694 | struct sk_buff *skb); | 1694 | struct sk_buff *skb); |
1695 | void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | 1695 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, |
1696 | struct sk_buff_head *skbs, | 1696 | struct sk_buff_head *skbs); |
1697 | void (*fn)(void *data), void *data); | ||
1698 | static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local, | ||
1699 | struct sk_buff_head *skbs) | ||
1700 | { | ||
1701 | ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); | ||
1702 | } | ||
1703 | void ieee80211_flush_queues(struct ieee80211_local *local, | 1697 | void ieee80211_flush_queues(struct ieee80211_local *local, |
1704 | struct ieee80211_sub_if_data *sdata); | 1698 | struct ieee80211_sub_if_data *sdata); |
1705 | 1699 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c24ca0d0f469..3e57f96c9666 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1128,6 +1128,13 @@ static void sta_ps_end(struct sta_info *sta) | |||
1128 | sta->sta.addr, sta->sta.aid); | 1128 | sta->sta.addr, sta->sta.aid); |
1129 | 1129 | ||
1130 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | 1130 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
1131 | /* | ||
1132 | * Clear the flag only if the other one is still set | ||
1133 | * so that the TX path won't start TX'ing new frames | ||
1134 | * directly ... In the case that the driver flag isn't | ||
1135 | * set ieee80211_sta_ps_deliver_wakeup() will clear it. | ||
1136 | */ | ||
1137 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
1131 | ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", | 1138 | ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", |
1132 | sta->sta.addr, sta->sta.aid); | 1139 | sta->sta.addr, sta->sta.aid); |
1133 | return; | 1140 | return; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ffc1ee6a2ec1..a023b432143b 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -99,7 +99,8 @@ static void __cleanup_single_sta(struct sta_info *sta) | |||
99 | struct ieee80211_local *local = sdata->local; | 99 | struct ieee80211_local *local = sdata->local; |
100 | struct ps_data *ps; | 100 | struct ps_data *ps; |
101 | 101 | ||
102 | if (test_sta_flag(sta, WLAN_STA_PS_STA)) { | 102 | if (test_sta_flag(sta, WLAN_STA_PS_STA) || |
103 | test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | ||
103 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || | 104 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || |
104 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 105 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
105 | ps = &sdata->bss->ps; | 106 | ps = &sdata->bss->ps; |
@@ -109,6 +110,7 @@ static void __cleanup_single_sta(struct sta_info *sta) | |||
109 | return; | 110 | return; |
110 | 111 | ||
111 | clear_sta_flag(sta, WLAN_STA_PS_STA); | 112 | clear_sta_flag(sta, WLAN_STA_PS_STA); |
113 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
112 | 114 | ||
113 | atomic_dec(&ps->num_sta_ps); | 115 | atomic_dec(&ps->num_sta_ps); |
114 | sta_info_recalc_tim(sta); | 116 | sta_info_recalc_tim(sta); |
@@ -1090,10 +1092,14 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | |||
1090 | } | 1092 | } |
1091 | EXPORT_SYMBOL(ieee80211_find_sta); | 1093 | EXPORT_SYMBOL(ieee80211_find_sta); |
1092 | 1094 | ||
1093 | static void clear_sta_ps_flags(void *_sta) | 1095 | /* powersave support code */ |
1096 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | ||
1094 | { | 1097 | { |
1095 | struct sta_info *sta = _sta; | ||
1096 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 1098 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
1099 | struct ieee80211_local *local = sdata->local; | ||
1100 | struct sk_buff_head pending; | ||
1101 | int filtered = 0, buffered = 0, ac; | ||
1102 | unsigned long flags; | ||
1097 | struct ps_data *ps; | 1103 | struct ps_data *ps; |
1098 | 1104 | ||
1099 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 1105 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
@@ -1104,20 +1110,6 @@ static void clear_sta_ps_flags(void *_sta) | |||
1104 | else | 1110 | else |
1105 | return; | 1111 | return; |
1106 | 1112 | ||
1107 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
1108 | if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) | ||
1109 | atomic_dec(&ps->num_sta_ps); | ||
1110 | } | ||
1111 | |||
1112 | /* powersave support code */ | ||
1113 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | ||
1114 | { | ||
1115 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
1116 | struct ieee80211_local *local = sdata->local; | ||
1117 | struct sk_buff_head pending; | ||
1118 | int filtered = 0, buffered = 0, ac; | ||
1119 | unsigned long flags; | ||
1120 | |||
1121 | clear_sta_flag(sta, WLAN_STA_SP); | 1113 | clear_sta_flag(sta, WLAN_STA_SP); |
1122 | 1114 | ||
1123 | BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); | 1115 | BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); |
@@ -1148,9 +1140,13 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1148 | buffered += tmp - count; | 1140 | buffered += tmp - count; |
1149 | } | 1141 | } |
1150 | 1142 | ||
1151 | ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); | 1143 | ieee80211_add_pending_skbs(local, &pending); |
1144 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
1145 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
1152 | spin_unlock(&sta->ps_lock); | 1146 | spin_unlock(&sta->ps_lock); |
1153 | 1147 | ||
1148 | atomic_dec(&ps->num_sta_ps); | ||
1149 | |||
1154 | /* This station just woke up and isn't aware of our SMPS state */ | 1150 | /* This station just woke up and isn't aware of our SMPS state */ |
1155 | if (!ieee80211_smps_is_restrictive(sta->known_smps_mode, | 1151 | if (!ieee80211_smps_is_restrictive(sta->known_smps_mode, |
1156 | sdata->smps_mode) && | 1152 | sdata->smps_mode) && |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 1d1bb7084c05..b8700d417a9c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
435 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 435 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
436 | } | 436 | } |
437 | 437 | ||
438 | void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | 438 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, |
439 | struct sk_buff_head *skbs, | 439 | struct sk_buff_head *skbs) |
440 | void (*fn)(void *data), void *data) | ||
441 | { | 440 | { |
442 | struct ieee80211_hw *hw = &local->hw; | 441 | struct ieee80211_hw *hw = &local->hw; |
443 | struct sk_buff *skb; | 442 | struct sk_buff *skb; |
@@ -461,9 +460,6 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | |||
461 | __skb_queue_tail(&local->pending[queue], skb); | 460 | __skb_queue_tail(&local->pending[queue], skb); |
462 | } | 461 | } |
463 | 462 | ||
464 | if (fn) | ||
465 | fn(data); | ||
466 | |||
467 | for (i = 0; i < hw->queues; i++) | 463 | for (i = 0; i < hw->queues; i++) |
468 | __ieee80211_wake_queue(hw, i, | 464 | __ieee80211_wake_queue(hw, i, |
469 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | 465 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); |