1dc7e38acSHans Petter Selasky /*- 2dc7e38acSHans Petter Selasky * Copyright (c) 2015 Mellanox Technologies. All rights reserved. 3dc7e38acSHans Petter Selasky * 4dc7e38acSHans Petter Selasky * Redistribution and use in source and binary forms, with or without 5dc7e38acSHans Petter Selasky * modification, are permitted provided that the following conditions 6dc7e38acSHans Petter Selasky * are met: 7dc7e38acSHans Petter Selasky * 1. Redistributions of source code must retain the above copyright 8dc7e38acSHans Petter Selasky * notice, this list of conditions and the following disclaimer. 9dc7e38acSHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright 10dc7e38acSHans Petter Selasky * notice, this list of conditions and the following disclaimer in the 11dc7e38acSHans Petter Selasky * documentation and/or other materials provided with the distribution. 12dc7e38acSHans Petter Selasky * 13dc7e38acSHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 14dc7e38acSHans Petter Selasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15dc7e38acSHans Petter Selasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16dc7e38acSHans Petter Selasky * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17dc7e38acSHans Petter Selasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18dc7e38acSHans Petter Selasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19dc7e38acSHans Petter Selasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20dc7e38acSHans Petter Selasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21dc7e38acSHans Petter Selasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22dc7e38acSHans Petter Selasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23dc7e38acSHans Petter Selasky * SUCH DAMAGE. 24dc7e38acSHans Petter Selasky * 25dc7e38acSHans Petter Selasky * $FreeBSD$ 26dc7e38acSHans Petter Selasky */ 27dc7e38acSHans Petter Selasky 28dc7e38acSHans Petter Selasky #include "en.h" 29dc7e38acSHans Petter Selasky #include <net/sff8472.h> 30dc7e38acSHans Petter Selasky 31dc7e38acSHans Petter Selasky void 32dc7e38acSHans Petter Selasky mlx5e_create_stats(struct sysctl_ctx_list *ctx, 33dc7e38acSHans Petter Selasky struct sysctl_oid_list *parent, const char *buffer, 34dc7e38acSHans Petter Selasky const char **desc, unsigned num, u64 * arg) 35dc7e38acSHans Petter Selasky { 36dc7e38acSHans Petter Selasky struct sysctl_oid *node; 37dc7e38acSHans Petter Selasky unsigned x; 38dc7e38acSHans Petter Selasky 39dc7e38acSHans Petter Selasky sysctl_ctx_init(ctx); 40dc7e38acSHans Petter Selasky 41dc7e38acSHans Petter Selasky node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, 42dc7e38acSHans Petter Selasky buffer, CTLFLAG_RD, NULL, "Statistics"); 43dc7e38acSHans Petter Selasky if (node == NULL) 44dc7e38acSHans Petter Selasky return; 45dc7e38acSHans Petter Selasky for (x = 0; x != num; x++) { 46dc7e38acSHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 47dc7e38acSHans Petter Selasky desc[2 * x], CTLFLAG_RD, arg + x, desc[2 * x + 1]); 48dc7e38acSHans Petter Selasky } 49dc7e38acSHans Petter Selasky } 50dc7e38acSHans Petter Selasky 51376bcf63SHans Petter Selasky static void 52376bcf63SHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(struct mlx5e_priv *priv) 53376bcf63SHans Petter Selasky { 54376bcf63SHans Petter Selasky /* 55376bcf63SHans Petter Selasky * Limit the maximum distance between completion events to 56376bcf63SHans Petter Selasky * half of the currently set TX queue size. 57376bcf63SHans Petter Selasky * 58376bcf63SHans Petter Selasky * The maximum number of queue entries a single IP packet can 59376bcf63SHans Petter Selasky * consume is given by MLX5_SEND_WQE_MAX_WQEBBS. 60376bcf63SHans Petter Selasky * 61376bcf63SHans Petter Selasky * The worst case max value is then given as below: 62376bcf63SHans Petter Selasky */ 63376bcf63SHans Petter Selasky uint64_t max = priv->params_ethtool.tx_queue_size / 64376bcf63SHans Petter Selasky (2 * MLX5_SEND_WQE_MAX_WQEBBS); 65376bcf63SHans Petter Selasky 66376bcf63SHans Petter Selasky /* 67376bcf63SHans Petter Selasky * Update the maximum completion factor value in case the 68376bcf63SHans Petter Selasky * tx_queue_size field changed. Ensure we don't overflow 69376bcf63SHans Petter Selasky * 16-bits. 70376bcf63SHans Petter Selasky */ 71376bcf63SHans Petter Selasky if (max < 1) 72376bcf63SHans Petter Selasky max = 1; 73376bcf63SHans Petter Selasky else if (max > 65535) 74376bcf63SHans Petter Selasky max = 65535; 75376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact_max = max; 76376bcf63SHans Petter Selasky 77376bcf63SHans Petter Selasky /* 78376bcf63SHans Petter Selasky * Verify that the current TX completion factor is within the 79376bcf63SHans Petter Selasky * given limits: 80376bcf63SHans Petter Selasky */ 81376bcf63SHans Petter Selasky if (priv->params_ethtool.tx_completion_fact < 1) 82376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact = 1; 83376bcf63SHans Petter Selasky else if (priv->params_ethtool.tx_completion_fact > max) 84376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact = max; 85376bcf63SHans Petter Selasky } 86376bcf63SHans Petter Selasky 8782d2623eSHans Petter Selasky #define MLX5_PARAM_OFFSET(n) \ 8882d2623eSHans Petter Selasky __offsetof(struct mlx5e_priv, params_ethtool.n) 8982d2623eSHans Petter Selasky 90dc7e38acSHans Petter Selasky static int 91dc7e38acSHans Petter Selasky mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS) 92dc7e38acSHans Petter Selasky { 93dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1; 94dc7e38acSHans Petter Selasky uint64_t value; 95d2bf00a9SHans Petter Selasky int mode_modify; 96dc7e38acSHans Petter Selasky int was_opened; 97dc7e38acSHans Petter Selasky int error; 98dc7e38acSHans Petter Selasky 99dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 100dc7e38acSHans Petter Selasky value = priv->params_ethtool.arg[arg2]; 101ec0143b2SHans Petter Selasky if (req != NULL) { 102dc7e38acSHans Petter Selasky error = sysctl_handle_64(oidp, &value, 0, req); 103dc7e38acSHans Petter Selasky if (error || req->newptr == NULL || 104dc7e38acSHans Petter Selasky value == priv->params_ethtool.arg[arg2]) 105dc7e38acSHans Petter Selasky goto done; 106dc7e38acSHans Petter Selasky 107dc7e38acSHans Petter Selasky /* assign new value */ 108dc7e38acSHans Petter Selasky priv->params_ethtool.arg[arg2] = value; 109ec0143b2SHans Petter Selasky } else { 110ec0143b2SHans Petter Selasky error = 0; 111ec0143b2SHans Petter Selasky } 112dc7e38acSHans Petter Selasky /* check if device is gone */ 113dc7e38acSHans Petter Selasky if (priv->gone) { 114dc7e38acSHans Petter Selasky error = ENXIO; 115dc7e38acSHans Petter Selasky goto done; 116dc7e38acSHans Petter Selasky } 11782d2623eSHans Petter Selasky was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); 118d2bf00a9SHans Petter Selasky mode_modify = MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify); 11982d2623eSHans Petter Selasky 12082d2623eSHans Petter Selasky switch (MLX5_PARAM_OFFSET(arg[arg2])) { 12182d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_usecs): 122f03f517bSHans Petter Selasky /* import RX coal time */ 123f03f517bSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_usecs < 1) 124f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = 0; 125f03f517bSHans Petter Selasky else if (priv->params_ethtool.rx_coalesce_usecs > 126f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period)) { 127f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = 128f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period); 129f03f517bSHans Petter Selasky } 13082d2623eSHans Petter Selasky priv->params.rx_cq_moderation_usec = 13182d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs; 132f03f517bSHans Petter Selasky 13382d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 13482d2623eSHans Petter Selasky if (was_opened) 13582d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 13682d2623eSHans Petter Selasky break; 13782d2623eSHans Petter Selasky 13882d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_pkts): 139f03f517bSHans Petter Selasky /* import RX coal pkts */ 140f03f517bSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_pkts < 1) 141f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = 0; 142f03f517bSHans Petter Selasky else if (priv->params_ethtool.rx_coalesce_pkts > 143f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count)) { 144f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = 145f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count); 146f03f517bSHans Petter Selasky } 14782d2623eSHans Petter Selasky priv->params.rx_cq_moderation_pkts = 14882d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts; 149f03f517bSHans Petter Selasky 15082d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 15182d2623eSHans Petter Selasky if (was_opened) 15282d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 15382d2623eSHans Petter Selasky break; 15482d2623eSHans Petter Selasky 15582d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_usecs): 156f03f517bSHans Petter Selasky /* import TX coal time */ 157f03f517bSHans Petter Selasky if (priv->params_ethtool.tx_coalesce_usecs < 1) 158f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = 0; 159f03f517bSHans Petter Selasky else if (priv->params_ethtool.tx_coalesce_usecs > 160f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period)) { 161f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = 162f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period); 163f03f517bSHans Petter Selasky } 16482d2623eSHans Petter Selasky priv->params.tx_cq_moderation_usec = 16582d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs; 166f03f517bSHans Petter Selasky 16782d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 16882d2623eSHans Petter Selasky if (was_opened) 16982d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 17082d2623eSHans Petter Selasky break; 17182d2623eSHans Petter Selasky 17282d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_pkts): 173f03f517bSHans Petter Selasky /* import TX coal pkts */ 174f03f517bSHans Petter Selasky if (priv->params_ethtool.tx_coalesce_pkts < 1) 175f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = 0; 176f03f517bSHans Petter Selasky else if (priv->params_ethtool.tx_coalesce_pkts > 177f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count)) { 17882d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = 17982d2623eSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count); 180f03f517bSHans Petter Selasky } 18182d2623eSHans Petter Selasky priv->params.tx_cq_moderation_pkts = 18282d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts; 183dc7e38acSHans Petter Selasky 18482d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 18582d2623eSHans Petter Selasky if (was_opened) 186f03f517bSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 18782d2623eSHans Petter Selasky break; 18882d2623eSHans Petter Selasky 18982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_queue_size): 19082d2623eSHans Petter Selasky /* network interface must be down */ 19182d2623eSHans Petter Selasky if (was_opened) 192f03f517bSHans Petter Selasky mlx5e_close_locked(priv->ifp); 19382d2623eSHans Petter Selasky 194dc7e38acSHans Petter Selasky /* import TX queue size */ 195dc7e38acSHans Petter Selasky if (priv->params_ethtool.tx_queue_size < 196dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) { 197dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 198dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE); 199dc7e38acSHans Petter Selasky } else if (priv->params_ethtool.tx_queue_size > 200dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max) { 201dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 202dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max; 203dc7e38acSHans Petter Selasky } 20482d2623eSHans Petter Selasky /* store actual TX queue size */ 205dc7e38acSHans Petter Selasky priv->params.log_sq_size = 206dc7e38acSHans Petter Selasky order_base_2(priv->params_ethtool.tx_queue_size); 20782d2623eSHans Petter Selasky priv->params_ethtool.tx_queue_size = 20882d2623eSHans Petter Selasky 1 << priv->params.log_sq_size; 20982d2623eSHans Petter Selasky 21082d2623eSHans Petter Selasky /* verify TX completion factor */ 21182d2623eSHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv); 21282d2623eSHans Petter Selasky 21382d2623eSHans Petter Selasky /* restart network interface, if any */ 21482d2623eSHans Petter Selasky if (was_opened) 21582d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 21682d2623eSHans Petter Selasky break; 21782d2623eSHans Petter Selasky 21882d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_queue_size): 21982d2623eSHans Petter Selasky /* network interface must be down */ 22082d2623eSHans Petter Selasky if (was_opened) 22182d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 222dc7e38acSHans Petter Selasky 223dc7e38acSHans Petter Selasky /* import RX queue size */ 224dc7e38acSHans Petter Selasky if (priv->params_ethtool.rx_queue_size < 225dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) { 226dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 227dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE); 228dc7e38acSHans Petter Selasky } else if (priv->params_ethtool.rx_queue_size > 229dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max) { 230dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 231dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max; 232dc7e38acSHans Petter Selasky } 23382d2623eSHans Petter Selasky /* store actual RX queue size */ 234dc7e38acSHans Petter Selasky priv->params.log_rq_size = 235dc7e38acSHans Petter Selasky order_base_2(priv->params_ethtool.rx_queue_size); 23682d2623eSHans Petter Selasky priv->params_ethtool.rx_queue_size = 23782d2623eSHans Petter Selasky 1 << priv->params.log_rq_size; 238dc7e38acSHans Petter Selasky 23982d2623eSHans Petter Selasky /* update least number of RX WQEs */ 24082d2623eSHans Petter Selasky priv->params.min_rx_wqes = min( 241dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size - 1, 242dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_MIN_RX_WQES); 243dc7e38acSHans Petter Selasky 24482d2623eSHans Petter Selasky /* restart network interface, if any */ 24582d2623eSHans Petter Selasky if (was_opened) 24682d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 24782d2623eSHans Petter Selasky break; 24882d2623eSHans Petter Selasky 24982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(channels): 25082d2623eSHans Petter Selasky /* network interface must be down */ 25182d2623eSHans Petter Selasky if (was_opened) 25282d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 25382d2623eSHans Petter Selasky 254dc7e38acSHans Petter Selasky /* import number of channels */ 255dc7e38acSHans Petter Selasky if (priv->params_ethtool.channels < 1) 256dc7e38acSHans Petter Selasky priv->params_ethtool.channels = 1; 257dc7e38acSHans Petter Selasky else if (priv->params_ethtool.channels > 258dc7e38acSHans Petter Selasky (u64) priv->mdev->priv.eq_table.num_comp_vectors) { 259dc7e38acSHans Petter Selasky priv->params_ethtool.channels = 260dc7e38acSHans Petter Selasky (u64) priv->mdev->priv.eq_table.num_comp_vectors; 261dc7e38acSHans Petter Selasky } 262dc7e38acSHans Petter Selasky priv->params.num_channels = priv->params_ethtool.channels; 263dc7e38acSHans Petter Selasky 26482d2623eSHans Petter Selasky /* restart network interface, if any */ 26582d2623eSHans Petter Selasky if (was_opened) 26682d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 26782d2623eSHans Petter Selasky break; 26882d2623eSHans Petter Selasky 26982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_mode): 27082d2623eSHans Petter Selasky /* network interface must be down */ 271d2bf00a9SHans Petter Selasky if (was_opened != 0 && mode_modify == 0) 27282d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 27382d2623eSHans Petter Selasky 27482d2623eSHans Petter Selasky /* import RX coalesce mode */ 275dc7e38acSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_mode != 0) 276dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode = 1; 27782d2623eSHans Petter Selasky priv->params.rx_cq_moderation_mode = 27882d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode; 279dc7e38acSHans Petter Selasky 28082d2623eSHans Petter Selasky /* restart network interface, if any */ 281d2bf00a9SHans Petter Selasky if (was_opened != 0) { 282d2bf00a9SHans Petter Selasky if (mode_modify == 0) 28382d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 284d2bf00a9SHans Petter Selasky else 285d2bf00a9SHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 286d2bf00a9SHans Petter Selasky } 28782d2623eSHans Petter Selasky break; 28882d2623eSHans Petter Selasky 28982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_mode): 29082d2623eSHans Petter Selasky /* network interface must be down */ 291d2bf00a9SHans Petter Selasky if (was_opened != 0 && mode_modify == 0) 29282d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 29382d2623eSHans Petter Selasky 29482d2623eSHans Petter Selasky /* import TX coalesce mode */ 29574540a31SHans Petter Selasky if (priv->params_ethtool.tx_coalesce_mode != 0) 29674540a31SHans Petter Selasky priv->params_ethtool.tx_coalesce_mode = 1; 29782d2623eSHans Petter Selasky priv->params.tx_cq_moderation_mode = 29882d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_mode; 29974540a31SHans Petter Selasky 30082d2623eSHans Petter Selasky /* restart network interface, if any */ 301d2bf00a9SHans Petter Selasky if (was_opened != 0) { 302d2bf00a9SHans Petter Selasky if (mode_modify == 0) 30382d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 304d2bf00a9SHans Petter Selasky else 305d2bf00a9SHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 306d2bf00a9SHans Petter Selasky } 30782d2623eSHans Petter Selasky break; 30882d2623eSHans Petter Selasky 30982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(hw_lro): 31082d2623eSHans Petter Selasky /* network interface must be down */ 31182d2623eSHans Petter Selasky if (was_opened) 31282d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 31382d2623eSHans Petter Selasky 31482d2623eSHans Petter Selasky /* import HW LRO mode */ 315d7633a30SHans Petter Selasky if (priv->params_ethtool.hw_lro != 0) { 316d7633a30SHans Petter Selasky if ((priv->ifp->if_capenable & IFCAP_LRO) && 317d7633a30SHans Petter Selasky MLX5_CAP_ETH(priv->mdev, lro_cap)) { 318d7633a30SHans Petter Selasky priv->params.hw_lro_en = 1; 319d7633a30SHans Petter Selasky priv->params_ethtool.hw_lro = 1; 320d7633a30SHans Petter Selasky } else { 321d7633a30SHans Petter Selasky priv->params.hw_lro_en = 0; 32236c1007dSHans Petter Selasky priv->params_ethtool.hw_lro = 0; 32336c1007dSHans Petter Selasky error = EINVAL; 324d7633a30SHans Petter Selasky 325d7633a30SHans Petter Selasky if_printf(priv->ifp, "Can't enable HW LRO: " 32682d2623eSHans Petter Selasky "The HW or SW LRO feature is disabled\n"); 32736c1007dSHans Petter Selasky } 328bb3853c6SHans Petter Selasky } else { 329d7633a30SHans Petter Selasky priv->params.hw_lro_en = 0; 330dc7e38acSHans Petter Selasky } 33182d2623eSHans Petter Selasky /* restart network interface, if any */ 33282d2623eSHans Petter Selasky if (was_opened) 33382d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 33482d2623eSHans Petter Selasky break; 335dc7e38acSHans Petter Selasky 33682d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(cqe_zipping): 33782d2623eSHans Petter Selasky /* network interface must be down */ 33882d2623eSHans Petter Selasky if (was_opened) 33982d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 34082d2623eSHans Petter Selasky 34182d2623eSHans Petter Selasky /* import CQE zipping mode */ 34290cc1c77SHans Petter Selasky if (priv->params_ethtool.cqe_zipping && 34390cc1c77SHans Petter Selasky MLX5_CAP_GEN(priv->mdev, cqe_compression)) { 34490cc1c77SHans Petter Selasky priv->params.cqe_zipping_en = true; 34590cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = 1; 34690cc1c77SHans Petter Selasky } else { 34790cc1c77SHans Petter Selasky priv->params.cqe_zipping_en = false; 34890cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = 0; 34990cc1c77SHans Petter Selasky } 35082d2623eSHans Petter Selasky /* restart network interface, if any */ 351dc7e38acSHans Petter Selasky if (was_opened) 352dc7e38acSHans Petter Selasky mlx5e_open_locked(priv->ifp); 35382d2623eSHans Petter Selasky break; 35482d2623eSHans Petter Selasky 355b98ba640SHans Petter Selasky case MLX5_PARAM_OFFSET(tx_bufring_disable): 356b98ba640SHans Petter Selasky /* rangecheck input value */ 357b98ba640SHans Petter Selasky priv->params_ethtool.tx_bufring_disable = 358b98ba640SHans Petter Selasky priv->params_ethtool.tx_bufring_disable ? 1 : 0; 359b98ba640SHans Petter Selasky 360b98ba640SHans Petter Selasky /* reconfigure the sendqueues, if any */ 361b98ba640SHans Petter Selasky if (was_opened) { 362b98ba640SHans Petter Selasky mlx5e_close_locked(priv->ifp); 363b98ba640SHans Petter Selasky mlx5e_open_locked(priv->ifp); 364b98ba640SHans Petter Selasky } 365b98ba640SHans Petter Selasky break; 366b98ba640SHans Petter Selasky 36782d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_completion_fact): 36882d2623eSHans Petter Selasky /* network interface must be down */ 36982d2623eSHans Petter Selasky if (was_opened) 37082d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 37182d2623eSHans Petter Selasky 37282d2623eSHans Petter Selasky /* verify parameter */ 37382d2623eSHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv); 37482d2623eSHans Petter Selasky 37582d2623eSHans Petter Selasky /* restart network interface, if any */ 37682d2623eSHans Petter Selasky if (was_opened) 37782d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 37882d2623eSHans Petter Selasky break; 37982d2623eSHans Petter Selasky 380bb3616abSHans Petter Selasky case MLX5_PARAM_OFFSET(modify_tx_dma): 381bb3616abSHans Petter Selasky /* check if network interface is opened */ 382bb3616abSHans Petter Selasky if (was_opened) { 383bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma = 384bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma ? 1 : 0; 385bb3616abSHans Petter Selasky /* modify tx according to value */ 386bb3616abSHans Petter Selasky mlx5e_modify_tx_dma(priv, value != 0); 387bb3616abSHans Petter Selasky } else { 388bb3616abSHans Petter Selasky /* if closed force enable tx */ 389bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma = 0; 390bb3616abSHans Petter Selasky } 391bb3616abSHans Petter Selasky break; 392bb3616abSHans Petter Selasky 393bb3616abSHans Petter Selasky case MLX5_PARAM_OFFSET(modify_rx_dma): 394bb3616abSHans Petter Selasky /* check if network interface is opened */ 395bb3616abSHans Petter Selasky if (was_opened) { 396bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma = 397bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma ? 1 : 0; 398bb3616abSHans Petter Selasky /* modify rx according to value */ 399bb3616abSHans Petter Selasky mlx5e_modify_rx_dma(priv, value != 0); 400bb3616abSHans Petter Selasky } else { 401bb3616abSHans Petter Selasky /* if closed force enable rx */ 402bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma = 0; 403bb3616abSHans Petter Selasky } 404bb3616abSHans Petter Selasky break; 405bb3616abSHans Petter Selasky 40666d53750SHans Petter Selasky case MLX5_PARAM_OFFSET(diag_pci_enable): 40766d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable = 40866d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable ? 1 : 0; 40966d53750SHans Petter Selasky 41066d53750SHans Petter Selasky error = -mlx5_core_set_diagnostics_full(priv->mdev, 41166d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable, 41266d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable); 41366d53750SHans Petter Selasky break; 41466d53750SHans Petter Selasky 41566d53750SHans Petter Selasky case MLX5_PARAM_OFFSET(diag_general_enable): 41666d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable = 41766d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable ? 1 : 0; 41866d53750SHans Petter Selasky 41966d53750SHans Petter Selasky error = -mlx5_core_set_diagnostics_full(priv->mdev, 42066d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable, 42166d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable); 42266d53750SHans Petter Selasky break; 42366d53750SHans Petter Selasky 42482d2623eSHans Petter Selasky default: 42582d2623eSHans Petter Selasky break; 42682d2623eSHans Petter Selasky } 427dc7e38acSHans Petter Selasky done: 428dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 429dc7e38acSHans Petter Selasky return (error); 430dc7e38acSHans Petter Selasky } 431dc7e38acSHans Petter Selasky 432dc7e38acSHans Petter Selasky /* 433dc7e38acSHans Petter Selasky * Read the first three bytes of the eeprom in order to get the needed info 434dc7e38acSHans Petter Selasky * for the whole reading. 435dc7e38acSHans Petter Selasky * Byte 0 - Identifier byte 436dc7e38acSHans Petter Selasky * Byte 1 - Revision byte 437dc7e38acSHans Petter Selasky * Byte 2 - Status byte 438dc7e38acSHans Petter Selasky */ 439dc7e38acSHans Petter Selasky static int 440dc7e38acSHans Petter Selasky mlx5e_get_eeprom_info(struct mlx5e_priv *priv, struct mlx5e_eeprom *eeprom) 441dc7e38acSHans Petter Selasky { 442dc7e38acSHans Petter Selasky struct mlx5_core_dev *dev = priv->mdev; 443dc7e38acSHans Petter Selasky u32 data = 0; 444dc7e38acSHans Petter Selasky int size_read = 0; 445dc7e38acSHans Petter Selasky int ret; 446dc7e38acSHans Petter Selasky 447dc7e38acSHans Petter Selasky ret = mlx5_query_module_num(dev, &eeprom->module_num); 448dc7e38acSHans Petter Selasky if (ret) { 449dc7e38acSHans Petter Selasky if_printf(priv->ifp, "%s:%d: Failed query module error=%d\n", 450dc7e38acSHans Petter Selasky __func__, __LINE__, ret); 451dc7e38acSHans Petter Selasky return (ret); 452dc7e38acSHans Petter Selasky } 453dc7e38acSHans Petter Selasky 454dc7e38acSHans Petter Selasky /* Read the first three bytes to get Identifier, Revision and Status */ 455dc7e38acSHans Petter Selasky ret = mlx5_query_eeprom(dev, eeprom->i2c_addr, eeprom->page_num, 456dc7e38acSHans Petter Selasky eeprom->device_addr, MLX5E_EEPROM_INFO_BYTES, eeprom->module_num, &data, 457dc7e38acSHans Petter Selasky &size_read); 458dc7e38acSHans Petter Selasky if (ret) { 459dc7e38acSHans Petter Selasky if_printf(priv->ifp, "%s:%d: Failed query eeprom module error=0x%x\n", 460dc7e38acSHans Petter Selasky __func__, __LINE__, ret); 461dc7e38acSHans Petter Selasky return (ret); 462dc7e38acSHans Petter Selasky } 463dc7e38acSHans Petter Selasky 464dc7e38acSHans Petter Selasky switch (data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK) { 465dc7e38acSHans Petter Selasky case SFF_8024_ID_QSFP: 466dc7e38acSHans Petter Selasky eeprom->type = MLX5E_ETH_MODULE_SFF_8436; 467dc7e38acSHans Petter Selasky eeprom->len = MLX5E_ETH_MODULE_SFF_8436_LEN; 468dc7e38acSHans Petter Selasky break; 469dc7e38acSHans Petter Selasky case SFF_8024_ID_QSFPPLUS: 470dc7e38acSHans Petter Selasky case SFF_8024_ID_QSFP28: 471dc7e38acSHans Petter Selasky if ((data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK) == SFF_8024_ID_QSFP28 || 472dc7e38acSHans Petter Selasky ((data & MLX5_EEPROM_REVISION_ID_BYTE_MASK) >> 8) >= 0x3) { 473dc7e38acSHans Petter Selasky eeprom->type = MLX5E_ETH_MODULE_SFF_8636; 474dc7e38acSHans Petter Selasky eeprom->len = MLX5E_ETH_MODULE_SFF_8636_LEN; 475dc7e38acSHans Petter Selasky } else { 476dc7e38acSHans Petter Selasky eeprom->type = MLX5E_ETH_MODULE_SFF_8436; 477dc7e38acSHans Petter Selasky eeprom->len = MLX5E_ETH_MODULE_SFF_8436_LEN; 478dc7e38acSHans Petter Selasky } 479dc7e38acSHans Petter Selasky if ((data & MLX5_EEPROM_PAGE_3_VALID_BIT_MASK) == 0) 480dc7e38acSHans Petter Selasky eeprom->page_valid = 1; 481dc7e38acSHans Petter Selasky break; 482dc7e38acSHans Petter Selasky case SFF_8024_ID_SFP: 483dc7e38acSHans Petter Selasky eeprom->type = MLX5E_ETH_MODULE_SFF_8472; 484dc7e38acSHans Petter Selasky eeprom->len = MLX5E_ETH_MODULE_SFF_8472_LEN; 485dc7e38acSHans Petter Selasky break; 486dc7e38acSHans Petter Selasky default: 4877e1b8bc0SHans Petter Selasky if_printf(priv->ifp, "%s:%d: Not recognized cable type = 0x%x(%s)\n", 4887e1b8bc0SHans Petter Selasky __func__, __LINE__, data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK, 4897e1b8bc0SHans Petter Selasky sff_8024_id[data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK]); 490dc7e38acSHans Petter Selasky return (EINVAL); 491dc7e38acSHans Petter Selasky } 492dc7e38acSHans Petter Selasky return (0); 493dc7e38acSHans Petter Selasky } 494dc7e38acSHans Petter Selasky 495dc7e38acSHans Petter Selasky /* Read both low and high pages of the eeprom */ 496dc7e38acSHans Petter Selasky static int 497dc7e38acSHans Petter Selasky mlx5e_get_eeprom(struct mlx5e_priv *priv, struct mlx5e_eeprom *ee) 498dc7e38acSHans Petter Selasky { 499dc7e38acSHans Petter Selasky struct mlx5_core_dev *dev = priv->mdev; 500dc7e38acSHans Petter Selasky int size_read = 0; 501dc7e38acSHans Petter Selasky int ret; 502dc7e38acSHans Petter Selasky 503dc7e38acSHans Petter Selasky if (ee->len == 0) 504dc7e38acSHans Petter Selasky return (EINVAL); 505dc7e38acSHans Petter Selasky 506dc7e38acSHans Petter Selasky /* Read low page of the eeprom */ 507dc7e38acSHans Petter Selasky while (ee->device_addr < ee->len) { 508dc7e38acSHans Petter Selasky ret = mlx5_query_eeprom(dev, ee->i2c_addr, ee->page_num, ee->device_addr, 509dc7e38acSHans Petter Selasky ee->len - ee->device_addr, ee->module_num, 510dc7e38acSHans Petter Selasky ee->data + (ee->device_addr / 4), &size_read); 511dc7e38acSHans Petter Selasky if (ret) { 512dc7e38acSHans Petter Selasky if_printf(priv->ifp, "%s:%d: Failed reading eeprom, " 513dc7e38acSHans Petter Selasky "error = 0x%02x\n", __func__, __LINE__, ret); 514dc7e38acSHans Petter Selasky return (ret); 515dc7e38acSHans Petter Selasky } 516dc7e38acSHans Petter Selasky ee->device_addr += size_read; 517dc7e38acSHans Petter Selasky } 518dc7e38acSHans Petter Selasky 519dc7e38acSHans Petter Selasky /* Read high page of the eeprom */ 520dc7e38acSHans Petter Selasky if (ee->page_valid) { 521dc7e38acSHans Petter Selasky ee->device_addr = MLX5E_EEPROM_HIGH_PAGE_OFFSET; 522dc7e38acSHans Petter Selasky ee->page_num = MLX5E_EEPROM_HIGH_PAGE; 523dc7e38acSHans Petter Selasky size_read = 0; 524dc7e38acSHans Petter Selasky while (ee->device_addr < MLX5E_EEPROM_PAGE_LENGTH) { 525dc7e38acSHans Petter Selasky ret = mlx5_query_eeprom(dev, ee->i2c_addr, ee->page_num, 526dc7e38acSHans Petter Selasky ee->device_addr, MLX5E_EEPROM_PAGE_LENGTH - ee->device_addr, 527dc7e38acSHans Petter Selasky ee->module_num, ee->data + (ee->len / 4) + 528dc7e38acSHans Petter Selasky ((ee->device_addr - MLX5E_EEPROM_HIGH_PAGE_OFFSET) / 4), 529dc7e38acSHans Petter Selasky &size_read); 530dc7e38acSHans Petter Selasky if (ret) { 531dc7e38acSHans Petter Selasky if_printf(priv->ifp, "%s:%d: Failed reading eeprom, " 532dc7e38acSHans Petter Selasky "error = 0x%02x\n", __func__, __LINE__, ret); 533dc7e38acSHans Petter Selasky return (ret); 534dc7e38acSHans Petter Selasky } 535dc7e38acSHans Petter Selasky ee->device_addr += size_read; 536dc7e38acSHans Petter Selasky } 537dc7e38acSHans Petter Selasky } 538dc7e38acSHans Petter Selasky return (0); 539dc7e38acSHans Petter Selasky } 540dc7e38acSHans Petter Selasky 541dc7e38acSHans Petter Selasky static void 542dc7e38acSHans Petter Selasky mlx5e_print_eeprom(struct mlx5e_eeprom *eeprom) 543dc7e38acSHans Petter Selasky { 544ee41fc8fSHans Petter Selasky int row; 545ee41fc8fSHans Petter Selasky int index_in_row; 546ee41fc8fSHans Petter Selasky int byte_to_write = 0; 547ee41fc8fSHans Petter Selasky int line_length = 16; 548dc7e38acSHans Petter Selasky 549dc7e38acSHans Petter Selasky printf("\nOffset\t\tValues\n"); 550ee41fc8fSHans Petter Selasky printf("------\t\t------"); 551ee41fc8fSHans Petter Selasky while (byte_to_write < eeprom->len) { 552ee41fc8fSHans Petter Selasky printf("\n0x%04X\t\t", byte_to_write); 553ee41fc8fSHans Petter Selasky for (index_in_row = 0; index_in_row < line_length; index_in_row++) { 554ee41fc8fSHans Petter Selasky printf("%02X ", ((u8 *)eeprom->data)[byte_to_write]); 555ee41fc8fSHans Petter Selasky byte_to_write++; 556dc7e38acSHans Petter Selasky } 557dc7e38acSHans Petter Selasky } 558dc7e38acSHans Petter Selasky 559dc7e38acSHans Petter Selasky if (eeprom->page_valid) { 560dc7e38acSHans Petter Selasky row = MLX5E_EEPROM_HIGH_PAGE_OFFSET; 561ee41fc8fSHans Petter Selasky printf("\n\nUpper Page 0x03\n"); 562dc7e38acSHans Petter Selasky printf("\nOffset\t\tValues\n"); 563ee41fc8fSHans Petter Selasky printf("------\t\t------"); 564dc7e38acSHans Petter Selasky while (row < MLX5E_EEPROM_PAGE_LENGTH) { 565ee41fc8fSHans Petter Selasky printf("\n0x%04X\t\t", row); 566ee41fc8fSHans Petter Selasky for (index_in_row = 0; index_in_row < line_length; index_in_row++) { 567ee41fc8fSHans Petter Selasky printf("%02X ", ((u8 *)eeprom->data)[byte_to_write]); 568ee41fc8fSHans Petter Selasky byte_to_write++; 569dc7e38acSHans Petter Selasky row++; 570dc7e38acSHans Petter Selasky } 571dc7e38acSHans Petter Selasky } 572dc7e38acSHans Petter Selasky } 573dc7e38acSHans Petter Selasky } 574dc7e38acSHans Petter Selasky 575dc7e38acSHans Petter Selasky /* 576dc7e38acSHans Petter Selasky * Read cable EEPROM module information by first inspecting the first 577dc7e38acSHans Petter Selasky * three bytes to get the initial information for a whole reading. 578dc7e38acSHans Petter Selasky * Information will be printed to dmesg. 579dc7e38acSHans Petter Selasky */ 580dc7e38acSHans Petter Selasky static int 581dc7e38acSHans Petter Selasky mlx5e_read_eeprom(SYSCTL_HANDLER_ARGS) 582dc7e38acSHans Petter Selasky { 583dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1; 584dc7e38acSHans Petter Selasky struct mlx5e_eeprom eeprom; 585dc7e38acSHans Petter Selasky int error; 586dc7e38acSHans Petter Selasky int result = 0; 587dc7e38acSHans Petter Selasky 588dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 589dc7e38acSHans Petter Selasky error = sysctl_handle_int(oidp, &result, 0, req); 590dc7e38acSHans Petter Selasky if (error || !req->newptr) 591dc7e38acSHans Petter Selasky goto done; 592dc7e38acSHans Petter Selasky 593dc7e38acSHans Petter Selasky /* Check if device is gone */ 594dc7e38acSHans Petter Selasky if (priv->gone) { 595dc7e38acSHans Petter Selasky error = ENXIO; 596dc7e38acSHans Petter Selasky goto done; 597dc7e38acSHans Petter Selasky } 598dc7e38acSHans Petter Selasky 599dc7e38acSHans Petter Selasky if (result == 1) { 600dc7e38acSHans Petter Selasky eeprom.i2c_addr = MLX5E_I2C_ADDR_LOW; 601dc7e38acSHans Petter Selasky eeprom.device_addr = 0; 602dc7e38acSHans Petter Selasky eeprom.page_num = MLX5E_EEPROM_LOW_PAGE; 603dc7e38acSHans Petter Selasky eeprom.page_valid = 0; 604dc7e38acSHans Petter Selasky 605dc7e38acSHans Petter Selasky /* Read three first bytes to get important info */ 606dc7e38acSHans Petter Selasky error = mlx5e_get_eeprom_info(priv, &eeprom); 607dc7e38acSHans Petter Selasky if (error) { 608dc7e38acSHans Petter Selasky if_printf(priv->ifp, "%s:%d: Failed reading eeprom's " 609dc7e38acSHans Petter Selasky "initial information\n", __func__, __LINE__); 610dc7e38acSHans Petter Selasky error = 0; 611dc7e38acSHans Petter Selasky goto done; 612dc7e38acSHans Petter Selasky } 613bb3853c6SHans Petter Selasky /* 614bb3853c6SHans Petter Selasky * Allocate needed length buffer and additional space for 615bb3853c6SHans Petter Selasky * page 0x03 616bb3853c6SHans Petter Selasky */ 617dc7e38acSHans Petter Selasky eeprom.data = malloc(eeprom.len + MLX5E_EEPROM_PAGE_LENGTH, 618dc7e38acSHans Petter Selasky M_MLX5EN, M_WAITOK | M_ZERO); 619dc7e38acSHans Petter Selasky 620dc7e38acSHans Petter Selasky /* Read the whole eeprom information */ 621dc7e38acSHans Petter Selasky error = mlx5e_get_eeprom(priv, &eeprom); 622dc7e38acSHans Petter Selasky if (error) { 623dc7e38acSHans Petter Selasky if_printf(priv->ifp, "%s:%d: Failed reading eeprom\n", 624dc7e38acSHans Petter Selasky __func__, __LINE__); 625dc7e38acSHans Petter Selasky error = 0; 626bb3853c6SHans Petter Selasky /* 627bb3853c6SHans Petter Selasky * Continue printing partial information in case of 628bb3853c6SHans Petter Selasky * an error 629bb3853c6SHans Petter Selasky */ 630dc7e38acSHans Petter Selasky } 631dc7e38acSHans Petter Selasky mlx5e_print_eeprom(&eeprom); 632dc7e38acSHans Petter Selasky free(eeprom.data, M_MLX5EN); 633dc7e38acSHans Petter Selasky } 634dc7e38acSHans Petter Selasky done: 635dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 636dc7e38acSHans Petter Selasky return (error); 637dc7e38acSHans Petter Selasky } 638dc7e38acSHans Petter Selasky 639dc7e38acSHans Petter Selasky static const char *mlx5e_params_desc[] = { 640dc7e38acSHans Petter Selasky MLX5E_PARAMS(MLX5E_STATS_DESC) 641dc7e38acSHans Petter Selasky }; 642dc7e38acSHans Petter Selasky 643dc7e38acSHans Petter Selasky static const char *mlx5e_port_stats_debug_desc[] = { 644dc7e38acSHans Petter Selasky MLX5E_PORT_STATS_DEBUG(MLX5E_STATS_DESC) 645dc7e38acSHans Petter Selasky }; 646dc7e38acSHans Petter Selasky 647dc7e38acSHans Petter Selasky static int 648dc7e38acSHans Petter Selasky mlx5e_ethtool_debug_stats(SYSCTL_HANDLER_ARGS) 649dc7e38acSHans Petter Selasky { 650dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1; 651dc7e38acSHans Petter Selasky int error; 652dc7e38acSHans Petter Selasky int sys_debug; 653dc7e38acSHans Petter Selasky 654dc7e38acSHans Petter Selasky sys_debug = priv->sysctl_debug; 655dc7e38acSHans Petter Selasky error = sysctl_handle_int(oidp, &priv->sysctl_debug, 0, req); 656dc7e38acSHans Petter Selasky if (error || !req->newptr) 657dc7e38acSHans Petter Selasky return (error); 658dc7e38acSHans Petter Selasky priv->sysctl_debug = !!priv->sysctl_debug; 659dc7e38acSHans Petter Selasky if (sys_debug == priv->sysctl_debug) 660dc7e38acSHans Petter Selasky return (error); 661dc7e38acSHans Petter Selasky if (priv->sysctl_debug) 662dc7e38acSHans Petter Selasky mlx5e_create_stats(&priv->stats.port_stats_debug.ctx, 663dc7e38acSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), "debug_stats", 664dc7e38acSHans Petter Selasky mlx5e_port_stats_debug_desc, MLX5E_PORT_STATS_DEBUG_NUM, 665dc7e38acSHans Petter Selasky priv->stats.port_stats_debug.arg); 666dc7e38acSHans Petter Selasky else 667dc7e38acSHans Petter Selasky sysctl_ctx_free(&priv->stats.port_stats_debug.ctx); 668dc7e38acSHans Petter Selasky return (error); 669dc7e38acSHans Petter Selasky } 670dc7e38acSHans Petter Selasky 67166d53750SHans Petter Selasky static void 67266d53750SHans Petter Selasky mlx5e_create_diagnostics(struct mlx5e_priv *priv) 67366d53750SHans Petter Selasky { 67466d53750SHans Petter Selasky struct mlx5_core_diagnostics_entry entry; 67566d53750SHans Petter Selasky struct sysctl_ctx_list *ctx; 67666d53750SHans Petter Selasky struct sysctl_oid *node; 67766d53750SHans Petter Selasky int x; 67866d53750SHans Petter Selasky 67966d53750SHans Petter Selasky /* sysctl context we are using */ 68066d53750SHans Petter Selasky ctx = &priv->sysctl_ctx; 68166d53750SHans Petter Selasky 68266d53750SHans Petter Selasky /* create root node */ 68366d53750SHans Petter Selasky node = SYSCTL_ADD_NODE(ctx, 68466d53750SHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO, 68566d53750SHans Petter Selasky "diagnostics", CTLFLAG_RD, NULL, "Diagnostics"); 68666d53750SHans Petter Selasky if (node == NULL) 68766d53750SHans Petter Selasky return; 68866d53750SHans Petter Selasky 68966d53750SHans Petter Selasky /* create PCI diagnostics */ 69066d53750SHans Petter Selasky for (x = 0; x != MLX5_CORE_PCI_DIAGNOSTICS_NUM; x++) { 69166d53750SHans Petter Selasky entry = mlx5_core_pci_diagnostics_table[x]; 69266d53750SHans Petter Selasky if (mlx5_core_supports_diagnostics(priv->mdev, entry.counter_id) == 0) 69366d53750SHans Petter Selasky continue; 69466d53750SHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 69566d53750SHans Petter Selasky entry.desc, CTLFLAG_RD, priv->params_pci.array + x, 69666d53750SHans Petter Selasky "PCI diagnostics counter"); 69766d53750SHans Petter Selasky } 69866d53750SHans Petter Selasky 69966d53750SHans Petter Selasky /* create general diagnostics */ 70066d53750SHans Petter Selasky for (x = 0; x != MLX5_CORE_GENERAL_DIAGNOSTICS_NUM; x++) { 70166d53750SHans Petter Selasky entry = mlx5_core_general_diagnostics_table[x]; 70266d53750SHans Petter Selasky if (mlx5_core_supports_diagnostics(priv->mdev, entry.counter_id) == 0) 70366d53750SHans Petter Selasky continue; 70466d53750SHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 70566d53750SHans Petter Selasky entry.desc, CTLFLAG_RD, priv->params_general.array + x, 70666d53750SHans Petter Selasky "General diagnostics counter"); 70766d53750SHans Petter Selasky } 70866d53750SHans Petter Selasky } 70966d53750SHans Petter Selasky 710dc7e38acSHans Petter Selasky void 711dc7e38acSHans Petter Selasky mlx5e_create_ethtool(struct mlx5e_priv *priv) 712dc7e38acSHans Petter Selasky { 713dc7e38acSHans Petter Selasky struct sysctl_oid *node; 714dc7e38acSHans Petter Selasky const char *pnameunit; 715dc7e38acSHans Petter Selasky unsigned x; 716dc7e38acSHans Petter Selasky 717dc7e38acSHans Petter Selasky /* set some defaults */ 718dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE; 719dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max = 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE; 720dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 1 << priv->params.log_sq_size; 721dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 1 << priv->params.log_rq_size; 722dc7e38acSHans Petter Selasky priv->params_ethtool.channels = priv->params.num_channels; 723dc7e38acSHans Petter Selasky priv->params_ethtool.coalesce_pkts_max = MLX5E_FLD_MAX(cqc, cq_max_count); 724dc7e38acSHans Petter Selasky priv->params_ethtool.coalesce_usecs_max = MLX5E_FLD_MAX(cqc, cq_period); 725dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode = priv->params.rx_cq_moderation_mode; 726dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = priv->params.rx_cq_moderation_usec; 727dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = priv->params.rx_cq_moderation_pkts; 72874540a31SHans Petter Selasky priv->params_ethtool.tx_coalesce_mode = priv->params.tx_cq_moderation_mode; 729dc7e38acSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = priv->params.tx_cq_moderation_usec; 730dc7e38acSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = priv->params.tx_cq_moderation_pkts; 731dc7e38acSHans Petter Selasky priv->params_ethtool.hw_lro = priv->params.hw_lro_en; 73290cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = priv->params.cqe_zipping_en; 733376bcf63SHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv); 734dc7e38acSHans Petter Selasky 735dc7e38acSHans Petter Selasky /* create root node */ 736dc7e38acSHans Petter Selasky node = SYSCTL_ADD_NODE(&priv->sysctl_ctx, 737dc7e38acSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO, 738dc7e38acSHans Petter Selasky "conf", CTLFLAG_RW, NULL, "Configuration"); 739dc7e38acSHans Petter Selasky if (node == NULL) 740dc7e38acSHans Petter Selasky return; 741dc7e38acSHans Petter Selasky for (x = 0; x != MLX5E_PARAMS_NUM; x++) { 742dc7e38acSHans Petter Selasky /* check for read-only parameter */ 743dc7e38acSHans Petter Selasky if (strstr(mlx5e_params_desc[2 * x], "_max") != NULL) { 744dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 745dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x], CTLTYPE_U64 | CTLFLAG_RD | 746dc7e38acSHans Petter Selasky CTLFLAG_MPSAFE, priv, x, &mlx5e_ethtool_handler, "QU", 747dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x + 1]); 748dc7e38acSHans Petter Selasky } else { 749ec0143b2SHans Petter Selasky #if (__FreeBSD_version < 1100000) 750ec0143b2SHans Petter Selasky char path[64]; 751ec0143b2SHans Petter Selasky #endif 752ec0143b2SHans Petter Selasky /* 753ec0143b2SHans Petter Selasky * NOTE: In FreeBSD-11 and newer the 754ec0143b2SHans Petter Selasky * CTLFLAG_RWTUN flag will take care of 755ec0143b2SHans Petter Selasky * loading default sysctl value from the 756ec0143b2SHans Petter Selasky * kernel environment, if any: 757ec0143b2SHans Petter Selasky */ 758dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 759dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x], CTLTYPE_U64 | CTLFLAG_RWTUN | 760dc7e38acSHans Petter Selasky CTLFLAG_MPSAFE, priv, x, &mlx5e_ethtool_handler, "QU", 761dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x + 1]); 762ec0143b2SHans Petter Selasky 763ec0143b2SHans Petter Selasky #if (__FreeBSD_version < 1100000) 764ec0143b2SHans Petter Selasky /* compute path for sysctl */ 765ec0143b2SHans Petter Selasky snprintf(path, sizeof(path), "dev.mce.%d.conf.%s", 766ec0143b2SHans Petter Selasky device_get_unit(priv->mdev->pdev->dev.bsddev), 767ec0143b2SHans Petter Selasky mlx5e_params_desc[2 * x]); 768ec0143b2SHans Petter Selasky 769ec0143b2SHans Petter Selasky /* try to fetch tunable, if any */ 770ec0143b2SHans Petter Selasky if (TUNABLE_QUAD_FETCH(path, &priv->params_ethtool.arg[x])) 771ec0143b2SHans Petter Selasky mlx5e_ethtool_handler(NULL, priv, x, NULL); 772ec0143b2SHans Petter Selasky #endif 773dc7e38acSHans Petter Selasky } 774dc7e38acSHans Petter Selasky } 775dc7e38acSHans Petter Selasky 776dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 777dc7e38acSHans Petter Selasky "debug_stats", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv, 778dc7e38acSHans Petter Selasky 0, &mlx5e_ethtool_debug_stats, "I", "Extended debug statistics"); 779dc7e38acSHans Petter Selasky 780dc7e38acSHans Petter Selasky pnameunit = device_get_nameunit(priv->mdev->pdev->dev.bsddev); 781dc7e38acSHans Petter Selasky 782dc7e38acSHans Petter Selasky SYSCTL_ADD_STRING(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), 783dc7e38acSHans Petter Selasky OID_AUTO, "device_name", CTLFLAG_RD, 784dc7e38acSHans Petter Selasky __DECONST(void *, pnameunit), 0, 785dc7e38acSHans Petter Selasky "PCI device name"); 786dc7e38acSHans Petter Selasky 787dc7e38acSHans Petter Selasky /* EEPROM support */ 788dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, "eeprom_info", 789dc7e38acSHans Petter Selasky CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv, 0, 790dc7e38acSHans Petter Selasky mlx5e_read_eeprom, "I", "EEPROM information"); 79166d53750SHans Petter Selasky 79266d53750SHans Petter Selasky /* Diagnostics support */ 79366d53750SHans Petter Selasky mlx5e_create_diagnostics(priv); 794dc7e38acSHans Petter Selasky } 795