1dc7e38acSHans Petter Selasky /*- 22110251aSHans Petter Selasky * Copyright (c) 2015-2019 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" 296deb0b1eSHans Petter Selasky #include "port_buffer.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 517272f9cdSHans Petter Selasky void 527272f9cdSHans Petter Selasky mlx5e_create_counter_stats(struct sysctl_ctx_list *ctx, 537272f9cdSHans Petter Selasky struct sysctl_oid_list *parent, const char *buffer, 547272f9cdSHans Petter Selasky const char **desc, unsigned num, counter_u64_t *arg) 557272f9cdSHans Petter Selasky { 567272f9cdSHans Petter Selasky struct sysctl_oid *node; 577272f9cdSHans Petter Selasky unsigned x; 587272f9cdSHans Petter Selasky 597272f9cdSHans Petter Selasky sysctl_ctx_init(ctx); 607272f9cdSHans Petter Selasky 617272f9cdSHans Petter Selasky node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, 627272f9cdSHans Petter Selasky buffer, CTLFLAG_RD, NULL, "Statistics"); 637272f9cdSHans Petter Selasky if (node == NULL) 647272f9cdSHans Petter Selasky return; 657272f9cdSHans Petter Selasky for (x = 0; x != num; x++) { 667272f9cdSHans Petter Selasky SYSCTL_ADD_COUNTER_U64(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 677272f9cdSHans Petter Selasky desc[2 * x], CTLFLAG_RD, arg + x, desc[2 * x + 1]); 687272f9cdSHans Petter Selasky } 697272f9cdSHans Petter Selasky } 707272f9cdSHans Petter Selasky 71376bcf63SHans Petter Selasky static void 72376bcf63SHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(struct mlx5e_priv *priv) 73376bcf63SHans Petter Selasky { 74376bcf63SHans Petter Selasky /* 75376bcf63SHans Petter Selasky * Limit the maximum distance between completion events to 76376bcf63SHans Petter Selasky * half of the currently set TX queue size. 77376bcf63SHans Petter Selasky * 78376bcf63SHans Petter Selasky * The maximum number of queue entries a single IP packet can 79376bcf63SHans Petter Selasky * consume is given by MLX5_SEND_WQE_MAX_WQEBBS. 80376bcf63SHans Petter Selasky * 81376bcf63SHans Petter Selasky * The worst case max value is then given as below: 82376bcf63SHans Petter Selasky */ 83376bcf63SHans Petter Selasky uint64_t max = priv->params_ethtool.tx_queue_size / 84376bcf63SHans Petter Selasky (2 * MLX5_SEND_WQE_MAX_WQEBBS); 85376bcf63SHans Petter Selasky 86376bcf63SHans Petter Selasky /* 87376bcf63SHans Petter Selasky * Update the maximum completion factor value in case the 88376bcf63SHans Petter Selasky * tx_queue_size field changed. Ensure we don't overflow 89376bcf63SHans Petter Selasky * 16-bits. 90376bcf63SHans Petter Selasky */ 91376bcf63SHans Petter Selasky if (max < 1) 92376bcf63SHans Petter Selasky max = 1; 93376bcf63SHans Petter Selasky else if (max > 65535) 94376bcf63SHans Petter Selasky max = 65535; 95376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact_max = max; 96376bcf63SHans Petter Selasky 97376bcf63SHans Petter Selasky /* 98376bcf63SHans Petter Selasky * Verify that the current TX completion factor is within the 99376bcf63SHans Petter Selasky * given limits: 100376bcf63SHans Petter Selasky */ 101376bcf63SHans Petter Selasky if (priv->params_ethtool.tx_completion_fact < 1) 102376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact = 1; 103376bcf63SHans Petter Selasky else if (priv->params_ethtool.tx_completion_fact > max) 104376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact = max; 105376bcf63SHans Petter Selasky } 106376bcf63SHans Petter Selasky 107cfc9c386SHans Petter Selasky static int 108cfc9c386SHans Petter Selasky mlx5e_getmaxrate(struct mlx5e_priv *priv) 109cfc9c386SHans Petter Selasky { 110cfc9c386SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 111cfc9c386SHans Petter Selasky u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS]; 112cfc9c386SHans Petter Selasky u8 max_bw_value[IEEE_8021QAZ_MAX_TCS]; 113cfc9c386SHans Petter Selasky int err; 114cfc9c386SHans Petter Selasky int i; 115cfc9c386SHans Petter Selasky 116cfc9c386SHans Petter Selasky PRIV_LOCK(priv); 117cfc9c386SHans Petter Selasky err = -mlx5_query_port_tc_rate_limit(mdev, max_bw_value, max_bw_unit); 118cfc9c386SHans Petter Selasky if (err) 119cfc9c386SHans Petter Selasky goto done; 120cfc9c386SHans Petter Selasky 121cfc9c386SHans Petter Selasky for (i = 0; i <= mlx5_max_tc(mdev); i++) { 122cfc9c386SHans Petter Selasky switch (max_bw_unit[i]) { 123cfc9c386SHans Petter Selasky case MLX5_100_MBPS_UNIT: 124cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = max_bw_value[i] * MLX5E_100MB; 125cfc9c386SHans Petter Selasky break; 126cfc9c386SHans Petter Selasky case MLX5_GBPS_UNIT: 127cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = max_bw_value[i] * MLX5E_1GB; 128cfc9c386SHans Petter Selasky break; 129cfc9c386SHans Petter Selasky case MLX5_BW_NO_LIMIT: 130cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = 0; 131cfc9c386SHans Petter Selasky break; 132cfc9c386SHans Petter Selasky default: 133cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = -1; 134cfc9c386SHans Petter Selasky WARN_ONCE(true, "non-supported BW unit"); 135cfc9c386SHans Petter Selasky break; 136cfc9c386SHans Petter Selasky } 137cfc9c386SHans Petter Selasky } 138cfc9c386SHans Petter Selasky done: 139cfc9c386SHans Petter Selasky PRIV_UNLOCK(priv); 140cfc9c386SHans Petter Selasky return (err); 141cfc9c386SHans Petter Selasky } 142cfc9c386SHans Petter Selasky 143cfc9c386SHans Petter Selasky static int 144e870c0abSSlava Shwartsman mlx5e_get_max_alloc(struct mlx5e_priv *priv) 145e870c0abSSlava Shwartsman { 146e870c0abSSlava Shwartsman struct mlx5_core_dev *mdev = priv->mdev; 147e870c0abSSlava Shwartsman int err; 148e870c0abSSlava Shwartsman int x; 149e870c0abSSlava Shwartsman 150e870c0abSSlava Shwartsman PRIV_LOCK(priv); 151e870c0abSSlava Shwartsman err = -mlx5_query_port_tc_bw_alloc(mdev, priv->params_ethtool.max_bw_share); 152e870c0abSSlava Shwartsman if (err == 0) { 153e870c0abSSlava Shwartsman /* set default value */ 154e870c0abSSlava Shwartsman for (x = 0; x != IEEE_8021QAZ_MAX_TCS; x++) { 155e870c0abSSlava Shwartsman priv->params_ethtool.max_bw_share[x] = 156e870c0abSSlava Shwartsman 100 / IEEE_8021QAZ_MAX_TCS; 157e870c0abSSlava Shwartsman } 158e870c0abSSlava Shwartsman err = -mlx5_set_port_tc_bw_alloc(mdev, 159e870c0abSSlava Shwartsman priv->params_ethtool.max_bw_share); 160e870c0abSSlava Shwartsman } 161e870c0abSSlava Shwartsman PRIV_UNLOCK(priv); 162e870c0abSSlava Shwartsman 163e870c0abSSlava Shwartsman return (err); 164e870c0abSSlava Shwartsman } 165e870c0abSSlava Shwartsman 166e870c0abSSlava Shwartsman static int 167ed0cee0bSHans Petter Selasky mlx5e_get_dscp(struct mlx5e_priv *priv) 168ed0cee0bSHans Petter Selasky { 169ed0cee0bSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 170ed0cee0bSHans Petter Selasky int err; 171ed0cee0bSHans Petter Selasky 172ed0cee0bSHans Petter Selasky if (MLX5_CAP_GEN(mdev, qcam_reg) == 0 || 173ed0cee0bSHans Petter Selasky MLX5_CAP_QCAM_REG(mdev, qpts) == 0 || 174ed0cee0bSHans Petter Selasky MLX5_CAP_QCAM_REG(mdev, qpdpm) == 0) 175ed0cee0bSHans Petter Selasky return (EOPNOTSUPP); 176ed0cee0bSHans Petter Selasky 177ed0cee0bSHans Petter Selasky PRIV_LOCK(priv); 178ed0cee0bSHans Petter Selasky err = -mlx5_query_dscp2prio(mdev, priv->params_ethtool.dscp2prio); 179ed0cee0bSHans Petter Selasky if (err) 180ed0cee0bSHans Petter Selasky goto done; 181ed0cee0bSHans Petter Selasky 182ed0cee0bSHans Petter Selasky err = -mlx5_query_trust_state(mdev, &priv->params_ethtool.trust_state); 183ed0cee0bSHans Petter Selasky if (err) 184ed0cee0bSHans Petter Selasky goto done; 185ed0cee0bSHans Petter Selasky done: 186ed0cee0bSHans Petter Selasky PRIV_UNLOCK(priv); 187ed0cee0bSHans Petter Selasky return (err); 188ed0cee0bSHans Petter Selasky } 189ed0cee0bSHans Petter Selasky 190e870c0abSSlava Shwartsman static void 191e870c0abSSlava Shwartsman mlx5e_tc_get_parameters(struct mlx5e_priv *priv, 192e870c0abSSlava Shwartsman u64 *new_bw_value, u8 *max_bw_value, u8 *max_bw_unit) 193e870c0abSSlava Shwartsman { 194e870c0abSSlava Shwartsman const u64 upper_limit_mbps = 255 * MLX5E_100MB; 195e870c0abSSlava Shwartsman const u64 upper_limit_gbps = 255 * MLX5E_1GB; 196e870c0abSSlava Shwartsman u64 temp; 197e870c0abSSlava Shwartsman int i; 198e870c0abSSlava Shwartsman 199e870c0abSSlava Shwartsman memset(max_bw_value, 0, IEEE_8021QAZ_MAX_TCS); 200e870c0abSSlava Shwartsman memset(max_bw_unit, 0, IEEE_8021QAZ_MAX_TCS); 201e870c0abSSlava Shwartsman 202e870c0abSSlava Shwartsman for (i = 0; i <= mlx5_max_tc(priv->mdev); i++) { 203e870c0abSSlava Shwartsman temp = (new_bw_value != NULL) ? 204e870c0abSSlava Shwartsman new_bw_value[i] : priv->params_ethtool.max_bw_value[i]; 205e870c0abSSlava Shwartsman 206e870c0abSSlava Shwartsman if (!temp) { 207e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_BW_NO_LIMIT; 208e870c0abSSlava Shwartsman } else if (temp > upper_limit_gbps) { 209e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_BW_NO_LIMIT; 210e870c0abSSlava Shwartsman } else if (temp <= upper_limit_mbps) { 211e870c0abSSlava Shwartsman max_bw_value[i] = howmany(temp, MLX5E_100MB); 212e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_100_MBPS_UNIT; 213e870c0abSSlava Shwartsman } else { 214e870c0abSSlava Shwartsman max_bw_value[i] = howmany(temp, MLX5E_1GB); 215e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_GBPS_UNIT; 216e870c0abSSlava Shwartsman } 217e870c0abSSlava Shwartsman } 218e870c0abSSlava Shwartsman } 219e870c0abSSlava Shwartsman 220ed0cee0bSHans Petter Selasky static int 221cfc9c386SHans Petter Selasky mlx5e_tc_maxrate_handler(SYSCTL_HANDLER_ARGS) 222cfc9c386SHans Petter Selasky { 223cfc9c386SHans Petter Selasky struct mlx5e_priv *priv = arg1; 224cfc9c386SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 225cfc9c386SHans Petter Selasky u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS]; 226cfc9c386SHans Petter Selasky u8 max_bw_value[IEEE_8021QAZ_MAX_TCS]; 227e870c0abSSlava Shwartsman u64 new_bw_value[IEEE_8021QAZ_MAX_TCS]; 228e870c0abSSlava Shwartsman u8 max_rates = mlx5_max_tc(mdev) + 1; 229e870c0abSSlava Shwartsman u8 x; 230e870c0abSSlava Shwartsman int err; 231cfc9c386SHans Petter Selasky 232cfc9c386SHans Petter Selasky PRIV_LOCK(priv); 233e870c0abSSlava Shwartsman err = SYSCTL_OUT(req, priv->params_ethtool.max_bw_value, 234e870c0abSSlava Shwartsman sizeof(priv->params_ethtool.max_bw_value[0]) * max_rates); 235e870c0abSSlava Shwartsman if (err || !req->newptr) 236e870c0abSSlava Shwartsman goto done; 237e870c0abSSlava Shwartsman err = SYSCTL_IN(req, new_bw_value, 238e870c0abSSlava Shwartsman sizeof(new_bw_value[0]) * max_rates); 239e870c0abSSlava Shwartsman if (err) 240cfc9c386SHans Petter Selasky goto done; 241cfc9c386SHans Petter Selasky 242e870c0abSSlava Shwartsman /* range check input value */ 243e870c0abSSlava Shwartsman for (x = 0; x != max_rates; x++) { 244e870c0abSSlava Shwartsman if (new_bw_value[x] % MLX5E_100MB) { 245cfc9c386SHans Petter Selasky err = ERANGE; 246cfc9c386SHans Petter Selasky goto done; 247cfc9c386SHans Petter Selasky } 248cfc9c386SHans Petter Selasky } 249e870c0abSSlava Shwartsman 250e870c0abSSlava Shwartsman mlx5e_tc_get_parameters(priv, new_bw_value, max_bw_value, max_bw_unit); 251cfc9c386SHans Petter Selasky 252cfc9c386SHans Petter Selasky err = -mlx5_modify_port_tc_rate_limit(mdev, max_bw_value, max_bw_unit); 253cfc9c386SHans Petter Selasky if (err) 254cfc9c386SHans Petter Selasky goto done; 255cfc9c386SHans Petter Selasky 256e870c0abSSlava Shwartsman memcpy(priv->params_ethtool.max_bw_value, new_bw_value, 257e870c0abSSlava Shwartsman sizeof(priv->params_ethtool.max_bw_value)); 258e870c0abSSlava Shwartsman done: 259e870c0abSSlava Shwartsman PRIV_UNLOCK(priv); 260e870c0abSSlava Shwartsman return (err); 261e870c0abSSlava Shwartsman } 262e870c0abSSlava Shwartsman 263e870c0abSSlava Shwartsman static int 264e870c0abSSlava Shwartsman mlx5e_tc_rate_share_handler(SYSCTL_HANDLER_ARGS) 265e870c0abSSlava Shwartsman { 266e870c0abSSlava Shwartsman struct mlx5e_priv *priv = arg1; 267e870c0abSSlava Shwartsman struct mlx5_core_dev *mdev = priv->mdev; 268e870c0abSSlava Shwartsman u8 max_bw_share[IEEE_8021QAZ_MAX_TCS]; 269e870c0abSSlava Shwartsman u8 max_rates = mlx5_max_tc(mdev) + 1; 270e870c0abSSlava Shwartsman int i; 271e870c0abSSlava Shwartsman int err; 272e870c0abSSlava Shwartsman int sum; 273e870c0abSSlava Shwartsman 274e870c0abSSlava Shwartsman PRIV_LOCK(priv); 275e870c0abSSlava Shwartsman err = SYSCTL_OUT(req, priv->params_ethtool.max_bw_share, max_rates); 276e870c0abSSlava Shwartsman if (err || !req->newptr) 277e870c0abSSlava Shwartsman goto done; 278e870c0abSSlava Shwartsman err = SYSCTL_IN(req, max_bw_share, max_rates); 279e870c0abSSlava Shwartsman if (err) 280e870c0abSSlava Shwartsman goto done; 281e870c0abSSlava Shwartsman 282e870c0abSSlava Shwartsman /* range check input value */ 283e870c0abSSlava Shwartsman for (sum = i = 0; i != max_rates; i++) { 284e870c0abSSlava Shwartsman if (max_bw_share[i] < 1 || max_bw_share[i] > 100) { 285e870c0abSSlava Shwartsman err = ERANGE; 286e870c0abSSlava Shwartsman goto done; 287e870c0abSSlava Shwartsman } 288e870c0abSSlava Shwartsman sum += max_bw_share[i]; 289e870c0abSSlava Shwartsman } 290e870c0abSSlava Shwartsman 291e870c0abSSlava Shwartsman /* sum of values should be as close to 100 as possible */ 292e870c0abSSlava Shwartsman if (sum < (100 - max_rates + 1) || sum > 100) { 293e870c0abSSlava Shwartsman err = ERANGE; 294e870c0abSSlava Shwartsman goto done; 295e870c0abSSlava Shwartsman } 296e870c0abSSlava Shwartsman 297e870c0abSSlava Shwartsman err = -mlx5_set_port_tc_bw_alloc(mdev, max_bw_share); 298e870c0abSSlava Shwartsman if (err) 299e870c0abSSlava Shwartsman goto done; 300e870c0abSSlava Shwartsman 301e870c0abSSlava Shwartsman memcpy(priv->params_ethtool.max_bw_share, max_bw_share, 302e870c0abSSlava Shwartsman sizeof(priv->params_ethtool.max_bw_share)); 303cfc9c386SHans Petter Selasky done: 304cfc9c386SHans Petter Selasky PRIV_UNLOCK(priv); 305cfc9c386SHans Petter Selasky return (err); 306cfc9c386SHans Petter Selasky } 307cfc9c386SHans Petter Selasky 3082e9c3a4fSHans Petter Selasky static int 3092e9c3a4fSHans Petter Selasky mlx5e_get_prio_tc(struct mlx5e_priv *priv) 3102e9c3a4fSHans Petter Selasky { 3112e9c3a4fSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 3122e9c3a4fSHans Petter Selasky int err = 0; 3132e9c3a4fSHans Petter Selasky int i; 3142e9c3a4fSHans Petter Selasky 3152e9c3a4fSHans Petter Selasky PRIV_LOCK(priv); 3162e9c3a4fSHans Petter Selasky if (!MLX5_CAP_GEN(priv->mdev, ets)) { 3172e9c3a4fSHans Petter Selasky PRIV_UNLOCK(priv); 3182e9c3a4fSHans Petter Selasky return (EOPNOTSUPP); 3192e9c3a4fSHans Petter Selasky } 3202e9c3a4fSHans Petter Selasky 32124385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) { 32224385321SHans Petter Selasky err = -mlx5_query_port_prio_tc(mdev, i, priv->params_ethtool.prio_tc + i); 3232e9c3a4fSHans Petter Selasky if (err) 3242e9c3a4fSHans Petter Selasky break; 3252e9c3a4fSHans Petter Selasky } 3262e9c3a4fSHans Petter Selasky PRIV_UNLOCK(priv); 3272e9c3a4fSHans Petter Selasky return (err); 3282e9c3a4fSHans Petter Selasky } 3292e9c3a4fSHans Petter Selasky 3302e9c3a4fSHans Petter Selasky static int 3312e9c3a4fSHans Petter Selasky mlx5e_prio_to_tc_handler(SYSCTL_HANDLER_ARGS) 3322e9c3a4fSHans Petter Selasky { 3332e9c3a4fSHans Petter Selasky struct mlx5e_priv *priv = arg1; 3342e9c3a4fSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 33524385321SHans Petter Selasky uint8_t temp[MLX5E_MAX_PRIORITY]; 3362e9c3a4fSHans Petter Selasky int err; 33724385321SHans Petter Selasky int i; 3382e9c3a4fSHans Petter Selasky 3392e9c3a4fSHans Petter Selasky PRIV_LOCK(priv); 34024385321SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.prio_tc, MLX5E_MAX_PRIORITY); 34124385321SHans Petter Selasky if (err || !req->newptr) 3422e9c3a4fSHans Petter Selasky goto done; 34324385321SHans Petter Selasky err = SYSCTL_IN(req, temp, MLX5E_MAX_PRIORITY); 3442e9c3a4fSHans Petter Selasky if (err) 3452e9c3a4fSHans Petter Selasky goto done; 3462e9c3a4fSHans Petter Selasky 34724385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) { 34824385321SHans Petter Selasky if (temp[i] > mlx5_max_tc(mdev)) { 34924385321SHans Petter Selasky err = ERANGE; 35024385321SHans Petter Selasky goto done; 35124385321SHans Petter Selasky } 35224385321SHans Petter Selasky } 3532e9c3a4fSHans Petter Selasky 35424385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) { 35524385321SHans Petter Selasky if (temp[i] == priv->params_ethtool.prio_tc[i]) 35624385321SHans Petter Selasky continue; 35724385321SHans Petter Selasky err = -mlx5_set_port_prio_tc(mdev, i, temp[i]); 35824385321SHans Petter Selasky if (err) 35924385321SHans Petter Selasky goto done; 36024385321SHans Petter Selasky /* update cached value */ 36124385321SHans Petter Selasky priv->params_ethtool.prio_tc[i] = temp[i]; 36224385321SHans Petter Selasky } 3632e9c3a4fSHans Petter Selasky done: 3642e9c3a4fSHans Petter Selasky PRIV_UNLOCK(priv); 3652e9c3a4fSHans Petter Selasky return (err); 3662e9c3a4fSHans Petter Selasky } 3672e9c3a4fSHans Petter Selasky 36896425f44SHans Petter Selasky int 36996425f44SHans Petter Selasky mlx5e_fec_update(struct mlx5e_priv *priv) 37096425f44SHans Petter Selasky { 37196425f44SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 37296425f44SHans Petter Selasky u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; 37396425f44SHans Petter Selasky const int sz = MLX5_ST_SZ_BYTES(pplm_reg); 37496425f44SHans Petter Selasky int err; 37596425f44SHans Petter Selasky 37696425f44SHans Petter Selasky if (!MLX5_CAP_GEN(mdev, pcam_reg)) 37796425f44SHans Petter Selasky return (EOPNOTSUPP); 37896425f44SHans Petter Selasky 37996425f44SHans Petter Selasky if (!MLX5_CAP_PCAM_REG(mdev, pplm)) 38096425f44SHans Petter Selasky return (EOPNOTSUPP); 38196425f44SHans Petter Selasky 38296425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 38396425f44SHans Petter Selasky 38496425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, in, sz, MLX5_REG_PPLM, 0, 0); 38596425f44SHans Petter Selasky if (err) 38696425f44SHans Petter Selasky return (err); 38796425f44SHans Petter Selasky 38896425f44SHans Petter Selasky /* get 10x..25x mask */ 38996425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[0] = 39096425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_10g_40g); 39196425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[1] = 39296425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_25g) & 39396425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_50g); 39496425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[2] = 39596425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_56g); 39696425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[3] = 39796425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_100g); 39896425f44SHans Petter Selasky 39996425f44SHans Petter Selasky /* get 10x..25x available bits */ 40096425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[0] = 40196425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_10g_40g); 40296425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[1] = 40396425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_25g) & 40496425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_50g); 40596425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[2] = 40696425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_56g); 40796425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[3] = 40896425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_100g); 40996425f44SHans Petter Selasky 41096425f44SHans Petter Selasky /* get 50x mask */ 41196425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[0] = 41296425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_50g_1x); 41396425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[1] = 41496425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_100g_2x); 41596425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[2] = 41696425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_200g_4x); 41796425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[3] = 41896425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_400g_8x); 41996425f44SHans Petter Selasky 42096425f44SHans Petter Selasky /* get 50x available bits */ 42196425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[0] = 42296425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_50g_1x); 42396425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[1] = 42496425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_100g_2x); 42596425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[2] = 42696425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_200g_4x); 42796425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[3] = 42896425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_400g_8x); 42996425f44SHans Petter Selasky 43096425f44SHans Petter Selasky /* get current FEC mask */ 43196425f44SHans Petter Selasky priv->params_ethtool.fec_mode_active = 43296425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_mode_active); 43396425f44SHans Petter Selasky 43496425f44SHans Petter Selasky return (0); 43596425f44SHans Petter Selasky } 43696425f44SHans Petter Selasky 43796425f44SHans Petter Selasky static int 43896425f44SHans Petter Selasky mlx5e_fec_mask_10x_25x_handler(SYSCTL_HANDLER_ARGS) 43996425f44SHans Petter Selasky { 44096425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1; 44196425f44SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 44296425f44SHans Petter Selasky u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {}; 44396425f44SHans Petter Selasky u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; 44496425f44SHans Petter Selasky const int sz = MLX5_ST_SZ_BYTES(pplm_reg); 44596425f44SHans Petter Selasky u8 fec_mask_10x_25x[MLX5E_MAX_FEC_10X_25X]; 44696425f44SHans Petter Selasky u8 fec_cap_changed = 0; 44796425f44SHans Petter Selasky u8 x; 44896425f44SHans Petter Selasky int err; 44996425f44SHans Petter Selasky 45096425f44SHans Petter Selasky PRIV_LOCK(priv); 45196425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_mask_10x_25x, 45296425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_10x_25x)); 45396425f44SHans Petter Selasky if (err || !req->newptr) 45496425f44SHans Petter Selasky goto done; 45596425f44SHans Petter Selasky 45696425f44SHans Petter Selasky err = SYSCTL_IN(req, fec_mask_10x_25x, 45796425f44SHans Petter Selasky sizeof(fec_mask_10x_25x)); 45896425f44SHans Petter Selasky if (err) 45996425f44SHans Petter Selasky goto done; 46096425f44SHans Petter Selasky 46196425f44SHans Petter Selasky if (!MLX5_CAP_GEN(mdev, pcam_reg)) { 46296425f44SHans Petter Selasky err = EOPNOTSUPP; 46396425f44SHans Petter Selasky goto done; 46496425f44SHans Petter Selasky } 46596425f44SHans Petter Selasky 46696425f44SHans Petter Selasky if (!MLX5_CAP_PCAM_REG(mdev, pplm)) { 46796425f44SHans Petter Selasky err = EOPNOTSUPP; 46896425f44SHans Petter Selasky goto done; 46996425f44SHans Petter Selasky } 47096425f44SHans Petter Selasky 47196425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 47296425f44SHans Petter Selasky 47396425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, in, sz, MLX5_REG_PPLM, 0, 0); 47496425f44SHans Petter Selasky if (err) 47596425f44SHans Petter Selasky goto done; 47696425f44SHans Petter Selasky 47796425f44SHans Petter Selasky /* range check input value */ 47896425f44SHans Petter Selasky for (x = 0; x != MLX5E_MAX_FEC_10X_25X; x++) { 47996425f44SHans Petter Selasky /* check only one bit is set, if any */ 48096425f44SHans Petter Selasky if (fec_mask_10x_25x[x] & (fec_mask_10x_25x[x] - 1)) { 48196425f44SHans Petter Selasky err = ERANGE; 48296425f44SHans Petter Selasky goto done; 48396425f44SHans Petter Selasky } 48496425f44SHans Petter Selasky /* check a supported bit is set, if any */ 48596425f44SHans Petter Selasky if (fec_mask_10x_25x[x] & 48696425f44SHans Petter Selasky ~priv->params_ethtool.fec_avail_10x_25x[x]) { 48796425f44SHans Petter Selasky err = ERANGE; 48896425f44SHans Petter Selasky goto done; 48996425f44SHans Petter Selasky } 49096425f44SHans Petter Selasky fec_cap_changed |= (fec_mask_10x_25x[x] ^ 49196425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[x]); 49296425f44SHans Petter Selasky } 49396425f44SHans Petter Selasky 49496425f44SHans Petter Selasky /* check for no changes */ 49596425f44SHans Petter Selasky if (fec_cap_changed == 0) 49696425f44SHans Petter Selasky goto done; 49796425f44SHans Petter Selasky 49896425f44SHans Petter Selasky memset(in, 0, sizeof(in)); 49996425f44SHans Petter Selasky 50096425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 50196425f44SHans Petter Selasky 50296425f44SHans Petter Selasky /* set new values */ 50396425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_10g_40g, fec_mask_10x_25x[0]); 50496425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_25g, fec_mask_10x_25x[1]); 50596425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g, fec_mask_10x_25x[1]); 50696425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_56g, fec_mask_10x_25x[2]); 50796425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g, fec_mask_10x_25x[3]); 50896425f44SHans Petter Selasky 50996425f44SHans Petter Selasky /* preserve other values */ 51096425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g_1x, priv->params_ethtool.fec_mask_50x[0]); 51196425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g_2x, priv->params_ethtool.fec_mask_50x[1]); 51296425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_200g_4x, priv->params_ethtool.fec_mask_50x[2]); 51396425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_400g_8x, priv->params_ethtool.fec_mask_50x[3]); 51496425f44SHans Petter Selasky 51596425f44SHans Petter Selasky /* send new value to the firmware */ 51696425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPLM, 0, 1); 51796425f44SHans Petter Selasky if (err) 51896425f44SHans Petter Selasky goto done; 51996425f44SHans Petter Selasky 52096425f44SHans Petter Selasky memcpy(priv->params_ethtool.fec_mask_10x_25x, fec_mask_10x_25x, 52196425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_10x_25x)); 52296425f44SHans Petter Selasky 52396425f44SHans Petter Selasky mlx5_toggle_port_link(priv->mdev); 52496425f44SHans Petter Selasky done: 52596425f44SHans Petter Selasky PRIV_UNLOCK(priv); 52696425f44SHans Petter Selasky return (err); 52796425f44SHans Petter Selasky } 52896425f44SHans Petter Selasky 52996425f44SHans Petter Selasky static int 53096425f44SHans Petter Selasky mlx5e_fec_avail_10x_25x_handler(SYSCTL_HANDLER_ARGS) 53196425f44SHans Petter Selasky { 53296425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1; 53396425f44SHans Petter Selasky int err; 53496425f44SHans Petter Selasky 53596425f44SHans Petter Selasky PRIV_LOCK(priv); 53696425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_avail_10x_25x, 53796425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_avail_10x_25x)); 53896425f44SHans Petter Selasky PRIV_UNLOCK(priv); 53996425f44SHans Petter Selasky return (err); 54096425f44SHans Petter Selasky } 54196425f44SHans Petter Selasky 54296425f44SHans Petter Selasky static int 54396425f44SHans Petter Selasky mlx5e_fec_mask_50x_handler(SYSCTL_HANDLER_ARGS) 54496425f44SHans Petter Selasky { 54596425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1; 54696425f44SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 54796425f44SHans Petter Selasky u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {}; 54896425f44SHans Petter Selasky u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; 54996425f44SHans Petter Selasky const int sz = MLX5_ST_SZ_BYTES(pplm_reg); 55096425f44SHans Petter Selasky u16 fec_mask_50x[MLX5E_MAX_FEC_50X]; 55196425f44SHans Petter Selasky u16 fec_cap_changed = 0; 55296425f44SHans Petter Selasky u8 x; 55396425f44SHans Petter Selasky int err; 55496425f44SHans Petter Selasky 55596425f44SHans Petter Selasky PRIV_LOCK(priv); 55696425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_mask_50x, 55796425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_50x)); 55896425f44SHans Petter Selasky if (err || !req->newptr) 55996425f44SHans Petter Selasky goto done; 56096425f44SHans Petter Selasky 56196425f44SHans Petter Selasky err = SYSCTL_IN(req, fec_mask_50x, 56296425f44SHans Petter Selasky sizeof(fec_mask_50x)); 56396425f44SHans Petter Selasky if (err) 56496425f44SHans Petter Selasky goto done; 56596425f44SHans Petter Selasky 56696425f44SHans Petter Selasky if (!MLX5_CAP_GEN(mdev, pcam_reg)) { 56796425f44SHans Petter Selasky err = EOPNOTSUPP; 56896425f44SHans Petter Selasky goto done; 56996425f44SHans Petter Selasky } 57096425f44SHans Petter Selasky 57196425f44SHans Petter Selasky if (!MLX5_CAP_PCAM_REG(mdev, pplm)) { 57296425f44SHans Petter Selasky err = EOPNOTSUPP; 57396425f44SHans Petter Selasky goto done; 57496425f44SHans Petter Selasky } 57596425f44SHans Petter Selasky 57696425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 57796425f44SHans Petter Selasky 57896425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, in, sz, MLX5_REG_PPLM, 0, 0); 57996425f44SHans Petter Selasky if (err) 58096425f44SHans Petter Selasky goto done; 58196425f44SHans Petter Selasky 58296425f44SHans Petter Selasky /* range check input value */ 58396425f44SHans Petter Selasky for (x = 0; x != MLX5E_MAX_FEC_50X; x++) { 58496425f44SHans Petter Selasky /* check only one bit is set, if any */ 58596425f44SHans Petter Selasky if (fec_mask_50x[x] & (fec_mask_50x[x] - 1)) { 58696425f44SHans Petter Selasky err = ERANGE; 58796425f44SHans Petter Selasky goto done; 58896425f44SHans Petter Selasky } 58996425f44SHans Petter Selasky /* check a supported bit is set, if any */ 59096425f44SHans Petter Selasky if (fec_mask_50x[x] & 59196425f44SHans Petter Selasky ~priv->params_ethtool.fec_avail_50x[x]) { 59296425f44SHans Petter Selasky err = ERANGE; 59396425f44SHans Petter Selasky goto done; 59496425f44SHans Petter Selasky } 59596425f44SHans Petter Selasky fec_cap_changed |= (fec_mask_50x[x] ^ 59696425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[x]); 59796425f44SHans Petter Selasky } 59896425f44SHans Petter Selasky 59996425f44SHans Petter Selasky /* check for no changes */ 60096425f44SHans Petter Selasky if (fec_cap_changed == 0) 60196425f44SHans Petter Selasky goto done; 60296425f44SHans Petter Selasky 60396425f44SHans Petter Selasky memset(in, 0, sizeof(in)); 60496425f44SHans Petter Selasky 60596425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 60696425f44SHans Petter Selasky 60796425f44SHans Petter Selasky /* set new values */ 60896425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g_1x, fec_mask_50x[0]); 60996425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g_2x, fec_mask_50x[1]); 61096425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_200g_4x, fec_mask_50x[2]); 61196425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_400g_8x, fec_mask_50x[3]); 61296425f44SHans Petter Selasky 61396425f44SHans Petter Selasky /* preserve other values */ 61496425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_10g_40g, priv->params_ethtool.fec_mask_10x_25x[0]); 61596425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_25g, priv->params_ethtool.fec_mask_10x_25x[1]); 61696425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g, priv->params_ethtool.fec_mask_10x_25x[1]); 61796425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_56g, priv->params_ethtool.fec_mask_10x_25x[2]); 61896425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g, priv->params_ethtool.fec_mask_10x_25x[3]); 61996425f44SHans Petter Selasky 62096425f44SHans Petter Selasky /* send new value to the firmware */ 62196425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPLM, 0, 1); 62296425f44SHans Petter Selasky if (err) 62396425f44SHans Petter Selasky goto done; 62496425f44SHans Petter Selasky 62596425f44SHans Petter Selasky memcpy(priv->params_ethtool.fec_mask_50x, fec_mask_50x, 62696425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_50x)); 62796425f44SHans Petter Selasky 62896425f44SHans Petter Selasky mlx5_toggle_port_link(priv->mdev); 62996425f44SHans Petter Selasky done: 63096425f44SHans Petter Selasky PRIV_UNLOCK(priv); 63196425f44SHans Petter Selasky return (err); 63296425f44SHans Petter Selasky } 63396425f44SHans Petter Selasky 63496425f44SHans Petter Selasky static int 63596425f44SHans Petter Selasky mlx5e_fec_avail_50x_handler(SYSCTL_HANDLER_ARGS) 63696425f44SHans Petter Selasky { 63796425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1; 63896425f44SHans Petter Selasky int err; 63996425f44SHans Petter Selasky 64096425f44SHans Petter Selasky PRIV_LOCK(priv); 64196425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_avail_50x, 64296425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_avail_50x)); 64396425f44SHans Petter Selasky PRIV_UNLOCK(priv); 64496425f44SHans Petter Selasky return (err); 64596425f44SHans Petter Selasky } 64696425f44SHans Petter Selasky 647ed0cee0bSHans Petter Selasky static int 648ed0cee0bSHans Petter Selasky mlx5e_trust_state_handler(SYSCTL_HANDLER_ARGS) 649ed0cee0bSHans Petter Selasky { 650ed0cee0bSHans Petter Selasky struct mlx5e_priv *priv = arg1; 651ed0cee0bSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 652ed0cee0bSHans Petter Selasky int err; 653ed0cee0bSHans Petter Selasky u8 result; 654ed0cee0bSHans Petter Selasky 655ed0cee0bSHans Petter Selasky PRIV_LOCK(priv); 656ed0cee0bSHans Petter Selasky result = priv->params_ethtool.trust_state; 657ed0cee0bSHans Petter Selasky err = sysctl_handle_8(oidp, &result, 0, req); 658ed0cee0bSHans Petter Selasky if (err || !req->newptr || 659ed0cee0bSHans Petter Selasky result == priv->params_ethtool.trust_state) 660ed0cee0bSHans Petter Selasky goto done; 661ed0cee0bSHans Petter Selasky 662ed0cee0bSHans Petter Selasky switch (result) { 663ed0cee0bSHans Petter Selasky case MLX5_QPTS_TRUST_PCP: 664ed0cee0bSHans Petter Selasky case MLX5_QPTS_TRUST_DSCP: 665ed0cee0bSHans Petter Selasky break; 666ed0cee0bSHans Petter Selasky case MLX5_QPTS_TRUST_BOTH: 667ed0cee0bSHans Petter Selasky if (!MLX5_CAP_QCAM_FEATURE(mdev, qpts_trust_both)) { 668ed0cee0bSHans Petter Selasky err = EOPNOTSUPP; 669ed0cee0bSHans Petter Selasky goto done; 670ed0cee0bSHans Petter Selasky } 671ed0cee0bSHans Petter Selasky break; 672ed0cee0bSHans Petter Selasky default: 673ed0cee0bSHans Petter Selasky err = ERANGE; 674ed0cee0bSHans Petter Selasky goto done; 675ed0cee0bSHans Petter Selasky } 676ed0cee0bSHans Petter Selasky 677ed0cee0bSHans Petter Selasky err = -mlx5_set_trust_state(mdev, result); 678ed0cee0bSHans Petter Selasky if (err) 679ed0cee0bSHans Petter Selasky goto done; 680ed0cee0bSHans Petter Selasky 681ed0cee0bSHans Petter Selasky priv->params_ethtool.trust_state = result; 6823e581cabSSlava Shwartsman 6833e581cabSSlava Shwartsman /* update inline mode */ 6843e581cabSSlava Shwartsman mlx5e_refresh_sq_inline(priv); 6853e581cabSSlava Shwartsman #ifdef RATELIMIT 6863e581cabSSlava Shwartsman mlx5e_rl_refresh_sq_inline(&priv->rl); 6873e581cabSSlava Shwartsman #endif 688ed0cee0bSHans Petter Selasky done: 689ed0cee0bSHans Petter Selasky PRIV_UNLOCK(priv); 690ed0cee0bSHans Petter Selasky return (err); 691ed0cee0bSHans Petter Selasky } 692ed0cee0bSHans Petter Selasky 693ed0cee0bSHans Petter Selasky static int 694ed0cee0bSHans Petter Selasky mlx5e_dscp_prio_handler(SYSCTL_HANDLER_ARGS) 695ed0cee0bSHans Petter Selasky { 696ed0cee0bSHans Petter Selasky struct mlx5e_priv *priv = arg1; 697ed0cee0bSHans Petter Selasky int prio_index = arg2; 698ed0cee0bSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 699ed0cee0bSHans Petter Selasky uint8_t dscp2prio[MLX5_MAX_SUPPORTED_DSCP]; 700ed0cee0bSHans Petter Selasky uint8_t x; 701ed0cee0bSHans Petter Selasky int err; 702ed0cee0bSHans Petter Selasky 703ed0cee0bSHans Petter Selasky PRIV_LOCK(priv); 704ed0cee0bSHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.dscp2prio + prio_index, 705ed0cee0bSHans Petter Selasky sizeof(priv->params_ethtool.dscp2prio) / 8); 706ed0cee0bSHans Petter Selasky if (err || !req->newptr) 707ed0cee0bSHans Petter Selasky goto done; 708ed0cee0bSHans Petter Selasky 709ed0cee0bSHans Petter Selasky memcpy(dscp2prio, priv->params_ethtool.dscp2prio, sizeof(dscp2prio)); 710ed0cee0bSHans Petter Selasky err = SYSCTL_IN(req, dscp2prio + prio_index, sizeof(dscp2prio) / 8); 711ed0cee0bSHans Petter Selasky if (err) 712ed0cee0bSHans Petter Selasky goto done; 713ed0cee0bSHans Petter Selasky for (x = 0; x != MLX5_MAX_SUPPORTED_DSCP; x++) { 714ed0cee0bSHans Petter Selasky if (dscp2prio[x] > 7) { 715ed0cee0bSHans Petter Selasky err = ERANGE; 716ed0cee0bSHans Petter Selasky goto done; 717ed0cee0bSHans Petter Selasky } 718ed0cee0bSHans Petter Selasky } 719ed0cee0bSHans Petter Selasky err = -mlx5_set_dscp2prio(mdev, dscp2prio); 720ed0cee0bSHans Petter Selasky if (err) 721ed0cee0bSHans Petter Selasky goto done; 722ed0cee0bSHans Petter Selasky 723ed0cee0bSHans Petter Selasky /* update local array */ 724ed0cee0bSHans Petter Selasky memcpy(priv->params_ethtool.dscp2prio, dscp2prio, 725ed0cee0bSHans Petter Selasky sizeof(priv->params_ethtool.dscp2prio)); 726ed0cee0bSHans Petter Selasky done: 727ed0cee0bSHans Petter Selasky PRIV_UNLOCK(priv); 728ed0cee0bSHans Petter Selasky return (err); 729ed0cee0bSHans Petter Selasky } 730ed0cee0bSHans Petter Selasky 7316deb0b1eSHans Petter Selasky int 7326deb0b1eSHans Petter Selasky mlx5e_update_buf_lossy(struct mlx5e_priv *priv) 7336deb0b1eSHans Petter Selasky { 7346deb0b1eSHans Petter Selasky struct ieee_pfc pfc; 7356deb0b1eSHans Petter Selasky 7366deb0b1eSHans Petter Selasky PRIV_ASSERT_LOCKED(priv); 7376deb0b1eSHans Petter Selasky bzero(&pfc, sizeof(pfc)); 7386deb0b1eSHans Petter Selasky pfc.pfc_en = priv->params.rx_priority_flow_control; 7396deb0b1eSHans Petter Selasky return (-mlx5e_port_manual_buffer_config(priv, MLX5E_PORT_BUFFER_PFC, 7406deb0b1eSHans Petter Selasky priv->params_ethtool.hw_mtu, &pfc, NULL, NULL)); 7416deb0b1eSHans Petter Selasky } 7426deb0b1eSHans Petter Selasky 7436deb0b1eSHans Petter Selasky static int 7446deb0b1eSHans Petter Selasky mlx5e_buf_size_handler(SYSCTL_HANDLER_ARGS) 7456deb0b1eSHans Petter Selasky { 7466deb0b1eSHans Petter Selasky struct mlx5e_priv *priv; 7476deb0b1eSHans Petter Selasky u32 buf_size[MLX5E_MAX_BUFFER]; 7486deb0b1eSHans Petter Selasky struct mlx5e_port_buffer port_buffer; 7496deb0b1eSHans Petter Selasky int error, i; 7506deb0b1eSHans Petter Selasky 7516deb0b1eSHans Petter Selasky priv = arg1; 7526deb0b1eSHans Petter Selasky PRIV_LOCK(priv); 7536deb0b1eSHans Petter Selasky error = -mlx5e_port_query_buffer(priv, &port_buffer); 7546deb0b1eSHans Petter Selasky if (error != 0) 7556deb0b1eSHans Petter Selasky goto done; 7566deb0b1eSHans Petter Selasky for (i = 0; i < nitems(buf_size); i++) 7576deb0b1eSHans Petter Selasky buf_size[i] = port_buffer.buffer[i].size; 7586deb0b1eSHans Petter Selasky error = SYSCTL_OUT(req, buf_size, sizeof(buf_size)); 7596deb0b1eSHans Petter Selasky if (error != 0 || req->newptr == NULL) 7606deb0b1eSHans Petter Selasky goto done; 7616deb0b1eSHans Petter Selasky error = SYSCTL_IN(req, buf_size, sizeof(buf_size)); 7626deb0b1eSHans Petter Selasky if (error != 0) 7636deb0b1eSHans Petter Selasky goto done; 7646deb0b1eSHans Petter Selasky error = -mlx5e_port_manual_buffer_config(priv, MLX5E_PORT_BUFFER_SIZE, 7656deb0b1eSHans Petter Selasky priv->params_ethtool.hw_mtu, NULL, buf_size, NULL); 7666deb0b1eSHans Petter Selasky done: 7676deb0b1eSHans Petter Selasky PRIV_UNLOCK(priv); 7686deb0b1eSHans Petter Selasky return (error); 7696deb0b1eSHans Petter Selasky } 7706deb0b1eSHans Petter Selasky 7716deb0b1eSHans Petter Selasky static int 7726deb0b1eSHans Petter Selasky mlx5e_buf_prio_handler(SYSCTL_HANDLER_ARGS) 7736deb0b1eSHans Petter Selasky { 7746deb0b1eSHans Petter Selasky struct mlx5e_priv *priv; 7756deb0b1eSHans Petter Selasky struct mlx5_core_dev *mdev; 7766deb0b1eSHans Petter Selasky u8 buffer[MLX5E_MAX_BUFFER]; 7776deb0b1eSHans Petter Selasky int error; 7786deb0b1eSHans Petter Selasky 7796deb0b1eSHans Petter Selasky priv = arg1; 7806deb0b1eSHans Petter Selasky mdev = priv->mdev; 7816deb0b1eSHans Petter Selasky PRIV_LOCK(priv); 7826deb0b1eSHans Petter Selasky error = -mlx5e_port_query_priority2buffer(mdev, buffer); 7836deb0b1eSHans Petter Selasky if (error != 0) 7846deb0b1eSHans Petter Selasky goto done; 7856deb0b1eSHans Petter Selasky error = SYSCTL_OUT(req, buffer, MLX5E_MAX_BUFFER); 7866deb0b1eSHans Petter Selasky if (error != 0 || req->newptr == NULL) 7876deb0b1eSHans Petter Selasky goto done; 7886deb0b1eSHans Petter Selasky error = SYSCTL_IN(req, buffer, MLX5E_MAX_BUFFER); 7896deb0b1eSHans Petter Selasky if (error != 0) 7906deb0b1eSHans Petter Selasky goto done; 7916deb0b1eSHans Petter Selasky error = -mlx5e_port_manual_buffer_config(priv, 7926deb0b1eSHans Petter Selasky MLX5E_PORT_BUFFER_PRIO2BUFFER, 7936deb0b1eSHans Petter Selasky priv->params_ethtool.hw_mtu, NULL, NULL, buffer); 7946deb0b1eSHans Petter Selasky if (error == 0) 7956deb0b1eSHans Petter Selasky error = mlx5e_update_buf_lossy(priv); 7966deb0b1eSHans Petter Selasky done: 7976deb0b1eSHans Petter Selasky PRIV_UNLOCK(priv); 7986deb0b1eSHans Petter Selasky return (error); 7996deb0b1eSHans Petter Selasky } 8006deb0b1eSHans Petter Selasky 8016deb0b1eSHans Petter Selasky static int 8026deb0b1eSHans Petter Selasky mlx5e_cable_length_handler(SYSCTL_HANDLER_ARGS) 8036deb0b1eSHans Petter Selasky { 8046deb0b1eSHans Petter Selasky struct mlx5e_priv *priv; 8056deb0b1eSHans Petter Selasky u_int cable_len; 8066deb0b1eSHans Petter Selasky int error; 8076deb0b1eSHans Petter Selasky 8086deb0b1eSHans Petter Selasky priv = arg1; 8096deb0b1eSHans Petter Selasky PRIV_LOCK(priv); 8106deb0b1eSHans Petter Selasky cable_len = priv->dcbx.cable_len; 8116deb0b1eSHans Petter Selasky error = sysctl_handle_int(oidp, &cable_len, 0, req); 8126deb0b1eSHans Petter Selasky if (error == 0 && req->newptr != NULL && 8136deb0b1eSHans Petter Selasky cable_len != priv->dcbx.cable_len) { 8146deb0b1eSHans Petter Selasky error = -mlx5e_port_manual_buffer_config(priv, 8156deb0b1eSHans Petter Selasky MLX5E_PORT_BUFFER_CABLE_LEN, priv->params_ethtool.hw_mtu, 8166deb0b1eSHans Petter Selasky NULL, NULL, NULL); 8176deb0b1eSHans Petter Selasky if (error == 0) 8186deb0b1eSHans Petter Selasky priv->dcbx.cable_len = cable_len; 8196deb0b1eSHans Petter Selasky } 8206deb0b1eSHans Petter Selasky PRIV_UNLOCK(priv); 8216deb0b1eSHans Petter Selasky return (error); 8226deb0b1eSHans Petter Selasky } 8236deb0b1eSHans Petter Selasky 82482d2623eSHans Petter Selasky #define MLX5_PARAM_OFFSET(n) \ 82582d2623eSHans Petter Selasky __offsetof(struct mlx5e_priv, params_ethtool.n) 82682d2623eSHans Petter Selasky 827dc7e38acSHans Petter Selasky static int 828dc7e38acSHans Petter Selasky mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS) 829dc7e38acSHans Petter Selasky { 830dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1; 831dc7e38acSHans Petter Selasky uint64_t value; 832d2bf00a9SHans Petter Selasky int mode_modify; 833dc7e38acSHans Petter Selasky int was_opened; 834dc7e38acSHans Petter Selasky int error; 835dc7e38acSHans Petter Selasky 836dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 837dc7e38acSHans Petter Selasky value = priv->params_ethtool.arg[arg2]; 838ec0143b2SHans Petter Selasky if (req != NULL) { 839dc7e38acSHans Petter Selasky error = sysctl_handle_64(oidp, &value, 0, req); 840dc7e38acSHans Petter Selasky if (error || req->newptr == NULL || 841dc7e38acSHans Petter Selasky value == priv->params_ethtool.arg[arg2]) 842dc7e38acSHans Petter Selasky goto done; 843dc7e38acSHans Petter Selasky 844dc7e38acSHans Petter Selasky /* assign new value */ 845dc7e38acSHans Petter Selasky priv->params_ethtool.arg[arg2] = value; 846ec0143b2SHans Petter Selasky } else { 847ec0143b2SHans Petter Selasky error = 0; 848ec0143b2SHans Petter Selasky } 849dc7e38acSHans Petter Selasky /* check if device is gone */ 850dc7e38acSHans Petter Selasky if (priv->gone) { 851dc7e38acSHans Petter Selasky error = ENXIO; 852dc7e38acSHans Petter Selasky goto done; 853dc7e38acSHans Petter Selasky } 85482d2623eSHans Petter Selasky was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); 855d2bf00a9SHans Petter Selasky mode_modify = MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify); 85682d2623eSHans Petter Selasky 85782d2623eSHans Petter Selasky switch (MLX5_PARAM_OFFSET(arg[arg2])) { 85882d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_usecs): 859f03f517bSHans Petter Selasky /* import RX coal time */ 860f03f517bSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_usecs < 1) 861f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = 0; 862f03f517bSHans Petter Selasky else if (priv->params_ethtool.rx_coalesce_usecs > 863f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period)) { 864f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = 865f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period); 866f03f517bSHans Petter Selasky } 86782d2623eSHans Petter Selasky priv->params.rx_cq_moderation_usec = 86882d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs; 869f03f517bSHans Petter Selasky 87082d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 87182d2623eSHans Petter Selasky if (was_opened) 87282d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 87382d2623eSHans Petter Selasky break; 87482d2623eSHans Petter Selasky 87582d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_pkts): 876f03f517bSHans Petter Selasky /* import RX coal pkts */ 877f03f517bSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_pkts < 1) 878f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = 0; 879f03f517bSHans Petter Selasky else if (priv->params_ethtool.rx_coalesce_pkts > 880f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count)) { 881f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = 882f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count); 883f03f517bSHans Petter Selasky } 88482d2623eSHans Petter Selasky priv->params.rx_cq_moderation_pkts = 88582d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts; 886f03f517bSHans Petter Selasky 88782d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 88882d2623eSHans Petter Selasky if (was_opened) 88982d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 89082d2623eSHans Petter Selasky break; 89182d2623eSHans Petter Selasky 89282d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_usecs): 893f03f517bSHans Petter Selasky /* import TX coal time */ 894f03f517bSHans Petter Selasky if (priv->params_ethtool.tx_coalesce_usecs < 1) 895f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = 0; 896f03f517bSHans Petter Selasky else if (priv->params_ethtool.tx_coalesce_usecs > 897f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period)) { 898f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = 899f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period); 900f03f517bSHans Petter Selasky } 90182d2623eSHans Petter Selasky priv->params.tx_cq_moderation_usec = 90282d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs; 903f03f517bSHans Petter Selasky 90482d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 90582d2623eSHans Petter Selasky if (was_opened) 90682d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 90782d2623eSHans Petter Selasky break; 90882d2623eSHans Petter Selasky 90982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_pkts): 910f03f517bSHans Petter Selasky /* import TX coal pkts */ 911f03f517bSHans Petter Selasky if (priv->params_ethtool.tx_coalesce_pkts < 1) 912f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = 0; 913f03f517bSHans Petter Selasky else if (priv->params_ethtool.tx_coalesce_pkts > 914f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count)) { 91582d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = 91682d2623eSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count); 917f03f517bSHans Petter Selasky } 91882d2623eSHans Petter Selasky priv->params.tx_cq_moderation_pkts = 91982d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts; 920dc7e38acSHans Petter Selasky 92182d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 92282d2623eSHans Petter Selasky if (was_opened) 923f03f517bSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 92482d2623eSHans Petter Selasky break; 92582d2623eSHans Petter Selasky 92682d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_queue_size): 92782d2623eSHans Petter Selasky /* network interface must be down */ 92882d2623eSHans Petter Selasky if (was_opened) 929f03f517bSHans Petter Selasky mlx5e_close_locked(priv->ifp); 93082d2623eSHans Petter Selasky 931dc7e38acSHans Petter Selasky /* import TX queue size */ 932dc7e38acSHans Petter Selasky if (priv->params_ethtool.tx_queue_size < 933dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) { 934dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 935dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE); 936dc7e38acSHans Petter Selasky } else if (priv->params_ethtool.tx_queue_size > 937dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max) { 938dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 939dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max; 940dc7e38acSHans Petter Selasky } 94182d2623eSHans Petter Selasky /* store actual TX queue size */ 942dc7e38acSHans Petter Selasky priv->params.log_sq_size = 943dc7e38acSHans Petter Selasky order_base_2(priv->params_ethtool.tx_queue_size); 94482d2623eSHans Petter Selasky priv->params_ethtool.tx_queue_size = 94582d2623eSHans Petter Selasky 1 << priv->params.log_sq_size; 94682d2623eSHans Petter Selasky 94782d2623eSHans Petter Selasky /* verify TX completion factor */ 94882d2623eSHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv); 94982d2623eSHans Petter Selasky 95082d2623eSHans Petter Selasky /* restart network interface, if any */ 95182d2623eSHans Petter Selasky if (was_opened) 95282d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 95382d2623eSHans Petter Selasky break; 95482d2623eSHans Petter Selasky 95582d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_queue_size): 95682d2623eSHans Petter Selasky /* network interface must be down */ 95782d2623eSHans Petter Selasky if (was_opened) 95882d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 959dc7e38acSHans Petter Selasky 960dc7e38acSHans Petter Selasky /* import RX queue size */ 961dc7e38acSHans Petter Selasky if (priv->params_ethtool.rx_queue_size < 962dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) { 963dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 964dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE); 965dc7e38acSHans Petter Selasky } else if (priv->params_ethtool.rx_queue_size > 966dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max) { 967dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 968dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max; 969dc7e38acSHans Petter Selasky } 97082d2623eSHans Petter Selasky /* store actual RX queue size */ 971dc7e38acSHans Petter Selasky priv->params.log_rq_size = 972dc7e38acSHans Petter Selasky order_base_2(priv->params_ethtool.rx_queue_size); 97382d2623eSHans Petter Selasky priv->params_ethtool.rx_queue_size = 97482d2623eSHans Petter Selasky 1 << priv->params.log_rq_size; 975dc7e38acSHans Petter Selasky 97682d2623eSHans Petter Selasky /* update least number of RX WQEs */ 97782d2623eSHans Petter Selasky priv->params.min_rx_wqes = min( 978dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size - 1, 979dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_MIN_RX_WQES); 980dc7e38acSHans Petter Selasky 98182d2623eSHans Petter Selasky /* restart network interface, if any */ 98282d2623eSHans Petter Selasky if (was_opened) 98382d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 98482d2623eSHans Petter Selasky break; 98582d2623eSHans Petter Selasky 98616ae32f9SHans Petter Selasky case MLX5_PARAM_OFFSET(channels_rsss): 98716ae32f9SHans Petter Selasky /* network interface must be down */ 98816ae32f9SHans Petter Selasky if (was_opened) 98916ae32f9SHans Petter Selasky mlx5e_close_locked(priv->ifp); 99016ae32f9SHans Petter Selasky 99116ae32f9SHans Petter Selasky /* import number of channels */ 99216ae32f9SHans Petter Selasky if (priv->params_ethtool.channels_rsss < 1) 99316ae32f9SHans Petter Selasky priv->params_ethtool.channels_rsss = 1; 99416ae32f9SHans Petter Selasky else if (priv->params_ethtool.channels_rsss > 128) 99516ae32f9SHans Petter Selasky priv->params_ethtool.channels_rsss = 128; 99616ae32f9SHans Petter Selasky 99716ae32f9SHans Petter Selasky priv->params.channels_rsss = priv->params_ethtool.channels_rsss; 99816ae32f9SHans Petter Selasky 99916ae32f9SHans Petter Selasky /* restart network interface, if any */ 100016ae32f9SHans Petter Selasky if (was_opened) 100116ae32f9SHans Petter Selasky mlx5e_open_locked(priv->ifp); 100216ae32f9SHans Petter Selasky break; 100316ae32f9SHans Petter Selasky 100482d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(channels): 100582d2623eSHans Petter Selasky /* network interface must be down */ 100682d2623eSHans Petter Selasky if (was_opened) 100782d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 100882d2623eSHans Petter Selasky 1009dc7e38acSHans Petter Selasky /* import number of channels */ 1010dc7e38acSHans Petter Selasky if (priv->params_ethtool.channels < 1) 1011dc7e38acSHans Petter Selasky priv->params_ethtool.channels = 1; 1012dc7e38acSHans Petter Selasky else if (priv->params_ethtool.channels > 1013dc7e38acSHans Petter Selasky (u64) priv->mdev->priv.eq_table.num_comp_vectors) { 1014dc7e38acSHans Petter Selasky priv->params_ethtool.channels = 1015dc7e38acSHans Petter Selasky (u64) priv->mdev->priv.eq_table.num_comp_vectors; 1016dc7e38acSHans Petter Selasky } 1017dc7e38acSHans Petter Selasky priv->params.num_channels = priv->params_ethtool.channels; 1018dc7e38acSHans Petter Selasky 101982d2623eSHans Petter Selasky /* restart network interface, if any */ 102082d2623eSHans Petter Selasky if (was_opened) 102182d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 102282d2623eSHans Petter Selasky break; 102382d2623eSHans Petter Selasky 102482d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_mode): 102582d2623eSHans Petter Selasky /* network interface must be down */ 1026d2bf00a9SHans Petter Selasky if (was_opened != 0 && mode_modify == 0) 102782d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 102882d2623eSHans Petter Selasky 102982d2623eSHans Petter Selasky /* import RX coalesce mode */ 1030423530beSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_mode > 3) 1031423530beSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode = 3; 103282d2623eSHans Petter Selasky priv->params.rx_cq_moderation_mode = 103382d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode; 1034dc7e38acSHans Petter Selasky 103582d2623eSHans Petter Selasky /* restart network interface, if any */ 1036d2bf00a9SHans Petter Selasky if (was_opened != 0) { 1037d2bf00a9SHans Petter Selasky if (mode_modify == 0) 103882d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 1039d2bf00a9SHans Petter Selasky else 1040d2bf00a9SHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 1041d2bf00a9SHans Petter Selasky } 104282d2623eSHans Petter Selasky break; 104382d2623eSHans Petter Selasky 104482d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_mode): 104582d2623eSHans Petter Selasky /* network interface must be down */ 1046d2bf00a9SHans Petter Selasky if (was_opened != 0 && mode_modify == 0) 104782d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 104882d2623eSHans Petter Selasky 104982d2623eSHans Petter Selasky /* import TX coalesce mode */ 105074540a31SHans Petter Selasky if (priv->params_ethtool.tx_coalesce_mode != 0) 105174540a31SHans Petter Selasky priv->params_ethtool.tx_coalesce_mode = 1; 105282d2623eSHans Petter Selasky priv->params.tx_cq_moderation_mode = 105382d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_mode; 105474540a31SHans Petter Selasky 105582d2623eSHans Petter Selasky /* restart network interface, if any */ 1056d2bf00a9SHans Petter Selasky if (was_opened != 0) { 1057d2bf00a9SHans Petter Selasky if (mode_modify == 0) 105882d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 1059d2bf00a9SHans Petter Selasky else 1060d2bf00a9SHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 1061d2bf00a9SHans Petter Selasky } 106282d2623eSHans Petter Selasky break; 106382d2623eSHans Petter Selasky 106482d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(hw_lro): 106582d2623eSHans Petter Selasky /* network interface must be down */ 106682d2623eSHans Petter Selasky if (was_opened) 106782d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 106882d2623eSHans Petter Selasky 106982d2623eSHans Petter Selasky /* import HW LRO mode */ 107071defedaSSlava Shwartsman if (priv->params_ethtool.hw_lro != 0 && 1071d7633a30SHans Petter Selasky MLX5_CAP_ETH(priv->mdev, lro_cap)) { 1072d7633a30SHans Petter Selasky priv->params_ethtool.hw_lro = 1; 107371defedaSSlava Shwartsman /* check if feature should actually be enabled */ 107471defedaSSlava Shwartsman if (priv->ifp->if_capenable & IFCAP_LRO) { 107571defedaSSlava Shwartsman priv->params.hw_lro_en = true; 1076d7633a30SHans Petter Selasky } else { 107771defedaSSlava Shwartsman priv->params.hw_lro_en = false; 1078d7633a30SHans Petter Selasky 10796b4040d8SHans Petter Selasky mlx5_en_warn(priv->ifp, "To enable HW LRO " 108071defedaSSlava Shwartsman "please also enable LRO via ifconfig(8).\n"); 108136c1007dSHans Petter Selasky } 1082bb3853c6SHans Petter Selasky } else { 108371defedaSSlava Shwartsman /* return an error if HW does not support this feature */ 108471defedaSSlava Shwartsman if (priv->params_ethtool.hw_lro != 0) 108571defedaSSlava Shwartsman error = EINVAL; 108671defedaSSlava Shwartsman priv->params.hw_lro_en = false; 108771defedaSSlava Shwartsman priv->params_ethtool.hw_lro = 0; 1088dc7e38acSHans Petter Selasky } 108982d2623eSHans Petter Selasky /* restart network interface, if any */ 109082d2623eSHans Petter Selasky if (was_opened) 109182d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 109282d2623eSHans Petter Selasky break; 1093dc7e38acSHans Petter Selasky 109482d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(cqe_zipping): 109582d2623eSHans Petter Selasky /* network interface must be down */ 109682d2623eSHans Petter Selasky if (was_opened) 109782d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 109882d2623eSHans Petter Selasky 109982d2623eSHans Petter Selasky /* import CQE zipping mode */ 110090cc1c77SHans Petter Selasky if (priv->params_ethtool.cqe_zipping && 110190cc1c77SHans Petter Selasky MLX5_CAP_GEN(priv->mdev, cqe_compression)) { 110290cc1c77SHans Petter Selasky priv->params.cqe_zipping_en = true; 110390cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = 1; 110490cc1c77SHans Petter Selasky } else { 110590cc1c77SHans Petter Selasky priv->params.cqe_zipping_en = false; 110690cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = 0; 110790cc1c77SHans Petter Selasky } 110882d2623eSHans Petter Selasky /* restart network interface, if any */ 1109dc7e38acSHans Petter Selasky if (was_opened) 1110dc7e38acSHans Petter Selasky mlx5e_open_locked(priv->ifp); 111182d2623eSHans Petter Selasky break; 111282d2623eSHans Petter Selasky 111382d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_completion_fact): 111482d2623eSHans Petter Selasky /* network interface must be down */ 111582d2623eSHans Petter Selasky if (was_opened) 111682d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 111782d2623eSHans Petter Selasky 111882d2623eSHans Petter Selasky /* verify parameter */ 111982d2623eSHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv); 112082d2623eSHans Petter Selasky 112182d2623eSHans Petter Selasky /* restart network interface, if any */ 112282d2623eSHans Petter Selasky if (was_opened) 112382d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 112482d2623eSHans Petter Selasky break; 112582d2623eSHans Petter Selasky 1126bb3616abSHans Petter Selasky case MLX5_PARAM_OFFSET(modify_tx_dma): 1127bb3616abSHans Petter Selasky /* check if network interface is opened */ 1128bb3616abSHans Petter Selasky if (was_opened) { 1129bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma = 1130bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma ? 1 : 0; 1131bb3616abSHans Petter Selasky /* modify tx according to value */ 1132bb3616abSHans Petter Selasky mlx5e_modify_tx_dma(priv, value != 0); 1133bb3616abSHans Petter Selasky } else { 1134bb3616abSHans Petter Selasky /* if closed force enable tx */ 1135bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma = 0; 1136bb3616abSHans Petter Selasky } 1137bb3616abSHans Petter Selasky break; 1138bb3616abSHans Petter Selasky 1139bb3616abSHans Petter Selasky case MLX5_PARAM_OFFSET(modify_rx_dma): 1140bb3616abSHans Petter Selasky /* check if network interface is opened */ 1141bb3616abSHans Petter Selasky if (was_opened) { 1142bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma = 1143bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma ? 1 : 0; 1144bb3616abSHans Petter Selasky /* modify rx according to value */ 1145bb3616abSHans Petter Selasky mlx5e_modify_rx_dma(priv, value != 0); 1146bb3616abSHans Petter Selasky } else { 1147bb3616abSHans Petter Selasky /* if closed force enable rx */ 1148bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma = 0; 1149bb3616abSHans Petter Selasky } 1150bb3616abSHans Petter Selasky break; 1151bb3616abSHans Petter Selasky 115266d53750SHans Petter Selasky case MLX5_PARAM_OFFSET(diag_pci_enable): 115366d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable = 115466d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable ? 1 : 0; 115566d53750SHans Petter Selasky 115666d53750SHans Petter Selasky error = -mlx5_core_set_diagnostics_full(priv->mdev, 115766d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable, 115866d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable); 115966d53750SHans Petter Selasky break; 116066d53750SHans Petter Selasky 116166d53750SHans Petter Selasky case MLX5_PARAM_OFFSET(diag_general_enable): 116266d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable = 116366d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable ? 1 : 0; 116466d53750SHans Petter Selasky 116566d53750SHans Petter Selasky error = -mlx5_core_set_diagnostics_full(priv->mdev, 116666d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable, 116766d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable); 116866d53750SHans Petter Selasky break; 116966d53750SHans Petter Selasky 117061fd7ac0SHans Petter Selasky case MLX5_PARAM_OFFSET(mc_local_lb): 117161fd7ac0SHans Petter Selasky priv->params_ethtool.mc_local_lb = 117261fd7ac0SHans Petter Selasky priv->params_ethtool.mc_local_lb ? 1 : 0; 117361fd7ac0SHans Petter Selasky 117461fd7ac0SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, disable_local_lb)) { 117561fd7ac0SHans Petter Selasky error = mlx5_nic_vport_modify_local_lb(priv->mdev, 117661fd7ac0SHans Petter Selasky MLX5_LOCAL_MC_LB, priv->params_ethtool.mc_local_lb); 117761fd7ac0SHans Petter Selasky } else { 117861fd7ac0SHans Petter Selasky error = EOPNOTSUPP; 117961fd7ac0SHans Petter Selasky } 118061fd7ac0SHans Petter Selasky break; 118161fd7ac0SHans Petter Selasky 118261fd7ac0SHans Petter Selasky case MLX5_PARAM_OFFSET(uc_local_lb): 118361fd7ac0SHans Petter Selasky priv->params_ethtool.uc_local_lb = 118461fd7ac0SHans Petter Selasky priv->params_ethtool.uc_local_lb ? 1 : 0; 118561fd7ac0SHans Petter Selasky 118661fd7ac0SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, disable_local_lb)) { 118761fd7ac0SHans Petter Selasky error = mlx5_nic_vport_modify_local_lb(priv->mdev, 118861fd7ac0SHans Petter Selasky MLX5_LOCAL_UC_LB, priv->params_ethtool.uc_local_lb); 118961fd7ac0SHans Petter Selasky } else { 119061fd7ac0SHans Petter Selasky error = EOPNOTSUPP; 119161fd7ac0SHans Petter Selasky } 119261fd7ac0SHans Petter Selasky break; 119361fd7ac0SHans Petter Selasky 119482d2623eSHans Petter Selasky default: 119582d2623eSHans Petter Selasky break; 119682d2623eSHans Petter Selasky } 1197dc7e38acSHans Petter Selasky done: 1198dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 1199dc7e38acSHans Petter Selasky return (error); 1200dc7e38acSHans Petter Selasky } 1201dc7e38acSHans Petter Selasky 1202dc7e38acSHans Petter Selasky static const char *mlx5e_params_desc[] = { 1203dc7e38acSHans Petter Selasky MLX5E_PARAMS(MLX5E_STATS_DESC) 1204dc7e38acSHans Petter Selasky }; 1205dc7e38acSHans Petter Selasky 1206dc7e38acSHans Petter Selasky static const char *mlx5e_port_stats_debug_desc[] = { 1207dc7e38acSHans Petter Selasky MLX5E_PORT_STATS_DEBUG(MLX5E_STATS_DESC) 1208dc7e38acSHans Petter Selasky }; 1209dc7e38acSHans Petter Selasky 1210dc7e38acSHans Petter Selasky static int 1211f2b4782cSHans Petter Selasky mlx5e_ethtool_debug_channel_info(SYSCTL_HANDLER_ARGS) 1212f2b4782cSHans Petter Selasky { 1213f2b4782cSHans Petter Selasky struct mlx5e_priv *priv; 1214f2b4782cSHans Petter Selasky struct sbuf sb; 1215f2b4782cSHans Petter Selasky struct mlx5e_channel *c; 1216f2b4782cSHans Petter Selasky struct mlx5e_sq *sq; 1217f2b4782cSHans Petter Selasky struct mlx5e_rq *rq; 1218f2b4782cSHans Petter Selasky int error, i, tc; 12192110251aSHans Petter Selasky bool opened; 1220f2b4782cSHans Petter Selasky 1221f2b4782cSHans Petter Selasky priv = arg1; 1222f2b4782cSHans Petter Selasky error = sysctl_wire_old_buffer(req, 0); 1223f2b4782cSHans Petter Selasky if (error != 0) 1224f2b4782cSHans Petter Selasky return (error); 12252110251aSHans Petter Selasky if (sbuf_new_for_sysctl(&sb, NULL, 1024, req) == NULL) 1226f2b4782cSHans Petter Selasky return (ENOMEM); 1227f2b4782cSHans Petter Selasky sbuf_clear_flags(&sb, SBUF_INCLUDENUL); 1228f2b4782cSHans Petter Selasky 1229f2b4782cSHans Petter Selasky PRIV_LOCK(priv); 12302110251aSHans Petter Selasky opened = test_bit(MLX5E_STATE_OPENED, &priv->state); 12312110251aSHans Petter Selasky 12322110251aSHans Petter Selasky sbuf_printf(&sb, "pages irq %d\n", 12332110251aSHans Petter Selasky priv->mdev->priv.msix_arr[MLX5_EQ_VEC_PAGES].vector); 12342110251aSHans Petter Selasky sbuf_printf(&sb, "command irq %d\n", 12352110251aSHans Petter Selasky priv->mdev->priv.msix_arr[MLX5_EQ_VEC_CMD].vector); 12362110251aSHans Petter Selasky sbuf_printf(&sb, "async irq %d\n", 12372110251aSHans Petter Selasky priv->mdev->priv.msix_arr[MLX5_EQ_VEC_ASYNC].vector); 12382110251aSHans Petter Selasky 12392110251aSHans Petter Selasky for (i = 0; i != priv->params.num_channels; i++) { 12402110251aSHans Petter Selasky int eqn_not_used = -1; 12412110251aSHans Petter Selasky int irqn = MLX5_EQ_VEC_COMP_BASE; 12422110251aSHans Petter Selasky 12432110251aSHans Petter Selasky if (mlx5_vector2eqn(priv->mdev, i, &eqn_not_used, &irqn) != 0) 12442110251aSHans Petter Selasky continue; 12452110251aSHans Petter Selasky 12462110251aSHans Petter Selasky c = opened ? &priv->channel[i] : NULL; 12472110251aSHans Petter Selasky rq = opened ? &c->rq : NULL; 12482110251aSHans Petter Selasky sbuf_printf(&sb, "channel %d rq %d cq %d irq %d\n", i, 12492110251aSHans Petter Selasky opened ? rq->rqn : -1, 12502110251aSHans Petter Selasky opened ? rq->cq.mcq.cqn : -1, 12512110251aSHans Petter Selasky priv->mdev->priv.msix_arr[irqn].vector); 12522110251aSHans Petter Selasky 12532110251aSHans Petter Selasky for (tc = 0; tc != priv->num_tc; tc++) { 12542110251aSHans Petter Selasky sq = opened ? &c->sq[tc] : NULL; 12552110251aSHans Petter Selasky sbuf_printf(&sb, "channel %d tc %d sq %d cq %d irq %d\n", 12562110251aSHans Petter Selasky i, tc, 12572110251aSHans Petter Selasky opened ? sq->sqn : -1, 12582110251aSHans Petter Selasky opened ? sq->cq.mcq.cqn : -1, 12592110251aSHans Petter Selasky priv->mdev->priv.msix_arr[irqn].vector); 1260f2b4782cSHans Petter Selasky } 1261f2b4782cSHans Petter Selasky } 1262f2b4782cSHans Petter Selasky PRIV_UNLOCK(priv); 1263f2b4782cSHans Petter Selasky error = sbuf_finish(&sb); 1264f2b4782cSHans Petter Selasky sbuf_delete(&sb); 1265f2b4782cSHans Petter Selasky return (error); 1266f2b4782cSHans Petter Selasky } 1267f2b4782cSHans Petter Selasky 1268f2b4782cSHans Petter Selasky static int 1269dc7e38acSHans Petter Selasky mlx5e_ethtool_debug_stats(SYSCTL_HANDLER_ARGS) 1270dc7e38acSHans Petter Selasky { 1271dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1; 1272b3cf1493SSlava Shwartsman int sys_debug; 1273b3cf1493SSlava Shwartsman int error; 1274f2b4782cSHans Petter Selasky 1275f2b4782cSHans Petter Selasky PRIV_LOCK(priv); 1276069963d7SHans Petter Selasky if (priv->gone != 0) { 1277069963d7SHans Petter Selasky error = ENODEV; 1278069963d7SHans Petter Selasky goto done; 1279069963d7SHans Petter Selasky } 1280b3cf1493SSlava Shwartsman sys_debug = priv->sysctl_debug; 1281b3cf1493SSlava Shwartsman error = sysctl_handle_int(oidp, &sys_debug, 0, req); 1282b3cf1493SSlava Shwartsman if (error != 0 || !req->newptr) 1283b3cf1493SSlava Shwartsman goto done; 1284b3cf1493SSlava Shwartsman sys_debug = sys_debug ? 1 : 0; 1285b3cf1493SSlava Shwartsman if (sys_debug == priv->sysctl_debug) 1286b3cf1493SSlava Shwartsman goto done; 1287b3cf1493SSlava Shwartsman 1288b3cf1493SSlava Shwartsman if ((priv->sysctl_debug = sys_debug)) { 1289dc7e38acSHans Petter Selasky mlx5e_create_stats(&priv->stats.port_stats_debug.ctx, 1290dc7e38acSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), "debug_stats", 1291dc7e38acSHans Petter Selasky mlx5e_port_stats_debug_desc, MLX5E_PORT_STATS_DEBUG_NUM, 1292dc7e38acSHans Petter Selasky priv->stats.port_stats_debug.arg); 1293b3cf1493SSlava Shwartsman SYSCTL_ADD_PROC(&priv->stats.port_stats_debug.ctx, 1294f2b4782cSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO, 1295f2b4782cSHans Petter Selasky "hw_ctx_debug", 1296f2b4782cSHans Petter Selasky CTLFLAG_RD | CTLFLAG_MPSAFE | CTLTYPE_STRING, priv, 0, 1297f2b4782cSHans Petter Selasky mlx5e_ethtool_debug_channel_info, "S", ""); 1298f2b4782cSHans Petter Selasky } else { 1299dc7e38acSHans Petter Selasky sysctl_ctx_free(&priv->stats.port_stats_debug.ctx); 1300f2b4782cSHans Petter Selasky } 1301b3cf1493SSlava Shwartsman done: 1302f2b4782cSHans Petter Selasky PRIV_UNLOCK(priv); 1303b3cf1493SSlava Shwartsman return (error); 1304dc7e38acSHans Petter Selasky } 1305dc7e38acSHans Petter Selasky 130666d53750SHans Petter Selasky static void 130766d53750SHans Petter Selasky mlx5e_create_diagnostics(struct mlx5e_priv *priv) 130866d53750SHans Petter Selasky { 130966d53750SHans Petter Selasky struct mlx5_core_diagnostics_entry entry; 131066d53750SHans Petter Selasky struct sysctl_ctx_list *ctx; 131166d53750SHans Petter Selasky struct sysctl_oid *node; 131266d53750SHans Petter Selasky int x; 131366d53750SHans Petter Selasky 131466d53750SHans Petter Selasky /* sysctl context we are using */ 131566d53750SHans Petter Selasky ctx = &priv->sysctl_ctx; 131666d53750SHans Petter Selasky 131766d53750SHans Petter Selasky /* create root node */ 131866d53750SHans Petter Selasky node = SYSCTL_ADD_NODE(ctx, 131966d53750SHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO, 132066d53750SHans Petter Selasky "diagnostics", CTLFLAG_RD, NULL, "Diagnostics"); 132166d53750SHans Petter Selasky if (node == NULL) 132266d53750SHans Petter Selasky return; 132366d53750SHans Petter Selasky 132466d53750SHans Petter Selasky /* create PCI diagnostics */ 132566d53750SHans Petter Selasky for (x = 0; x != MLX5_CORE_PCI_DIAGNOSTICS_NUM; x++) { 132666d53750SHans Petter Selasky entry = mlx5_core_pci_diagnostics_table[x]; 132766d53750SHans Petter Selasky if (mlx5_core_supports_diagnostics(priv->mdev, entry.counter_id) == 0) 132866d53750SHans Petter Selasky continue; 132966d53750SHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 133066d53750SHans Petter Selasky entry.desc, CTLFLAG_RD, priv->params_pci.array + x, 133166d53750SHans Petter Selasky "PCI diagnostics counter"); 133266d53750SHans Petter Selasky } 133366d53750SHans Petter Selasky 133466d53750SHans Petter Selasky /* create general diagnostics */ 133566d53750SHans Petter Selasky for (x = 0; x != MLX5_CORE_GENERAL_DIAGNOSTICS_NUM; x++) { 133666d53750SHans Petter Selasky entry = mlx5_core_general_diagnostics_table[x]; 133766d53750SHans Petter Selasky if (mlx5_core_supports_diagnostics(priv->mdev, entry.counter_id) == 0) 133866d53750SHans Petter Selasky continue; 133966d53750SHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 134066d53750SHans Petter Selasky entry.desc, CTLFLAG_RD, priv->params_general.array + x, 134166d53750SHans Petter Selasky "General diagnostics counter"); 134266d53750SHans Petter Selasky } 134366d53750SHans Petter Selasky } 134466d53750SHans Petter Selasky 1345dc7e38acSHans Petter Selasky void 1346dc7e38acSHans Petter Selasky mlx5e_create_ethtool(struct mlx5e_priv *priv) 1347dc7e38acSHans Petter Selasky { 134896425f44SHans Petter Selasky struct sysctl_oid *fec_node; 134996425f44SHans Petter Selasky struct sysctl_oid *qos_node; 135096425f44SHans Petter Selasky struct sysctl_oid *node; 1351dc7e38acSHans Petter Selasky const char *pnameunit; 13526deb0b1eSHans Petter Selasky struct mlx5e_port_buffer port_buffer; 1353dc7e38acSHans Petter Selasky unsigned x; 1354cfc9c386SHans Petter Selasky int i; 1355dc7e38acSHans Petter Selasky 1356dc7e38acSHans Petter Selasky /* set some defaults */ 1357dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE; 1358dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max = 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE; 1359dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 1 << priv->params.log_sq_size; 1360dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 1 << priv->params.log_rq_size; 1361dc7e38acSHans Petter Selasky priv->params_ethtool.channels = priv->params.num_channels; 136216ae32f9SHans Petter Selasky priv->params_ethtool.channels_rsss = priv->params.channels_rsss; 1363dc7e38acSHans Petter Selasky priv->params_ethtool.coalesce_pkts_max = MLX5E_FLD_MAX(cqc, cq_max_count); 1364dc7e38acSHans Petter Selasky priv->params_ethtool.coalesce_usecs_max = MLX5E_FLD_MAX(cqc, cq_period); 1365dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode = priv->params.rx_cq_moderation_mode; 1366dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = priv->params.rx_cq_moderation_usec; 1367dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = priv->params.rx_cq_moderation_pkts; 136874540a31SHans Petter Selasky priv->params_ethtool.tx_coalesce_mode = priv->params.tx_cq_moderation_mode; 1369dc7e38acSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = priv->params.tx_cq_moderation_usec; 1370dc7e38acSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = priv->params.tx_cq_moderation_pkts; 1371dc7e38acSHans Petter Selasky priv->params_ethtool.hw_lro = priv->params.hw_lro_en; 137290cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = priv->params.cqe_zipping_en; 1373376bcf63SHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv); 1374dc7e38acSHans Petter Selasky 137561fd7ac0SHans Petter Selasky /* get default values for local loopback, if any */ 137661fd7ac0SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, disable_local_lb)) { 137761fd7ac0SHans Petter Selasky int err; 137861fd7ac0SHans Petter Selasky u8 val; 137961fd7ac0SHans Petter Selasky 138061fd7ac0SHans Petter Selasky err = mlx5_nic_vport_query_local_lb(priv->mdev, MLX5_LOCAL_MC_LB, &val); 138161fd7ac0SHans Petter Selasky if (err == 0) 138261fd7ac0SHans Petter Selasky priv->params_ethtool.mc_local_lb = val; 138361fd7ac0SHans Petter Selasky 138461fd7ac0SHans Petter Selasky err = mlx5_nic_vport_query_local_lb(priv->mdev, MLX5_LOCAL_UC_LB, &val); 138561fd7ac0SHans Petter Selasky if (err == 0) 138661fd7ac0SHans Petter Selasky priv->params_ethtool.uc_local_lb = val; 138761fd7ac0SHans Petter Selasky } 138861fd7ac0SHans Petter Selasky 1389dc7e38acSHans Petter Selasky /* create root node */ 1390dc7e38acSHans Petter Selasky node = SYSCTL_ADD_NODE(&priv->sysctl_ctx, 1391dc7e38acSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO, 1392dc7e38acSHans Petter Selasky "conf", CTLFLAG_RW, NULL, "Configuration"); 1393dc7e38acSHans Petter Selasky if (node == NULL) 1394dc7e38acSHans Petter Selasky return; 1395dc7e38acSHans Petter Selasky for (x = 0; x != MLX5E_PARAMS_NUM; x++) { 1396dc7e38acSHans Petter Selasky /* check for read-only parameter */ 139753d7bb46SHans Petter Selasky if (strstr(mlx5e_params_desc[2 * x], "_max") != NULL || 139853d7bb46SHans Petter Selasky strstr(mlx5e_params_desc[2 * x], "_mtu") != NULL) { 1399dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 1400dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x], CTLTYPE_U64 | CTLFLAG_RD | 1401dc7e38acSHans Petter Selasky CTLFLAG_MPSAFE, priv, x, &mlx5e_ethtool_handler, "QU", 1402dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x + 1]); 1403dc7e38acSHans Petter Selasky } else { 1404ec0143b2SHans Petter Selasky #if (__FreeBSD_version < 1100000) 1405ec0143b2SHans Petter Selasky char path[64]; 1406ec0143b2SHans Petter Selasky #endif 1407ec0143b2SHans Petter Selasky /* 1408ec0143b2SHans Petter Selasky * NOTE: In FreeBSD-11 and newer the 1409ec0143b2SHans Petter Selasky * CTLFLAG_RWTUN flag will take care of 1410ec0143b2SHans Petter Selasky * loading default sysctl value from the 1411ec0143b2SHans Petter Selasky * kernel environment, if any: 1412ec0143b2SHans Petter Selasky */ 1413dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 1414dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x], CTLTYPE_U64 | CTLFLAG_RWTUN | 1415dc7e38acSHans Petter Selasky CTLFLAG_MPSAFE, priv, x, &mlx5e_ethtool_handler, "QU", 1416dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x + 1]); 1417ec0143b2SHans Petter Selasky 1418ec0143b2SHans Petter Selasky #if (__FreeBSD_version < 1100000) 1419ec0143b2SHans Petter Selasky /* compute path for sysctl */ 1420ec0143b2SHans Petter Selasky snprintf(path, sizeof(path), "dev.mce.%d.conf.%s", 1421ec0143b2SHans Petter Selasky device_get_unit(priv->mdev->pdev->dev.bsddev), 1422ec0143b2SHans Petter Selasky mlx5e_params_desc[2 * x]); 1423ec0143b2SHans Petter Selasky 1424ec0143b2SHans Petter Selasky /* try to fetch tunable, if any */ 1425ec0143b2SHans Petter Selasky if (TUNABLE_QUAD_FETCH(path, &priv->params_ethtool.arg[x])) 1426ec0143b2SHans Petter Selasky mlx5e_ethtool_handler(NULL, priv, x, NULL); 1427ec0143b2SHans Petter Selasky #endif 1428dc7e38acSHans Petter Selasky } 1429dc7e38acSHans Petter Selasky } 1430dc7e38acSHans Petter Selasky 143196425f44SHans Petter Selasky /* create fec node */ 143296425f44SHans Petter Selasky fec_node = SYSCTL_ADD_NODE(&priv->sysctl_ctx, 143396425f44SHans Petter Selasky SYSCTL_CHILDREN(node), OID_AUTO, 143496425f44SHans Petter Selasky "fec", CTLFLAG_RW, NULL, "Forward Error Correction"); 143596425f44SHans Petter Selasky if (fec_node == NULL) 143696425f44SHans Petter Selasky return; 143796425f44SHans Petter Selasky 143896425f44SHans Petter Selasky if (mlx5e_fec_update(priv) == 0) { 143996425f44SHans Petter Selasky SYSCTL_ADD_U32(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 144096425f44SHans Petter Selasky "mode_active", CTLFLAG_RD | CTLFLAG_MPSAFE, 144196425f44SHans Petter Selasky &priv->params_ethtool.fec_mode_active, 0, 144296425f44SHans Petter Selasky "Current FEC mode bit, if any."); 144396425f44SHans Petter Selasky 144496425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 144596425f44SHans Petter Selasky "mask_10x_25x", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 144696425f44SHans Petter Selasky priv, 0, &mlx5e_fec_mask_10x_25x_handler, "CU", 144796425f44SHans Petter Selasky "Set FEC masks for 10G_40G, 25G_50G, 56G, 100G respectivly. " 144896425f44SHans Petter Selasky "0:Auto " 144996425f44SHans Petter Selasky "1:NOFEC " 145096425f44SHans Petter Selasky "2:FIRECODE " 145196425f44SHans Petter Selasky "4:RS"); 145296425f44SHans Petter Selasky 145396425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 145496425f44SHans Petter Selasky "avail_10x_25x", CTLTYPE_U8 | CTLFLAG_RD | CTLFLAG_MPSAFE, 145596425f44SHans Petter Selasky priv, 0, &mlx5e_fec_avail_10x_25x_handler, "CU", 145696425f44SHans Petter Selasky "Get available FEC bits for 10G_40G, 25G_50G, 56G, 100G respectivly. " 145796425f44SHans Petter Selasky "0:Auto " 145896425f44SHans Petter Selasky "1:NOFEC " 145996425f44SHans Petter Selasky "2:FIRECODE " 146096425f44SHans Petter Selasky "4:RS"); 146196425f44SHans Petter Selasky 146296425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 146396425f44SHans Petter Selasky "mask_50x", CTLTYPE_U16 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 146496425f44SHans Petter Selasky priv, 0, &mlx5e_fec_mask_50x_handler, "SU", 146596425f44SHans Petter Selasky "Set FEC masks for 50G 1x, 100G 2x, 200G 4x, 400G 8x respectivly. " 146696425f44SHans Petter Selasky "0:Auto " 146796425f44SHans Petter Selasky "128:RS " 146896425f44SHans Petter Selasky "512:LL RS"); 146996425f44SHans Petter Selasky 147096425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 147196425f44SHans Petter Selasky "avail_50x", CTLTYPE_U16 | CTLFLAG_RD | CTLFLAG_MPSAFE, 147296425f44SHans Petter Selasky priv, 0, &mlx5e_fec_avail_50x_handler, "SU", 147396425f44SHans Petter Selasky "Get available FEC bits for 50G 1x, 100G 2x, 200G 4x, 400G 8x respectivly. " 147496425f44SHans Petter Selasky "0:Auto " 147596425f44SHans Petter Selasky "128:RS " 147696425f44SHans Petter Selasky "512:LL RS"); 147796425f44SHans Petter Selasky } 147896425f44SHans Petter Selasky 1479dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 1480dc7e38acSHans Petter Selasky "debug_stats", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv, 1481dc7e38acSHans Petter Selasky 0, &mlx5e_ethtool_debug_stats, "I", "Extended debug statistics"); 1482dc7e38acSHans Petter Selasky 1483dc7e38acSHans Petter Selasky pnameunit = device_get_nameunit(priv->mdev->pdev->dev.bsddev); 1484dc7e38acSHans Petter Selasky 1485dc7e38acSHans Petter Selasky SYSCTL_ADD_STRING(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), 1486dc7e38acSHans Petter Selasky OID_AUTO, "device_name", CTLFLAG_RD, 1487dc7e38acSHans Petter Selasky __DECONST(void *, pnameunit), 0, 1488dc7e38acSHans Petter Selasky "PCI device name"); 1489dc7e38acSHans Petter Selasky 149066d53750SHans Petter Selasky /* Diagnostics support */ 149166d53750SHans Petter Selasky mlx5e_create_diagnostics(priv); 1492cfc9c386SHans Petter Selasky 1493cfc9c386SHans Petter Selasky /* create qos node */ 1494cfc9c386SHans Petter Selasky qos_node = SYSCTL_ADD_NODE(&priv->sysctl_ctx, 1495cfc9c386SHans Petter Selasky SYSCTL_CHILDREN(node), OID_AUTO, 1496cfc9c386SHans Petter Selasky "qos", CTLFLAG_RW, NULL, "Quality Of Service configuration"); 1497e870c0abSSlava Shwartsman if (qos_node == NULL) 1498cfc9c386SHans Petter Selasky return; 1499cfc9c386SHans Petter Selasky 1500e870c0abSSlava Shwartsman /* Priority rate limit support */ 1501e870c0abSSlava Shwartsman if (mlx5e_getmaxrate(priv) == 0) { 1502cfc9c386SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 1503e870c0abSSlava Shwartsman OID_AUTO, "tc_max_rate", CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 1504e870c0abSSlava Shwartsman priv, 0, mlx5e_tc_maxrate_handler, "QU", 1505e870c0abSSlava Shwartsman "Max rate for priority, specified in kilobits, where kilo=1000, " 1506e870c0abSSlava Shwartsman "max_rate must be divisible by 100000"); 1507cfc9c386SHans Petter Selasky } 15082e9c3a4fSHans Petter Selasky 1509e870c0abSSlava Shwartsman /* Bandwidth limiting by ratio */ 1510e870c0abSSlava Shwartsman if (mlx5e_get_max_alloc(priv) == 0) { 1511e870c0abSSlava Shwartsman SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 1512e870c0abSSlava Shwartsman OID_AUTO, "tc_rate_share", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 1513e870c0abSSlava Shwartsman priv, 0, mlx5e_tc_rate_share_handler, "QU", 1514e870c0abSSlava Shwartsman "Specify bandwidth ratio from 1 to 100 " 1515e870c0abSSlava Shwartsman "for the available traffic classes"); 1516e870c0abSSlava Shwartsman } 15172e9c3a4fSHans Petter Selasky 1518e870c0abSSlava Shwartsman /* Priority to traffic class mapping */ 1519e870c0abSSlava Shwartsman if (mlx5e_get_prio_tc(priv) == 0) { 15202e9c3a4fSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 152124385321SHans Petter Selasky OID_AUTO, "prio_0_7_tc", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 152224385321SHans Petter Selasky priv, 0, mlx5e_prio_to_tc_handler, "CU", 152324385321SHans Petter Selasky "Set traffic class 0 to 7 for priority 0 to 7 inclusivly"); 1524e870c0abSSlava Shwartsman } 1525ed0cee0bSHans Petter Selasky 1526ed0cee0bSHans Petter Selasky /* DSCP support */ 1527ed0cee0bSHans Petter Selasky if (mlx5e_get_dscp(priv) == 0) { 1528ed0cee0bSHans Petter Selasky for (i = 0; i != MLX5_MAX_SUPPORTED_DSCP; i += 8) { 1529ed0cee0bSHans Petter Selasky char name[32]; 1530ed0cee0bSHans Petter Selasky snprintf(name, sizeof(name), "dscp_%d_%d_prio", i, i + 7); 1531ed0cee0bSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 1532ed0cee0bSHans Petter Selasky OID_AUTO, name, CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 1533ed0cee0bSHans Petter Selasky priv, i, mlx5e_dscp_prio_handler, "CU", 1534ed0cee0bSHans Petter Selasky "Set DSCP to priority mapping, 0..7"); 1535ed0cee0bSHans Petter Selasky } 1536a880c1ffSHans Petter Selasky #define A "Set trust state, 1:PCP 2:DSCP" 1537a880c1ffSHans Petter Selasky #define B " 3:BOTH" 1538ed0cee0bSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 1539ed0cee0bSHans Petter Selasky OID_AUTO, "trust_state", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 1540ed0cee0bSHans Petter Selasky priv, 0, mlx5e_trust_state_handler, "CU", 1541dfea1c3eSHans Petter Selasky MLX5_CAP_QCAM_FEATURE(priv->mdev, qpts_trust_both) ? 1542a880c1ffSHans Petter Selasky A B : A); 1543a880c1ffSHans Petter Selasky #undef B 1544a880c1ffSHans Petter Selasky #undef A 1545ed0cee0bSHans Petter Selasky } 15466deb0b1eSHans Petter Selasky 15476deb0b1eSHans Petter Selasky if (mlx5e_port_query_buffer(priv, &port_buffer) == 0) { 15486deb0b1eSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 15496deb0b1eSHans Petter Selasky OID_AUTO, "buffers_size", 15506deb0b1eSHans Petter Selasky CTLTYPE_U32 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 15516deb0b1eSHans Petter Selasky priv, 0, mlx5e_buf_size_handler, "IU", 15526deb0b1eSHans Petter Selasky "Set buffers sizes"); 15536deb0b1eSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 15546deb0b1eSHans Petter Selasky OID_AUTO, "buffers_prio", 15556deb0b1eSHans Petter Selasky CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 15566deb0b1eSHans Petter Selasky priv, 0, mlx5e_buf_prio_handler, "CU", 15576deb0b1eSHans Petter Selasky "Set prio to buffers mapping"); 15586deb0b1eSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 15596deb0b1eSHans Petter Selasky OID_AUTO, "cable_length", 15606deb0b1eSHans Petter Selasky CTLTYPE_UINT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 15616deb0b1eSHans Petter Selasky priv, 0, mlx5e_cable_length_handler, "IU", 15626deb0b1eSHans Petter Selasky "Set cable length in meters for xoff threshold calculation"); 15636deb0b1eSHans Petter Selasky } 1564dc7e38acSHans Petter Selasky } 1565