diff options
author | Toke Høiland-Jørgensen <toke@toke.dk> | 2018-05-08 07:03:50 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2018-05-08 07:25:22 -0400 |
commit | 2fe4a29a452a68ffa8a501000d0ef8095c242eba (patch) | |
tree | dcd8e22b24297d6011262ea2ad6fc5b2ef593430 /net/mac80211 | |
parent | 52539ca89f365d3db530535fbffa88a3cca4d2ec (diff) |
mac80211: Support the new cfg80211 TXQ stats API
This adds support to mac80211 to export TXQ stats via the newly added
cfg80211 API.
Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 99 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 12 | ||||
-rw-r--r-- | net/mac80211/tx.c | 20 |
5 files changed, 137 insertions, 0 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 85dbaa891059..5ce9d121af2b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2376,6 +2376,11 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
2376 | (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG)) | 2376 | (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG)) |
2377 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); | 2377 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); |
2378 | 2378 | ||
2379 | if (changed & (WIPHY_PARAM_TXQ_LIMIT | | ||
2380 | WIPHY_PARAM_TXQ_MEMORY_LIMIT | | ||
2381 | WIPHY_PARAM_TXQ_QUANTUM)) | ||
2382 | ieee80211_txq_set_params(local); | ||
2383 | |||
2379 | return 0; | 2384 | return 0; |
2380 | } | 2385 | } |
2381 | 2386 | ||
@@ -3705,6 +3710,99 @@ static int ieee80211_set_multicast_to_unicast(struct wiphy *wiphy, | |||
3705 | return 0; | 3710 | return 0; |
3706 | } | 3711 | } |
3707 | 3712 | ||
3713 | void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats, | ||
3714 | struct txq_info *txqi) | ||
3715 | { | ||
3716 | if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_BACKLOG_BYTES))) { | ||
3717 | txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_BYTES); | ||
3718 | txqstats->backlog_bytes = txqi->tin.backlog_bytes; | ||
3719 | } | ||
3720 | |||
3721 | if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS))) { | ||
3722 | txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS); | ||
3723 | txqstats->backlog_packets = txqi->tin.backlog_packets; | ||
3724 | } | ||
3725 | |||
3726 | if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_FLOWS))) { | ||
3727 | txqstats->filled |= BIT(NL80211_TXQ_STATS_FLOWS); | ||
3728 | txqstats->flows = txqi->tin.flows; | ||
3729 | } | ||
3730 | |||
3731 | if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_DROPS))) { | ||
3732 | txqstats->filled |= BIT(NL80211_TXQ_STATS_DROPS); | ||
3733 | txqstats->drops = txqi->cstats.drop_count; | ||
3734 | } | ||
3735 | |||
3736 | if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_ECN_MARKS))) { | ||
3737 | txqstats->filled |= BIT(NL80211_TXQ_STATS_ECN_MARKS); | ||
3738 | txqstats->ecn_marks = txqi->cstats.ecn_mark; | ||
3739 | } | ||
3740 | |||
3741 | if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_OVERLIMIT))) { | ||
3742 | txqstats->filled |= BIT(NL80211_TXQ_STATS_OVERLIMIT); | ||
3743 | txqstats->overlimit = txqi->tin.overlimit; | ||
3744 | } | ||
3745 | |||
3746 | if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_COLLISIONS))) { | ||
3747 | txqstats->filled |= BIT(NL80211_TXQ_STATS_COLLISIONS); | ||
3748 | txqstats->collisions = txqi->tin.collisions; | ||
3749 | } | ||
3750 | |||
3751 | if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_TX_BYTES))) { | ||
3752 | txqstats->filled |= BIT(NL80211_TXQ_STATS_TX_BYTES); | ||
3753 | txqstats->tx_bytes = txqi->tin.tx_bytes; | ||
3754 | } | ||
3755 | |||
3756 | if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_TX_PACKETS))) { | ||
3757 | txqstats->filled |= BIT(NL80211_TXQ_STATS_TX_PACKETS); | ||
3758 | txqstats->tx_packets = txqi->tin.tx_packets; | ||
3759 | } | ||
3760 | } | ||
3761 | |||
3762 | static int ieee80211_get_txq_stats(struct wiphy *wiphy, | ||
3763 | struct wireless_dev *wdev, | ||
3764 | struct cfg80211_txq_stats *txqstats) | ||
3765 | { | ||
3766 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
3767 | struct ieee80211_sub_if_data *sdata; | ||
3768 | int ret = 0; | ||
3769 | |||
3770 | if (!local->ops->wake_tx_queue) | ||
3771 | return 1; | ||
3772 | |||
3773 | spin_lock_bh(&local->fq.lock); | ||
3774 | rcu_read_lock(); | ||
3775 | |||
3776 | if (wdev) { | ||
3777 | sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | ||
3778 | if (!sdata->vif.txq) { | ||
3779 | ret = 1; | ||
3780 | goto out; | ||
3781 | } | ||
3782 | ieee80211_fill_txq_stats(txqstats, to_txq_info(sdata->vif.txq)); | ||
3783 | } else { | ||
3784 | /* phy stats */ | ||
3785 | txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS) | | ||
3786 | BIT(NL80211_TXQ_STATS_BACKLOG_BYTES) | | ||
3787 | BIT(NL80211_TXQ_STATS_OVERLIMIT) | | ||
3788 | BIT(NL80211_TXQ_STATS_OVERMEMORY) | | ||
3789 | BIT(NL80211_TXQ_STATS_COLLISIONS) | | ||
3790 | BIT(NL80211_TXQ_STATS_MAX_FLOWS); | ||
3791 | txqstats->backlog_packets = local->fq.backlog; | ||
3792 | txqstats->backlog_bytes = local->fq.memory_usage; | ||
3793 | txqstats->overlimit = local->fq.overlimit; | ||
3794 | txqstats->overmemory = local->fq.overmemory; | ||
3795 | txqstats->collisions = local->fq.collisions; | ||
3796 | txqstats->max_flows = local->fq.flows_cnt; | ||
3797 | } | ||
3798 | |||
3799 | out: | ||
3800 | rcu_read_unlock(); | ||
3801 | spin_unlock_bh(&local->fq.lock); | ||
3802 | |||
3803 | return ret; | ||
3804 | } | ||
3805 | |||
3708 | const struct cfg80211_ops mac80211_config_ops = { | 3806 | const struct cfg80211_ops mac80211_config_ops = { |
3709 | .add_virtual_intf = ieee80211_add_iface, | 3807 | .add_virtual_intf = ieee80211_add_iface, |
3710 | .del_virtual_intf = ieee80211_del_iface, | 3808 | .del_virtual_intf = ieee80211_del_iface, |
@@ -3798,4 +3896,5 @@ const struct cfg80211_ops mac80211_config_ops = { | |||
3798 | .del_nan_func = ieee80211_del_nan_func, | 3896 | .del_nan_func = ieee80211_del_nan_func, |
3799 | .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast, | 3897 | .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast, |
3800 | .tx_control_port = ieee80211_tx_control_port, | 3898 | .tx_control_port = ieee80211_tx_control_port, |
3899 | .get_txq_stats = ieee80211_get_txq_stats, | ||
3801 | }; | 3900 | }; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6372dbdadf53..d1978aa1c15d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -2012,6 +2012,7 @@ static inline bool ieee80211_can_run_worker(struct ieee80211_local *local) | |||
2012 | } | 2012 | } |
2013 | 2013 | ||
2014 | int ieee80211_txq_setup_flows(struct ieee80211_local *local); | 2014 | int ieee80211_txq_setup_flows(struct ieee80211_local *local); |
2015 | void ieee80211_txq_set_params(struct ieee80211_local *local); | ||
2015 | void ieee80211_txq_teardown_flows(struct ieee80211_local *local); | 2016 | void ieee80211_txq_teardown_flows(struct ieee80211_local *local); |
2016 | void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, | 2017 | void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, |
2017 | struct sta_info *sta, | 2018 | struct sta_info *sta, |
@@ -2020,6 +2021,8 @@ void ieee80211_txq_purge(struct ieee80211_local *local, | |||
2020 | struct txq_info *txqi); | 2021 | struct txq_info *txqi); |
2021 | void ieee80211_txq_remove_vlan(struct ieee80211_local *local, | 2022 | void ieee80211_txq_remove_vlan(struct ieee80211_local *local, |
2022 | struct ieee80211_sub_if_data *sdata); | 2023 | struct ieee80211_sub_if_data *sdata); |
2024 | void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats, | ||
2025 | struct txq_info *txqi); | ||
2023 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 2026 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
2024 | u16 transaction, u16 auth_alg, u16 status, | 2027 | u16 transaction, u16 auth_alg, u16 status, |
2025 | const u8 *extra, size_t extra_len, const u8 *bssid, | 2028 | const u8 *extra, size_t extra_len, const u8 *bssid, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 9ea17afaa237..4d2e797e3f16 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -565,6 +565,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, | |||
565 | if (!ops->set_key) | 565 | if (!ops->set_key) |
566 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 566 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
567 | 567 | ||
568 | if (ops->wake_tx_queue) | ||
569 | wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS); | ||
570 | |||
568 | wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM); | 571 | wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM); |
569 | 572 | ||
570 | wiphy->bss_priv_size = sizeof(struct ieee80211_bss); | 573 | wiphy->bss_priv_size = sizeof(struct ieee80211_bss); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index f83e6e2ad5ab..43f34aa873bc 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -2052,6 +2052,18 @@ static void sta_set_tidstats(struct sta_info *sta, | |||
2052 | tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_FAILED); | 2052 | tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_FAILED); |
2053 | tidstats->tx_msdu_failed = sta->status_stats.msdu_failed[tid]; | 2053 | tidstats->tx_msdu_failed = sta->status_stats.msdu_failed[tid]; |
2054 | } | 2054 | } |
2055 | |||
2056 | if (local->ops->wake_tx_queue && tid < IEEE80211_NUM_TIDS) { | ||
2057 | spin_lock_bh(&local->fq.lock); | ||
2058 | rcu_read_lock(); | ||
2059 | |||
2060 | tidstats->filled |= BIT(NL80211_TID_STATS_TXQ_STATS); | ||
2061 | ieee80211_fill_txq_stats(&tidstats->txq_stats, | ||
2062 | to_txq_info(sta->sta.txq[tid])); | ||
2063 | |||
2064 | rcu_read_unlock(); | ||
2065 | spin_unlock_bh(&local->fq.lock); | ||
2066 | } | ||
2055 | } | 2067 | } |
2056 | 2068 | ||
2057 | static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats) | 2069 | static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats) |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 062e125a324c..8275a58450b2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1459,6 +1459,24 @@ void ieee80211_txq_purge(struct ieee80211_local *local, | |||
1459 | ieee80211_purge_tx_queue(&local->hw, &txqi->frags); | 1459 | ieee80211_purge_tx_queue(&local->hw, &txqi->frags); |
1460 | } | 1460 | } |
1461 | 1461 | ||
1462 | void ieee80211_txq_set_params(struct ieee80211_local *local) | ||
1463 | { | ||
1464 | if (local->hw.wiphy->txq_limit) | ||
1465 | local->fq.limit = local->hw.wiphy->txq_limit; | ||
1466 | else | ||
1467 | local->hw.wiphy->txq_limit = local->fq.limit; | ||
1468 | |||
1469 | if (local->hw.wiphy->txq_memory_limit) | ||
1470 | local->fq.memory_limit = local->hw.wiphy->txq_memory_limit; | ||
1471 | else | ||
1472 | local->hw.wiphy->txq_memory_limit = local->fq.memory_limit; | ||
1473 | |||
1474 | if (local->hw.wiphy->txq_quantum) | ||
1475 | local->fq.quantum = local->hw.wiphy->txq_quantum; | ||
1476 | else | ||
1477 | local->hw.wiphy->txq_quantum = local->fq.quantum; | ||
1478 | } | ||
1479 | |||
1462 | int ieee80211_txq_setup_flows(struct ieee80211_local *local) | 1480 | int ieee80211_txq_setup_flows(struct ieee80211_local *local) |
1463 | { | 1481 | { |
1464 | struct fq *fq = &local->fq; | 1482 | struct fq *fq = &local->fq; |
@@ -1508,6 +1526,8 @@ int ieee80211_txq_setup_flows(struct ieee80211_local *local) | |||
1508 | for (i = 0; i < fq->flows_cnt; i++) | 1526 | for (i = 0; i < fq->flows_cnt; i++) |
1509 | codel_vars_init(&local->cvars[i]); | 1527 | codel_vars_init(&local->cvars[i]); |
1510 | 1528 | ||
1529 | ieee80211_txq_set_params(local); | ||
1530 | |||
1511 | return 0; | 1531 | return 0; |
1512 | } | 1532 | } |
1513 | 1533 | ||