xref: /freebsd/sys/dev/rge/if_rge_sysctl.c (revision 4bf8ce037dc8fa699be87350bb6467f1b74cb96d)
1*4bf8ce03SAdrian Chadd /*-
2*4bf8ce03SAdrian Chadd  * SPDX-License-Identifier: BSD-2-Clause
3*4bf8ce03SAdrian Chadd  *
4*4bf8ce03SAdrian Chadd  * Copyright (c) 2025 Adrian Chadd <adrian@FreeBSD.org>
5*4bf8ce03SAdrian Chadd  *
6*4bf8ce03SAdrian Chadd  * Permission to use, copy, modify, and distribute this software for any
7*4bf8ce03SAdrian Chadd  * purpose with or without fee is hereby granted, provided that the above
8*4bf8ce03SAdrian Chadd  * copyright notice and this permission notice appear in all copies.
9*4bf8ce03SAdrian Chadd  *
10*4bf8ce03SAdrian Chadd  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*4bf8ce03SAdrian Chadd  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*4bf8ce03SAdrian Chadd  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*4bf8ce03SAdrian Chadd  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*4bf8ce03SAdrian Chadd  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*4bf8ce03SAdrian Chadd  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*4bf8ce03SAdrian Chadd  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*4bf8ce03SAdrian Chadd  */
18*4bf8ce03SAdrian Chadd 
19*4bf8ce03SAdrian Chadd #include <sys/param.h>
20*4bf8ce03SAdrian Chadd #include <sys/systm.h>
21*4bf8ce03SAdrian Chadd #include <sys/sysctl.h>
22*4bf8ce03SAdrian Chadd #include <sys/sockio.h>
23*4bf8ce03SAdrian Chadd #include <sys/mbuf.h>
24*4bf8ce03SAdrian Chadd #include <sys/malloc.h>
25*4bf8ce03SAdrian Chadd #include <sys/endian.h>
26*4bf8ce03SAdrian Chadd #include <sys/socket.h>
27*4bf8ce03SAdrian Chadd #include <net/if.h>
28*4bf8ce03SAdrian Chadd #include <net/if_media.h>
29*4bf8ce03SAdrian Chadd #include <sys/queue.h>
30*4bf8ce03SAdrian Chadd #include <sys/taskqueue.h>
31*4bf8ce03SAdrian Chadd #include <sys/bus.h>
32*4bf8ce03SAdrian Chadd #include <sys/module.h>
33*4bf8ce03SAdrian Chadd #include <sys/rman.h>
34*4bf8ce03SAdrian Chadd 
35*4bf8ce03SAdrian Chadd #include <netinet/in.h>
36*4bf8ce03SAdrian Chadd #include <netinet/if_ether.h>
37*4bf8ce03SAdrian Chadd 
38*4bf8ce03SAdrian Chadd #include <net/bpf.h>
39*4bf8ce03SAdrian Chadd #include <net/ethernet.h>
40*4bf8ce03SAdrian Chadd #include <net/if.h>
41*4bf8ce03SAdrian Chadd #include <net/if_var.h>
42*4bf8ce03SAdrian Chadd #include <net/if_arp.h>
43*4bf8ce03SAdrian Chadd #include <net/if_dl.h>
44*4bf8ce03SAdrian Chadd #include <net/if_media.h>
45*4bf8ce03SAdrian Chadd #include <net/if_types.h>
46*4bf8ce03SAdrian Chadd #include <net/if_vlan_var.h>
47*4bf8ce03SAdrian Chadd 
48*4bf8ce03SAdrian Chadd #include <machine/bus.h>
49*4bf8ce03SAdrian Chadd #include <machine/resource.h>
50*4bf8ce03SAdrian Chadd 
51*4bf8ce03SAdrian Chadd #include <dev/mii/mii.h>
52*4bf8ce03SAdrian Chadd 
53*4bf8ce03SAdrian Chadd #include <dev/pci/pcivar.h>
54*4bf8ce03SAdrian Chadd #include <dev/pci/pcireg.h>
55*4bf8ce03SAdrian Chadd 
56*4bf8ce03SAdrian Chadd #include "if_rge_vendor.h"
57*4bf8ce03SAdrian Chadd #include "if_rgereg.h"
58*4bf8ce03SAdrian Chadd #include "if_rgevar.h"
59*4bf8ce03SAdrian Chadd #include "if_rge_debug.h"
60*4bf8ce03SAdrian Chadd #include "if_rge_sysctl.h"
61*4bf8ce03SAdrian Chadd 
62*4bf8ce03SAdrian Chadd static void
rge_sysctl_drv_stats_attach(struct rge_softc * sc)63*4bf8ce03SAdrian Chadd rge_sysctl_drv_stats_attach(struct rge_softc *sc)
64*4bf8ce03SAdrian Chadd {
65*4bf8ce03SAdrian Chadd 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
66*4bf8ce03SAdrian Chadd 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
67*4bf8ce03SAdrian Chadd 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
68*4bf8ce03SAdrian Chadd 
69*4bf8ce03SAdrian Chadd 	/* Create stats node */
70*4bf8ce03SAdrian Chadd 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "drv_stats",
71*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "driver statistics");
72*4bf8ce03SAdrian Chadd 	child = SYSCTL_CHILDREN(tree);
73*4bf8ce03SAdrian Chadd 
74*4bf8ce03SAdrian Chadd 	/* Driver stats */
75*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "transmit_call_cnt", CTLFLAG_RD,
76*4bf8ce03SAdrian Chadd 	    &sc->sc_drv_stats.transmit_call_cnt, "Calls to rge_transmit");
77*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "transmit_stopped_cnt",
78*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.transmit_stopped_cnt,
79*4bf8ce03SAdrian Chadd 	        "rge_transmit calls to a stopped interface");
80*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "transmit_full_cnt",
81*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.transmit_full_cnt,
82*4bf8ce03SAdrian Chadd 	        "rge_transmit calls to a full tx queue");
83*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "transmit_queued_cnt",
84*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.transmit_queued_cnt,
85*4bf8ce03SAdrian Chadd 	        "rge_transmit calls which queued a frame");
86*4bf8ce03SAdrian Chadd 
87*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "intr_cnt",
88*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.intr_cnt,
89*4bf8ce03SAdrian Chadd 	        "incoming interrupts");
90*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "intr_system_errcnt",
91*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.intr_system_err_cnt,
92*4bf8ce03SAdrian Chadd 	        "INTR_SYSTEM_ERR interrupt leading to a hardware reset");
93*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rxeof_cnt",
94*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rxeof_cnt,
95*4bf8ce03SAdrian Chadd 	        "calls to rxeof() to process RX frames");
96*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "txeof_cnt",
97*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.txeof_cnt,
98*4bf8ce03SAdrian Chadd 	        "calls to rxeof() to process TX frame completions");
99*4bf8ce03SAdrian Chadd 
100*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "link_state_change_cnt",
101*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.link_state_change_cnt,
102*4bf8ce03SAdrian Chadd 	        "link state changes");
103*4bf8ce03SAdrian Chadd 
104*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "tx_task_cnt",
105*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.tx_task_cnt,
106*4bf8ce03SAdrian Chadd 	        "calls to tx_task task to send queued frames");
107*4bf8ce03SAdrian Chadd 
108*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "recv_input_cnt",
109*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.recv_input_cnt,
110*4bf8ce03SAdrian Chadd 	        "calls to if_input to process frames");
111*4bf8ce03SAdrian Chadd 
112*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_desc_err_multidesc",
113*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_desc_err_multidesc,
114*4bf8ce03SAdrian Chadd 	        "multi-descriptor RX frames (unsupported, so dropped)");
115*4bf8ce03SAdrian Chadd 
116*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "tx_watchdog_timeout_cnt",
117*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.tx_watchdog_timeout_cnt,
118*4bf8ce03SAdrian Chadd 	        "TX watchdog timeouts");
119*4bf8ce03SAdrian Chadd 
120*4bf8ce03SAdrian Chadd 	/* TX encap counters */
121*4bf8ce03SAdrian Chadd 
122*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "tx_encap_cnt",
123*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.tx_encap_cnt, "calls to rge_encap()");
124*4bf8ce03SAdrian Chadd 
125*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "tx_encap_refrag_cnt",
126*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.tx_encap_refrag_cnt,
127*4bf8ce03SAdrian Chadd 	    "How often rge_encap() has re-linearised TX mbufs");
128*4bf8ce03SAdrian Chadd 
129*4bf8ce03SAdrian Chadd 	/* TX checksum counters */
130*4bf8ce03SAdrian Chadd 
131*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "tx_encap_err_toofrag",
132*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.tx_encap_err_toofrag,
133*4bf8ce03SAdrian Chadd 	    "How often rge_encap() failed to defrag a TX mbuf");
134*4bf8ce03SAdrian Chadd 
135*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "tx_offload_ip_csum_set",
136*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.tx_offload_ip_csum_set,
137*4bf8ce03SAdrian Chadd 	    "Number of frames with TX'ed with IPv4 checksum offload set");
138*4bf8ce03SAdrian Chadd 
139*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "tx_offload_tcp_csum_set",
140*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.tx_offload_tcp_csum_set,
141*4bf8ce03SAdrian Chadd 	    "Number of frames TX'ed with TCP checksum offload set");
142*4bf8ce03SAdrian Chadd 
143*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "tx_offload_udp_csum_set",
144*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.tx_offload_udp_csum_set,
145*4bf8ce03SAdrian Chadd 	    "Number of frames TX'ed with UDP checksum offload set");
146*4bf8ce03SAdrian Chadd 
147*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "tx_offload_vlan_tag_set",
148*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.tx_offload_vlan_tag_set,
149*4bf8ce03SAdrian Chadd 	    "Number of frames TX'ed with VLAN offload tag set");
150*4bf8ce03SAdrian Chadd 
151*4bf8ce03SAdrian Chadd 	/* RX counters */
152*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_ether_csum_err",
153*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_ether_csum_err,
154*4bf8ce03SAdrian Chadd 	    "Number of frames RX'ed with invalid ethernet CRC");
155*4bf8ce03SAdrian Chadd 
156*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_offload_vlan_tag",
157*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_offload_vlan_tag,
158*4bf8ce03SAdrian Chadd 	    "Number of frames RX'ed with offload VLAN tag");
159*4bf8ce03SAdrian Chadd 
160*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_jumbo_frag",
161*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_desc_jumbo_frag,
162*4bf8ce03SAdrian Chadd 	    "Number of descriptors RX'ed as part of a multi-descriptor frame");
163*4bf8ce03SAdrian Chadd 
164*4bf8ce03SAdrian Chadd 	/* RX checksum offload counters */
165*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_offload_csum_ipv4_exists",
166*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_offload_csum_ipv4_exists,
167*4bf8ce03SAdrian Chadd 	    "Number of frames RX'ed with IPv4 checksum offload set");
168*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_offload_csum_ipv4_valid",
169*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_offload_csum_ipv4_valid,
170*4bf8ce03SAdrian Chadd 	    "Number of frames RX'ed with IPv4 checksum offload valid");
171*4bf8ce03SAdrian Chadd 
172*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_offload_csum_tcp_exists",
173*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_offload_csum_tcp_exists,
174*4bf8ce03SAdrian Chadd 	    "Number of frames RX'ed with TCP checksum offload set");
175*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_offload_csum_tcp_valid",
176*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_offload_csum_tcp_valid,
177*4bf8ce03SAdrian Chadd 	    "Number of frames RX'ed with TCP checksum offload valid");
178*4bf8ce03SAdrian Chadd 
179*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_offload_csum_udp_exists",
180*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_offload_csum_udp_exists,
181*4bf8ce03SAdrian Chadd 	    "Number of frames RX'ed with UDP checksum offload set");
182*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rx_offload_csum_udp_valid",
183*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD, &sc->sc_drv_stats.rx_offload_csum_udp_valid,
184*4bf8ce03SAdrian Chadd 	    "Number of frames RX'ed with UDP checksum offload valid");
185*4bf8ce03SAdrian Chadd }
186*4bf8ce03SAdrian Chadd 
187*4bf8ce03SAdrian Chadd static void
rge_sysctl_mac_stats_attach(struct rge_softc * sc)188*4bf8ce03SAdrian Chadd rge_sysctl_mac_stats_attach(struct rge_softc *sc)
189*4bf8ce03SAdrian Chadd {
190*4bf8ce03SAdrian Chadd 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
191*4bf8ce03SAdrian Chadd 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
192*4bf8ce03SAdrian Chadd 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
193*4bf8ce03SAdrian Chadd 	struct rge_mac_stats *ss = &sc->sc_mac_stats;
194*4bf8ce03SAdrian Chadd 
195*4bf8ce03SAdrian Chadd 	/* Create stats node */
196*4bf8ce03SAdrian Chadd 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac_stats",
197*4bf8ce03SAdrian Chadd 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "mac statistics");
198*4bf8ce03SAdrian Chadd 	child = SYSCTL_CHILDREN(tree);
199*4bf8ce03SAdrian Chadd 
200*4bf8ce03SAdrian Chadd 	/* MAC statistics */
201*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rge_tx_ok", CTLFLAG_RD,
202*4bf8ce03SAdrian Chadd 	    &ss->lcl_stats.rge_tx_ok, "");
203*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rge_rx_ok", CTLFLAG_RD,
204*4bf8ce03SAdrian Chadd 	    &ss->lcl_stats.rge_rx_ok, "");
205*4bf8ce03SAdrian Chadd 
206*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rge_tx_er", CTLFLAG_RD,
207*4bf8ce03SAdrian Chadd 	    &ss->lcl_stats.rge_tx_er, "");
208*4bf8ce03SAdrian Chadd 	/* uint32_t rge_rx_er */
209*4bf8ce03SAdrian Chadd 
210*4bf8ce03SAdrian Chadd 	/* uint16_t rge_miss_pkt */
211*4bf8ce03SAdrian Chadd 	/* uint16_t rge_fae */
212*4bf8ce03SAdrian Chadd 	/* uint32_t rge_tx_1col */
213*4bf8ce03SAdrian Chadd 	/* uint32_t rge_tx_mcol */
214*4bf8ce03SAdrian Chadd 
215*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rge_rx_ok_phy", CTLFLAG_RD,
216*4bf8ce03SAdrian Chadd 	    &ss->lcl_stats.rge_rx_ok_phy, "");
217*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "rge_rx_ok_brd", CTLFLAG_RD,
218*4bf8ce03SAdrian Chadd 	    &ss->lcl_stats.rge_rx_ok_brd, "");
219*4bf8ce03SAdrian Chadd 
220*4bf8ce03SAdrian Chadd 	/* uint32_t rge_rx_ok_mul */
221*4bf8ce03SAdrian Chadd 	/* uint16_t rge_tx_abt */
222*4bf8ce03SAdrian Chadd 	/* uint16_t rge_tx_undrn */
223*4bf8ce03SAdrian Chadd }
224*4bf8ce03SAdrian Chadd 
225*4bf8ce03SAdrian Chadd void
rge_sysctl_attach(struct rge_softc * sc)226*4bf8ce03SAdrian Chadd rge_sysctl_attach(struct rge_softc *sc)
227*4bf8ce03SAdrian Chadd {
228*4bf8ce03SAdrian Chadd 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
229*4bf8ce03SAdrian Chadd 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
230*4bf8ce03SAdrian Chadd 
231*4bf8ce03SAdrian Chadd 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
232*4bf8ce03SAdrian Chadd 	    "debug", CTLFLAG_RW, &sc->sc_debug, 0,
233*4bf8ce03SAdrian Chadd 	    "control debugging printfs");
234*4bf8ce03SAdrian Chadd 
235*4bf8ce03SAdrian Chadd 	/* Stats */
236*4bf8ce03SAdrian Chadd 	rge_sysctl_drv_stats_attach(sc);
237*4bf8ce03SAdrian Chadd 	rge_sysctl_mac_stats_attach(sc);
238*4bf8ce03SAdrian Chadd }
239