Skip to content

Commit 899a37a

Browse files
Jakub Kicinskidavem330
authored andcommitted
nfp: add ethtool statistics for representors
Representors may be associated with both VFs or more importantly with physical ports. Allow vNIC and MAC statistics to be read with ethtool -S on representors. In case of vNICs we reuse the vNIC statistic helper, we just need to swap RX and TX to give statistics the "switch perspective." Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent ef0ec67 commit 899a37a

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ static const struct nfp_et_stat nfp_mac_et_stats[] = {
180180
};
181181

182182
#define NN_ET_GLOBAL_STATS_LEN ARRAY_SIZE(nfp_net_et_stats)
183+
#define NN_ET_SWITCH_STATS_LEN 9
183184
#define NN_ET_RVEC_GATHER_STATS 7
184185

185186
static void nfp_net_get_nspinfo(struct nfp_app *app, char *version)
@@ -497,11 +498,24 @@ nfp_vnic_get_hw_stats_count(unsigned int rx_rings, unsigned int tx_rings)
497498

498499
static u8 *
499500
nfp_vnic_get_hw_stats_strings(u8 *data, unsigned int rx_rings,
500-
unsigned int tx_rings)
501+
unsigned int tx_rings, bool repr)
501502
{
502-
int i;
503+
int swap_off, i;
503504

504-
for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++)
505+
BUILD_BUG_ON(NN_ET_GLOBAL_STATS_LEN < NN_ET_SWITCH_STATS_LEN * 2);
506+
/* If repr is true first add SWITCH_STATS_LEN and then subtract it
507+
* effectively swapping the RX and TX statistics (giving us the RX
508+
* and TX from perspective of the switch).
509+
*/
510+
swap_off = repr * NN_ET_SWITCH_STATS_LEN;
511+
512+
for (i = 0; i < NN_ET_SWITCH_STATS_LEN; i++)
513+
data = nfp_pr_et(data, nfp_net_et_stats[i + swap_off].name);
514+
515+
for (i = NN_ET_SWITCH_STATS_LEN; i < NN_ET_SWITCH_STATS_LEN * 2; i++)
516+
data = nfp_pr_et(data, nfp_net_et_stats[i - swap_off].name);
517+
518+
for (i = NN_ET_SWITCH_STATS_LEN * 2; i < NN_ET_GLOBAL_STATS_LEN; i++)
505519
data = nfp_pr_et(data, nfp_net_et_stats[i].name);
506520

507521
for (i = 0; i < tx_rings; i++) {
@@ -589,7 +603,8 @@ static void nfp_net_get_strings(struct net_device *netdev,
589603
case ETH_SS_STATS:
590604
data = nfp_vnic_get_sw_stats_strings(netdev, data);
591605
data = nfp_vnic_get_hw_stats_strings(data, nn->dp.num_rx_rings,
592-
nn->dp.num_tx_rings);
606+
nn->dp.num_tx_rings,
607+
false);
593608
data = nfp_mac_get_stats_strings(netdev, data);
594609
break;
595610
}
@@ -622,6 +637,50 @@ static int nfp_net_get_sset_count(struct net_device *netdev, int sset)
622637
}
623638
}
624639

640+
static void nfp_port_get_strings(struct net_device *netdev,
641+
u32 stringset, u8 *data)
642+
{
643+
struct nfp_port *port = nfp_port_from_netdev(netdev);
644+
645+
switch (stringset) {
646+
case ETH_SS_STATS:
647+
if (nfp_port_is_vnic(port))
648+
data = nfp_vnic_get_hw_stats_strings(data, 0, 0, true);
649+
else
650+
data = nfp_mac_get_stats_strings(netdev, data);
651+
break;
652+
}
653+
}
654+
655+
static void
656+
nfp_port_get_stats(struct net_device *netdev, struct ethtool_stats *stats,
657+
u64 *data)
658+
{
659+
struct nfp_port *port = nfp_port_from_netdev(netdev);
660+
661+
if (nfp_port_is_vnic(port))
662+
data = nfp_vnic_get_hw_stats(data, port->vnic, 0, 0);
663+
else
664+
data = nfp_mac_get_stats(netdev, data);
665+
}
666+
667+
static int nfp_port_get_sset_count(struct net_device *netdev, int sset)
668+
{
669+
struct nfp_port *port = nfp_port_from_netdev(netdev);
670+
unsigned int count;
671+
672+
switch (sset) {
673+
case ETH_SS_STATS:
674+
if (nfp_port_is_vnic(port))
675+
count = nfp_vnic_get_hw_stats_count(0, 0);
676+
else
677+
count = nfp_mac_get_stats_count(netdev);
678+
return count;
679+
default:
680+
return -EOPNOTSUPP;
681+
}
682+
}
683+
625684
/* RX network flow classification (RSS, filters, etc)
626685
*/
627686
static u32 ethtool_flow_to_nfp_flag(u32 flow_type)
@@ -1085,6 +1144,9 @@ static const struct ethtool_ops nfp_net_ethtool_ops = {
10851144
const struct ethtool_ops nfp_port_ethtool_ops = {
10861145
.get_drvinfo = nfp_app_get_drvinfo,
10871146
.get_link = ethtool_op_get_link,
1147+
.get_strings = nfp_port_get_strings,
1148+
.get_ethtool_stats = nfp_port_get_stats,
1149+
.get_sset_count = nfp_port_get_sset_count,
10881150
.set_dump = nfp_app_set_dump,
10891151
.get_dump_flag = nfp_app_get_dump_flag,
10901152
.get_dump_data = nfp_app_get_dump_data,

drivers/net/ethernet/netronome/nfp/nfp_port.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ extern const struct switchdev_ops nfp_port_switchdev_ops;
116116
int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type,
117117
void *type_data);
118118

119+
static inline bool nfp_port_is_vnic(const struct nfp_port *port)
120+
{
121+
return port->type == NFP_PORT_PF_PORT || port->type == NFP_PORT_VF_PORT;
122+
}
123+
119124
struct nfp_port *nfp_port_from_netdev(struct net_device *netdev);
120125
struct nfp_port *
121126
nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id);

0 commit comments

Comments
 (0)