xref: /freebsd/sys/dev/ena/ena_sysctl.c (revision f180142c7659a150f58ad8d8c878216a0b53fc66)
19b8d05b8SZbigniew Bodek /*-
20835cc78SMarcin Wojtas  * SPDX-License-Identifier: BSD-2-Clause
39b8d05b8SZbigniew Bodek  *
42287afd8SMarcin Wojtas  * Copyright (c) 2015-2020 Amazon.com, Inc. or its affiliates.
59b8d05b8SZbigniew Bodek  * All rights reserved.
69b8d05b8SZbigniew Bodek  *
79b8d05b8SZbigniew Bodek  * Redistribution and use in source and binary forms, with or without
89b8d05b8SZbigniew Bodek  * modification, are permitted provided that the following conditions
99b8d05b8SZbigniew Bodek  * are met:
109b8d05b8SZbigniew Bodek  *
119b8d05b8SZbigniew Bodek  * 1. Redistributions of source code must retain the above copyright
129b8d05b8SZbigniew Bodek  *    notice, this list of conditions and the following disclaimer.
139b8d05b8SZbigniew Bodek  *
149b8d05b8SZbigniew Bodek  * 2. Redistributions in binary form must reproduce the above copyright
159b8d05b8SZbigniew Bodek  *    notice, this list of conditions and the following disclaimer in the
169b8d05b8SZbigniew Bodek  *    documentation and/or other materials provided with the distribution.
179b8d05b8SZbigniew Bodek  *
189b8d05b8SZbigniew Bodek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
199b8d05b8SZbigniew Bodek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
209b8d05b8SZbigniew Bodek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
219b8d05b8SZbigniew Bodek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
229b8d05b8SZbigniew Bodek  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
239b8d05b8SZbigniew Bodek  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
249b8d05b8SZbigniew Bodek  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
259b8d05b8SZbigniew Bodek  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
269b8d05b8SZbigniew Bodek  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
279b8d05b8SZbigniew Bodek  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
289b8d05b8SZbigniew Bodek  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
299b8d05b8SZbigniew Bodek  */
309b8d05b8SZbigniew Bodek #include <sys/cdefs.h>
319b8d05b8SZbigniew Bodek __FBSDID("$FreeBSD$");
329b8d05b8SZbigniew Bodek 
339b8d05b8SZbigniew Bodek #include "ena_sysctl.h"
349b8d05b8SZbigniew Bodek 
350bdffe59SMarcin Wojtas static void	ena_sysctl_add_wd(struct ena_adapter *);
369b8d05b8SZbigniew Bodek static void	ena_sysctl_add_stats(struct ena_adapter *);
37*f180142cSMarcin Wojtas static void	ena_sysctl_add_eni_metrics(struct ena_adapter *);
386064f289SMarcin Wojtas static void	ena_sysctl_add_tuneables(struct ena_adapter *);
396064f289SMarcin Wojtas static int	ena_sysctl_buf_ring_size(SYSCTL_HANDLER_ARGS);
406064f289SMarcin Wojtas static int	ena_sysctl_rx_queue_size(SYSCTL_HANDLER_ARGS);
4156d41ad5SMarcin Wojtas static int	ena_sysctl_io_queues_nb(SYSCTL_HANDLER_ARGS);
42*f180142cSMarcin Wojtas static int	ena_sysctl_eni_metrics_interval(SYSCTL_HANDLER_ARGS);
43*f180142cSMarcin Wojtas 
44*f180142cSMarcin Wojtas /* Limit max ENI sample rate to be an hour. */
45*f180142cSMarcin Wojtas #define ENI_METRICS_MAX_SAMPLE_INTERVAL 3600
466064f289SMarcin Wojtas 
477029da5cSPawel Biernacki static SYSCTL_NODE(_hw, OID_AUTO, ena, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
487029da5cSPawel Biernacki     "ENA driver parameters");
496064f289SMarcin Wojtas 
506064f289SMarcin Wojtas /*
516064f289SMarcin Wojtas  * Logging level for changing verbosity of the output
526064f289SMarcin Wojtas  */
536064f289SMarcin Wojtas int ena_log_level = ENA_ALERT | ENA_WARNING;
546064f289SMarcin Wojtas SYSCTL_INT(_hw_ena, OID_AUTO, log_level, CTLFLAG_RWTUN,
556064f289SMarcin Wojtas     &ena_log_level, 0, "Logging level indicating verbosity of the logs");
566064f289SMarcin Wojtas 
5785516621SMarcin Wojtas SYSCTL_CONST_STRING(_hw_ena, OID_AUTO, driver_version, CTLFLAG_RD,
5885516621SMarcin Wojtas     DRV_MODULE_VERSION, "ENA driver version");
5985516621SMarcin Wojtas 
6004cf2b88SMarcin Wojtas /*
6104cf2b88SMarcin Wojtas  * Use 9k mbufs for the Rx buffers. Default to 0 (use page size mbufs instead).
6204cf2b88SMarcin Wojtas  * Using 9k mbufs in low memory conditions might cause allocation to take a lot
6304cf2b88SMarcin Wojtas  * of time and lead to the OS instability as it needs to look for the contiguous
6404cf2b88SMarcin Wojtas  * pages.
6504cf2b88SMarcin Wojtas  * However, page size mbufs has a bit smaller throughput than 9k mbufs, so if
6604cf2b88SMarcin Wojtas  * the network performance is the priority, the 9k mbufs can be used.
6704cf2b88SMarcin Wojtas  */
6804cf2b88SMarcin Wojtas int ena_enable_9k_mbufs = 0;
6904cf2b88SMarcin Wojtas SYSCTL_INT(_hw_ena, OID_AUTO, enable_9k_mbufs, CTLFLAG_RDTUN,
7004cf2b88SMarcin Wojtas     &ena_enable_9k_mbufs, 0, "Use 9 kB mbufs for Rx descriptors");
719b8d05b8SZbigniew Bodek 
729b8d05b8SZbigniew Bodek void
739b8d05b8SZbigniew Bodek ena_sysctl_add_nodes(struct ena_adapter *adapter)
749b8d05b8SZbigniew Bodek {
750bdffe59SMarcin Wojtas 	ena_sysctl_add_wd(adapter);
769b8d05b8SZbigniew Bodek 	ena_sysctl_add_stats(adapter);
77*f180142cSMarcin Wojtas 	ena_sysctl_add_eni_metrics(adapter);
786064f289SMarcin Wojtas 	ena_sysctl_add_tuneables(adapter);
799b8d05b8SZbigniew Bodek }
809b8d05b8SZbigniew Bodek 
819b8d05b8SZbigniew Bodek static void
820bdffe59SMarcin Wojtas ena_sysctl_add_wd(struct ena_adapter *adapter)
830bdffe59SMarcin Wojtas {
840bdffe59SMarcin Wojtas 	device_t dev;
850bdffe59SMarcin Wojtas 
860bdffe59SMarcin Wojtas 	struct sysctl_ctx_list *ctx;
870bdffe59SMarcin Wojtas 	struct sysctl_oid *tree;
880bdffe59SMarcin Wojtas 	struct sysctl_oid_list *child;
890bdffe59SMarcin Wojtas 
900bdffe59SMarcin Wojtas 	dev = adapter->pdev;
910bdffe59SMarcin Wojtas 
920bdffe59SMarcin Wojtas 	ctx = device_get_sysctl_ctx(dev);
930bdffe59SMarcin Wojtas 	tree = device_get_sysctl_tree(dev);
940bdffe59SMarcin Wojtas 	child = SYSCTL_CHILDREN(tree);
950bdffe59SMarcin Wojtas 
960bdffe59SMarcin Wojtas 	/* Sysctl calls for Watchdog service */
970bdffe59SMarcin Wojtas 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "wd_active",
980bdffe59SMarcin Wojtas 	    CTLFLAG_RWTUN, &adapter->wd_active, 0,
990bdffe59SMarcin Wojtas 	    "Watchdog is active");
1000bdffe59SMarcin Wojtas 
1010bdffe59SMarcin Wojtas 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "keep_alive_timeout",
1020bdffe59SMarcin Wojtas 	    CTLFLAG_RWTUN, &adapter->keep_alive_timeout,
1030bdffe59SMarcin Wojtas 	    "Timeout for Keep Alive messages");
1040bdffe59SMarcin Wojtas 
1050bdffe59SMarcin Wojtas 	SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "missing_tx_timeout",
1060bdffe59SMarcin Wojtas 	    CTLFLAG_RWTUN, &adapter->missing_tx_timeout,
1070bdffe59SMarcin Wojtas 	    "Timeout for TX completion");
1080bdffe59SMarcin Wojtas 
1090bdffe59SMarcin Wojtas 	SYSCTL_ADD_U32(ctx, child, OID_AUTO, "missing_tx_max_queues",
1100bdffe59SMarcin Wojtas 	    CTLFLAG_RWTUN, &adapter->missing_tx_max_queues, 0,
1110bdffe59SMarcin Wojtas 	    "Number of TX queues to check per run");
1120bdffe59SMarcin Wojtas 
1130bdffe59SMarcin Wojtas 	SYSCTL_ADD_U32(ctx, child, OID_AUTO, "missing_tx_threshold",
1140bdffe59SMarcin Wojtas 	    CTLFLAG_RWTUN, &adapter->missing_tx_threshold, 0,
1150bdffe59SMarcin Wojtas 	    "Max number of timeouted packets");
1160bdffe59SMarcin Wojtas }
1170bdffe59SMarcin Wojtas 
1180bdffe59SMarcin Wojtas static void
1199b8d05b8SZbigniew Bodek ena_sysctl_add_stats(struct ena_adapter *adapter)
1209b8d05b8SZbigniew Bodek {
1219b8d05b8SZbigniew Bodek 	device_t dev;
1229b8d05b8SZbigniew Bodek 
1239b8d05b8SZbigniew Bodek 	struct ena_ring *tx_ring;
1249b8d05b8SZbigniew Bodek 	struct ena_ring *rx_ring;
1259b8d05b8SZbigniew Bodek 
1269b8d05b8SZbigniew Bodek 	struct ena_hw_stats *hw_stats;
1279b8d05b8SZbigniew Bodek 	struct ena_stats_dev *dev_stats;
1289b8d05b8SZbigniew Bodek 	struct ena_stats_tx *tx_stats;
1299b8d05b8SZbigniew Bodek 	struct ena_stats_rx *rx_stats;
1309b8d05b8SZbigniew Bodek 	struct ena_com_stats_admin *admin_stats;
1319b8d05b8SZbigniew Bodek 
1329b8d05b8SZbigniew Bodek 	struct sysctl_ctx_list *ctx;
1339b8d05b8SZbigniew Bodek 	struct sysctl_oid *tree;
1349b8d05b8SZbigniew Bodek 	struct sysctl_oid_list *child;
1359b8d05b8SZbigniew Bodek 
1369b8d05b8SZbigniew Bodek 	struct sysctl_oid *queue_node, *tx_node, *rx_node, *hw_node;
1379b8d05b8SZbigniew Bodek 	struct sysctl_oid *admin_node;
1389b8d05b8SZbigniew Bodek 	struct sysctl_oid_list *queue_list, *tx_list, *rx_list, *hw_list;
1399b8d05b8SZbigniew Bodek 	struct sysctl_oid_list *admin_list;
1409b8d05b8SZbigniew Bodek 
1419b8d05b8SZbigniew Bodek #define QUEUE_NAME_LEN 32
1429b8d05b8SZbigniew Bodek 	char namebuf[QUEUE_NAME_LEN];
1439b8d05b8SZbigniew Bodek 	int i;
1449b8d05b8SZbigniew Bodek 
1459b8d05b8SZbigniew Bodek 	dev = adapter->pdev;
1469b8d05b8SZbigniew Bodek 
1479b8d05b8SZbigniew Bodek 	ctx = device_get_sysctl_ctx(dev);
1489b8d05b8SZbigniew Bodek 	tree = device_get_sysctl_tree(dev);
1499b8d05b8SZbigniew Bodek 	child = SYSCTL_CHILDREN(tree);
1509b8d05b8SZbigniew Bodek 
1519b8d05b8SZbigniew Bodek 	tx_ring = adapter->tx_ring;
1529b8d05b8SZbigniew Bodek 	rx_ring = adapter->rx_ring;
1539b8d05b8SZbigniew Bodek 
1549b8d05b8SZbigniew Bodek 	hw_stats = &adapter->hw_stats;
1559b8d05b8SZbigniew Bodek 	dev_stats = &adapter->dev_stats;
1569b8d05b8SZbigniew Bodek 	admin_stats = &adapter->ena_dev->admin_queue.stats;
1579b8d05b8SZbigniew Bodek 
1589b8d05b8SZbigniew Bodek 	SYSCTL_ADD_COUNTER_U64(ctx, child, OID_AUTO, "wd_expired",
1599b8d05b8SZbigniew Bodek 	    CTLFLAG_RD, &dev_stats->wd_expired,
1609b8d05b8SZbigniew Bodek 	    "Watchdog expiry count");
1619b8d05b8SZbigniew Bodek 	SYSCTL_ADD_COUNTER_U64(ctx, child, OID_AUTO, "interface_up",
1629b8d05b8SZbigniew Bodek 	    CTLFLAG_RD, &dev_stats->interface_up,
1639b8d05b8SZbigniew Bodek 	    "Network interface up count");
1649b8d05b8SZbigniew Bodek 	SYSCTL_ADD_COUNTER_U64(ctx, child, OID_AUTO, "interface_down",
1659b8d05b8SZbigniew Bodek 	    CTLFLAG_RD, &dev_stats->interface_down,
1669b8d05b8SZbigniew Bodek 	    "Network interface down count");
1679b8d05b8SZbigniew Bodek 	SYSCTL_ADD_COUNTER_U64(ctx, child, OID_AUTO, "admin_q_pause",
1689b8d05b8SZbigniew Bodek 	    CTLFLAG_RD, &dev_stats->admin_q_pause,
1699b8d05b8SZbigniew Bodek 	    "Admin queue pauses");
1709b8d05b8SZbigniew Bodek 
1717d8c4feeSMarcin Wojtas 	for (i = 0; i < adapter->num_io_queues; ++i, ++tx_ring, ++rx_ring) {
1729b8d05b8SZbigniew Bodek 		snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i);
1739b8d05b8SZbigniew Bodek 
1749b8d05b8SZbigniew Bodek 		queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO,
1757029da5cSPawel Biernacki 		    namebuf, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Queue Name");
1769b8d05b8SZbigniew Bodek 		queue_list = SYSCTL_CHILDREN(queue_node);
1779b8d05b8SZbigniew Bodek 
1789b8d05b8SZbigniew Bodek 		/* TX specific stats */
1799b8d05b8SZbigniew Bodek 		tx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO,
1807029da5cSPawel Biernacki 		    "tx_ring", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "TX ring");
1819b8d05b8SZbigniew Bodek 		tx_list = SYSCTL_CHILDREN(tx_node);
1829b8d05b8SZbigniew Bodek 
1839b8d05b8SZbigniew Bodek 		tx_stats = &tx_ring->tx_stats;
1849b8d05b8SZbigniew Bodek 
1859b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
1869b8d05b8SZbigniew Bodek 		    "count", CTLFLAG_RD,
1879b8d05b8SZbigniew Bodek 		    &tx_stats->cnt, "Packets sent");
1889b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
1899b8d05b8SZbigniew Bodek 		    "bytes", CTLFLAG_RD,
1909b8d05b8SZbigniew Bodek 		    &tx_stats->bytes, "Bytes sent");
1919b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
1929b8d05b8SZbigniew Bodek 		    "prepare_ctx_err", CTLFLAG_RD,
1939b8d05b8SZbigniew Bodek 		    &tx_stats->prepare_ctx_err,
1949b8d05b8SZbigniew Bodek 		    "TX buffer preparation failures");
1959b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
1969b8d05b8SZbigniew Bodek 		    "dma_mapping_err", CTLFLAG_RD,
1979b8d05b8SZbigniew Bodek 		    &tx_stats->dma_mapping_err, "DMA mapping failures");
1989b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
1999b8d05b8SZbigniew Bodek 		    "doorbells", CTLFLAG_RD,
2009b8d05b8SZbigniew Bodek 		    &tx_stats->doorbells, "Queue doorbells");
2019b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
2029b8d05b8SZbigniew Bodek 		    "missing_tx_comp", CTLFLAG_RD,
2039b8d05b8SZbigniew Bodek 		    &tx_stats->missing_tx_comp, "TX completions missed");
2049b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
2059b8d05b8SZbigniew Bodek 		    "bad_req_id", CTLFLAG_RD,
2069b8d05b8SZbigniew Bodek 		    &tx_stats->bad_req_id, "Bad request id count");
2079b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
2081b069f1cSZbigniew Bodek 		        "mbuf_collapses", CTLFLAG_RD,
2091b069f1cSZbigniew Bodek 		        &tx_stats->collapse,
2101b069f1cSZbigniew Bodek 		        "Mbuf collapse count");
2111e9fb899SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
2121b069f1cSZbigniew Bodek 		        "mbuf_collapse_err", CTLFLAG_RD,
2131b069f1cSZbigniew Bodek 		        &tx_stats->collapse_err,
2141b069f1cSZbigniew Bodek 		        "Mbuf collapse failures");
2155cb9db07SMarcin Wojtas 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
2165cb9db07SMarcin Wojtas 		    "queue_wakeups", CTLFLAG_RD,
2175cb9db07SMarcin Wojtas 		    &tx_stats->queue_wakeup, "Queue wakeups");
2185cb9db07SMarcin Wojtas 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
2195cb9db07SMarcin Wojtas 		    "queue_stops", CTLFLAG_RD,
2205cb9db07SMarcin Wojtas 		    &tx_stats->queue_stop, "Queue stops");
2214fa9e02dSMarcin Wojtas 		SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
2224fa9e02dSMarcin Wojtas 		    "llq_buffer_copy", CTLFLAG_RD,
2234fa9e02dSMarcin Wojtas 		    &tx_stats->llq_buffer_copy,
2244fa9e02dSMarcin Wojtas 		    "Header copies for llq transaction");
2259b8d05b8SZbigniew Bodek 
2269b8d05b8SZbigniew Bodek 		/* RX specific stats */
2279b8d05b8SZbigniew Bodek 		rx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO,
2287029da5cSPawel Biernacki 		    "rx_ring", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "RX ring");
2299b8d05b8SZbigniew Bodek 		rx_list = SYSCTL_CHILDREN(rx_node);
2309b8d05b8SZbigniew Bodek 
2319b8d05b8SZbigniew Bodek 		rx_stats = &rx_ring->rx_stats;
2329b8d05b8SZbigniew Bodek 
2339b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
2349b8d05b8SZbigniew Bodek 		    "count", CTLFLAG_RD,
2359b8d05b8SZbigniew Bodek 		    &rx_stats->cnt, "Packets received");
2369b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
2379b8d05b8SZbigniew Bodek 		    "bytes", CTLFLAG_RD,
2389b8d05b8SZbigniew Bodek 		    &rx_stats->bytes, "Bytes received");
2399b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
2409b8d05b8SZbigniew Bodek 		    "refil_partial", CTLFLAG_RD,
2419b8d05b8SZbigniew Bodek 		    &rx_stats->refil_partial, "Partial refilled mbufs");
2429b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
2439b8d05b8SZbigniew Bodek 		    "bad_csum", CTLFLAG_RD,
2449b8d05b8SZbigniew Bodek 		    &rx_stats->bad_csum, "Bad RX checksum");
2459b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
2469b8d05b8SZbigniew Bodek 		    "mbuf_alloc_fail", CTLFLAG_RD,
2479b8d05b8SZbigniew Bodek 		    &rx_stats->mbuf_alloc_fail, "Failed mbuf allocs");
2489b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
2494727bda6SMarcin Wojtas 		    "mjum_alloc_fail", CTLFLAG_RD,
2504727bda6SMarcin Wojtas 		    &rx_stats->mjum_alloc_fail, "Failed jumbo mbuf allocs");
2514727bda6SMarcin Wojtas 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
2529b8d05b8SZbigniew Bodek 		    "dma_mapping_err", CTLFLAG_RD,
2539b8d05b8SZbigniew Bodek 		    &rx_stats->dma_mapping_err, "DMA mapping errors");
2549b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
2559b8d05b8SZbigniew Bodek 		    "bad_desc_num", CTLFLAG_RD,
2569b8d05b8SZbigniew Bodek 		    &rx_stats->bad_desc_num, "Bad descriptor count");
2579b8d05b8SZbigniew Bodek 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
25843fefd16SMarcin Wojtas 		    "bad_req_id", CTLFLAG_RD,
25943fefd16SMarcin Wojtas 		    &rx_stats->bad_req_id, "Bad request id count");
260efe6ab18SMarcin Wojtas 		SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO,
261efe6ab18SMarcin Wojtas 		    "empty_rx_ring", CTLFLAG_RD,
262efe6ab18SMarcin Wojtas 		    &rx_stats->empty_rx_ring, "RX descriptors depletion count");
2639b8d05b8SZbigniew Bodek 	}
2649b8d05b8SZbigniew Bodek 
2659b8d05b8SZbigniew Bodek 	/* Stats read from device */
2669b8d05b8SZbigniew Bodek 	hw_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "hw_stats",
2677029da5cSPawel Biernacki 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Statistics from hardware");
2689b8d05b8SZbigniew Bodek 	hw_list = SYSCTL_CHILDREN(hw_node);
2699b8d05b8SZbigniew Bodek 
27030217e2dSMarcin Wojtas 	SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "rx_packets", CTLFLAG_RD,
27130217e2dSMarcin Wojtas 	    &hw_stats->rx_packets, "Packets received");
27230217e2dSMarcin Wojtas 	SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "tx_packets", CTLFLAG_RD,
27330217e2dSMarcin Wojtas 	    &hw_stats->tx_packets, "Packets transmitted");
27430217e2dSMarcin Wojtas 	SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "rx_bytes", CTLFLAG_RD,
27530217e2dSMarcin Wojtas 	    &hw_stats->rx_bytes, "Bytes received");
27630217e2dSMarcin Wojtas 	SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "tx_bytes", CTLFLAG_RD,
27730217e2dSMarcin Wojtas 	    &hw_stats->tx_bytes, "Bytes transmitted");
27830217e2dSMarcin Wojtas 	SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "rx_drops", CTLFLAG_RD,
27930217e2dSMarcin Wojtas 	    &hw_stats->rx_drops, "Receive packet drops");
2806c84cec3SMarcin Wojtas 	SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "tx_drops", CTLFLAG_RD,
2816c84cec3SMarcin Wojtas 	    &hw_stats->tx_drops, "Transmit packet drops");
282a195fab0SMarcin Wojtas 
2839b8d05b8SZbigniew Bodek 	/* ENA Admin queue stats */
2849b8d05b8SZbigniew Bodek 	admin_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "admin_stats",
2857029da5cSPawel Biernacki 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "ENA Admin Queue statistics");
2869b8d05b8SZbigniew Bodek 	admin_list = SYSCTL_CHILDREN(admin_node);
2879b8d05b8SZbigniew Bodek 
2888483b844SMarcin Wojtas 	SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "aborted_cmd", CTLFLAG_RD,
2899b8d05b8SZbigniew Bodek 	    &admin_stats->aborted_cmd, 0, "Aborted commands");
2908483b844SMarcin Wojtas 	SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "sumbitted_cmd", CTLFLAG_RD,
2919b8d05b8SZbigniew Bodek 	    &admin_stats->submitted_cmd, 0, "Submitted commands");
2928483b844SMarcin Wojtas 	SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "completed_cmd", CTLFLAG_RD,
2939b8d05b8SZbigniew Bodek 	    &admin_stats->completed_cmd, 0, "Completed commands");
2948483b844SMarcin Wojtas 	SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "out_of_space", CTLFLAG_RD,
2959b8d05b8SZbigniew Bodek 	    &admin_stats->out_of_space, 0, "Queue out of space");
2968483b844SMarcin Wojtas 	SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "no_completion", CTLFLAG_RD,
2979b8d05b8SZbigniew Bodek 	    &admin_stats->no_completion, 0, "Commands not completed");
2989b8d05b8SZbigniew Bodek }
2999b8d05b8SZbigniew Bodek 
3006064f289SMarcin Wojtas static void
301*f180142cSMarcin Wojtas ena_sysctl_add_eni_metrics(struct ena_adapter *adapter)
302*f180142cSMarcin Wojtas {
303*f180142cSMarcin Wojtas 	device_t dev;
304*f180142cSMarcin Wojtas 	struct ena_admin_eni_stats *eni_metrics;
305*f180142cSMarcin Wojtas 
306*f180142cSMarcin Wojtas 	struct sysctl_ctx_list *ctx;
307*f180142cSMarcin Wojtas 	struct sysctl_oid *tree;
308*f180142cSMarcin Wojtas 	struct sysctl_oid_list *child;
309*f180142cSMarcin Wojtas 
310*f180142cSMarcin Wojtas 	struct sysctl_oid *eni_node;
311*f180142cSMarcin Wojtas 	struct sysctl_oid_list *eni_list;
312*f180142cSMarcin Wojtas 
313*f180142cSMarcin Wojtas 	dev = adapter->pdev;
314*f180142cSMarcin Wojtas 
315*f180142cSMarcin Wojtas 	ctx = device_get_sysctl_ctx(dev);
316*f180142cSMarcin Wojtas 	tree = device_get_sysctl_tree(dev);
317*f180142cSMarcin Wojtas 	child = SYSCTL_CHILDREN(tree);
318*f180142cSMarcin Wojtas 
319*f180142cSMarcin Wojtas 	eni_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "eni_metrics",
320*f180142cSMarcin Wojtas 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "ENA's ENI metrics");
321*f180142cSMarcin Wojtas 	eni_list = SYSCTL_CHILDREN(eni_node);
322*f180142cSMarcin Wojtas 
323*f180142cSMarcin Wojtas 	eni_metrics = &adapter->eni_metrics;
324*f180142cSMarcin Wojtas 
325*f180142cSMarcin Wojtas 	SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "bw_in_allowance_exceeded",
326*f180142cSMarcin Wojtas 	    CTLFLAG_RD, &eni_metrics->bw_in_allowance_exceeded, 0,
327*f180142cSMarcin Wojtas 	    "Inbound BW allowance exceeded");
328*f180142cSMarcin Wojtas 	SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "bw_out_allowance_exceeded",
329*f180142cSMarcin Wojtas 	    CTLFLAG_RD, &eni_metrics->bw_out_allowance_exceeded, 0,
330*f180142cSMarcin Wojtas 	    "Outbound BW allowance exceeded");
331*f180142cSMarcin Wojtas 	SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "pps_allowance_exceeded",
332*f180142cSMarcin Wojtas 	    CTLFLAG_RD, &eni_metrics->pps_allowance_exceeded, 0,
333*f180142cSMarcin Wojtas 	    "PPS allowance exceeded");
334*f180142cSMarcin Wojtas 	SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "conntrack_allowance_exceeded",
335*f180142cSMarcin Wojtas 	    CTLFLAG_RD, &eni_metrics->conntrack_allowance_exceeded, 0,
336*f180142cSMarcin Wojtas 	    "Connection tracking allowance exceeded");
337*f180142cSMarcin Wojtas 	SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "linklocal_allowance_exceeded",
338*f180142cSMarcin Wojtas 	    CTLFLAG_RD, &eni_metrics->linklocal_allowance_exceeded, 0,
339*f180142cSMarcin Wojtas 	    "Linklocal packet rate allowance exceeded");
340*f180142cSMarcin Wojtas 
341*f180142cSMarcin Wojtas 	/*
342*f180142cSMarcin Wojtas 	 * Tuneable, which determines how often ENI metrics will be read.
343*f180142cSMarcin Wojtas 	 * 0 means it's turned off. Maximum allowed value is limited by:
344*f180142cSMarcin Wojtas 	 * ENI_METRICS_MAX_SAMPLE_INTERVAL.
345*f180142cSMarcin Wojtas 	 */
346*f180142cSMarcin Wojtas 	SYSCTL_ADD_PROC(ctx, eni_list, OID_AUTO, "sample_interval",
347*f180142cSMarcin Wojtas 	    CTLTYPE_U16 | CTLFLAG_RW | CTLFLAG_MPSAFE, adapter, 0,
348*f180142cSMarcin Wojtas 	    ena_sysctl_eni_metrics_interval, "SU",
349*f180142cSMarcin Wojtas 	    "Interval in seconds for updating ENI emetrics. 0 turns off the update.");
350*f180142cSMarcin Wojtas }
351*f180142cSMarcin Wojtas 
352*f180142cSMarcin Wojtas static void
3536064f289SMarcin Wojtas ena_sysctl_add_tuneables(struct ena_adapter *adapter)
3546064f289SMarcin Wojtas {
3556064f289SMarcin Wojtas 	device_t dev;
3566064f289SMarcin Wojtas 
3576064f289SMarcin Wojtas 	struct sysctl_ctx_list *ctx;
3586064f289SMarcin Wojtas 	struct sysctl_oid *tree;
3596064f289SMarcin Wojtas 	struct sysctl_oid_list *child;
3606064f289SMarcin Wojtas 
3616064f289SMarcin Wojtas 	dev = adapter->pdev;
3626064f289SMarcin Wojtas 
3636064f289SMarcin Wojtas 	ctx = device_get_sysctl_ctx(dev);
3646064f289SMarcin Wojtas 	tree = device_get_sysctl_tree(dev);
3656064f289SMarcin Wojtas 	child = SYSCTL_CHILDREN(tree);
3666064f289SMarcin Wojtas 
3676064f289SMarcin Wojtas 	/* Tuneable number of buffers in the buf-ring (drbr) */
3687029da5cSPawel Biernacki 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "buf_ring_size",
36921823546SMarcin Wojtas 	    CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE, adapter, 0,
37021823546SMarcin Wojtas 	    ena_sysctl_buf_ring_size, "I",
37121823546SMarcin Wojtas 	    "Size of the Tx buffer ring (drbr).");
3726064f289SMarcin Wojtas 
3737d8c4feeSMarcin Wojtas 	/* Tuneable number of the Rx ring size */
3747029da5cSPawel Biernacki 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_queue_size",
3757d8c4feeSMarcin Wojtas 	    CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE, adapter, 0,
3767d8c4feeSMarcin Wojtas 	    ena_sysctl_rx_queue_size, "I",
3777d8c4feeSMarcin Wojtas 	    "Size of the Rx ring. The size should be a power of 2.");
37856d41ad5SMarcin Wojtas 
37956d41ad5SMarcin Wojtas 	/* Tuneable number of IO queues */
38056d41ad5SMarcin Wojtas 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "io_queues_nb",
38156d41ad5SMarcin Wojtas 	    CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE, adapter, 0,
38256d41ad5SMarcin Wojtas 	    ena_sysctl_io_queues_nb, "I", "Number of IO queues.");
3836064f289SMarcin Wojtas }
3846064f289SMarcin Wojtas 
3856064f289SMarcin Wojtas 
3866064f289SMarcin Wojtas static int
3876064f289SMarcin Wojtas ena_sysctl_buf_ring_size(SYSCTL_HANDLER_ARGS)
3886064f289SMarcin Wojtas {
3896064f289SMarcin Wojtas 	struct ena_adapter *adapter = arg1;
39021823546SMarcin Wojtas 	uint32_t val;
3916064f289SMarcin Wojtas 	int error;
3926064f289SMarcin Wojtas 
3936064f289SMarcin Wojtas 	val = 0;
39421823546SMarcin Wojtas 	error = sysctl_wire_old_buffer(req, sizeof(val));
3956064f289SMarcin Wojtas 	if (error == 0) {
3966064f289SMarcin Wojtas 		val = adapter->buf_ring_size;
397*f180142cSMarcin Wojtas 		error = sysctl_handle_32(oidp, &val, 0, req);
3986064f289SMarcin Wojtas 	}
3996064f289SMarcin Wojtas 	if (error != 0 || req->newptr == NULL)
4006064f289SMarcin Wojtas 		return (error);
4016064f289SMarcin Wojtas 
40221823546SMarcin Wojtas 	if (!powerof2(val) || val == 0) {
4036064f289SMarcin Wojtas 		device_printf(adapter->pdev,
40421823546SMarcin Wojtas 		    "Requested new Tx buffer ring size (%u) is not a power of 2\n",
40521823546SMarcin Wojtas 		    val);
40621823546SMarcin Wojtas 		return (EINVAL);
4076064f289SMarcin Wojtas 	}
4086064f289SMarcin Wojtas 
40921823546SMarcin Wojtas 	if (val != adapter->buf_ring_size) {
41021823546SMarcin Wojtas 		device_printf(adapter->pdev,
41121823546SMarcin Wojtas 		    "Requested new Tx buffer ring size: %d. Old size: %d\n",
41221823546SMarcin Wojtas 		    val, adapter->buf_ring_size);
41321823546SMarcin Wojtas 
41421823546SMarcin Wojtas 		error = ena_update_buf_ring_size(adapter, val);
41521823546SMarcin Wojtas 	} else {
41621823546SMarcin Wojtas 		device_printf(adapter->pdev,
41721823546SMarcin Wojtas 		    "New Tx buffer ring size is the same as already used: %u\n",
41821823546SMarcin Wojtas 		    adapter->buf_ring_size);
41921823546SMarcin Wojtas 	}
42021823546SMarcin Wojtas 
42121823546SMarcin Wojtas 	return (error);
4226064f289SMarcin Wojtas }
4236064f289SMarcin Wojtas 
4246064f289SMarcin Wojtas static int
4256064f289SMarcin Wojtas ena_sysctl_rx_queue_size(SYSCTL_HANDLER_ARGS)
4266064f289SMarcin Wojtas {
4276064f289SMarcin Wojtas 	struct ena_adapter *adapter = arg1;
4287d8c4feeSMarcin Wojtas 	uint32_t val;
4296064f289SMarcin Wojtas 	int error;
4306064f289SMarcin Wojtas 
4316064f289SMarcin Wojtas 	val = 0;
4327d8c4feeSMarcin Wojtas 	error = sysctl_wire_old_buffer(req, sizeof(val));
4336064f289SMarcin Wojtas 	if (error == 0) {
4349762a033SMarcin Wojtas 		val = adapter->requested_rx_ring_size;
4357d8c4feeSMarcin Wojtas 		error = sysctl_handle_32(oidp, &val, 0, req);
4366064f289SMarcin Wojtas 	}
4376064f289SMarcin Wojtas 	if (error != 0 || req->newptr == NULL)
4386064f289SMarcin Wojtas 		return (error);
4396064f289SMarcin Wojtas 
4407d8c4feeSMarcin Wojtas 	if  (val < ENA_MIN_RING_SIZE || val > adapter->max_rx_ring_size) {
4416064f289SMarcin Wojtas 		device_printf(adapter->pdev,
4427d8c4feeSMarcin Wojtas 		    "Requested new Rx queue size (%u) is out of range: [%u, %u]\n",
4437d8c4feeSMarcin Wojtas 		    val, ENA_MIN_RING_SIZE, adapter->max_rx_ring_size);
4447d8c4feeSMarcin Wojtas 		return (EINVAL);
4456064f289SMarcin Wojtas 	}
4466064f289SMarcin Wojtas 
4477d8c4feeSMarcin Wojtas 	/* Check if the parameter is power of 2 */
4487d8c4feeSMarcin Wojtas 	if (!powerof2(val)) {
4497d8c4feeSMarcin Wojtas 		device_printf(adapter->pdev,
4507d8c4feeSMarcin Wojtas 		    "Requested new Rx queue size (%u) is not a power of 2\n",
4517d8c4feeSMarcin Wojtas 		    val);
4527d8c4feeSMarcin Wojtas 		return (EINVAL);
4537d8c4feeSMarcin Wojtas 	}
4547d8c4feeSMarcin Wojtas 
4559762a033SMarcin Wojtas 	if (val != adapter->requested_rx_ring_size) {
4567d8c4feeSMarcin Wojtas 		device_printf(adapter->pdev,
4577d8c4feeSMarcin Wojtas 		    "Requested new Rx queue size: %u. Old size: %u\n",
4589762a033SMarcin Wojtas 		    val, adapter->requested_rx_ring_size);
4597d8c4feeSMarcin Wojtas 
4609762a033SMarcin Wojtas 		error = ena_update_queue_size(adapter,
4619762a033SMarcin Wojtas 		    adapter->requested_tx_ring_size, val);
4627d8c4feeSMarcin Wojtas 	} else {
4637d8c4feeSMarcin Wojtas 		device_printf(adapter->pdev,
4647d8c4feeSMarcin Wojtas 		    "New Rx queue size is the same as already used: %u\n",
4659762a033SMarcin Wojtas 		    adapter->requested_rx_ring_size);
4667d8c4feeSMarcin Wojtas 	}
4677d8c4feeSMarcin Wojtas 
4687d8c4feeSMarcin Wojtas 	return (error);
4696064f289SMarcin Wojtas }
47056d41ad5SMarcin Wojtas 
47156d41ad5SMarcin Wojtas /*
47256d41ad5SMarcin Wojtas  * Change number of effectively used IO queues adapter->num_io_queues
47356d41ad5SMarcin Wojtas  */
47456d41ad5SMarcin Wojtas static int
47556d41ad5SMarcin Wojtas ena_sysctl_io_queues_nb(SYSCTL_HANDLER_ARGS)
47656d41ad5SMarcin Wojtas {
47756d41ad5SMarcin Wojtas 	struct ena_adapter *adapter = arg1;
47856d41ad5SMarcin Wojtas 	uint32_t tmp = 0;
47956d41ad5SMarcin Wojtas 	int error;
48056d41ad5SMarcin Wojtas 
48156d41ad5SMarcin Wojtas 	error = sysctl_wire_old_buffer(req, sizeof(tmp));
48256d41ad5SMarcin Wojtas 	if (error == 0) {
48356d41ad5SMarcin Wojtas 		tmp = adapter->num_io_queues;
48456d41ad5SMarcin Wojtas 		error = sysctl_handle_int(oidp, &tmp, 0, req);
48556d41ad5SMarcin Wojtas 	}
48656d41ad5SMarcin Wojtas 	if (error != 0 || req->newptr == NULL)
48756d41ad5SMarcin Wojtas 		return (error);
48856d41ad5SMarcin Wojtas 
48956d41ad5SMarcin Wojtas 	if (tmp == 0) {
49056d41ad5SMarcin Wojtas 		device_printf(adapter->pdev,
49156d41ad5SMarcin Wojtas 		    "Requested number of IO queues is zero\n");
49256d41ad5SMarcin Wojtas 		return (EINVAL);
49356d41ad5SMarcin Wojtas 	}
49456d41ad5SMarcin Wojtas 
49556d41ad5SMarcin Wojtas 	/*
49656d41ad5SMarcin Wojtas 	 * The adapter::max_num_io_queues is the HW capability. The system
49756d41ad5SMarcin Wojtas 	 * resources availability may potentially be a tighter limit. Therefore
49856d41ad5SMarcin Wojtas 	 * the relation `adapter::max_num_io_queues >= adapter::msix_vecs`
49956d41ad5SMarcin Wojtas 	 * always holds true, while the `adapter::msix_vecs` is variable across
50056d41ad5SMarcin Wojtas 	 * device reset (`ena_destroy_device()` + `ena_restore_device()`).
50156d41ad5SMarcin Wojtas 	 */
50256d41ad5SMarcin Wojtas 	if (tmp > (adapter->msix_vecs - ENA_ADMIN_MSIX_VEC)) {
50356d41ad5SMarcin Wojtas 		device_printf(adapter->pdev,
50456d41ad5SMarcin Wojtas 		    "Requested number of IO queues is higher than maximum "
50556d41ad5SMarcin Wojtas 		    "allowed (%u)\n", adapter->msix_vecs - ENA_ADMIN_MSIX_VEC);
50656d41ad5SMarcin Wojtas 		return (EINVAL);
50756d41ad5SMarcin Wojtas 	}
50856d41ad5SMarcin Wojtas 	if (tmp == adapter->num_io_queues) {
50956d41ad5SMarcin Wojtas 		device_printf(adapter->pdev,
51056d41ad5SMarcin Wojtas 		    "Requested number of IO queues is equal to current value "
51156d41ad5SMarcin Wojtas 		    "(%u)\n", adapter->num_io_queues);
51256d41ad5SMarcin Wojtas 	} else {
51356d41ad5SMarcin Wojtas 		device_printf(adapter->pdev,
51456d41ad5SMarcin Wojtas 		    "Requested new number of IO queues: %u, current value: "
51556d41ad5SMarcin Wojtas 		    "%u\n", tmp, adapter->num_io_queues);
51656d41ad5SMarcin Wojtas 
51756d41ad5SMarcin Wojtas 		error = ena_update_io_queue_nb(adapter, tmp);
51856d41ad5SMarcin Wojtas 	}
51956d41ad5SMarcin Wojtas 
52056d41ad5SMarcin Wojtas 	return (error);
52156d41ad5SMarcin Wojtas }
522*f180142cSMarcin Wojtas 
523*f180142cSMarcin Wojtas static int
524*f180142cSMarcin Wojtas ena_sysctl_eni_metrics_interval(SYSCTL_HANDLER_ARGS)
525*f180142cSMarcin Wojtas {
526*f180142cSMarcin Wojtas 	struct ena_adapter *adapter = arg1;
527*f180142cSMarcin Wojtas 	uint16_t interval;
528*f180142cSMarcin Wojtas 	int error;
529*f180142cSMarcin Wojtas 
530*f180142cSMarcin Wojtas 	error = sysctl_wire_old_buffer(req, sizeof(interval));
531*f180142cSMarcin Wojtas 	if (error == 0) {
532*f180142cSMarcin Wojtas 		interval = adapter->eni_metrics_sample_interval;
533*f180142cSMarcin Wojtas 		error = sysctl_handle_16(oidp, &interval, 0, req);
534*f180142cSMarcin Wojtas 	}
535*f180142cSMarcin Wojtas 	if (error != 0 || req->newptr == NULL)
536*f180142cSMarcin Wojtas 		return (error);
537*f180142cSMarcin Wojtas 
538*f180142cSMarcin Wojtas 	if (interval > ENI_METRICS_MAX_SAMPLE_INTERVAL) {
539*f180142cSMarcin Wojtas 		device_printf(adapter->pdev,
540*f180142cSMarcin Wojtas 		    "ENI metrics update interval is out of range - maximum allowed value: %d seconds\n",
541*f180142cSMarcin Wojtas 		    ENI_METRICS_MAX_SAMPLE_INTERVAL);
542*f180142cSMarcin Wojtas 		return (EINVAL);
543*f180142cSMarcin Wojtas 	}
544*f180142cSMarcin Wojtas 
545*f180142cSMarcin Wojtas 	if (interval == 0) {
546*f180142cSMarcin Wojtas 		device_printf(adapter->pdev,
547*f180142cSMarcin Wojtas 		    "ENI metrics update is now turned off\n");
548*f180142cSMarcin Wojtas 		bzero(&adapter->eni_metrics, sizeof(adapter->eni_metrics));
549*f180142cSMarcin Wojtas 	} else {
550*f180142cSMarcin Wojtas 		device_printf(adapter->pdev,
551*f180142cSMarcin Wojtas 		    "ENI metrics update interval is set to: %"PRIu16" seconds\n",
552*f180142cSMarcin Wojtas 		    interval);
553*f180142cSMarcin Wojtas 	}
554*f180142cSMarcin Wojtas 
555*f180142cSMarcin Wojtas 	adapter->eni_metrics_sample_interval = interval;
556*f180142cSMarcin Wojtas 
557*f180142cSMarcin Wojtas 	return (0);
558*f180142cSMarcin Wojtas }
559