The MAC maintains counts of PFC per-prio pause frames.  Unfortunately,
I couldn't find such counters in any standard, so add a partial
group (HW doesn't give us "non-PFC" count) with those counters.

Signed-off-by: Jakub Kicinski <jakub.kicin...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_hstat.c    | 44 +++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_hstat.c 
b/drivers/net/ethernet/netronome/nfp/nfp_hstat.c
index cd97cd2676f6..ced4edca8b73 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_hstat.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_hstat.c
@@ -216,6 +216,49 @@ static const struct rtnl_hstat_group nfp_hstat_tm = {
        .stats_cnt = 1,
 };
 
+static int
+nfp_hstat_mac_pp_pause(struct net_device *netdev, struct rtnl_hstat_req *req,
+                      const struct rtnl_hstat_group *grp)
+{
+       static const u32 remap_rx[] = {
+               0xe0, 0xe8, 0xb0, 0xb8, 0xf0, 0xf7, 0x100, 0x108
+       };
+       static const u32 remap_tx[] = {
+               0x1c0, 0x1c8, 0x1e0, 0x1e8, 0x1d0, 0x1d8, 0x1f0, 0x1f8
+       };
+       struct nfp_port *port;
+       const u32 *remap;
+       u8 dir, prio;
+
+       port = nfp_port_from_netdev(netdev);
+       if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
+               return -EINVAL;
+
+       prio = rtnl_hstat_qual_get(req, RTNL_HSTATS_QUAL_PRIORITY);
+       dir = rtnl_hstat_qual_get(req, RTNL_HSTATS_QUAL_DIRECTION);
+       remap = dir == IFLA_HSTATS_QUAL_DIR_RX ? remap_rx : remap_tx;
+
+       rtnl_hstat_dump(req, IFLA_HSTATS_STAT_IEEE8023_PAUSEMACCtrlFrames,
+                       readq(port->eth_stats + remap[prio]));
+       return 0;
+}
+
+static const struct rtnl_hstat_group nfp_hstat_pp_pause = {
+       .qualifiers = {
+               RTNL_HSTATS_QUALS_BASIC_BIDIR(DEV),
+               [RTNL_HSTATS_QUAL_PRIORITY] = {
+                       .max    = 8,
+               },
+       },
+       .partial_flags = IFLA_HSTATS_PARTIAL_CLASSIFIER,
+
+       .get_stats = nfp_hstat_mac_pp_pause,
+       .stats  = {
+               [1] =   RTNL_HSTATS_STAT_IEEE8023_PAUSEMACCtrlFrames_BIT,
+       },
+       .stats_cnt = 1,
+};
+
 /* NFD per-vNIC stats */
 static int
 nfp_hstat_vnic_nfd_basic_get(struct net_device *netdev,
@@ -402,6 +445,7 @@ int nfp_net_hstat_get_groups(const struct net_device 
*netdev,
        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_pp_pause);
                rtnl_hstat_add_grp(req, &nfp_hstat_mac);
        }
 
-- 
2.19.2

Reply via email to