Skip to content

Commit

Permalink
cfg80211: Expose TXQ stats and parameters to userspace
Browse files Browse the repository at this point in the history
This adds support for exporting the mac80211 TXQ stats via nl80211 by
way of a nested TXQ stats attribute, as well as for configuring the
quantum and limits that were previously only changeable through debugfs.

This commit adds just the nl80211 API, a subsequent commit adds support to
mac80211 itself.

Signed-off-by: Toke Høiland-Jørgensen <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
  • Loading branch information
tohojo authored and jmberg-intel committed May 8, 2018
1 parent cc60dbb commit 52539ca
Show file tree
Hide file tree
Showing 7 changed files with 343 additions and 48 deletions.
50 changes: 50 additions & 0 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,37 @@ struct sta_bss_parameters {
u16 beacon_interval;
};

/**
* struct cfg80211_txq_stats - TXQ statistics for this TID
* @filled: bitmap of flags using the bits of &enum nl80211_txq_stats to
* indicate the relevant values in this struct are filled
* @backlog_bytes: total number of bytes currently backlogged
* @backlog_packets: total number of packets currently backlogged
* @flows: number of new flows seen
* @drops: total number of packets dropped
* @ecn_marks: total number of packets marked with ECN CE
* @overlimit: number of drops due to queue space overflow
* @overmemory: number of drops due to memory limit overflow
* @collisions: number of hash collisions
* @tx_bytes: total number of bytes dequeued
* @tx_packets: total number of packets dequeued
* @max_flows: maximum number of flows supported
*/
struct cfg80211_txq_stats {
u32 filled;
u32 backlog_bytes;
u32 backlog_packets;
u32 flows;
u32 drops;
u32 ecn_marks;
u32 overlimit;
u32 overmemory;
u32 collisions;
u32 tx_bytes;
u32 tx_packets;
u32 max_flows;
};

/**
* struct cfg80211_tid_stats - per-TID statistics
* @filled: bitmap of flags using the bits of &enum nl80211_tid_stats to
Expand All @@ -1088,13 +1119,15 @@ struct sta_bss_parameters {
* @tx_msdu_retries: number of retries (not counting the first) for
* transmitted MSDUs
* @tx_msdu_failed: number of failed transmitted MSDUs
* @txq_stats: TXQ statistics
*/
struct cfg80211_tid_stats {
u32 filled;
u64 rx_msdu;
u64 tx_msdu;
u64 tx_msdu_retries;
u64 tx_msdu_failed;
struct cfg80211_txq_stats txq_stats;
};

#define IEEE80211_MAX_CHAINS 4
Expand Down Expand Up @@ -2204,6 +2237,9 @@ enum cfg80211_connect_params_changed {
* @WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed
* @WIPHY_PARAM_COVERAGE_CLASS: coverage class changed
* @WIPHY_PARAM_DYN_ACK: dynack has been enabled
* @WIPHY_PARAM_TXQ_LIMIT: TXQ packet limit has been changed
* @WIPHY_PARAM_TXQ_MEMORY_LIMIT: TXQ memory limit has been changed
* @WIPHY_PARAM_TXQ_QUANTUM: TXQ scheduler quantum
*/
enum wiphy_params_flags {
WIPHY_PARAM_RETRY_SHORT = 1 << 0,
Expand All @@ -2212,6 +2248,9 @@ enum wiphy_params_flags {
WIPHY_PARAM_RTS_THRESHOLD = 1 << 3,
WIPHY_PARAM_COVERAGE_CLASS = 1 << 4,
WIPHY_PARAM_DYN_ACK = 1 << 5,
WIPHY_PARAM_TXQ_LIMIT = 1 << 6,
WIPHY_PARAM_TXQ_MEMORY_LIMIT = 1 << 7,
WIPHY_PARAM_TXQ_QUANTUM = 1 << 8,
};

/**
Expand Down Expand Up @@ -2964,6 +3003,9 @@ struct cfg80211_external_auth_params {
*
* @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
*
* @get_txq_stats: Get TXQ stats for interface or phy. If wdev is %NULL, this
* function should return phy stats, and interface stats otherwise.
*
* @set_pmk: configure the PMK to be used for offloaded 802.1X 4-Way handshake.
* If not deleted through @del_pmk the PMK remains valid until disconnect
* upon which the driver should clear it.
Expand Down Expand Up @@ -3265,6 +3307,10 @@ struct cfg80211_ops {
struct net_device *dev,
const bool enabled);

int (*get_txq_stats)(struct wiphy *wiphy,
struct wireless_dev *wdev,
struct cfg80211_txq_stats *txqstats);

int (*set_pmk)(struct wiphy *wiphy, struct net_device *dev,
const struct cfg80211_pmk_conf *conf);
int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
Expand Down Expand Up @@ -3943,6 +3989,10 @@ struct wiphy {

u8 nan_supported_bands;

u32 txq_limit;
u32 txq_memory_limit;
u32 txq_quantum;

char priv[0] __aligned(NETDEV_ALIGN);
};

Expand Down
58 changes: 58 additions & 0 deletions include/uapi/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -2226,6 +2226,16 @@ enum nl80211_commands {
* @NL80211_ATTR_NSS: Station's New/updated RX_NSS value notified using this
* u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED.
*
* @NL80211_ATTR_TXQ_STATS: TXQ statistics (nested attribute, see &enum
* nl80211_txq_stats)
* @NL80211_ATTR_TXQ_LIMIT: Total packet limit for the TXQ queues for this phy.
* The smaller of this and the memory limit is enforced.
* @NL80211_ATTR_TXQ_MEMORY_LIMIT: Total memory memory limit (in bytes) for the
* TXQ queues for this phy. The smaller of this and the packet limit is
* enforced.
* @NL80211_ATTR_TXQ_QUANTUM: TXQ scheduler quantum (bytes). Number of bytes
* a flow is assigned on each round of the DRR scheduler.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
Expand Down Expand Up @@ -2660,6 +2670,11 @@ enum nl80211_attrs {

NL80211_ATTR_CONTROL_PORT_OVER_NL80211,

NL80211_ATTR_TXQ_STATS,
NL80211_ATTR_TXQ_LIMIT,
NL80211_ATTR_TXQ_MEMORY_LIMIT,
NL80211_ATTR_TXQ_QUANTUM,

/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
Expand Down Expand Up @@ -3040,6 +3055,7 @@ enum nl80211_sta_info {
* @NL80211_TID_STATS_TX_MSDU_FAILED: number of failed transmitted
* MSDUs (u64)
* @NL80211_TID_STATS_PAD: attribute used for padding for 64-bit alignment
* @NL80211_TID_STATS_TXQ_STATS: TXQ stats (nested attribute)
* @NUM_NL80211_TID_STATS: number of attributes here
* @NL80211_TID_STATS_MAX: highest numbered attribute here
*/
Expand All @@ -3050,12 +3066,51 @@ enum nl80211_tid_stats {
NL80211_TID_STATS_TX_MSDU_RETRIES,
NL80211_TID_STATS_TX_MSDU_FAILED,
NL80211_TID_STATS_PAD,
NL80211_TID_STATS_TXQ_STATS,

/* keep last */
NUM_NL80211_TID_STATS,
NL80211_TID_STATS_MAX = NUM_NL80211_TID_STATS - 1
};

/**
* enum nl80211_txq_stats - per TXQ statistics attributes
* @__NL80211_TXQ_STATS_INVALID: attribute number 0 is reserved
* @NUM_NL80211_TXQ_STATS: number of attributes here
* @NL80211_TXQ_STATS_BACKLOG_BYTES: number of bytes currently backlogged
* @NL80211_TXQ_STATS_BACKLOG_PACKETS: number of packets currently
* backlogged
* @NL80211_TXQ_STATS_FLOWS: total number of new flows seen
* @NL80211_TXQ_STATS_DROPS: total number of packet drops
* @NL80211_TXQ_STATS_ECN_MARKS: total number of packet ECN marks
* @NL80211_TXQ_STATS_OVERLIMIT: number of drops due to queue space overflow
* @NL80211_TXQ_STATS_OVERMEMORY: number of drops due to memory limit overflow
* (only for per-phy stats)
* @NL80211_TXQ_STATS_COLLISIONS: number of hash collisions
* @NL80211_TXQ_STATS_TX_BYTES: total number of bytes dequeued from TXQ
* @NL80211_TXQ_STATS_TX_PACKETS: total number of packets dequeued from TXQ
* @NL80211_TXQ_STATS_MAX_FLOWS: number of flow buckets for PHY
* @NL80211_TXQ_STATS_MAX: highest numbered attribute here
*/
enum nl80211_txq_stats {
__NL80211_TXQ_STATS_INVALID,
NL80211_TXQ_STATS_BACKLOG_BYTES,
NL80211_TXQ_STATS_BACKLOG_PACKETS,
NL80211_TXQ_STATS_FLOWS,
NL80211_TXQ_STATS_DROPS,
NL80211_TXQ_STATS_ECN_MARKS,
NL80211_TXQ_STATS_OVERLIMIT,
NL80211_TXQ_STATS_OVERMEMORY,
NL80211_TXQ_STATS_COLLISIONS,
NL80211_TXQ_STATS_TX_BYTES,
NL80211_TXQ_STATS_TX_PACKETS,
NL80211_TXQ_STATS_MAX_FLOWS,

/* keep last */
NUM_NL80211_TXQ_STATS,
NL80211_TXQ_STATS_MAX = NUM_NL80211_TXQ_STATS - 1
};

/**
* enum nl80211_mpath_flags - nl80211 mesh path flags
*
Expand Down Expand Up @@ -5072,6 +5127,8 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT: This Driver support data ack
* rssi if firmware support, this flag is to intimate about ack rssi
* support to nl80211.
* @NL80211_EXT_FEATURE_TXQS: Driver supports FQ-CoDel-enabled intermediate
* TXQs.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
Expand Down Expand Up @@ -5105,6 +5162,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_DFS_OFFLOAD,
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211,
NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT,
NL80211_EXT_FEATURE_TXQS,

/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
Expand Down
32 changes: 19 additions & 13 deletions net/mac80211/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,15 @@ static void ieee80211_get_stats(struct net_device *dev,
struct ieee80211_channel *channel;
struct sta_info *sta;
struct ieee80211_local *local = sdata->local;
struct station_info sinfo;
struct station_info *sinfo;
struct survey_info survey;
int i, q;
#define STA_STATS_SURVEY_LEN 7

sinfo = kmalloc(sizeof(*sinfo), GFP_KERNEL);
if (!sinfo)
return;

memset(data, 0, sizeof(u64) * STA_STATS_LEN);

#define ADD_STA_STATS(sta) \
Expand All @@ -86,8 +90,8 @@ static void ieee80211_get_stats(struct net_device *dev,
data[i++] += sta->rx_stats.fragments; \
data[i++] += sta->rx_stats.dropped; \
\
data[i++] += sinfo.tx_packets; \
data[i++] += sinfo.tx_bytes; \
data[i++] += sinfo->tx_packets; \
data[i++] += sinfo->tx_bytes; \
data[i++] += sta->status_stats.filtered; \
data[i++] += sta->status_stats.retry_failed; \
data[i++] += sta->status_stats.retry_count; \
Expand All @@ -107,41 +111,43 @@ static void ieee80211_get_stats(struct net_device *dev,
if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
goto do_survey;

memset(&sinfo, 0, sizeof(sinfo));
sta_set_sinfo(sta, &sinfo);
memset(sinfo, 0, sizeof(*sinfo));
sta_set_sinfo(sta, sinfo);

i = 0;
ADD_STA_STATS(sta);

data[i++] = sta->sta_state;


if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE))
if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE))
data[i] = 100000 *
cfg80211_calculate_bitrate(&sinfo.txrate);
cfg80211_calculate_bitrate(&sinfo->txrate);
i++;
if (sinfo.filled & BIT(NL80211_STA_INFO_RX_BITRATE))
if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE))
data[i] = 100000 *
cfg80211_calculate_bitrate(&sinfo.rxrate);
cfg80211_calculate_bitrate(&sinfo->rxrate);
i++;

if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL_AVG))
data[i] = (u8)sinfo.signal_avg;
if (sinfo->filled & BIT(NL80211_STA_INFO_SIGNAL_AVG))
data[i] = (u8)sinfo->signal_avg;
i++;
} else {
list_for_each_entry(sta, &local->sta_list, list) {
/* Make sure this station belongs to the proper dev */
if (sta->sdata->dev != dev)
continue;

memset(&sinfo, 0, sizeof(sinfo));
sta_set_sinfo(sta, &sinfo);
memset(sinfo, 0, sizeof(*sinfo));
sta_set_sinfo(sta, sinfo);
i = 0;
ADD_STA_STATS(sta);
}
}

do_survey:
kfree(sinfo);

i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
/* Get survey stats for current channel */
survey.filled = 0;
Expand Down
Loading

0 comments on commit 52539ca

Please sign in to comment.