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