1290650Shselasky/*-
2290650Shselasky * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  All rights reserved.
3290650Shselasky *
4290650Shselasky * Redistribution and use in source and binary forms, with or without
5290650Shselasky * modification, are permitted provided that the following conditions
6290650Shselasky * are met:
7290650Shselasky * 1. Redistributions of source code must retain the above copyright
8290650Shselasky *    notice, this list of conditions and the following disclaimer.
9290650Shselasky * 2. Redistributions in binary form must reproduce the above copyright
10290650Shselasky *    notice, this list of conditions and the following disclaimer in the
11290650Shselasky *    documentation and/or other materials provided with the distribution.
12290650Shselasky *
13290650Shselasky * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14290650Shselasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15290650Shselasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16290650Shselasky * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17290650Shselasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18290650Shselasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19290650Shselasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20290650Shselasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21290650Shselasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22290650Shselasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23290650Shselasky * SUCH DAMAGE.
24290650Shselasky *
25290650Shselasky * $FreeBSD: stable/10/sys/dev/mlx5/mlx5_core/mlx5_port.c 308684 2016-11-15 08:58:51Z hselasky $
26290650Shselasky */
27290650Shselasky
28290650Shselasky#include <linux/module.h>
29290650Shselasky#include <dev/mlx5/driver.h>
30290650Shselasky#include "mlx5_core.h"
31290650Shselasky
32290650Shselaskyint mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in,
33290650Shselasky			 int size_in, void *data_out, int size_out,
34290650Shselasky			 u16 reg_num, int arg, int write)
35290650Shselasky{
36290650Shselasky	struct mlx5_access_reg_mbox_in *in = NULL;
37290650Shselasky	struct mlx5_access_reg_mbox_out *out = NULL;
38290650Shselasky	int err = -ENOMEM;
39290650Shselasky
40290650Shselasky	in = mlx5_vzalloc(sizeof(*in) + size_in);
41290650Shselasky	if (!in)
42290650Shselasky		return -ENOMEM;
43290650Shselasky
44290650Shselasky	out = mlx5_vzalloc(sizeof(*out) + size_out);
45290650Shselasky	if (!out)
46290650Shselasky		goto ex1;
47290650Shselasky
48290650Shselasky	memcpy(in->data, data_in, size_in);
49290650Shselasky	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ACCESS_REG);
50290650Shselasky	in->hdr.opmod = cpu_to_be16(!write);
51290650Shselasky	in->arg = cpu_to_be32(arg);
52290650Shselasky	in->register_id = cpu_to_be16(reg_num);
53290650Shselasky	err = mlx5_cmd_exec(dev, in, sizeof(*in) + size_in, out,
54290650Shselasky			    sizeof(*out) + size_out);
55290650Shselasky	if (err)
56290650Shselasky		goto ex2;
57290650Shselasky
58290650Shselasky	if (out->hdr.status)
59290650Shselasky		err = mlx5_cmd_status_to_err(&out->hdr);
60290650Shselasky
61290650Shselasky	if (!err)
62290650Shselasky		memcpy(data_out, out->data, size_out);
63290650Shselasky
64290650Shselaskyex2:
65290650Shselasky	kvfree(out);
66290650Shselaskyex1:
67290650Shselasky	kvfree(in);
68290650Shselasky	return err;
69290650Shselasky}
70290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_access_reg);
71290650Shselasky
72290650Shselasky
73290650Shselaskystruct mlx5_reg_pcap {
74290650Shselasky	u8			rsvd0;
75290650Shselasky	u8			port_num;
76290650Shselasky	u8			rsvd1[2];
77290650Shselasky	__be32			caps_127_96;
78290650Shselasky	__be32			caps_95_64;
79290650Shselasky	__be32			caps_63_32;
80290650Shselasky	__be32			caps_31_0;
81290650Shselasky};
82290650Shselasky
83306244Shselasky/* This function should be used after setting a port register only */
84306244Shselaskyvoid mlx5_toggle_port_link(struct mlx5_core_dev *dev)
85306244Shselasky{
86306244Shselasky	enum mlx5_port_status ps;
87306244Shselasky
88306244Shselasky	mlx5_query_port_admin_status(dev, &ps);
89306244Shselasky	mlx5_set_port_status(dev, MLX5_PORT_DOWN);
90306244Shselasky	if (ps == MLX5_PORT_UP)
91306244Shselasky		mlx5_set_port_status(dev, MLX5_PORT_UP);
92306244Shselasky}
93306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_toggle_port_link);
94306244Shselasky
95290650Shselaskyint mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps)
96290650Shselasky{
97290650Shselasky	struct mlx5_reg_pcap in;
98290650Shselasky	struct mlx5_reg_pcap out;
99290650Shselasky	int err;
100290650Shselasky
101290650Shselasky	memset(&in, 0, sizeof(in));
102290650Shselasky	in.caps_127_96 = cpu_to_be32(caps);
103290650Shselasky	in.port_num = port_num;
104290650Shselasky
105290650Shselasky	err = mlx5_core_access_reg(dev, &in, sizeof(in), &out,
106290650Shselasky				   sizeof(out), MLX5_REG_PCAP, 0, 1);
107290650Shselasky
108290650Shselasky	return err;
109290650Shselasky}
110290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_set_port_caps);
111290650Shselasky
112290650Shselaskyint mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
113290650Shselasky			 int ptys_size, int proto_mask)
114290650Shselasky{
115290650Shselasky	u32 in[MLX5_ST_SZ_DW(ptys_reg)];
116290650Shselasky	int err;
117290650Shselasky
118290650Shselasky	memset(in, 0, sizeof(in));
119290650Shselasky	MLX5_SET(ptys_reg, in, local_port, 1);
120290650Shselasky	MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
121290650Shselasky
122290650Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), ptys,
123290650Shselasky				   ptys_size, MLX5_REG_PTYS, 0, 0);
124290650Shselasky
125290650Shselasky	return err;
126290650Shselasky}
127290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_port_ptys);
128290650Shselasky
129290650Shselaskyint mlx5_query_port_proto_cap(struct mlx5_core_dev *dev,
130290650Shselasky			      u32 *proto_cap, int proto_mask)
131290650Shselasky{
132290650Shselasky	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
133290650Shselasky	int err;
134290650Shselasky
135290650Shselasky	err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask);
136290650Shselasky	if (err)
137290650Shselasky		return err;
138290650Shselasky
139290650Shselasky	if (proto_mask == MLX5_PTYS_EN)
140290650Shselasky		*proto_cap = MLX5_GET(ptys_reg, out, eth_proto_capability);
141290650Shselasky	else
142290650Shselasky		*proto_cap = MLX5_GET(ptys_reg, out, ib_proto_capability);
143290650Shselasky
144290650Shselasky	return 0;
145290650Shselasky}
146290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_port_proto_cap);
147290650Shselasky
148306244Shselaskyint mlx5_query_port_autoneg(struct mlx5_core_dev *dev, int proto_mask,
149306244Shselasky			    u8 *an_disable_cap, u8 *an_disable_status)
150306244Shselasky{
151306244Shselasky	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
152306244Shselasky	int err;
153306244Shselasky
154306244Shselasky	err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask);
155306244Shselasky	if (err)
156306244Shselasky		return err;
157306244Shselasky
158306244Shselasky	*an_disable_status = MLX5_GET(ptys_reg, out, an_disable_admin);
159306244Shselasky	*an_disable_cap = MLX5_GET(ptys_reg, out, an_disable_cap);
160306244Shselasky
161306244Shselasky	return 0;
162306244Shselasky}
163306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_port_autoneg);
164306244Shselasky
165306244Shselaskyint mlx5_set_port_autoneg(struct mlx5_core_dev *dev, bool disable,
166306244Shselasky			  u32 eth_proto_admin, int proto_mask)
167306244Shselasky{
168306244Shselasky	u32 in[MLX5_ST_SZ_DW(ptys_reg)];
169306244Shselasky	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
170306244Shselasky	u8 an_disable_cap;
171306244Shselasky	u8 an_disable_status;
172306244Shselasky	int err;
173306244Shselasky
174306244Shselasky	err = mlx5_query_port_autoneg(dev, proto_mask, &an_disable_cap,
175306244Shselasky				      &an_disable_status);
176306244Shselasky	if (err)
177306244Shselasky		return err;
178306244Shselasky	if (!an_disable_cap)
179306244Shselasky		return -EPERM;
180306244Shselasky
181306244Shselasky	memset(in, 0, sizeof(in));
182306244Shselasky
183306244Shselasky	MLX5_SET(ptys_reg, in, local_port, 1);
184306244Shselasky	MLX5_SET(ptys_reg, in, an_disable_admin, disable);
185306244Shselasky	MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
186306244Shselasky	if (proto_mask == MLX5_PTYS_EN)
187306244Shselasky		MLX5_SET(ptys_reg, in, eth_proto_admin, eth_proto_admin);
188306244Shselasky
189306244Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
190306244Shselasky				   sizeof(out), MLX5_REG_PTYS, 0, 1);
191306244Shselasky	return err;
192306244Shselasky}
193306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_set_port_autoneg);
194306244Shselasky
195290650Shselaskyint mlx5_query_port_proto_admin(struct mlx5_core_dev *dev,
196290650Shselasky				u32 *proto_admin, int proto_mask)
197290650Shselasky{
198290650Shselasky	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
199290650Shselasky	int err;
200290650Shselasky
201290650Shselasky	err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask);
202290650Shselasky	if (err)
203290650Shselasky		return err;
204290650Shselasky
205290650Shselasky	if (proto_mask == MLX5_PTYS_EN)
206290650Shselasky		*proto_admin = MLX5_GET(ptys_reg, out, eth_proto_admin);
207290650Shselasky	else
208290650Shselasky		*proto_admin = MLX5_GET(ptys_reg, out, ib_proto_admin);
209290650Shselasky
210290650Shselasky	return 0;
211290650Shselasky}
212290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_port_proto_admin);
213290650Shselasky
214290650Shselaskyint mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
215290650Shselasky			int proto_mask)
216290650Shselasky{
217290650Shselasky	u32 in[MLX5_ST_SZ_DW(ptys_reg)];
218290650Shselasky	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
219290650Shselasky	int err;
220290650Shselasky
221290650Shselasky	memset(in, 0, sizeof(in));
222290650Shselasky
223290650Shselasky	MLX5_SET(ptys_reg, in, local_port, 1);
224290650Shselasky	MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
225290650Shselasky	if (proto_mask == MLX5_PTYS_EN)
226290650Shselasky		MLX5_SET(ptys_reg, in, eth_proto_admin, proto_admin);
227290650Shselasky	else
228290650Shselasky		MLX5_SET(ptys_reg, in, ib_proto_admin, proto_admin);
229290650Shselasky
230290650Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
231290650Shselasky				   sizeof(out), MLX5_REG_PTYS, 0, 1);
232290650Shselasky	return err;
233290650Shselasky}
234290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_set_port_proto);
235290650Shselasky
236290650Shselaskyint mlx5_set_port_status(struct mlx5_core_dev *dev,
237290650Shselasky			 enum mlx5_port_status status)
238290650Shselasky{
239290650Shselasky	u32 in[MLX5_ST_SZ_DW(paos_reg)];
240290650Shselasky	u32 out[MLX5_ST_SZ_DW(paos_reg)];
241290650Shselasky	int err;
242290650Shselasky
243290650Shselasky	memset(in, 0, sizeof(in));
244290650Shselasky
245290650Shselasky	MLX5_SET(paos_reg, in, local_port, 1);
246290650Shselasky
247290650Shselasky	MLX5_SET(paos_reg, in, admin_status, status);
248290650Shselasky	MLX5_SET(paos_reg, in, ase, 1);
249290650Shselasky
250290650Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
251290650Shselasky				   sizeof(out), MLX5_REG_PAOS, 0, 1);
252290650Shselasky	return err;
253290650Shselasky}
254290650Shselasky
255290650Shselaskyint mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
256290650Shselasky{
257290650Shselasky	u32 in[MLX5_ST_SZ_DW(paos_reg)];
258290650Shselasky	u32 out[MLX5_ST_SZ_DW(paos_reg)];
259290650Shselasky	int err;
260290650Shselasky
261290650Shselasky	memset(in, 0, sizeof(in));
262290650Shselasky
263290650Shselasky	MLX5_SET(paos_reg, in, local_port, 1);
264290650Shselasky
265290650Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
266290650Shselasky				   sizeof(out), MLX5_REG_PAOS, 0, 0);
267290650Shselasky	if (err)
268290650Shselasky		return err;
269290650Shselasky
270290650Shselasky	*status = MLX5_GET(paos_reg, out, oper_status);
271290650Shselasky	return err;
272290650Shselasky}
273290650Shselasky
274306244Shselaskyint mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
275306244Shselasky				 enum mlx5_port_status *status)
276306244Shselasky{
277306244Shselasky	u32 in[MLX5_ST_SZ_DW(paos_reg)] = {0};
278306244Shselasky	u32 out[MLX5_ST_SZ_DW(paos_reg)];
279306244Shselasky	int err;
280306244Shselasky
281306244Shselasky	MLX5_SET(paos_reg, in, local_port, 1);
282306244Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
283306244Shselasky				   sizeof(out), MLX5_REG_PAOS, 0, 0);
284306244Shselasky	if (err)
285306244Shselasky		return err;
286306244Shselasky	*status = MLX5_GET(paos_reg, out, admin_status);
287306244Shselasky	return 0;
288306244Shselasky}
289306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_port_admin_status);
290306244Shselasky
291290650Shselaskystatic int mlx5_query_port_mtu(struct mlx5_core_dev *dev,
292290650Shselasky			       int *admin_mtu, int *max_mtu, int *oper_mtu)
293290650Shselasky{
294290650Shselasky	u32 in[MLX5_ST_SZ_DW(pmtu_reg)];
295290650Shselasky	u32 out[MLX5_ST_SZ_DW(pmtu_reg)];
296290650Shselasky	int err;
297290650Shselasky
298290650Shselasky	memset(in, 0, sizeof(in));
299290650Shselasky
300290650Shselasky	MLX5_SET(pmtu_reg, in, local_port, 1);
301290650Shselasky
302290650Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
303290650Shselasky				   sizeof(out), MLX5_REG_PMTU, 0, 0);
304290650Shselasky	if (err)
305290650Shselasky		return err;
306290650Shselasky
307290650Shselasky	if (max_mtu)
308290650Shselasky		*max_mtu  = MLX5_GET(pmtu_reg, out, max_mtu);
309290650Shselasky	if (oper_mtu)
310290650Shselasky		*oper_mtu = MLX5_GET(pmtu_reg, out, oper_mtu);
311290650Shselasky	if (admin_mtu)
312290650Shselasky		*admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu);
313290650Shselasky
314290650Shselasky	return err;
315290650Shselasky}
316290650Shselasky
317290650Shselaskyint mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu)
318290650Shselasky{
319290650Shselasky	u32 in[MLX5_ST_SZ_DW(pmtu_reg)];
320290650Shselasky	u32 out[MLX5_ST_SZ_DW(pmtu_reg)];
321290650Shselasky
322290650Shselasky	memset(in, 0, sizeof(in));
323290650Shselasky
324290650Shselasky	MLX5_SET(pmtu_reg, in, admin_mtu, mtu);
325290650Shselasky	MLX5_SET(pmtu_reg, in, local_port, 1);
326290650Shselasky
327290650Shselasky	return mlx5_core_access_reg(dev, in, sizeof(in), out,
328290650Shselasky				   sizeof(out), MLX5_REG_PMTU, 0, 1);
329290650Shselasky}
330290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_set_port_mtu);
331290650Shselasky
332290650Shselaskyint mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu)
333290650Shselasky{
334290650Shselasky	return mlx5_query_port_mtu(dev, NULL, max_mtu, NULL);
335290650Shselasky}
336290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu);
337290650Shselasky
338290650Shselaskyint mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 port,
339290650Shselasky			u32 rx_pause, u32 tx_pause)
340290650Shselasky{
341290650Shselasky	u32 in[MLX5_ST_SZ_DW(pfcc_reg)];
342290650Shselasky	u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
343290650Shselasky
344290650Shselasky	memset(in, 0, sizeof(in));
345290650Shselasky	memset(out, 0, sizeof(out));
346290650Shselasky
347290650Shselasky	MLX5_SET(pfcc_reg, in, local_port, port);
348290650Shselasky	MLX5_SET(pfcc_reg, in, pptx, tx_pause);
349290650Shselasky	MLX5_SET(pfcc_reg, in, pprx, rx_pause);
350290650Shselasky
351290650Shselasky	return mlx5_core_access_reg(dev, in, sizeof(in), out,
352290650Shselasky				   sizeof(out), MLX5_REG_PFCC, 0, 1);
353290650Shselasky}
354290650Shselasky
355290650Shselaskyint mlx5_query_port_pause(struct mlx5_core_dev *dev, u32 port,
356290650Shselasky			  u32 *rx_pause, u32 *tx_pause)
357290650Shselasky{
358290650Shselasky	u32 in[MLX5_ST_SZ_DW(pfcc_reg)];
359290650Shselasky	u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
360290650Shselasky	int err;
361290650Shselasky
362290650Shselasky	memset(in, 0, sizeof(in));
363290650Shselasky	memset(out, 0, sizeof(out));
364290650Shselasky
365290650Shselasky	MLX5_SET(pfcc_reg, in, local_port, port);
366290650Shselasky
367290650Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
368290650Shselasky				   sizeof(out), MLX5_REG_PFCC, 0, 0);
369290650Shselasky	if (err)
370290650Shselasky		return err;
371290650Shselasky
372290650Shselasky	*rx_pause = MLX5_GET(pfcc_reg, out, pprx);
373290650Shselasky	*tx_pause = MLX5_GET(pfcc_reg, out, pptx);
374290650Shselasky
375290650Shselasky	return 0;
376290650Shselasky}
377290650Shselasky
378306244Shselaskyint mlx5_set_port_pfc(struct mlx5_core_dev *dev, u8 pfc_en_tx, u8 pfc_en_rx)
379306244Shselasky{
380306244Shselasky	u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
381306244Shselasky	u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
382306244Shselasky
383306244Shselasky	MLX5_SET(pfcc_reg, in, local_port, 1);
384306244Shselasky	MLX5_SET(pfcc_reg, in, pfctx, pfc_en_tx);
385306244Shselasky	MLX5_SET(pfcc_reg, in, pfcrx, pfc_en_rx);
386306244Shselasky	MLX5_SET_TO_ONES(pfcc_reg, in, prio_mask_tx);
387306244Shselasky	MLX5_SET_TO_ONES(pfcc_reg, in, prio_mask_rx);
388306244Shselasky
389306244Shselasky	return mlx5_core_access_reg(dev, in, sizeof(in), out,
390306244Shselasky				    sizeof(out), MLX5_REG_PFCC, 0, 1);
391306244Shselasky}
392306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_set_port_pfc);
393306244Shselasky
394306244Shselaskyint mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx, u8 *pfc_en_rx)
395306244Shselasky{
396306244Shselasky	u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
397306244Shselasky	u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
398306244Shselasky	int err;
399306244Shselasky
400306244Shselasky	MLX5_SET(pfcc_reg, in, local_port, 1);
401306244Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
402306244Shselasky				   sizeof(out), MLX5_REG_PFCC, 0, 0);
403306244Shselasky	if (err)
404306244Shselasky		return err;
405306244Shselasky
406306244Shselasky	if (pfc_en_tx)
407306244Shselasky		*pfc_en_tx = MLX5_GET(pfcc_reg, out, pfctx);
408306244Shselasky
409306244Shselasky	if (pfc_en_rx)
410306244Shselasky		*pfc_en_rx = MLX5_GET(pfcc_reg, out, pfcrx);
411306244Shselasky
412306244Shselasky	return 0;
413306244Shselasky}
414306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_port_pfc);
415306244Shselasky
416290650Shselaskyint mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu)
417290650Shselasky{
418290650Shselasky	return mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu);
419290650Shselasky}
420290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_port_oper_mtu);
421290650Shselasky
422290650Shselaskyu8 mlx5_is_wol_supported(struct mlx5_core_dev *dev)
423290650Shselasky{
424290650Shselasky	u8 wol_supported = 0;
425290650Shselasky
426290650Shselasky	if (MLX5_CAP_GEN(dev, wol_s))
427290650Shselasky		wol_supported |= MLX5_WOL_SECURED_MAGIC;
428290650Shselasky	if (MLX5_CAP_GEN(dev, wol_g))
429290650Shselasky		wol_supported |= MLX5_WOL_MAGIC;
430290650Shselasky	if (MLX5_CAP_GEN(dev, wol_a))
431290650Shselasky		wol_supported |= MLX5_WOL_ARP;
432290650Shselasky	if (MLX5_CAP_GEN(dev, wol_b))
433290650Shselasky		wol_supported |= MLX5_WOL_BROADCAST;
434290650Shselasky	if (MLX5_CAP_GEN(dev, wol_m))
435290650Shselasky		wol_supported |= MLX5_WOL_MULTICAST;
436290650Shselasky	if (MLX5_CAP_GEN(dev, wol_u))
437290650Shselasky		wol_supported |= MLX5_WOL_UNICAST;
438290650Shselasky	if (MLX5_CAP_GEN(dev, wol_p))
439290650Shselasky		wol_supported |= MLX5_WOL_PHY_ACTIVITY;
440290650Shselasky
441290650Shselasky	return wol_supported;
442290650Shselasky}
443290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_is_wol_supported);
444290650Shselasky
445290650Shselaskyint mlx5_set_wol(struct mlx5_core_dev *dev, u8 wol_mode)
446290650Shselasky{
447290650Shselasky	u32 in[MLX5_ST_SZ_DW(set_wol_rol_in)];
448290650Shselasky	u32 out[MLX5_ST_SZ_DW(set_wol_rol_out)];
449290650Shselasky
450290650Shselasky	memset(in, 0, sizeof(in));
451290650Shselasky	memset(out, 0, sizeof(out));
452290650Shselasky
453290650Shselasky	MLX5_SET(set_wol_rol_in, in, opcode, MLX5_CMD_OP_SET_WOL_ROL);
454290650Shselasky	MLX5_SET(set_wol_rol_in, in, wol_mode_valid, 1);
455290650Shselasky	MLX5_SET(set_wol_rol_in, in, wol_mode, wol_mode);
456290650Shselasky
457290650Shselasky	return mlx5_cmd_exec_check_status(dev, in, sizeof(in),
458290650Shselasky					  out, sizeof(out));
459290650Shselasky}
460290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_set_wol);
461290650Shselasky
462290650Shselaskyint mlx5_core_access_pvlc(struct mlx5_core_dev *dev,
463290650Shselasky			  struct mlx5_pvlc_reg *pvlc, int write)
464290650Shselasky{
465290650Shselasky	int sz = MLX5_ST_SZ_BYTES(pvlc_reg);
466290650Shselasky	u8 in[MLX5_ST_SZ_BYTES(pvlc_reg)];
467290650Shselasky	u8 out[MLX5_ST_SZ_BYTES(pvlc_reg)];
468290650Shselasky	int err;
469290650Shselasky
470290650Shselasky	memset(out, 0, sizeof(out));
471290650Shselasky	memset(in, 0, sizeof(in));
472290650Shselasky
473290650Shselasky	MLX5_SET(pvlc_reg, in, local_port, pvlc->local_port);
474290650Shselasky	if (write)
475290650Shselasky		MLX5_SET(pvlc_reg, in, vl_admin, pvlc->vl_admin);
476290650Shselasky
477290650Shselasky	err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PVLC, 0,
478290650Shselasky				   !!write);
479290650Shselasky	if (err)
480290650Shselasky		return err;
481290650Shselasky
482290650Shselasky	if (!write) {
483290650Shselasky		pvlc->local_port = MLX5_GET(pvlc_reg, out, local_port);
484290650Shselasky		pvlc->vl_hw_cap = MLX5_GET(pvlc_reg, out, vl_hw_cap);
485290650Shselasky		pvlc->vl_admin = MLX5_GET(pvlc_reg, out, vl_admin);
486290650Shselasky		pvlc->vl_operational = MLX5_GET(pvlc_reg, out, vl_operational);
487290650Shselasky	}
488290650Shselasky
489290650Shselasky	return 0;
490290650Shselasky}
491290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_access_pvlc);
492290650Shselasky
493290650Shselaskyint mlx5_core_access_ptys(struct mlx5_core_dev *dev,
494290650Shselasky			  struct mlx5_ptys_reg *ptys, int write)
495290650Shselasky{
496290650Shselasky	int sz = MLX5_ST_SZ_BYTES(ptys_reg);
497290650Shselasky	void *out = NULL;
498290650Shselasky	void *in = NULL;
499290650Shselasky	int err;
500290650Shselasky
501290650Shselasky	in = mlx5_vzalloc(sz);
502290650Shselasky	if (!in)
503290650Shselasky		return -ENOMEM;
504290650Shselasky
505290650Shselasky	out = mlx5_vzalloc(sz);
506290650Shselasky	if (!out) {
507290650Shselasky		kfree(in);
508290650Shselasky		return -ENOMEM;
509290650Shselasky	}
510290650Shselasky
511290650Shselasky	MLX5_SET(ptys_reg, in, local_port, ptys->local_port);
512290650Shselasky	MLX5_SET(ptys_reg, in, proto_mask, ptys->proto_mask);
513290650Shselasky	if (write) {
514290650Shselasky		MLX5_SET(ptys_reg, in, eth_proto_capability,
515290650Shselasky			 ptys->eth_proto_cap);
516290650Shselasky		MLX5_SET(ptys_reg, in, ib_link_width_capability,
517290650Shselasky			 ptys->ib_link_width_cap);
518290650Shselasky		MLX5_SET(ptys_reg, in, ib_proto_capability,
519290650Shselasky			 ptys->ib_proto_cap);
520290650Shselasky		MLX5_SET(ptys_reg, in, eth_proto_admin, ptys->eth_proto_admin);
521290650Shselasky		MLX5_SET(ptys_reg, in, ib_link_width_admin,
522290650Shselasky			 ptys->ib_link_width_admin);
523290650Shselasky		MLX5_SET(ptys_reg, in, ib_proto_admin, ptys->ib_proto_admin);
524290650Shselasky		MLX5_SET(ptys_reg, in, eth_proto_oper, ptys->eth_proto_oper);
525290650Shselasky		MLX5_SET(ptys_reg, in, ib_link_width_oper,
526290650Shselasky			 ptys->ib_link_width_oper);
527290650Shselasky		MLX5_SET(ptys_reg, in, ib_proto_oper, ptys->ib_proto_oper);
528290650Shselasky		MLX5_SET(ptys_reg, in, eth_proto_lp_advertise,
529290650Shselasky			 ptys->eth_proto_lp_advertise);
530290650Shselasky	}
531290650Shselasky
532290650Shselasky	err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PTYS, 0,
533290650Shselasky				   !!write);
534290650Shselasky	if (err)
535290650Shselasky		goto out;
536290650Shselasky
537290650Shselasky	if (!write) {
538290650Shselasky		ptys->local_port = MLX5_GET(ptys_reg, out, local_port);
539290650Shselasky		ptys->proto_mask = MLX5_GET(ptys_reg, out, proto_mask);
540290650Shselasky		ptys->eth_proto_cap = MLX5_GET(ptys_reg, out,
541290650Shselasky					       eth_proto_capability);
542290650Shselasky		ptys->ib_link_width_cap = MLX5_GET(ptys_reg, out,
543290650Shselasky					   ib_link_width_capability);
544290650Shselasky		ptys->ib_proto_cap = MLX5_GET(ptys_reg, out,
545290650Shselasky					      ib_proto_capability);
546290650Shselasky		ptys->eth_proto_admin = MLX5_GET(ptys_reg, out,
547290650Shselasky						 eth_proto_admin);
548290650Shselasky		ptys->ib_link_width_admin = MLX5_GET(ptys_reg, out,
549290650Shselasky						     ib_link_width_admin);
550290650Shselasky		ptys->ib_proto_admin = MLX5_GET(ptys_reg, out, ib_proto_admin);
551290650Shselasky		ptys->eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
552290650Shselasky		ptys->ib_link_width_oper = MLX5_GET(ptys_reg, out,
553290650Shselasky						    ib_link_width_oper);
554290650Shselasky		ptys->ib_proto_oper = MLX5_GET(ptys_reg, out, ib_proto_oper);
555290650Shselasky		ptys->eth_proto_lp_advertise = MLX5_GET(ptys_reg, out,
556290650Shselasky							eth_proto_lp_advertise);
557290650Shselasky	}
558290650Shselasky
559290650Shselaskyout:
560290650Shselasky	kvfree(in);
561290650Shselasky	kvfree(out);
562290650Shselasky	return err;
563290650Shselasky}
564290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_access_ptys);
565290650Shselasky
566290650Shselaskystatic int mtu_to_ib_mtu(int mtu)
567290650Shselasky{
568290650Shselasky	switch (mtu) {
569290650Shselasky	case 256: return 1;
570290650Shselasky	case 512: return 2;
571290650Shselasky	case 1024: return 3;
572290650Shselasky	case 2048: return 4;
573290650Shselasky	case 4096: return 5;
574290650Shselasky	default:
575290650Shselasky		printf("mlx5_core: WARN: ""invalid mtu\n");
576290650Shselasky		return -1;
577290650Shselasky	}
578290650Shselasky}
579290650Shselasky
580290650Shselaskyint mlx5_core_access_pmtu(struct mlx5_core_dev *dev,
581290650Shselasky			  struct mlx5_pmtu_reg *pmtu, int write)
582290650Shselasky{
583290650Shselasky	int sz = MLX5_ST_SZ_BYTES(pmtu_reg);
584290650Shselasky	void *out = NULL;
585290650Shselasky	void *in = NULL;
586290650Shselasky	int err;
587290650Shselasky
588290650Shselasky	in = mlx5_vzalloc(sz);
589290650Shselasky	if (!in)
590290650Shselasky		return -ENOMEM;
591290650Shselasky
592290650Shselasky	out = mlx5_vzalloc(sz);
593290650Shselasky	if (!out) {
594290650Shselasky		kfree(in);
595290650Shselasky		return -ENOMEM;
596290650Shselasky	}
597290650Shselasky
598290650Shselasky	MLX5_SET(pmtu_reg, in, local_port, pmtu->local_port);
599290650Shselasky	if (write)
600290650Shselasky		MLX5_SET(pmtu_reg, in, admin_mtu, pmtu->admin_mtu);
601290650Shselasky
602290650Shselasky	err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PMTU, 0,
603290650Shselasky				   !!write);
604290650Shselasky	if (err)
605290650Shselasky		goto out;
606290650Shselasky
607290650Shselasky	if (!write) {
608290650Shselasky		pmtu->local_port = MLX5_GET(pmtu_reg, out, local_port);
609290650Shselasky		pmtu->max_mtu = mtu_to_ib_mtu(MLX5_GET(pmtu_reg, out,
610290650Shselasky						       max_mtu));
611290650Shselasky		pmtu->admin_mtu = mtu_to_ib_mtu(MLX5_GET(pmtu_reg, out,
612290650Shselasky							 admin_mtu));
613290650Shselasky		pmtu->oper_mtu = mtu_to_ib_mtu(MLX5_GET(pmtu_reg, out,
614290650Shselasky							oper_mtu));
615290650Shselasky	}
616290650Shselasky
617290650Shselaskyout:
618290650Shselasky	kvfree(in);
619290650Shselasky	kvfree(out);
620290650Shselasky	return err;
621290650Shselasky}
622290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_access_pmtu);
623290650Shselasky
624290650Shselaskyint mlx5_query_module_num(struct mlx5_core_dev *dev, int *module_num)
625290650Shselasky{
626290650Shselasky	u32 in[MLX5_ST_SZ_DW(pmlp_reg)];
627290650Shselasky	u32 out[MLX5_ST_SZ_DW(pmlp_reg)];
628290650Shselasky	int lane = 0;
629290650Shselasky	int err;
630290650Shselasky
631290650Shselasky	memset(in, 0, sizeof(in));
632290650Shselasky
633290650Shselasky	MLX5_SET(pmlp_reg, in, local_port, 1);
634290650Shselasky
635290650Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
636290650Shselasky				   sizeof(out), MLX5_REG_PMLP, 0, 0);
637290650Shselasky	if (err)
638290650Shselasky		return err;
639290650Shselasky
640290650Shselasky	lane = MLX5_GET(pmlp_reg, out, lane0_module_mapping);
641290650Shselasky	*module_num = lane & MLX5_EEPROM_IDENTIFIER_BYTE_MASK;
642290650Shselasky
643290650Shselasky	return 0;
644290650Shselasky}
645290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_module_num);
646290650Shselasky
647290650Shselaskyint mlx5_query_eeprom(struct mlx5_core_dev *dev,
648290650Shselasky		      int i2c_addr, int page_num, int device_addr,
649290650Shselasky		      int size, int module_num, u32 *data, int *size_read)
650290650Shselasky{
651290650Shselasky	u32 in[MLX5_ST_SZ_DW(mcia_reg)];
652290650Shselasky	u32 out[MLX5_ST_SZ_DW(mcia_reg)];
653290650Shselasky	u32 *ptr = (u32 *)MLX5_ADDR_OF(mcia_reg, out, dword_0);
654290650Shselasky	int status;
655290650Shselasky	int err;
656290650Shselasky
657290650Shselasky	memset(in, 0, sizeof(in));
658290650Shselasky	size = min_t(int, size, MLX5_EEPROM_MAX_BYTES);
659290650Shselasky
660290650Shselasky	MLX5_SET(mcia_reg, in, l, 0);
661290650Shselasky	MLX5_SET(mcia_reg, in, module, module_num);
662290650Shselasky	MLX5_SET(mcia_reg, in, i2c_device_address, i2c_addr);
663290650Shselasky	MLX5_SET(mcia_reg, in, page_number, page_num);
664290650Shselasky	MLX5_SET(mcia_reg, in, device_address, device_addr);
665290650Shselasky	MLX5_SET(mcia_reg, in, size, size);
666290650Shselasky
667290650Shselasky	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
668290650Shselasky				   sizeof(out), MLX5_REG_MCIA, 0, 0);
669290650Shselasky	if (err)
670290650Shselasky		return err;
671290650Shselasky
672290650Shselasky	status = MLX5_GET(mcia_reg, out, status);
673290650Shselasky	if (status)
674290650Shselasky		return status;
675290650Shselasky
676290650Shselasky	memcpy(data, ptr, size);
677290650Shselasky	*size_read = size;
678290650Shselasky	return 0;
679290650Shselasky}
680290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_eeprom);
681290650Shselasky
682290650Shselaskyint mlx5_vxlan_udp_port_add(struct mlx5_core_dev *dev, u16 port)
683290650Shselasky{
684290650Shselasky	u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)];
685290650Shselasky	u32 out[MLX5_ST_SZ_DW(add_vxlan_udp_dport_out)];
686290650Shselasky	int err;
687290650Shselasky
688290650Shselasky	memset(in, 0, sizeof(in));
689290650Shselasky	memset(out, 0, sizeof(out));
690290650Shselasky
691290650Shselasky	MLX5_SET(add_vxlan_udp_dport_in, in, opcode,
692290650Shselasky		 MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT);
693290650Shselasky	MLX5_SET(add_vxlan_udp_dport_in, in, vxlan_udp_port, port);
694290650Shselasky
695290650Shselasky	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
696290650Shselasky	if (err) {
697290650Shselasky		mlx5_core_err(dev, "Failed %s, port %u, err - %d",
698290650Shselasky			      mlx5_command_str(MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT),
699290650Shselasky			      port, err);
700290650Shselasky	}
701290650Shselasky
702290650Shselasky	return err;
703290650Shselasky}
704290650Shselasky
705290650Shselaskyint mlx5_vxlan_udp_port_delete(struct mlx5_core_dev *dev, u16 port)
706290650Shselasky{
707290650Shselasky	u32 in[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_in)];
708290650Shselasky	u32 out[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_out)];
709290650Shselasky	int err;
710290650Shselasky
711290650Shselasky	memset(in, 0, sizeof(in));
712290650Shselasky	memset(out, 0, sizeof(out));
713290650Shselasky
714290650Shselasky	MLX5_SET(delete_vxlan_udp_dport_in, in, opcode,
715290650Shselasky		 MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT);
716290650Shselasky	MLX5_SET(delete_vxlan_udp_dport_in, in, vxlan_udp_port, port);
717290650Shselasky
718290650Shselasky	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
719290650Shselasky	if (err) {
720290650Shselasky		mlx5_core_err(dev, "Failed %s, port %u, err - %d",
721290650Shselasky			      mlx5_command_str(MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT),
722290650Shselasky			      port, err);
723290650Shselasky	}
724290650Shselasky
725290650Shselasky	return err;
726290650Shselasky}
727290650Shselasky
728290650Shselaskyint mlx5_query_wol(struct mlx5_core_dev *dev, u8 *wol_mode)
729290650Shselasky{
730290650Shselasky	u32 in[MLX5_ST_SZ_DW(query_wol_rol_in)];
731290650Shselasky	u32 out[MLX5_ST_SZ_DW(query_wol_rol_out)];
732290650Shselasky	int err;
733290650Shselasky
734290650Shselasky	memset(in, 0, sizeof(in));
735290650Shselasky	memset(out, 0, sizeof(out));
736290650Shselasky
737290650Shselasky	MLX5_SET(query_wol_rol_in, in, opcode, MLX5_CMD_OP_QUERY_WOL_ROL);
738290650Shselasky
739290650Shselasky	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
740290650Shselasky
741290650Shselasky	if (!err)
742290650Shselasky		*wol_mode = MLX5_GET(query_wol_rol_out, out, wol_mode);
743290650Shselasky
744290650Shselasky	return err;
745290650Shselasky}
746290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_query_wol);
747290650Shselasky
748290650Shselaskyint mlx5_query_port_cong_status(struct mlx5_core_dev *mdev, int protocol,
749290650Shselasky				int priority, int *is_enable)
750290650Shselasky{
751290650Shselasky	u32 in[MLX5_ST_SZ_DW(query_cong_status_in)];
752290650Shselasky	u32 out[MLX5_ST_SZ_DW(query_cong_status_out)];
753290650Shselasky	int err;
754290650Shselasky
755290650Shselasky	memset(in, 0, sizeof(in));
756290650Shselasky	memset(out, 0, sizeof(out));
757290650Shselasky
758290650Shselasky	*is_enable = 0;
759290650Shselasky
760290650Shselasky	MLX5_SET(query_cong_status_in, in, opcode,
761290650Shselasky		 MLX5_CMD_OP_QUERY_CONG_STATUS);
762290650Shselasky	MLX5_SET(query_cong_status_in, in, cong_protocol, protocol);
763290650Shselasky	MLX5_SET(query_cong_status_in, in, priority, priority);
764290650Shselasky
765290650Shselasky	err = mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
766290650Shselasky					 out, sizeof(out));
767290650Shselasky	if (!err)
768290650Shselasky		*is_enable = MLX5_GET(query_cong_status_out, out, enable);
769290650Shselasky	return err;
770290650Shselasky}
771290650Shselasky
772290650Shselaskyint mlx5_modify_port_cong_status(struct mlx5_core_dev *mdev, int protocol,
773290650Shselasky				 int priority, int enable)
774290650Shselasky{
775290650Shselasky	u32 in[MLX5_ST_SZ_DW(modify_cong_status_in)];
776290650Shselasky	u32 out[MLX5_ST_SZ_DW(modify_cong_status_out)];
777290650Shselasky
778290650Shselasky	memset(in, 0, sizeof(in));
779290650Shselasky	memset(out, 0, sizeof(out));
780290650Shselasky
781290650Shselasky	MLX5_SET(modify_cong_status_in, in, opcode,
782290650Shselasky		 MLX5_CMD_OP_MODIFY_CONG_STATUS);
783290650Shselasky	MLX5_SET(modify_cong_status_in, in, cong_protocol, protocol);
784290650Shselasky	MLX5_SET(modify_cong_status_in, in, priority, priority);
785290650Shselasky	MLX5_SET(modify_cong_status_in, in, enable, enable);
786290650Shselasky
787290650Shselasky	return mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
788290650Shselasky					  out, sizeof(out));
789290650Shselasky}
790290650Shselasky
791290650Shselaskyint mlx5_query_port_cong_params(struct mlx5_core_dev *mdev, int protocol,
792290650Shselasky				void *out, int out_size)
793290650Shselasky{
794290650Shselasky	u32 in[MLX5_ST_SZ_DW(query_cong_params_in)];
795290650Shselasky
796290650Shselasky	memset(in, 0, sizeof(in));
797290650Shselasky
798290650Shselasky	MLX5_SET(query_cong_params_in, in, opcode,
799290650Shselasky		 MLX5_CMD_OP_QUERY_CONG_PARAMS);
800290650Shselasky	MLX5_SET(query_cong_params_in, in, cong_protocol, protocol);
801290650Shselasky
802290650Shselasky	return mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
803290650Shselasky					  out, out_size);
804290650Shselasky}
805290650Shselasky
806290650Shselaskyint mlx5_modify_port_cong_params(struct mlx5_core_dev *mdev,
807290650Shselasky				 void *in, int in_size)
808290650Shselasky{
809290650Shselasky	u32 out[MLX5_ST_SZ_DW(modify_cong_params_out)];
810290650Shselasky
811290650Shselasky	memset(out, 0, sizeof(out));
812290650Shselasky
813290650Shselasky	MLX5_SET(modify_cong_params_in, in, opcode,
814290650Shselasky		 MLX5_CMD_OP_MODIFY_CONG_PARAMS);
815290650Shselasky
816290650Shselasky	return mlx5_cmd_exec_check_status(mdev, in, in_size, out, sizeof(out));
817290650Shselasky}
818290650Shselasky
819290650Shselaskyint mlx5_query_port_cong_statistics(struct mlx5_core_dev *mdev, int clear,
820290650Shselasky				    void *out, int out_size)
821290650Shselasky{
822290650Shselasky	u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)];
823290650Shselasky
824290650Shselasky	memset(in, 0, sizeof(in));
825290650Shselasky
826290650Shselasky	MLX5_SET(query_cong_statistics_in, in, opcode,
827290650Shselasky		 MLX5_CMD_OP_QUERY_CONG_STATISTICS);
828290650Shselasky	MLX5_SET(query_cong_statistics_in, in, clear, clear);
829290650Shselasky
830290650Shselasky	return mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
831290650Shselasky					  out, out_size);
832290650Shselasky}
833306244Shselasky
834308684Shselaskyint mlx5_set_diagnostic_params(struct mlx5_core_dev *mdev, void *in,
835308684Shselasky			       int in_size)
836306244Shselasky{
837308684Shselasky	u32 out[MLX5_ST_SZ_DW(set_diagnostic_params_out)];
838306244Shselasky
839306244Shselasky	memset(out, 0, sizeof(out));
840306244Shselasky
841308684Shselasky	MLX5_SET(set_diagnostic_params_in, in, opcode,
842308684Shselasky		 MLX5_CMD_OP_SET_DIAGNOSTICS);
843306244Shselasky
844306244Shselasky	return mlx5_cmd_exec_check_status(mdev, in, in_size, out, sizeof(out));
845306244Shselasky}
846306244Shselasky
847308684Shselaskyint mlx5_query_diagnostic_counters(struct mlx5_core_dev *mdev,
848308684Shselasky				   u8 num_of_samples, u16 sample_index,
849308684Shselasky				   void *out, int out_size)
850306244Shselasky{
851308684Shselasky	u32 in[MLX5_ST_SZ_DW(query_diagnostic_counters_in)];
852306244Shselasky
853306244Shselasky	memset(in, 0, sizeof(in));
854306244Shselasky
855308684Shselasky	MLX5_SET(query_diagnostic_counters_in, in, opcode,
856306244Shselasky		 MLX5_CMD_OP_QUERY_DIAGNOSTICS);
857308684Shselasky	MLX5_SET(query_diagnostic_counters_in, in, num_of_samples,
858308684Shselasky		 num_of_samples);
859308684Shselasky	MLX5_SET(query_diagnostic_counters_in, in, sample_index, sample_index);
860306244Shselasky
861306244Shselasky	return mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out, out_size);
862306244Shselasky}
863