Skip to content

Commit 79da2aa

Browse files
sanmanp2111993kuba-moo
authored andcommitted
eth: fbnic: add RPC hardware statistics
Report Rx parser statistics via ethtool -S. The parser stats are 32b, so we need to add refresh to the service task to make sure we don't miss overflows. Signed-off-by: Sanman Pradhan <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 25ba596 commit 79da2aa

File tree

6 files changed

+180
-0
lines changed

6 files changed

+180
-0
lines changed

Documentation/networking/device_drivers/ethernet/meta/fbnic.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ separate entry.
3131
Statistics
3232
----------
3333

34+
RPC (Rx parser)
35+
~~~~~~~~~~~~~~~
36+
37+
- ``rpc_unkn_etype``: frames containing unknown EtherType
38+
- ``rpc_unkn_ext_hdr``: frames containing unknown IPv6 extension header
39+
- ``rpc_ipv4_frag``: frames containing IPv4 fragment
40+
- ``rpc_ipv6_frag``: frames containing IPv6 fragment
41+
- ``rpc_ipv4_esp``: frames with IPv4 ESP encapsulation
42+
- ``rpc_ipv6_esp``: frames with IPv6 ESP encapsulation
43+
- ``rpc_tcp_opt_err``: frames which encountered TCP option parsing error
44+
- ``rpc_out_of_hdr_err``: frames where header was larger than parsable region
45+
- ``ovr_size_err``: oversized frames
46+
3447
PCIe
3548
~~~~
3649

drivers/net/ethernet/meta/fbnic/fbnic_csr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,16 @@ enum {
638638
FBNIC_RPC_RSS_KEY_DWORD_LEN * 32 - \
639639
FBNIC_RPC_RSS_KEY_BIT_LEN)
640640

641+
#define FBNIC_RPC_CNTR_TCP_OPT_ERR 0x0849e /* 0x21278 */
642+
#define FBNIC_RPC_CNTR_UNKN_ETYPE 0x0849f /* 0x2127c */
643+
#define FBNIC_RPC_CNTR_IPV4_FRAG 0x084a0 /* 0x21280 */
644+
#define FBNIC_RPC_CNTR_IPV6_FRAG 0x084a1 /* 0x21284 */
645+
#define FBNIC_RPC_CNTR_IPV4_ESP 0x084a2 /* 0x21288 */
646+
#define FBNIC_RPC_CNTR_IPV6_ESP 0x084a3 /* 0x2128c */
647+
#define FBNIC_RPC_CNTR_UNKN_EXT_HDR 0x084a4 /* 0x21290 */
648+
#define FBNIC_RPC_CNTR_OUT_OF_HDR_ERR 0x084a5 /* 0x21294 */
649+
#define FBNIC_RPC_CNTR_OVR_SIZE_ERR 0x084a6 /* 0x21298 */
650+
641651
#define FBNIC_RPC_TCAM_MACDA_VALIDATE 0x0852d /* 0x214b4 */
642652
#define FBNIC_CSR_END_RPC 0x0856b /* CSR section delimiter */
643653

drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,37 @@
99
#include "fbnic_netdev.h"
1010
#include "fbnic_tlv.h"
1111

12+
struct fbnic_stat {
13+
u8 string[ETH_GSTRING_LEN];
14+
unsigned int size;
15+
unsigned int offset;
16+
};
17+
18+
#define FBNIC_STAT_FIELDS(type, name, stat) { \
19+
.string = name, \
20+
.size = sizeof_field(struct type, stat), \
21+
.offset = offsetof(struct type, stat), \
22+
}
23+
24+
/* Hardware statistics not captured in rtnl_link_stats */
25+
#define FBNIC_HW_STAT(name, stat) \
26+
FBNIC_STAT_FIELDS(fbnic_hw_stats, name, stat)
27+
28+
static const struct fbnic_stat fbnic_gstrings_hw_stats[] = {
29+
/* RPC */
30+
FBNIC_HW_STAT("rpc_unkn_etype", rpc.unkn_etype),
31+
FBNIC_HW_STAT("rpc_unkn_ext_hdr", rpc.unkn_ext_hdr),
32+
FBNIC_HW_STAT("rpc_ipv4_frag", rpc.ipv4_frag),
33+
FBNIC_HW_STAT("rpc_ipv6_frag", rpc.ipv6_frag),
34+
FBNIC_HW_STAT("rpc_ipv4_esp", rpc.ipv4_esp),
35+
FBNIC_HW_STAT("rpc_ipv6_esp", rpc.ipv6_esp),
36+
FBNIC_HW_STAT("rpc_tcp_opt_err", rpc.tcp_opt_err),
37+
FBNIC_HW_STAT("rpc_out_of_hdr_err", rpc.out_of_hdr_err),
38+
};
39+
40+
#define FBNIC_HW_FIXED_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_stats)
41+
#define FBNIC_HW_STATS_LEN FBNIC_HW_FIXED_STATS_LEN
42+
1243
static int
1344
fbnic_get_ts_info(struct net_device *netdev,
1445
struct kernel_ethtool_ts_info *tsinfo)
@@ -54,6 +85,43 @@ static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
5485
*stat = counter->value;
5586
}
5687

88+
static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
89+
{
90+
int i;
91+
92+
switch (sset) {
93+
case ETH_SS_STATS:
94+
for (i = 0; i < FBNIC_HW_STATS_LEN; i++)
95+
ethtool_puts(&data, fbnic_gstrings_hw_stats[i].string);
96+
break;
97+
}
98+
}
99+
100+
static int fbnic_get_sset_count(struct net_device *dev, int sset)
101+
{
102+
switch (sset) {
103+
case ETH_SS_STATS:
104+
return FBNIC_HW_STATS_LEN;
105+
default:
106+
return -EOPNOTSUPP;
107+
}
108+
}
109+
110+
static void fbnic_get_ethtool_stats(struct net_device *dev,
111+
struct ethtool_stats *stats, u64 *data)
112+
{
113+
struct fbnic_net *fbn = netdev_priv(dev);
114+
const struct fbnic_stat *stat;
115+
int i;
116+
117+
fbnic_get_hw_stats(fbn->fbd);
118+
119+
for (i = 0; i < FBNIC_HW_STATS_LEN; i++) {
120+
stat = &fbnic_gstrings_hw_stats[i];
121+
data[i] = *(u64 *)((u8 *)&fbn->fbd->hw_stats + stat->offset);
122+
}
123+
}
124+
57125
static void
58126
fbnic_get_eth_mac_stats(struct net_device *netdev,
59127
struct ethtool_eth_mac_stats *eth_mac_stats)
@@ -138,6 +206,9 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
138206
.get_drvinfo = fbnic_get_drvinfo,
139207
.get_regs_len = fbnic_get_regs_len,
140208
.get_regs = fbnic_get_regs,
209+
.get_strings = fbnic_get_strings,
210+
.get_ethtool_stats = fbnic_get_ethtool_stats,
211+
.get_sset_count = fbnic_get_sset_count,
141212
.get_ts_info = fbnic_get_ts_info,
142213
.get_ts_stats = fbnic_get_ts_stats,
143214
.get_eth_mac_stats = fbnic_get_eth_mac_stats,

drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,27 @@
33

44
#include "fbnic.h"
55

6+
static void fbnic_hw_stat_rst32(struct fbnic_dev *fbd, u32 reg,
7+
struct fbnic_stat_counter *stat)
8+
{
9+
/* We do not touch the "value" field here.
10+
* It gets zeroed out on fbd structure allocation.
11+
* After that we want it to grow continuously
12+
* through device resets and power state changes.
13+
*/
14+
stat->u.old_reg_value_32 = rd32(fbd, reg);
15+
}
16+
17+
static void fbnic_hw_stat_rd32(struct fbnic_dev *fbd, u32 reg,
18+
struct fbnic_stat_counter *stat)
19+
{
20+
u32 new_reg_value;
21+
22+
new_reg_value = rd32(fbd, reg);
23+
stat->value += new_reg_value - stat->u.old_reg_value_32;
24+
stat->u.old_reg_value_32 = new_reg_value;
25+
}
26+
627
u64 fbnic_stat_rd64(struct fbnic_dev *fbd, u32 reg, u32 offset)
728
{
829
u32 prev_upper, upper, lower, diff;
@@ -49,6 +70,53 @@ static void fbnic_hw_stat_rd64(struct fbnic_dev *fbd, u32 reg, s32 offset,
4970
stat->u.old_reg_value_64 = new_reg_value;
5071
}
5172

73+
static void fbnic_reset_rpc_stats(struct fbnic_dev *fbd,
74+
struct fbnic_rpc_stats *rpc)
75+
{
76+
fbnic_hw_stat_rst32(fbd,
77+
FBNIC_RPC_CNTR_UNKN_ETYPE,
78+
&rpc->unkn_etype);
79+
fbnic_hw_stat_rst32(fbd,
80+
FBNIC_RPC_CNTR_UNKN_EXT_HDR,
81+
&rpc->unkn_ext_hdr);
82+
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV4_FRAG, &rpc->ipv4_frag);
83+
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV6_FRAG, &rpc->ipv6_frag);
84+
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV4_ESP, &rpc->ipv4_esp);
85+
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV6_ESP, &rpc->ipv6_esp);
86+
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_TCP_OPT_ERR, &rpc->tcp_opt_err);
87+
fbnic_hw_stat_rst32(fbd,
88+
FBNIC_RPC_CNTR_OUT_OF_HDR_ERR,
89+
&rpc->out_of_hdr_err);
90+
fbnic_hw_stat_rst32(fbd,
91+
FBNIC_RPC_CNTR_OVR_SIZE_ERR,
92+
&rpc->ovr_size_err);
93+
}
94+
95+
static void fbnic_get_rpc_stats32(struct fbnic_dev *fbd,
96+
struct fbnic_rpc_stats *rpc)
97+
{
98+
fbnic_hw_stat_rd32(fbd,
99+
FBNIC_RPC_CNTR_UNKN_ETYPE,
100+
&rpc->unkn_etype);
101+
fbnic_hw_stat_rd32(fbd,
102+
FBNIC_RPC_CNTR_UNKN_EXT_HDR,
103+
&rpc->unkn_ext_hdr);
104+
105+
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV4_FRAG, &rpc->ipv4_frag);
106+
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV6_FRAG, &rpc->ipv6_frag);
107+
108+
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV4_ESP, &rpc->ipv4_esp);
109+
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV6_ESP, &rpc->ipv6_esp);
110+
111+
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_TCP_OPT_ERR, &rpc->tcp_opt_err);
112+
fbnic_hw_stat_rd32(fbd,
113+
FBNIC_RPC_CNTR_OUT_OF_HDR_ERR,
114+
&rpc->out_of_hdr_err);
115+
fbnic_hw_stat_rd32(fbd,
116+
FBNIC_RPC_CNTR_OVR_SIZE_ERR,
117+
&rpc->ovr_size_err);
118+
}
119+
52120
static void fbnic_reset_pcie_stats_asic(struct fbnic_dev *fbd,
53121
struct fbnic_pcie_stats *pcie)
54122
{
@@ -135,10 +203,18 @@ static void fbnic_get_pcie_stats_asic64(struct fbnic_dev *fbd,
135203

136204
void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
137205
{
206+
fbnic_reset_rpc_stats(fbd, &fbd->hw_stats.rpc);
138207
fbnic_reset_pcie_stats_asic(fbd, &fbd->hw_stats.pcie);
139208
}
140209

210+
void fbnic_get_hw_stats32(struct fbnic_dev *fbd)
211+
{
212+
fbnic_get_rpc_stats32(fbd, &fbd->hw_stats.rpc);
213+
}
214+
141215
void fbnic_get_hw_stats(struct fbnic_dev *fbd)
142216
{
217+
fbnic_get_hw_stats32(fbd);
218+
143219
fbnic_get_pcie_stats_asic64(fbd, &fbd->hw_stats.pcie);
144220
}

drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ struct fbnic_mac_stats {
3737
struct fbnic_eth_mac_stats eth_mac;
3838
};
3939

40+
struct fbnic_rpc_stats {
41+
struct fbnic_stat_counter unkn_etype, unkn_ext_hdr;
42+
struct fbnic_stat_counter ipv4_frag, ipv6_frag, ipv4_esp, ipv6_esp;
43+
struct fbnic_stat_counter tcp_opt_err, out_of_hdr_err, ovr_size_err;
44+
};
45+
4046
struct fbnic_pcie_stats {
4147
struct fbnic_stat_counter ob_rd_tlp, ob_rd_dword;
4248
struct fbnic_stat_counter ob_wr_tlp, ob_wr_dword;
@@ -49,12 +55,14 @@ struct fbnic_pcie_stats {
4955

5056
struct fbnic_hw_stats {
5157
struct fbnic_mac_stats mac;
58+
struct fbnic_rpc_stats rpc;
5259
struct fbnic_pcie_stats pcie;
5360
};
5461

5562
u64 fbnic_stat_rd64(struct fbnic_dev *fbd, u32 reg, u32 offset);
5663

5764
void fbnic_reset_hw_stats(struct fbnic_dev *fbd);
65+
void fbnic_get_hw_stats32(struct fbnic_dev *fbd);
5866
void fbnic_get_hw_stats(struct fbnic_dev *fbd);
5967

6068
#endif /* _FBNIC_HW_STATS_H_ */

drivers/net/ethernet/meta/fbnic/fbnic_pci.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ static void fbnic_service_task(struct work_struct *work)
199199

200200
rtnl_lock();
201201

202+
fbnic_get_hw_stats32(fbd);
203+
202204
fbnic_fw_check_heartbeat(fbd);
203205

204206
fbnic_health_check(fbd);

0 commit comments

Comments
 (0)