1dc7e38acSHans Petter Selasky /*- 2c8d16d1eSHans Petter Selasky * Copyright (c) 2015-2021 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 28b984b956SKonstantin Belousov #include "opt_rss.h" 29b984b956SKonstantin Belousov #include "opt_ratelimit.h" 30b984b956SKonstantin Belousov 3189918a23SKonstantin Belousov #include <dev/mlx5/mlx5_en/en.h> 3289918a23SKonstantin Belousov #include <dev/mlx5/mlx5_en/port_buffer.h> 33dc7e38acSHans Petter Selasky 34dc7e38acSHans Petter Selasky void 35dc7e38acSHans Petter Selasky mlx5e_create_stats(struct sysctl_ctx_list *ctx, 36dc7e38acSHans Petter Selasky struct sysctl_oid_list *parent, const char *buffer, 37dc7e38acSHans Petter Selasky const char **desc, unsigned num, u64 * arg) 38dc7e38acSHans Petter Selasky { 39dc7e38acSHans Petter Selasky struct sysctl_oid *node; 40dc7e38acSHans Petter Selasky unsigned x; 41dc7e38acSHans Petter Selasky 42dc7e38acSHans Petter Selasky sysctl_ctx_init(ctx); 43dc7e38acSHans Petter Selasky 44dc7e38acSHans Petter Selasky node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, 457029da5cSPawel Biernacki buffer, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Statistics"); 46dc7e38acSHans Petter Selasky if (node == NULL) 47dc7e38acSHans Petter Selasky return; 48dc7e38acSHans Petter Selasky for (x = 0; x != num; x++) { 49dc7e38acSHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 50dc7e38acSHans Petter Selasky desc[2 * x], CTLFLAG_RD, arg + x, desc[2 * x + 1]); 51dc7e38acSHans Petter Selasky } 52dc7e38acSHans Petter Selasky } 53dc7e38acSHans Petter Selasky 547272f9cdSHans Petter Selasky void 557272f9cdSHans Petter Selasky mlx5e_create_counter_stats(struct sysctl_ctx_list *ctx, 567272f9cdSHans Petter Selasky struct sysctl_oid_list *parent, const char *buffer, 577272f9cdSHans Petter Selasky const char **desc, unsigned num, counter_u64_t *arg) 587272f9cdSHans Petter Selasky { 597272f9cdSHans Petter Selasky struct sysctl_oid *node; 607272f9cdSHans Petter Selasky unsigned x; 617272f9cdSHans Petter Selasky 627272f9cdSHans Petter Selasky sysctl_ctx_init(ctx); 637272f9cdSHans Petter Selasky 647272f9cdSHans Petter Selasky node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, 657029da5cSPawel Biernacki buffer, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Statistics"); 667272f9cdSHans Petter Selasky if (node == NULL) 677272f9cdSHans Petter Selasky return; 687272f9cdSHans Petter Selasky for (x = 0; x != num; x++) { 697272f9cdSHans Petter Selasky SYSCTL_ADD_COUNTER_U64(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 707272f9cdSHans Petter Selasky desc[2 * x], CTLFLAG_RD, arg + x, desc[2 * x + 1]); 717272f9cdSHans Petter Selasky } 727272f9cdSHans Petter Selasky } 737272f9cdSHans Petter Selasky 74376bcf63SHans Petter Selasky static void 75376bcf63SHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(struct mlx5e_priv *priv) 76376bcf63SHans Petter Selasky { 77376bcf63SHans Petter Selasky /* 78376bcf63SHans Petter Selasky * Limit the maximum distance between completion events to 79376bcf63SHans Petter Selasky * half of the currently set TX queue size. 80376bcf63SHans Petter Selasky * 81376bcf63SHans Petter Selasky * The maximum number of queue entries a single IP packet can 82376bcf63SHans Petter Selasky * consume is given by MLX5_SEND_WQE_MAX_WQEBBS. 83376bcf63SHans Petter Selasky * 84376bcf63SHans Petter Selasky * The worst case max value is then given as below: 85376bcf63SHans Petter Selasky */ 86376bcf63SHans Petter Selasky uint64_t max = priv->params_ethtool.tx_queue_size / 87376bcf63SHans Petter Selasky (2 * MLX5_SEND_WQE_MAX_WQEBBS); 88376bcf63SHans Petter Selasky 89376bcf63SHans Petter Selasky /* 90376bcf63SHans Petter Selasky * Update the maximum completion factor value in case the 91376bcf63SHans Petter Selasky * tx_queue_size field changed. Ensure we don't overflow 92376bcf63SHans Petter Selasky * 16-bits. 93376bcf63SHans Petter Selasky */ 94376bcf63SHans Petter Selasky if (max < 1) 95376bcf63SHans Petter Selasky max = 1; 96376bcf63SHans Petter Selasky else if (max > 65535) 97376bcf63SHans Petter Selasky max = 65535; 98376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact_max = max; 99376bcf63SHans Petter Selasky 100376bcf63SHans Petter Selasky /* 101376bcf63SHans Petter Selasky * Verify that the current TX completion factor is within the 102376bcf63SHans Petter Selasky * given limits: 103376bcf63SHans Petter Selasky */ 104376bcf63SHans Petter Selasky if (priv->params_ethtool.tx_completion_fact < 1) 105376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact = 1; 106376bcf63SHans Petter Selasky else if (priv->params_ethtool.tx_completion_fact > max) 107376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact = max; 108376bcf63SHans Petter Selasky } 109376bcf63SHans Petter Selasky 110cfc9c386SHans Petter Selasky static int 111cfc9c386SHans Petter Selasky mlx5e_getmaxrate(struct mlx5e_priv *priv) 112cfc9c386SHans Petter Selasky { 113cfc9c386SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 114cfc9c386SHans Petter Selasky u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS]; 115cfc9c386SHans Petter Selasky u8 max_bw_value[IEEE_8021QAZ_MAX_TCS]; 116cfc9c386SHans Petter Selasky int err; 117cfc9c386SHans Petter Selasky int i; 118cfc9c386SHans Petter Selasky 119cfc9c386SHans Petter Selasky PRIV_LOCK(priv); 120cfc9c386SHans Petter Selasky err = -mlx5_query_port_tc_rate_limit(mdev, max_bw_value, max_bw_unit); 121cfc9c386SHans Petter Selasky if (err) 122cfc9c386SHans Petter Selasky goto done; 123cfc9c386SHans Petter Selasky 124cfc9c386SHans Petter Selasky for (i = 0; i <= mlx5_max_tc(mdev); i++) { 125cfc9c386SHans Petter Selasky switch (max_bw_unit[i]) { 126cfc9c386SHans Petter Selasky case MLX5_100_MBPS_UNIT: 127cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = max_bw_value[i] * MLX5E_100MB; 128cfc9c386SHans Petter Selasky break; 129cfc9c386SHans Petter Selasky case MLX5_GBPS_UNIT: 130cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = max_bw_value[i] * MLX5E_1GB; 131cfc9c386SHans Petter Selasky break; 132cfc9c386SHans Petter Selasky case MLX5_BW_NO_LIMIT: 133cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = 0; 134cfc9c386SHans Petter Selasky break; 135cfc9c386SHans Petter Selasky default: 136cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = -1; 137cfc9c386SHans Petter Selasky WARN_ONCE(true, "non-supported BW unit"); 138cfc9c386SHans Petter Selasky break; 139cfc9c386SHans Petter Selasky } 140cfc9c386SHans Petter Selasky } 141cfc9c386SHans Petter Selasky done: 142cfc9c386SHans Petter Selasky PRIV_UNLOCK(priv); 143cfc9c386SHans Petter Selasky return (err); 144cfc9c386SHans Petter Selasky } 145cfc9c386SHans Petter Selasky 146cfc9c386SHans Petter Selasky static int 147e870c0abSSlava Shwartsman mlx5e_get_max_alloc(struct mlx5e_priv *priv) 148e870c0abSSlava Shwartsman { 149e870c0abSSlava Shwartsman struct mlx5_core_dev *mdev = priv->mdev; 150e870c0abSSlava Shwartsman int err; 151e870c0abSSlava Shwartsman int x; 152e870c0abSSlava Shwartsman 153e870c0abSSlava Shwartsman PRIV_LOCK(priv); 154e870c0abSSlava Shwartsman err = -mlx5_query_port_tc_bw_alloc(mdev, priv->params_ethtool.max_bw_share); 155e870c0abSSlava Shwartsman if (err == 0) { 156e870c0abSSlava Shwartsman /* set default value */ 157e870c0abSSlava Shwartsman for (x = 0; x != IEEE_8021QAZ_MAX_TCS; x++) { 158e870c0abSSlava Shwartsman priv->params_ethtool.max_bw_share[x] = 159e870c0abSSlava Shwartsman 100 / IEEE_8021QAZ_MAX_TCS; 160e870c0abSSlava Shwartsman } 161e870c0abSSlava Shwartsman err = -mlx5_set_port_tc_bw_alloc(mdev, 162e870c0abSSlava Shwartsman priv->params_ethtool.max_bw_share); 163e870c0abSSlava Shwartsman } 164e870c0abSSlava Shwartsman PRIV_UNLOCK(priv); 165e870c0abSSlava Shwartsman 166e870c0abSSlava Shwartsman return (err); 167e870c0abSSlava Shwartsman } 168e870c0abSSlava Shwartsman 169e870c0abSSlava Shwartsman static int 170ed0cee0bSHans Petter Selasky mlx5e_get_dscp(struct mlx5e_priv *priv) 171ed0cee0bSHans Petter Selasky { 172ed0cee0bSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 173ed0cee0bSHans Petter Selasky int err; 174ed0cee0bSHans Petter Selasky 175ed0cee0bSHans Petter Selasky if (MLX5_CAP_GEN(mdev, qcam_reg) == 0 || 176ed0cee0bSHans Petter Selasky MLX5_CAP_QCAM_REG(mdev, qpts) == 0 || 177ed0cee0bSHans Petter Selasky MLX5_CAP_QCAM_REG(mdev, qpdpm) == 0) 178ed0cee0bSHans Petter Selasky return (EOPNOTSUPP); 179ed0cee0bSHans Petter Selasky 180ed0cee0bSHans Petter Selasky PRIV_LOCK(priv); 181ed0cee0bSHans Petter Selasky err = -mlx5_query_dscp2prio(mdev, priv->params_ethtool.dscp2prio); 182ed0cee0bSHans Petter Selasky if (err) 183ed0cee0bSHans Petter Selasky goto done; 184ed0cee0bSHans Petter Selasky 185ed0cee0bSHans Petter Selasky err = -mlx5_query_trust_state(mdev, &priv->params_ethtool.trust_state); 186ed0cee0bSHans Petter Selasky if (err) 187ed0cee0bSHans Petter Selasky goto done; 188ed0cee0bSHans Petter Selasky done: 189ed0cee0bSHans Petter Selasky PRIV_UNLOCK(priv); 190ed0cee0bSHans Petter Selasky return (err); 191ed0cee0bSHans Petter Selasky } 192ed0cee0bSHans Petter Selasky 193e870c0abSSlava Shwartsman static void 194e870c0abSSlava Shwartsman mlx5e_tc_get_parameters(struct mlx5e_priv *priv, 195e870c0abSSlava Shwartsman u64 *new_bw_value, u8 *max_bw_value, u8 *max_bw_unit) 196e870c0abSSlava Shwartsman { 197e870c0abSSlava Shwartsman const u64 upper_limit_mbps = 255 * MLX5E_100MB; 198e870c0abSSlava Shwartsman const u64 upper_limit_gbps = 255 * MLX5E_1GB; 199e870c0abSSlava Shwartsman u64 temp; 200e870c0abSSlava Shwartsman int i; 201e870c0abSSlava Shwartsman 202e870c0abSSlava Shwartsman memset(max_bw_value, 0, IEEE_8021QAZ_MAX_TCS); 203e870c0abSSlava Shwartsman memset(max_bw_unit, 0, IEEE_8021QAZ_MAX_TCS); 204e870c0abSSlava Shwartsman 205e870c0abSSlava Shwartsman for (i = 0; i <= mlx5_max_tc(priv->mdev); i++) { 206e870c0abSSlava Shwartsman temp = (new_bw_value != NULL) ? 207e870c0abSSlava Shwartsman new_bw_value[i] : priv->params_ethtool.max_bw_value[i]; 208e870c0abSSlava Shwartsman 209e870c0abSSlava Shwartsman if (!temp) { 210e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_BW_NO_LIMIT; 211e870c0abSSlava Shwartsman } else if (temp > upper_limit_gbps) { 212e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_BW_NO_LIMIT; 213e870c0abSSlava Shwartsman } else if (temp <= upper_limit_mbps) { 214e870c0abSSlava Shwartsman max_bw_value[i] = howmany(temp, MLX5E_100MB); 215e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_100_MBPS_UNIT; 216e870c0abSSlava Shwartsman } else { 217e870c0abSSlava Shwartsman max_bw_value[i] = howmany(temp, MLX5E_1GB); 218e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_GBPS_UNIT; 219e870c0abSSlava Shwartsman } 220e870c0abSSlava Shwartsman } 221e870c0abSSlava Shwartsman } 222e870c0abSSlava Shwartsman 223ed0cee0bSHans Petter Selasky static int 224cfc9c386SHans Petter Selasky mlx5e_tc_maxrate_handler(SYSCTL_HANDLER_ARGS) 225cfc9c386SHans Petter Selasky { 226cfc9c386SHans Petter Selasky struct mlx5e_priv *priv = arg1; 227cfc9c386SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 228cfc9c386SHans Petter Selasky u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS]; 229cfc9c386SHans Petter Selasky u8 max_bw_value[IEEE_8021QAZ_MAX_TCS]; 230e870c0abSSlava Shwartsman u64 new_bw_value[IEEE_8021QAZ_MAX_TCS]; 231e870c0abSSlava Shwartsman u8 max_rates = mlx5_max_tc(mdev) + 1; 232e870c0abSSlava Shwartsman u8 x; 233e870c0abSSlava Shwartsman int err; 234cfc9c386SHans Petter Selasky 235cfc9c386SHans Petter Selasky PRIV_LOCK(priv); 236e870c0abSSlava Shwartsman err = SYSCTL_OUT(req, priv->params_ethtool.max_bw_value, 237e870c0abSSlava Shwartsman sizeof(priv->params_ethtool.max_bw_value[0]) * max_rates); 238e870c0abSSlava Shwartsman if (err || !req->newptr) 239e870c0abSSlava Shwartsman goto done; 240e870c0abSSlava Shwartsman err = SYSCTL_IN(req, new_bw_value, 241e870c0abSSlava Shwartsman sizeof(new_bw_value[0]) * max_rates); 242e870c0abSSlava Shwartsman if (err) 243cfc9c386SHans Petter Selasky goto done; 244cfc9c386SHans Petter Selasky 245e870c0abSSlava Shwartsman /* range check input value */ 246e870c0abSSlava Shwartsman for (x = 0; x != max_rates; x++) { 247e870c0abSSlava Shwartsman if (new_bw_value[x] % MLX5E_100MB) { 248cfc9c386SHans Petter Selasky err = ERANGE; 249cfc9c386SHans Petter Selasky goto done; 250cfc9c386SHans Petter Selasky } 251cfc9c386SHans Petter Selasky } 252e870c0abSSlava Shwartsman 253e870c0abSSlava Shwartsman mlx5e_tc_get_parameters(priv, new_bw_value, max_bw_value, max_bw_unit); 254cfc9c386SHans Petter Selasky 255cfc9c386SHans Petter Selasky err = -mlx5_modify_port_tc_rate_limit(mdev, max_bw_value, max_bw_unit); 256cfc9c386SHans Petter Selasky if (err) 257cfc9c386SHans Petter Selasky goto done; 258cfc9c386SHans Petter Selasky 259e870c0abSSlava Shwartsman memcpy(priv->params_ethtool.max_bw_value, new_bw_value, 260e870c0abSSlava Shwartsman sizeof(priv->params_ethtool.max_bw_value)); 261e870c0abSSlava Shwartsman done: 262e870c0abSSlava Shwartsman PRIV_UNLOCK(priv); 263e870c0abSSlava Shwartsman return (err); 264e870c0abSSlava Shwartsman } 265e870c0abSSlava Shwartsman 266e870c0abSSlava Shwartsman static int 267e870c0abSSlava Shwartsman mlx5e_tc_rate_share_handler(SYSCTL_HANDLER_ARGS) 268e870c0abSSlava Shwartsman { 269e870c0abSSlava Shwartsman struct mlx5e_priv *priv = arg1; 270e870c0abSSlava Shwartsman struct mlx5_core_dev *mdev = priv->mdev; 271e870c0abSSlava Shwartsman u8 max_bw_share[IEEE_8021QAZ_MAX_TCS]; 272e870c0abSSlava Shwartsman u8 max_rates = mlx5_max_tc(mdev) + 1; 273e870c0abSSlava Shwartsman int i; 274e870c0abSSlava Shwartsman int err; 275e870c0abSSlava Shwartsman int sum; 276e870c0abSSlava Shwartsman 277e870c0abSSlava Shwartsman PRIV_LOCK(priv); 278e870c0abSSlava Shwartsman err = SYSCTL_OUT(req, priv->params_ethtool.max_bw_share, max_rates); 279e870c0abSSlava Shwartsman if (err || !req->newptr) 280e870c0abSSlava Shwartsman goto done; 281e870c0abSSlava Shwartsman err = SYSCTL_IN(req, max_bw_share, max_rates); 282e870c0abSSlava Shwartsman if (err) 283e870c0abSSlava Shwartsman goto done; 284e870c0abSSlava Shwartsman 285e870c0abSSlava Shwartsman /* range check input value */ 286e870c0abSSlava Shwartsman for (sum = i = 0; i != max_rates; i++) { 287e870c0abSSlava Shwartsman if (max_bw_share[i] < 1 || max_bw_share[i] > 100) { 288e870c0abSSlava Shwartsman err = ERANGE; 289e870c0abSSlava Shwartsman goto done; 290e870c0abSSlava Shwartsman } 291e870c0abSSlava Shwartsman sum += max_bw_share[i]; 292e870c0abSSlava Shwartsman } 293e870c0abSSlava Shwartsman 294e870c0abSSlava Shwartsman /* sum of values should be as close to 100 as possible */ 295e870c0abSSlava Shwartsman if (sum < (100 - max_rates + 1) || sum > 100) { 296e870c0abSSlava Shwartsman err = ERANGE; 297e870c0abSSlava Shwartsman goto done; 298e870c0abSSlava Shwartsman } 299e870c0abSSlava Shwartsman 300e870c0abSSlava Shwartsman err = -mlx5_set_port_tc_bw_alloc(mdev, max_bw_share); 301e870c0abSSlava Shwartsman if (err) 302e870c0abSSlava Shwartsman goto done; 303e870c0abSSlava Shwartsman 304e870c0abSSlava Shwartsman memcpy(priv->params_ethtool.max_bw_share, max_bw_share, 305e870c0abSSlava Shwartsman sizeof(priv->params_ethtool.max_bw_share)); 306cfc9c386SHans Petter Selasky done: 307cfc9c386SHans Petter Selasky PRIV_UNLOCK(priv); 308cfc9c386SHans Petter Selasky return (err); 309cfc9c386SHans Petter Selasky } 310cfc9c386SHans Petter Selasky 3112e9c3a4fSHans Petter Selasky static int 3122e9c3a4fSHans Petter Selasky mlx5e_get_prio_tc(struct mlx5e_priv *priv) 3132e9c3a4fSHans Petter Selasky { 3142e9c3a4fSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 3152e9c3a4fSHans Petter Selasky int err = 0; 3162e9c3a4fSHans Petter Selasky int i; 3172e9c3a4fSHans Petter Selasky 3182e9c3a4fSHans Petter Selasky PRIV_LOCK(priv); 3192e9c3a4fSHans Petter Selasky if (!MLX5_CAP_GEN(priv->mdev, ets)) { 3202e9c3a4fSHans Petter Selasky PRIV_UNLOCK(priv); 3212e9c3a4fSHans Petter Selasky return (EOPNOTSUPP); 3222e9c3a4fSHans Petter Selasky } 3232e9c3a4fSHans Petter Selasky 32424385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) { 32524385321SHans Petter Selasky err = -mlx5_query_port_prio_tc(mdev, i, priv->params_ethtool.prio_tc + i); 3262e9c3a4fSHans Petter Selasky if (err) 3272e9c3a4fSHans Petter Selasky break; 3282e9c3a4fSHans Petter Selasky } 3292e9c3a4fSHans Petter Selasky PRIV_UNLOCK(priv); 3302e9c3a4fSHans Petter Selasky return (err); 3312e9c3a4fSHans Petter Selasky } 3322e9c3a4fSHans Petter Selasky 3332e9c3a4fSHans Petter Selasky static int 3342e9c3a4fSHans Petter Selasky mlx5e_prio_to_tc_handler(SYSCTL_HANDLER_ARGS) 3352e9c3a4fSHans Petter Selasky { 3362e9c3a4fSHans Petter Selasky struct mlx5e_priv *priv = arg1; 3372e9c3a4fSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 33824385321SHans Petter Selasky uint8_t temp[MLX5E_MAX_PRIORITY]; 3392e9c3a4fSHans Petter Selasky int err; 34024385321SHans Petter Selasky int i; 3412e9c3a4fSHans Petter Selasky 3422e9c3a4fSHans Petter Selasky PRIV_LOCK(priv); 34324385321SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.prio_tc, MLX5E_MAX_PRIORITY); 34424385321SHans Petter Selasky if (err || !req->newptr) 3452e9c3a4fSHans Petter Selasky goto done; 34624385321SHans Petter Selasky err = SYSCTL_IN(req, temp, MLX5E_MAX_PRIORITY); 3472e9c3a4fSHans Petter Selasky if (err) 3482e9c3a4fSHans Petter Selasky goto done; 3492e9c3a4fSHans Petter Selasky 35024385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) { 35124385321SHans Petter Selasky if (temp[i] > mlx5_max_tc(mdev)) { 35224385321SHans Petter Selasky err = ERANGE; 35324385321SHans Petter Selasky goto done; 35424385321SHans Petter Selasky } 35524385321SHans Petter Selasky } 3562e9c3a4fSHans Petter Selasky 35724385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) { 35824385321SHans Petter Selasky if (temp[i] == priv->params_ethtool.prio_tc[i]) 35924385321SHans Petter Selasky continue; 36024385321SHans Petter Selasky err = -mlx5_set_port_prio_tc(mdev, i, temp[i]); 36124385321SHans Petter Selasky if (err) 36224385321SHans Petter Selasky goto done; 36324385321SHans Petter Selasky /* update cached value */ 36424385321SHans Petter Selasky priv->params_ethtool.prio_tc[i] = temp[i]; 36524385321SHans Petter Selasky } 3662e9c3a4fSHans Petter Selasky done: 3672e9c3a4fSHans Petter Selasky PRIV_UNLOCK(priv); 3682e9c3a4fSHans Petter Selasky return (err); 3692e9c3a4fSHans Petter Selasky } 3702e9c3a4fSHans Petter Selasky 37196425f44SHans Petter Selasky int 37296425f44SHans Petter Selasky mlx5e_fec_update(struct mlx5e_priv *priv) 37396425f44SHans Petter Selasky { 37496425f44SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 37596425f44SHans Petter Selasky u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; 37696425f44SHans Petter Selasky const int sz = MLX5_ST_SZ_BYTES(pplm_reg); 37796425f44SHans Petter Selasky int err; 37896425f44SHans Petter Selasky 37996425f44SHans Petter Selasky if (!MLX5_CAP_GEN(mdev, pcam_reg)) 38096425f44SHans Petter Selasky return (EOPNOTSUPP); 38196425f44SHans Petter Selasky 38296425f44SHans Petter Selasky if (!MLX5_CAP_PCAM_REG(mdev, pplm)) 38396425f44SHans Petter Selasky return (EOPNOTSUPP); 38496425f44SHans Petter Selasky 38596425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 38696425f44SHans Petter Selasky 38796425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, in, sz, MLX5_REG_PPLM, 0, 0); 38896425f44SHans Petter Selasky if (err) 38996425f44SHans Petter Selasky return (err); 39096425f44SHans Petter Selasky 39196425f44SHans Petter Selasky /* get 10x..25x mask */ 39296425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[0] = 39396425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_10g_40g); 39496425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[1] = 39596425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_25g) & 39696425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_50g); 39796425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[2] = 39896425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_56g); 39996425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[3] = 40096425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_100g); 40196425f44SHans Petter Selasky 40296425f44SHans Petter Selasky /* get 10x..25x available bits */ 40396425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[0] = 40496425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_10g_40g); 40596425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[1] = 40696425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_25g) & 40796425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_50g); 40896425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[2] = 40996425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_56g); 41096425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[3] = 41196425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_100g); 41296425f44SHans Petter Selasky 41396425f44SHans Petter Selasky /* get 50x mask */ 41496425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[0] = 41596425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_50g_1x); 41696425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[1] = 41796425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_100g_2x); 41896425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[2] = 41996425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_200g_4x); 42096425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[3] = 42196425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_400g_8x); 42296425f44SHans Petter Selasky 42396425f44SHans Petter Selasky /* get 50x available bits */ 42496425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[0] = 42596425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_50g_1x); 42696425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[1] = 42796425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_100g_2x); 42896425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[2] = 42996425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_200g_4x); 43096425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[3] = 43196425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_400g_8x); 43296425f44SHans Petter Selasky 43396425f44SHans Petter Selasky /* get current FEC mask */ 43496425f44SHans Petter Selasky priv->params_ethtool.fec_mode_active = 43596425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_mode_active); 43696425f44SHans Petter Selasky 43796425f44SHans Petter Selasky return (0); 43896425f44SHans Petter Selasky } 43996425f44SHans Petter Selasky 44096425f44SHans Petter Selasky static int 44196425f44SHans Petter Selasky mlx5e_fec_mask_10x_25x_handler(SYSCTL_HANDLER_ARGS) 44296425f44SHans Petter Selasky { 44396425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1; 44496425f44SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 44596425f44SHans Petter Selasky u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {}; 44696425f44SHans Petter Selasky u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; 44796425f44SHans Petter Selasky const int sz = MLX5_ST_SZ_BYTES(pplm_reg); 44896425f44SHans Petter Selasky u8 fec_mask_10x_25x[MLX5E_MAX_FEC_10X_25X]; 44996425f44SHans Petter Selasky u8 fec_cap_changed = 0; 45096425f44SHans Petter Selasky u8 x; 45196425f44SHans Petter Selasky int err; 45296425f44SHans Petter Selasky 45396425f44SHans Petter Selasky PRIV_LOCK(priv); 45496425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_mask_10x_25x, 45596425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_10x_25x)); 45696425f44SHans Petter Selasky if (err || !req->newptr) 45796425f44SHans Petter Selasky goto done; 45896425f44SHans Petter Selasky 45996425f44SHans Petter Selasky err = SYSCTL_IN(req, fec_mask_10x_25x, 46096425f44SHans Petter Selasky sizeof(fec_mask_10x_25x)); 46196425f44SHans Petter Selasky if (err) 46296425f44SHans Petter Selasky goto done; 46396425f44SHans Petter Selasky 46496425f44SHans Petter Selasky if (!MLX5_CAP_GEN(mdev, pcam_reg)) { 46596425f44SHans Petter Selasky err = EOPNOTSUPP; 46696425f44SHans Petter Selasky goto done; 46796425f44SHans Petter Selasky } 46896425f44SHans Petter Selasky 46996425f44SHans Petter Selasky if (!MLX5_CAP_PCAM_REG(mdev, pplm)) { 47096425f44SHans Petter Selasky err = EOPNOTSUPP; 47196425f44SHans Petter Selasky goto done; 47296425f44SHans Petter Selasky } 47396425f44SHans Petter Selasky 47496425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 47596425f44SHans Petter Selasky 47696425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, in, sz, MLX5_REG_PPLM, 0, 0); 47796425f44SHans Petter Selasky if (err) 47896425f44SHans Petter Selasky goto done; 47996425f44SHans Petter Selasky 48096425f44SHans Petter Selasky /* range check input value */ 48196425f44SHans Petter Selasky for (x = 0; x != MLX5E_MAX_FEC_10X_25X; x++) { 48296425f44SHans Petter Selasky /* check only one bit is set, if any */ 48396425f44SHans Petter Selasky if (fec_mask_10x_25x[x] & (fec_mask_10x_25x[x] - 1)) { 48496425f44SHans Petter Selasky err = ERANGE; 48596425f44SHans Petter Selasky goto done; 48696425f44SHans Petter Selasky } 48796425f44SHans Petter Selasky /* check a supported bit is set, if any */ 48896425f44SHans Petter Selasky if (fec_mask_10x_25x[x] & 48996425f44SHans Petter Selasky ~priv->params_ethtool.fec_avail_10x_25x[x]) { 49096425f44SHans Petter Selasky err = ERANGE; 49196425f44SHans Petter Selasky goto done; 49296425f44SHans Petter Selasky } 49396425f44SHans Petter Selasky fec_cap_changed |= (fec_mask_10x_25x[x] ^ 49496425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[x]); 49596425f44SHans Petter Selasky } 49696425f44SHans Petter Selasky 49796425f44SHans Petter Selasky /* check for no changes */ 49896425f44SHans Petter Selasky if (fec_cap_changed == 0) 49996425f44SHans Petter Selasky goto done; 50096425f44SHans Petter Selasky 50196425f44SHans Petter Selasky memset(in, 0, sizeof(in)); 50296425f44SHans Petter Selasky 50396425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 50496425f44SHans Petter Selasky 50596425f44SHans Petter Selasky /* set new values */ 50696425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_10g_40g, fec_mask_10x_25x[0]); 50796425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_25g, fec_mask_10x_25x[1]); 50896425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g, fec_mask_10x_25x[1]); 50996425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_56g, fec_mask_10x_25x[2]); 51096425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g, fec_mask_10x_25x[3]); 51196425f44SHans Petter Selasky 51296425f44SHans Petter Selasky /* preserve other values */ 51396425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g_1x, priv->params_ethtool.fec_mask_50x[0]); 51496425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g_2x, priv->params_ethtool.fec_mask_50x[1]); 51596425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_200g_4x, priv->params_ethtool.fec_mask_50x[2]); 51696425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_400g_8x, priv->params_ethtool.fec_mask_50x[3]); 51796425f44SHans Petter Selasky 51896425f44SHans Petter Selasky /* send new value to the firmware */ 51996425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPLM, 0, 1); 52096425f44SHans Petter Selasky if (err) 52196425f44SHans Petter Selasky goto done; 52296425f44SHans Petter Selasky 52396425f44SHans Petter Selasky memcpy(priv->params_ethtool.fec_mask_10x_25x, fec_mask_10x_25x, 52496425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_10x_25x)); 52596425f44SHans Petter Selasky 52696425f44SHans Petter Selasky mlx5_toggle_port_link(priv->mdev); 52796425f44SHans Petter Selasky done: 52896425f44SHans Petter Selasky PRIV_UNLOCK(priv); 52996425f44SHans Petter Selasky return (err); 53096425f44SHans Petter Selasky } 53196425f44SHans Petter Selasky 53296425f44SHans Petter Selasky static int 53396425f44SHans Petter Selasky mlx5e_fec_avail_10x_25x_handler(SYSCTL_HANDLER_ARGS) 53496425f44SHans Petter Selasky { 53596425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1; 53696425f44SHans Petter Selasky int err; 53796425f44SHans Petter Selasky 53896425f44SHans Petter Selasky PRIV_LOCK(priv); 53996425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_avail_10x_25x, 54096425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_avail_10x_25x)); 54196425f44SHans Petter Selasky PRIV_UNLOCK(priv); 54296425f44SHans Petter Selasky return (err); 54396425f44SHans Petter Selasky } 54496425f44SHans Petter Selasky 54596425f44SHans Petter Selasky static int 54696425f44SHans Petter Selasky mlx5e_fec_mask_50x_handler(SYSCTL_HANDLER_ARGS) 54796425f44SHans Petter Selasky { 54896425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1; 54996425f44SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 55096425f44SHans Petter Selasky u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {}; 55196425f44SHans Petter Selasky u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; 55296425f44SHans Petter Selasky const int sz = MLX5_ST_SZ_BYTES(pplm_reg); 55396425f44SHans Petter Selasky u16 fec_mask_50x[MLX5E_MAX_FEC_50X]; 55496425f44SHans Petter Selasky u16 fec_cap_changed = 0; 55596425f44SHans Petter Selasky u8 x; 55696425f44SHans Petter Selasky int err; 55796425f44SHans Petter Selasky 55896425f44SHans Petter Selasky PRIV_LOCK(priv); 55996425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_mask_50x, 56096425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_50x)); 56196425f44SHans Petter Selasky if (err || !req->newptr) 56296425f44SHans Petter Selasky goto done; 56396425f44SHans Petter Selasky 56496425f44SHans Petter Selasky err = SYSCTL_IN(req, fec_mask_50x, 56596425f44SHans Petter Selasky sizeof(fec_mask_50x)); 56696425f44SHans Petter Selasky if (err) 56796425f44SHans Petter Selasky goto done; 56896425f44SHans Petter Selasky 56996425f44SHans Petter Selasky if (!MLX5_CAP_GEN(mdev, pcam_reg)) { 57096425f44SHans Petter Selasky err = EOPNOTSUPP; 57196425f44SHans Petter Selasky goto done; 57296425f44SHans Petter Selasky } 57396425f44SHans Petter Selasky 57496425f44SHans Petter Selasky if (!MLX5_CAP_PCAM_REG(mdev, pplm)) { 57596425f44SHans Petter Selasky err = EOPNOTSUPP; 57696425f44SHans Petter Selasky goto done; 57796425f44SHans Petter Selasky } 57896425f44SHans Petter Selasky 57996425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 58096425f44SHans Petter Selasky 58196425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, in, sz, MLX5_REG_PPLM, 0, 0); 58296425f44SHans Petter Selasky if (err) 58396425f44SHans Petter Selasky goto done; 58496425f44SHans Petter Selasky 58596425f44SHans Petter Selasky /* range check input value */ 58696425f44SHans Petter Selasky for (x = 0; x != MLX5E_MAX_FEC_50X; x++) { 58796425f44SHans Petter Selasky /* check only one bit is set, if any */ 58896425f44SHans Petter Selasky if (fec_mask_50x[x] & (fec_mask_50x[x] - 1)) { 58996425f44SHans Petter Selasky err = ERANGE; 59096425f44SHans Petter Selasky goto done; 59196425f44SHans Petter Selasky } 59296425f44SHans Petter Selasky /* check a supported bit is set, if any */ 59396425f44SHans Petter Selasky if (fec_mask_50x[x] & 59496425f44SHans Petter Selasky ~priv->params_ethtool.fec_avail_50x[x]) { 59596425f44SHans Petter Selasky err = ERANGE; 59696425f44SHans Petter Selasky goto done; 59796425f44SHans Petter Selasky } 59896425f44SHans Petter Selasky fec_cap_changed |= (fec_mask_50x[x] ^ 59996425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[x]); 60096425f44SHans Petter Selasky } 60196425f44SHans Petter Selasky 60296425f44SHans Petter Selasky /* check for no changes */ 60396425f44SHans Petter Selasky if (fec_cap_changed == 0) 60496425f44SHans Petter Selasky goto done; 60596425f44SHans Petter Selasky 60696425f44SHans Petter Selasky memset(in, 0, sizeof(in)); 60796425f44SHans Petter Selasky 60896425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1); 60996425f44SHans Petter Selasky 61096425f44SHans Petter Selasky /* set new values */ 61196425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g_1x, fec_mask_50x[0]); 61296425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g_2x, fec_mask_50x[1]); 61396425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_200g_4x, fec_mask_50x[2]); 61496425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_400g_8x, fec_mask_50x[3]); 61596425f44SHans Petter Selasky 61696425f44SHans Petter Selasky /* preserve other values */ 61796425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_10g_40g, priv->params_ethtool.fec_mask_10x_25x[0]); 61896425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_25g, priv->params_ethtool.fec_mask_10x_25x[1]); 61996425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g, priv->params_ethtool.fec_mask_10x_25x[1]); 62096425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_56g, priv->params_ethtool.fec_mask_10x_25x[2]); 62196425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g, priv->params_ethtool.fec_mask_10x_25x[3]); 62296425f44SHans Petter Selasky 62396425f44SHans Petter Selasky /* send new value to the firmware */ 62496425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPLM, 0, 1); 62596425f44SHans Petter Selasky if (err) 62696425f44SHans Petter Selasky goto done; 62796425f44SHans Petter Selasky 62896425f44SHans Petter Selasky memcpy(priv->params_ethtool.fec_mask_50x, fec_mask_50x, 62996425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_50x)); 63096425f44SHans Petter Selasky 63196425f44SHans Petter Selasky mlx5_toggle_port_link(priv->mdev); 63296425f44SHans Petter Selasky done: 63396425f44SHans Petter Selasky PRIV_UNLOCK(priv); 63496425f44SHans Petter Selasky return (err); 63596425f44SHans Petter Selasky } 63696425f44SHans Petter Selasky 63796425f44SHans Petter Selasky static int 63896425f44SHans Petter Selasky mlx5e_fec_avail_50x_handler(SYSCTL_HANDLER_ARGS) 63996425f44SHans Petter Selasky { 64096425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1; 64196425f44SHans Petter Selasky int err; 64296425f44SHans Petter Selasky 64396425f44SHans Petter Selasky PRIV_LOCK(priv); 64496425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_avail_50x, 64596425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_avail_50x)); 64696425f44SHans Petter Selasky PRIV_UNLOCK(priv); 64796425f44SHans Petter Selasky return (err); 64896425f44SHans Petter Selasky } 64996425f44SHans Petter Selasky 650ed0cee0bSHans Petter Selasky static int 651ed0cee0bSHans Petter Selasky mlx5e_trust_state_handler(SYSCTL_HANDLER_ARGS) 652ed0cee0bSHans Petter Selasky { 653ed0cee0bSHans Petter Selasky struct mlx5e_priv *priv = arg1; 654ed0cee0bSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 655ed0cee0bSHans Petter Selasky int err; 656ed0cee0bSHans Petter Selasky u8 result; 657ed0cee0bSHans Petter Selasky 658ed0cee0bSHans Petter Selasky PRIV_LOCK(priv); 659ed0cee0bSHans Petter Selasky result = priv->params_ethtool.trust_state; 660ed0cee0bSHans Petter Selasky err = sysctl_handle_8(oidp, &result, 0, req); 661ed0cee0bSHans Petter Selasky if (err || !req->newptr || 662ed0cee0bSHans Petter Selasky result == priv->params_ethtool.trust_state) 663ed0cee0bSHans Petter Selasky goto done; 664ed0cee0bSHans Petter Selasky 665ed0cee0bSHans Petter Selasky switch (result) { 666ed0cee0bSHans Petter Selasky case MLX5_QPTS_TRUST_PCP: 667ed0cee0bSHans Petter Selasky case MLX5_QPTS_TRUST_DSCP: 668ed0cee0bSHans Petter Selasky break; 669ed0cee0bSHans Petter Selasky case MLX5_QPTS_TRUST_BOTH: 670ed0cee0bSHans Petter Selasky if (!MLX5_CAP_QCAM_FEATURE(mdev, qpts_trust_both)) { 671ed0cee0bSHans Petter Selasky err = EOPNOTSUPP; 672ed0cee0bSHans Petter Selasky goto done; 673ed0cee0bSHans Petter Selasky } 674ed0cee0bSHans Petter Selasky break; 675ed0cee0bSHans Petter Selasky default: 676ed0cee0bSHans Petter Selasky err = ERANGE; 677ed0cee0bSHans Petter Selasky goto done; 678ed0cee0bSHans Petter Selasky } 679ed0cee0bSHans Petter Selasky 680ed0cee0bSHans Petter Selasky err = -mlx5_set_trust_state(mdev, result); 681ed0cee0bSHans Petter Selasky if (err) 682ed0cee0bSHans Petter Selasky goto done; 683ed0cee0bSHans Petter Selasky 684ed0cee0bSHans Petter Selasky priv->params_ethtool.trust_state = result; 6853e581cabSSlava Shwartsman 6863e581cabSSlava Shwartsman /* update inline mode */ 6873e581cabSSlava Shwartsman mlx5e_refresh_sq_inline(priv); 6883e581cabSSlava Shwartsman #ifdef RATELIMIT 6893e581cabSSlava Shwartsman mlx5e_rl_refresh_sq_inline(&priv->rl); 6903e581cabSSlava Shwartsman #endif 691ed0cee0bSHans Petter Selasky done: 692ed0cee0bSHans Petter Selasky PRIV_UNLOCK(priv); 693ed0cee0bSHans Petter Selasky return (err); 694ed0cee0bSHans Petter Selasky } 695ed0cee0bSHans Petter Selasky 696ed0cee0bSHans Petter Selasky static int 697ed0cee0bSHans Petter Selasky mlx5e_dscp_prio_handler(SYSCTL_HANDLER_ARGS) 698ed0cee0bSHans Petter Selasky { 699ed0cee0bSHans Petter Selasky struct mlx5e_priv *priv = arg1; 700ed0cee0bSHans Petter Selasky int prio_index = arg2; 701ed0cee0bSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 702ed0cee0bSHans Petter Selasky uint8_t dscp2prio[MLX5_MAX_SUPPORTED_DSCP]; 703ed0cee0bSHans Petter Selasky uint8_t x; 704ed0cee0bSHans Petter Selasky int err; 705ed0cee0bSHans Petter Selasky 706ed0cee0bSHans Petter Selasky PRIV_LOCK(priv); 707ed0cee0bSHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.dscp2prio + prio_index, 708ed0cee0bSHans Petter Selasky sizeof(priv->params_ethtool.dscp2prio) / 8); 709ed0cee0bSHans Petter Selasky if (err || !req->newptr) 710ed0cee0bSHans Petter Selasky goto done; 711ed0cee0bSHans Petter Selasky 712ed0cee0bSHans Petter Selasky memcpy(dscp2prio, priv->params_ethtool.dscp2prio, sizeof(dscp2prio)); 713ed0cee0bSHans Petter Selasky err = SYSCTL_IN(req, dscp2prio + prio_index, sizeof(dscp2prio) / 8); 714ed0cee0bSHans Petter Selasky if (err) 715ed0cee0bSHans Petter Selasky goto done; 716ed0cee0bSHans Petter Selasky for (x = 0; x != MLX5_MAX_SUPPORTED_DSCP; x++) { 717ed0cee0bSHans Petter Selasky if (dscp2prio[x] > 7) { 718ed0cee0bSHans Petter Selasky err = ERANGE; 719ed0cee0bSHans Petter Selasky goto done; 720ed0cee0bSHans Petter Selasky } 721ed0cee0bSHans Petter Selasky } 722ed0cee0bSHans Petter Selasky err = -mlx5_set_dscp2prio(mdev, dscp2prio); 723ed0cee0bSHans Petter Selasky if (err) 724ed0cee0bSHans Petter Selasky goto done; 725ed0cee0bSHans Petter Selasky 726ed0cee0bSHans Petter Selasky /* update local array */ 727ed0cee0bSHans Petter Selasky memcpy(priv->params_ethtool.dscp2prio, dscp2prio, 728ed0cee0bSHans Petter Selasky sizeof(priv->params_ethtool.dscp2prio)); 729ed0cee0bSHans Petter Selasky done: 730ed0cee0bSHans Petter Selasky PRIV_UNLOCK(priv); 731ed0cee0bSHans Petter Selasky return (err); 732ed0cee0bSHans Petter Selasky } 733ed0cee0bSHans Petter Selasky 7346deb0b1eSHans Petter Selasky int 7356deb0b1eSHans Petter Selasky mlx5e_update_buf_lossy(struct mlx5e_priv *priv) 7366deb0b1eSHans Petter Selasky { 7376deb0b1eSHans Petter Selasky struct ieee_pfc pfc; 7386deb0b1eSHans Petter Selasky 7396deb0b1eSHans Petter Selasky PRIV_ASSERT_LOCKED(priv); 7406deb0b1eSHans Petter Selasky bzero(&pfc, sizeof(pfc)); 7416deb0b1eSHans Petter Selasky pfc.pfc_en = priv->params.rx_priority_flow_control; 7426deb0b1eSHans Petter Selasky return (-mlx5e_port_manual_buffer_config(priv, MLX5E_PORT_BUFFER_PFC, 7436deb0b1eSHans Petter Selasky priv->params_ethtool.hw_mtu, &pfc, NULL, NULL)); 7446deb0b1eSHans Petter Selasky } 7456deb0b1eSHans Petter Selasky 7466deb0b1eSHans Petter Selasky static int 7476deb0b1eSHans Petter Selasky mlx5e_buf_size_handler(SYSCTL_HANDLER_ARGS) 7486deb0b1eSHans Petter Selasky { 7496deb0b1eSHans Petter Selasky struct mlx5e_priv *priv; 7506deb0b1eSHans Petter Selasky u32 buf_size[MLX5E_MAX_BUFFER]; 7516deb0b1eSHans Petter Selasky struct mlx5e_port_buffer port_buffer; 7526deb0b1eSHans Petter Selasky int error, i; 7536deb0b1eSHans Petter Selasky 7546deb0b1eSHans Petter Selasky priv = arg1; 7556deb0b1eSHans Petter Selasky PRIV_LOCK(priv); 7566deb0b1eSHans Petter Selasky error = -mlx5e_port_query_buffer(priv, &port_buffer); 7576deb0b1eSHans Petter Selasky if (error != 0) 7586deb0b1eSHans Petter Selasky goto done; 7596deb0b1eSHans Petter Selasky for (i = 0; i < nitems(buf_size); i++) 7606deb0b1eSHans Petter Selasky buf_size[i] = port_buffer.buffer[i].size; 7616deb0b1eSHans Petter Selasky error = SYSCTL_OUT(req, buf_size, sizeof(buf_size)); 7626deb0b1eSHans Petter Selasky if (error != 0 || req->newptr == NULL) 7636deb0b1eSHans Petter Selasky goto done; 7646deb0b1eSHans Petter Selasky error = SYSCTL_IN(req, buf_size, sizeof(buf_size)); 7656deb0b1eSHans Petter Selasky if (error != 0) 7666deb0b1eSHans Petter Selasky goto done; 7676deb0b1eSHans Petter Selasky error = -mlx5e_port_manual_buffer_config(priv, MLX5E_PORT_BUFFER_SIZE, 7686deb0b1eSHans Petter Selasky priv->params_ethtool.hw_mtu, NULL, buf_size, NULL); 7696deb0b1eSHans Petter Selasky done: 7706deb0b1eSHans Petter Selasky PRIV_UNLOCK(priv); 7716deb0b1eSHans Petter Selasky return (error); 7726deb0b1eSHans Petter Selasky } 7736deb0b1eSHans Petter Selasky 7746deb0b1eSHans Petter Selasky static int 7756deb0b1eSHans Petter Selasky mlx5e_buf_prio_handler(SYSCTL_HANDLER_ARGS) 7766deb0b1eSHans Petter Selasky { 7776deb0b1eSHans Petter Selasky struct mlx5e_priv *priv; 7786deb0b1eSHans Petter Selasky struct mlx5_core_dev *mdev; 7796deb0b1eSHans Petter Selasky u8 buffer[MLX5E_MAX_BUFFER]; 7806deb0b1eSHans Petter Selasky int error; 7816deb0b1eSHans Petter Selasky 7826deb0b1eSHans Petter Selasky priv = arg1; 7836deb0b1eSHans Petter Selasky mdev = priv->mdev; 7846deb0b1eSHans Petter Selasky PRIV_LOCK(priv); 7856deb0b1eSHans Petter Selasky error = -mlx5e_port_query_priority2buffer(mdev, buffer); 7866deb0b1eSHans Petter Selasky if (error != 0) 7876deb0b1eSHans Petter Selasky goto done; 7886deb0b1eSHans Petter Selasky error = SYSCTL_OUT(req, buffer, MLX5E_MAX_BUFFER); 7896deb0b1eSHans Petter Selasky if (error != 0 || req->newptr == NULL) 7906deb0b1eSHans Petter Selasky goto done; 7916deb0b1eSHans Petter Selasky error = SYSCTL_IN(req, buffer, MLX5E_MAX_BUFFER); 7926deb0b1eSHans Petter Selasky if (error != 0) 7936deb0b1eSHans Petter Selasky goto done; 7946deb0b1eSHans Petter Selasky error = -mlx5e_port_manual_buffer_config(priv, 7956deb0b1eSHans Petter Selasky MLX5E_PORT_BUFFER_PRIO2BUFFER, 7966deb0b1eSHans Petter Selasky priv->params_ethtool.hw_mtu, NULL, NULL, buffer); 7976deb0b1eSHans Petter Selasky if (error == 0) 7986deb0b1eSHans Petter Selasky error = mlx5e_update_buf_lossy(priv); 7996deb0b1eSHans Petter Selasky done: 8006deb0b1eSHans Petter Selasky PRIV_UNLOCK(priv); 8016deb0b1eSHans Petter Selasky return (error); 8026deb0b1eSHans Petter Selasky } 8036deb0b1eSHans Petter Selasky 8046deb0b1eSHans Petter Selasky static int 8056deb0b1eSHans Petter Selasky mlx5e_cable_length_handler(SYSCTL_HANDLER_ARGS) 8066deb0b1eSHans Petter Selasky { 8076deb0b1eSHans Petter Selasky struct mlx5e_priv *priv; 8086deb0b1eSHans Petter Selasky u_int cable_len; 8096deb0b1eSHans Petter Selasky int error; 8106deb0b1eSHans Petter Selasky 8116deb0b1eSHans Petter Selasky priv = arg1; 8126deb0b1eSHans Petter Selasky PRIV_LOCK(priv); 8136deb0b1eSHans Petter Selasky cable_len = priv->dcbx.cable_len; 8146deb0b1eSHans Petter Selasky error = sysctl_handle_int(oidp, &cable_len, 0, req); 8156deb0b1eSHans Petter Selasky if (error == 0 && req->newptr != NULL && 8166deb0b1eSHans Petter Selasky cable_len != priv->dcbx.cable_len) { 8176deb0b1eSHans Petter Selasky error = -mlx5e_port_manual_buffer_config(priv, 8186deb0b1eSHans Petter Selasky MLX5E_PORT_BUFFER_CABLE_LEN, priv->params_ethtool.hw_mtu, 8196deb0b1eSHans Petter Selasky NULL, NULL, NULL); 8206deb0b1eSHans Petter Selasky if (error == 0) 8216deb0b1eSHans Petter Selasky priv->dcbx.cable_len = cable_len; 8226deb0b1eSHans Petter Selasky } 8236deb0b1eSHans Petter Selasky PRIV_UNLOCK(priv); 8246deb0b1eSHans Petter Selasky return (error); 8256deb0b1eSHans Petter Selasky } 8266deb0b1eSHans Petter Selasky 827decb087cSHans Petter Selasky static int 828decb087cSHans Petter Selasky mlx5e_hw_temperature_handler(SYSCTL_HANDLER_ARGS) 829decb087cSHans Petter Selasky { 830decb087cSHans Petter Selasky struct mlx5e_priv *priv = arg1; 831decb087cSHans Petter Selasky int err; 832decb087cSHans Petter Selasky 833decb087cSHans Petter Selasky PRIV_LOCK(priv); 834decb087cSHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.hw_val_temp, 835decb087cSHans Petter Selasky sizeof(priv->params_ethtool.hw_val_temp[0]) * 836decb087cSHans Petter Selasky priv->params_ethtool.hw_num_temp); 837decb087cSHans Petter Selasky if (err == 0 && req->newptr != NULL) 838decb087cSHans Petter Selasky err = EOPNOTSUPP; 839decb087cSHans Petter Selasky PRIV_UNLOCK(priv); 840decb087cSHans Petter Selasky return (err); 841decb087cSHans Petter Selasky } 842decb087cSHans Petter Selasky 843decb087cSHans Petter Selasky int 844decb087cSHans Petter Selasky mlx5e_hw_temperature_update(struct mlx5e_priv *priv) 845decb087cSHans Petter Selasky { 846decb087cSHans Petter Selasky int err; 847decb087cSHans Petter Selasky u32 x; 848decb087cSHans Petter Selasky 849decb087cSHans Petter Selasky if (priv->params_ethtool.hw_num_temp == 0) { 850decb087cSHans Petter Selasky u32 out_cap[MLX5_ST_SZ_DW(mtcap)] = {}; 851decb087cSHans Petter Selasky const int sz_cap = MLX5_ST_SZ_BYTES(mtcap); 852decb087cSHans Petter Selasky u32 value; 853decb087cSHans Petter Selasky 854decb087cSHans Petter Selasky err = -mlx5_core_access_reg(priv->mdev, NULL, 0, out_cap, sz_cap, 855decb087cSHans Petter Selasky MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTCAP, 0, 0); 856decb087cSHans Petter Selasky if (err) 857decb087cSHans Petter Selasky goto done; 858decb087cSHans Petter Selasky value = MLX5_GET(mtcap, out_cap, sensor_count); 859decb087cSHans Petter Selasky if (value == 0) 860decb087cSHans Petter Selasky return (0); 861decb087cSHans Petter Selasky if (value > MLX5_MAX_TEMPERATURE) 862decb087cSHans Petter Selasky value = MLX5_MAX_TEMPERATURE; 863decb087cSHans Petter Selasky /* update number of temperature sensors */ 864decb087cSHans Petter Selasky priv->params_ethtool.hw_num_temp = value; 865decb087cSHans Petter Selasky } 866decb087cSHans Petter Selasky 867decb087cSHans Petter Selasky for (x = 0; x != priv->params_ethtool.hw_num_temp; x++) { 868decb087cSHans Petter Selasky u32 out_sensor[MLX5_ST_SZ_DW(mtmp_reg)] = {}; 869decb087cSHans Petter Selasky const int sz_sensor = MLX5_ST_SZ_BYTES(mtmp_reg); 870decb087cSHans Petter Selasky 871decb087cSHans Petter Selasky MLX5_SET(mtmp_reg, out_sensor, sensor_index, x); 872decb087cSHans Petter Selasky 873decb087cSHans Petter Selasky err = -mlx5_core_access_reg(priv->mdev, out_sensor, sz_sensor, 874decb087cSHans Petter Selasky out_sensor, sz_sensor, 875decb087cSHans Petter Selasky MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTMP, 0, 0); 876decb087cSHans Petter Selasky if (err) 877decb087cSHans Petter Selasky goto done; 8789097ac9aSElyes HAOUAS /* convert from 0.125 celsius to millicelsius */ 879decb087cSHans Petter Selasky priv->params_ethtool.hw_val_temp[x] = 880decb087cSHans Petter Selasky (s16)MLX5_GET(mtmp_reg, out_sensor, temperature) * 125; 881decb087cSHans Petter Selasky } 882decb087cSHans Petter Selasky done: 883decb087cSHans Petter Selasky return (err); 884decb087cSHans Petter Selasky } 885decb087cSHans Petter Selasky 88682d2623eSHans Petter Selasky #define MLX5_PARAM_OFFSET(n) \ 88782d2623eSHans Petter Selasky __offsetof(struct mlx5e_priv, params_ethtool.n) 88882d2623eSHans Petter Selasky 889dc7e38acSHans Petter Selasky static int 890dc7e38acSHans Petter Selasky mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS) 891dc7e38acSHans Petter Selasky { 892dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1; 893dc7e38acSHans Petter Selasky uint64_t value; 894d2bf00a9SHans Petter Selasky int mode_modify; 895dc7e38acSHans Petter Selasky int was_opened; 896dc7e38acSHans Petter Selasky int error; 897dc7e38acSHans Petter Selasky 898dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 899dc7e38acSHans Petter Selasky value = priv->params_ethtool.arg[arg2]; 900ec0143b2SHans Petter Selasky if (req != NULL) { 901dc7e38acSHans Petter Selasky error = sysctl_handle_64(oidp, &value, 0, req); 902dc7e38acSHans Petter Selasky if (error || req->newptr == NULL || 903dc7e38acSHans Petter Selasky value == priv->params_ethtool.arg[arg2]) 904dc7e38acSHans Petter Selasky goto done; 905dc7e38acSHans Petter Selasky 906dc7e38acSHans Petter Selasky /* assign new value */ 907dc7e38acSHans Petter Selasky priv->params_ethtool.arg[arg2] = value; 908ec0143b2SHans Petter Selasky } else { 909ec0143b2SHans Petter Selasky error = 0; 910ec0143b2SHans Petter Selasky } 911dc7e38acSHans Petter Selasky /* check if device is gone */ 912dc7e38acSHans Petter Selasky if (priv->gone) { 913dc7e38acSHans Petter Selasky error = ENXIO; 914dc7e38acSHans Petter Selasky goto done; 915dc7e38acSHans Petter Selasky } 91682d2623eSHans Petter Selasky was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); 917d2bf00a9SHans Petter Selasky mode_modify = MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify); 91882d2623eSHans Petter Selasky 91982d2623eSHans Petter Selasky switch (MLX5_PARAM_OFFSET(arg[arg2])) { 92082d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_usecs): 921f03f517bSHans Petter Selasky /* import RX coal time */ 922f03f517bSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_usecs < 1) 923f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = 0; 924f03f517bSHans Petter Selasky else if (priv->params_ethtool.rx_coalesce_usecs > 925f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period)) { 926f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = 927f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period); 928f03f517bSHans Petter Selasky } 92982d2623eSHans Petter Selasky priv->params.rx_cq_moderation_usec = 93082d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs; 931f03f517bSHans Petter Selasky 93282d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 93382d2623eSHans Petter Selasky if (was_opened) 93482d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 93582d2623eSHans Petter Selasky break; 93682d2623eSHans Petter Selasky 93782d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_pkts): 938f03f517bSHans Petter Selasky /* import RX coal pkts */ 939f03f517bSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_pkts < 1) 940f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = 0; 941f03f517bSHans Petter Selasky else if (priv->params_ethtool.rx_coalesce_pkts > 942f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count)) { 943f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = 944f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count); 945f03f517bSHans Petter Selasky } 94682d2623eSHans Petter Selasky priv->params.rx_cq_moderation_pkts = 94782d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts; 948f03f517bSHans Petter Selasky 94982d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 95082d2623eSHans Petter Selasky if (was_opened) 95182d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 95282d2623eSHans Petter Selasky break; 95382d2623eSHans Petter Selasky 95482d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_usecs): 955f03f517bSHans Petter Selasky /* import TX coal time */ 956f03f517bSHans Petter Selasky if (priv->params_ethtool.tx_coalesce_usecs < 1) 957f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = 0; 958f03f517bSHans Petter Selasky else if (priv->params_ethtool.tx_coalesce_usecs > 959f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period)) { 960f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = 961f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period); 962f03f517bSHans Petter Selasky } 96382d2623eSHans Petter Selasky priv->params.tx_cq_moderation_usec = 96482d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs; 965f03f517bSHans Petter Selasky 96682d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 96782d2623eSHans Petter Selasky if (was_opened) 96882d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 96982d2623eSHans Petter Selasky break; 97082d2623eSHans Petter Selasky 97182d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_pkts): 972f03f517bSHans Petter Selasky /* import TX coal pkts */ 973f03f517bSHans Petter Selasky if (priv->params_ethtool.tx_coalesce_pkts < 1) 974f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = 0; 975f03f517bSHans Petter Selasky else if (priv->params_ethtool.tx_coalesce_pkts > 976f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count)) { 97782d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = 97882d2623eSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count); 979f03f517bSHans Petter Selasky } 98082d2623eSHans Petter Selasky priv->params.tx_cq_moderation_pkts = 98182d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts; 982dc7e38acSHans Petter Selasky 98382d2623eSHans Petter Selasky /* check to avoid down and up the network interface */ 98482d2623eSHans Petter Selasky if (was_opened) 985f03f517bSHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 98682d2623eSHans Petter Selasky break; 98782d2623eSHans Petter Selasky 98882d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_queue_size): 98982d2623eSHans Petter Selasky /* network interface must be down */ 99082d2623eSHans Petter Selasky if (was_opened) 991f03f517bSHans Petter Selasky mlx5e_close_locked(priv->ifp); 99282d2623eSHans Petter Selasky 993dc7e38acSHans Petter Selasky /* import TX queue size */ 994dc7e38acSHans Petter Selasky if (priv->params_ethtool.tx_queue_size < 995dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) { 996dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 997dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE); 998dc7e38acSHans Petter Selasky } else if (priv->params_ethtool.tx_queue_size > 999dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max) { 1000dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 1001dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max; 1002dc7e38acSHans Petter Selasky } 100382d2623eSHans Petter Selasky /* store actual TX queue size */ 1004dc7e38acSHans Petter Selasky priv->params.log_sq_size = 1005dc7e38acSHans Petter Selasky order_base_2(priv->params_ethtool.tx_queue_size); 100682d2623eSHans Petter Selasky priv->params_ethtool.tx_queue_size = 100782d2623eSHans Petter Selasky 1 << priv->params.log_sq_size; 100882d2623eSHans Petter Selasky 100982d2623eSHans Petter Selasky /* verify TX completion factor */ 101082d2623eSHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv); 101182d2623eSHans Petter Selasky 101282d2623eSHans Petter Selasky /* restart network interface, if any */ 101382d2623eSHans Petter Selasky if (was_opened) 101482d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 101582d2623eSHans Petter Selasky break; 101682d2623eSHans Petter Selasky 101782d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_queue_size): 101882d2623eSHans Petter Selasky /* network interface must be down */ 101982d2623eSHans Petter Selasky if (was_opened) 102082d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 1021dc7e38acSHans Petter Selasky 1022dc7e38acSHans Petter Selasky /* import RX queue size */ 1023dc7e38acSHans Petter Selasky if (priv->params_ethtool.rx_queue_size < 1024dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) { 1025dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 1026dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE); 1027dc7e38acSHans Petter Selasky } else if (priv->params_ethtool.rx_queue_size > 1028dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max) { 1029dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 1030dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max; 1031dc7e38acSHans Petter Selasky } 103282d2623eSHans Petter Selasky /* store actual RX queue size */ 1033dc7e38acSHans Petter Selasky priv->params.log_rq_size = 1034dc7e38acSHans Petter Selasky order_base_2(priv->params_ethtool.rx_queue_size); 103582d2623eSHans Petter Selasky priv->params_ethtool.rx_queue_size = 103682d2623eSHans Petter Selasky 1 << priv->params.log_rq_size; 1037dc7e38acSHans Petter Selasky 103882d2623eSHans Petter Selasky /* update least number of RX WQEs */ 103982d2623eSHans Petter Selasky priv->params.min_rx_wqes = min( 1040dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size - 1, 1041dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_MIN_RX_WQES); 1042dc7e38acSHans Petter Selasky 104382d2623eSHans Petter Selasky /* restart network interface, if any */ 104482d2623eSHans Petter Selasky if (was_opened) 104582d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 104682d2623eSHans Petter Selasky break; 104782d2623eSHans Petter Selasky 104816ae32f9SHans Petter Selasky case MLX5_PARAM_OFFSET(channels_rsss): 104916ae32f9SHans Petter Selasky /* network interface must be down */ 105016ae32f9SHans Petter Selasky if (was_opened) 105116ae32f9SHans Petter Selasky mlx5e_close_locked(priv->ifp); 105216ae32f9SHans Petter Selasky 105316ae32f9SHans Petter Selasky /* import number of channels */ 105416ae32f9SHans Petter Selasky if (priv->params_ethtool.channels_rsss < 1) 105516ae32f9SHans Petter Selasky priv->params_ethtool.channels_rsss = 1; 105616ae32f9SHans Petter Selasky else if (priv->params_ethtool.channels_rsss > 128) 105716ae32f9SHans Petter Selasky priv->params_ethtool.channels_rsss = 128; 105816ae32f9SHans Petter Selasky 105916ae32f9SHans Petter Selasky priv->params.channels_rsss = priv->params_ethtool.channels_rsss; 106016ae32f9SHans Petter Selasky 106116ae32f9SHans Petter Selasky /* restart network interface, if any */ 106216ae32f9SHans Petter Selasky if (was_opened) 106316ae32f9SHans Petter Selasky mlx5e_open_locked(priv->ifp); 106416ae32f9SHans Petter Selasky break; 106516ae32f9SHans Petter Selasky 106682d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(channels): 106782d2623eSHans Petter Selasky /* network interface must be down */ 106882d2623eSHans Petter Selasky if (was_opened) 106982d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 107082d2623eSHans Petter Selasky 1071dc7e38acSHans Petter Selasky /* import number of channels */ 1072dc7e38acSHans Petter Selasky if (priv->params_ethtool.channels < 1) 1073dc7e38acSHans Petter Selasky priv->params_ethtool.channels = 1; 1074dc7e38acSHans Petter Selasky else if (priv->params_ethtool.channels > 1075dc7e38acSHans Petter Selasky (u64) priv->mdev->priv.eq_table.num_comp_vectors) { 1076dc7e38acSHans Petter Selasky priv->params_ethtool.channels = 1077dc7e38acSHans Petter Selasky (u64) priv->mdev->priv.eq_table.num_comp_vectors; 1078dc7e38acSHans Petter Selasky } 1079dc7e38acSHans Petter Selasky priv->params.num_channels = priv->params_ethtool.channels; 1080dc7e38acSHans Petter Selasky 108182d2623eSHans Petter Selasky /* restart network interface, if any */ 108282d2623eSHans Petter Selasky if (was_opened) 108382d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 108482d2623eSHans Petter Selasky break; 108582d2623eSHans Petter Selasky 108682d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_mode): 108782d2623eSHans Petter Selasky /* network interface must be down */ 1088d2bf00a9SHans Petter Selasky if (was_opened != 0 && mode_modify == 0) 108982d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 109082d2623eSHans Petter Selasky 109182d2623eSHans Petter Selasky /* import RX coalesce mode */ 1092423530beSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_mode > 3) 1093423530beSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode = 3; 109482d2623eSHans Petter Selasky priv->params.rx_cq_moderation_mode = 109582d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode; 1096dc7e38acSHans Petter Selasky 109782d2623eSHans Petter Selasky /* restart network interface, if any */ 1098d2bf00a9SHans Petter Selasky if (was_opened != 0) { 1099d2bf00a9SHans Petter Selasky if (mode_modify == 0) 110082d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 1101d2bf00a9SHans Petter Selasky else 1102d2bf00a9SHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 1103d2bf00a9SHans Petter Selasky } 110482d2623eSHans Petter Selasky break; 110582d2623eSHans Petter Selasky 110682d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_mode): 110782d2623eSHans Petter Selasky /* network interface must be down */ 1108d2bf00a9SHans Petter Selasky if (was_opened != 0 && mode_modify == 0) 110982d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 111082d2623eSHans Petter Selasky 111182d2623eSHans Petter Selasky /* import TX coalesce mode */ 111274540a31SHans Petter Selasky if (priv->params_ethtool.tx_coalesce_mode != 0) 111374540a31SHans Petter Selasky priv->params_ethtool.tx_coalesce_mode = 1; 111482d2623eSHans Petter Selasky priv->params.tx_cq_moderation_mode = 111582d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_mode; 111674540a31SHans Petter Selasky 111782d2623eSHans Petter Selasky /* restart network interface, if any */ 1118d2bf00a9SHans Petter Selasky if (was_opened != 0) { 1119d2bf00a9SHans Petter Selasky if (mode_modify == 0) 112082d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 1121d2bf00a9SHans Petter Selasky else 1122d2bf00a9SHans Petter Selasky error = mlx5e_refresh_channel_params(priv); 1123d2bf00a9SHans Petter Selasky } 112482d2623eSHans Petter Selasky break; 112582d2623eSHans Petter Selasky 112682d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(hw_lro): 112782d2623eSHans Petter Selasky /* network interface must be down */ 112882d2623eSHans Petter Selasky if (was_opened) 112982d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 113082d2623eSHans Petter Selasky 113182d2623eSHans Petter Selasky /* import HW LRO mode */ 113271defedaSSlava Shwartsman if (priv->params_ethtool.hw_lro != 0 && 1133d7633a30SHans Petter Selasky MLX5_CAP_ETH(priv->mdev, lro_cap)) { 1134d7633a30SHans Petter Selasky priv->params_ethtool.hw_lro = 1; 113571defedaSSlava Shwartsman /* check if feature should actually be enabled */ 11365dc00f00SJustin Hibbits if (if_getcapenable(priv->ifp) & IFCAP_LRO) { 113771defedaSSlava Shwartsman priv->params.hw_lro_en = true; 1138d7633a30SHans Petter Selasky } else { 113971defedaSSlava Shwartsman priv->params.hw_lro_en = false; 1140d7633a30SHans Petter Selasky 11416b4040d8SHans Petter Selasky mlx5_en_warn(priv->ifp, "To enable HW LRO " 114271defedaSSlava Shwartsman "please also enable LRO via ifconfig(8).\n"); 114336c1007dSHans Petter Selasky } 1144bb3853c6SHans Petter Selasky } else { 114571defedaSSlava Shwartsman /* return an error if HW does not support this feature */ 114671defedaSSlava Shwartsman if (priv->params_ethtool.hw_lro != 0) 114771defedaSSlava Shwartsman error = EINVAL; 114871defedaSSlava Shwartsman priv->params.hw_lro_en = false; 114971defedaSSlava Shwartsman priv->params_ethtool.hw_lro = 0; 1150dc7e38acSHans Petter Selasky } 115182d2623eSHans Petter Selasky /* restart network interface, if any */ 115282d2623eSHans Petter Selasky if (was_opened) 115382d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 115482d2623eSHans Petter Selasky break; 1155dc7e38acSHans Petter Selasky 115682d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(cqe_zipping): 115782d2623eSHans Petter Selasky /* network interface must be down */ 115882d2623eSHans Petter Selasky if (was_opened) 115982d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 116082d2623eSHans Petter Selasky 116182d2623eSHans Petter Selasky /* import CQE zipping mode */ 116290cc1c77SHans Petter Selasky if (priv->params_ethtool.cqe_zipping && 116390cc1c77SHans Petter Selasky MLX5_CAP_GEN(priv->mdev, cqe_compression)) { 116490cc1c77SHans Petter Selasky priv->params.cqe_zipping_en = true; 116590cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = 1; 116690cc1c77SHans Petter Selasky } else { 116790cc1c77SHans Petter Selasky priv->params.cqe_zipping_en = false; 116890cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = 0; 116990cc1c77SHans Petter Selasky } 117082d2623eSHans Petter Selasky /* restart network interface, if any */ 1171dc7e38acSHans Petter Selasky if (was_opened) 1172dc7e38acSHans Petter Selasky mlx5e_open_locked(priv->ifp); 117382d2623eSHans Petter Selasky break; 117482d2623eSHans Petter Selasky 117582d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_completion_fact): 117682d2623eSHans Petter Selasky /* network interface must be down */ 117782d2623eSHans Petter Selasky if (was_opened) 117882d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 117982d2623eSHans Petter Selasky 118082d2623eSHans Petter Selasky /* verify parameter */ 118182d2623eSHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv); 118282d2623eSHans Petter Selasky 118382d2623eSHans Petter Selasky /* restart network interface, if any */ 118482d2623eSHans Petter Selasky if (was_opened) 118582d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 118682d2623eSHans Petter Selasky break; 118782d2623eSHans Petter Selasky 1188bb3616abSHans Petter Selasky case MLX5_PARAM_OFFSET(modify_tx_dma): 1189bb3616abSHans Petter Selasky /* check if network interface is opened */ 1190bb3616abSHans Petter Selasky if (was_opened) { 1191bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma = 1192bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma ? 1 : 0; 1193bb3616abSHans Petter Selasky /* modify tx according to value */ 1194bb3616abSHans Petter Selasky mlx5e_modify_tx_dma(priv, value != 0); 1195bb3616abSHans Petter Selasky } else { 1196bb3616abSHans Petter Selasky /* if closed force enable tx */ 1197bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma = 0; 1198bb3616abSHans Petter Selasky } 1199bb3616abSHans Petter Selasky break; 1200bb3616abSHans Petter Selasky 1201bb3616abSHans Petter Selasky case MLX5_PARAM_OFFSET(modify_rx_dma): 1202bb3616abSHans Petter Selasky /* check if network interface is opened */ 1203bb3616abSHans Petter Selasky if (was_opened) { 1204bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma = 1205bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma ? 1 : 0; 1206bb3616abSHans Petter Selasky /* modify rx according to value */ 1207bb3616abSHans Petter Selasky mlx5e_modify_rx_dma(priv, value != 0); 1208bb3616abSHans Petter Selasky } else { 1209bb3616abSHans Petter Selasky /* if closed force enable rx */ 1210bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma = 0; 1211bb3616abSHans Petter Selasky } 1212bb3616abSHans Petter Selasky break; 1213bb3616abSHans Petter Selasky 121466d53750SHans Petter Selasky case MLX5_PARAM_OFFSET(diag_pci_enable): 121566d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable = 121666d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable ? 1 : 0; 121766d53750SHans Petter Selasky 121866d53750SHans Petter Selasky error = -mlx5_core_set_diagnostics_full(priv->mdev, 121966d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable, 122066d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable); 122166d53750SHans Petter Selasky break; 122266d53750SHans Petter Selasky 122366d53750SHans Petter Selasky case MLX5_PARAM_OFFSET(diag_general_enable): 122466d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable = 122566d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable ? 1 : 0; 122666d53750SHans Petter Selasky 122766d53750SHans Petter Selasky error = -mlx5_core_set_diagnostics_full(priv->mdev, 122866d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable, 122966d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable); 123066d53750SHans Petter Selasky break; 123166d53750SHans Petter Selasky 123261fd7ac0SHans Petter Selasky case MLX5_PARAM_OFFSET(mc_local_lb): 1233ea00d7e8SHans Petter Selasky /* check if mlx5ib is managing this feature */ 1234ea00d7e8SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) { 1235ea00d7e8SHans Petter Selasky error = EOPNOTSUPP; 1236ea00d7e8SHans Petter Selasky break; 1237ea00d7e8SHans Petter Selasky } 1238ea00d7e8SHans Petter Selasky 123961fd7ac0SHans Petter Selasky priv->params_ethtool.mc_local_lb = 124061fd7ac0SHans Petter Selasky priv->params_ethtool.mc_local_lb ? 1 : 0; 124161fd7ac0SHans Petter Selasky 1242c1b76119SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, disable_local_lb_mc)) { 124361fd7ac0SHans Petter Selasky error = mlx5_nic_vport_modify_local_lb(priv->mdev, 124461fd7ac0SHans Petter Selasky MLX5_LOCAL_MC_LB, priv->params_ethtool.mc_local_lb); 124561fd7ac0SHans Petter Selasky } else { 124661fd7ac0SHans Petter Selasky error = EOPNOTSUPP; 124761fd7ac0SHans Petter Selasky } 124861fd7ac0SHans Petter Selasky break; 124961fd7ac0SHans Petter Selasky 125061fd7ac0SHans Petter Selasky case MLX5_PARAM_OFFSET(uc_local_lb): 1251ea00d7e8SHans Petter Selasky /* check if mlx5ib is managing this feature */ 1252ea00d7e8SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) { 1253ea00d7e8SHans Petter Selasky error = EOPNOTSUPP; 1254ea00d7e8SHans Petter Selasky break; 1255ea00d7e8SHans Petter Selasky } 1256ea00d7e8SHans Petter Selasky 125761fd7ac0SHans Petter Selasky priv->params_ethtool.uc_local_lb = 125861fd7ac0SHans Petter Selasky priv->params_ethtool.uc_local_lb ? 1 : 0; 125961fd7ac0SHans Petter Selasky 1260c1b76119SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, disable_local_lb_uc)) { 126161fd7ac0SHans Petter Selasky error = mlx5_nic_vport_modify_local_lb(priv->mdev, 126261fd7ac0SHans Petter Selasky MLX5_LOCAL_UC_LB, priv->params_ethtool.uc_local_lb); 126361fd7ac0SHans Petter Selasky } else { 126461fd7ac0SHans Petter Selasky error = EOPNOTSUPP; 126561fd7ac0SHans Petter Selasky } 126661fd7ac0SHans Petter Selasky break; 126761fd7ac0SHans Petter Selasky 1268c8d16d1eSHans Petter Selasky case MLX5_PARAM_OFFSET(irq_cpu_base): 1269c8d16d1eSHans Petter Selasky case MLX5_PARAM_OFFSET(irq_cpu_stride): 1270c8d16d1eSHans Petter Selasky if (was_opened) { 1271c8d16d1eSHans Petter Selasky /* network interface must toggled */ 1272c8d16d1eSHans Petter Selasky mlx5e_close_locked(priv->ifp); 1273c8d16d1eSHans Petter Selasky mlx5e_open_locked(priv->ifp); 1274c8d16d1eSHans Petter Selasky } 1275c8d16d1eSHans Petter Selasky break; 1276c8d16d1eSHans Petter Selasky 127782d2623eSHans Petter Selasky default: 127882d2623eSHans Petter Selasky break; 127982d2623eSHans Petter Selasky } 1280dc7e38acSHans Petter Selasky done: 1281dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 1282dc7e38acSHans Petter Selasky return (error); 1283dc7e38acSHans Petter Selasky } 1284dc7e38acSHans Petter Selasky 1285dc7e38acSHans Petter Selasky static const char *mlx5e_params_desc[] = { 1286dc7e38acSHans Petter Selasky MLX5E_PARAMS(MLX5E_STATS_DESC) 1287dc7e38acSHans Petter Selasky }; 1288dc7e38acSHans Petter Selasky 1289dc7e38acSHans Petter Selasky static const char *mlx5e_port_stats_debug_desc[] = { 1290dc7e38acSHans Petter Selasky MLX5E_PORT_STATS_DEBUG(MLX5E_STATS_DESC) 1291dc7e38acSHans Petter Selasky }; 1292dc7e38acSHans Petter Selasky 1293dc7e38acSHans Petter Selasky static int 1294f2b4782cSHans Petter Selasky mlx5e_ethtool_debug_channel_info(SYSCTL_HANDLER_ARGS) 1295f2b4782cSHans Petter Selasky { 1296f2b4782cSHans Petter Selasky struct mlx5e_priv *priv; 1297f2b4782cSHans Petter Selasky struct sbuf sb; 1298f2b4782cSHans Petter Selasky struct mlx5e_channel *c; 1299f2b4782cSHans Petter Selasky struct mlx5e_sq *sq; 1300f2b4782cSHans Petter Selasky struct mlx5e_rq *rq; 1301f2b4782cSHans Petter Selasky int error, i, tc; 13022110251aSHans Petter Selasky bool opened; 1303f2b4782cSHans Petter Selasky 1304f2b4782cSHans Petter Selasky priv = arg1; 1305f2b4782cSHans Petter Selasky error = sysctl_wire_old_buffer(req, 0); 1306f2b4782cSHans Petter Selasky if (error != 0) 1307f2b4782cSHans Petter Selasky return (error); 13082110251aSHans Petter Selasky if (sbuf_new_for_sysctl(&sb, NULL, 1024, req) == NULL) 1309f2b4782cSHans Petter Selasky return (ENOMEM); 1310f2b4782cSHans Petter Selasky sbuf_clear_flags(&sb, SBUF_INCLUDENUL); 1311f2b4782cSHans Petter Selasky 1312f2b4782cSHans Petter Selasky PRIV_LOCK(priv); 13132110251aSHans Petter Selasky opened = test_bit(MLX5E_STATE_OPENED, &priv->state); 13142110251aSHans Petter Selasky 13152110251aSHans Petter Selasky sbuf_printf(&sb, "pages irq %d\n", 13162110251aSHans Petter Selasky priv->mdev->priv.msix_arr[MLX5_EQ_VEC_PAGES].vector); 13172110251aSHans Petter Selasky sbuf_printf(&sb, "command irq %d\n", 13182110251aSHans Petter Selasky priv->mdev->priv.msix_arr[MLX5_EQ_VEC_CMD].vector); 13192110251aSHans Petter Selasky sbuf_printf(&sb, "async irq %d\n", 13202110251aSHans Petter Selasky priv->mdev->priv.msix_arr[MLX5_EQ_VEC_ASYNC].vector); 13212110251aSHans Petter Selasky 13222110251aSHans Petter Selasky for (i = 0; i != priv->params.num_channels; i++) { 13232110251aSHans Petter Selasky int eqn_not_used = -1; 13242110251aSHans Petter Selasky int irqn = MLX5_EQ_VEC_COMP_BASE; 13252110251aSHans Petter Selasky 13262110251aSHans Petter Selasky if (mlx5_vector2eqn(priv->mdev, i, &eqn_not_used, &irqn) != 0) 13272110251aSHans Petter Selasky continue; 13282110251aSHans Petter Selasky 13292110251aSHans Petter Selasky c = opened ? &priv->channel[i] : NULL; 13302110251aSHans Petter Selasky rq = opened ? &c->rq : NULL; 13312110251aSHans Petter Selasky sbuf_printf(&sb, "channel %d rq %d cq %d irq %d\n", i, 13322110251aSHans Petter Selasky opened ? rq->rqn : -1, 13332110251aSHans Petter Selasky opened ? rq->cq.mcq.cqn : -1, 13342110251aSHans Petter Selasky priv->mdev->priv.msix_arr[irqn].vector); 13352110251aSHans Petter Selasky 13362110251aSHans Petter Selasky for (tc = 0; tc != priv->num_tc; tc++) { 13372110251aSHans Petter Selasky sq = opened ? &c->sq[tc] : NULL; 13382110251aSHans Petter Selasky sbuf_printf(&sb, "channel %d tc %d sq %d cq %d irq %d\n", 13392110251aSHans Petter Selasky i, tc, 13402110251aSHans Petter Selasky opened ? sq->sqn : -1, 13412110251aSHans Petter Selasky opened ? sq->cq.mcq.cqn : -1, 13422110251aSHans Petter Selasky priv->mdev->priv.msix_arr[irqn].vector); 1343f2b4782cSHans Petter Selasky } 1344f2b4782cSHans Petter Selasky } 1345f2b4782cSHans Petter Selasky PRIV_UNLOCK(priv); 1346f2b4782cSHans Petter Selasky error = sbuf_finish(&sb); 1347f2b4782cSHans Petter Selasky sbuf_delete(&sb); 1348f2b4782cSHans Petter Selasky return (error); 1349f2b4782cSHans Petter Selasky } 1350f2b4782cSHans Petter Selasky 1351f2b4782cSHans Petter Selasky static int 1352dc7e38acSHans Petter Selasky mlx5e_ethtool_debug_stats(SYSCTL_HANDLER_ARGS) 1353dc7e38acSHans Petter Selasky { 1354dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1; 1355b3cf1493SSlava Shwartsman int sys_debug; 1356b3cf1493SSlava Shwartsman int error; 1357f2b4782cSHans Petter Selasky 1358f2b4782cSHans Petter Selasky PRIV_LOCK(priv); 1359069963d7SHans Petter Selasky if (priv->gone != 0) { 1360069963d7SHans Petter Selasky error = ENODEV; 1361069963d7SHans Petter Selasky goto done; 1362069963d7SHans Petter Selasky } 1363b3cf1493SSlava Shwartsman sys_debug = priv->sysctl_debug; 1364b3cf1493SSlava Shwartsman error = sysctl_handle_int(oidp, &sys_debug, 0, req); 1365b3cf1493SSlava Shwartsman if (error != 0 || !req->newptr) 1366b3cf1493SSlava Shwartsman goto done; 1367b3cf1493SSlava Shwartsman sys_debug = sys_debug ? 1 : 0; 1368b3cf1493SSlava Shwartsman if (sys_debug == priv->sysctl_debug) 1369b3cf1493SSlava Shwartsman goto done; 1370b3cf1493SSlava Shwartsman 1371b3cf1493SSlava Shwartsman if ((priv->sysctl_debug = sys_debug)) { 1372dc7e38acSHans Petter Selasky mlx5e_create_stats(&priv->stats.port_stats_debug.ctx, 1373dc7e38acSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), "debug_stats", 1374dc7e38acSHans Petter Selasky mlx5e_port_stats_debug_desc, MLX5E_PORT_STATS_DEBUG_NUM, 1375dc7e38acSHans Petter Selasky priv->stats.port_stats_debug.arg); 1376b3cf1493SSlava Shwartsman SYSCTL_ADD_PROC(&priv->stats.port_stats_debug.ctx, 1377f2b4782cSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO, 1378f2b4782cSHans Petter Selasky "hw_ctx_debug", 1379f2b4782cSHans Petter Selasky CTLFLAG_RD | CTLFLAG_MPSAFE | CTLTYPE_STRING, priv, 0, 1380f2b4782cSHans Petter Selasky mlx5e_ethtool_debug_channel_info, "S", ""); 1381f2b4782cSHans Petter Selasky } else { 1382dc7e38acSHans Petter Selasky sysctl_ctx_free(&priv->stats.port_stats_debug.ctx); 1383f2b4782cSHans Petter Selasky } 1384b3cf1493SSlava Shwartsman done: 1385f2b4782cSHans Petter Selasky PRIV_UNLOCK(priv); 1386b3cf1493SSlava Shwartsman return (error); 1387dc7e38acSHans Petter Selasky } 1388dc7e38acSHans Petter Selasky 138966d53750SHans Petter Selasky static void 139066d53750SHans Petter Selasky mlx5e_create_diagnostics(struct mlx5e_priv *priv) 139166d53750SHans Petter Selasky { 139266d53750SHans Petter Selasky struct mlx5_core_diagnostics_entry entry; 139366d53750SHans Petter Selasky struct sysctl_ctx_list *ctx; 139466d53750SHans Petter Selasky struct sysctl_oid *node; 139566d53750SHans Petter Selasky int x; 139666d53750SHans Petter Selasky 139766d53750SHans Petter Selasky /* sysctl context we are using */ 139866d53750SHans Petter Selasky ctx = &priv->sysctl_ctx; 139966d53750SHans Petter Selasky 140066d53750SHans Petter Selasky /* create root node */ 140166d53750SHans Petter Selasky node = SYSCTL_ADD_NODE(ctx, 140266d53750SHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO, 14037029da5cSPawel Biernacki "diagnostics", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Diagnostics"); 140466d53750SHans Petter Selasky if (node == NULL) 140566d53750SHans Petter Selasky return; 140666d53750SHans Petter Selasky 140766d53750SHans Petter Selasky /* create PCI diagnostics */ 140866d53750SHans Petter Selasky for (x = 0; x != MLX5_CORE_PCI_DIAGNOSTICS_NUM; x++) { 140966d53750SHans Petter Selasky entry = mlx5_core_pci_diagnostics_table[x]; 141066d53750SHans Petter Selasky if (mlx5_core_supports_diagnostics(priv->mdev, entry.counter_id) == 0) 141166d53750SHans Petter Selasky continue; 141266d53750SHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 141366d53750SHans Petter Selasky entry.desc, CTLFLAG_RD, priv->params_pci.array + x, 141466d53750SHans Petter Selasky "PCI diagnostics counter"); 141566d53750SHans Petter Selasky } 141666d53750SHans Petter Selasky 141766d53750SHans Petter Selasky /* create general diagnostics */ 141866d53750SHans Petter Selasky for (x = 0; x != MLX5_CORE_GENERAL_DIAGNOSTICS_NUM; x++) { 141966d53750SHans Petter Selasky entry = mlx5_core_general_diagnostics_table[x]; 142066d53750SHans Petter Selasky if (mlx5_core_supports_diagnostics(priv->mdev, entry.counter_id) == 0) 142166d53750SHans Petter Selasky continue; 142266d53750SHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO, 142366d53750SHans Petter Selasky entry.desc, CTLFLAG_RD, priv->params_general.array + x, 142466d53750SHans Petter Selasky "General diagnostics counter"); 142566d53750SHans Petter Selasky } 142666d53750SHans Petter Selasky } 142766d53750SHans Petter Selasky 1428dc7e38acSHans Petter Selasky void 1429dc7e38acSHans Petter Selasky mlx5e_create_ethtool(struct mlx5e_priv *priv) 1430dc7e38acSHans Petter Selasky { 143196425f44SHans Petter Selasky struct sysctl_oid *fec_node; 143296425f44SHans Petter Selasky struct sysctl_oid *qos_node; 143396425f44SHans Petter Selasky struct sysctl_oid *node; 1434dc7e38acSHans Petter Selasky const char *pnameunit; 14356deb0b1eSHans Petter Selasky struct mlx5e_port_buffer port_buffer; 1436dc7e38acSHans Petter Selasky unsigned x; 1437cfc9c386SHans Petter Selasky int i; 1438dc7e38acSHans Petter Selasky 1439dc7e38acSHans Petter Selasky /* set some defaults */ 1440c8d16d1eSHans Petter Selasky priv->params_ethtool.irq_cpu_base = -1; /* disabled */ 1441c8d16d1eSHans Petter Selasky priv->params_ethtool.irq_cpu_stride = 1; 1442dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE; 1443dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max = 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE; 1444dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 1 << priv->params.log_sq_size; 1445dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 1 << priv->params.log_rq_size; 1446dc7e38acSHans Petter Selasky priv->params_ethtool.channels = priv->params.num_channels; 144716ae32f9SHans Petter Selasky priv->params_ethtool.channels_rsss = priv->params.channels_rsss; 1448dc7e38acSHans Petter Selasky priv->params_ethtool.coalesce_pkts_max = MLX5E_FLD_MAX(cqc, cq_max_count); 1449dc7e38acSHans Petter Selasky priv->params_ethtool.coalesce_usecs_max = MLX5E_FLD_MAX(cqc, cq_period); 1450dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode = priv->params.rx_cq_moderation_mode; 1451dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = priv->params.rx_cq_moderation_usec; 1452dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = priv->params.rx_cq_moderation_pkts; 145374540a31SHans Petter Selasky priv->params_ethtool.tx_coalesce_mode = priv->params.tx_cq_moderation_mode; 1454dc7e38acSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = priv->params.tx_cq_moderation_usec; 1455dc7e38acSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = priv->params.tx_cq_moderation_pkts; 1456dc7e38acSHans Petter Selasky priv->params_ethtool.hw_lro = priv->params.hw_lro_en; 145790cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = priv->params.cqe_zipping_en; 1458376bcf63SHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv); 1459dc7e38acSHans Petter Selasky 146061fd7ac0SHans Petter Selasky /* get default values for local loopback, if any */ 1461c1b76119SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, disable_local_lb_mc) || 1462c1b76119SHans Petter Selasky MLX5_CAP_GEN(priv->mdev, disable_local_lb_uc)) { 146361fd7ac0SHans Petter Selasky int err; 146461fd7ac0SHans Petter Selasky u8 val; 146561fd7ac0SHans Petter Selasky 146661fd7ac0SHans Petter Selasky err = mlx5_nic_vport_query_local_lb(priv->mdev, MLX5_LOCAL_MC_LB, &val); 146761fd7ac0SHans Petter Selasky if (err == 0) 146861fd7ac0SHans Petter Selasky priv->params_ethtool.mc_local_lb = val; 146961fd7ac0SHans Petter Selasky 147061fd7ac0SHans Petter Selasky err = mlx5_nic_vport_query_local_lb(priv->mdev, MLX5_LOCAL_UC_LB, &val); 147161fd7ac0SHans Petter Selasky if (err == 0) 147261fd7ac0SHans Petter Selasky priv->params_ethtool.uc_local_lb = val; 147361fd7ac0SHans Petter Selasky } 147461fd7ac0SHans Petter Selasky 1475dc7e38acSHans Petter Selasky /* create root node */ 1476dc7e38acSHans Petter Selasky node = SYSCTL_ADD_NODE(&priv->sysctl_ctx, 1477dc7e38acSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO, 14787029da5cSPawel Biernacki "conf", CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, "Configuration"); 1479dc7e38acSHans Petter Selasky if (node == NULL) 1480dc7e38acSHans Petter Selasky return; 1481dc7e38acSHans Petter Selasky for (x = 0; x != MLX5E_PARAMS_NUM; x++) { 1482dc7e38acSHans Petter Selasky /* check for read-only parameter */ 148353d7bb46SHans Petter Selasky if (strstr(mlx5e_params_desc[2 * x], "_max") != NULL || 148453d7bb46SHans Petter Selasky strstr(mlx5e_params_desc[2 * x], "_mtu") != NULL) { 1485dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 1486dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x], CTLTYPE_U64 | CTLFLAG_RD | 1487dc7e38acSHans Petter Selasky CTLFLAG_MPSAFE, priv, x, &mlx5e_ethtool_handler, "QU", 1488dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x + 1]); 1489a60f9534SHans Petter Selasky } else if (strcmp(mlx5e_params_desc[2 * x], "hw_lro") == 0) { 1490a60f9534SHans Petter Selasky /* read-only, but tunable parameters */ 1491a60f9534SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 1492a60f9534SHans Petter Selasky mlx5e_params_desc[2 * x], CTLTYPE_U64 | CTLFLAG_RDTUN | 1493a60f9534SHans Petter Selasky CTLFLAG_MPSAFE, priv, x, &mlx5e_ethtool_handler, "QU", 1494a60f9534SHans Petter Selasky mlx5e_params_desc[2 * x + 1]); 1495dc7e38acSHans Petter Selasky } else { 1496ec0143b2SHans Petter Selasky /* 1497ec0143b2SHans Petter Selasky * NOTE: In FreeBSD-11 and newer the 1498ec0143b2SHans Petter Selasky * CTLFLAG_RWTUN flag will take care of 1499ec0143b2SHans Petter Selasky * loading default sysctl value from the 1500ec0143b2SHans Petter Selasky * kernel environment, if any: 1501ec0143b2SHans Petter Selasky */ 1502dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 1503dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x], CTLTYPE_U64 | CTLFLAG_RWTUN | 1504dc7e38acSHans Petter Selasky CTLFLAG_MPSAFE, priv, x, &mlx5e_ethtool_handler, "QU", 1505dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x + 1]); 1506dc7e38acSHans Petter Selasky } 1507dc7e38acSHans Petter Selasky } 1508dc7e38acSHans Petter Selasky 150996425f44SHans Petter Selasky /* create fec node */ 151096425f44SHans Petter Selasky fec_node = SYSCTL_ADD_NODE(&priv->sysctl_ctx, 151196425f44SHans Petter Selasky SYSCTL_CHILDREN(node), OID_AUTO, 15127029da5cSPawel Biernacki "fec", CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 15137029da5cSPawel Biernacki "Forward Error Correction"); 151496425f44SHans Petter Selasky if (fec_node == NULL) 151596425f44SHans Petter Selasky return; 151696425f44SHans Petter Selasky 151796425f44SHans Petter Selasky if (mlx5e_fec_update(priv) == 0) { 151896425f44SHans Petter Selasky SYSCTL_ADD_U32(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 151996425f44SHans Petter Selasky "mode_active", CTLFLAG_RD | CTLFLAG_MPSAFE, 152096425f44SHans Petter Selasky &priv->params_ethtool.fec_mode_active, 0, 152196425f44SHans Petter Selasky "Current FEC mode bit, if any."); 152296425f44SHans Petter Selasky 152396425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 152496425f44SHans Petter Selasky "mask_10x_25x", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 152596425f44SHans Petter Selasky priv, 0, &mlx5e_fec_mask_10x_25x_handler, "CU", 152696425f44SHans Petter Selasky "Set FEC masks for 10G_40G, 25G_50G, 56G, 100G respectivly. " 152796425f44SHans Petter Selasky "0:Auto " 152896425f44SHans Petter Selasky "1:NOFEC " 152996425f44SHans Petter Selasky "2:FIRECODE " 153096425f44SHans Petter Selasky "4:RS"); 153196425f44SHans Petter Selasky 153296425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 153396425f44SHans Petter Selasky "avail_10x_25x", CTLTYPE_U8 | CTLFLAG_RD | CTLFLAG_MPSAFE, 153496425f44SHans Petter Selasky priv, 0, &mlx5e_fec_avail_10x_25x_handler, "CU", 153596425f44SHans Petter Selasky "Get available FEC bits for 10G_40G, 25G_50G, 56G, 100G respectivly. " 153696425f44SHans Petter Selasky "0:Auto " 153796425f44SHans Petter Selasky "1:NOFEC " 153896425f44SHans Petter Selasky "2:FIRECODE " 153996425f44SHans Petter Selasky "4:RS"); 154096425f44SHans Petter Selasky 154196425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 154296425f44SHans Petter Selasky "mask_50x", CTLTYPE_U16 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 154396425f44SHans Petter Selasky priv, 0, &mlx5e_fec_mask_50x_handler, "SU", 154496425f44SHans Petter Selasky "Set FEC masks for 50G 1x, 100G 2x, 200G 4x, 400G 8x respectivly. " 154596425f44SHans Petter Selasky "0:Auto " 154696425f44SHans Petter Selasky "128:RS " 154796425f44SHans Petter Selasky "512:LL RS"); 154896425f44SHans Petter Selasky 154996425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO, 155096425f44SHans Petter Selasky "avail_50x", CTLTYPE_U16 | CTLFLAG_RD | CTLFLAG_MPSAFE, 155196425f44SHans Petter Selasky priv, 0, &mlx5e_fec_avail_50x_handler, "SU", 155296425f44SHans Petter Selasky "Get available FEC bits for 50G 1x, 100G 2x, 200G 4x, 400G 8x respectivly. " 155396425f44SHans Petter Selasky "0:Auto " 155496425f44SHans Petter Selasky "128:RS " 155596425f44SHans Petter Selasky "512:LL RS"); 155696425f44SHans Petter Selasky } 155796425f44SHans Petter Selasky 1558dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, 1559dc7e38acSHans Petter Selasky "debug_stats", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv, 1560dc7e38acSHans Petter Selasky 0, &mlx5e_ethtool_debug_stats, "I", "Extended debug statistics"); 1561dc7e38acSHans Petter Selasky 1562dc7e38acSHans Petter Selasky pnameunit = device_get_nameunit(priv->mdev->pdev->dev.bsddev); 1563dc7e38acSHans Petter Selasky 1564dc7e38acSHans Petter Selasky SYSCTL_ADD_STRING(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), 1565dc7e38acSHans Petter Selasky OID_AUTO, "device_name", CTLFLAG_RD, 1566dc7e38acSHans Petter Selasky __DECONST(void *, pnameunit), 0, 1567dc7e38acSHans Petter Selasky "PCI device name"); 1568dc7e38acSHans Petter Selasky 156966d53750SHans Petter Selasky /* Diagnostics support */ 157066d53750SHans Petter Selasky mlx5e_create_diagnostics(priv); 1571cfc9c386SHans Petter Selasky 1572cfc9c386SHans Petter Selasky /* create qos node */ 1573cfc9c386SHans Petter Selasky qos_node = SYSCTL_ADD_NODE(&priv->sysctl_ctx, 1574cfc9c386SHans Petter Selasky SYSCTL_CHILDREN(node), OID_AUTO, 15757029da5cSPawel Biernacki "qos", CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 15767029da5cSPawel Biernacki "Quality Of Service configuration"); 1577e870c0abSSlava Shwartsman if (qos_node == NULL) 1578cfc9c386SHans Petter Selasky return; 1579cfc9c386SHans Petter Selasky 1580e870c0abSSlava Shwartsman /* Priority rate limit support */ 1581e870c0abSSlava Shwartsman if (mlx5e_getmaxrate(priv) == 0) { 1582cfc9c386SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 1583e870c0abSSlava Shwartsman OID_AUTO, "tc_max_rate", CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 1584e870c0abSSlava Shwartsman priv, 0, mlx5e_tc_maxrate_handler, "QU", 1585e870c0abSSlava Shwartsman "Max rate for priority, specified in kilobits, where kilo=1000, " 1586e870c0abSSlava Shwartsman "max_rate must be divisible by 100000"); 1587cfc9c386SHans Petter Selasky } 15882e9c3a4fSHans Petter Selasky 1589e870c0abSSlava Shwartsman /* Bandwidth limiting by ratio */ 1590e870c0abSSlava Shwartsman if (mlx5e_get_max_alloc(priv) == 0) { 1591e870c0abSSlava Shwartsman SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 1592e870c0abSSlava Shwartsman OID_AUTO, "tc_rate_share", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 1593e870c0abSSlava Shwartsman priv, 0, mlx5e_tc_rate_share_handler, "QU", 1594e870c0abSSlava Shwartsman "Specify bandwidth ratio from 1 to 100 " 1595e870c0abSSlava Shwartsman "for the available traffic classes"); 1596e870c0abSSlava Shwartsman } 15972e9c3a4fSHans Petter Selasky 1598e870c0abSSlava Shwartsman /* Priority to traffic class mapping */ 1599e870c0abSSlava Shwartsman if (mlx5e_get_prio_tc(priv) == 0) { 16002e9c3a4fSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 160124385321SHans Petter Selasky OID_AUTO, "prio_0_7_tc", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 160224385321SHans Petter Selasky priv, 0, mlx5e_prio_to_tc_handler, "CU", 160324385321SHans Petter Selasky "Set traffic class 0 to 7 for priority 0 to 7 inclusivly"); 1604e870c0abSSlava Shwartsman } 1605ed0cee0bSHans Petter Selasky 1606ed0cee0bSHans Petter Selasky /* DSCP support */ 1607ed0cee0bSHans Petter Selasky if (mlx5e_get_dscp(priv) == 0) { 1608ed0cee0bSHans Petter Selasky for (i = 0; i != MLX5_MAX_SUPPORTED_DSCP; i += 8) { 1609ed0cee0bSHans Petter Selasky char name[32]; 1610ed0cee0bSHans Petter Selasky snprintf(name, sizeof(name), "dscp_%d_%d_prio", i, i + 7); 1611ed0cee0bSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 1612ed0cee0bSHans Petter Selasky OID_AUTO, name, CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 1613ed0cee0bSHans Petter Selasky priv, i, mlx5e_dscp_prio_handler, "CU", 1614ed0cee0bSHans Petter Selasky "Set DSCP to priority mapping, 0..7"); 1615ed0cee0bSHans Petter Selasky } 1616a880c1ffSHans Petter Selasky #define A "Set trust state, 1:PCP 2:DSCP" 1617a880c1ffSHans Petter Selasky #define B " 3:BOTH" 1618ed0cee0bSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 1619ed0cee0bSHans Petter Selasky OID_AUTO, "trust_state", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 1620ed0cee0bSHans Petter Selasky priv, 0, mlx5e_trust_state_handler, "CU", 1621dfea1c3eSHans Petter Selasky MLX5_CAP_QCAM_FEATURE(priv->mdev, qpts_trust_both) ? 1622a880c1ffSHans Petter Selasky A B : A); 1623a880c1ffSHans Petter Selasky #undef B 1624a880c1ffSHans Petter Selasky #undef A 1625ed0cee0bSHans Petter Selasky } 16266deb0b1eSHans Petter Selasky 16276deb0b1eSHans Petter Selasky if (mlx5e_port_query_buffer(priv, &port_buffer) == 0) { 16286deb0b1eSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 16296deb0b1eSHans Petter Selasky OID_AUTO, "buffers_size", 16306deb0b1eSHans Petter Selasky CTLTYPE_U32 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 16316deb0b1eSHans Petter Selasky priv, 0, mlx5e_buf_size_handler, "IU", 16326deb0b1eSHans Petter Selasky "Set buffers sizes"); 16336deb0b1eSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 16346deb0b1eSHans Petter Selasky OID_AUTO, "buffers_prio", 16356deb0b1eSHans Petter Selasky CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 16366deb0b1eSHans Petter Selasky priv, 0, mlx5e_buf_prio_handler, "CU", 16376deb0b1eSHans Petter Selasky "Set prio to buffers mapping"); 16386deb0b1eSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node), 16396deb0b1eSHans Petter Selasky OID_AUTO, "cable_length", 16406deb0b1eSHans Petter Selasky CTLTYPE_UINT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 16416deb0b1eSHans Petter Selasky priv, 0, mlx5e_cable_length_handler, "IU", 16426deb0b1eSHans Petter Selasky "Set cable length in meters for xoff threshold calculation"); 16436deb0b1eSHans Petter Selasky } 1644decb087cSHans Petter Selasky 1645decb087cSHans Petter Selasky if (mlx5e_hw_temperature_update(priv) == 0) { 1646decb087cSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 1647decb087cSHans Petter Selasky OID_AUTO, "hw_temperature", 1648decb087cSHans Petter Selasky CTLTYPE_S32 | CTLFLAG_RD | CTLFLAG_MPSAFE, 1649decb087cSHans Petter Selasky priv, 0, mlx5e_hw_temperature_handler, "I", 16509097ac9aSElyes HAOUAS "HW temperature in millicelsius"); 1651decb087cSHans Petter Selasky } 1652dc7e38acSHans Petter Selasky } 1653