aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Greear <greearb@candelatech.com>2014-10-22 15:22:58 -0400
committerJohannes Berg <johannes.berg@intel.com>2014-10-24 04:19:58 -0400
commit2155c3f82327bddd092bd704ebaff79c0a2dfb9c (patch)
treee6e5630b2cb7b883b7703f0798e929742de66dd8
parent0fc1e0495fd6e261e75acdbe66b53e769e5ffb81 (diff)
mac80211-hwsim: add ethtool stats support
This gives a view into packet activity at the virtual radio level. Signed-off-by: Ben Greear <greearb@candelatech.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c75
1 files changed, 74 insertions, 1 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 6ffe07323e6e..4e92a5b9324d 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -450,6 +450,14 @@ struct mac80211_hwsim_data {
450 s64 bcn_delta; 450 s64 bcn_delta;
451 /* absolute beacon transmission time. Used to cover up "tx" delay. */ 451 /* absolute beacon transmission time. Used to cover up "tx" delay. */
452 u64 abs_bcn_ts; 452 u64 abs_bcn_ts;
453
454 /* Stats */
455 u64 tx_pkts;
456 u64 rx_pkts;
457 u64 tx_bytes;
458 u64 rx_bytes;
459 u64 tx_dropped;
460 u64 tx_failed;
453}; 461};
454 462
455 463
@@ -865,8 +873,10 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
865 /* If the queue contains MAX_QUEUE skb's drop some */ 873 /* If the queue contains MAX_QUEUE skb's drop some */
866 if (skb_queue_len(&data->pending) >= MAX_QUEUE) { 874 if (skb_queue_len(&data->pending) >= MAX_QUEUE) {
867 /* Droping until WARN_QUEUE level */ 875 /* Droping until WARN_QUEUE level */
868 while (skb_queue_len(&data->pending) >= WARN_QUEUE) 876 while (skb_queue_len(&data->pending) >= WARN_QUEUE) {
869 ieee80211_free_txskb(hw, skb_dequeue(&data->pending)); 877 ieee80211_free_txskb(hw, skb_dequeue(&data->pending));
878 data->tx_dropped++;
879 }
870 } 880 }
871 881
872 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC); 882 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
@@ -921,11 +931,14 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
921 931
922 /* Enqueue the packet */ 932 /* Enqueue the packet */
923 skb_queue_tail(&data->pending, my_skb); 933 skb_queue_tail(&data->pending, my_skb);
934 data->tx_pkts++;
935 data->tx_bytes += my_skb->len;
924 return; 936 return;
925 937
926nla_put_failure: 938nla_put_failure:
927 printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); 939 printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
928 ieee80211_free_txskb(hw, my_skb); 940 ieee80211_free_txskb(hw, my_skb);
941 data->tx_failed++;
929} 942}
930 943
931static bool hwsim_chans_compat(struct ieee80211_channel *c1, 944static bool hwsim_chans_compat(struct ieee80211_channel *c1,
@@ -1071,6 +1084,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
1071 rx_status.mactime = now + data2->tsf_offset; 1084 rx_status.mactime = now + data2->tsf_offset;
1072 1085
1073 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); 1086 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
1087 data2->rx_pkts++;
1088 data2->rx_bytes += nskb->len;
1074 ieee80211_rx_irqsafe(data2->hw, nskb); 1089 ieee80211_rx_irqsafe(data2->hw, nskb);
1075 } 1090 }
1076 spin_unlock(&hwsim_radio_lock); 1091 spin_unlock(&hwsim_radio_lock);
@@ -1138,6 +1153,8 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
1138 return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); 1153 return mac80211_hwsim_tx_frame_nl(hw, skb, _portid);
1139 1154
1140 /* NO wmediumd detected, perfect medium simulation */ 1155 /* NO wmediumd detected, perfect medium simulation */
1156 data->tx_pkts++;
1157 data->tx_bytes += skb->len;
1141 ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel); 1158 ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel);
1142 1159
1143 if (ack && skb->len >= 16) { 1160 if (ack && skb->len >= 16) {
@@ -1921,6 +1938,57 @@ static void mac80211_hwsim_unassign_vif_chanctx(struct ieee80211_hw *hw,
1921 hwsim_check_chanctx_magic(ctx); 1938 hwsim_check_chanctx_magic(ctx);
1922} 1939}
1923 1940
1941static const char mac80211_hwsim_gstrings_stats[][ETH_GSTRING_LEN] = {
1942 "tx_pkts_nic",
1943 "tx_bytes_nic",
1944 "rx_pkts_nic",
1945 "rx_bytes_nic",
1946 "d_tx_dropped",
1947 "d_tx_failed",
1948 "d_ps_mode",
1949 "d_group",
1950 "d_tx_power",
1951};
1952
1953#define MAC80211_HWSIM_SSTATS_LEN ARRAY_SIZE(mac80211_hwsim_gstrings_stats)
1954
1955static void mac80211_hwsim_get_et_strings(struct ieee80211_hw *hw,
1956 struct ieee80211_vif *vif,
1957 u32 sset, u8 *data)
1958{
1959 if (sset == ETH_SS_STATS)
1960 memcpy(data, *mac80211_hwsim_gstrings_stats,
1961 sizeof(mac80211_hwsim_gstrings_stats));
1962}
1963
1964static int mac80211_hwsim_get_et_sset_count(struct ieee80211_hw *hw,
1965 struct ieee80211_vif *vif, int sset)
1966{
1967 if (sset == ETH_SS_STATS)
1968 return MAC80211_HWSIM_SSTATS_LEN;
1969 return 0;
1970}
1971
1972static void mac80211_hwsim_get_et_stats(struct ieee80211_hw *hw,
1973 struct ieee80211_vif *vif,
1974 struct ethtool_stats *stats, u64 *data)
1975{
1976 struct mac80211_hwsim_data *ar = hw->priv;
1977 int i = 0;
1978
1979 data[i++] = ar->tx_pkts;
1980 data[i++] = ar->tx_bytes;
1981 data[i++] = ar->rx_pkts;
1982 data[i++] = ar->rx_bytes;
1983 data[i++] = ar->tx_dropped;
1984 data[i++] = ar->tx_failed;
1985 data[i++] = ar->ps;
1986 data[i++] = ar->group;
1987 data[i++] = ar->power_level;
1988
1989 WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN);
1990}
1991
1924static const struct ieee80211_ops mac80211_hwsim_ops = { 1992static const struct ieee80211_ops mac80211_hwsim_ops = {
1925 .tx = mac80211_hwsim_tx, 1993 .tx = mac80211_hwsim_tx,
1926 .start = mac80211_hwsim_start, 1994 .start = mac80211_hwsim_start,
@@ -1944,6 +2012,9 @@ static const struct ieee80211_ops mac80211_hwsim_ops = {
1944 .flush = mac80211_hwsim_flush, 2012 .flush = mac80211_hwsim_flush,
1945 .get_tsf = mac80211_hwsim_get_tsf, 2013 .get_tsf = mac80211_hwsim_get_tsf,
1946 .set_tsf = mac80211_hwsim_set_tsf, 2014 .set_tsf = mac80211_hwsim_set_tsf,
2015 .get_et_sset_count = mac80211_hwsim_get_et_sset_count,
2016 .get_et_stats = mac80211_hwsim_get_et_stats,
2017 .get_et_strings = mac80211_hwsim_get_et_strings,
1947}; 2018};
1948 2019
1949static struct ieee80211_ops mac80211_hwsim_mchan_ops; 2020static struct ieee80211_ops mac80211_hwsim_mchan_ops;
@@ -2394,6 +2465,8 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
2394 rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); 2465 rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
2395 2466
2396 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); 2467 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
2468 data2->rx_pkts++;
2469 data2->rx_bytes += skb->len;
2397 ieee80211_rx_irqsafe(data2->hw, skb); 2470 ieee80211_rx_irqsafe(data2->hw, skb);
2398 2471
2399 return 0; 2472 return 0;