xref: /freebsd/sys/dev/gve/gve_sysctl.c (revision 71702df6126226b31dc3ec66459388e32b993be1)
154dfc97bSShailend Chand /*-
254dfc97bSShailend Chand  * SPDX-License-Identifier: BSD-3-Clause
354dfc97bSShailend Chand  *
4d438b4efSShailend Chand  * Copyright (c) 2023-2024 Google LLC
554dfc97bSShailend Chand  *
654dfc97bSShailend Chand  * Redistribution and use in source and binary forms, with or without modification,
754dfc97bSShailend Chand  * are permitted provided that the following conditions are met:
854dfc97bSShailend Chand  *
954dfc97bSShailend Chand  * 1. Redistributions of source code must retain the above copyright notice, this
1054dfc97bSShailend Chand  *    list of conditions and the following disclaimer.
1154dfc97bSShailend Chand  *
1254dfc97bSShailend Chand  * 2. Redistributions in binary form must reproduce the above copyright notice,
1354dfc97bSShailend Chand  *    this list of conditions and the following disclaimer in the documentation
1454dfc97bSShailend Chand  *    and/or other materials provided with the distribution.
1554dfc97bSShailend Chand  *
1654dfc97bSShailend Chand  * 3. Neither the name of the copyright holder nor the names of its contributors
1754dfc97bSShailend Chand  *    may be used to endorse or promote products derived from this software without
1854dfc97bSShailend Chand  *    specific prior written permission.
1954dfc97bSShailend Chand  *
2054dfc97bSShailend Chand  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2154dfc97bSShailend Chand  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2254dfc97bSShailend Chand  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2354dfc97bSShailend Chand  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
2454dfc97bSShailend Chand  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2554dfc97bSShailend Chand  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2654dfc97bSShailend Chand  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2754dfc97bSShailend Chand  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2854dfc97bSShailend Chand  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2954dfc97bSShailend Chand  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3054dfc97bSShailend Chand  */
3154dfc97bSShailend Chand #include "gve.h"
3254dfc97bSShailend Chand 
33d438b4efSShailend Chand static SYSCTL_NODE(_hw, OID_AUTO, gve, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
34d438b4efSShailend Chand     "GVE driver parameters");
35d438b4efSShailend Chand 
36d438b4efSShailend Chand bool gve_disable_hw_lro = false;
37d438b4efSShailend Chand SYSCTL_BOOL(_hw_gve, OID_AUTO, disable_hw_lro, CTLFLAG_RDTUN,
38d438b4efSShailend Chand     &gve_disable_hw_lro, 0, "Controls if hardware LRO is used");
39d438b4efSShailend Chand 
40*71702df6SVee Agarwal bool gve_allow_4k_rx_buffers = false;
41*71702df6SVee Agarwal SYSCTL_BOOL(_hw_gve, OID_AUTO, allow_4k_rx_buffers, CTLFLAG_RDTUN,
42*71702df6SVee Agarwal     &gve_allow_4k_rx_buffers, 0, "Controls if 4K RX Buffers are allowed");
43*71702df6SVee Agarwal 
44d438b4efSShailend Chand char gve_queue_format[8];
45d438b4efSShailend Chand SYSCTL_STRING(_hw_gve, OID_AUTO, queue_format, CTLFLAG_RD,
46d438b4efSShailend Chand     &gve_queue_format, 0, "Queue format being used by the iface");
47d438b4efSShailend Chand 
48d438b4efSShailend Chand char gve_version[8];
49d438b4efSShailend Chand SYSCTL_STRING(_hw_gve, OID_AUTO, driver_version, CTLFLAG_RD,
50d438b4efSShailend Chand     &gve_version, 0, "Driver version");
51d438b4efSShailend Chand 
5254dfc97bSShailend Chand static void
gve_setup_rxq_sysctl(struct sysctl_ctx_list * ctx,struct sysctl_oid_list * child,struct gve_rx_ring * rxq)5354dfc97bSShailend Chand gve_setup_rxq_sysctl(struct sysctl_ctx_list *ctx,
5454dfc97bSShailend Chand     struct sysctl_oid_list *child, struct gve_rx_ring *rxq)
5554dfc97bSShailend Chand {
5654dfc97bSShailend Chand 	struct sysctl_oid *node;
5754dfc97bSShailend Chand 	struct sysctl_oid_list *list;
5854dfc97bSShailend Chand 	struct gve_rxq_stats *stats;
5954dfc97bSShailend Chand 	char namebuf[16];
6054dfc97bSShailend Chand 
6154dfc97bSShailend Chand 	snprintf(namebuf, sizeof(namebuf), "rxq%d", rxq->com.id);
6254dfc97bSShailend Chand 	node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
6354dfc97bSShailend Chand 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Receive Queue");
6454dfc97bSShailend Chand 	list = SYSCTL_CHILDREN(node);
6554dfc97bSShailend Chand 
6654dfc97bSShailend Chand 	stats = &rxq->stats;
6754dfc97bSShailend Chand 
6854dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
6954dfc97bSShailend Chand 	    "rx_bytes", CTLFLAG_RD,
7054dfc97bSShailend Chand 	    &stats->rbytes, "Bytes received");
7154dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
7254dfc97bSShailend Chand 	    "rx_packets", CTLFLAG_RD,
7354dfc97bSShailend Chand 	    &stats->rpackets, "Packets received");
7454dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO, "rx_copybreak_cnt",
7554dfc97bSShailend Chand 	    CTLFLAG_RD, &stats->rx_copybreak_cnt,
7654dfc97bSShailend Chand 	    "Total frags with mbufs allocated for copybreak");
7754dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO, "rx_frag_flip_cnt",
7854dfc97bSShailend Chand 	    CTLFLAG_RD, &stats->rx_frag_flip_cnt,
7954dfc97bSShailend Chand 	    "Total frags that allocated mbuf with page flip");
8054dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO, "rx_frag_copy_cnt",
8154dfc97bSShailend Chand 	    CTLFLAG_RD, &stats->rx_frag_copy_cnt,
8254dfc97bSShailend Chand 	    "Total frags with mbuf that copied payload into mbuf");
8354dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO, "rx_dropped_pkt",
8454dfc97bSShailend Chand 	    CTLFLAG_RD, &stats->rx_dropped_pkt,
8554dfc97bSShailend Chand 	    "Total rx packets dropped");
8654dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
8754dfc97bSShailend Chand 	    "rx_dropped_pkt_desc_err", CTLFLAG_RD,
8854dfc97bSShailend Chand 	    &stats->rx_dropped_pkt_desc_err,
8954dfc97bSShailend Chand 	    "Packets dropped due to descriptor error");
9054dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
912348ac89SShailend Chand 	    "rx_dropped_pkt_buf_post_fail", CTLFLAG_RD,
922348ac89SShailend Chand 	    &stats->rx_dropped_pkt_buf_post_fail,
932348ac89SShailend Chand 	    "Packets dropped due to failure to post enough buffers");
942348ac89SShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
9554dfc97bSShailend Chand 	    "rx_dropped_pkt_mbuf_alloc_fail", CTLFLAG_RD,
9654dfc97bSShailend Chand 	    &stats->rx_dropped_pkt_mbuf_alloc_fail,
9754dfc97bSShailend Chand 	    "Packets dropped due to failed mbuf allocation");
98d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
99d438b4efSShailend Chand 	    "rx_mbuf_dmamap_err", CTLFLAG_RD,
100d438b4efSShailend Chand 	    &stats->rx_mbuf_dmamap_err,
101031800c7SJasper Tran O'Leary 	    "Number of rx mbufs which could not be dma mapped");
102d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
103d438b4efSShailend Chand 	    "rx_mbuf_mclget_null", CTLFLAG_RD,
104d438b4efSShailend Chand 	    &stats->rx_mbuf_mclget_null,
105d438b4efSShailend Chand 	    "Number of times when there were no cluster mbufs");
10654dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, list, OID_AUTO,
10754dfc97bSShailend Chand 	    "rx_completed_desc", CTLFLAG_RD,
10854dfc97bSShailend Chand 	    &rxq->cnt, 0, "Number of descriptors completed");
10954dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, list, OID_AUTO,
11054dfc97bSShailend Chand 	    "num_desc_posted", CTLFLAG_RD,
11154dfc97bSShailend Chand 	    &rxq->fill_cnt, rxq->fill_cnt,
11254dfc97bSShailend Chand 	    "Toal number of descriptors posted");
11354dfc97bSShailend Chand }
11454dfc97bSShailend Chand 
11554dfc97bSShailend Chand static void
gve_setup_txq_sysctl(struct sysctl_ctx_list * ctx,struct sysctl_oid_list * child,struct gve_tx_ring * txq)11654dfc97bSShailend Chand gve_setup_txq_sysctl(struct sysctl_ctx_list *ctx,
11754dfc97bSShailend Chand     struct sysctl_oid_list *child, struct gve_tx_ring *txq)
11854dfc97bSShailend Chand {
11954dfc97bSShailend Chand 	struct sysctl_oid *node;
12054dfc97bSShailend Chand 	struct sysctl_oid_list *tx_list;
12154dfc97bSShailend Chand 	struct gve_txq_stats *stats;
12254dfc97bSShailend Chand 	char namebuf[16];
12354dfc97bSShailend Chand 
12454dfc97bSShailend Chand 	snprintf(namebuf, sizeof(namebuf), "txq%d", txq->com.id);
12554dfc97bSShailend Chand 	node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
12654dfc97bSShailend Chand 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Transmit Queue");
12754dfc97bSShailend Chand 	tx_list = SYSCTL_CHILDREN(node);
12854dfc97bSShailend Chand 
12954dfc97bSShailend Chand 	stats = &txq->stats;
13054dfc97bSShailend Chand 
13154dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, tx_list, OID_AUTO,
13254dfc97bSShailend Chand 	    "tx_posted_desc", CTLFLAG_RD,
13354dfc97bSShailend Chand 	    &txq->req, 0, "Number of descriptors posted by NIC");
13454dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, tx_list, OID_AUTO,
13554dfc97bSShailend Chand 	    "tx_completed_desc", CTLFLAG_RD,
13654dfc97bSShailend Chand 	    &txq->done, 0, "Number of descriptors completed");
13754dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
13854dfc97bSShailend Chand 	    "tx_packets", CTLFLAG_RD,
13954dfc97bSShailend Chand 	    &stats->tpackets, "Packets transmitted");
14054dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
14154dfc97bSShailend Chand 	    "tx_tso_packets", CTLFLAG_RD,
14254dfc97bSShailend Chand 	    &stats->tso_packet_cnt, "TSO Packets transmitted");
14354dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
14454dfc97bSShailend Chand 	    "tx_bytes", CTLFLAG_RD,
14554dfc97bSShailend Chand 	    &stats->tbytes, "Bytes transmitted");
14654dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
14740097cd6SShailend Chand 	    "tx_delayed_pkt_nospace_device", CTLFLAG_RD,
14840097cd6SShailend Chand 	    &stats->tx_delayed_pkt_nospace_device,
14940097cd6SShailend Chand 	    "Packets delayed due to no space in device");
15054dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
15154dfc97bSShailend Chand 	    "tx_dropped_pkt_nospace_bufring", CTLFLAG_RD,
15254dfc97bSShailend Chand 	    &stats->tx_dropped_pkt_nospace_bufring,
15354dfc97bSShailend Chand 	    "Packets dropped due to no space in br ring");
15454dfc97bSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
15554dfc97bSShailend Chand 	    "tx_dropped_pkt_vlan", CTLFLAG_RD,
15654dfc97bSShailend Chand 	    &stats->tx_dropped_pkt_vlan,
15754dfc97bSShailend Chand 	    "Dropped VLAN packets");
158d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
159d438b4efSShailend Chand 	    "tx_delayed_pkt_nospace_descring", CTLFLAG_RD,
160d438b4efSShailend Chand 	    &stats->tx_delayed_pkt_nospace_descring,
161d438b4efSShailend Chand 	    "Packets delayed due to no space in desc ring");
162d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
163d438b4efSShailend Chand 	    "tx_delayed_pkt_nospace_compring", CTLFLAG_RD,
164d438b4efSShailend Chand 	    &stats->tx_delayed_pkt_nospace_compring,
165d438b4efSShailend Chand 	    "Packets delayed due to no space in comp ring");
166d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
1672348ac89SShailend Chand 	    "tx_delayed_pkt_nospace_qpl_bufs", CTLFLAG_RD,
1682348ac89SShailend Chand 	    &stats->tx_delayed_pkt_nospace_qpl_bufs,
1692348ac89SShailend Chand 	    "Packets delayed due to not enough qpl bufs");
1702348ac89SShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
171d438b4efSShailend Chand 	    "tx_delayed_pkt_tsoerr", CTLFLAG_RD,
172d438b4efSShailend Chand 	    &stats->tx_delayed_pkt_tsoerr,
173d438b4efSShailend Chand 	    "TSO packets delayed due to err in prep errors");
174d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
1753d295733SJasper Tran O'Leary 	    "tx_mbuf_collapse", CTLFLAG_RD,
176d438b4efSShailend Chand 	    &stats->tx_mbuf_collapse,
177031800c7SJasper Tran O'Leary 	    "tx mbufs that had to be collapsed");
178d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
179d438b4efSShailend Chand 	    "tx_mbuf_defrag", CTLFLAG_RD,
180d438b4efSShailend Chand 	    &stats->tx_mbuf_defrag,
181d438b4efSShailend Chand 	    "tx mbufs that had to be defragged");
182d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
183d438b4efSShailend Chand 	    "tx_mbuf_defrag_err", CTLFLAG_RD,
184d438b4efSShailend Chand 	    &stats->tx_mbuf_defrag_err,
185d438b4efSShailend Chand 	    "tx mbufs that failed defrag");
186d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
187d438b4efSShailend Chand 	    "tx_mbuf_dmamap_enomem_err", CTLFLAG_RD,
188d438b4efSShailend Chand 	    &stats->tx_mbuf_dmamap_enomem_err,
189d438b4efSShailend Chand 	    "tx mbufs that could not be dma-mapped due to low mem");
190d438b4efSShailend Chand 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
191d438b4efSShailend Chand 	    "tx_mbuf_dmamap_err", CTLFLAG_RD,
192d438b4efSShailend Chand 	    &stats->tx_mbuf_dmamap_err,
193d438b4efSShailend Chand 	    "tx mbufs that could not be dma-mapped");
1943d295733SJasper Tran O'Leary 	SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
1953d295733SJasper Tran O'Leary 	    "tx_timeout", CTLFLAG_RD,
1963d295733SJasper Tran O'Leary 	    &stats->tx_timeout,
1973d295733SJasper Tran O'Leary 	    "detections of timed out packets on tx queues");
19854dfc97bSShailend Chand }
19954dfc97bSShailend Chand 
20054dfc97bSShailend Chand static void
gve_setup_queue_stat_sysctl(struct sysctl_ctx_list * ctx,struct sysctl_oid_list * child,struct gve_priv * priv)20154dfc97bSShailend Chand gve_setup_queue_stat_sysctl(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *child,
20254dfc97bSShailend Chand     struct gve_priv *priv)
20354dfc97bSShailend Chand {
20454dfc97bSShailend Chand 	int i;
20554dfc97bSShailend Chand 
20654dfc97bSShailend Chand 	for (i = 0; i < priv->rx_cfg.num_queues; i++) {
20754dfc97bSShailend Chand 		gve_setup_rxq_sysctl(ctx, child, &priv->rx[i]);
20854dfc97bSShailend Chand 	}
20954dfc97bSShailend Chand 	for (i = 0; i < priv->tx_cfg.num_queues; i++) {
21054dfc97bSShailend Chand 		gve_setup_txq_sysctl(ctx, child, &priv->tx[i]);
21154dfc97bSShailend Chand 	}
21254dfc97bSShailend Chand }
21354dfc97bSShailend Chand 
21454dfc97bSShailend Chand static void
gve_setup_adminq_stat_sysctl(struct sysctl_ctx_list * ctx,struct sysctl_oid_list * child,struct gve_priv * priv)21554dfc97bSShailend Chand gve_setup_adminq_stat_sysctl(struct sysctl_ctx_list *ctx,
21654dfc97bSShailend Chand     struct sysctl_oid_list *child, struct gve_priv *priv)
21754dfc97bSShailend Chand {
21854dfc97bSShailend Chand 	struct sysctl_oid *admin_node;
21954dfc97bSShailend Chand 	struct sysctl_oid_list *admin_list;
22054dfc97bSShailend Chand 
22154dfc97bSShailend Chand 	/* Admin queue stats */
22254dfc97bSShailend Chand 	admin_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "adminq_stats",
22354dfc97bSShailend Chand 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Admin Queue statistics");
22454dfc97bSShailend Chand 	admin_list = SYSCTL_CHILDREN(admin_node);
22554dfc97bSShailend Chand 
22654dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_prod_cnt", CTLFLAG_RD,
22754dfc97bSShailend Chand 	    &priv->adminq_prod_cnt, 0, "Adminq Commands issued");
22854dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_cmd_fail", CTLFLAG_RD,
22954dfc97bSShailend Chand 	    &priv->adminq_cmd_fail, 0, "Aqminq Failed commands");
23054dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_timeouts", CTLFLAG_RD,
23154dfc97bSShailend Chand 	    &priv->adminq_timeouts, 0, "Adminq Timedout commands");
23254dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_describe_device_cnt",
23354dfc97bSShailend Chand 	    CTLFLAG_RD, &priv->adminq_describe_device_cnt, 0,
23454dfc97bSShailend Chand 	    "adminq_describe_device_cnt");
23554dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
23654dfc97bSShailend Chand 	    "adminq_cfg_device_resources_cnt", CTLFLAG_RD,
23754dfc97bSShailend Chand 	    &priv->adminq_cfg_device_resources_cnt, 0,
23854dfc97bSShailend Chand 	    "adminq_cfg_device_resources_cnt");
23954dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
24054dfc97bSShailend Chand 	    "adminq_register_page_list_cnt", CTLFLAG_RD,
24154dfc97bSShailend Chand 	    &priv->adminq_register_page_list_cnt, 0,
24254dfc97bSShailend Chand 	    "adminq_register_page_list_cnt");
24354dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
24454dfc97bSShailend Chand 	    "adminq_unregister_page_list_cnt", CTLFLAG_RD,
24554dfc97bSShailend Chand 	    &priv->adminq_unregister_page_list_cnt, 0,
24654dfc97bSShailend Chand 	    "adminq_unregister_page_list_cnt");
24754dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_create_tx_queue_cnt",
24854dfc97bSShailend Chand 	    CTLFLAG_RD, &priv->adminq_create_tx_queue_cnt, 0,
24954dfc97bSShailend Chand 	    "adminq_create_tx_queue_cnt");
25054dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_create_rx_queue_cnt",
25154dfc97bSShailend Chand 	    CTLFLAG_RD, &priv->adminq_create_rx_queue_cnt, 0,
25254dfc97bSShailend Chand 	    "adminq_create_rx_queue_cnt");
25354dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_destroy_tx_queue_cnt",
25454dfc97bSShailend Chand 	    CTLFLAG_RD, &priv->adminq_destroy_tx_queue_cnt, 0,
25554dfc97bSShailend Chand 	    "adminq_destroy_tx_queue_cnt");
25654dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_destroy_rx_queue_cnt",
25754dfc97bSShailend Chand 	    CTLFLAG_RD, &priv->adminq_destroy_rx_queue_cnt, 0,
25854dfc97bSShailend Chand 	    "adminq_destroy_rx_queue_cnt");
259d438b4efSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_get_ptype_map_cnt",
260d438b4efSShailend Chand 	    CTLFLAG_RD, &priv->adminq_get_ptype_map_cnt, 0,
261d438b4efSShailend Chand 	    "adminq_get_ptype_map_cnt");
26254dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
26354dfc97bSShailend Chand 	    "adminq_dcfg_device_resources_cnt", CTLFLAG_RD,
26454dfc97bSShailend Chand 	    &priv->adminq_dcfg_device_resources_cnt, 0,
26554dfc97bSShailend Chand 	    "adminq_dcfg_device_resources_cnt");
26654dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
26754dfc97bSShailend Chand 	    "adminq_set_driver_parameter_cnt", CTLFLAG_RD,
26854dfc97bSShailend Chand 	    &priv->adminq_set_driver_parameter_cnt, 0,
26954dfc97bSShailend Chand 	    "adminq_set_driver_parameter_cnt");
27054dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
27154dfc97bSShailend Chand 	    "adminq_verify_driver_compatibility_cnt", CTLFLAG_RD,
27254dfc97bSShailend Chand 	    &priv->adminq_verify_driver_compatibility_cnt, 0,
27354dfc97bSShailend Chand 	    "adminq_verify_driver_compatibility_cnt");
27454dfc97bSShailend Chand }
27554dfc97bSShailend Chand 
27654dfc97bSShailend Chand static void
gve_setup_main_stat_sysctl(struct sysctl_ctx_list * ctx,struct sysctl_oid_list * child,struct gve_priv * priv)27754dfc97bSShailend Chand gve_setup_main_stat_sysctl(struct sysctl_ctx_list *ctx,
27854dfc97bSShailend Chand     struct sysctl_oid_list *child, struct gve_priv *priv)
27954dfc97bSShailend Chand {
28054dfc97bSShailend Chand 	struct sysctl_oid *main_node;
28154dfc97bSShailend Chand 	struct sysctl_oid_list *main_list;
28254dfc97bSShailend Chand 
28354dfc97bSShailend Chand 	/* Main stats */
28454dfc97bSShailend Chand 	main_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "main_stats",
28554dfc97bSShailend Chand 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Main statistics");
28654dfc97bSShailend Chand 	main_list = SYSCTL_CHILDREN(main_node);
28754dfc97bSShailend Chand 
28854dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, main_list, OID_AUTO, "interface_up_cnt", CTLFLAG_RD,
28954dfc97bSShailend Chand 	    &priv->interface_up_cnt, 0, "Times interface was set to up");
29054dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, main_list, OID_AUTO, "interface_down_cnt", CTLFLAG_RD,
29154dfc97bSShailend Chand 	    &priv->interface_down_cnt, 0, "Times interface was set to down");
29254dfc97bSShailend Chand 	SYSCTL_ADD_U32(ctx, main_list, OID_AUTO, "reset_cnt", CTLFLAG_RD,
29354dfc97bSShailend Chand 	    &priv->reset_cnt, 0, "Times reset");
29454dfc97bSShailend Chand }
29554dfc97bSShailend Chand 
296e0464f74SVee Agarwal static int
gve_check_num_queues(struct gve_priv * priv,int val,bool is_rx)297e0464f74SVee Agarwal gve_check_num_queues(struct gve_priv *priv, int val, bool is_rx)
298e0464f74SVee Agarwal {
299e0464f74SVee Agarwal 	if (val < 1) {
300e0464f74SVee Agarwal 		device_printf(priv->dev,
301e0464f74SVee Agarwal 		    "Requested num queues (%u) must be a positive integer\n", val);
302e0464f74SVee Agarwal 		return (EINVAL);
303e0464f74SVee Agarwal 	}
304e0464f74SVee Agarwal 
305e0464f74SVee Agarwal 	if (val > (is_rx ? priv->rx_cfg.max_queues : priv->tx_cfg.max_queues)) {
306e0464f74SVee Agarwal 		device_printf(priv->dev,
307e0464f74SVee Agarwal 		    "Requested num queues (%u) is too large\n", val);
308e0464f74SVee Agarwal 		return (EINVAL);
309e0464f74SVee Agarwal 	}
310e0464f74SVee Agarwal 
311e0464f74SVee Agarwal 	return (0);
312e0464f74SVee Agarwal }
313e0464f74SVee Agarwal 
314e0464f74SVee Agarwal static int
gve_sysctl_num_tx_queues(SYSCTL_HANDLER_ARGS)315e0464f74SVee Agarwal gve_sysctl_num_tx_queues(SYSCTL_HANDLER_ARGS)
316e0464f74SVee Agarwal {
317e0464f74SVee Agarwal 	struct gve_priv *priv = arg1;
318e0464f74SVee Agarwal 	int val;
319e0464f74SVee Agarwal 	int err;
320e0464f74SVee Agarwal 
321e0464f74SVee Agarwal 	val = priv->tx_cfg.num_queues;
322e0464f74SVee Agarwal 	err = sysctl_handle_int(oidp, &val, 0, req);
323e0464f74SVee Agarwal 	if (err != 0 || req->newptr == NULL)
324e0464f74SVee Agarwal 		return (err);
325e0464f74SVee Agarwal 
326e0464f74SVee Agarwal 	err = gve_check_num_queues(priv, val, /*is_rx=*/false);
327e0464f74SVee Agarwal 	if (err != 0)
328e0464f74SVee Agarwal 		return (err);
329e0464f74SVee Agarwal 
330e0464f74SVee Agarwal 	if (val != priv->tx_cfg.num_queues) {
331e0464f74SVee Agarwal 		GVE_IFACE_LOCK_LOCK(priv->gve_iface_lock);
332e0464f74SVee Agarwal 		err = gve_adjust_tx_queues(priv, val);
333e0464f74SVee Agarwal 		GVE_IFACE_LOCK_UNLOCK(priv->gve_iface_lock);
334e0464f74SVee Agarwal 	}
335e0464f74SVee Agarwal 
336e0464f74SVee Agarwal 	return (err);
337e0464f74SVee Agarwal }
338e0464f74SVee Agarwal 
339e0464f74SVee Agarwal static int
gve_sysctl_num_rx_queues(SYSCTL_HANDLER_ARGS)340e0464f74SVee Agarwal gve_sysctl_num_rx_queues(SYSCTL_HANDLER_ARGS)
341e0464f74SVee Agarwal {
342e0464f74SVee Agarwal 	struct gve_priv *priv = arg1;
343e0464f74SVee Agarwal 	int val;
344e0464f74SVee Agarwal 	int err;
345e0464f74SVee Agarwal 
346e0464f74SVee Agarwal 	val = priv->rx_cfg.num_queues;
347e0464f74SVee Agarwal 	err = sysctl_handle_int(oidp, &val, 0, req);
348e0464f74SVee Agarwal 	if (err != 0 || req->newptr == NULL)
349e0464f74SVee Agarwal 		return (err);
350e0464f74SVee Agarwal 
351e0464f74SVee Agarwal 	err = gve_check_num_queues(priv, val, /*is_rx=*/true);
352e0464f74SVee Agarwal 
353e0464f74SVee Agarwal 	if (err != 0)
354e0464f74SVee Agarwal 		return (err);
355e0464f74SVee Agarwal 
356e0464f74SVee Agarwal 	if (val != priv->rx_cfg.num_queues) {
357e0464f74SVee Agarwal 		GVE_IFACE_LOCK_LOCK(priv->gve_iface_lock);
358e0464f74SVee Agarwal 		err = gve_adjust_rx_queues(priv, val);
359e0464f74SVee Agarwal 		GVE_IFACE_LOCK_UNLOCK(priv->gve_iface_lock);
360e0464f74SVee Agarwal 	}
361e0464f74SVee Agarwal 
362e0464f74SVee Agarwal 	return (err);
363e0464f74SVee Agarwal }
364e0464f74SVee Agarwal 
36522fe926aSVee Agarwal static int
gve_check_ring_size(struct gve_priv * priv,int val,bool is_rx)36622fe926aSVee Agarwal gve_check_ring_size(struct gve_priv *priv, int val, bool is_rx)
36722fe926aSVee Agarwal {
36822fe926aSVee Agarwal 	if (!powerof2(val) || val == 0) {
36922fe926aSVee Agarwal 		device_printf(priv->dev,
37022fe926aSVee Agarwal 		    "Requested ring size (%u) must be a power of 2\n", val);
37122fe926aSVee Agarwal 		return (EINVAL);
37222fe926aSVee Agarwal 	}
37322fe926aSVee Agarwal 
37422fe926aSVee Agarwal 	if (val < (is_rx ? priv->min_rx_desc_cnt : priv->min_tx_desc_cnt)) {
37522fe926aSVee Agarwal 		device_printf(priv->dev,
37622fe926aSVee Agarwal 		    "Requested ring size (%u) cannot be less than %d\n", val,
37722fe926aSVee Agarwal 		    (is_rx ? priv->min_rx_desc_cnt : priv->min_tx_desc_cnt));
37822fe926aSVee Agarwal 		return (EINVAL);
37922fe926aSVee Agarwal 	}
38022fe926aSVee Agarwal 
38122fe926aSVee Agarwal 
38222fe926aSVee Agarwal 	if (val > (is_rx ? priv->max_rx_desc_cnt : priv->max_tx_desc_cnt)) {
38322fe926aSVee Agarwal 		device_printf(priv->dev,
38422fe926aSVee Agarwal 		    "Requested ring size (%u) cannot be greater than %d\n", val,
38522fe926aSVee Agarwal 		    (is_rx ? priv->max_rx_desc_cnt : priv->max_tx_desc_cnt));
38622fe926aSVee Agarwal 		return (EINVAL);
38722fe926aSVee Agarwal 	}
38822fe926aSVee Agarwal 
38922fe926aSVee Agarwal 	return (0);
39022fe926aSVee Agarwal }
39122fe926aSVee Agarwal 
39222fe926aSVee Agarwal static int
gve_sysctl_tx_ring_size(SYSCTL_HANDLER_ARGS)39322fe926aSVee Agarwal gve_sysctl_tx_ring_size(SYSCTL_HANDLER_ARGS)
39422fe926aSVee Agarwal {
39522fe926aSVee Agarwal 	struct gve_priv *priv = arg1;
39622fe926aSVee Agarwal 	int val;
39722fe926aSVee Agarwal 	int err;
39822fe926aSVee Agarwal 
39922fe926aSVee Agarwal 	val = priv->tx_desc_cnt;
40022fe926aSVee Agarwal 	err = sysctl_handle_int(oidp, &val, 0, req);
40122fe926aSVee Agarwal 	if (err != 0 || req->newptr == NULL)
40222fe926aSVee Agarwal 		return (err);
40322fe926aSVee Agarwal 
40422fe926aSVee Agarwal 	err = gve_check_ring_size(priv, val, /*is_rx=*/false);
40522fe926aSVee Agarwal 	if (err != 0)
40622fe926aSVee Agarwal 		return (err);
40722fe926aSVee Agarwal 
40822fe926aSVee Agarwal 	if (val != priv->tx_desc_cnt) {
40922fe926aSVee Agarwal 		GVE_IFACE_LOCK_LOCK(priv->gve_iface_lock);
41022fe926aSVee Agarwal 		err = gve_adjust_ring_sizes(priv, val, /*is_rx=*/false);
41122fe926aSVee Agarwal 		GVE_IFACE_LOCK_UNLOCK(priv->gve_iface_lock);
41222fe926aSVee Agarwal 	}
41322fe926aSVee Agarwal 
41422fe926aSVee Agarwal 	return (err);
41522fe926aSVee Agarwal }
41622fe926aSVee Agarwal 
41722fe926aSVee Agarwal static int
gve_sysctl_rx_ring_size(SYSCTL_HANDLER_ARGS)41822fe926aSVee Agarwal gve_sysctl_rx_ring_size(SYSCTL_HANDLER_ARGS)
41922fe926aSVee Agarwal {
42022fe926aSVee Agarwal 	struct gve_priv *priv = arg1;
42122fe926aSVee Agarwal 	int val;
42222fe926aSVee Agarwal 	int err;
42322fe926aSVee Agarwal 
42422fe926aSVee Agarwal 	val = priv->rx_desc_cnt;
42522fe926aSVee Agarwal 	err = sysctl_handle_int(oidp, &val, 0, req);
42622fe926aSVee Agarwal 	if (err != 0 || req->newptr == NULL)
42722fe926aSVee Agarwal 		return (err);
42822fe926aSVee Agarwal 
42922fe926aSVee Agarwal 	err = gve_check_ring_size(priv, val, /*is_rx=*/true);
43022fe926aSVee Agarwal 	if (err != 0)
43122fe926aSVee Agarwal 		return (err);
43222fe926aSVee Agarwal 
43322fe926aSVee Agarwal 	if (val != priv->rx_desc_cnt) {
43422fe926aSVee Agarwal 		GVE_IFACE_LOCK_LOCK(priv->gve_iface_lock);
43522fe926aSVee Agarwal 		err = gve_adjust_ring_sizes(priv, val, /*is_rx=*/true);
43622fe926aSVee Agarwal 		GVE_IFACE_LOCK_UNLOCK(priv->gve_iface_lock);
43722fe926aSVee Agarwal 	}
43822fe926aSVee Agarwal 
43922fe926aSVee Agarwal 	return (err);
44022fe926aSVee Agarwal }
44122fe926aSVee Agarwal 
442e0464f74SVee Agarwal static void
gve_setup_sysctl_writables(struct sysctl_ctx_list * ctx,struct sysctl_oid_list * child,struct gve_priv * priv)443e0464f74SVee Agarwal gve_setup_sysctl_writables(struct sysctl_ctx_list *ctx,
444e0464f74SVee Agarwal     struct sysctl_oid_list *child, struct gve_priv *priv)
445e0464f74SVee Agarwal {
446e0464f74SVee Agarwal 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "num_tx_queues",
447e0464f74SVee Agarwal 	    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv, 0,
448e0464f74SVee Agarwal 	    gve_sysctl_num_tx_queues, "I", "Number of TX queues");
449e0464f74SVee Agarwal 
450e0464f74SVee Agarwal 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "num_rx_queues",
451e0464f74SVee Agarwal 	    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv, 0,
452e0464f74SVee Agarwal 	    gve_sysctl_num_rx_queues, "I", "Number of RX queues");
45322fe926aSVee Agarwal 
45422fe926aSVee Agarwal 	if (priv->modify_ringsize_enabled) {
45522fe926aSVee Agarwal 		SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "tx_ring_size",
45622fe926aSVee Agarwal 		    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv, 0,
45722fe926aSVee Agarwal 		    gve_sysctl_tx_ring_size, "I", "TX ring size");
45822fe926aSVee Agarwal 
45922fe926aSVee Agarwal 		SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_ring_size",
46022fe926aSVee Agarwal 		    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv, 0,
46122fe926aSVee Agarwal 		    gve_sysctl_rx_ring_size, "I", "RX ring size");
46222fe926aSVee Agarwal 	}
463e0464f74SVee Agarwal }
464e0464f74SVee Agarwal 
gve_setup_sysctl(struct gve_priv * priv)46554dfc97bSShailend Chand void gve_setup_sysctl(struct gve_priv *priv)
46654dfc97bSShailend Chand {
46754dfc97bSShailend Chand 	device_t dev;
46854dfc97bSShailend Chand 	struct sysctl_ctx_list *ctx;
46954dfc97bSShailend Chand 	struct sysctl_oid *tree;
47054dfc97bSShailend Chand 	struct sysctl_oid_list *child;
47154dfc97bSShailend Chand 
47254dfc97bSShailend Chand 	dev = priv->dev;
47354dfc97bSShailend Chand 	ctx = device_get_sysctl_ctx(dev);
47454dfc97bSShailend Chand 	tree = device_get_sysctl_tree(dev);
47554dfc97bSShailend Chand 	child = SYSCTL_CHILDREN(tree);
47654dfc97bSShailend Chand 
47754dfc97bSShailend Chand 	gve_setup_queue_stat_sysctl(ctx, child, priv);
47854dfc97bSShailend Chand 	gve_setup_adminq_stat_sysctl(ctx, child, priv);
47954dfc97bSShailend Chand 	gve_setup_main_stat_sysctl(ctx, child, priv);
480e0464f74SVee Agarwal 	gve_setup_sysctl_writables(ctx, child, priv);
48154dfc97bSShailend Chand }
48254dfc97bSShailend Chand 
48354dfc97bSShailend Chand void
gve_accum_stats(struct gve_priv * priv,uint64_t * rpackets,uint64_t * rbytes,uint64_t * rx_dropped_pkt,uint64_t * tpackets,uint64_t * tbytes,uint64_t * tx_dropped_pkt)48454dfc97bSShailend Chand gve_accum_stats(struct gve_priv *priv, uint64_t *rpackets,
48554dfc97bSShailend Chand     uint64_t *rbytes, uint64_t *rx_dropped_pkt, uint64_t *tpackets,
48654dfc97bSShailend Chand     uint64_t *tbytes, uint64_t *tx_dropped_pkt)
48754dfc97bSShailend Chand {
48854dfc97bSShailend Chand 	struct gve_rxq_stats *rxqstats;
48954dfc97bSShailend Chand 	struct gve_txq_stats *txqstats;
49054dfc97bSShailend Chand 	int i;
49154dfc97bSShailend Chand 
49254dfc97bSShailend Chand 	for (i = 0; i < priv->rx_cfg.num_queues; i++) {
49354dfc97bSShailend Chand 		rxqstats = &priv->rx[i].stats;
49454dfc97bSShailend Chand 		*rpackets += counter_u64_fetch(rxqstats->rpackets);
49554dfc97bSShailend Chand 		*rbytes += counter_u64_fetch(rxqstats->rbytes);
49654dfc97bSShailend Chand 		*rx_dropped_pkt += counter_u64_fetch(rxqstats->rx_dropped_pkt);
49754dfc97bSShailend Chand 	}
49854dfc97bSShailend Chand 
49954dfc97bSShailend Chand 	for (i = 0; i < priv->tx_cfg.num_queues; i++) {
50054dfc97bSShailend Chand 		txqstats = &priv->tx[i].stats;
50154dfc97bSShailend Chand 		*tpackets += counter_u64_fetch(txqstats->tpackets);
50254dfc97bSShailend Chand 		*tbytes += counter_u64_fetch(txqstats->tbytes);
50354dfc97bSShailend Chand 		*tx_dropped_pkt += counter_u64_fetch(txqstats->tx_dropped_pkt);
50454dfc97bSShailend Chand 	}
50554dfc97bSShailend Chand }
506