mlx5_port.c revision 302408
1/*-
2 * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 * $FreeBSD: stable/11/sys/dev/mlx5/mlx5_core/mlx5_port.c 290650 2015-11-10 12:20:22Z hselasky $
26 */
27
28#include <linux/module.h>
29#include <dev/mlx5/driver.h>
30#include "mlx5_core.h"
31
32int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in,
33			 int size_in, void *data_out, int size_out,
34			 u16 reg_num, int arg, int write)
35{
36	struct mlx5_access_reg_mbox_in *in = NULL;
37	struct mlx5_access_reg_mbox_out *out = NULL;
38	int err = -ENOMEM;
39
40	in = mlx5_vzalloc(sizeof(*in) + size_in);
41	if (!in)
42		return -ENOMEM;
43
44	out = mlx5_vzalloc(sizeof(*out) + size_out);
45	if (!out)
46		goto ex1;
47
48	memcpy(in->data, data_in, size_in);
49	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ACCESS_REG);
50	in->hdr.opmod = cpu_to_be16(!write);
51	in->arg = cpu_to_be32(arg);
52	in->register_id = cpu_to_be16(reg_num);
53	err = mlx5_cmd_exec(dev, in, sizeof(*in) + size_in, out,
54			    sizeof(*out) + size_out);
55	if (err)
56		goto ex2;
57
58	if (out->hdr.status)
59		err = mlx5_cmd_status_to_err(&out->hdr);
60
61	if (!err)
62		memcpy(data_out, out->data, size_out);
63
64ex2:
65	kvfree(out);
66ex1:
67	kvfree(in);
68	return err;
69}
70EXPORT_SYMBOL_GPL(mlx5_core_access_reg);
71
72
73struct mlx5_reg_pcap {
74	u8			rsvd0;
75	u8			port_num;
76	u8			rsvd1[2];
77	__be32			caps_127_96;
78	__be32			caps_95_64;
79	__be32			caps_63_32;
80	__be32			caps_31_0;
81};
82
83int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps)
84{
85	struct mlx5_reg_pcap in;
86	struct mlx5_reg_pcap out;
87	int err;
88
89	memset(&in, 0, sizeof(in));
90	in.caps_127_96 = cpu_to_be32(caps);
91	in.port_num = port_num;
92
93	err = mlx5_core_access_reg(dev, &in, sizeof(in), &out,
94				   sizeof(out), MLX5_REG_PCAP, 0, 1);
95
96	return err;
97}
98EXPORT_SYMBOL_GPL(mlx5_set_port_caps);
99
100int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
101			 int ptys_size, int proto_mask)
102{
103	u32 in[MLX5_ST_SZ_DW(ptys_reg)];
104	int err;
105
106	memset(in, 0, sizeof(in));
107	MLX5_SET(ptys_reg, in, local_port, 1);
108	MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
109
110	err = mlx5_core_access_reg(dev, in, sizeof(in), ptys,
111				   ptys_size, MLX5_REG_PTYS, 0, 0);
112
113	return err;
114}
115EXPORT_SYMBOL_GPL(mlx5_query_port_ptys);
116
117int mlx5_query_port_proto_cap(struct mlx5_core_dev *dev,
118			      u32 *proto_cap, int proto_mask)
119{
120	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
121	int err;
122
123	err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask);
124	if (err)
125		return err;
126
127	if (proto_mask == MLX5_PTYS_EN)
128		*proto_cap = MLX5_GET(ptys_reg, out, eth_proto_capability);
129	else
130		*proto_cap = MLX5_GET(ptys_reg, out, ib_proto_capability);
131
132	return 0;
133}
134EXPORT_SYMBOL_GPL(mlx5_query_port_proto_cap);
135
136int mlx5_query_port_proto_admin(struct mlx5_core_dev *dev,
137				u32 *proto_admin, int proto_mask)
138{
139	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
140	int err;
141
142	err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask);
143	if (err)
144		return err;
145
146	if (proto_mask == MLX5_PTYS_EN)
147		*proto_admin = MLX5_GET(ptys_reg, out, eth_proto_admin);
148	else
149		*proto_admin = MLX5_GET(ptys_reg, out, ib_proto_admin);
150
151	return 0;
152}
153EXPORT_SYMBOL_GPL(mlx5_query_port_proto_admin);
154
155int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
156			int proto_mask)
157{
158	u32 in[MLX5_ST_SZ_DW(ptys_reg)];
159	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
160	int err;
161
162	memset(in, 0, sizeof(in));
163
164	MLX5_SET(ptys_reg, in, local_port, 1);
165	MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
166	if (proto_mask == MLX5_PTYS_EN)
167		MLX5_SET(ptys_reg, in, eth_proto_admin, proto_admin);
168	else
169		MLX5_SET(ptys_reg, in, ib_proto_admin, proto_admin);
170
171	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
172				   sizeof(out), MLX5_REG_PTYS, 0, 1);
173	return err;
174}
175EXPORT_SYMBOL_GPL(mlx5_set_port_proto);
176
177int mlx5_set_port_status(struct mlx5_core_dev *dev,
178			 enum mlx5_port_status status)
179{
180	u32 in[MLX5_ST_SZ_DW(paos_reg)];
181	u32 out[MLX5_ST_SZ_DW(paos_reg)];
182	int err;
183
184	memset(in, 0, sizeof(in));
185
186	MLX5_SET(paos_reg, in, local_port, 1);
187
188	MLX5_SET(paos_reg, in, admin_status, status);
189	MLX5_SET(paos_reg, in, ase, 1);
190
191	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
192				   sizeof(out), MLX5_REG_PAOS, 0, 1);
193	return err;
194}
195
196int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
197{
198	u32 in[MLX5_ST_SZ_DW(paos_reg)];
199	u32 out[MLX5_ST_SZ_DW(paos_reg)];
200	int err;
201
202	memset(in, 0, sizeof(in));
203
204	MLX5_SET(paos_reg, in, local_port, 1);
205
206	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
207				   sizeof(out), MLX5_REG_PAOS, 0, 0);
208	if (err)
209		return err;
210
211	*status = MLX5_GET(paos_reg, out, oper_status);
212	return err;
213}
214
215static int mlx5_query_port_mtu(struct mlx5_core_dev *dev,
216			       int *admin_mtu, int *max_mtu, int *oper_mtu)
217{
218	u32 in[MLX5_ST_SZ_DW(pmtu_reg)];
219	u32 out[MLX5_ST_SZ_DW(pmtu_reg)];
220	int err;
221
222	memset(in, 0, sizeof(in));
223
224	MLX5_SET(pmtu_reg, in, local_port, 1);
225
226	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
227				   sizeof(out), MLX5_REG_PMTU, 0, 0);
228	if (err)
229		return err;
230
231	if (max_mtu)
232		*max_mtu  = MLX5_GET(pmtu_reg, out, max_mtu);
233	if (oper_mtu)
234		*oper_mtu = MLX5_GET(pmtu_reg, out, oper_mtu);
235	if (admin_mtu)
236		*admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu);
237
238	return err;
239}
240
241int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu)
242{
243	u32 in[MLX5_ST_SZ_DW(pmtu_reg)];
244	u32 out[MLX5_ST_SZ_DW(pmtu_reg)];
245
246	memset(in, 0, sizeof(in));
247
248	MLX5_SET(pmtu_reg, in, admin_mtu, mtu);
249	MLX5_SET(pmtu_reg, in, local_port, 1);
250
251	return mlx5_core_access_reg(dev, in, sizeof(in), out,
252				   sizeof(out), MLX5_REG_PMTU, 0, 1);
253}
254EXPORT_SYMBOL_GPL(mlx5_set_port_mtu);
255
256int mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu)
257{
258	return mlx5_query_port_mtu(dev, NULL, max_mtu, NULL);
259}
260EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu);
261
262int mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 port,
263			u32 rx_pause, u32 tx_pause)
264{
265	u32 in[MLX5_ST_SZ_DW(pfcc_reg)];
266	u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
267
268	memset(in, 0, sizeof(in));
269	memset(out, 0, sizeof(out));
270
271	MLX5_SET(pfcc_reg, in, local_port, port);
272	MLX5_SET(pfcc_reg, in, pptx, tx_pause);
273	MLX5_SET(pfcc_reg, in, pprx, rx_pause);
274
275	return mlx5_core_access_reg(dev, in, sizeof(in), out,
276				   sizeof(out), MLX5_REG_PFCC, 0, 1);
277}
278
279int mlx5_query_port_pause(struct mlx5_core_dev *dev, u32 port,
280			  u32 *rx_pause, u32 *tx_pause)
281{
282	u32 in[MLX5_ST_SZ_DW(pfcc_reg)];
283	u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
284	int err;
285
286	memset(in, 0, sizeof(in));
287	memset(out, 0, sizeof(out));
288
289	MLX5_SET(pfcc_reg, in, local_port, port);
290
291	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
292				   sizeof(out), MLX5_REG_PFCC, 0, 0);
293	if (err)
294		return err;
295
296	*rx_pause = MLX5_GET(pfcc_reg, out, pprx);
297	*tx_pause = MLX5_GET(pfcc_reg, out, pptx);
298
299	return 0;
300}
301
302int mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu)
303{
304	return mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu);
305}
306EXPORT_SYMBOL_GPL(mlx5_query_port_oper_mtu);
307
308u8 mlx5_is_wol_supported(struct mlx5_core_dev *dev)
309{
310	u8 wol_supported = 0;
311
312	if (MLX5_CAP_GEN(dev, wol_s))
313		wol_supported |= MLX5_WOL_SECURED_MAGIC;
314	if (MLX5_CAP_GEN(dev, wol_g))
315		wol_supported |= MLX5_WOL_MAGIC;
316	if (MLX5_CAP_GEN(dev, wol_a))
317		wol_supported |= MLX5_WOL_ARP;
318	if (MLX5_CAP_GEN(dev, wol_b))
319		wol_supported |= MLX5_WOL_BROADCAST;
320	if (MLX5_CAP_GEN(dev, wol_m))
321		wol_supported |= MLX5_WOL_MULTICAST;
322	if (MLX5_CAP_GEN(dev, wol_u))
323		wol_supported |= MLX5_WOL_UNICAST;
324	if (MLX5_CAP_GEN(dev, wol_p))
325		wol_supported |= MLX5_WOL_PHY_ACTIVITY;
326
327	return wol_supported;
328}
329EXPORT_SYMBOL_GPL(mlx5_is_wol_supported);
330
331int mlx5_set_wol(struct mlx5_core_dev *dev, u8 wol_mode)
332{
333	u32 in[MLX5_ST_SZ_DW(set_wol_rol_in)];
334	u32 out[MLX5_ST_SZ_DW(set_wol_rol_out)];
335
336	memset(in, 0, sizeof(in));
337	memset(out, 0, sizeof(out));
338
339	MLX5_SET(set_wol_rol_in, in, opcode, MLX5_CMD_OP_SET_WOL_ROL);
340	MLX5_SET(set_wol_rol_in, in, wol_mode_valid, 1);
341	MLX5_SET(set_wol_rol_in, in, wol_mode, wol_mode);
342
343	return mlx5_cmd_exec_check_status(dev, in, sizeof(in),
344					  out, sizeof(out));
345}
346EXPORT_SYMBOL_GPL(mlx5_set_wol);
347
348int mlx5_core_access_pvlc(struct mlx5_core_dev *dev,
349			  struct mlx5_pvlc_reg *pvlc, int write)
350{
351	int sz = MLX5_ST_SZ_BYTES(pvlc_reg);
352	u8 in[MLX5_ST_SZ_BYTES(pvlc_reg)];
353	u8 out[MLX5_ST_SZ_BYTES(pvlc_reg)];
354	int err;
355
356	memset(out, 0, sizeof(out));
357	memset(in, 0, sizeof(in));
358
359	MLX5_SET(pvlc_reg, in, local_port, pvlc->local_port);
360	if (write)
361		MLX5_SET(pvlc_reg, in, vl_admin, pvlc->vl_admin);
362
363	err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PVLC, 0,
364				   !!write);
365	if (err)
366		return err;
367
368	if (!write) {
369		pvlc->local_port = MLX5_GET(pvlc_reg, out, local_port);
370		pvlc->vl_hw_cap = MLX5_GET(pvlc_reg, out, vl_hw_cap);
371		pvlc->vl_admin = MLX5_GET(pvlc_reg, out, vl_admin);
372		pvlc->vl_operational = MLX5_GET(pvlc_reg, out, vl_operational);
373	}
374
375	return 0;
376}
377EXPORT_SYMBOL_GPL(mlx5_core_access_pvlc);
378
379int mlx5_core_access_ptys(struct mlx5_core_dev *dev,
380			  struct mlx5_ptys_reg *ptys, int write)
381{
382	int sz = MLX5_ST_SZ_BYTES(ptys_reg);
383	void *out = NULL;
384	void *in = NULL;
385	int err;
386
387	in = mlx5_vzalloc(sz);
388	if (!in)
389		return -ENOMEM;
390
391	out = mlx5_vzalloc(sz);
392	if (!out) {
393		kfree(in);
394		return -ENOMEM;
395	}
396
397	MLX5_SET(ptys_reg, in, local_port, ptys->local_port);
398	MLX5_SET(ptys_reg, in, proto_mask, ptys->proto_mask);
399	if (write) {
400		MLX5_SET(ptys_reg, in, eth_proto_capability,
401			 ptys->eth_proto_cap);
402		MLX5_SET(ptys_reg, in, ib_link_width_capability,
403			 ptys->ib_link_width_cap);
404		MLX5_SET(ptys_reg, in, ib_proto_capability,
405			 ptys->ib_proto_cap);
406		MLX5_SET(ptys_reg, in, eth_proto_admin, ptys->eth_proto_admin);
407		MLX5_SET(ptys_reg, in, ib_link_width_admin,
408			 ptys->ib_link_width_admin);
409		MLX5_SET(ptys_reg, in, ib_proto_admin, ptys->ib_proto_admin);
410		MLX5_SET(ptys_reg, in, eth_proto_oper, ptys->eth_proto_oper);
411		MLX5_SET(ptys_reg, in, ib_link_width_oper,
412			 ptys->ib_link_width_oper);
413		MLX5_SET(ptys_reg, in, ib_proto_oper, ptys->ib_proto_oper);
414		MLX5_SET(ptys_reg, in, eth_proto_lp_advertise,
415			 ptys->eth_proto_lp_advertise);
416	}
417
418	err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PTYS, 0,
419				   !!write);
420	if (err)
421		goto out;
422
423	if (!write) {
424		ptys->local_port = MLX5_GET(ptys_reg, out, local_port);
425		ptys->proto_mask = MLX5_GET(ptys_reg, out, proto_mask);
426		ptys->eth_proto_cap = MLX5_GET(ptys_reg, out,
427					       eth_proto_capability);
428		ptys->ib_link_width_cap = MLX5_GET(ptys_reg, out,
429					   ib_link_width_capability);
430		ptys->ib_proto_cap = MLX5_GET(ptys_reg, out,
431					      ib_proto_capability);
432		ptys->eth_proto_admin = MLX5_GET(ptys_reg, out,
433						 eth_proto_admin);
434		ptys->ib_link_width_admin = MLX5_GET(ptys_reg, out,
435						     ib_link_width_admin);
436		ptys->ib_proto_admin = MLX5_GET(ptys_reg, out, ib_proto_admin);
437		ptys->eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
438		ptys->ib_link_width_oper = MLX5_GET(ptys_reg, out,
439						    ib_link_width_oper);
440		ptys->ib_proto_oper = MLX5_GET(ptys_reg, out, ib_proto_oper);
441		ptys->eth_proto_lp_advertise = MLX5_GET(ptys_reg, out,
442							eth_proto_lp_advertise);
443	}
444
445out:
446	kvfree(in);
447	kvfree(out);
448	return err;
449}
450EXPORT_SYMBOL_GPL(mlx5_core_access_ptys);
451
452static int mtu_to_ib_mtu(int mtu)
453{
454	switch (mtu) {
455	case 256: return 1;
456	case 512: return 2;
457	case 1024: return 3;
458	case 2048: return 4;
459	case 4096: return 5;
460	default:
461		printf("mlx5_core: WARN: ""invalid mtu\n");
462		return -1;
463	}
464}
465
466int mlx5_core_access_pmtu(struct mlx5_core_dev *dev,
467			  struct mlx5_pmtu_reg *pmtu, int write)
468{
469	int sz = MLX5_ST_SZ_BYTES(pmtu_reg);
470	void *out = NULL;
471	void *in = NULL;
472	int err;
473
474	in = mlx5_vzalloc(sz);
475	if (!in)
476		return -ENOMEM;
477
478	out = mlx5_vzalloc(sz);
479	if (!out) {
480		kfree(in);
481		return -ENOMEM;
482	}
483
484	MLX5_SET(pmtu_reg, in, local_port, pmtu->local_port);
485	if (write)
486		MLX5_SET(pmtu_reg, in, admin_mtu, pmtu->admin_mtu);
487
488	err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PMTU, 0,
489				   !!write);
490	if (err)
491		goto out;
492
493	if (!write) {
494		pmtu->local_port = MLX5_GET(pmtu_reg, out, local_port);
495		pmtu->max_mtu = mtu_to_ib_mtu(MLX5_GET(pmtu_reg, out,
496						       max_mtu));
497		pmtu->admin_mtu = mtu_to_ib_mtu(MLX5_GET(pmtu_reg, out,
498							 admin_mtu));
499		pmtu->oper_mtu = mtu_to_ib_mtu(MLX5_GET(pmtu_reg, out,
500							oper_mtu));
501	}
502
503out:
504	kvfree(in);
505	kvfree(out);
506	return err;
507}
508EXPORT_SYMBOL_GPL(mlx5_core_access_pmtu);
509
510int mlx5_query_module_num(struct mlx5_core_dev *dev, int *module_num)
511{
512	u32 in[MLX5_ST_SZ_DW(pmlp_reg)];
513	u32 out[MLX5_ST_SZ_DW(pmlp_reg)];
514	int lane = 0;
515	int err;
516
517	memset(in, 0, sizeof(in));
518
519	MLX5_SET(pmlp_reg, in, local_port, 1);
520
521	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
522				   sizeof(out), MLX5_REG_PMLP, 0, 0);
523	if (err)
524		return err;
525
526	lane = MLX5_GET(pmlp_reg, out, lane0_module_mapping);
527	*module_num = lane & MLX5_EEPROM_IDENTIFIER_BYTE_MASK;
528
529	return 0;
530}
531EXPORT_SYMBOL_GPL(mlx5_query_module_num);
532
533int mlx5_query_eeprom(struct mlx5_core_dev *dev,
534		      int i2c_addr, int page_num, int device_addr,
535		      int size, int module_num, u32 *data, int *size_read)
536{
537	u32 in[MLX5_ST_SZ_DW(mcia_reg)];
538	u32 out[MLX5_ST_SZ_DW(mcia_reg)];
539	u32 *ptr = (u32 *)MLX5_ADDR_OF(mcia_reg, out, dword_0);
540	int status;
541	int err;
542
543	memset(in, 0, sizeof(in));
544	size = min_t(int, size, MLX5_EEPROM_MAX_BYTES);
545
546	MLX5_SET(mcia_reg, in, l, 0);
547	MLX5_SET(mcia_reg, in, module, module_num);
548	MLX5_SET(mcia_reg, in, i2c_device_address, i2c_addr);
549	MLX5_SET(mcia_reg, in, page_number, page_num);
550	MLX5_SET(mcia_reg, in, device_address, device_addr);
551	MLX5_SET(mcia_reg, in, size, size);
552
553	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
554				   sizeof(out), MLX5_REG_MCIA, 0, 0);
555	if (err)
556		return err;
557
558	status = MLX5_GET(mcia_reg, out, status);
559	if (status)
560		return status;
561
562	memcpy(data, ptr, size);
563	*size_read = size;
564	return 0;
565}
566EXPORT_SYMBOL_GPL(mlx5_query_eeprom);
567
568int mlx5_vxlan_udp_port_add(struct mlx5_core_dev *dev, u16 port)
569{
570	u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)];
571	u32 out[MLX5_ST_SZ_DW(add_vxlan_udp_dport_out)];
572	int err;
573
574	memset(in, 0, sizeof(in));
575	memset(out, 0, sizeof(out));
576
577	MLX5_SET(add_vxlan_udp_dport_in, in, opcode,
578		 MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT);
579	MLX5_SET(add_vxlan_udp_dport_in, in, vxlan_udp_port, port);
580
581	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
582	if (err) {
583		mlx5_core_err(dev, "Failed %s, port %u, err - %d",
584			      mlx5_command_str(MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT),
585			      port, err);
586	}
587
588	return err;
589}
590
591int mlx5_vxlan_udp_port_delete(struct mlx5_core_dev *dev, u16 port)
592{
593	u32 in[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_in)];
594	u32 out[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_out)];
595	int err;
596
597	memset(in, 0, sizeof(in));
598	memset(out, 0, sizeof(out));
599
600	MLX5_SET(delete_vxlan_udp_dport_in, in, opcode,
601		 MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT);
602	MLX5_SET(delete_vxlan_udp_dport_in, in, vxlan_udp_port, port);
603
604	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
605	if (err) {
606		mlx5_core_err(dev, "Failed %s, port %u, err - %d",
607			      mlx5_command_str(MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT),
608			      port, err);
609	}
610
611	return err;
612}
613
614int mlx5_query_wol(struct mlx5_core_dev *dev, u8 *wol_mode)
615{
616	u32 in[MLX5_ST_SZ_DW(query_wol_rol_in)];
617	u32 out[MLX5_ST_SZ_DW(query_wol_rol_out)];
618	int err;
619
620	memset(in, 0, sizeof(in));
621	memset(out, 0, sizeof(out));
622
623	MLX5_SET(query_wol_rol_in, in, opcode, MLX5_CMD_OP_QUERY_WOL_ROL);
624
625	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
626
627	if (!err)
628		*wol_mode = MLX5_GET(query_wol_rol_out, out, wol_mode);
629
630	return err;
631}
632EXPORT_SYMBOL_GPL(mlx5_query_wol);
633
634int mlx5_query_port_cong_status(struct mlx5_core_dev *mdev, int protocol,
635				int priority, int *is_enable)
636{
637	u32 in[MLX5_ST_SZ_DW(query_cong_status_in)];
638	u32 out[MLX5_ST_SZ_DW(query_cong_status_out)];
639	int err;
640
641	memset(in, 0, sizeof(in));
642	memset(out, 0, sizeof(out));
643
644	*is_enable = 0;
645
646	MLX5_SET(query_cong_status_in, in, opcode,
647		 MLX5_CMD_OP_QUERY_CONG_STATUS);
648	MLX5_SET(query_cong_status_in, in, cong_protocol, protocol);
649	MLX5_SET(query_cong_status_in, in, priority, priority);
650
651	err = mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
652					 out, sizeof(out));
653	if (!err)
654		*is_enable = MLX5_GET(query_cong_status_out, out, enable);
655	return err;
656}
657
658int mlx5_modify_port_cong_status(struct mlx5_core_dev *mdev, int protocol,
659				 int priority, int enable)
660{
661	u32 in[MLX5_ST_SZ_DW(modify_cong_status_in)];
662	u32 out[MLX5_ST_SZ_DW(modify_cong_status_out)];
663
664	memset(in, 0, sizeof(in));
665	memset(out, 0, sizeof(out));
666
667	MLX5_SET(modify_cong_status_in, in, opcode,
668		 MLX5_CMD_OP_MODIFY_CONG_STATUS);
669	MLX5_SET(modify_cong_status_in, in, cong_protocol, protocol);
670	MLX5_SET(modify_cong_status_in, in, priority, priority);
671	MLX5_SET(modify_cong_status_in, in, enable, enable);
672
673	return mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
674					  out, sizeof(out));
675}
676
677int mlx5_query_port_cong_params(struct mlx5_core_dev *mdev, int protocol,
678				void *out, int out_size)
679{
680	u32 in[MLX5_ST_SZ_DW(query_cong_params_in)];
681
682	memset(in, 0, sizeof(in));
683
684	MLX5_SET(query_cong_params_in, in, opcode,
685		 MLX5_CMD_OP_QUERY_CONG_PARAMS);
686	MLX5_SET(query_cong_params_in, in, cong_protocol, protocol);
687
688	return mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
689					  out, out_size);
690}
691
692int mlx5_modify_port_cong_params(struct mlx5_core_dev *mdev,
693				 void *in, int in_size)
694{
695	u32 out[MLX5_ST_SZ_DW(modify_cong_params_out)];
696
697	memset(out, 0, sizeof(out));
698
699	MLX5_SET(modify_cong_params_in, in, opcode,
700		 MLX5_CMD_OP_MODIFY_CONG_PARAMS);
701
702	return mlx5_cmd_exec_check_status(mdev, in, in_size, out, sizeof(out));
703}
704
705int mlx5_query_port_cong_statistics(struct mlx5_core_dev *mdev, int clear,
706				    void *out, int out_size)
707{
708	u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)];
709
710	memset(in, 0, sizeof(in));
711
712	MLX5_SET(query_cong_statistics_in, in, opcode,
713		 MLX5_CMD_OP_QUERY_CONG_STATISTICS);
714	MLX5_SET(query_cong_statistics_in, in, clear, clear);
715
716	return mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
717					  out, out_size);
718}
719