diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/agg-tx.c | 6 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 12 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 5 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 7 | ||||
-rw-r--r-- | net/mac80211/trace.h | 32 | ||||
-rw-r--r-- | net/mac80211/tx.c | 49 |
7 files changed, 73 insertions, 41 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 595c662a61e8..6c6cad98ce92 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -226,9 +226,13 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable) | |||
226 | clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags); | 226 | clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags); |
227 | 227 | ||
228 | clear_bit(IEEE80211_TXQ_STOP, &txqi->flags); | 228 | clear_bit(IEEE80211_TXQ_STOP, &txqi->flags); |
229 | |||
230 | if (!ieee80211_schedule_txq(&sta->sdata->local->hw, txq)) | ||
231 | return; | ||
232 | |||
229 | local_bh_disable(); | 233 | local_bh_disable(); |
230 | rcu_read_lock(); | 234 | rcu_read_lock(); |
231 | drv_wake_tx_queue(sta->sdata->local, txqi); | 235 | drv_wake_tx_queue(sta->sdata->local); |
232 | rcu_read_unlock(); | 236 | rcu_read_unlock(); |
233 | local_bh_enable(); | 237 | local_bh_enable(); |
234 | } | 238 | } |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index c7f93fd9ca7a..cdd76306cb8f 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -1158,16 +1158,10 @@ drv_tdls_recv_channel_switch(struct ieee80211_local *local, | |||
1158 | trace_drv_return_void(local); | 1158 | trace_drv_return_void(local); |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | static inline void drv_wake_tx_queue(struct ieee80211_local *local, | 1161 | static inline void drv_wake_tx_queue(struct ieee80211_local *local) |
1162 | struct txq_info *txq) | ||
1163 | { | 1162 | { |
1164 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); | 1163 | trace_drv_wake_tx_queue(local); |
1165 | 1164 | local->ops->wake_tx_queue(&local->hw); | |
1166 | if (!check_sdata_in_driver(sdata)) | ||
1167 | return; | ||
1168 | |||
1169 | trace_drv_wake_tx_queue(local, sdata, txq); | ||
1170 | local->ops->wake_tx_queue(&local->hw, &txq->txq); | ||
1171 | } | 1165 | } |
1172 | 1166 | ||
1173 | static inline int drv_start_nan(struct ieee80211_local *local, | 1167 | static inline int drv_start_nan(struct ieee80211_local *local, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 26900025de2f..4155838c7bef 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -832,6 +832,7 @@ struct txq_info { | |||
832 | struct codel_vars def_cvars; | 832 | struct codel_vars def_cvars; |
833 | struct codel_stats cstats; | 833 | struct codel_stats cstats; |
834 | struct sk_buff_head frags; | 834 | struct sk_buff_head frags; |
835 | struct list_head schedule_order; | ||
835 | unsigned long flags; | 836 | unsigned long flags; |
836 | 837 | ||
837 | /* keep last! */ | 838 | /* keep last! */ |
@@ -1122,6 +1123,10 @@ struct ieee80211_local { | |||
1122 | struct codel_vars *cvars; | 1123 | struct codel_vars *cvars; |
1123 | struct codel_params cparams; | 1124 | struct codel_params cparams; |
1124 | 1125 | ||
1126 | /* protects active_txqs and txqi->schedule_order */ | ||
1127 | spinlock_t active_txq_lock; | ||
1128 | struct list_head active_txqs; | ||
1129 | |||
1125 | const struct ieee80211_ops *ops; | 1130 | const struct ieee80211_ops *ops; |
1126 | 1131 | ||
1127 | /* | 1132 | /* |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0785d04a80bc..935d6e2491b1 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -619,6 +619,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, | |||
619 | spin_lock_init(&local->rx_path_lock); | 619 | spin_lock_init(&local->rx_path_lock); |
620 | spin_lock_init(&local->queue_stop_reason_lock); | 620 | spin_lock_init(&local->queue_stop_reason_lock); |
621 | 621 | ||
622 | INIT_LIST_HEAD(&local->active_txqs); | ||
623 | spin_lock_init(&local->active_txq_lock); | ||
624 | |||
622 | INIT_LIST_HEAD(&local->chanctx_list); | 625 | INIT_LIST_HEAD(&local->chanctx_list); |
623 | mutex_init(&local->chanctx_mtx); | 626 | mutex_init(&local->chanctx_mtx); |
624 | 627 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 0c5627f8a104..e0bcf16df494 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1237,12 +1237,17 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1237 | drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); | 1237 | drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); |
1238 | 1238 | ||
1239 | if (sta->sta.txq[0]) { | 1239 | if (sta->sta.txq[0]) { |
1240 | bool wake = false; | ||
1241 | |||
1240 | for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { | 1242 | for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { |
1241 | if (!txq_has_queue(sta->sta.txq[i])) | 1243 | if (!txq_has_queue(sta->sta.txq[i])) |
1242 | continue; | 1244 | continue; |
1243 | 1245 | ||
1244 | drv_wake_tx_queue(local, to_txq_info(sta->sta.txq[i])); | 1246 | if (ieee80211_schedule_txq(&local->hw, sta->sta.txq[i])) |
1247 | wake = true; | ||
1245 | } | 1248 | } |
1249 | if (wake) | ||
1250 | drv_wake_tx_queue(local); | ||
1246 | } | 1251 | } |
1247 | 1252 | ||
1248 | skb_queue_head_init(&pending); | 1253 | skb_queue_head_init(&pending); |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 591ad02e1fa4..08eaad85942e 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -2550,35 +2550,9 @@ TRACE_EVENT(drv_tdls_recv_channel_switch, | |||
2550 | ) | 2550 | ) |
2551 | ); | 2551 | ); |
2552 | 2552 | ||
2553 | TRACE_EVENT(drv_wake_tx_queue, | 2553 | DEFINE_EVENT(local_only_evt, drv_wake_tx_queue, |
2554 | TP_PROTO(struct ieee80211_local *local, | 2554 | TP_PROTO(struct ieee80211_local *local), |
2555 | struct ieee80211_sub_if_data *sdata, | 2555 | TP_ARGS(local) |
2556 | struct txq_info *txq), | ||
2557 | |||
2558 | TP_ARGS(local, sdata, txq), | ||
2559 | |||
2560 | TP_STRUCT__entry( | ||
2561 | LOCAL_ENTRY | ||
2562 | VIF_ENTRY | ||
2563 | STA_ENTRY | ||
2564 | __field(u8, ac) | ||
2565 | __field(u8, tid) | ||
2566 | ), | ||
2567 | |||
2568 | TP_fast_assign( | ||
2569 | struct ieee80211_sta *sta = txq->txq.sta; | ||
2570 | |||
2571 | LOCAL_ASSIGN; | ||
2572 | VIF_ASSIGN; | ||
2573 | STA_ASSIGN; | ||
2574 | __entry->ac = txq->txq.ac; | ||
2575 | __entry->tid = txq->txq.tid; | ||
2576 | ), | ||
2577 | |||
2578 | TP_printk( | ||
2579 | LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " ac:%d tid:%d", | ||
2580 | LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->ac, __entry->tid | ||
2581 | ) | ||
2582 | ); | 2556 | ); |
2583 | 2557 | ||
2584 | #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ | 2558 | #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 25904af38839..842881ca8f20 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1439,6 +1439,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, | |||
1439 | codel_vars_init(&txqi->def_cvars); | 1439 | codel_vars_init(&txqi->def_cvars); |
1440 | codel_stats_init(&txqi->cstats); | 1440 | codel_stats_init(&txqi->cstats); |
1441 | __skb_queue_head_init(&txqi->frags); | 1441 | __skb_queue_head_init(&txqi->frags); |
1442 | INIT_LIST_HEAD(&txqi->schedule_order); | ||
1442 | 1443 | ||
1443 | txqi->txq.vif = &sdata->vif; | 1444 | txqi->txq.vif = &sdata->vif; |
1444 | 1445 | ||
@@ -1462,6 +1463,7 @@ void ieee80211_txq_purge(struct ieee80211_local *local, | |||
1462 | 1463 | ||
1463 | fq_tin_reset(fq, tin, fq_skb_free_func); | 1464 | fq_tin_reset(fq, tin, fq_skb_free_func); |
1464 | ieee80211_purge_tx_queue(&local->hw, &txqi->frags); | 1465 | ieee80211_purge_tx_queue(&local->hw, &txqi->frags); |
1466 | list_del_init(&txqi->schedule_order); | ||
1465 | } | 1467 | } |
1466 | 1468 | ||
1467 | int ieee80211_txq_setup_flows(struct ieee80211_local *local) | 1469 | int ieee80211_txq_setup_flows(struct ieee80211_local *local) |
@@ -1558,7 +1560,8 @@ static bool ieee80211_queue_skb(struct ieee80211_local *local, | |||
1558 | ieee80211_txq_enqueue(local, txqi, skb); | 1560 | ieee80211_txq_enqueue(local, txqi, skb); |
1559 | spin_unlock_bh(&fq->lock); | 1561 | spin_unlock_bh(&fq->lock); |
1560 | 1562 | ||
1561 | drv_wake_tx_queue(local, txqi); | 1563 | if (ieee80211_schedule_txq(&local->hw, &txqi->txq)) |
1564 | drv_wake_tx_queue(local); | ||
1562 | 1565 | ||
1563 | return true; | 1566 | return true; |
1564 | } | 1567 | } |
@@ -3553,6 +3556,50 @@ out: | |||
3553 | } | 3556 | } |
3554 | EXPORT_SYMBOL(ieee80211_tx_dequeue); | 3557 | EXPORT_SYMBOL(ieee80211_tx_dequeue); |
3555 | 3558 | ||
3559 | bool ieee80211_schedule_txq(struct ieee80211_hw *hw, | ||
3560 | struct ieee80211_txq *txq) | ||
3561 | { | ||
3562 | struct ieee80211_local *local = hw_to_local(hw); | ||
3563 | struct txq_info *txqi = to_txq_info(txq); | ||
3564 | bool ret = false; | ||
3565 | |||
3566 | spin_lock_bh(&local->active_txq_lock); | ||
3567 | |||
3568 | if (list_empty(&txqi->schedule_order)) { | ||
3569 | list_add_tail(&txqi->schedule_order, &local->active_txqs); | ||
3570 | ret = true; | ||
3571 | } | ||
3572 | |||
3573 | spin_unlock_bh(&local->active_txq_lock); | ||
3574 | |||
3575 | return ret; | ||
3576 | } | ||
3577 | EXPORT_SYMBOL(ieee80211_schedule_txq); | ||
3578 | |||
3579 | struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw) | ||
3580 | { | ||
3581 | struct ieee80211_local *local = hw_to_local(hw); | ||
3582 | struct txq_info *txqi = NULL; | ||
3583 | |||
3584 | spin_lock_bh(&local->active_txq_lock); | ||
3585 | |||
3586 | if (list_empty(&local->active_txqs)) | ||
3587 | goto out; | ||
3588 | |||
3589 | txqi = list_first_entry(&local->active_txqs, | ||
3590 | struct txq_info, schedule_order); | ||
3591 | list_del_init(&txqi->schedule_order); | ||
3592 | |||
3593 | out: | ||
3594 | spin_unlock_bh(&local->active_txq_lock); | ||
3595 | |||
3596 | if (!txqi) | ||
3597 | return NULL; | ||
3598 | |||
3599 | return &txqi->txq; | ||
3600 | } | ||
3601 | EXPORT_SYMBOL(ieee80211_next_txq); | ||
3602 | |||
3556 | void __ieee80211_subif_start_xmit(struct sk_buff *skb, | 3603 | void __ieee80211_subif_start_xmit(struct sk_buff *skb, |
3557 | struct net_device *dev, | 3604 | struct net_device *dev, |
3558 | u32 info_flags) | 3605 | u32 info_flags) |