[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190128234507.32028-12-jakub.kicinski@netronome.com>
Date: Mon, 28 Jan 2019 15:45:04 -0800
From: Jakub Kicinski <jakub.kicinski@...ronome.com>
To: davem@...emloft.net
Cc: oss-drivers@...ronome.com, netdev@...r.kernel.org,
jiri@...nulli.us, f.fainelli@...il.com, andrew@...n.ch,
mkubecek@...e.cz, dsahern@...il.com, simon.horman@...ronome.com,
jesse.brandeburg@...el.com, maciejromanfijalkowski@...il.com,
vasundhara-v.volam@...adcom.com, michael.chan@...adcom.com,
shalomt@...lanox.com, idosch@...lanox.com,
Jakub Kicinski <jakub.kicinski@...ronome.com>
Subject: [RFC 11/14] nfp: hstats: add IEEE/RMON ethernet port/MAC stats
Add groups for MAC statistics, NFP's MAC/PHY maintains a mix
of IEEE 802.3 and RMON-compatible statistics. Use the RMON
stats for driver drops and error counters as well.
Since the MAC stats are quite large initialize the hstat
bitmap when driver is loaded.
Signed-off-by: Jakub Kicinski <jakub.kicinski@...ronome.com>
---
.../net/ethernet/netronome/nfp/nfp_hstat.c | 257 +++++++++++++++++-
drivers/net/ethernet/netronome/nfp/nfp_main.c | 1 +
drivers/net/ethernet/netronome/nfp/nfp_main.h | 2 +
3 files changed, 257 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_hstat.c b/drivers/net/ethernet/netronome/nfp/nfp_hstat.c
index 9300996e756c..cd97cd2676f6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_hstat.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_hstat.c
@@ -4,6 +4,217 @@
#include <net/hstats.h>
#include "nfp_net.h"
+#include "nfp_port.h"
+
+/* MAC stats */
+static const struct nfp_stat_pair {
+ u32 attr;
+ u32 offset;
+} nfp_mac_stats_rx[] = {
+ {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsOctets,
+ NFP_MAC_STATS_RX_IN_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_IEEE8023_FrameTooLongErrors,
+ NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS
+ }, {
+ IFLA_HSTATS_STAT_IEEE8023_InRangeLengthErrors,
+ NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS
+ },
+ /* missing NFP_MAC_STATS_RX_VLAN_RECEIVED_OK, no standard counter */
+ {
+ IFLA_HSTATS_STAT_RFC2863_Errors,
+ NFP_MAC_STATS_RX_IN_ERRORS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsBroadcastPkts,
+ NFP_MAC_STATS_RX_IN_BROADCAST_PKTS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsDropEvents,
+ NFP_MAC_STATS_RX_DROP_EVENTS
+ }, {
+ IFLA_HSTATS_STAT_IEEE8023_AlignmentErrors,
+ NFP_MAC_STATS_RX_ALIGNMENT_ERRORS
+ }, {
+ IFLA_HSTATS_STAT_IEEE8023_PAUSEMACCtrlFrames,
+ NFP_MAC_STATS_RX_PAUSE_MAC_CTRL_FRAMES
+ }, {
+ IFLA_HSTATS_STAT_IEEE8023_FramesOK,
+ NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK
+ }, {
+ IFLA_HSTATS_STAT_IEEE8023_FrameCheckSequenceErrors,
+ NFP_MAC_STATS_RX_FRAME_CHECK_SEQUENCE_ERRORS
+ }, {
+ IFLA_HSTATS_STAT_RFC2863_UcastPkts,
+ NFP_MAC_STATS_RX_UNICAST_PKTS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsMulticastPkts,
+ NFP_MAC_STATS_RX_MULTICAST_PKTS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts,
+ NFP_MAC_STATS_RX_PKTS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsUndersizePkts,
+ NFP_MAC_STATS_RX_UNDERSIZE_PKTS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts64Octets,
+ NFP_MAC_STATS_RX_PKTS_64_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts65to127Octets,
+ NFP_MAC_STATS_RX_PKTS_65_TO_127_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts512to1023Octets,
+ NFP_MAC_STATS_RX_PKTS_512_TO_1023_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts1024to1518Octets,
+ NFP_MAC_STATS_RX_PKTS_1024_TO_1518_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsJabbers,
+ NFP_MAC_STATS_RX_JABBERS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsFragments,
+ NFP_MAC_STATS_RX_FRAGMENTS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts128to255Octets,
+ NFP_MAC_STATS_RX_PKTS_128_TO_255_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts256to511Octets,
+ NFP_MAC_STATS_RX_PKTS_256_TO_511_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819EXT_etherStatsPkts1519toMaxOctets,
+ NFP_MAC_STATS_RX_PKTS_1519_TO_MAX_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsOversizePkts,
+ NFP_MAC_STATS_RX_OVERSIZE_PKTS
+ }, {
+ IFLA_HSTATS_STAT_IEEE8023_MACControlFrames,
+ NFP_MAC_STATS_RX_MAC_CTRL_FRAMES_RECEIVED
+ }
+}, nfp_mac_stats_tx[] = {
+ {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsOctets,
+ NFP_MAC_STATS_TX_OUT_OCTETS
+ },
+ /* missing NFP_MAC_STATS_TX_VLAN_TRANSMITTED_OK, no standard counter */
+ {
+ IFLA_HSTATS_STAT_RFC2863_Errors,
+ NFP_MAC_STATS_TX_OUT_ERRORS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsBroadcastPkts,
+ NFP_MAC_STATS_TX_BROADCAST_PKTS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts64Octets,
+ NFP_MAC_STATS_TX_PKTS_64_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts256to511Octets,
+ NFP_MAC_STATS_TX_PKTS_256_TO_511_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts512to1023Octets,
+ NFP_MAC_STATS_TX_PKTS_512_TO_1023_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_IEEE8023_PAUSEMACCtrlFrames,
+ NFP_MAC_STATS_TX_PAUSE_MAC_CTRL_FRAMES
+ }, {
+ IFLA_HSTATS_STAT_IEEE8023_FramesOK,
+ NFP_MAC_STATS_TX_FRAMES_TRANSMITTED_OK
+ }, {
+ IFLA_HSTATS_STAT_RFC2863_UcastPkts,
+ NFP_MAC_STATS_TX_UNICAST_PKTS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsMulticastPkts,
+ NFP_MAC_STATS_TX_MULTICAST_PKTS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts65to127Octets,
+ NFP_MAC_STATS_TX_PKTS_65_TO_127_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts128to255Octets,
+ NFP_MAC_STATS_TX_PKTS_128_TO_255_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819_etherStatsPkts1024to1518Octets,
+ NFP_MAC_STATS_TX_PKTS_1024_TO_1518_OCTETS
+ }, {
+ IFLA_HSTATS_STAT_RFC2819EXT_etherStatsPkts1519toMaxOctets,
+ NFP_MAC_STATS_TX_PKTS_1519_TO_MAX_OCTETS
+ }
+};
+
+static int
+nfp_hstat_mac_get(struct net_device *netdev, struct rtnl_hstat_req *req,
+ const struct rtnl_hstat_group *grp)
+{
+ const struct nfp_stat_pair *pairs;
+ struct nfp_port *port;
+ unsigned int dir, i;
+
+ port = nfp_port_from_netdev(netdev);
+ if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
+ return -EINVAL;
+
+ dir = rtnl_hstat_qual_get(req, RTNL_HSTATS_QUAL_DIRECTION);
+ pairs = dir == IFLA_HSTATS_QUAL_DIR_RX ?
+ nfp_mac_stats_rx : nfp_mac_stats_tx;
+
+ for (i = 0; i < grp->stats_cnt; i++)
+ rtnl_hstat_dump(req, pairs[i].attr,
+ readq(port->eth_stats + pairs[i].offset));
+ return 0;
+}
+
+static struct rtnl_hstat_group nfp_hstat_mac_rx __ro_after_init = {
+ .qualifiers = {
+ RTNL_HSTATS_QUALS_BASIC(DEV, RX),
+ },
+
+ .get_stats = nfp_hstat_mac_get,
+};
+
+static struct rtnl_hstat_group nfp_hstat_mac_tx __ro_after_init = {
+ .qualifiers = {
+ RTNL_HSTATS_QUALS_BASIC(DEV, TX),
+ },
+
+ .get_stats = nfp_hstat_mac_get,
+};
+
+static const struct rtnl_hstat_group nfp_hstat_mac = {
+ .has_children = true,
+ .children = {
+ &nfp_hstat_mac_rx,
+ &nfp_hstat_mac_tx,
+ NULL,
+ },
+};
+
+static int
+nfp_hstat_mac_head_drop(struct net_device *netdev, struct rtnl_hstat_req *req,
+ const struct rtnl_hstat_group *grp)
+{
+ struct nfp_port *port;
+ unsigned int off, dir;
+
+ port = nfp_port_from_netdev(netdev);
+ if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
+ return -EINVAL;
+
+ dir = rtnl_hstat_qual_get(req, RTNL_HSTATS_QUAL_DIRECTION);
+ off = dir == IFLA_HSTATS_QUAL_DIR_RX ?
+ NFP_MAC_STATS_RX_MAC_HEAD_DROP : NFP_MAC_STATS_TX_QUEUE_DROP;
+
+ rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2819_etherStatsDropEvents,
+ readq(port->eth_stats + off));
+ return 0;
+}
+
+static const struct rtnl_hstat_group nfp_hstat_tm = {
+ .qualifiers = {
+ RTNL_HSTATS_QUALS_BASIC_BIDIR(DEV),
+ },
+
+ .get_stats = nfp_hstat_mac_head_drop,
+ .stats = {
+ [1] = RTNL_HSTATS_STAT_RFC2819_etherStatsDropEvents_BIT,
+ },
+ .stats_cnt = 1,
+};
/* NFD per-vNIC stats */
static int
@@ -21,6 +232,10 @@ nfp_hstat_vnic_nfd_basic_get(struct net_device *netdev,
nn_readq(nn, NFP_NET_CFG_STATS_RX_FRAMES + off));
rtnl_hstat_dump(req, IFLA_HSTATS_STAT_LINUX_BYTES,
nn_readq(nn, NFP_NET_CFG_STATS_RX_OCTETS + off));
+ rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2863_Errors,
+ nn_readq(nn, NFP_NET_CFG_STATS_RX_ERRORS + off));
+ rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2863_Discards,
+ nn_readq(nn, NFP_NET_CFG_STATS_RX_DISCARDS + off));
return 0;
}
@@ -33,8 +248,10 @@ static const struct rtnl_hstat_group nfp_hstat_vnic_nfd = {
.stats = {
[0] = RTNL_HSTATS_STAT_LINUX_PKTS_BIT |
RTNL_HSTATS_STAT_LINUX_BYTES_BIT,
+ [2] = RTNL_HSTATS_STAT_RFC2863_Errors_BIT |
+ RTNL_HSTATS_STAT_RFC2863_Discards_BIT,
},
- .stats_cnt = 2,
+ .stats_cnt = 4,
};
/* NFD per-Q stats */
@@ -99,6 +316,8 @@ nfp_hstat_vnic_sw_rx_get(struct net_device *dev, struct rtnl_hstat_req *req,
r_vec->hw_csum_rx_complete);
rtnl_hstat_dump(req, IFLA_HSTATS_STAT_LINUX_CSUM_UNNECESSARY,
r_vec->hw_csum_rx_ok + r_vec->hw_csum_rx_inner_ok);
+ rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2819_etherStatsDropEvents,
+ r_vec->rx_drops);
return 0;
}
@@ -116,9 +335,10 @@ static const struct rtnl_hstat_group nfp_hstat_vnic_sw_rx = {
RTNL_HSTATS_STAT_LINUX_BYTES_BIT |
RTNL_HSTATS_STAT_LINUX_CSUM_PARTIAL_BIT |
RTNL_HSTATS_STAT_LINUX_CSUM_UNNECESSARY_BIT,
+ [1] = RTNL_HSTATS_STAT_RFC2819_etherStatsDropEvents_BIT,
},
- .stats_cnt = 4,
+ .stats_cnt = 5,
};
static int
@@ -137,6 +357,7 @@ nfp_hstat_vnic_sw_tx_get(struct net_device *dev, struct rtnl_hstat_req *req,
r_vec->hw_csum_tx + r_vec->hw_csum_tx_inner);
rtnl_hstat_dump(req, IFLA_HSTATS_STAT_LINUX_SEGMENTATION_OFFLOAD_PKTS,
r_vec->tx_lso);
+ rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2863_Errors, r_vec->tx_errors);
return 0;
}
@@ -155,8 +376,9 @@ static const struct rtnl_hstat_group nfp_hstat_vnic_sw_tx = {
RTNL_HSTATS_STAT_LINUX_BUSY_BIT |
RTNL_HSTATS_STAT_LINUX_CSUM_PARTIAL_BIT |
RTNL_HSTATS_STAT_LINUX_SEGMENTATION_OFFLOAD_PKTS_BIT,
+ [1] = RTNL_HSTATS_STAT_RFC2863_Errors_BIT,
},
- .stats_cnt = 5,
+ .stats_cnt = 6,
};
static const struct rtnl_hstat_group nfp_hstat_vnic_sw = {
@@ -171,9 +393,38 @@ static const struct rtnl_hstat_group nfp_hstat_vnic_sw = {
int nfp_net_hstat_get_groups(const struct net_device *netdev,
struct rtnl_hstat_req *req)
{
+ struct nfp_port *port;
+
rtnl_hstat_add_grp(req, &nfp_hstat_vnic_sw);
rtnl_hstat_add_grp(req, &nfp_hstat_vnic_nfd_pq);
rtnl_hstat_add_grp(req, &nfp_hstat_vnic_nfd);
+ port = nfp_port_from_netdev(netdev);
+ if (__nfp_port_get_eth_port(port) && port->eth_stats) {
+ rtnl_hstat_add_grp(req, &nfp_hstat_tm);
+ rtnl_hstat_add_grp(req, &nfp_hstat_mac);
+ }
+
return 0;
}
+
+void __init nfp_net_hstat_init(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(nfp_mac_stats_rx); i++) {
+ unsigned int attr;
+
+ attr = nfp_mac_stats_rx[i].attr;
+ nfp_hstat_mac_rx.stats[attr / 64] |= BIT_ULL(attr % 64);
+ }
+ nfp_hstat_mac_rx.stats_cnt = ARRAY_SIZE(nfp_mac_stats_rx);
+
+ for (i = 0; i < ARRAY_SIZE(nfp_mac_stats_tx); i++) {
+ unsigned int attr;
+
+ attr = nfp_mac_stats_tx[i].attr;
+ nfp_hstat_mac_tx.stats[attr / 64] |= BIT_ULL(attr % 64);
+ }
+ nfp_hstat_mac_tx.stats_cnt = ARRAY_SIZE(nfp_mac_stats_tx);
+}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index 6c10e8d119e4..4e366fde3478 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -724,6 +724,7 @@ static int __init nfp_main_init(void)
nfp_driver_name);
nfp_net_debugfs_create();
+ nfp_net_hstat_init();
err = pci_register_driver(&nfp_pci_driver);
if (err < 0)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.h b/drivers/net/ethernet/netronome/nfp/nfp_main.h
index a3613a2e0aa5..367afb869df6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.h
@@ -145,6 +145,8 @@ extern struct pci_driver nfp_netvf_pci_driver;
extern const struct devlink_ops nfp_devlink_ops;
+void nfp_net_hstat_init(void);
+
int nfp_net_pci_probe(struct nfp_pf *pf);
void nfp_net_pci_remove(struct nfp_pf *pf);
--
2.19.2
Powered by blists - more mailing lists