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
26b984b956SKonstantin Belousov #include "opt_rss.h"
27b984b956SKonstantin Belousov #include "opt_ratelimit.h"
28b984b956SKonstantin Belousov
2989918a23SKonstantin Belousov #include <dev/mlx5/mlx5_en/en.h>
3089918a23SKonstantin Belousov #include <dev/mlx5/mlx5_en/port_buffer.h>
31dc7e38acSHans Petter Selasky
32dc7e38acSHans Petter Selasky void
mlx5e_create_stats(struct sysctl_ctx_list * ctx,struct sysctl_oid_list * parent,const char * buffer,const char ** desc,unsigned num,u64 * arg)33dc7e38acSHans Petter Selasky mlx5e_create_stats(struct sysctl_ctx_list *ctx,
34dc7e38acSHans Petter Selasky struct sysctl_oid_list *parent, const char *buffer,
35dc7e38acSHans Petter Selasky const char **desc, unsigned num, u64 * arg)
36dc7e38acSHans Petter Selasky {
37dc7e38acSHans Petter Selasky struct sysctl_oid *node;
38dc7e38acSHans Petter Selasky unsigned x;
39dc7e38acSHans Petter Selasky
40dc7e38acSHans Petter Selasky sysctl_ctx_init(ctx);
41dc7e38acSHans Petter Selasky
42dc7e38acSHans Petter Selasky node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO,
437029da5cSPawel Biernacki buffer, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Statistics");
44dc7e38acSHans Petter Selasky if (node == NULL)
45dc7e38acSHans Petter Selasky return;
46dc7e38acSHans Petter Selasky for (x = 0; x != num; x++) {
47dc7e38acSHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO,
48dc7e38acSHans Petter Selasky desc[2 * x], CTLFLAG_RD, arg + x, desc[2 * x + 1]);
49dc7e38acSHans Petter Selasky }
50dc7e38acSHans Petter Selasky }
51dc7e38acSHans Petter Selasky
527272f9cdSHans Petter Selasky void
mlx5e_create_counter_stats(struct sysctl_ctx_list * ctx,struct sysctl_oid_list * parent,const char * buffer,const char ** desc,unsigned num,counter_u64_t * arg)537272f9cdSHans Petter Selasky mlx5e_create_counter_stats(struct sysctl_ctx_list *ctx,
547272f9cdSHans Petter Selasky struct sysctl_oid_list *parent, const char *buffer,
557272f9cdSHans Petter Selasky const char **desc, unsigned num, counter_u64_t *arg)
567272f9cdSHans Petter Selasky {
577272f9cdSHans Petter Selasky struct sysctl_oid *node;
587272f9cdSHans Petter Selasky unsigned x;
597272f9cdSHans Petter Selasky
607272f9cdSHans Petter Selasky sysctl_ctx_init(ctx);
617272f9cdSHans Petter Selasky
627272f9cdSHans Petter Selasky node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO,
637029da5cSPawel Biernacki buffer, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Statistics");
647272f9cdSHans Petter Selasky if (node == NULL)
657272f9cdSHans Petter Selasky return;
667272f9cdSHans Petter Selasky for (x = 0; x != num; x++) {
677272f9cdSHans Petter Selasky SYSCTL_ADD_COUNTER_U64(ctx, SYSCTL_CHILDREN(node), OID_AUTO,
687272f9cdSHans Petter Selasky desc[2 * x], CTLFLAG_RD, arg + x, desc[2 * x + 1]);
697272f9cdSHans Petter Selasky }
707272f9cdSHans Petter Selasky }
717272f9cdSHans Petter Selasky
72376bcf63SHans Petter Selasky static void
mlx5e_ethtool_sync_tx_completion_fact(struct mlx5e_priv * priv)73376bcf63SHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(struct mlx5e_priv *priv)
74376bcf63SHans Petter Selasky {
75376bcf63SHans Petter Selasky /*
76376bcf63SHans Petter Selasky * Limit the maximum distance between completion events to
77376bcf63SHans Petter Selasky * half of the currently set TX queue size.
78376bcf63SHans Petter Selasky *
79376bcf63SHans Petter Selasky * The maximum number of queue entries a single IP packet can
80376bcf63SHans Petter Selasky * consume is given by MLX5_SEND_WQE_MAX_WQEBBS.
81376bcf63SHans Petter Selasky *
82376bcf63SHans Petter Selasky * The worst case max value is then given as below:
83376bcf63SHans Petter Selasky */
84376bcf63SHans Petter Selasky uint64_t max = priv->params_ethtool.tx_queue_size /
85376bcf63SHans Petter Selasky (2 * MLX5_SEND_WQE_MAX_WQEBBS);
86376bcf63SHans Petter Selasky
87376bcf63SHans Petter Selasky /*
88376bcf63SHans Petter Selasky * Update the maximum completion factor value in case the
89376bcf63SHans Petter Selasky * tx_queue_size field changed. Ensure we don't overflow
90376bcf63SHans Petter Selasky * 16-bits.
91376bcf63SHans Petter Selasky */
92376bcf63SHans Petter Selasky if (max < 1)
93376bcf63SHans Petter Selasky max = 1;
94376bcf63SHans Petter Selasky else if (max > 65535)
95376bcf63SHans Petter Selasky max = 65535;
96376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact_max = max;
97376bcf63SHans Petter Selasky
98376bcf63SHans Petter Selasky /*
99376bcf63SHans Petter Selasky * Verify that the current TX completion factor is within the
100376bcf63SHans Petter Selasky * given limits:
101376bcf63SHans Petter Selasky */
102376bcf63SHans Petter Selasky if (priv->params_ethtool.tx_completion_fact < 1)
103376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact = 1;
104376bcf63SHans Petter Selasky else if (priv->params_ethtool.tx_completion_fact > max)
105376bcf63SHans Petter Selasky priv->params_ethtool.tx_completion_fact = max;
106376bcf63SHans Petter Selasky }
107376bcf63SHans Petter Selasky
108cfc9c386SHans Petter Selasky static int
mlx5e_getmaxrate(struct mlx5e_priv * priv)109cfc9c386SHans Petter Selasky mlx5e_getmaxrate(struct mlx5e_priv *priv)
110cfc9c386SHans Petter Selasky {
111cfc9c386SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
112cfc9c386SHans Petter Selasky u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
113cfc9c386SHans Petter Selasky u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
114cfc9c386SHans Petter Selasky int err;
115cfc9c386SHans Petter Selasky int i;
116cfc9c386SHans Petter Selasky
117cfc9c386SHans Petter Selasky PRIV_LOCK(priv);
118cfc9c386SHans Petter Selasky err = -mlx5_query_port_tc_rate_limit(mdev, max_bw_value, max_bw_unit);
119cfc9c386SHans Petter Selasky if (err)
120cfc9c386SHans Petter Selasky goto done;
121cfc9c386SHans Petter Selasky
122cfc9c386SHans Petter Selasky for (i = 0; i <= mlx5_max_tc(mdev); i++) {
123cfc9c386SHans Petter Selasky switch (max_bw_unit[i]) {
124cfc9c386SHans Petter Selasky case MLX5_100_MBPS_UNIT:
125cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = max_bw_value[i] * MLX5E_100MB;
126cfc9c386SHans Petter Selasky break;
127cfc9c386SHans Petter Selasky case MLX5_GBPS_UNIT:
128cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = max_bw_value[i] * MLX5E_1GB;
129cfc9c386SHans Petter Selasky break;
130cfc9c386SHans Petter Selasky case MLX5_BW_NO_LIMIT:
131cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = 0;
132cfc9c386SHans Petter Selasky break;
133cfc9c386SHans Petter Selasky default:
134cfc9c386SHans Petter Selasky priv->params_ethtool.max_bw_value[i] = -1;
135cfc9c386SHans Petter Selasky WARN_ONCE(true, "non-supported BW unit");
136cfc9c386SHans Petter Selasky break;
137cfc9c386SHans Petter Selasky }
138cfc9c386SHans Petter Selasky }
139cfc9c386SHans Petter Selasky done:
140cfc9c386SHans Petter Selasky PRIV_UNLOCK(priv);
141cfc9c386SHans Petter Selasky return (err);
142cfc9c386SHans Petter Selasky }
143cfc9c386SHans Petter Selasky
144cfc9c386SHans Petter Selasky static int
mlx5e_get_max_alloc(struct mlx5e_priv * priv)145e870c0abSSlava Shwartsman mlx5e_get_max_alloc(struct mlx5e_priv *priv)
146e870c0abSSlava Shwartsman {
147e870c0abSSlava Shwartsman struct mlx5_core_dev *mdev = priv->mdev;
148e870c0abSSlava Shwartsman int err;
149e870c0abSSlava Shwartsman int x;
150e870c0abSSlava Shwartsman
151e870c0abSSlava Shwartsman PRIV_LOCK(priv);
152e870c0abSSlava Shwartsman err = -mlx5_query_port_tc_bw_alloc(mdev, priv->params_ethtool.max_bw_share);
153e870c0abSSlava Shwartsman if (err == 0) {
154e870c0abSSlava Shwartsman /* set default value */
155e870c0abSSlava Shwartsman for (x = 0; x != IEEE_8021QAZ_MAX_TCS; x++) {
156e870c0abSSlava Shwartsman priv->params_ethtool.max_bw_share[x] =
157e870c0abSSlava Shwartsman 100 / IEEE_8021QAZ_MAX_TCS;
158e870c0abSSlava Shwartsman }
159e870c0abSSlava Shwartsman err = -mlx5_set_port_tc_bw_alloc(mdev,
160e870c0abSSlava Shwartsman priv->params_ethtool.max_bw_share);
161e870c0abSSlava Shwartsman }
162e870c0abSSlava Shwartsman PRIV_UNLOCK(priv);
163e870c0abSSlava Shwartsman
164e870c0abSSlava Shwartsman return (err);
165e870c0abSSlava Shwartsman }
166e870c0abSSlava Shwartsman
167e870c0abSSlava Shwartsman static int
mlx5e_get_dscp(struct mlx5e_priv * priv)168ed0cee0bSHans Petter Selasky mlx5e_get_dscp(struct mlx5e_priv *priv)
169ed0cee0bSHans Petter Selasky {
170ed0cee0bSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
171ed0cee0bSHans Petter Selasky int err;
172ed0cee0bSHans Petter Selasky
173ed0cee0bSHans Petter Selasky if (MLX5_CAP_GEN(mdev, qcam_reg) == 0 ||
174ed0cee0bSHans Petter Selasky MLX5_CAP_QCAM_REG(mdev, qpts) == 0 ||
175ed0cee0bSHans Petter Selasky MLX5_CAP_QCAM_REG(mdev, qpdpm) == 0)
176ed0cee0bSHans Petter Selasky return (EOPNOTSUPP);
177ed0cee0bSHans Petter Selasky
178ed0cee0bSHans Petter Selasky PRIV_LOCK(priv);
179ed0cee0bSHans Petter Selasky err = -mlx5_query_dscp2prio(mdev, priv->params_ethtool.dscp2prio);
180ed0cee0bSHans Petter Selasky if (err)
181ed0cee0bSHans Petter Selasky goto done;
182ed0cee0bSHans Petter Selasky
183ed0cee0bSHans Petter Selasky err = -mlx5_query_trust_state(mdev, &priv->params_ethtool.trust_state);
184ed0cee0bSHans Petter Selasky if (err)
185ed0cee0bSHans Petter Selasky goto done;
186ed0cee0bSHans Petter Selasky done:
187ed0cee0bSHans Petter Selasky PRIV_UNLOCK(priv);
188ed0cee0bSHans Petter Selasky return (err);
189ed0cee0bSHans Petter Selasky }
190ed0cee0bSHans Petter Selasky
191e870c0abSSlava Shwartsman static void
mlx5e_tc_get_parameters(struct mlx5e_priv * priv,u64 * new_bw_value,u8 * max_bw_value,u8 * max_bw_unit)192e870c0abSSlava Shwartsman mlx5e_tc_get_parameters(struct mlx5e_priv *priv,
193e870c0abSSlava Shwartsman u64 *new_bw_value, u8 *max_bw_value, u8 *max_bw_unit)
194e870c0abSSlava Shwartsman {
195e870c0abSSlava Shwartsman const u64 upper_limit_mbps = 255 * MLX5E_100MB;
196e870c0abSSlava Shwartsman const u64 upper_limit_gbps = 255 * MLX5E_1GB;
197e870c0abSSlava Shwartsman u64 temp;
198e870c0abSSlava Shwartsman int i;
199e870c0abSSlava Shwartsman
200e870c0abSSlava Shwartsman memset(max_bw_value, 0, IEEE_8021QAZ_MAX_TCS);
201e870c0abSSlava Shwartsman memset(max_bw_unit, 0, IEEE_8021QAZ_MAX_TCS);
202e870c0abSSlava Shwartsman
203e870c0abSSlava Shwartsman for (i = 0; i <= mlx5_max_tc(priv->mdev); i++) {
204e870c0abSSlava Shwartsman temp = (new_bw_value != NULL) ?
205e870c0abSSlava Shwartsman new_bw_value[i] : priv->params_ethtool.max_bw_value[i];
206e870c0abSSlava Shwartsman
207e870c0abSSlava Shwartsman if (!temp) {
208e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_BW_NO_LIMIT;
209e870c0abSSlava Shwartsman } else if (temp > upper_limit_gbps) {
210e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_BW_NO_LIMIT;
211e870c0abSSlava Shwartsman } else if (temp <= upper_limit_mbps) {
212e870c0abSSlava Shwartsman max_bw_value[i] = howmany(temp, MLX5E_100MB);
213e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_100_MBPS_UNIT;
214e870c0abSSlava Shwartsman } else {
215e870c0abSSlava Shwartsman max_bw_value[i] = howmany(temp, MLX5E_1GB);
216e870c0abSSlava Shwartsman max_bw_unit[i] = MLX5_GBPS_UNIT;
217e870c0abSSlava Shwartsman }
218e870c0abSSlava Shwartsman }
219e870c0abSSlava Shwartsman }
220e870c0abSSlava Shwartsman
221ed0cee0bSHans Petter Selasky static int
mlx5e_tc_maxrate_handler(SYSCTL_HANDLER_ARGS)222cfc9c386SHans Petter Selasky mlx5e_tc_maxrate_handler(SYSCTL_HANDLER_ARGS)
223cfc9c386SHans Petter Selasky {
224cfc9c386SHans Petter Selasky struct mlx5e_priv *priv = arg1;
225cfc9c386SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
226cfc9c386SHans Petter Selasky u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
227cfc9c386SHans Petter Selasky u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
228e870c0abSSlava Shwartsman u64 new_bw_value[IEEE_8021QAZ_MAX_TCS];
229e870c0abSSlava Shwartsman u8 max_rates = mlx5_max_tc(mdev) + 1;
230e870c0abSSlava Shwartsman u8 x;
231e870c0abSSlava Shwartsman int err;
232cfc9c386SHans Petter Selasky
233cfc9c386SHans Petter Selasky PRIV_LOCK(priv);
234e870c0abSSlava Shwartsman err = SYSCTL_OUT(req, priv->params_ethtool.max_bw_value,
235e870c0abSSlava Shwartsman sizeof(priv->params_ethtool.max_bw_value[0]) * max_rates);
236e870c0abSSlava Shwartsman if (err || !req->newptr)
237e870c0abSSlava Shwartsman goto done;
238e870c0abSSlava Shwartsman err = SYSCTL_IN(req, new_bw_value,
239e870c0abSSlava Shwartsman sizeof(new_bw_value[0]) * max_rates);
240e870c0abSSlava Shwartsman if (err)
241cfc9c386SHans Petter Selasky goto done;
242cfc9c386SHans Petter Selasky
243e870c0abSSlava Shwartsman /* range check input value */
244e870c0abSSlava Shwartsman for (x = 0; x != max_rates; x++) {
245e870c0abSSlava Shwartsman if (new_bw_value[x] % MLX5E_100MB) {
246cfc9c386SHans Petter Selasky err = ERANGE;
247cfc9c386SHans Petter Selasky goto done;
248cfc9c386SHans Petter Selasky }
249cfc9c386SHans Petter Selasky }
250e870c0abSSlava Shwartsman
251e870c0abSSlava Shwartsman mlx5e_tc_get_parameters(priv, new_bw_value, max_bw_value, max_bw_unit);
252cfc9c386SHans Petter Selasky
253cfc9c386SHans Petter Selasky err = -mlx5_modify_port_tc_rate_limit(mdev, max_bw_value, max_bw_unit);
254cfc9c386SHans Petter Selasky if (err)
255cfc9c386SHans Petter Selasky goto done;
256cfc9c386SHans Petter Selasky
257e870c0abSSlava Shwartsman memcpy(priv->params_ethtool.max_bw_value, new_bw_value,
258e870c0abSSlava Shwartsman sizeof(priv->params_ethtool.max_bw_value));
259e870c0abSSlava Shwartsman done:
260e870c0abSSlava Shwartsman PRIV_UNLOCK(priv);
261e870c0abSSlava Shwartsman return (err);
262e870c0abSSlava Shwartsman }
263e870c0abSSlava Shwartsman
264e870c0abSSlava Shwartsman static int
mlx5e_tc_rate_share_handler(SYSCTL_HANDLER_ARGS)265e870c0abSSlava Shwartsman mlx5e_tc_rate_share_handler(SYSCTL_HANDLER_ARGS)
266e870c0abSSlava Shwartsman {
267e870c0abSSlava Shwartsman struct mlx5e_priv *priv = arg1;
268e870c0abSSlava Shwartsman struct mlx5_core_dev *mdev = priv->mdev;
269e870c0abSSlava Shwartsman u8 max_bw_share[IEEE_8021QAZ_MAX_TCS];
270e870c0abSSlava Shwartsman u8 max_rates = mlx5_max_tc(mdev) + 1;
271e870c0abSSlava Shwartsman int i;
272e870c0abSSlava Shwartsman int err;
273e870c0abSSlava Shwartsman int sum;
274e870c0abSSlava Shwartsman
275e870c0abSSlava Shwartsman PRIV_LOCK(priv);
276e870c0abSSlava Shwartsman err = SYSCTL_OUT(req, priv->params_ethtool.max_bw_share, max_rates);
277e870c0abSSlava Shwartsman if (err || !req->newptr)
278e870c0abSSlava Shwartsman goto done;
279e870c0abSSlava Shwartsman err = SYSCTL_IN(req, max_bw_share, max_rates);
280e870c0abSSlava Shwartsman if (err)
281e870c0abSSlava Shwartsman goto done;
282e870c0abSSlava Shwartsman
283e870c0abSSlava Shwartsman /* range check input value */
284e870c0abSSlava Shwartsman for (sum = i = 0; i != max_rates; i++) {
285e870c0abSSlava Shwartsman if (max_bw_share[i] < 1 || max_bw_share[i] > 100) {
286e870c0abSSlava Shwartsman err = ERANGE;
287e870c0abSSlava Shwartsman goto done;
288e870c0abSSlava Shwartsman }
289e870c0abSSlava Shwartsman sum += max_bw_share[i];
290e870c0abSSlava Shwartsman }
291e870c0abSSlava Shwartsman
292e870c0abSSlava Shwartsman /* sum of values should be as close to 100 as possible */
293e870c0abSSlava Shwartsman if (sum < (100 - max_rates + 1) || sum > 100) {
294e870c0abSSlava Shwartsman err = ERANGE;
295e870c0abSSlava Shwartsman goto done;
296e870c0abSSlava Shwartsman }
297e870c0abSSlava Shwartsman
298e870c0abSSlava Shwartsman err = -mlx5_set_port_tc_bw_alloc(mdev, max_bw_share);
299e870c0abSSlava Shwartsman if (err)
300e870c0abSSlava Shwartsman goto done;
301e870c0abSSlava Shwartsman
302e870c0abSSlava Shwartsman memcpy(priv->params_ethtool.max_bw_share, max_bw_share,
303e870c0abSSlava Shwartsman sizeof(priv->params_ethtool.max_bw_share));
304cfc9c386SHans Petter Selasky done:
305cfc9c386SHans Petter Selasky PRIV_UNLOCK(priv);
306cfc9c386SHans Petter Selasky return (err);
307cfc9c386SHans Petter Selasky }
308cfc9c386SHans Petter Selasky
3092e9c3a4fSHans Petter Selasky static int
mlx5e_get_prio_tc(struct mlx5e_priv * priv)3102e9c3a4fSHans Petter Selasky mlx5e_get_prio_tc(struct mlx5e_priv *priv)
3112e9c3a4fSHans Petter Selasky {
3122e9c3a4fSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
3132e9c3a4fSHans Petter Selasky int err = 0;
3142e9c3a4fSHans Petter Selasky int i;
3152e9c3a4fSHans Petter Selasky
3162e9c3a4fSHans Petter Selasky PRIV_LOCK(priv);
3172e9c3a4fSHans Petter Selasky if (!MLX5_CAP_GEN(priv->mdev, ets)) {
3182e9c3a4fSHans Petter Selasky PRIV_UNLOCK(priv);
3192e9c3a4fSHans Petter Selasky return (EOPNOTSUPP);
3202e9c3a4fSHans Petter Selasky }
3212e9c3a4fSHans Petter Selasky
32224385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) {
32324385321SHans Petter Selasky err = -mlx5_query_port_prio_tc(mdev, i, priv->params_ethtool.prio_tc + i);
3242e9c3a4fSHans Petter Selasky if (err)
3252e9c3a4fSHans Petter Selasky break;
3262e9c3a4fSHans Petter Selasky }
3272e9c3a4fSHans Petter Selasky PRIV_UNLOCK(priv);
3282e9c3a4fSHans Petter Selasky return (err);
3292e9c3a4fSHans Petter Selasky }
3302e9c3a4fSHans Petter Selasky
3312e9c3a4fSHans Petter Selasky static int
mlx5e_prio_to_tc_handler(SYSCTL_HANDLER_ARGS)3322e9c3a4fSHans Petter Selasky mlx5e_prio_to_tc_handler(SYSCTL_HANDLER_ARGS)
3332e9c3a4fSHans Petter Selasky {
3342e9c3a4fSHans Petter Selasky struct mlx5e_priv *priv = arg1;
3352e9c3a4fSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
33624385321SHans Petter Selasky uint8_t temp[MLX5E_MAX_PRIORITY];
3372e9c3a4fSHans Petter Selasky int err;
33824385321SHans Petter Selasky int i;
3392e9c3a4fSHans Petter Selasky
3402e9c3a4fSHans Petter Selasky PRIV_LOCK(priv);
34124385321SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.prio_tc, MLX5E_MAX_PRIORITY);
34224385321SHans Petter Selasky if (err || !req->newptr)
3432e9c3a4fSHans Petter Selasky goto done;
34424385321SHans Petter Selasky err = SYSCTL_IN(req, temp, MLX5E_MAX_PRIORITY);
3452e9c3a4fSHans Petter Selasky if (err)
3462e9c3a4fSHans Petter Selasky goto done;
3472e9c3a4fSHans Petter Selasky
34824385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) {
34924385321SHans Petter Selasky if (temp[i] > mlx5_max_tc(mdev)) {
35024385321SHans Petter Selasky err = ERANGE;
35124385321SHans Petter Selasky goto done;
35224385321SHans Petter Selasky }
35324385321SHans Petter Selasky }
3542e9c3a4fSHans Petter Selasky
35524385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) {
35624385321SHans Petter Selasky if (temp[i] == priv->params_ethtool.prio_tc[i])
35724385321SHans Petter Selasky continue;
35824385321SHans Petter Selasky err = -mlx5_set_port_prio_tc(mdev, i, temp[i]);
35924385321SHans Petter Selasky if (err)
36024385321SHans Petter Selasky goto done;
36124385321SHans Petter Selasky /* update cached value */
36224385321SHans Petter Selasky priv->params_ethtool.prio_tc[i] = temp[i];
36324385321SHans Petter Selasky }
3642e9c3a4fSHans Petter Selasky done:
3652e9c3a4fSHans Petter Selasky PRIV_UNLOCK(priv);
3662e9c3a4fSHans Petter Selasky return (err);
3672e9c3a4fSHans Petter Selasky }
3682e9c3a4fSHans Petter Selasky
36996425f44SHans Petter Selasky int
mlx5e_fec_update(struct mlx5e_priv * priv)37096425f44SHans Petter Selasky mlx5e_fec_update(struct mlx5e_priv *priv)
37196425f44SHans Petter Selasky {
37296425f44SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
37396425f44SHans Petter Selasky u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
37496425f44SHans Petter Selasky const int sz = MLX5_ST_SZ_BYTES(pplm_reg);
37596425f44SHans Petter Selasky int err;
37696425f44SHans Petter Selasky
37796425f44SHans Petter Selasky if (!MLX5_CAP_GEN(mdev, pcam_reg))
37896425f44SHans Petter Selasky return (EOPNOTSUPP);
37996425f44SHans Petter Selasky
38096425f44SHans Petter Selasky if (!MLX5_CAP_PCAM_REG(mdev, pplm))
38196425f44SHans Petter Selasky return (EOPNOTSUPP);
38296425f44SHans Petter Selasky
38396425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1);
38496425f44SHans Petter Selasky
38596425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, in, sz, MLX5_REG_PPLM, 0, 0);
38696425f44SHans Petter Selasky if (err)
38796425f44SHans Petter Selasky return (err);
38896425f44SHans Petter Selasky
38996425f44SHans Petter Selasky /* get 10x..25x mask */
39096425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[0] =
39196425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_10g_40g);
39296425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[1] =
39396425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_25g) &
39496425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_50g);
39596425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[2] =
39696425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_56g);
39796425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[3] =
39896425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_100g);
39996425f44SHans Petter Selasky
40096425f44SHans Petter Selasky /* get 10x..25x available bits */
40196425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[0] =
40296425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_10g_40g);
40396425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[1] =
40496425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_25g) &
40596425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_50g);
40696425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[2] =
40796425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_56g);
40896425f44SHans Petter Selasky priv->params_ethtool.fec_avail_10x_25x[3] =
40996425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_100g);
41096425f44SHans Petter Selasky
41196425f44SHans Petter Selasky /* get 50x mask */
41296425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[0] =
41396425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_50g_1x);
41496425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[1] =
41596425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_100g_2x);
41696425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[2] =
41796425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_200g_4x);
41896425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[3] =
41996425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_admin_400g_8x);
42096425f44SHans Petter Selasky
42196425f44SHans Petter Selasky /* get 50x available bits */
42296425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[0] =
42396425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_50g_1x);
42496425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[1] =
42596425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_100g_2x);
42696425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[2] =
42796425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_200g_4x);
42896425f44SHans Petter Selasky priv->params_ethtool.fec_avail_50x[3] =
42996425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_override_cap_400g_8x);
43096425f44SHans Petter Selasky
43196425f44SHans Petter Selasky /* get current FEC mask */
43296425f44SHans Petter Selasky priv->params_ethtool.fec_mode_active =
43396425f44SHans Petter Selasky MLX5_GET(pplm_reg, in, fec_mode_active);
43496425f44SHans Petter Selasky
43596425f44SHans Petter Selasky return (0);
43696425f44SHans Petter Selasky }
43796425f44SHans Petter Selasky
43896425f44SHans Petter Selasky static int
mlx5e_fec_mask_10x_25x_handler(SYSCTL_HANDLER_ARGS)43996425f44SHans Petter Selasky mlx5e_fec_mask_10x_25x_handler(SYSCTL_HANDLER_ARGS)
44096425f44SHans Petter Selasky {
44196425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1;
44296425f44SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
44396425f44SHans Petter Selasky u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {};
44496425f44SHans Petter Selasky u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
44596425f44SHans Petter Selasky const int sz = MLX5_ST_SZ_BYTES(pplm_reg);
44696425f44SHans Petter Selasky u8 fec_mask_10x_25x[MLX5E_MAX_FEC_10X_25X];
44796425f44SHans Petter Selasky u8 fec_cap_changed = 0;
44896425f44SHans Petter Selasky u8 x;
44996425f44SHans Petter Selasky int err;
45096425f44SHans Petter Selasky
45196425f44SHans Petter Selasky PRIV_LOCK(priv);
45296425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_mask_10x_25x,
45396425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_10x_25x));
45496425f44SHans Petter Selasky if (err || !req->newptr)
45596425f44SHans Petter Selasky goto done;
45696425f44SHans Petter Selasky
45796425f44SHans Petter Selasky err = SYSCTL_IN(req, fec_mask_10x_25x,
45896425f44SHans Petter Selasky sizeof(fec_mask_10x_25x));
45996425f44SHans Petter Selasky if (err)
46096425f44SHans Petter Selasky goto done;
46196425f44SHans Petter Selasky
46296425f44SHans Petter Selasky if (!MLX5_CAP_GEN(mdev, pcam_reg)) {
46396425f44SHans Petter Selasky err = EOPNOTSUPP;
46496425f44SHans Petter Selasky goto done;
46596425f44SHans Petter Selasky }
46696425f44SHans Petter Selasky
46796425f44SHans Petter Selasky if (!MLX5_CAP_PCAM_REG(mdev, pplm)) {
46896425f44SHans Petter Selasky err = EOPNOTSUPP;
46996425f44SHans Petter Selasky goto done;
47096425f44SHans Petter Selasky }
47196425f44SHans Petter Selasky
47296425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1);
47396425f44SHans Petter Selasky
47496425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, in, sz, MLX5_REG_PPLM, 0, 0);
47596425f44SHans Petter Selasky if (err)
47696425f44SHans Petter Selasky goto done;
47796425f44SHans Petter Selasky
47896425f44SHans Petter Selasky /* range check input value */
47996425f44SHans Petter Selasky for (x = 0; x != MLX5E_MAX_FEC_10X_25X; x++) {
48096425f44SHans Petter Selasky /* check only one bit is set, if any */
48196425f44SHans Petter Selasky if (fec_mask_10x_25x[x] & (fec_mask_10x_25x[x] - 1)) {
48296425f44SHans Petter Selasky err = ERANGE;
48396425f44SHans Petter Selasky goto done;
48496425f44SHans Petter Selasky }
48596425f44SHans Petter Selasky /* check a supported bit is set, if any */
48696425f44SHans Petter Selasky if (fec_mask_10x_25x[x] &
48796425f44SHans Petter Selasky ~priv->params_ethtool.fec_avail_10x_25x[x]) {
48896425f44SHans Petter Selasky err = ERANGE;
48996425f44SHans Petter Selasky goto done;
49096425f44SHans Petter Selasky }
49196425f44SHans Petter Selasky fec_cap_changed |= (fec_mask_10x_25x[x] ^
49296425f44SHans Petter Selasky priv->params_ethtool.fec_mask_10x_25x[x]);
49396425f44SHans Petter Selasky }
49496425f44SHans Petter Selasky
49596425f44SHans Petter Selasky /* check for no changes */
49696425f44SHans Petter Selasky if (fec_cap_changed == 0)
49796425f44SHans Petter Selasky goto done;
49896425f44SHans Petter Selasky
49996425f44SHans Petter Selasky memset(in, 0, sizeof(in));
50096425f44SHans Petter Selasky
50196425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1);
50296425f44SHans Petter Selasky
50396425f44SHans Petter Selasky /* set new values */
50496425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_10g_40g, fec_mask_10x_25x[0]);
50596425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_25g, fec_mask_10x_25x[1]);
50696425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g, fec_mask_10x_25x[1]);
50796425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_56g, fec_mask_10x_25x[2]);
50896425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g, fec_mask_10x_25x[3]);
50996425f44SHans Petter Selasky
51096425f44SHans Petter Selasky /* preserve other values */
51196425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g_1x, priv->params_ethtool.fec_mask_50x[0]);
51296425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g_2x, priv->params_ethtool.fec_mask_50x[1]);
51396425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_200g_4x, priv->params_ethtool.fec_mask_50x[2]);
51496425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_400g_8x, priv->params_ethtool.fec_mask_50x[3]);
51596425f44SHans Petter Selasky
51696425f44SHans Petter Selasky /* send new value to the firmware */
51796425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPLM, 0, 1);
51896425f44SHans Petter Selasky if (err)
51996425f44SHans Petter Selasky goto done;
52096425f44SHans Petter Selasky
52196425f44SHans Petter Selasky memcpy(priv->params_ethtool.fec_mask_10x_25x, fec_mask_10x_25x,
52296425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_10x_25x));
52396425f44SHans Petter Selasky
52496425f44SHans Petter Selasky mlx5_toggle_port_link(priv->mdev);
52596425f44SHans Petter Selasky done:
52696425f44SHans Petter Selasky PRIV_UNLOCK(priv);
52796425f44SHans Petter Selasky return (err);
52896425f44SHans Petter Selasky }
52996425f44SHans Petter Selasky
53096425f44SHans Petter Selasky static int
mlx5e_fec_avail_10x_25x_handler(SYSCTL_HANDLER_ARGS)53196425f44SHans Petter Selasky mlx5e_fec_avail_10x_25x_handler(SYSCTL_HANDLER_ARGS)
53296425f44SHans Petter Selasky {
53396425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1;
53496425f44SHans Petter Selasky int err;
53596425f44SHans Petter Selasky
53696425f44SHans Petter Selasky PRIV_LOCK(priv);
53796425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_avail_10x_25x,
53896425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_avail_10x_25x));
53996425f44SHans Petter Selasky PRIV_UNLOCK(priv);
54096425f44SHans Petter Selasky return (err);
54196425f44SHans Petter Selasky }
54296425f44SHans Petter Selasky
54396425f44SHans Petter Selasky static int
mlx5e_fec_mask_50x_handler(SYSCTL_HANDLER_ARGS)54496425f44SHans Petter Selasky mlx5e_fec_mask_50x_handler(SYSCTL_HANDLER_ARGS)
54596425f44SHans Petter Selasky {
54696425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1;
54796425f44SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
54896425f44SHans Petter Selasky u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {};
54996425f44SHans Petter Selasky u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
55096425f44SHans Petter Selasky const int sz = MLX5_ST_SZ_BYTES(pplm_reg);
55196425f44SHans Petter Selasky u16 fec_mask_50x[MLX5E_MAX_FEC_50X];
55296425f44SHans Petter Selasky u16 fec_cap_changed = 0;
55396425f44SHans Petter Selasky u8 x;
55496425f44SHans Petter Selasky int err;
55596425f44SHans Petter Selasky
55696425f44SHans Petter Selasky PRIV_LOCK(priv);
55796425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_mask_50x,
55896425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_50x));
55996425f44SHans Petter Selasky if (err || !req->newptr)
56096425f44SHans Petter Selasky goto done;
56196425f44SHans Petter Selasky
56296425f44SHans Petter Selasky err = SYSCTL_IN(req, fec_mask_50x,
56396425f44SHans Petter Selasky sizeof(fec_mask_50x));
56496425f44SHans Petter Selasky if (err)
56596425f44SHans Petter Selasky goto done;
56696425f44SHans Petter Selasky
56796425f44SHans Petter Selasky if (!MLX5_CAP_GEN(mdev, pcam_reg)) {
56896425f44SHans Petter Selasky err = EOPNOTSUPP;
56996425f44SHans Petter Selasky goto done;
57096425f44SHans Petter Selasky }
57196425f44SHans Petter Selasky
57296425f44SHans Petter Selasky if (!MLX5_CAP_PCAM_REG(mdev, pplm)) {
57396425f44SHans Petter Selasky err = EOPNOTSUPP;
57496425f44SHans Petter Selasky goto done;
57596425f44SHans Petter Selasky }
57696425f44SHans Petter Selasky
57796425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1);
57896425f44SHans Petter Selasky
57996425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, in, sz, MLX5_REG_PPLM, 0, 0);
58096425f44SHans Petter Selasky if (err)
58196425f44SHans Petter Selasky goto done;
58296425f44SHans Petter Selasky
58396425f44SHans Petter Selasky /* range check input value */
58496425f44SHans Petter Selasky for (x = 0; x != MLX5E_MAX_FEC_50X; x++) {
58596425f44SHans Petter Selasky /* check only one bit is set, if any */
58696425f44SHans Petter Selasky if (fec_mask_50x[x] & (fec_mask_50x[x] - 1)) {
58796425f44SHans Petter Selasky err = ERANGE;
58896425f44SHans Petter Selasky goto done;
58996425f44SHans Petter Selasky }
59096425f44SHans Petter Selasky /* check a supported bit is set, if any */
59196425f44SHans Petter Selasky if (fec_mask_50x[x] &
59296425f44SHans Petter Selasky ~priv->params_ethtool.fec_avail_50x[x]) {
59396425f44SHans Petter Selasky err = ERANGE;
59496425f44SHans Petter Selasky goto done;
59596425f44SHans Petter Selasky }
59696425f44SHans Petter Selasky fec_cap_changed |= (fec_mask_50x[x] ^
59796425f44SHans Petter Selasky priv->params_ethtool.fec_mask_50x[x]);
59896425f44SHans Petter Selasky }
59996425f44SHans Petter Selasky
60096425f44SHans Petter Selasky /* check for no changes */
60196425f44SHans Petter Selasky if (fec_cap_changed == 0)
60296425f44SHans Petter Selasky goto done;
60396425f44SHans Petter Selasky
60496425f44SHans Petter Selasky memset(in, 0, sizeof(in));
60596425f44SHans Petter Selasky
60696425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, local_port, 1);
60796425f44SHans Petter Selasky
60896425f44SHans Petter Selasky /* set new values */
60996425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g_1x, fec_mask_50x[0]);
61096425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g_2x, fec_mask_50x[1]);
61196425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_200g_4x, fec_mask_50x[2]);
61296425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_400g_8x, fec_mask_50x[3]);
61396425f44SHans Petter Selasky
61496425f44SHans Petter Selasky /* preserve other values */
61596425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_10g_40g, priv->params_ethtool.fec_mask_10x_25x[0]);
61696425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_25g, priv->params_ethtool.fec_mask_10x_25x[1]);
61796425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_50g, priv->params_ethtool.fec_mask_10x_25x[1]);
61896425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_56g, priv->params_ethtool.fec_mask_10x_25x[2]);
61996425f44SHans Petter Selasky MLX5_SET(pplm_reg, in, fec_override_admin_100g, priv->params_ethtool.fec_mask_10x_25x[3]);
62096425f44SHans Petter Selasky
62196425f44SHans Petter Selasky /* send new value to the firmware */
62296425f44SHans Petter Selasky err = -mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPLM, 0, 1);
62396425f44SHans Petter Selasky if (err)
62496425f44SHans Petter Selasky goto done;
62596425f44SHans Petter Selasky
62696425f44SHans Petter Selasky memcpy(priv->params_ethtool.fec_mask_50x, fec_mask_50x,
62796425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_mask_50x));
62896425f44SHans Petter Selasky
62996425f44SHans Petter Selasky mlx5_toggle_port_link(priv->mdev);
63096425f44SHans Petter Selasky done:
63196425f44SHans Petter Selasky PRIV_UNLOCK(priv);
63296425f44SHans Petter Selasky return (err);
63396425f44SHans Petter Selasky }
63496425f44SHans Petter Selasky
63596425f44SHans Petter Selasky static int
mlx5e_fec_avail_50x_handler(SYSCTL_HANDLER_ARGS)63696425f44SHans Petter Selasky mlx5e_fec_avail_50x_handler(SYSCTL_HANDLER_ARGS)
63796425f44SHans Petter Selasky {
63896425f44SHans Petter Selasky struct mlx5e_priv *priv = arg1;
63996425f44SHans Petter Selasky int err;
64096425f44SHans Petter Selasky
64196425f44SHans Petter Selasky PRIV_LOCK(priv);
64296425f44SHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.fec_avail_50x,
64396425f44SHans Petter Selasky sizeof(priv->params_ethtool.fec_avail_50x));
64496425f44SHans Petter Selasky PRIV_UNLOCK(priv);
64596425f44SHans Petter Selasky return (err);
64696425f44SHans Petter Selasky }
64796425f44SHans Petter Selasky
648ed0cee0bSHans Petter Selasky static int
mlx5e_trust_state_handler(SYSCTL_HANDLER_ARGS)649ed0cee0bSHans Petter Selasky mlx5e_trust_state_handler(SYSCTL_HANDLER_ARGS)
650ed0cee0bSHans Petter Selasky {
651ed0cee0bSHans Petter Selasky struct mlx5e_priv *priv = arg1;
652ed0cee0bSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
653ed0cee0bSHans Petter Selasky int err;
654ed0cee0bSHans Petter Selasky u8 result;
655ed0cee0bSHans Petter Selasky
656ed0cee0bSHans Petter Selasky PRIV_LOCK(priv);
657ed0cee0bSHans Petter Selasky result = priv->params_ethtool.trust_state;
658ed0cee0bSHans Petter Selasky err = sysctl_handle_8(oidp, &result, 0, req);
659ed0cee0bSHans Petter Selasky if (err || !req->newptr ||
660ed0cee0bSHans Petter Selasky result == priv->params_ethtool.trust_state)
661ed0cee0bSHans Petter Selasky goto done;
662ed0cee0bSHans Petter Selasky
663ed0cee0bSHans Petter Selasky switch (result) {
664ed0cee0bSHans Petter Selasky case MLX5_QPTS_TRUST_PCP:
665ed0cee0bSHans Petter Selasky case MLX5_QPTS_TRUST_DSCP:
666ed0cee0bSHans Petter Selasky break;
667ed0cee0bSHans Petter Selasky case MLX5_QPTS_TRUST_BOTH:
668ed0cee0bSHans Petter Selasky if (!MLX5_CAP_QCAM_FEATURE(mdev, qpts_trust_both)) {
669ed0cee0bSHans Petter Selasky err = EOPNOTSUPP;
670ed0cee0bSHans Petter Selasky goto done;
671ed0cee0bSHans Petter Selasky }
672ed0cee0bSHans Petter Selasky break;
673ed0cee0bSHans Petter Selasky default:
674ed0cee0bSHans Petter Selasky err = ERANGE;
675ed0cee0bSHans Petter Selasky goto done;
676ed0cee0bSHans Petter Selasky }
677ed0cee0bSHans Petter Selasky
678ed0cee0bSHans Petter Selasky err = -mlx5_set_trust_state(mdev, result);
679ed0cee0bSHans Petter Selasky if (err)
680ed0cee0bSHans Petter Selasky goto done;
681ed0cee0bSHans Petter Selasky
682ed0cee0bSHans Petter Selasky priv->params_ethtool.trust_state = result;
6833e581cabSSlava Shwartsman
6843e581cabSSlava Shwartsman /* update inline mode */
6853e581cabSSlava Shwartsman mlx5e_refresh_sq_inline(priv);
6863e581cabSSlava Shwartsman #ifdef RATELIMIT
6873e581cabSSlava Shwartsman mlx5e_rl_refresh_sq_inline(&priv->rl);
6883e581cabSSlava Shwartsman #endif
689ed0cee0bSHans Petter Selasky done:
690ed0cee0bSHans Petter Selasky PRIV_UNLOCK(priv);
691ed0cee0bSHans Petter Selasky return (err);
692ed0cee0bSHans Petter Selasky }
693ed0cee0bSHans Petter Selasky
694ed0cee0bSHans Petter Selasky static int
mlx5e_dscp_prio_handler(SYSCTL_HANDLER_ARGS)695ed0cee0bSHans Petter Selasky mlx5e_dscp_prio_handler(SYSCTL_HANDLER_ARGS)
696ed0cee0bSHans Petter Selasky {
697ed0cee0bSHans Petter Selasky struct mlx5e_priv *priv = arg1;
698ed0cee0bSHans Petter Selasky int prio_index = arg2;
699ed0cee0bSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev;
700ed0cee0bSHans Petter Selasky uint8_t dscp2prio[MLX5_MAX_SUPPORTED_DSCP];
701ed0cee0bSHans Petter Selasky uint8_t x;
702ed0cee0bSHans Petter Selasky int err;
703ed0cee0bSHans Petter Selasky
704ed0cee0bSHans Petter Selasky PRIV_LOCK(priv);
705ed0cee0bSHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.dscp2prio + prio_index,
706ed0cee0bSHans Petter Selasky sizeof(priv->params_ethtool.dscp2prio) / 8);
707ed0cee0bSHans Petter Selasky if (err || !req->newptr)
708ed0cee0bSHans Petter Selasky goto done;
709ed0cee0bSHans Petter Selasky
710ed0cee0bSHans Petter Selasky memcpy(dscp2prio, priv->params_ethtool.dscp2prio, sizeof(dscp2prio));
711ed0cee0bSHans Petter Selasky err = SYSCTL_IN(req, dscp2prio + prio_index, sizeof(dscp2prio) / 8);
712ed0cee0bSHans Petter Selasky if (err)
713ed0cee0bSHans Petter Selasky goto done;
714ed0cee0bSHans Petter Selasky for (x = 0; x != MLX5_MAX_SUPPORTED_DSCP; x++) {
715ed0cee0bSHans Petter Selasky if (dscp2prio[x] > 7) {
716ed0cee0bSHans Petter Selasky err = ERANGE;
717ed0cee0bSHans Petter Selasky goto done;
718ed0cee0bSHans Petter Selasky }
719ed0cee0bSHans Petter Selasky }
720ed0cee0bSHans Petter Selasky err = -mlx5_set_dscp2prio(mdev, dscp2prio);
721ed0cee0bSHans Petter Selasky if (err)
722ed0cee0bSHans Petter Selasky goto done;
723ed0cee0bSHans Petter Selasky
724ed0cee0bSHans Petter Selasky /* update local array */
725ed0cee0bSHans Petter Selasky memcpy(priv->params_ethtool.dscp2prio, dscp2prio,
726ed0cee0bSHans Petter Selasky sizeof(priv->params_ethtool.dscp2prio));
727ed0cee0bSHans Petter Selasky done:
728ed0cee0bSHans Petter Selasky PRIV_UNLOCK(priv);
729ed0cee0bSHans Petter Selasky return (err);
730ed0cee0bSHans Petter Selasky }
731ed0cee0bSHans Petter Selasky
7326deb0b1eSHans Petter Selasky int
mlx5e_update_buf_lossy(struct mlx5e_priv * priv)7336deb0b1eSHans Petter Selasky mlx5e_update_buf_lossy(struct mlx5e_priv *priv)
7346deb0b1eSHans Petter Selasky {
7356deb0b1eSHans Petter Selasky struct ieee_pfc pfc;
7366deb0b1eSHans Petter Selasky
7376deb0b1eSHans Petter Selasky PRIV_ASSERT_LOCKED(priv);
7386deb0b1eSHans Petter Selasky bzero(&pfc, sizeof(pfc));
7396deb0b1eSHans Petter Selasky pfc.pfc_en = priv->params.rx_priority_flow_control;
7406deb0b1eSHans Petter Selasky return (-mlx5e_port_manual_buffer_config(priv, MLX5E_PORT_BUFFER_PFC,
7416deb0b1eSHans Petter Selasky priv->params_ethtool.hw_mtu, &pfc, NULL, NULL));
7426deb0b1eSHans Petter Selasky }
7436deb0b1eSHans Petter Selasky
7446deb0b1eSHans Petter Selasky static int
mlx5e_buf_size_handler(SYSCTL_HANDLER_ARGS)7456deb0b1eSHans Petter Selasky mlx5e_buf_size_handler(SYSCTL_HANDLER_ARGS)
7466deb0b1eSHans Petter Selasky {
7476deb0b1eSHans Petter Selasky struct mlx5e_priv *priv;
7486deb0b1eSHans Petter Selasky u32 buf_size[MLX5E_MAX_BUFFER];
7496deb0b1eSHans Petter Selasky struct mlx5e_port_buffer port_buffer;
7506deb0b1eSHans Petter Selasky int error, i;
7516deb0b1eSHans Petter Selasky
7526deb0b1eSHans Petter Selasky priv = arg1;
7536deb0b1eSHans Petter Selasky PRIV_LOCK(priv);
7546deb0b1eSHans Petter Selasky error = -mlx5e_port_query_buffer(priv, &port_buffer);
7556deb0b1eSHans Petter Selasky if (error != 0)
7566deb0b1eSHans Petter Selasky goto done;
7576deb0b1eSHans Petter Selasky for (i = 0; i < nitems(buf_size); i++)
7586deb0b1eSHans Petter Selasky buf_size[i] = port_buffer.buffer[i].size;
7596deb0b1eSHans Petter Selasky error = SYSCTL_OUT(req, buf_size, sizeof(buf_size));
7606deb0b1eSHans Petter Selasky if (error != 0 || req->newptr == NULL)
7616deb0b1eSHans Petter Selasky goto done;
7626deb0b1eSHans Petter Selasky error = SYSCTL_IN(req, buf_size, sizeof(buf_size));
7636deb0b1eSHans Petter Selasky if (error != 0)
7646deb0b1eSHans Petter Selasky goto done;
7656deb0b1eSHans Petter Selasky error = -mlx5e_port_manual_buffer_config(priv, MLX5E_PORT_BUFFER_SIZE,
7666deb0b1eSHans Petter Selasky priv->params_ethtool.hw_mtu, NULL, buf_size, NULL);
7676deb0b1eSHans Petter Selasky done:
7686deb0b1eSHans Petter Selasky PRIV_UNLOCK(priv);
7696deb0b1eSHans Petter Selasky return (error);
7706deb0b1eSHans Petter Selasky }
7716deb0b1eSHans Petter Selasky
7726deb0b1eSHans Petter Selasky static int
mlx5e_buf_prio_handler(SYSCTL_HANDLER_ARGS)7736deb0b1eSHans Petter Selasky mlx5e_buf_prio_handler(SYSCTL_HANDLER_ARGS)
7746deb0b1eSHans Petter Selasky {
7756deb0b1eSHans Petter Selasky struct mlx5e_priv *priv;
7766deb0b1eSHans Petter Selasky struct mlx5_core_dev *mdev;
7776deb0b1eSHans Petter Selasky u8 buffer[MLX5E_MAX_BUFFER];
7786deb0b1eSHans Petter Selasky int error;
7796deb0b1eSHans Petter Selasky
7806deb0b1eSHans Petter Selasky priv = arg1;
7816deb0b1eSHans Petter Selasky mdev = priv->mdev;
7826deb0b1eSHans Petter Selasky PRIV_LOCK(priv);
7836deb0b1eSHans Petter Selasky error = -mlx5e_port_query_priority2buffer(mdev, buffer);
7846deb0b1eSHans Petter Selasky if (error != 0)
7856deb0b1eSHans Petter Selasky goto done;
7866deb0b1eSHans Petter Selasky error = SYSCTL_OUT(req, buffer, MLX5E_MAX_BUFFER);
7876deb0b1eSHans Petter Selasky if (error != 0 || req->newptr == NULL)
7886deb0b1eSHans Petter Selasky goto done;
7896deb0b1eSHans Petter Selasky error = SYSCTL_IN(req, buffer, MLX5E_MAX_BUFFER);
7906deb0b1eSHans Petter Selasky if (error != 0)
7916deb0b1eSHans Petter Selasky goto done;
7926deb0b1eSHans Petter Selasky error = -mlx5e_port_manual_buffer_config(priv,
7936deb0b1eSHans Petter Selasky MLX5E_PORT_BUFFER_PRIO2BUFFER,
7946deb0b1eSHans Petter Selasky priv->params_ethtool.hw_mtu, NULL, NULL, buffer);
7956deb0b1eSHans Petter Selasky if (error == 0)
7966deb0b1eSHans Petter Selasky error = mlx5e_update_buf_lossy(priv);
7976deb0b1eSHans Petter Selasky done:
7986deb0b1eSHans Petter Selasky PRIV_UNLOCK(priv);
7996deb0b1eSHans Petter Selasky return (error);
8006deb0b1eSHans Petter Selasky }
8016deb0b1eSHans Petter Selasky
8026deb0b1eSHans Petter Selasky static int
mlx5e_cable_length_handler(SYSCTL_HANDLER_ARGS)8036deb0b1eSHans Petter Selasky mlx5e_cable_length_handler(SYSCTL_HANDLER_ARGS)
8046deb0b1eSHans Petter Selasky {
8056deb0b1eSHans Petter Selasky struct mlx5e_priv *priv;
8066deb0b1eSHans Petter Selasky u_int cable_len;
8076deb0b1eSHans Petter Selasky int error;
8086deb0b1eSHans Petter Selasky
8096deb0b1eSHans Petter Selasky priv = arg1;
8106deb0b1eSHans Petter Selasky PRIV_LOCK(priv);
8116deb0b1eSHans Petter Selasky cable_len = priv->dcbx.cable_len;
8126deb0b1eSHans Petter Selasky error = sysctl_handle_int(oidp, &cable_len, 0, req);
8136deb0b1eSHans Petter Selasky if (error == 0 && req->newptr != NULL &&
8146deb0b1eSHans Petter Selasky cable_len != priv->dcbx.cable_len) {
8156deb0b1eSHans Petter Selasky error = -mlx5e_port_manual_buffer_config(priv,
8166deb0b1eSHans Petter Selasky MLX5E_PORT_BUFFER_CABLE_LEN, priv->params_ethtool.hw_mtu,
8176deb0b1eSHans Petter Selasky NULL, NULL, NULL);
8186deb0b1eSHans Petter Selasky if (error == 0)
8196deb0b1eSHans Petter Selasky priv->dcbx.cable_len = cable_len;
8206deb0b1eSHans Petter Selasky }
8216deb0b1eSHans Petter Selasky PRIV_UNLOCK(priv);
8226deb0b1eSHans Petter Selasky return (error);
8236deb0b1eSHans Petter Selasky }
8246deb0b1eSHans Petter Selasky
825decb087cSHans Petter Selasky static int
mlx5e_hw_temperature_handler(SYSCTL_HANDLER_ARGS)826decb087cSHans Petter Selasky mlx5e_hw_temperature_handler(SYSCTL_HANDLER_ARGS)
827decb087cSHans Petter Selasky {
828decb087cSHans Petter Selasky struct mlx5e_priv *priv = arg1;
829decb087cSHans Petter Selasky int err;
830decb087cSHans Petter Selasky
831decb087cSHans Petter Selasky PRIV_LOCK(priv);
832decb087cSHans Petter Selasky err = SYSCTL_OUT(req, priv->params_ethtool.hw_val_temp,
833decb087cSHans Petter Selasky sizeof(priv->params_ethtool.hw_val_temp[0]) *
834decb087cSHans Petter Selasky priv->params_ethtool.hw_num_temp);
835decb087cSHans Petter Selasky if (err == 0 && req->newptr != NULL)
836decb087cSHans Petter Selasky err = EOPNOTSUPP;
837decb087cSHans Petter Selasky PRIV_UNLOCK(priv);
838decb087cSHans Petter Selasky return (err);
839decb087cSHans Petter Selasky }
840decb087cSHans Petter Selasky
841decb087cSHans Petter Selasky int
mlx5e_hw_temperature_update(struct mlx5e_priv * priv)842decb087cSHans Petter Selasky mlx5e_hw_temperature_update(struct mlx5e_priv *priv)
843decb087cSHans Petter Selasky {
844decb087cSHans Petter Selasky int err;
845decb087cSHans Petter Selasky u32 x;
846decb087cSHans Petter Selasky
847decb087cSHans Petter Selasky if (priv->params_ethtool.hw_num_temp == 0) {
848decb087cSHans Petter Selasky u32 out_cap[MLX5_ST_SZ_DW(mtcap)] = {};
849decb087cSHans Petter Selasky const int sz_cap = MLX5_ST_SZ_BYTES(mtcap);
850decb087cSHans Petter Selasky u32 value;
851decb087cSHans Petter Selasky
852decb087cSHans Petter Selasky err = -mlx5_core_access_reg(priv->mdev, NULL, 0, out_cap, sz_cap,
853decb087cSHans Petter Selasky MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTCAP, 0, 0);
854decb087cSHans Petter Selasky if (err)
855decb087cSHans Petter Selasky goto done;
856decb087cSHans Petter Selasky value = MLX5_GET(mtcap, out_cap, sensor_count);
857decb087cSHans Petter Selasky if (value == 0)
858decb087cSHans Petter Selasky return (0);
859decb087cSHans Petter Selasky if (value > MLX5_MAX_TEMPERATURE)
860decb087cSHans Petter Selasky value = MLX5_MAX_TEMPERATURE;
861decb087cSHans Petter Selasky /* update number of temperature sensors */
862decb087cSHans Petter Selasky priv->params_ethtool.hw_num_temp = value;
863decb087cSHans Petter Selasky }
864decb087cSHans Petter Selasky
865decb087cSHans Petter Selasky for (x = 0; x != priv->params_ethtool.hw_num_temp; x++) {
866decb087cSHans Petter Selasky u32 out_sensor[MLX5_ST_SZ_DW(mtmp_reg)] = {};
867decb087cSHans Petter Selasky const int sz_sensor = MLX5_ST_SZ_BYTES(mtmp_reg);
868decb087cSHans Petter Selasky
869decb087cSHans Petter Selasky MLX5_SET(mtmp_reg, out_sensor, sensor_index, x);
870decb087cSHans Petter Selasky
871decb087cSHans Petter Selasky err = -mlx5_core_access_reg(priv->mdev, out_sensor, sz_sensor,
872decb087cSHans Petter Selasky out_sensor, sz_sensor,
873decb087cSHans Petter Selasky MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTMP, 0, 0);
874decb087cSHans Petter Selasky if (err)
875decb087cSHans Petter Selasky goto done;
8769097ac9aSElyes HAOUAS /* convert from 0.125 celsius to millicelsius */
877decb087cSHans Petter Selasky priv->params_ethtool.hw_val_temp[x] =
878decb087cSHans Petter Selasky (s16)MLX5_GET(mtmp_reg, out_sensor, temperature) * 125;
879decb087cSHans Petter Selasky }
880decb087cSHans Petter Selasky done:
881decb087cSHans Petter Selasky return (err);
882decb087cSHans Petter Selasky }
883decb087cSHans Petter Selasky
88482d2623eSHans Petter Selasky #define MLX5_PARAM_OFFSET(n) \
88582d2623eSHans Petter Selasky __offsetof(struct mlx5e_priv, params_ethtool.n)
88682d2623eSHans Petter Selasky
887dc7e38acSHans Petter Selasky static int
mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)888dc7e38acSHans Petter Selasky mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
889dc7e38acSHans Petter Selasky {
890dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1;
891dc7e38acSHans Petter Selasky uint64_t value;
892d2bf00a9SHans Petter Selasky int mode_modify;
893dc7e38acSHans Petter Selasky int was_opened;
894dc7e38acSHans Petter Selasky int error;
895dc7e38acSHans Petter Selasky
896dc7e38acSHans Petter Selasky PRIV_LOCK(priv);
897dc7e38acSHans Petter Selasky value = priv->params_ethtool.arg[arg2];
898ec0143b2SHans Petter Selasky if (req != NULL) {
899dc7e38acSHans Petter Selasky error = sysctl_handle_64(oidp, &value, 0, req);
900dc7e38acSHans Petter Selasky if (error || req->newptr == NULL ||
901dc7e38acSHans Petter Selasky value == priv->params_ethtool.arg[arg2])
902dc7e38acSHans Petter Selasky goto done;
903dc7e38acSHans Petter Selasky
904dc7e38acSHans Petter Selasky /* assign new value */
905dc7e38acSHans Petter Selasky priv->params_ethtool.arg[arg2] = value;
906ec0143b2SHans Petter Selasky } else {
907ec0143b2SHans Petter Selasky error = 0;
908ec0143b2SHans Petter Selasky }
909dc7e38acSHans Petter Selasky /* check if device is gone */
910dc7e38acSHans Petter Selasky if (priv->gone) {
911dc7e38acSHans Petter Selasky error = ENXIO;
912dc7e38acSHans Petter Selasky goto done;
913dc7e38acSHans Petter Selasky }
91482d2623eSHans Petter Selasky was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
915d2bf00a9SHans Petter Selasky mode_modify = MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify);
91682d2623eSHans Petter Selasky
91782d2623eSHans Petter Selasky switch (MLX5_PARAM_OFFSET(arg[arg2])) {
91882d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_usecs):
919f03f517bSHans Petter Selasky /* import RX coal time */
920f03f517bSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_usecs < 1)
921f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = 0;
922f03f517bSHans Petter Selasky else if (priv->params_ethtool.rx_coalesce_usecs >
923f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period)) {
924f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs =
925f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period);
926f03f517bSHans Petter Selasky }
92782d2623eSHans Petter Selasky priv->params.rx_cq_moderation_usec =
92882d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs;
929f03f517bSHans Petter Selasky
93082d2623eSHans Petter Selasky /* check to avoid down and up the network interface */
93182d2623eSHans Petter Selasky if (was_opened)
93282d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv);
93382d2623eSHans Petter Selasky break;
93482d2623eSHans Petter Selasky
93582d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_pkts):
936f03f517bSHans Petter Selasky /* import RX coal pkts */
937f03f517bSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_pkts < 1)
938f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = 0;
939f03f517bSHans Petter Selasky else if (priv->params_ethtool.rx_coalesce_pkts >
940f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count)) {
941f03f517bSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts =
942f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count);
943f03f517bSHans Petter Selasky }
94482d2623eSHans Petter Selasky priv->params.rx_cq_moderation_pkts =
94582d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts;
946f03f517bSHans Petter Selasky
94782d2623eSHans Petter Selasky /* check to avoid down and up the network interface */
94882d2623eSHans Petter Selasky if (was_opened)
94982d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv);
95082d2623eSHans Petter Selasky break;
95182d2623eSHans Petter Selasky
95282d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_usecs):
953f03f517bSHans Petter Selasky /* import TX coal time */
954f03f517bSHans Petter Selasky if (priv->params_ethtool.tx_coalesce_usecs < 1)
955f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = 0;
956f03f517bSHans Petter Selasky else if (priv->params_ethtool.tx_coalesce_usecs >
957f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period)) {
958f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs =
959f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_period);
960f03f517bSHans Petter Selasky }
96182d2623eSHans Petter Selasky priv->params.tx_cq_moderation_usec =
96282d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs;
963f03f517bSHans Petter Selasky
96482d2623eSHans Petter Selasky /* check to avoid down and up the network interface */
96582d2623eSHans Petter Selasky if (was_opened)
96682d2623eSHans Petter Selasky error = mlx5e_refresh_channel_params(priv);
96782d2623eSHans Petter Selasky break;
96882d2623eSHans Petter Selasky
96982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_pkts):
970f03f517bSHans Petter Selasky /* import TX coal pkts */
971f03f517bSHans Petter Selasky if (priv->params_ethtool.tx_coalesce_pkts < 1)
972f03f517bSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = 0;
973f03f517bSHans Petter Selasky else if (priv->params_ethtool.tx_coalesce_pkts >
974f03f517bSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count)) {
97582d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts =
97682d2623eSHans Petter Selasky MLX5E_FLD_MAX(cqc, cq_max_count);
977f03f517bSHans Petter Selasky }
97882d2623eSHans Petter Selasky priv->params.tx_cq_moderation_pkts =
97982d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts;
980dc7e38acSHans Petter Selasky
98182d2623eSHans Petter Selasky /* check to avoid down and up the network interface */
98282d2623eSHans Petter Selasky if (was_opened)
983f03f517bSHans Petter Selasky error = mlx5e_refresh_channel_params(priv);
98482d2623eSHans Petter Selasky break;
98582d2623eSHans Petter Selasky
98682d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_queue_size):
98782d2623eSHans Petter Selasky /* network interface must be down */
98882d2623eSHans Petter Selasky if (was_opened)
989f03f517bSHans Petter Selasky mlx5e_close_locked(priv->ifp);
99082d2623eSHans Petter Selasky
991dc7e38acSHans Petter Selasky /* import TX queue size */
992dc7e38acSHans Petter Selasky if (priv->params_ethtool.tx_queue_size <
993dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
994dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size =
995dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE);
996dc7e38acSHans Petter Selasky } else if (priv->params_ethtool.tx_queue_size >
997dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max) {
998dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size =
999dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max;
1000dc7e38acSHans Petter Selasky }
100182d2623eSHans Petter Selasky /* store actual TX queue size */
1002dc7e38acSHans Petter Selasky priv->params.log_sq_size =
1003dc7e38acSHans Petter Selasky order_base_2(priv->params_ethtool.tx_queue_size);
100482d2623eSHans Petter Selasky priv->params_ethtool.tx_queue_size =
100582d2623eSHans Petter Selasky 1 << priv->params.log_sq_size;
100682d2623eSHans Petter Selasky
100782d2623eSHans Petter Selasky /* verify TX completion factor */
100882d2623eSHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv);
100982d2623eSHans Petter Selasky
101082d2623eSHans Petter Selasky /* restart network interface, if any */
101182d2623eSHans Petter Selasky if (was_opened)
101282d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp);
101382d2623eSHans Petter Selasky break;
101482d2623eSHans Petter Selasky
101582d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_queue_size):
101682d2623eSHans Petter Selasky /* network interface must be down */
101782d2623eSHans Petter Selasky if (was_opened)
101882d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp);
1019dc7e38acSHans Petter Selasky
1020dc7e38acSHans Petter Selasky /* import RX queue size */
1021dc7e38acSHans Petter Selasky if (priv->params_ethtool.rx_queue_size <
1022dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) {
1023dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size =
1024dc7e38acSHans Petter Selasky (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE);
1025dc7e38acSHans Petter Selasky } else if (priv->params_ethtool.rx_queue_size >
1026dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max) {
1027dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size =
1028dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max;
1029dc7e38acSHans Petter Selasky }
103082d2623eSHans Petter Selasky /* store actual RX queue size */
1031dc7e38acSHans Petter Selasky priv->params.log_rq_size =
1032dc7e38acSHans Petter Selasky order_base_2(priv->params_ethtool.rx_queue_size);
103382d2623eSHans Petter Selasky priv->params_ethtool.rx_queue_size =
103482d2623eSHans Petter Selasky 1 << priv->params.log_rq_size;
1035dc7e38acSHans Petter Selasky
103682d2623eSHans Petter Selasky /* restart network interface, if any */
103782d2623eSHans Petter Selasky if (was_opened)
103882d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp);
103982d2623eSHans Petter Selasky break;
104082d2623eSHans Petter Selasky
104116ae32f9SHans Petter Selasky case MLX5_PARAM_OFFSET(channels_rsss):
104216ae32f9SHans Petter Selasky /* network interface must be down */
104316ae32f9SHans Petter Selasky if (was_opened)
104416ae32f9SHans Petter Selasky mlx5e_close_locked(priv->ifp);
104516ae32f9SHans Petter Selasky
104616ae32f9SHans Petter Selasky /* import number of channels */
104716ae32f9SHans Petter Selasky if (priv->params_ethtool.channels_rsss < 1)
104816ae32f9SHans Petter Selasky priv->params_ethtool.channels_rsss = 1;
104916ae32f9SHans Petter Selasky else if (priv->params_ethtool.channels_rsss > 128)
105016ae32f9SHans Petter Selasky priv->params_ethtool.channels_rsss = 128;
105116ae32f9SHans Petter Selasky
105216ae32f9SHans Petter Selasky priv->params.channels_rsss = priv->params_ethtool.channels_rsss;
105316ae32f9SHans Petter Selasky
105416ae32f9SHans Petter Selasky /* restart network interface, if any */
105516ae32f9SHans Petter Selasky if (was_opened)
105616ae32f9SHans Petter Selasky mlx5e_open_locked(priv->ifp);
105716ae32f9SHans Petter Selasky break;
105816ae32f9SHans Petter Selasky
105982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(channels):
106082d2623eSHans Petter Selasky /* network interface must be down */
106182d2623eSHans Petter Selasky if (was_opened)
106282d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp);
106382d2623eSHans Petter Selasky
1064dc7e38acSHans Petter Selasky /* import number of channels */
1065dc7e38acSHans Petter Selasky if (priv->params_ethtool.channels < 1)
1066dc7e38acSHans Petter Selasky priv->params_ethtool.channels = 1;
1067dc7e38acSHans Petter Selasky else if (priv->params_ethtool.channels >
1068dc7e38acSHans Petter Selasky (u64) priv->mdev->priv.eq_table.num_comp_vectors) {
1069dc7e38acSHans Petter Selasky priv->params_ethtool.channels =
1070dc7e38acSHans Petter Selasky (u64) priv->mdev->priv.eq_table.num_comp_vectors;
1071dc7e38acSHans Petter Selasky }
1072dc7e38acSHans Petter Selasky priv->params.num_channels = priv->params_ethtool.channels;
1073dc7e38acSHans Petter Selasky
107482d2623eSHans Petter Selasky /* restart network interface, if any */
107582d2623eSHans Petter Selasky if (was_opened)
107682d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp);
107782d2623eSHans Petter Selasky break;
107882d2623eSHans Petter Selasky
107982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(rx_coalesce_mode):
108082d2623eSHans Petter Selasky /* network interface must be down */
1081d2bf00a9SHans Petter Selasky if (was_opened != 0 && mode_modify == 0)
108282d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp);
108382d2623eSHans Petter Selasky
108482d2623eSHans Petter Selasky /* import RX coalesce mode */
1085423530beSHans Petter Selasky if (priv->params_ethtool.rx_coalesce_mode > 3)
1086423530beSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode = 3;
108782d2623eSHans Petter Selasky priv->params.rx_cq_moderation_mode =
108882d2623eSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode;
1089dc7e38acSHans Petter Selasky
109082d2623eSHans Petter Selasky /* restart network interface, if any */
1091d2bf00a9SHans Petter Selasky if (was_opened != 0) {
1092d2bf00a9SHans Petter Selasky if (mode_modify == 0)
109382d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp);
1094d2bf00a9SHans Petter Selasky else
1095d2bf00a9SHans Petter Selasky error = mlx5e_refresh_channel_params(priv);
1096d2bf00a9SHans Petter Selasky }
109782d2623eSHans Petter Selasky break;
109882d2623eSHans Petter Selasky
109982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_coalesce_mode):
110082d2623eSHans Petter Selasky /* network interface must be down */
1101d2bf00a9SHans Petter Selasky if (was_opened != 0 && mode_modify == 0)
110282d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp);
110382d2623eSHans Petter Selasky
110482d2623eSHans Petter Selasky /* import TX coalesce mode */
110574540a31SHans Petter Selasky if (priv->params_ethtool.tx_coalesce_mode != 0)
110674540a31SHans Petter Selasky priv->params_ethtool.tx_coalesce_mode = 1;
110782d2623eSHans Petter Selasky priv->params.tx_cq_moderation_mode =
110882d2623eSHans Petter Selasky priv->params_ethtool.tx_coalesce_mode;
110974540a31SHans Petter Selasky
111082d2623eSHans Petter Selasky /* restart network interface, if any */
1111d2bf00a9SHans Petter Selasky if (was_opened != 0) {
1112d2bf00a9SHans Petter Selasky if (mode_modify == 0)
111382d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp);
1114d2bf00a9SHans Petter Selasky else
1115d2bf00a9SHans Petter Selasky error = mlx5e_refresh_channel_params(priv);
1116d2bf00a9SHans Petter Selasky }
111782d2623eSHans Petter Selasky break;
111882d2623eSHans Petter Selasky
111982d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(hw_lro):
112082d2623eSHans Petter Selasky /* network interface must be down */
112182d2623eSHans Petter Selasky if (was_opened)
112282d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp);
112382d2623eSHans Petter Selasky
112482d2623eSHans Petter Selasky /* import HW LRO mode */
112571defedaSSlava Shwartsman if (priv->params_ethtool.hw_lro != 0 &&
1126d7633a30SHans Petter Selasky MLX5_CAP_ETH(priv->mdev, lro_cap)) {
112771defedaSSlava Shwartsman priv->params.hw_lro_en = true;
1128816f27e8SKonstantin Belousov priv->params_ethtool.hw_lro = 1;
1129bb3853c6SHans Petter Selasky } else {
113071defedaSSlava Shwartsman /* return an error if HW does not support this feature */
113171defedaSSlava Shwartsman if (priv->params_ethtool.hw_lro != 0)
113271defedaSSlava Shwartsman error = EINVAL;
113371defedaSSlava Shwartsman priv->params.hw_lro_en = false;
113471defedaSSlava Shwartsman priv->params_ethtool.hw_lro = 0;
1135dc7e38acSHans Petter Selasky }
113602fe38b9SKonstantin Belousov
113702fe38b9SKonstantin Belousov error = mlx5e_hw_lro_update_tirs(priv);
113802fe38b9SKonstantin Belousov
1139*93e70e3aSKonstantin Belousov /*
1140*93e70e3aSKonstantin Belousov * Restart network interface, if any. This
1141*93e70e3aSKonstantin Belousov * re-populates rx wqes with proper segment sizes.
1142*93e70e3aSKonstantin Belousov */
114382d2623eSHans Petter Selasky if (was_opened)
114482d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp);
114582d2623eSHans Petter Selasky break;
1146dc7e38acSHans Petter Selasky
114782d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(cqe_zipping):
114882d2623eSHans Petter Selasky /* network interface must be down */
114982d2623eSHans Petter Selasky if (was_opened)
115082d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp);
115182d2623eSHans Petter Selasky
115282d2623eSHans Petter Selasky /* import CQE zipping mode */
115390cc1c77SHans Petter Selasky if (priv->params_ethtool.cqe_zipping &&
115490cc1c77SHans Petter Selasky MLX5_CAP_GEN(priv->mdev, cqe_compression)) {
115590cc1c77SHans Petter Selasky priv->params.cqe_zipping_en = true;
115690cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = 1;
115790cc1c77SHans Petter Selasky } else {
115890cc1c77SHans Petter Selasky priv->params.cqe_zipping_en = false;
115990cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = 0;
116090cc1c77SHans Petter Selasky }
116182d2623eSHans Petter Selasky /* restart network interface, if any */
1162dc7e38acSHans Petter Selasky if (was_opened)
1163dc7e38acSHans Petter Selasky mlx5e_open_locked(priv->ifp);
116482d2623eSHans Petter Selasky break;
116582d2623eSHans Petter Selasky
116682d2623eSHans Petter Selasky case MLX5_PARAM_OFFSET(tx_completion_fact):
116782d2623eSHans Petter Selasky /* network interface must be down */
116882d2623eSHans Petter Selasky if (was_opened)
116982d2623eSHans Petter Selasky mlx5e_close_locked(priv->ifp);
117082d2623eSHans Petter Selasky
117182d2623eSHans Petter Selasky /* verify parameter */
117282d2623eSHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv);
117382d2623eSHans Petter Selasky
117482d2623eSHans Petter Selasky /* restart network interface, if any */
117582d2623eSHans Petter Selasky if (was_opened)
117682d2623eSHans Petter Selasky mlx5e_open_locked(priv->ifp);
117782d2623eSHans Petter Selasky break;
117882d2623eSHans Petter Selasky
1179bb3616abSHans Petter Selasky case MLX5_PARAM_OFFSET(modify_tx_dma):
1180bb3616abSHans Petter Selasky /* check if network interface is opened */
1181bb3616abSHans Petter Selasky if (was_opened) {
1182bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma =
1183bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma ? 1 : 0;
1184bb3616abSHans Petter Selasky /* modify tx according to value */
1185bb3616abSHans Petter Selasky mlx5e_modify_tx_dma(priv, value != 0);
1186bb3616abSHans Petter Selasky } else {
1187bb3616abSHans Petter Selasky /* if closed force enable tx */
1188bb3616abSHans Petter Selasky priv->params_ethtool.modify_tx_dma = 0;
1189bb3616abSHans Petter Selasky }
1190bb3616abSHans Petter Selasky break;
1191bb3616abSHans Petter Selasky
1192bb3616abSHans Petter Selasky case MLX5_PARAM_OFFSET(modify_rx_dma):
1193bb3616abSHans Petter Selasky /* check if network interface is opened */
1194bb3616abSHans Petter Selasky if (was_opened) {
1195bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma =
1196bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma ? 1 : 0;
1197bb3616abSHans Petter Selasky /* modify rx according to value */
1198bb3616abSHans Petter Selasky mlx5e_modify_rx_dma(priv, value != 0);
1199bb3616abSHans Petter Selasky } else {
1200bb3616abSHans Petter Selasky /* if closed force enable rx */
1201bb3616abSHans Petter Selasky priv->params_ethtool.modify_rx_dma = 0;
1202bb3616abSHans Petter Selasky }
1203bb3616abSHans Petter Selasky break;
1204bb3616abSHans Petter Selasky
120566d53750SHans Petter Selasky case MLX5_PARAM_OFFSET(diag_pci_enable):
120666d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable =
120766d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable ? 1 : 0;
120866d53750SHans Petter Selasky
120966d53750SHans Petter Selasky error = -mlx5_core_set_diagnostics_full(priv->mdev,
121066d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable,
121166d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable);
121266d53750SHans Petter Selasky break;
121366d53750SHans Petter Selasky
121466d53750SHans Petter Selasky case MLX5_PARAM_OFFSET(diag_general_enable):
121566d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable =
121666d53750SHans Petter Selasky priv->params_ethtool.diag_general_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
122361fd7ac0SHans Petter Selasky case MLX5_PARAM_OFFSET(mc_local_lb):
1224ea00d7e8SHans Petter Selasky /* check if mlx5ib is managing this feature */
1225ea00d7e8SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) {
1226ea00d7e8SHans Petter Selasky error = EOPNOTSUPP;
1227ea00d7e8SHans Petter Selasky break;
1228ea00d7e8SHans Petter Selasky }
1229ea00d7e8SHans Petter Selasky
123061fd7ac0SHans Petter Selasky priv->params_ethtool.mc_local_lb =
123161fd7ac0SHans Petter Selasky priv->params_ethtool.mc_local_lb ? 1 : 0;
123261fd7ac0SHans Petter Selasky
1233c1b76119SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, disable_local_lb_mc)) {
123461fd7ac0SHans Petter Selasky error = mlx5_nic_vport_modify_local_lb(priv->mdev,
123561fd7ac0SHans Petter Selasky MLX5_LOCAL_MC_LB, priv->params_ethtool.mc_local_lb);
123661fd7ac0SHans Petter Selasky } else {
123761fd7ac0SHans Petter Selasky error = EOPNOTSUPP;
123861fd7ac0SHans Petter Selasky }
123961fd7ac0SHans Petter Selasky break;
124061fd7ac0SHans Petter Selasky
124161fd7ac0SHans Petter Selasky case MLX5_PARAM_OFFSET(uc_local_lb):
1242ea00d7e8SHans Petter Selasky /* check if mlx5ib is managing this feature */
1243ea00d7e8SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) {
1244ea00d7e8SHans Petter Selasky error = EOPNOTSUPP;
1245ea00d7e8SHans Petter Selasky break;
1246ea00d7e8SHans Petter Selasky }
1247ea00d7e8SHans Petter Selasky
124861fd7ac0SHans Petter Selasky priv->params_ethtool.uc_local_lb =
124961fd7ac0SHans Petter Selasky priv->params_ethtool.uc_local_lb ? 1 : 0;
125061fd7ac0SHans Petter Selasky
1251c1b76119SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, disable_local_lb_uc)) {
125261fd7ac0SHans Petter Selasky error = mlx5_nic_vport_modify_local_lb(priv->mdev,
125361fd7ac0SHans Petter Selasky MLX5_LOCAL_UC_LB, priv->params_ethtool.uc_local_lb);
125461fd7ac0SHans Petter Selasky } else {
125561fd7ac0SHans Petter Selasky error = EOPNOTSUPP;
125661fd7ac0SHans Petter Selasky }
125761fd7ac0SHans Petter Selasky break;
125861fd7ac0SHans Petter Selasky
1259c8d16d1eSHans Petter Selasky case MLX5_PARAM_OFFSET(irq_cpu_base):
1260c8d16d1eSHans Petter Selasky case MLX5_PARAM_OFFSET(irq_cpu_stride):
1261c8d16d1eSHans Petter Selasky if (was_opened) {
1262c8d16d1eSHans Petter Selasky /* network interface must toggled */
1263c8d16d1eSHans Petter Selasky mlx5e_close_locked(priv->ifp);
1264c8d16d1eSHans Petter Selasky mlx5e_open_locked(priv->ifp);
1265c8d16d1eSHans Petter Selasky }
1266c8d16d1eSHans Petter Selasky break;
1267c8d16d1eSHans Petter Selasky
126882d2623eSHans Petter Selasky default:
126982d2623eSHans Petter Selasky break;
127082d2623eSHans Petter Selasky }
1271dc7e38acSHans Petter Selasky done:
1272dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv);
1273dc7e38acSHans Petter Selasky return (error);
1274dc7e38acSHans Petter Selasky }
1275dc7e38acSHans Petter Selasky
1276dc7e38acSHans Petter Selasky static const char *mlx5e_params_desc[] = {
1277dc7e38acSHans Petter Selasky MLX5E_PARAMS(MLX5E_STATS_DESC)
1278dc7e38acSHans Petter Selasky };
1279dc7e38acSHans Petter Selasky
1280dc7e38acSHans Petter Selasky static const char *mlx5e_port_stats_debug_desc[] = {
1281dc7e38acSHans Petter Selasky MLX5E_PORT_STATS_DEBUG(MLX5E_STATS_DESC)
1282dc7e38acSHans Petter Selasky };
1283dc7e38acSHans Petter Selasky
1284dc7e38acSHans Petter Selasky static int
mlx5e_ethtool_debug_channel_info(SYSCTL_HANDLER_ARGS)1285f2b4782cSHans Petter Selasky mlx5e_ethtool_debug_channel_info(SYSCTL_HANDLER_ARGS)
1286f2b4782cSHans Petter Selasky {
1287f2b4782cSHans Petter Selasky struct mlx5e_priv *priv;
1288f2b4782cSHans Petter Selasky struct sbuf sb;
1289f2b4782cSHans Petter Selasky struct mlx5e_channel *c;
1290f2b4782cSHans Petter Selasky struct mlx5e_sq *sq;
1291f2b4782cSHans Petter Selasky struct mlx5e_rq *rq;
1292f2b4782cSHans Petter Selasky int error, i, tc;
12932110251aSHans Petter Selasky bool opened;
1294f2b4782cSHans Petter Selasky
1295f2b4782cSHans Petter Selasky priv = arg1;
1296f2b4782cSHans Petter Selasky error = sysctl_wire_old_buffer(req, 0);
1297f2b4782cSHans Petter Selasky if (error != 0)
1298f2b4782cSHans Petter Selasky return (error);
12992110251aSHans Petter Selasky if (sbuf_new_for_sysctl(&sb, NULL, 1024, req) == NULL)
1300f2b4782cSHans Petter Selasky return (ENOMEM);
1301f2b4782cSHans Petter Selasky sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
1302f2b4782cSHans Petter Selasky
1303f2b4782cSHans Petter Selasky PRIV_LOCK(priv);
13042110251aSHans Petter Selasky opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
13052110251aSHans Petter Selasky
13062110251aSHans Petter Selasky sbuf_printf(&sb, "pages irq %d\n",
13072110251aSHans Petter Selasky priv->mdev->priv.msix_arr[MLX5_EQ_VEC_PAGES].vector);
13082110251aSHans Petter Selasky sbuf_printf(&sb, "command irq %d\n",
13092110251aSHans Petter Selasky priv->mdev->priv.msix_arr[MLX5_EQ_VEC_CMD].vector);
13102110251aSHans Petter Selasky sbuf_printf(&sb, "async irq %d\n",
13112110251aSHans Petter Selasky priv->mdev->priv.msix_arr[MLX5_EQ_VEC_ASYNC].vector);
13122110251aSHans Petter Selasky
13132110251aSHans Petter Selasky for (i = 0; i != priv->params.num_channels; i++) {
13142110251aSHans Petter Selasky int eqn_not_used = -1;
13152110251aSHans Petter Selasky int irqn = MLX5_EQ_VEC_COMP_BASE;
13162110251aSHans Petter Selasky
13172110251aSHans Petter Selasky if (mlx5_vector2eqn(priv->mdev, i, &eqn_not_used, &irqn) != 0)
13182110251aSHans Petter Selasky continue;
13192110251aSHans Petter Selasky
13202110251aSHans Petter Selasky c = opened ? &priv->channel[i] : NULL;
13212110251aSHans Petter Selasky rq = opened ? &c->rq : NULL;
13222110251aSHans Petter Selasky sbuf_printf(&sb, "channel %d rq %d cq %d irq %d\n", i,
13232110251aSHans Petter Selasky opened ? rq->rqn : -1,
13242110251aSHans Petter Selasky opened ? rq->cq.mcq.cqn : -1,
13252110251aSHans Petter Selasky priv->mdev->priv.msix_arr[irqn].vector);
13262110251aSHans Petter Selasky
13272110251aSHans Petter Selasky for (tc = 0; tc != priv->num_tc; tc++) {
13282110251aSHans Petter Selasky sq = opened ? &c->sq[tc] : NULL;
13292110251aSHans Petter Selasky sbuf_printf(&sb, "channel %d tc %d sq %d cq %d irq %d\n",
13302110251aSHans Petter Selasky i, tc,
13312110251aSHans Petter Selasky opened ? sq->sqn : -1,
13322110251aSHans Petter Selasky opened ? sq->cq.mcq.cqn : -1,
13332110251aSHans Petter Selasky priv->mdev->priv.msix_arr[irqn].vector);
1334f2b4782cSHans Petter Selasky }
1335f2b4782cSHans Petter Selasky }
1336f2b4782cSHans Petter Selasky PRIV_UNLOCK(priv);
1337f2b4782cSHans Petter Selasky error = sbuf_finish(&sb);
1338f2b4782cSHans Petter Selasky sbuf_delete(&sb);
1339f2b4782cSHans Petter Selasky return (error);
1340f2b4782cSHans Petter Selasky }
1341f2b4782cSHans Petter Selasky
1342f2b4782cSHans Petter Selasky static int
mlx5e_ethtool_debug_stats(SYSCTL_HANDLER_ARGS)1343dc7e38acSHans Petter Selasky mlx5e_ethtool_debug_stats(SYSCTL_HANDLER_ARGS)
1344dc7e38acSHans Petter Selasky {
1345dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1;
1346b3cf1493SSlava Shwartsman int sys_debug;
1347b3cf1493SSlava Shwartsman int error;
1348f2b4782cSHans Petter Selasky
1349f2b4782cSHans Petter Selasky PRIV_LOCK(priv);
1350069963d7SHans Petter Selasky if (priv->gone != 0) {
1351069963d7SHans Petter Selasky error = ENODEV;
1352069963d7SHans Petter Selasky goto done;
1353069963d7SHans Petter Selasky }
1354b3cf1493SSlava Shwartsman sys_debug = priv->sysctl_debug;
1355b3cf1493SSlava Shwartsman error = sysctl_handle_int(oidp, &sys_debug, 0, req);
1356b3cf1493SSlava Shwartsman if (error != 0 || !req->newptr)
1357b3cf1493SSlava Shwartsman goto done;
1358b3cf1493SSlava Shwartsman sys_debug = sys_debug ? 1 : 0;
1359b3cf1493SSlava Shwartsman if (sys_debug == priv->sysctl_debug)
1360b3cf1493SSlava Shwartsman goto done;
1361b3cf1493SSlava Shwartsman
1362b3cf1493SSlava Shwartsman if ((priv->sysctl_debug = sys_debug)) {
1363dc7e38acSHans Petter Selasky mlx5e_create_stats(&priv->stats.port_stats_debug.ctx,
1364dc7e38acSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), "debug_stats",
1365dc7e38acSHans Petter Selasky mlx5e_port_stats_debug_desc, MLX5E_PORT_STATS_DEBUG_NUM,
1366dc7e38acSHans Petter Selasky priv->stats.port_stats_debug.arg);
1367b3cf1493SSlava Shwartsman SYSCTL_ADD_PROC(&priv->stats.port_stats_debug.ctx,
1368f2b4782cSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO,
1369f2b4782cSHans Petter Selasky "hw_ctx_debug",
1370f2b4782cSHans Petter Selasky CTLFLAG_RD | CTLFLAG_MPSAFE | CTLTYPE_STRING, priv, 0,
1371f2b4782cSHans Petter Selasky mlx5e_ethtool_debug_channel_info, "S", "");
1372f2b4782cSHans Petter Selasky } else {
1373dc7e38acSHans Petter Selasky sysctl_ctx_free(&priv->stats.port_stats_debug.ctx);
1374f2b4782cSHans Petter Selasky }
1375b3cf1493SSlava Shwartsman done:
1376f2b4782cSHans Petter Selasky PRIV_UNLOCK(priv);
1377b3cf1493SSlava Shwartsman return (error);
1378dc7e38acSHans Petter Selasky }
1379dc7e38acSHans Petter Selasky
138066d53750SHans Petter Selasky static void
mlx5e_create_diagnostics(struct mlx5e_priv * priv)138166d53750SHans Petter Selasky mlx5e_create_diagnostics(struct mlx5e_priv *priv)
138266d53750SHans Petter Selasky {
138366d53750SHans Petter Selasky struct mlx5_core_diagnostics_entry entry;
138466d53750SHans Petter Selasky struct sysctl_ctx_list *ctx;
138566d53750SHans Petter Selasky struct sysctl_oid *node;
138666d53750SHans Petter Selasky int x;
138766d53750SHans Petter Selasky
138866d53750SHans Petter Selasky /* sysctl context we are using */
138966d53750SHans Petter Selasky ctx = &priv->sysctl_ctx;
139066d53750SHans Petter Selasky
139166d53750SHans Petter Selasky /* create root node */
139266d53750SHans Petter Selasky node = SYSCTL_ADD_NODE(ctx,
139366d53750SHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO,
13947029da5cSPawel Biernacki "diagnostics", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Diagnostics");
139566d53750SHans Petter Selasky if (node == NULL)
139666d53750SHans Petter Selasky return;
139766d53750SHans Petter Selasky
139866d53750SHans Petter Selasky /* create PCI diagnostics */
139966d53750SHans Petter Selasky for (x = 0; x != MLX5_CORE_PCI_DIAGNOSTICS_NUM; x++) {
140066d53750SHans Petter Selasky entry = mlx5_core_pci_diagnostics_table[x];
140166d53750SHans Petter Selasky if (mlx5_core_supports_diagnostics(priv->mdev, entry.counter_id) == 0)
140266d53750SHans Petter Selasky continue;
140366d53750SHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO,
140466d53750SHans Petter Selasky entry.desc, CTLFLAG_RD, priv->params_pci.array + x,
140566d53750SHans Petter Selasky "PCI diagnostics counter");
140666d53750SHans Petter Selasky }
140766d53750SHans Petter Selasky
140866d53750SHans Petter Selasky /* create general diagnostics */
140966d53750SHans Petter Selasky for (x = 0; x != MLX5_CORE_GENERAL_DIAGNOSTICS_NUM; x++) {
141066d53750SHans Petter Selasky entry = mlx5_core_general_diagnostics_table[x];
141166d53750SHans Petter Selasky if (mlx5_core_supports_diagnostics(priv->mdev, entry.counter_id) == 0)
141266d53750SHans Petter Selasky continue;
141366d53750SHans Petter Selasky SYSCTL_ADD_UQUAD(ctx, SYSCTL_CHILDREN(node), OID_AUTO,
141466d53750SHans Petter Selasky entry.desc, CTLFLAG_RD, priv->params_general.array + x,
141566d53750SHans Petter Selasky "General diagnostics counter");
141666d53750SHans Petter Selasky }
141766d53750SHans Petter Selasky }
141866d53750SHans Petter Selasky
1419dc7e38acSHans Petter Selasky void
mlx5e_create_ethtool(struct mlx5e_priv * priv)1420dc7e38acSHans Petter Selasky mlx5e_create_ethtool(struct mlx5e_priv *priv)
1421dc7e38acSHans Petter Selasky {
142296425f44SHans Petter Selasky struct sysctl_oid *fec_node;
142396425f44SHans Petter Selasky struct sysctl_oid *qos_node;
142496425f44SHans Petter Selasky struct sysctl_oid *node;
1425dc7e38acSHans Petter Selasky const char *pnameunit;
14266deb0b1eSHans Petter Selasky struct mlx5e_port_buffer port_buffer;
1427dc7e38acSHans Petter Selasky unsigned x;
1428cfc9c386SHans Petter Selasky int i;
1429dc7e38acSHans Petter Selasky
1430dc7e38acSHans Petter Selasky /* set some defaults */
1431c8d16d1eSHans Petter Selasky priv->params_ethtool.irq_cpu_base = -1; /* disabled */
1432c8d16d1eSHans Petter Selasky priv->params_ethtool.irq_cpu_stride = 1;
1433dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size_max = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE;
1434dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size_max = 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE;
1435dc7e38acSHans Petter Selasky priv->params_ethtool.tx_queue_size = 1 << priv->params.log_sq_size;
1436dc7e38acSHans Petter Selasky priv->params_ethtool.rx_queue_size = 1 << priv->params.log_rq_size;
1437dc7e38acSHans Petter Selasky priv->params_ethtool.channels = priv->params.num_channels;
143816ae32f9SHans Petter Selasky priv->params_ethtool.channels_rsss = priv->params.channels_rsss;
1439dc7e38acSHans Petter Selasky priv->params_ethtool.coalesce_pkts_max = MLX5E_FLD_MAX(cqc, cq_max_count);
1440dc7e38acSHans Petter Selasky priv->params_ethtool.coalesce_usecs_max = MLX5E_FLD_MAX(cqc, cq_period);
1441dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_mode = priv->params.rx_cq_moderation_mode;
1442dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_usecs = priv->params.rx_cq_moderation_usec;
1443dc7e38acSHans Petter Selasky priv->params_ethtool.rx_coalesce_pkts = priv->params.rx_cq_moderation_pkts;
144474540a31SHans Petter Selasky priv->params_ethtool.tx_coalesce_mode = priv->params.tx_cq_moderation_mode;
1445dc7e38acSHans Petter Selasky priv->params_ethtool.tx_coalesce_usecs = priv->params.tx_cq_moderation_usec;
1446dc7e38acSHans Petter Selasky priv->params_ethtool.tx_coalesce_pkts = priv->params.tx_cq_moderation_pkts;
1447dc7e38acSHans Petter Selasky priv->params_ethtool.hw_lro = priv->params.hw_lro_en;
144890cc1c77SHans Petter Selasky priv->params_ethtool.cqe_zipping = priv->params.cqe_zipping_en;
1449376bcf63SHans Petter Selasky mlx5e_ethtool_sync_tx_completion_fact(priv);
1450dc7e38acSHans Petter Selasky
145161fd7ac0SHans Petter Selasky /* get default values for local loopback, if any */
1452c1b76119SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, disable_local_lb_mc) ||
1453c1b76119SHans Petter Selasky MLX5_CAP_GEN(priv->mdev, disable_local_lb_uc)) {
145461fd7ac0SHans Petter Selasky int err;
145561fd7ac0SHans Petter Selasky u8 val;
145661fd7ac0SHans Petter Selasky
145761fd7ac0SHans Petter Selasky err = mlx5_nic_vport_query_local_lb(priv->mdev, MLX5_LOCAL_MC_LB, &val);
145861fd7ac0SHans Petter Selasky if (err == 0)
145961fd7ac0SHans Petter Selasky priv->params_ethtool.mc_local_lb = val;
146061fd7ac0SHans Petter Selasky
146161fd7ac0SHans Petter Selasky err = mlx5_nic_vport_query_local_lb(priv->mdev, MLX5_LOCAL_UC_LB, &val);
146261fd7ac0SHans Petter Selasky if (err == 0)
146361fd7ac0SHans Petter Selasky priv->params_ethtool.uc_local_lb = val;
146461fd7ac0SHans Petter Selasky }
146561fd7ac0SHans Petter Selasky
1466dc7e38acSHans Petter Selasky /* create root node */
1467dc7e38acSHans Petter Selasky node = SYSCTL_ADD_NODE(&priv->sysctl_ctx,
1468dc7e38acSHans Petter Selasky SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO,
14697029da5cSPawel Biernacki "conf", CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, "Configuration");
1470dc7e38acSHans Petter Selasky if (node == NULL)
1471dc7e38acSHans Petter Selasky return;
1472dc7e38acSHans Petter Selasky for (x = 0; x != MLX5E_PARAMS_NUM; x++) {
1473dc7e38acSHans Petter Selasky /* check for read-only parameter */
147453d7bb46SHans Petter Selasky if (strstr(mlx5e_params_desc[2 * x], "_max") != NULL ||
147553d7bb46SHans Petter Selasky strstr(mlx5e_params_desc[2 * x], "_mtu") != NULL) {
1476dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO,
1477dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x], CTLTYPE_U64 | CTLFLAG_RD |
1478dc7e38acSHans Petter Selasky CTLFLAG_MPSAFE, priv, x, &mlx5e_ethtool_handler, "QU",
1479dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x + 1]);
1480dc7e38acSHans Petter Selasky } else {
1481ec0143b2SHans Petter Selasky /*
1482ec0143b2SHans Petter Selasky * NOTE: In FreeBSD-11 and newer the
1483ec0143b2SHans Petter Selasky * CTLFLAG_RWTUN flag will take care of
1484ec0143b2SHans Petter Selasky * loading default sysctl value from the
1485ec0143b2SHans Petter Selasky * kernel environment, if any:
1486ec0143b2SHans Petter Selasky */
1487dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO,
1488dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x], CTLTYPE_U64 | CTLFLAG_RWTUN |
1489dc7e38acSHans Petter Selasky CTLFLAG_MPSAFE, priv, x, &mlx5e_ethtool_handler, "QU",
1490dc7e38acSHans Petter Selasky mlx5e_params_desc[2 * x + 1]);
1491dc7e38acSHans Petter Selasky }
1492dc7e38acSHans Petter Selasky }
1493dc7e38acSHans Petter Selasky
149496425f44SHans Petter Selasky /* create fec node */
149596425f44SHans Petter Selasky fec_node = SYSCTL_ADD_NODE(&priv->sysctl_ctx,
149696425f44SHans Petter Selasky SYSCTL_CHILDREN(node), OID_AUTO,
14977029da5cSPawel Biernacki "fec", CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
14987029da5cSPawel Biernacki "Forward Error Correction");
149996425f44SHans Petter Selasky if (fec_node == NULL)
150096425f44SHans Petter Selasky return;
150196425f44SHans Petter Selasky
150296425f44SHans Petter Selasky if (mlx5e_fec_update(priv) == 0) {
150396425f44SHans Petter Selasky SYSCTL_ADD_U32(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO,
150496425f44SHans Petter Selasky "mode_active", CTLFLAG_RD | CTLFLAG_MPSAFE,
150596425f44SHans Petter Selasky &priv->params_ethtool.fec_mode_active, 0,
150696425f44SHans Petter Selasky "Current FEC mode bit, if any.");
150796425f44SHans Petter Selasky
150896425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO,
150996425f44SHans Petter Selasky "mask_10x_25x", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
151096425f44SHans Petter Selasky priv, 0, &mlx5e_fec_mask_10x_25x_handler, "CU",
151196425f44SHans Petter Selasky "Set FEC masks for 10G_40G, 25G_50G, 56G, 100G respectivly. "
151296425f44SHans Petter Selasky "0:Auto "
151396425f44SHans Petter Selasky "1:NOFEC "
151496425f44SHans Petter Selasky "2:FIRECODE "
151596425f44SHans Petter Selasky "4:RS");
151696425f44SHans Petter Selasky
151796425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO,
151896425f44SHans Petter Selasky "avail_10x_25x", CTLTYPE_U8 | CTLFLAG_RD | CTLFLAG_MPSAFE,
151996425f44SHans Petter Selasky priv, 0, &mlx5e_fec_avail_10x_25x_handler, "CU",
152096425f44SHans Petter Selasky "Get available FEC bits for 10G_40G, 25G_50G, 56G, 100G respectivly. "
152196425f44SHans Petter Selasky "0:Auto "
152296425f44SHans Petter Selasky "1:NOFEC "
152396425f44SHans Petter Selasky "2:FIRECODE "
152496425f44SHans Petter Selasky "4:RS");
152596425f44SHans Petter Selasky
152696425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO,
152796425f44SHans Petter Selasky "mask_50x", CTLTYPE_U16 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
152896425f44SHans Petter Selasky priv, 0, &mlx5e_fec_mask_50x_handler, "SU",
152996425f44SHans Petter Selasky "Set FEC masks for 50G 1x, 100G 2x, 200G 4x, 400G 8x respectivly. "
153096425f44SHans Petter Selasky "0:Auto "
153196425f44SHans Petter Selasky "128:RS "
153296425f44SHans Petter Selasky "512:LL RS");
153396425f44SHans Petter Selasky
153496425f44SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(fec_node), OID_AUTO,
153596425f44SHans Petter Selasky "avail_50x", CTLTYPE_U16 | CTLFLAG_RD | CTLFLAG_MPSAFE,
153696425f44SHans Petter Selasky priv, 0, &mlx5e_fec_avail_50x_handler, "SU",
153796425f44SHans Petter Selasky "Get available FEC bits for 50G 1x, 100G 2x, 200G 4x, 400G 8x respectivly. "
153896425f44SHans Petter Selasky "0:Auto "
153996425f44SHans Petter Selasky "128:RS "
154096425f44SHans Petter Selasky "512:LL RS");
154196425f44SHans Petter Selasky }
154296425f44SHans Petter Selasky
1543dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO,
1544dc7e38acSHans Petter Selasky "debug_stats", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv,
1545dc7e38acSHans Petter Selasky 0, &mlx5e_ethtool_debug_stats, "I", "Extended debug statistics");
1546dc7e38acSHans Petter Selasky
1547dc7e38acSHans Petter Selasky pnameunit = device_get_nameunit(priv->mdev->pdev->dev.bsddev);
1548dc7e38acSHans Petter Selasky
1549dc7e38acSHans Petter Selasky SYSCTL_ADD_STRING(&priv->sysctl_ctx, SYSCTL_CHILDREN(node),
1550dc7e38acSHans Petter Selasky OID_AUTO, "device_name", CTLFLAG_RD,
1551dc7e38acSHans Petter Selasky __DECONST(void *, pnameunit), 0,
1552dc7e38acSHans Petter Selasky "PCI device name");
1553dc7e38acSHans Petter Selasky
155466d53750SHans Petter Selasky /* Diagnostics support */
155566d53750SHans Petter Selasky mlx5e_create_diagnostics(priv);
1556cfc9c386SHans Petter Selasky
1557cfc9c386SHans Petter Selasky /* create qos node */
1558cfc9c386SHans Petter Selasky qos_node = SYSCTL_ADD_NODE(&priv->sysctl_ctx,
1559cfc9c386SHans Petter Selasky SYSCTL_CHILDREN(node), OID_AUTO,
15607029da5cSPawel Biernacki "qos", CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
15617029da5cSPawel Biernacki "Quality Of Service configuration");
1562e870c0abSSlava Shwartsman if (qos_node == NULL)
1563cfc9c386SHans Petter Selasky return;
1564cfc9c386SHans Petter Selasky
1565e870c0abSSlava Shwartsman /* Priority rate limit support */
1566e870c0abSSlava Shwartsman if (mlx5e_getmaxrate(priv) == 0) {
1567cfc9c386SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node),
1568e870c0abSSlava Shwartsman OID_AUTO, "tc_max_rate", CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1569e870c0abSSlava Shwartsman priv, 0, mlx5e_tc_maxrate_handler, "QU",
1570e870c0abSSlava Shwartsman "Max rate for priority, specified in kilobits, where kilo=1000, "
1571e870c0abSSlava Shwartsman "max_rate must be divisible by 100000");
1572cfc9c386SHans Petter Selasky }
15732e9c3a4fSHans Petter Selasky
1574e870c0abSSlava Shwartsman /* Bandwidth limiting by ratio */
1575e870c0abSSlava Shwartsman if (mlx5e_get_max_alloc(priv) == 0) {
1576e870c0abSSlava Shwartsman SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node),
1577e870c0abSSlava Shwartsman OID_AUTO, "tc_rate_share", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1578e870c0abSSlava Shwartsman priv, 0, mlx5e_tc_rate_share_handler, "QU",
1579e870c0abSSlava Shwartsman "Specify bandwidth ratio from 1 to 100 "
1580e870c0abSSlava Shwartsman "for the available traffic classes");
1581e870c0abSSlava Shwartsman }
15822e9c3a4fSHans Petter Selasky
1583e870c0abSSlava Shwartsman /* Priority to traffic class mapping */
1584e870c0abSSlava Shwartsman if (mlx5e_get_prio_tc(priv) == 0) {
15852e9c3a4fSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node),
158624385321SHans Petter Selasky OID_AUTO, "prio_0_7_tc", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
158724385321SHans Petter Selasky priv, 0, mlx5e_prio_to_tc_handler, "CU",
158824385321SHans Petter Selasky "Set traffic class 0 to 7 for priority 0 to 7 inclusivly");
1589e870c0abSSlava Shwartsman }
1590ed0cee0bSHans Petter Selasky
1591ed0cee0bSHans Petter Selasky /* DSCP support */
1592ed0cee0bSHans Petter Selasky if (mlx5e_get_dscp(priv) == 0) {
1593ed0cee0bSHans Petter Selasky for (i = 0; i != MLX5_MAX_SUPPORTED_DSCP; i += 8) {
1594ed0cee0bSHans Petter Selasky char name[32];
1595ed0cee0bSHans Petter Selasky snprintf(name, sizeof(name), "dscp_%d_%d_prio", i, i + 7);
1596ed0cee0bSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node),
1597ed0cee0bSHans Petter Selasky OID_AUTO, name, CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1598ed0cee0bSHans Petter Selasky priv, i, mlx5e_dscp_prio_handler, "CU",
1599ed0cee0bSHans Petter Selasky "Set DSCP to priority mapping, 0..7");
1600ed0cee0bSHans Petter Selasky }
1601a880c1ffSHans Petter Selasky #define A "Set trust state, 1:PCP 2:DSCP"
1602a880c1ffSHans Petter Selasky #define B " 3:BOTH"
1603ed0cee0bSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node),
1604ed0cee0bSHans Petter Selasky OID_AUTO, "trust_state", CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1605ed0cee0bSHans Petter Selasky priv, 0, mlx5e_trust_state_handler, "CU",
1606dfea1c3eSHans Petter Selasky MLX5_CAP_QCAM_FEATURE(priv->mdev, qpts_trust_both) ?
1607a880c1ffSHans Petter Selasky A B : A);
1608a880c1ffSHans Petter Selasky #undef B
1609a880c1ffSHans Petter Selasky #undef A
1610ed0cee0bSHans Petter Selasky }
16116deb0b1eSHans Petter Selasky
16126deb0b1eSHans Petter Selasky if (mlx5e_port_query_buffer(priv, &port_buffer) == 0) {
16136deb0b1eSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node),
16146deb0b1eSHans Petter Selasky OID_AUTO, "buffers_size",
16156deb0b1eSHans Petter Selasky CTLTYPE_U32 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16166deb0b1eSHans Petter Selasky priv, 0, mlx5e_buf_size_handler, "IU",
16176deb0b1eSHans Petter Selasky "Set buffers sizes");
16186deb0b1eSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node),
16196deb0b1eSHans Petter Selasky OID_AUTO, "buffers_prio",
16206deb0b1eSHans Petter Selasky CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16216deb0b1eSHans Petter Selasky priv, 0, mlx5e_buf_prio_handler, "CU",
16226deb0b1eSHans Petter Selasky "Set prio to buffers mapping");
16236deb0b1eSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node),
16246deb0b1eSHans Petter Selasky OID_AUTO, "cable_length",
16256deb0b1eSHans Petter Selasky CTLTYPE_UINT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16266deb0b1eSHans Petter Selasky priv, 0, mlx5e_cable_length_handler, "IU",
16276deb0b1eSHans Petter Selasky "Set cable length in meters for xoff threshold calculation");
16286deb0b1eSHans Petter Selasky }
1629decb087cSHans Petter Selasky
1630decb087cSHans Petter Selasky if (mlx5e_hw_temperature_update(priv) == 0) {
1631decb087cSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
1632decb087cSHans Petter Selasky OID_AUTO, "hw_temperature",
1633decb087cSHans Petter Selasky CTLTYPE_S32 | CTLFLAG_RD | CTLFLAG_MPSAFE,
1634decb087cSHans Petter Selasky priv, 0, mlx5e_hw_temperature_handler, "I",
16359097ac9aSElyes HAOUAS "HW temperature in millicelsius");
1636decb087cSHans Petter Selasky }
1637dc7e38acSHans Petter Selasky }
1638