diff options
author | David S. Miller <davem@davemloft.net> | 2017-08-19 01:39:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-08-19 01:39:34 -0400 |
commit | e9638c504e204a78cc9827a025d8c78e93e8fa5d (patch) | |
tree | bbe21cec1adefc15cef840b2b4c3f22066e21464 | |
parent | ef319d4f2561c94bc2d7b8cb86dbbf4359074d8f (diff) | |
parent | 85d8e2ba7060ced6b23a2b1a2a8dd5cdaf951fb9 (diff) |
Merge branch 'nfp-add-basic-ethtool-callbacks-to-representors'
Jakub Kicinski says:
====================
nfp: add basic ethtool callbacks to representors
This set extends the basic ethtool functionality to representor
netdevs. I start with providing link state via ethtool and then
move on to functions such as driver information, statistics and
FW log dump. The series contains a number of clean ups to the
ethtool stats code too, some of the logic is simplified by making
better use of the nfp_port abstraction. The stats we expose on
representors are only the PCIe and MAC port statistics firmware
maintains for us.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/main.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_app.c | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_app.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | 593 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 59 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_port.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_port.h | 54 |
10 files changed, 497 insertions, 261 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index 3088e959f2a3..126a6b5233bf 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c | |||
@@ -159,12 +159,18 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app, | |||
159 | goto err_reprs_clean; | 159 | goto err_reprs_clean; |
160 | } | 160 | } |
161 | 161 | ||
162 | /* For now we only support 1 PF */ | ||
163 | WARN_ON(repr_type == NFP_REPR_TYPE_PF && i); | ||
164 | |||
162 | port = nfp_port_alloc(app, port_type, reprs->reprs[i]); | 165 | port = nfp_port_alloc(app, port_type, reprs->reprs[i]); |
163 | if (repr_type == NFP_REPR_TYPE_PF) { | 166 | if (repr_type == NFP_REPR_TYPE_PF) { |
164 | port->pf_id = i; | 167 | port->pf_id = i; |
168 | port->vnic = priv->nn->dp.ctrl_bar; | ||
165 | } else { | 169 | } else { |
166 | port->pf_id = 0; /* For now we only support 1 PF */ | 170 | port->pf_id = 0; |
167 | port->vf_id = i; | 171 | port->vf_id = i; |
172 | port->vnic = | ||
173 | app->pf->vf_cfg_mem + i * NFP_NET_CFG_BAR_SZ; | ||
168 | } | 174 | } |
169 | 175 | ||
170 | eth_hw_addr_random(reprs->reprs[i]); | 176 | eth_hw_addr_random(reprs->reprs[i]); |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.c b/drivers/net/ethernet/netronome/nfp/nfp_app.c index c704c022574f..505e63f47419 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_app.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "nfpcore/nfp_nffw.h" | 38 | #include "nfpcore/nfp_nffw.h" |
39 | #include "nfp_app.h" | 39 | #include "nfp_app.h" |
40 | #include "nfp_main.h" | 40 | #include "nfp_main.h" |
41 | #include "nfp_net.h" | ||
41 | #include "nfp_net_repr.h" | 42 | #include "nfp_net_repr.h" |
42 | 43 | ||
43 | static const struct nfp_app_type *apps[] = { | 44 | static const struct nfp_app_type *apps[] = { |
@@ -48,6 +49,25 @@ static const struct nfp_app_type *apps[] = { | |||
48 | #endif | 49 | #endif |
49 | }; | 50 | }; |
50 | 51 | ||
52 | struct nfp_app *nfp_app_from_netdev(struct net_device *netdev) | ||
53 | { | ||
54 | if (nfp_netdev_is_nfp_net(netdev)) { | ||
55 | struct nfp_net *nn = netdev_priv(netdev); | ||
56 | |||
57 | return nn->app; | ||
58 | } | ||
59 | |||
60 | if (nfp_netdev_is_nfp_repr(netdev)) { | ||
61 | struct nfp_repr *repr = netdev_priv(netdev); | ||
62 | |||
63 | return repr->app; | ||
64 | } | ||
65 | |||
66 | WARN(1, "Unknown netdev type for nfp_app\n"); | ||
67 | |||
68 | return NULL; | ||
69 | } | ||
70 | |||
51 | const char *nfp_app_mip_name(struct nfp_app *app) | 71 | const char *nfp_app_mip_name(struct nfp_app *app) |
52 | { | 72 | { |
53 | if (!app || !app->pf->mip) | 73 | if (!app || !app->pf->mip) |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.h b/drivers/net/ethernet/netronome/nfp/nfp_app.h index f34e8778fae2..c13b9bbe7e62 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_app.h | |||
@@ -293,6 +293,8 @@ static inline struct net_device *nfp_app_repr_get(struct nfp_app *app, u32 id) | |||
293 | return app->type->repr_get(app, id); | 293 | return app->type->repr_get(app, id); |
294 | } | 294 | } |
295 | 295 | ||
296 | struct nfp_app *nfp_app_from_netdev(struct net_device *netdev); | ||
297 | |||
296 | struct nfp_reprs * | 298 | struct nfp_reprs * |
297 | nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type, | 299 | nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type, |
298 | struct nfp_reprs *reprs); | 300 | struct nfp_reprs *reprs); |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h index b1fa77bd708b..d51d8237b984 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h | |||
@@ -573,7 +573,6 @@ struct nfp_net_dp { | |||
573 | * @tx_bar: Pointer to mapped TX queues | 573 | * @tx_bar: Pointer to mapped TX queues |
574 | * @rx_bar: Pointer to mapped FL/RX queues | 574 | * @rx_bar: Pointer to mapped FL/RX queues |
575 | * @debugfs_dir: Device directory in debugfs | 575 | * @debugfs_dir: Device directory in debugfs |
576 | * @ethtool_dump_flag: Ethtool dump flag | ||
577 | * @vnic_list: Entry on device vNIC list | 576 | * @vnic_list: Entry on device vNIC list |
578 | * @pdev: Backpointer to PCI device | 577 | * @pdev: Backpointer to PCI device |
579 | * @app: APP handle if available | 578 | * @app: APP handle if available |
@@ -640,7 +639,6 @@ struct nfp_net { | |||
640 | u8 __iomem *rx_bar; | 639 | u8 __iomem *rx_bar; |
641 | 640 | ||
642 | struct dentry *debugfs_dir; | 641 | struct dentry *debugfs_dir; |
643 | u32 ethtool_dump_flag; | ||
644 | 642 | ||
645 | struct list_head vnic_list; | 643 | struct list_head vnic_list; |
646 | 644 | ||
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c b/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c index 40217ece5fcb..cf81cf95d1d8 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c | |||
@@ -125,7 +125,6 @@ static int nfp_net_debugfs_tx_q_read(struct seq_file *file, void *data) | |||
125 | struct nfp_net_tx_ring *tx_ring; | 125 | struct nfp_net_tx_ring *tx_ring; |
126 | struct nfp_net_tx_desc *txd; | 126 | struct nfp_net_tx_desc *txd; |
127 | int d_rd_p, d_wr_p, txd_cnt; | 127 | int d_rd_p, d_wr_p, txd_cnt; |
128 | struct sk_buff *skb; | ||
129 | struct nfp_net *nn; | 128 | struct nfp_net *nn; |
130 | int i; | 129 | int i; |
131 | 130 | ||
@@ -158,13 +157,15 @@ static int nfp_net_debugfs_tx_q_read(struct seq_file *file, void *data) | |||
158 | txd->vals[0], txd->vals[1], | 157 | txd->vals[0], txd->vals[1], |
159 | txd->vals[2], txd->vals[3]); | 158 | txd->vals[2], txd->vals[3]); |
160 | 159 | ||
161 | skb = READ_ONCE(tx_ring->txbufs[i].skb); | 160 | if (tx_ring == r_vec->tx_ring) { |
162 | if (skb) { | 161 | struct sk_buff *skb = READ_ONCE(tx_ring->txbufs[i].skb); |
163 | if (tx_ring == r_vec->tx_ring) | 162 | |
163 | if (skb) | ||
164 | seq_printf(file, " skb->head=%p skb->data=%p", | 164 | seq_printf(file, " skb->head=%p skb->data=%p", |
165 | skb->head, skb->data); | 165 | skb->head, skb->data); |
166 | else | 166 | } else { |
167 | seq_printf(file, " frag=%p", skb); | 167 | seq_printf(file, " frag=%p", |
168 | READ_ONCE(tx_ring->txbufs[i].frag)); | ||
168 | } | 169 | } |
169 | 170 | ||
170 | if (tx_ring->txbufs[i].dma_addr) | 171 | if (tx_ring->txbufs[i].dma_addr) |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c index 6e31355c3567..07969f06df10 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | |||
@@ -59,82 +59,129 @@ enum nfp_dump_diag { | |||
59 | NFP_DUMP_NSP_DIAG = 0, | 59 | NFP_DUMP_NSP_DIAG = 0, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | /* Support for stats. Returns netdev, driver, and device stats */ | 62 | struct nfp_et_stat { |
63 | enum { NETDEV_ET_STATS, NFP_NET_DRV_ET_STATS, NFP_NET_DEV_ET_STATS }; | ||
64 | struct _nfp_net_et_stats { | ||
65 | char name[ETH_GSTRING_LEN]; | 63 | char name[ETH_GSTRING_LEN]; |
66 | int type; | ||
67 | int sz; | ||
68 | int off; | 64 | int off; |
69 | }; | 65 | }; |
70 | 66 | ||
71 | #define NN_ET_NETDEV_STAT(m) NETDEV_ET_STATS, \ | 67 | static const struct nfp_et_stat nfp_net_et_stats[] = { |
72 | FIELD_SIZEOF(struct net_device_stats, m), \ | ||
73 | offsetof(struct net_device_stats, m) | ||
74 | /* For stats in the control BAR (other than Q stats) */ | ||
75 | #define NN_ET_DEV_STAT(m) NFP_NET_DEV_ET_STATS, \ | ||
76 | sizeof(u64), \ | ||
77 | (m) | ||
78 | static const struct _nfp_net_et_stats nfp_net_et_stats[] = { | ||
79 | /* netdev stats */ | ||
80 | {"rx_packets", NN_ET_NETDEV_STAT(rx_packets)}, | ||
81 | {"tx_packets", NN_ET_NETDEV_STAT(tx_packets)}, | ||
82 | {"rx_bytes", NN_ET_NETDEV_STAT(rx_bytes)}, | ||
83 | {"tx_bytes", NN_ET_NETDEV_STAT(tx_bytes)}, | ||
84 | {"rx_errors", NN_ET_NETDEV_STAT(rx_errors)}, | ||
85 | {"tx_errors", NN_ET_NETDEV_STAT(tx_errors)}, | ||
86 | {"rx_dropped", NN_ET_NETDEV_STAT(rx_dropped)}, | ||
87 | {"tx_dropped", NN_ET_NETDEV_STAT(tx_dropped)}, | ||
88 | {"multicast", NN_ET_NETDEV_STAT(multicast)}, | ||
89 | {"collisions", NN_ET_NETDEV_STAT(collisions)}, | ||
90 | {"rx_over_errors", NN_ET_NETDEV_STAT(rx_over_errors)}, | ||
91 | {"rx_crc_errors", NN_ET_NETDEV_STAT(rx_crc_errors)}, | ||
92 | {"rx_frame_errors", NN_ET_NETDEV_STAT(rx_frame_errors)}, | ||
93 | {"rx_fifo_errors", NN_ET_NETDEV_STAT(rx_fifo_errors)}, | ||
94 | {"rx_missed_errors", NN_ET_NETDEV_STAT(rx_missed_errors)}, | ||
95 | {"tx_aborted_errors", NN_ET_NETDEV_STAT(tx_aborted_errors)}, | ||
96 | {"tx_carrier_errors", NN_ET_NETDEV_STAT(tx_carrier_errors)}, | ||
97 | {"tx_fifo_errors", NN_ET_NETDEV_STAT(tx_fifo_errors)}, | ||
98 | /* Stats from the device */ | 68 | /* Stats from the device */ |
99 | {"dev_rx_discards", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_RX_DISCARDS)}, | 69 | { "dev_rx_discards", NFP_NET_CFG_STATS_RX_DISCARDS }, |
100 | {"dev_rx_errors", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_RX_ERRORS)}, | 70 | { "dev_rx_errors", NFP_NET_CFG_STATS_RX_ERRORS }, |
101 | {"dev_rx_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_RX_OCTETS)}, | 71 | { "dev_rx_bytes", NFP_NET_CFG_STATS_RX_OCTETS }, |
102 | {"dev_rx_uc_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_RX_UC_OCTETS)}, | 72 | { "dev_rx_uc_bytes", NFP_NET_CFG_STATS_RX_UC_OCTETS }, |
103 | {"dev_rx_mc_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_RX_MC_OCTETS)}, | 73 | { "dev_rx_mc_bytes", NFP_NET_CFG_STATS_RX_MC_OCTETS }, |
104 | {"dev_rx_bc_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_RX_BC_OCTETS)}, | 74 | { "dev_rx_bc_bytes", NFP_NET_CFG_STATS_RX_BC_OCTETS }, |
105 | {"dev_rx_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_RX_FRAMES)}, | 75 | { "dev_rx_pkts", NFP_NET_CFG_STATS_RX_FRAMES }, |
106 | {"dev_rx_mc_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_RX_MC_FRAMES)}, | 76 | { "dev_rx_mc_pkts", NFP_NET_CFG_STATS_RX_MC_FRAMES }, |
107 | {"dev_rx_bc_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_RX_BC_FRAMES)}, | 77 | { "dev_rx_bc_pkts", NFP_NET_CFG_STATS_RX_BC_FRAMES }, |
108 | 78 | ||
109 | {"dev_tx_discards", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_TX_DISCARDS)}, | 79 | { "dev_tx_discards", NFP_NET_CFG_STATS_TX_DISCARDS }, |
110 | {"dev_tx_errors", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_TX_ERRORS)}, | 80 | { "dev_tx_errors", NFP_NET_CFG_STATS_TX_ERRORS }, |
111 | {"dev_tx_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_TX_OCTETS)}, | 81 | { "dev_tx_bytes", NFP_NET_CFG_STATS_TX_OCTETS }, |
112 | {"dev_tx_uc_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_TX_UC_OCTETS)}, | 82 | { "dev_tx_uc_bytes", NFP_NET_CFG_STATS_TX_UC_OCTETS }, |
113 | {"dev_tx_mc_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_TX_MC_OCTETS)}, | 83 | { "dev_tx_mc_bytes", NFP_NET_CFG_STATS_TX_MC_OCTETS }, |
114 | {"dev_tx_bc_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_TX_BC_OCTETS)}, | 84 | { "dev_tx_bc_bytes", NFP_NET_CFG_STATS_TX_BC_OCTETS }, |
115 | {"dev_tx_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_TX_FRAMES)}, | 85 | { "dev_tx_pkts", NFP_NET_CFG_STATS_TX_FRAMES }, |
116 | {"dev_tx_mc_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_TX_MC_FRAMES)}, | 86 | { "dev_tx_mc_pkts", NFP_NET_CFG_STATS_TX_MC_FRAMES }, |
117 | {"dev_tx_bc_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_TX_BC_FRAMES)}, | 87 | { "dev_tx_bc_pkts", NFP_NET_CFG_STATS_TX_BC_FRAMES }, |
118 | 88 | ||
119 | {"bpf_pass_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_APP0_FRAMES)}, | 89 | { "bpf_pass_pkts", NFP_NET_CFG_STATS_APP0_FRAMES }, |
120 | {"bpf_pass_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_APP0_BYTES)}, | 90 | { "bpf_pass_bytes", NFP_NET_CFG_STATS_APP0_BYTES }, |
121 | /* see comments in outro functions in nfp_bpf_jit.c to find out | 91 | /* see comments in outro functions in nfp_bpf_jit.c to find out |
122 | * how different BPF modes use app-specific counters | 92 | * how different BPF modes use app-specific counters |
123 | */ | 93 | */ |
124 | {"bpf_app1_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_APP1_FRAMES)}, | 94 | { "bpf_app1_pkts", NFP_NET_CFG_STATS_APP1_FRAMES }, |
125 | {"bpf_app1_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_APP1_BYTES)}, | 95 | { "bpf_app1_bytes", NFP_NET_CFG_STATS_APP1_BYTES }, |
126 | {"bpf_app2_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_APP2_FRAMES)}, | 96 | { "bpf_app2_pkts", NFP_NET_CFG_STATS_APP2_FRAMES }, |
127 | {"bpf_app2_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_APP2_BYTES)}, | 97 | { "bpf_app2_bytes", NFP_NET_CFG_STATS_APP2_BYTES }, |
128 | {"bpf_app3_pkts", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_APP3_FRAMES)}, | 98 | { "bpf_app3_pkts", NFP_NET_CFG_STATS_APP3_FRAMES }, |
129 | {"bpf_app3_bytes", NN_ET_DEV_STAT(NFP_NET_CFG_STATS_APP3_BYTES)}, | 99 | { "bpf_app3_bytes", NFP_NET_CFG_STATS_APP3_BYTES }, |
100 | }; | ||
101 | |||
102 | static const struct nfp_et_stat nfp_mac_et_stats[] = { | ||
103 | { "rx_octets", NFP_MAC_STATS_RX_IN_OCTETS, }, | ||
104 | { "rx_frame_too_long_errors", | ||
105 | NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS, }, | ||
106 | { "rx_range_length_errors", NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS, }, | ||
107 | { "rx_vlan_reveive_ok", NFP_MAC_STATS_RX_VLAN_REVEIVE_OK, }, | ||
108 | { "rx_errors", NFP_MAC_STATS_RX_IN_ERRORS, }, | ||
109 | { "rx_broadcast_pkts", NFP_MAC_STATS_RX_IN_BROADCAST_PKTS, }, | ||
110 | { "rx_drop_events", NFP_MAC_STATS_RX_DROP_EVENTS, }, | ||
111 | { "rx_alignment_errors", NFP_MAC_STATS_RX_ALIGNMENT_ERRORS, }, | ||
112 | { "rx_pause_mac_ctrl_frames", | ||
113 | NFP_MAC_STATS_RX_PAUSE_MAC_CTRL_FRAMES, }, | ||
114 | { "rx_frames_received_ok", NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK, }, | ||
115 | { "rx_frame_check_sequence_errors", | ||
116 | NFP_MAC_STATS_RX_FRAME_CHECK_SEQUENCE_ERRORS, }, | ||
117 | { "rx_unicast_pkts", NFP_MAC_STATS_RX_UNICAST_PKTS, }, | ||
118 | { "rx_multicast_pkts", NFP_MAC_STATS_RX_MULTICAST_PKTS, }, | ||
119 | { "rx_pkts", NFP_MAC_STATS_RX_PKTS, }, | ||
120 | { "rx_undersize_pkts", NFP_MAC_STATS_RX_UNDERSIZE_PKTS, }, | ||
121 | { "rx_pkts_64_octets", NFP_MAC_STATS_RX_PKTS_64_OCTETS, }, | ||
122 | { "rx_pkts_65_to_127_octets", | ||
123 | NFP_MAC_STATS_RX_PKTS_65_TO_127_OCTETS, }, | ||
124 | { "rx_pkts_128_to_255_octets", | ||
125 | NFP_MAC_STATS_RX_PKTS_128_TO_255_OCTETS, }, | ||
126 | { "rx_pkts_256_to_511_octets", | ||
127 | NFP_MAC_STATS_RX_PKTS_256_TO_511_OCTETS, }, | ||
128 | { "rx_pkts_512_to_1023_octets", | ||
129 | NFP_MAC_STATS_RX_PKTS_512_TO_1023_OCTETS, }, | ||
130 | { "rx_pkts_1024_to_1518_octets", | ||
131 | NFP_MAC_STATS_RX_PKTS_1024_TO_1518_OCTETS, }, | ||
132 | { "rx_pkts_1519_to_max_octets", | ||
133 | NFP_MAC_STATS_RX_PKTS_1519_TO_MAX_OCTETS, }, | ||
134 | { "rx_jabbers", NFP_MAC_STATS_RX_JABBERS, }, | ||
135 | { "rx_fragments", NFP_MAC_STATS_RX_FRAGMENTS, }, | ||
136 | { "rx_oversize_pkts", NFP_MAC_STATS_RX_OVERSIZE_PKTS, }, | ||
137 | { "rx_pause_frames_class0", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS0, }, | ||
138 | { "rx_pause_frames_class1", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS1, }, | ||
139 | { "rx_pause_frames_class2", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS2, }, | ||
140 | { "rx_pause_frames_class3", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS3, }, | ||
141 | { "rx_pause_frames_class4", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS4, }, | ||
142 | { "rx_pause_frames_class5", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS5, }, | ||
143 | { "rx_pause_frames_class6", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS6, }, | ||
144 | { "rx_pause_frames_class7", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS7, }, | ||
145 | { "rx_mac_ctrl_frames_received", | ||
146 | NFP_MAC_STATS_RX_MAC_CTRL_FRAMES_RECEIVED, }, | ||
147 | { "rx_mac_head_drop", NFP_MAC_STATS_RX_MAC_HEAD_DROP, }, | ||
148 | { "tx_queue_drop", NFP_MAC_STATS_TX_QUEUE_DROP, }, | ||
149 | { "tx_octets", NFP_MAC_STATS_TX_OUT_OCTETS, }, | ||
150 | { "tx_vlan_transmitted_ok", NFP_MAC_STATS_TX_VLAN_TRANSMITTED_OK, }, | ||
151 | { "tx_errors", NFP_MAC_STATS_TX_OUT_ERRORS, }, | ||
152 | { "tx_broadcast_pkts", NFP_MAC_STATS_TX_BROADCAST_PKTS, }, | ||
153 | { "tx_pause_mac_ctrl_frames", | ||
154 | NFP_MAC_STATS_TX_PAUSE_MAC_CTRL_FRAMES, }, | ||
155 | { "tx_frames_transmitted_ok", | ||
156 | NFP_MAC_STATS_TX_FRAMES_TRANSMITTED_OK, }, | ||
157 | { "tx_unicast_pkts", NFP_MAC_STATS_TX_UNICAST_PKTS, }, | ||
158 | { "tx_multicast_pkts", NFP_MAC_STATS_TX_MULTICAST_PKTS, }, | ||
159 | { "tx_pkts_64_octets", NFP_MAC_STATS_TX_PKTS_64_OCTETS, }, | ||
160 | { "tx_pkts_65_to_127_octets", | ||
161 | NFP_MAC_STATS_TX_PKTS_65_TO_127_OCTETS, }, | ||
162 | { "tx_pkts_128_to_255_octets", | ||
163 | NFP_MAC_STATS_TX_PKTS_128_TO_255_OCTETS, }, | ||
164 | { "tx_pkts_256_to_511_octets", | ||
165 | NFP_MAC_STATS_TX_PKTS_256_TO_511_OCTETS, }, | ||
166 | { "tx_pkts_512_to_1023_octets", | ||
167 | NFP_MAC_STATS_TX_PKTS_512_TO_1023_OCTETS, }, | ||
168 | { "tx_pkts_1024_to_1518_octets", | ||
169 | NFP_MAC_STATS_TX_PKTS_1024_TO_1518_OCTETS, }, | ||
170 | { "tx_pkts_1519_to_max_octets", | ||
171 | NFP_MAC_STATS_TX_PKTS_1519_TO_MAX_OCTETS, }, | ||
172 | { "tx_pause_frames_class0", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS0, }, | ||
173 | { "tx_pause_frames_class1", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS1, }, | ||
174 | { "tx_pause_frames_class2", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS2, }, | ||
175 | { "tx_pause_frames_class3", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS3, }, | ||
176 | { "tx_pause_frames_class4", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS4, }, | ||
177 | { "tx_pause_frames_class5", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS5, }, | ||
178 | { "tx_pause_frames_class6", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS6, }, | ||
179 | { "tx_pause_frames_class7", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS7, }, | ||
130 | }; | 180 | }; |
131 | 181 | ||
132 | #define NN_ET_GLOBAL_STATS_LEN ARRAY_SIZE(nfp_net_et_stats) | 182 | #define NN_ET_GLOBAL_STATS_LEN ARRAY_SIZE(nfp_net_et_stats) |
133 | #define NN_ET_RVEC_STATS_LEN (nn->dp.num_r_vecs * 3) | 183 | #define NN_ET_SWITCH_STATS_LEN 9 |
134 | #define NN_ET_RVEC_GATHER_STATS 7 | 184 | #define NN_ET_RVEC_GATHER_STATS 7 |
135 | #define NN_ET_QUEUE_STATS_LEN ((nn->dp.num_tx_rings + nn->dp.num_rx_rings) * 2) | ||
136 | #define NN_ET_STATS_LEN (NN_ET_GLOBAL_STATS_LEN + NN_ET_RVEC_GATHER_STATS + \ | ||
137 | NN_ET_RVEC_STATS_LEN + NN_ET_QUEUE_STATS_LEN) | ||
138 | 185 | ||
139 | static void nfp_net_get_nspinfo(struct nfp_app *app, char *version) | 186 | static void nfp_net_get_nspinfo(struct nfp_app *app, char *version) |
140 | { | 187 | { |
@@ -147,34 +194,53 @@ static void nfp_net_get_nspinfo(struct nfp_app *app, char *version) | |||
147 | if (IS_ERR(nsp)) | 194 | if (IS_ERR(nsp)) |
148 | return; | 195 | return; |
149 | 196 | ||
150 | snprintf(version, ETHTOOL_FWVERS_LEN, "sp:%hu.%hu", | 197 | snprintf(version, ETHTOOL_FWVERS_LEN, "%hu.%hu", |
151 | nfp_nsp_get_abi_ver_major(nsp), | 198 | nfp_nsp_get_abi_ver_major(nsp), |
152 | nfp_nsp_get_abi_ver_minor(nsp)); | 199 | nfp_nsp_get_abi_ver_minor(nsp)); |
153 | 200 | ||
154 | nfp_nsp_close(nsp); | 201 | nfp_nsp_close(nsp); |
155 | } | 202 | } |
156 | 203 | ||
157 | static void nfp_net_get_drvinfo(struct net_device *netdev, | 204 | static void |
158 | struct ethtool_drvinfo *drvinfo) | 205 | nfp_get_drvinfo(struct nfp_app *app, struct pci_dev *pdev, |
206 | const char *vnic_version, struct ethtool_drvinfo *drvinfo) | ||
159 | { | 207 | { |
160 | char nsp_version[ETHTOOL_FWVERS_LEN] = {}; | 208 | char nsp_version[ETHTOOL_FWVERS_LEN] = {}; |
161 | struct nfp_net *nn = netdev_priv(netdev); | ||
162 | 209 | ||
163 | strlcpy(drvinfo->driver, nn->pdev->driver->name, | 210 | strlcpy(drvinfo->driver, pdev->driver->name, sizeof(drvinfo->driver)); |
164 | sizeof(drvinfo->driver)); | ||
165 | strlcpy(drvinfo->version, nfp_driver_version, sizeof(drvinfo->version)); | 211 | strlcpy(drvinfo->version, nfp_driver_version, sizeof(drvinfo->version)); |
166 | 212 | ||
167 | nfp_net_get_nspinfo(nn->app, nsp_version); | 213 | nfp_net_get_nspinfo(app, nsp_version); |
168 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | 214 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), |
169 | "%d.%d.%d.%d %s %s %s", | 215 | "%s %s %s %s", vnic_version, nsp_version, |
216 | nfp_app_mip_name(app), nfp_app_name(app)); | ||
217 | } | ||
218 | |||
219 | static void | ||
220 | nfp_net_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | ||
221 | { | ||
222 | char vnic_version[ETHTOOL_FWVERS_LEN] = {}; | ||
223 | struct nfp_net *nn = netdev_priv(netdev); | ||
224 | |||
225 | snprintf(vnic_version, sizeof(vnic_version), "%d.%d.%d.%d", | ||
170 | nn->fw_ver.resv, nn->fw_ver.class, | 226 | nn->fw_ver.resv, nn->fw_ver.class, |
171 | nn->fw_ver.major, nn->fw_ver.minor, nsp_version, | 227 | nn->fw_ver.major, nn->fw_ver.minor); |
172 | nfp_app_mip_name(nn->app), nfp_app_name(nn->app)); | ||
173 | strlcpy(drvinfo->bus_info, pci_name(nn->pdev), | 228 | strlcpy(drvinfo->bus_info, pci_name(nn->pdev), |
174 | sizeof(drvinfo->bus_info)); | 229 | sizeof(drvinfo->bus_info)); |
175 | 230 | ||
176 | drvinfo->n_stats = NN_ET_STATS_LEN; | 231 | nfp_get_drvinfo(nn->app, nn->pdev, vnic_version, drvinfo); |
177 | drvinfo->regdump_len = NFP_NET_CFG_BAR_SZ; | 232 | } |
233 | |||
234 | static void | ||
235 | nfp_app_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | ||
236 | { | ||
237 | struct nfp_app *app; | ||
238 | |||
239 | app = nfp_app_from_netdev(netdev); | ||
240 | if (!app) | ||
241 | return; | ||
242 | |||
243 | nfp_get_drvinfo(app, app->pdev, "*", drvinfo); | ||
178 | } | 244 | } |
179 | 245 | ||
180 | /** | 246 | /** |
@@ -346,132 +412,270 @@ static int nfp_net_set_ringparam(struct net_device *netdev, | |||
346 | return nfp_net_set_ring_size(nn, rxd_cnt, txd_cnt); | 412 | return nfp_net_set_ring_size(nn, rxd_cnt, txd_cnt); |
347 | } | 413 | } |
348 | 414 | ||
349 | static void nfp_net_get_strings(struct net_device *netdev, | 415 | static __printf(2, 3) u8 *nfp_pr_et(u8 *data, const char *fmt, ...) |
350 | u32 stringset, u8 *data) | 416 | { |
417 | va_list args; | ||
418 | |||
419 | va_start(args, fmt); | ||
420 | vsnprintf(data, ETH_GSTRING_LEN, fmt, args); | ||
421 | va_end(args); | ||
422 | |||
423 | return data + ETH_GSTRING_LEN; | ||
424 | } | ||
425 | |||
426 | static unsigned int nfp_vnic_get_sw_stats_count(struct net_device *netdev) | ||
427 | { | ||
428 | struct nfp_net *nn = netdev_priv(netdev); | ||
429 | |||
430 | return NN_ET_RVEC_GATHER_STATS + nn->dp.num_r_vecs * 3; | ||
431 | } | ||
432 | |||
433 | static u8 *nfp_vnic_get_sw_stats_strings(struct net_device *netdev, u8 *data) | ||
351 | { | 434 | { |
352 | struct nfp_net *nn = netdev_priv(netdev); | 435 | struct nfp_net *nn = netdev_priv(netdev); |
353 | u8 *p = data; | ||
354 | int i; | 436 | int i; |
355 | 437 | ||
356 | switch (stringset) { | 438 | for (i = 0; i < nn->dp.num_r_vecs; i++) { |
357 | case ETH_SS_STATS: | 439 | data = nfp_pr_et(data, "rvec_%u_rx_pkts", i); |
358 | for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++) { | 440 | data = nfp_pr_et(data, "rvec_%u_tx_pkts", i); |
359 | memcpy(p, nfp_net_et_stats[i].name, ETH_GSTRING_LEN); | 441 | data = nfp_pr_et(data, "rvec_%u_tx_busy", i); |
360 | p += ETH_GSTRING_LEN; | ||
361 | } | ||
362 | for (i = 0; i < nn->dp.num_r_vecs; i++) { | ||
363 | sprintf(p, "rvec_%u_rx_pkts", i); | ||
364 | p += ETH_GSTRING_LEN; | ||
365 | sprintf(p, "rvec_%u_tx_pkts", i); | ||
366 | p += ETH_GSTRING_LEN; | ||
367 | sprintf(p, "rvec_%u_tx_busy", i); | ||
368 | p += ETH_GSTRING_LEN; | ||
369 | } | ||
370 | strncpy(p, "hw_rx_csum_ok", ETH_GSTRING_LEN); | ||
371 | p += ETH_GSTRING_LEN; | ||
372 | strncpy(p, "hw_rx_csum_inner_ok", ETH_GSTRING_LEN); | ||
373 | p += ETH_GSTRING_LEN; | ||
374 | strncpy(p, "hw_rx_csum_err", ETH_GSTRING_LEN); | ||
375 | p += ETH_GSTRING_LEN; | ||
376 | strncpy(p, "hw_tx_csum", ETH_GSTRING_LEN); | ||
377 | p += ETH_GSTRING_LEN; | ||
378 | strncpy(p, "hw_tx_inner_csum", ETH_GSTRING_LEN); | ||
379 | p += ETH_GSTRING_LEN; | ||
380 | strncpy(p, "tx_gather", ETH_GSTRING_LEN); | ||
381 | p += ETH_GSTRING_LEN; | ||
382 | strncpy(p, "tx_lso", ETH_GSTRING_LEN); | ||
383 | p += ETH_GSTRING_LEN; | ||
384 | for (i = 0; i < nn->dp.num_tx_rings; i++) { | ||
385 | sprintf(p, "txq_%u_pkts", i); | ||
386 | p += ETH_GSTRING_LEN; | ||
387 | sprintf(p, "txq_%u_bytes", i); | ||
388 | p += ETH_GSTRING_LEN; | ||
389 | } | ||
390 | for (i = 0; i < nn->dp.num_rx_rings; i++) { | ||
391 | sprintf(p, "rxq_%u_pkts", i); | ||
392 | p += ETH_GSTRING_LEN; | ||
393 | sprintf(p, "rxq_%u_bytes", i); | ||
394 | p += ETH_GSTRING_LEN; | ||
395 | } | ||
396 | break; | ||
397 | } | 442 | } |
443 | |||
444 | data = nfp_pr_et(data, "hw_rx_csum_ok"); | ||
445 | data = nfp_pr_et(data, "hw_rx_csum_inner_ok"); | ||
446 | data = nfp_pr_et(data, "hw_rx_csum_err"); | ||
447 | data = nfp_pr_et(data, "hw_tx_csum"); | ||
448 | data = nfp_pr_et(data, "hw_tx_inner_csum"); | ||
449 | data = nfp_pr_et(data, "tx_gather"); | ||
450 | data = nfp_pr_et(data, "tx_lso"); | ||
451 | |||
452 | return data; | ||
398 | } | 453 | } |
399 | 454 | ||
400 | static void nfp_net_get_stats(struct net_device *netdev, | 455 | static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data) |
401 | struct ethtool_stats *stats, u64 *data) | ||
402 | { | 456 | { |
403 | u64 gathered_stats[NN_ET_RVEC_GATHER_STATS] = {}; | 457 | u64 gathered_stats[NN_ET_RVEC_GATHER_STATS] = {}; |
404 | struct nfp_net *nn = netdev_priv(netdev); | 458 | struct nfp_net *nn = netdev_priv(netdev); |
405 | struct rtnl_link_stats64 *netdev_stats; | ||
406 | struct rtnl_link_stats64 temp = {}; | ||
407 | u64 tmp[NN_ET_RVEC_GATHER_STATS]; | 459 | u64 tmp[NN_ET_RVEC_GATHER_STATS]; |
408 | u8 __iomem *io_p; | 460 | unsigned int i, j; |
409 | int i, j, k; | 461 | |
410 | u8 *p; | 462 | for (i = 0; i < nn->dp.num_r_vecs; i++) { |
411 | |||
412 | netdev_stats = dev_get_stats(netdev, &temp); | ||
413 | |||
414 | for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++) { | ||
415 | switch (nfp_net_et_stats[i].type) { | ||
416 | case NETDEV_ET_STATS: | ||
417 | p = (char *)netdev_stats + nfp_net_et_stats[i].off; | ||
418 | data[i] = nfp_net_et_stats[i].sz == sizeof(u64) ? | ||
419 | *(u64 *)p : *(u32 *)p; | ||
420 | break; | ||
421 | |||
422 | case NFP_NET_DEV_ET_STATS: | ||
423 | io_p = nn->dp.ctrl_bar + nfp_net_et_stats[i].off; | ||
424 | data[i] = readq(io_p); | ||
425 | break; | ||
426 | } | ||
427 | } | ||
428 | for (j = 0; j < nn->dp.num_r_vecs; j++) { | ||
429 | unsigned int start; | 463 | unsigned int start; |
430 | 464 | ||
431 | do { | 465 | do { |
432 | start = u64_stats_fetch_begin(&nn->r_vecs[j].rx_sync); | 466 | start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync); |
433 | data[i++] = nn->r_vecs[j].rx_pkts; | 467 | *data++ = nn->r_vecs[i].rx_pkts; |
434 | tmp[0] = nn->r_vecs[j].hw_csum_rx_ok; | 468 | tmp[0] = nn->r_vecs[i].hw_csum_rx_ok; |
435 | tmp[1] = nn->r_vecs[j].hw_csum_rx_inner_ok; | 469 | tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok; |
436 | tmp[2] = nn->r_vecs[j].hw_csum_rx_error; | 470 | tmp[2] = nn->r_vecs[i].hw_csum_rx_error; |
437 | } while (u64_stats_fetch_retry(&nn->r_vecs[j].rx_sync, start)); | 471 | } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start)); |
438 | 472 | ||
439 | do { | 473 | do { |
440 | start = u64_stats_fetch_begin(&nn->r_vecs[j].tx_sync); | 474 | start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync); |
441 | data[i++] = nn->r_vecs[j].tx_pkts; | 475 | *data++ = nn->r_vecs[i].tx_pkts; |
442 | data[i++] = nn->r_vecs[j].tx_busy; | 476 | *data++ = nn->r_vecs[i].tx_busy; |
443 | tmp[3] = nn->r_vecs[j].hw_csum_tx; | 477 | tmp[3] = nn->r_vecs[i].hw_csum_tx; |
444 | tmp[4] = nn->r_vecs[j].hw_csum_tx_inner; | 478 | tmp[4] = nn->r_vecs[i].hw_csum_tx_inner; |
445 | tmp[5] = nn->r_vecs[j].tx_gather; | 479 | tmp[5] = nn->r_vecs[i].tx_gather; |
446 | tmp[6] = nn->r_vecs[j].tx_lso; | 480 | tmp[6] = nn->r_vecs[i].tx_lso; |
447 | } while (u64_stats_fetch_retry(&nn->r_vecs[j].tx_sync, start)); | 481 | } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start)); |
448 | 482 | ||
449 | for (k = 0; k < NN_ET_RVEC_GATHER_STATS; k++) | 483 | for (j = 0; j < NN_ET_RVEC_GATHER_STATS; j++) |
450 | gathered_stats[k] += tmp[k]; | 484 | gathered_stats[j] += tmp[j]; |
451 | } | 485 | } |
486 | |||
452 | for (j = 0; j < NN_ET_RVEC_GATHER_STATS; j++) | 487 | for (j = 0; j < NN_ET_RVEC_GATHER_STATS; j++) |
453 | data[i++] = gathered_stats[j]; | 488 | *data++ = gathered_stats[j]; |
454 | for (j = 0; j < nn->dp.num_tx_rings; j++) { | 489 | |
455 | io_p = nn->dp.ctrl_bar + NFP_NET_CFG_TXR_STATS(j); | 490 | return data; |
456 | data[i++] = readq(io_p); | 491 | } |
457 | io_p = nn->dp.ctrl_bar + NFP_NET_CFG_TXR_STATS(j) + 8; | 492 | |
458 | data[i++] = readq(io_p); | 493 | static unsigned int |
494 | nfp_vnic_get_hw_stats_count(unsigned int rx_rings, unsigned int tx_rings) | ||
495 | { | ||
496 | return NN_ET_GLOBAL_STATS_LEN + (rx_rings + tx_rings) * 2; | ||
497 | } | ||
498 | |||
499 | static u8 * | ||
500 | nfp_vnic_get_hw_stats_strings(u8 *data, unsigned int rx_rings, | ||
501 | unsigned int tx_rings, bool repr) | ||
502 | { | ||
503 | int swap_off, i; | ||
504 | |||
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++) | ||
519 | data = nfp_pr_et(data, nfp_net_et_stats[i].name); | ||
520 | |||
521 | for (i = 0; i < tx_rings; i++) { | ||
522 | data = nfp_pr_et(data, "txq_%u_pkts", i); | ||
523 | data = nfp_pr_et(data, "txq_%u_bytes", i); | ||
524 | } | ||
525 | |||
526 | for (i = 0; i < rx_rings; i++) { | ||
527 | data = nfp_pr_et(data, "rxq_%u_pkts", i); | ||
528 | data = nfp_pr_et(data, "rxq_%u_bytes", i); | ||
529 | } | ||
530 | |||
531 | return data; | ||
532 | } | ||
533 | |||
534 | static u64 * | ||
535 | nfp_vnic_get_hw_stats(u64 *data, u8 __iomem *mem, | ||
536 | unsigned int rx_rings, unsigned int tx_rings) | ||
537 | { | ||
538 | unsigned int i; | ||
539 | |||
540 | for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++) | ||
541 | *data++ = readq(mem + nfp_net_et_stats[i].off); | ||
542 | |||
543 | for (i = 0; i < tx_rings; i++) { | ||
544 | *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i)); | ||
545 | *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i) + 8); | ||
546 | } | ||
547 | |||
548 | for (i = 0; i < rx_rings; i++) { | ||
549 | *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i)); | ||
550 | *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i) + 8); | ||
459 | } | 551 | } |
460 | for (j = 0; j < nn->dp.num_rx_rings; j++) { | 552 | |
461 | io_p = nn->dp.ctrl_bar + NFP_NET_CFG_RXR_STATS(j); | 553 | return data; |
462 | data[i++] = readq(io_p); | 554 | } |
463 | io_p = nn->dp.ctrl_bar + NFP_NET_CFG_RXR_STATS(j) + 8; | 555 | |
464 | data[i++] = readq(io_p); | 556 | static unsigned int nfp_mac_get_stats_count(struct net_device *netdev) |
557 | { | ||
558 | struct nfp_port *port; | ||
559 | |||
560 | port = nfp_port_from_netdev(netdev); | ||
561 | if (!__nfp_port_get_eth_port(port) || !port->eth_stats) | ||
562 | return 0; | ||
563 | |||
564 | return ARRAY_SIZE(nfp_mac_et_stats); | ||
565 | } | ||
566 | |||
567 | static u8 *nfp_mac_get_stats_strings(struct net_device *netdev, u8 *data) | ||
568 | { | ||
569 | struct nfp_port *port; | ||
570 | unsigned int i; | ||
571 | |||
572 | port = nfp_port_from_netdev(netdev); | ||
573 | if (!__nfp_port_get_eth_port(port) || !port->eth_stats) | ||
574 | return data; | ||
575 | |||
576 | for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++) | ||
577 | data = nfp_pr_et(data, "mac.%s", nfp_mac_et_stats[i].name); | ||
578 | |||
579 | return data; | ||
580 | } | ||
581 | |||
582 | static u64 *nfp_mac_get_stats(struct net_device *netdev, u64 *data) | ||
583 | { | ||
584 | struct nfp_port *port; | ||
585 | unsigned int i; | ||
586 | |||
587 | port = nfp_port_from_netdev(netdev); | ||
588 | if (!__nfp_port_get_eth_port(port) || !port->eth_stats) | ||
589 | return data; | ||
590 | |||
591 | for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++) | ||
592 | *data++ = readq(port->eth_stats + nfp_mac_et_stats[i].off); | ||
593 | |||
594 | return data; | ||
595 | } | ||
596 | |||
597 | static void nfp_net_get_strings(struct net_device *netdev, | ||
598 | u32 stringset, u8 *data) | ||
599 | { | ||
600 | struct nfp_net *nn = netdev_priv(netdev); | ||
601 | |||
602 | switch (stringset) { | ||
603 | case ETH_SS_STATS: | ||
604 | data = nfp_vnic_get_sw_stats_strings(netdev, data); | ||
605 | data = nfp_vnic_get_hw_stats_strings(data, nn->dp.num_rx_rings, | ||
606 | nn->dp.num_tx_rings, | ||
607 | false); | ||
608 | data = nfp_mac_get_stats_strings(netdev, data); | ||
609 | break; | ||
465 | } | 610 | } |
466 | } | 611 | } |
467 | 612 | ||
613 | static void | ||
614 | nfp_net_get_stats(struct net_device *netdev, struct ethtool_stats *stats, | ||
615 | u64 *data) | ||
616 | { | ||
617 | struct nfp_net *nn = netdev_priv(netdev); | ||
618 | |||
619 | data = nfp_vnic_get_sw_stats(netdev, data); | ||
620 | data = nfp_vnic_get_hw_stats(data, nn->dp.ctrl_bar, | ||
621 | nn->dp.num_rx_rings, nn->dp.num_tx_rings); | ||
622 | data = nfp_mac_get_stats(netdev, data); | ||
623 | } | ||
624 | |||
468 | static int nfp_net_get_sset_count(struct net_device *netdev, int sset) | 625 | static int nfp_net_get_sset_count(struct net_device *netdev, int sset) |
469 | { | 626 | { |
470 | struct nfp_net *nn = netdev_priv(netdev); | 627 | struct nfp_net *nn = netdev_priv(netdev); |
471 | 628 | ||
472 | switch (sset) { | 629 | switch (sset) { |
473 | case ETH_SS_STATS: | 630 | case ETH_SS_STATS: |
474 | return NN_ET_STATS_LEN; | 631 | return nfp_vnic_get_sw_stats_count(netdev) + |
632 | nfp_vnic_get_hw_stats_count(nn->dp.num_rx_rings, | ||
633 | nn->dp.num_tx_rings) + | ||
634 | nfp_mac_get_stats_count(netdev); | ||
635 | default: | ||
636 | return -EOPNOTSUPP; | ||
637 | } | ||
638 | } | ||
639 | |||
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; | ||
475 | default: | 679 | default: |
476 | return -EOPNOTSUPP; | 680 | return -EOPNOTSUPP; |
477 | } | 681 | } |
@@ -708,18 +912,18 @@ static int nfp_net_get_coalesce(struct net_device *netdev, | |||
708 | /* Other debug dumps | 912 | /* Other debug dumps |
709 | */ | 913 | */ |
710 | static int | 914 | static int |
711 | nfp_dump_nsp_diag(struct nfp_net *nn, struct ethtool_dump *dump, void *buffer) | 915 | nfp_dump_nsp_diag(struct nfp_app *app, struct ethtool_dump *dump, void *buffer) |
712 | { | 916 | { |
713 | struct nfp_resource *res; | 917 | struct nfp_resource *res; |
714 | int ret; | 918 | int ret; |
715 | 919 | ||
716 | if (!nn->app) | 920 | if (!app) |
717 | return -EOPNOTSUPP; | 921 | return -EOPNOTSUPP; |
718 | 922 | ||
719 | dump->version = 1; | 923 | dump->version = 1; |
720 | dump->flag = NFP_DUMP_NSP_DIAG; | 924 | dump->flag = NFP_DUMP_NSP_DIAG; |
721 | 925 | ||
722 | res = nfp_resource_acquire(nn->app->cpp, NFP_RESOURCE_NSP_DIAG); | 926 | res = nfp_resource_acquire(app->cpp, NFP_RESOURCE_NSP_DIAG); |
723 | if (IS_ERR(res)) | 927 | if (IS_ERR(res)) |
724 | return PTR_ERR(res); | 928 | return PTR_ERR(res); |
725 | 929 | ||
@@ -729,7 +933,7 @@ nfp_dump_nsp_diag(struct nfp_net *nn, struct ethtool_dump *dump, void *buffer) | |||
729 | goto exit_release; | 933 | goto exit_release; |
730 | } | 934 | } |
731 | 935 | ||
732 | ret = nfp_cpp_read(nn->app->cpp, nfp_resource_cpp_id(res), | 936 | ret = nfp_cpp_read(app->cpp, nfp_resource_cpp_id(res), |
733 | nfp_resource_address(res), | 937 | nfp_resource_address(res), |
734 | buffer, dump->len); | 938 | buffer, dump->len); |
735 | if (ret != dump->len) | 939 | if (ret != dump->len) |
@@ -746,32 +950,30 @@ exit_release: | |||
746 | return ret; | 950 | return ret; |
747 | } | 951 | } |
748 | 952 | ||
749 | static int nfp_net_set_dump(struct net_device *netdev, struct ethtool_dump *val) | 953 | static int nfp_app_set_dump(struct net_device *netdev, struct ethtool_dump *val) |
750 | { | 954 | { |
751 | struct nfp_net *nn = netdev_priv(netdev); | 955 | struct nfp_app *app = nfp_app_from_netdev(netdev); |
752 | 956 | ||
753 | if (!nn->app) | 957 | if (!app) |
754 | return -EOPNOTSUPP; | 958 | return -EOPNOTSUPP; |
755 | 959 | ||
756 | if (val->flag != NFP_DUMP_NSP_DIAG) | 960 | if (val->flag != NFP_DUMP_NSP_DIAG) |
757 | return -EINVAL; | 961 | return -EINVAL; |
758 | 962 | ||
759 | nn->ethtool_dump_flag = val->flag; | ||
760 | |||
761 | return 0; | 963 | return 0; |
762 | } | 964 | } |
763 | 965 | ||
764 | static int | 966 | static int |
765 | nfp_net_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) | 967 | nfp_app_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) |
766 | { | 968 | { |
767 | return nfp_dump_nsp_diag(netdev_priv(netdev), dump, NULL); | 969 | return nfp_dump_nsp_diag(nfp_app_from_netdev(netdev), dump, NULL); |
768 | } | 970 | } |
769 | 971 | ||
770 | static int | 972 | static int |
771 | nfp_net_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, | 973 | nfp_app_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, |
772 | void *buffer) | 974 | void *buffer) |
773 | { | 975 | { |
774 | return nfp_dump_nsp_diag(netdev_priv(netdev), dump, buffer); | 976 | return nfp_dump_nsp_diag(nfp_app_from_netdev(netdev), dump, buffer); |
775 | } | 977 | } |
776 | 978 | ||
777 | static int nfp_net_set_coalesce(struct net_device *netdev, | 979 | static int nfp_net_set_coalesce(struct net_device *netdev, |
@@ -928,9 +1130,9 @@ static const struct ethtool_ops nfp_net_ethtool_ops = { | |||
928 | .set_rxfh = nfp_net_set_rxfh, | 1130 | .set_rxfh = nfp_net_set_rxfh, |
929 | .get_regs_len = nfp_net_get_regs_len, | 1131 | .get_regs_len = nfp_net_get_regs_len, |
930 | .get_regs = nfp_net_get_regs, | 1132 | .get_regs = nfp_net_get_regs, |
931 | .set_dump = nfp_net_set_dump, | 1133 | .set_dump = nfp_app_set_dump, |
932 | .get_dump_flag = nfp_net_get_dump_flag, | 1134 | .get_dump_flag = nfp_app_get_dump_flag, |
933 | .get_dump_data = nfp_net_get_dump_data, | 1135 | .get_dump_data = nfp_app_get_dump_data, |
934 | .get_coalesce = nfp_net_get_coalesce, | 1136 | .get_coalesce = nfp_net_get_coalesce, |
935 | .set_coalesce = nfp_net_set_coalesce, | 1137 | .set_coalesce = nfp_net_set_coalesce, |
936 | .get_channels = nfp_net_get_channels, | 1138 | .get_channels = nfp_net_get_channels, |
@@ -939,6 +1141,17 @@ static const struct ethtool_ops nfp_net_ethtool_ops = { | |||
939 | .set_link_ksettings = nfp_net_set_link_ksettings, | 1141 | .set_link_ksettings = nfp_net_set_link_ksettings, |
940 | }; | 1142 | }; |
941 | 1143 | ||
1144 | const struct ethtool_ops nfp_port_ethtool_ops = { | ||
1145 | .get_drvinfo = nfp_app_get_drvinfo, | ||
1146 | .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, | ||
1150 | .set_dump = nfp_app_set_dump, | ||
1151 | .get_dump_flag = nfp_app_get_dump_flag, | ||
1152 | .get_dump_data = nfp_app_get_dump_data, | ||
1153 | }; | ||
1154 | |||
942 | void nfp_net_set_ethtool_ops(struct net_device *netdev) | 1155 | void nfp_net_set_ethtool_ops(struct net_device *netdev) |
943 | { | 1156 | { |
944 | netdev->ethtool_ops = &nfp_net_ethtool_ops; | 1157 | netdev->ethtool_ops = &nfp_net_ethtool_ops; |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c index d5e2361f0e86..acdad6f20251 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c | |||
@@ -388,7 +388,7 @@ nfp_net_pf_app_init(struct nfp_pf *pf, u8 __iomem *qc_bar, unsigned int stride) | |||
388 | NFP_PF_CSR_SLICE_SIZE, | 388 | NFP_PF_CSR_SLICE_SIZE, |
389 | &pf->ctrl_vnic_bar); | 389 | &pf->ctrl_vnic_bar); |
390 | if (IS_ERR(ctrl_bar)) { | 390 | if (IS_ERR(ctrl_bar)) { |
391 | nfp_err(pf->cpp, "Failed to find data vNIC memory symbol\n"); | 391 | nfp_err(pf->cpp, "Failed to find ctrl vNIC memory symbol\n"); |
392 | err = PTR_ERR(ctrl_bar); | 392 | err = PTR_ERR(ctrl_bar); |
393 | goto err_app_clean; | 393 | goto err_app_clean; |
394 | } | 394 | } |
@@ -504,7 +504,7 @@ static int nfp_net_pci_map_mem(struct nfp_pf *pf) | |||
504 | int err; | 504 | int err; |
505 | 505 | ||
506 | min_size = pf->max_data_vnics * NFP_PF_CSR_SLICE_SIZE; | 506 | min_size = pf->max_data_vnics * NFP_PF_CSR_SLICE_SIZE; |
507 | mem = nfp_net_pf_map_rtsym(pf, "net.ctrl", "_pf%d_net_bar0", | 507 | mem = nfp_net_pf_map_rtsym(pf, "net.bar0", "_pf%d_net_bar0", |
508 | min_size, &pf->data_vnic_bar); | 508 | min_size, &pf->data_vnic_bar); |
509 | if (IS_ERR(mem)) { | 509 | if (IS_ERR(mem)) { |
510 | nfp_err(pf->cpp, "Failed to find data vNIC memory symbol\n"); | 510 | nfp_err(pf->cpp, "Failed to find data vNIC memory symbol\n"); |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c index 47daad30756c..0f9878d1bf40 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | |||
@@ -78,12 +78,10 @@ void nfp_repr_inc_rx_stats(struct net_device *netdev, unsigned int len) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | static void | 80 | static void |
81 | nfp_repr_phy_port_get_stats64(const struct nfp_app *app, u8 phy_port, | 81 | nfp_repr_phy_port_get_stats64(struct nfp_port *port, |
82 | struct rtnl_link_stats64 *stats) | 82 | struct rtnl_link_stats64 *stats) |
83 | { | 83 | { |
84 | u8 __iomem *mem; | 84 | u8 __iomem *mem = port->eth_stats; |
85 | |||
86 | mem = app->pf->mac_stats_mem + phy_port * NFP_MAC_STATS_SIZE; | ||
87 | 85 | ||
88 | /* TX and RX stats are flipped as we are returning the stats as seen | 86 | /* TX and RX stats are flipped as we are returning the stats as seen |
89 | * at the switch port corresponding to the phys port. | 87 | * at the switch port corresponding to the phys port. |
@@ -98,67 +96,38 @@ nfp_repr_phy_port_get_stats64(const struct nfp_app *app, u8 phy_port, | |||
98 | } | 96 | } |
99 | 97 | ||
100 | static void | 98 | static void |
101 | nfp_repr_vf_get_stats64(const struct nfp_app *app, u8 vf, | 99 | nfp_repr_vnic_get_stats64(struct nfp_port *port, |
102 | struct rtnl_link_stats64 *stats) | 100 | struct rtnl_link_stats64 *stats) |
103 | { | 101 | { |
104 | u8 __iomem *mem; | ||
105 | |||
106 | mem = app->pf->vf_cfg_mem + vf * NFP_NET_CFG_BAR_SZ; | ||
107 | |||
108 | /* TX and RX stats are flipped as we are returning the stats as seen | 102 | /* TX and RX stats are flipped as we are returning the stats as seen |
109 | * at the switch port corresponding to the VF. | 103 | * at the switch port corresponding to the VF. |
110 | */ | 104 | */ |
111 | stats->tx_packets = readq(mem + NFP_NET_CFG_STATS_RX_FRAMES); | 105 | stats->tx_packets = readq(port->vnic + NFP_NET_CFG_STATS_RX_FRAMES); |
112 | stats->tx_bytes = readq(mem + NFP_NET_CFG_STATS_RX_OCTETS); | 106 | stats->tx_bytes = readq(port->vnic + NFP_NET_CFG_STATS_RX_OCTETS); |
113 | stats->tx_dropped = readq(mem + NFP_NET_CFG_STATS_RX_DISCARDS); | 107 | stats->tx_dropped = readq(port->vnic + NFP_NET_CFG_STATS_RX_DISCARDS); |
114 | 108 | ||
115 | stats->rx_packets = readq(mem + NFP_NET_CFG_STATS_TX_FRAMES); | 109 | stats->rx_packets = readq(port->vnic + NFP_NET_CFG_STATS_TX_FRAMES); |
116 | stats->rx_bytes = readq(mem + NFP_NET_CFG_STATS_TX_OCTETS); | 110 | stats->rx_bytes = readq(port->vnic + NFP_NET_CFG_STATS_TX_OCTETS); |
117 | stats->rx_dropped = readq(mem + NFP_NET_CFG_STATS_TX_DISCARDS); | 111 | stats->rx_dropped = readq(port->vnic + NFP_NET_CFG_STATS_TX_DISCARDS); |
118 | } | ||
119 | |||
120 | static void | ||
121 | nfp_repr_pf_get_stats64(const struct nfp_app *app, u8 pf, | ||
122 | struct rtnl_link_stats64 *stats) | ||
123 | { | ||
124 | u8 __iomem *mem; | ||
125 | |||
126 | if (pf) | ||
127 | return; | ||
128 | |||
129 | mem = nfp_cpp_area_iomem(app->pf->data_vnic_bar); | ||
130 | |||
131 | stats->tx_packets = readq(mem + NFP_NET_CFG_STATS_RX_FRAMES); | ||
132 | stats->tx_bytes = readq(mem + NFP_NET_CFG_STATS_RX_OCTETS); | ||
133 | stats->tx_dropped = readq(mem + NFP_NET_CFG_STATS_RX_DISCARDS); | ||
134 | |||
135 | stats->rx_packets = readq(mem + NFP_NET_CFG_STATS_TX_FRAMES); | ||
136 | stats->rx_bytes = readq(mem + NFP_NET_CFG_STATS_TX_OCTETS); | ||
137 | stats->rx_dropped = readq(mem + NFP_NET_CFG_STATS_TX_DISCARDS); | ||
138 | } | 112 | } |
139 | 113 | ||
140 | static void | 114 | static void |
141 | nfp_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) | 115 | nfp_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) |
142 | { | 116 | { |
143 | struct nfp_repr *repr = netdev_priv(netdev); | 117 | struct nfp_repr *repr = netdev_priv(netdev); |
144 | struct nfp_eth_table_port *eth_port; | ||
145 | struct nfp_app *app = repr->app; | ||
146 | 118 | ||
147 | if (WARN_ON(!repr->port)) | 119 | if (WARN_ON(!repr->port)) |
148 | return; | 120 | return; |
149 | 121 | ||
150 | switch (repr->port->type) { | 122 | switch (repr->port->type) { |
151 | case NFP_PORT_PHYS_PORT: | 123 | case NFP_PORT_PHYS_PORT: |
152 | eth_port = __nfp_port_get_eth_port(repr->port); | 124 | if (!__nfp_port_get_eth_port(repr->port)) |
153 | if (!eth_port) | ||
154 | break; | 125 | break; |
155 | nfp_repr_phy_port_get_stats64(app, eth_port->index, stats); | 126 | nfp_repr_phy_port_get_stats64(repr->port, stats); |
156 | break; | 127 | break; |
157 | case NFP_PORT_PF_PORT: | 128 | case NFP_PORT_PF_PORT: |
158 | nfp_repr_pf_get_stats64(app, repr->port->pf_id, stats); | ||
159 | break; | ||
160 | case NFP_PORT_VF_PORT: | 129 | case NFP_PORT_VF_PORT: |
161 | nfp_repr_vf_get_stats64(app, repr->port->vf_id, stats); | 130 | nfp_repr_vnic_get_stats64(repr->port, stats); |
162 | default: | 131 | default: |
163 | break; | 132 | break; |
164 | } | 133 | } |
@@ -320,6 +289,8 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev, | |||
320 | repr->dst->u.port_info.lower_dev = pf_netdev; | 289 | repr->dst->u.port_info.lower_dev = pf_netdev; |
321 | 290 | ||
322 | netdev->netdev_ops = &nfp_repr_netdev_ops; | 291 | netdev->netdev_ops = &nfp_repr_netdev_ops; |
292 | netdev->ethtool_ops = &nfp_port_ethtool_ops; | ||
293 | |||
323 | SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops); | 294 | SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops); |
324 | 295 | ||
325 | if (nfp_app_has_tc(app)) { | 296 | if (nfp_app_has_tc(app)) { |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.c b/drivers/net/ethernet/netronome/nfp/nfp_port.c index 0cf65e57addb..34a6e035fe9a 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_port.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_port.c | |||
@@ -225,6 +225,9 @@ int nfp_port_init_phy_port(struct nfp_pf *pf, struct nfp_app *app, | |||
225 | 225 | ||
226 | port->eth_port = &pf->eth_tbl->ports[id]; | 226 | port->eth_port = &pf->eth_tbl->ports[id]; |
227 | port->eth_id = pf->eth_tbl->ports[id].index; | 227 | port->eth_id = pf->eth_tbl->ports[id].index; |
228 | if (pf->mac_stats_mem) | ||
229 | port->eth_stats = | ||
230 | pf->mac_stats_mem + port->eth_id * NFP_MAC_STATS_SIZE; | ||
228 | 231 | ||
229 | return 0; | 232 | return 0; |
230 | } | 233 | } |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.h b/drivers/net/ethernet/netronome/nfp/nfp_port.h index c88e376dcf0f..51dcb9c603ee 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_port.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_port.h | |||
@@ -76,8 +76,10 @@ enum nfp_port_flags { | |||
76 | * @dl_port: devlink port structure | 76 | * @dl_port: devlink port structure |
77 | * @eth_id: for %NFP_PORT_PHYS_PORT port ID in NFP enumeration scheme | 77 | * @eth_id: for %NFP_PORT_PHYS_PORT port ID in NFP enumeration scheme |
78 | * @eth_port: for %NFP_PORT_PHYS_PORT translated ETH Table port entry | 78 | * @eth_port: for %NFP_PORT_PHYS_PORT translated ETH Table port entry |
79 | * @eth_stats: for %NFP_PORT_PHYS_PORT MAC stats if available | ||
79 | * @pf_id: for %NFP_PORT_PF_PORT, %NFP_PORT_VF_PORT ID of the PCI PF (0-3) | 80 | * @pf_id: for %NFP_PORT_PF_PORT, %NFP_PORT_VF_PORT ID of the PCI PF (0-3) |
80 | * @vf_id: for %NFP_PORT_VF_PORT ID of the PCI VF within @pf_id | 81 | * @vf_id: for %NFP_PORT_VF_PORT ID of the PCI VF within @pf_id |
82 | * @vnic: for %NFP_PORT_PF_PORT, %NFP_PORT_VF_PORT vNIC ctrl memory | ||
81 | * @port_list: entry on pf's list of ports | 83 | * @port_list: entry on pf's list of ports |
82 | */ | 84 | */ |
83 | struct nfp_port { | 85 | struct nfp_port { |
@@ -95,22 +97,30 @@ struct nfp_port { | |||
95 | struct { | 97 | struct { |
96 | unsigned int eth_id; | 98 | unsigned int eth_id; |
97 | struct nfp_eth_table_port *eth_port; | 99 | struct nfp_eth_table_port *eth_port; |
100 | u8 __iomem *eth_stats; | ||
98 | }; | 101 | }; |
99 | /* NFP_PORT_PF_PORT, NFP_PORT_VF_PORT */ | 102 | /* NFP_PORT_PF_PORT, NFP_PORT_VF_PORT */ |
100 | struct { | 103 | struct { |
101 | unsigned int pf_id; | 104 | unsigned int pf_id; |
102 | unsigned int vf_id; | 105 | unsigned int vf_id; |
106 | u8 __iomem *vnic; | ||
103 | }; | 107 | }; |
104 | }; | 108 | }; |
105 | 109 | ||
106 | struct list_head port_list; | 110 | struct list_head port_list; |
107 | }; | 111 | }; |
108 | 112 | ||
113 | extern const struct ethtool_ops nfp_port_ethtool_ops; | ||
109 | extern const struct switchdev_ops nfp_port_switchdev_ops; | 114 | extern const struct switchdev_ops nfp_port_switchdev_ops; |
110 | 115 | ||
111 | int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type, | 116 | int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type, |
112 | void *type_data); | 117 | void *type_data); |
113 | 118 | ||
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 | |||
114 | struct nfp_port *nfp_port_from_netdev(struct net_device *netdev); | 124 | struct nfp_port *nfp_port_from_netdev(struct net_device *netdev); |
115 | struct nfp_port * | 125 | struct nfp_port * |
116 | nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id); | 126 | nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id); |
@@ -144,31 +154,32 @@ void nfp_devlink_port_unregister(struct nfp_port *port); | |||
144 | #define NFP_MAC_STATS_SIZE 0x0200 | 154 | #define NFP_MAC_STATS_SIZE 0x0200 |
145 | 155 | ||
146 | #define NFP_MAC_STATS_RX_IN_OCTETS (NFP_MAC_STATS_BASE + 0x000) | 156 | #define NFP_MAC_STATS_RX_IN_OCTETS (NFP_MAC_STATS_BASE + 0x000) |
157 | /* unused 0x008 */ | ||
147 | #define NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS (NFP_MAC_STATS_BASE + 0x010) | 158 | #define NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS (NFP_MAC_STATS_BASE + 0x010) |
148 | #define NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS (NFP_MAC_STATS_BASE + 0x018) | 159 | #define NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS (NFP_MAC_STATS_BASE + 0x018) |
149 | #define NFP_MAC_STATS_RX_VLAN_REVEIVE_OK (NFP_MAC_STATS_BASE + 0x020) | 160 | #define NFP_MAC_STATS_RX_VLAN_REVEIVE_OK (NFP_MAC_STATS_BASE + 0x020) |
150 | #define NFP_MAC_STATS_RX_IN_ERRORS (NFP_MAC_STATS_BASE + 0x028) | 161 | #define NFP_MAC_STATS_RX_IN_ERRORS (NFP_MAC_STATS_BASE + 0x028) |
151 | #define NFP_MAC_STATS_RX_IN_BROADCAST_PKTS (NFP_MAC_STATS_BASE + 0x030) | 162 | #define NFP_MAC_STATS_RX_IN_BROADCAST_PKTS (NFP_MAC_STATS_BASE + 0x030) |
152 | #define NFP_MAC_STATS_RX_STATS_DROP_EVENTS (NFP_MAC_STATS_BASE + 0x038) | 163 | #define NFP_MAC_STATS_RX_DROP_EVENTS (NFP_MAC_STATS_BASE + 0x038) |
153 | #define NFP_MAC_STATS_RX_ALIGNMENT_ERRORS (NFP_MAC_STATS_BASE + 0x040) | 164 | #define NFP_MAC_STATS_RX_ALIGNMENT_ERRORS (NFP_MAC_STATS_BASE + 0x040) |
154 | #define NFP_MAC_STATS_RX_PAUSE_MAC_CTRL_FRAMES (NFP_MAC_STATS_BASE + 0x048) | 165 | #define NFP_MAC_STATS_RX_PAUSE_MAC_CTRL_FRAMES (NFP_MAC_STATS_BASE + 0x048) |
155 | #define NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK (NFP_MAC_STATS_BASE + 0x050) | 166 | #define NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK (NFP_MAC_STATS_BASE + 0x050) |
156 | #define NFP_MAC_STATS_RX_FRAME_CHECK_SEQUENCE_ERRORS (NFP_MAC_STATS_BASE + 0x058) | 167 | #define NFP_MAC_STATS_RX_FRAME_CHECK_SEQUENCE_ERRORS (NFP_MAC_STATS_BASE + 0x058) |
157 | #define NFP_MAC_STATS_RX_UNICAST_PKTS (NFP_MAC_STATS_BASE + 0x060) | 168 | #define NFP_MAC_STATS_RX_UNICAST_PKTS (NFP_MAC_STATS_BASE + 0x060) |
158 | #define NFP_MAC_STATS_RX_MULTICAST_PKTS (NFP_MAC_STATS_BASE + 0x068) | 169 | #define NFP_MAC_STATS_RX_MULTICAST_PKTS (NFP_MAC_STATS_BASE + 0x068) |
159 | #define NFP_MAC_STATS_RX_STATS_PKTS (NFP_MAC_STATS_BASE + 0x070) | 170 | #define NFP_MAC_STATS_RX_PKTS (NFP_MAC_STATS_BASE + 0x070) |
160 | #define NFP_MAC_STATS_RX_STATS_UNDERSIZE_PKTS (NFP_MAC_STATS_BASE + 0x078) | 171 | #define NFP_MAC_STATS_RX_UNDERSIZE_PKTS (NFP_MAC_STATS_BASE + 0x078) |
161 | #define NFP_MAC_STATS_RX_STATS_PKTS_64_OCTETS (NFP_MAC_STATS_BASE + 0x080) | 172 | #define NFP_MAC_STATS_RX_PKTS_64_OCTETS (NFP_MAC_STATS_BASE + 0x080) |
162 | #define NFP_MAC_STATS_RX_STATS_PKTS_65_TO_127_OCTETS (NFP_MAC_STATS_BASE + 0x088) | 173 | #define NFP_MAC_STATS_RX_PKTS_65_TO_127_OCTETS (NFP_MAC_STATS_BASE + 0x088) |
163 | #define NFP_MAC_STATS_RX_STATS_PKTS_512_TO_1023_OCTETS (NFP_MAC_STATS_BASE + 0x090) | 174 | #define NFP_MAC_STATS_RX_PKTS_512_TO_1023_OCTETS (NFP_MAC_STATS_BASE + 0x090) |
164 | #define NFP_MAC_STATS_RX_STATS_PKTS_1024_TO_1518_OCTETS (NFP_MAC_STATS_BASE + 0x098) | 175 | #define NFP_MAC_STATS_RX_PKTS_1024_TO_1518_OCTETS (NFP_MAC_STATS_BASE + 0x098) |
165 | #define NFP_MAC_STATS_RX_STATS_JABBERS (NFP_MAC_STATS_BASE + 0x0a0) | 176 | #define NFP_MAC_STATS_RX_JABBERS (NFP_MAC_STATS_BASE + 0x0a0) |
166 | #define NFP_MAC_STATS_RX_STATS_FRAGMENTS (NFP_MAC_STATS_BASE + 0x0a8) | 177 | #define NFP_MAC_STATS_RX_FRAGMENTS (NFP_MAC_STATS_BASE + 0x0a8) |
167 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS2 (NFP_MAC_STATS_BASE + 0x0b0) | 178 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS2 (NFP_MAC_STATS_BASE + 0x0b0) |
168 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS3 (NFP_MAC_STATS_BASE + 0x0b8) | 179 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS3 (NFP_MAC_STATS_BASE + 0x0b8) |
169 | #define NFP_MAC_STATS_RX_STATS_PKTS_128_TO_255_OCTETS (NFP_MAC_STATS_BASE + 0x0c0) | 180 | #define NFP_MAC_STATS_RX_PKTS_128_TO_255_OCTETS (NFP_MAC_STATS_BASE + 0x0c0) |
170 | #define NFP_MAC_STATS_RX_STATS_PKTS_256_TO_511_OCTETS (NFP_MAC_STATS_BASE + 0x0c8) | 181 | #define NFP_MAC_STATS_RX_PKTS_256_TO_511_OCTETS (NFP_MAC_STATS_BASE + 0x0c8) |
171 | #define NFP_MAC_STATS_RX_STATS_PKTS_1519_TO_MAX_OCTETS (NFP_MAC_STATS_BASE + 0x0d0) | 182 | #define NFP_MAC_STATS_RX_PKTS_1519_TO_MAX_OCTETS (NFP_MAC_STATS_BASE + 0x0d0) |
172 | #define NFP_MAC_STATS_RX_OVERSIZE_PKTS (NFP_MAC_STATS_BASE + 0x0d8) | 183 | #define NFP_MAC_STATS_RX_OVERSIZE_PKTS (NFP_MAC_STATS_BASE + 0x0d8) |
173 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS0 (NFP_MAC_STATS_BASE + 0x0e0) | 184 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS0 (NFP_MAC_STATS_BASE + 0x0e0) |
174 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS1 (NFP_MAC_STATS_BASE + 0x0e8) | 185 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS1 (NFP_MAC_STATS_BASE + 0x0e8) |
@@ -178,9 +189,12 @@ void nfp_devlink_port_unregister(struct nfp_port *port); | |||
178 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS7 (NFP_MAC_STATS_BASE + 0x108) | 189 | #define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS7 (NFP_MAC_STATS_BASE + 0x108) |
179 | #define NFP_MAC_STATS_RX_MAC_CTRL_FRAMES_RECEIVED (NFP_MAC_STATS_BASE + 0x110) | 190 | #define NFP_MAC_STATS_RX_MAC_CTRL_FRAMES_RECEIVED (NFP_MAC_STATS_BASE + 0x110) |
180 | #define NFP_MAC_STATS_RX_MAC_HEAD_DROP (NFP_MAC_STATS_BASE + 0x118) | 191 | #define NFP_MAC_STATS_RX_MAC_HEAD_DROP (NFP_MAC_STATS_BASE + 0x118) |
181 | 192 | /* unused 0x120 */ | |
193 | /* unused 0x128 */ | ||
194 | /* unused 0x130 */ | ||
182 | #define NFP_MAC_STATS_TX_QUEUE_DROP (NFP_MAC_STATS_BASE + 0x138) | 195 | #define NFP_MAC_STATS_TX_QUEUE_DROP (NFP_MAC_STATS_BASE + 0x138) |
183 | #define NFP_MAC_STATS_TX_OUT_OCTETS (NFP_MAC_STATS_BASE + 0x140) | 196 | #define NFP_MAC_STATS_TX_OUT_OCTETS (NFP_MAC_STATS_BASE + 0x140) |
197 | /* unused 0x148 */ | ||
184 | #define NFP_MAC_STATS_TX_VLAN_TRANSMITTED_OK (NFP_MAC_STATS_BASE + 0x150) | 198 | #define NFP_MAC_STATS_TX_VLAN_TRANSMITTED_OK (NFP_MAC_STATS_BASE + 0x150) |
185 | #define NFP_MAC_STATS_TX_OUT_ERRORS (NFP_MAC_STATS_BASE + 0x158) | 199 | #define NFP_MAC_STATS_TX_OUT_ERRORS (NFP_MAC_STATS_BASE + 0x158) |
186 | #define NFP_MAC_STATS_TX_BROADCAST_PKTS (NFP_MAC_STATS_BASE + 0x160) | 200 | #define NFP_MAC_STATS_TX_BROADCAST_PKTS (NFP_MAC_STATS_BASE + 0x160) |
@@ -192,8 +206,16 @@ void nfp_devlink_port_unregister(struct nfp_port *port); | |||
192 | #define NFP_MAC_STATS_TX_UNICAST_PKTS (NFP_MAC_STATS_BASE + 0x190) | 206 | #define NFP_MAC_STATS_TX_UNICAST_PKTS (NFP_MAC_STATS_BASE + 0x190) |
193 | #define NFP_MAC_STATS_TX_MULTICAST_PKTS (NFP_MAC_STATS_BASE + 0x198) | 207 | #define NFP_MAC_STATS_TX_MULTICAST_PKTS (NFP_MAC_STATS_BASE + 0x198) |
194 | #define NFP_MAC_STATS_TX_PKTS_65_TO_127_OCTETS (NFP_MAC_STATS_BASE + 0x1a0) | 208 | #define NFP_MAC_STATS_TX_PKTS_65_TO_127_OCTETS (NFP_MAC_STATS_BASE + 0x1a0) |
195 | #define NFP_MAC_STATS_TX_PKTS_127_TO_512_OCTETS (NFP_MAC_STATS_BASE + 0x1a8) | 209 | #define NFP_MAC_STATS_TX_PKTS_128_TO_255_OCTETS (NFP_MAC_STATS_BASE + 0x1a8) |
196 | #define NFP_MAC_STATS_TX_PKTS_128_TO_1518_OCTETS (NFP_MAC_STATS_BASE + 0x1b0) | 210 | #define NFP_MAC_STATS_TX_PKTS_1024_TO_1518_OCTETS (NFP_MAC_STATS_BASE + 0x1b0) |
197 | #define NFP_MAC_STATS_TX_PKTS_1518_TO_MAX_OCTETS (NFP_MAC_STATS_BASE + 0x1b8) | 211 | #define NFP_MAC_STATS_TX_PKTS_1519_TO_MAX_OCTETS (NFP_MAC_STATS_BASE + 0x1b8) |
212 | #define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS0 (NFP_MAC_STATS_BASE + 0x1c0) | ||
213 | #define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS1 (NFP_MAC_STATS_BASE + 0x1c8) | ||
214 | #define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS4 (NFP_MAC_STATS_BASE + 0x1d0) | ||
215 | #define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS5 (NFP_MAC_STATS_BASE + 0x1d8) | ||
216 | #define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS2 (NFP_MAC_STATS_BASE + 0x1e0) | ||
217 | #define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS3 (NFP_MAC_STATS_BASE + 0x1e8) | ||
218 | #define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS6 (NFP_MAC_STATS_BASE + 0x1f0) | ||
219 | #define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS7 (NFP_MAC_STATS_BASE + 0x1f8) | ||
198 | 220 | ||
199 | #endif | 221 | #endif |