summaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorToke Høiland-Jørgensen <toke@toke.dk>2018-05-08 07:03:50 -0400
committerJohannes Berg <johannes.berg@intel.com>2018-05-08 07:25:22 -0400
commit2fe4a29a452a68ffa8a501000d0ef8095c242eba (patch)
treedcd8e22b24297d6011262ea2ad6fc5b2ef593430 /net/mac80211
parent52539ca89f365d3db530535fbffa88a3cca4d2ec (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.c99
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/sta_info.c12
-rw-r--r--net/mac80211/tx.c20
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
3713void 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
3762static 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
3799out:
3800 rcu_read_unlock();
3801 spin_unlock_bh(&local->fq.lock);
3802
3803 return ret;
3804}
3805
3708const struct cfg80211_ops mac80211_config_ops = { 3806const 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
2014int ieee80211_txq_setup_flows(struct ieee80211_local *local); 2014int ieee80211_txq_setup_flows(struct ieee80211_local *local);
2015void ieee80211_txq_set_params(struct ieee80211_local *local);
2015void ieee80211_txq_teardown_flows(struct ieee80211_local *local); 2016void ieee80211_txq_teardown_flows(struct ieee80211_local *local);
2016void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, 2017void 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);
2021void ieee80211_txq_remove_vlan(struct ieee80211_local *local, 2022void ieee80211_txq_remove_vlan(struct ieee80211_local *local,
2022 struct ieee80211_sub_if_data *sdata); 2023 struct ieee80211_sub_if_data *sdata);
2024void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats,
2025 struct txq_info *txqi);
2023void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 2026void 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
2057static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats) 2069static 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
1462void 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
1462int ieee80211_txq_setup_flows(struct ieee80211_local *local) 1480int 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