2 * Copyright (c) 2013-2015, Mellanox Technologies, Ltd. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
28 #include <linux/module.h>
29 #include <dev/mlx5/port.h>
30 #include "mlx5_core.h"
32 int 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)
36 int outlen = MLX5_ST_SZ_BYTES(access_register_out) + size_out;
37 int inlen = MLX5_ST_SZ_BYTES(access_register_in) + size_in;
43 in = mlx5_vzalloc(inlen);
44 out = mlx5_vzalloc(outlen);
48 data = MLX5_ADDR_OF(access_register_in, in, register_data);
49 memcpy(data, data_in, size_in);
51 MLX5_SET(access_register_in, in, opcode, MLX5_CMD_OP_ACCESS_REG);
52 MLX5_SET(access_register_in, in, op_mod, !write);
53 MLX5_SET(access_register_in, in, argument, arg);
54 MLX5_SET(access_register_in, in, register_id, reg_num);
56 err = mlx5_cmd_exec(dev, in, inlen, out, outlen);
59 data = MLX5_ADDR_OF(access_register_out, out, register_data);
60 memcpy(data_out, data, size_out);
67 EXPORT_SYMBOL_GPL(mlx5_core_access_reg);
69 struct mlx5_reg_pcap {
79 /* This function should be used after setting a port register only */
80 void mlx5_toggle_port_link(struct mlx5_core_dev *dev)
82 enum mlx5_port_status ps;
84 mlx5_query_port_admin_status(dev, &ps);
85 mlx5_set_port_status(dev, MLX5_PORT_DOWN);
86 if (ps == MLX5_PORT_UP)
87 mlx5_set_port_status(dev, MLX5_PORT_UP);
89 EXPORT_SYMBOL_GPL(mlx5_toggle_port_link);
91 int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps)
93 struct mlx5_reg_pcap in;
94 struct mlx5_reg_pcap out;
97 memset(&in, 0, sizeof(in));
98 in.caps_127_96 = cpu_to_be32(caps);
99 in.port_num = port_num;
101 err = mlx5_core_access_reg(dev, &in, sizeof(in), &out,
102 sizeof(out), MLX5_REG_PCAP, 0, 1);
106 EXPORT_SYMBOL_GPL(mlx5_set_port_caps);
108 int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
109 int ptys_size, int proto_mask, u8 local_port)
111 u32 in[MLX5_ST_SZ_DW(ptys_reg)];
114 memset(in, 0, sizeof(in));
115 MLX5_SET(ptys_reg, in, local_port, local_port);
116 MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
118 err = mlx5_core_access_reg(dev, in, sizeof(in), ptys,
119 ptys_size, MLX5_REG_PTYS, 0, 0);
123 EXPORT_SYMBOL_GPL(mlx5_query_port_ptys);
125 int mlx5_query_port_proto_cap(struct mlx5_core_dev *dev,
126 u32 *proto_cap, int proto_mask)
128 u32 out[MLX5_ST_SZ_DW(ptys_reg)];
131 err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask, 1);
135 if (proto_mask == MLX5_PTYS_EN)
136 *proto_cap = MLX5_GET(ptys_reg, out, eth_proto_capability);
138 *proto_cap = MLX5_GET(ptys_reg, out, ib_proto_capability);
142 EXPORT_SYMBOL_GPL(mlx5_query_port_proto_cap);
144 int mlx5_query_port_autoneg(struct mlx5_core_dev *dev, int proto_mask,
145 u8 *an_disable_cap, u8 *an_disable_status)
147 u32 out[MLX5_ST_SZ_DW(ptys_reg)];
150 err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask, 1);
154 *an_disable_status = MLX5_GET(ptys_reg, out, an_disable_admin);
155 *an_disable_cap = MLX5_GET(ptys_reg, out, an_disable_cap);
159 EXPORT_SYMBOL_GPL(mlx5_query_port_autoneg);
161 int mlx5_set_port_autoneg(struct mlx5_core_dev *dev, bool disable,
162 u32 eth_proto_admin, int proto_mask)
164 u32 in[MLX5_ST_SZ_DW(ptys_reg)] = {0};
165 u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0};
167 u8 an_disable_status;
170 err = mlx5_query_port_autoneg(dev, proto_mask, &an_disable_cap,
177 MLX5_SET(ptys_reg, in, local_port, 1);
178 MLX5_SET(ptys_reg, in, an_disable_admin, disable);
179 MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
180 if (proto_mask == MLX5_PTYS_EN)
181 MLX5_SET(ptys_reg, in, eth_proto_admin, eth_proto_admin);
183 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
184 sizeof(out), MLX5_REG_PTYS, 0, 1);
187 EXPORT_SYMBOL_GPL(mlx5_set_port_autoneg);
189 int mlx5_query_port_proto_admin(struct mlx5_core_dev *dev,
190 u32 *proto_admin, int proto_mask)
192 u32 out[MLX5_ST_SZ_DW(ptys_reg)];
195 err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask, 1);
199 if (proto_mask == MLX5_PTYS_EN)
200 *proto_admin = MLX5_GET(ptys_reg, out, eth_proto_admin);
202 *proto_admin = MLX5_GET(ptys_reg, out, ib_proto_admin);
206 EXPORT_SYMBOL_GPL(mlx5_query_port_proto_admin);
208 int mlx5_query_port_eth_proto_oper(struct mlx5_core_dev *dev,
209 u32 *proto_oper, u8 local_port)
211 u32 out[MLX5_ST_SZ_DW(ptys_reg)];
214 err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN,
219 *proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
223 EXPORT_SYMBOL(mlx5_query_port_eth_proto_oper);
225 int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
228 u32 in[MLX5_ST_SZ_DW(ptys_reg)] = {0};
229 u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0};
232 MLX5_SET(ptys_reg, in, local_port, 1);
233 MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
234 if (proto_mask == MLX5_PTYS_EN)
235 MLX5_SET(ptys_reg, in, eth_proto_admin, proto_admin);
237 MLX5_SET(ptys_reg, in, ib_proto_admin, proto_admin);
239 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
240 sizeof(out), MLX5_REG_PTYS, 0, 1);
243 EXPORT_SYMBOL_GPL(mlx5_set_port_proto);
245 int mlx5_set_port_status(struct mlx5_core_dev *dev,
246 enum mlx5_port_status status)
248 u32 in[MLX5_ST_SZ_DW(paos_reg)] = {0};
249 u32 out[MLX5_ST_SZ_DW(paos_reg)] = {0};
252 MLX5_SET(paos_reg, in, local_port, 1);
254 MLX5_SET(paos_reg, in, admin_status, status);
255 MLX5_SET(paos_reg, in, ase, 1);
257 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
258 sizeof(out), MLX5_REG_PAOS, 0, 1);
262 int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
264 u32 in[MLX5_ST_SZ_DW(paos_reg)] = {0};
265 u32 out[MLX5_ST_SZ_DW(paos_reg)] = {0};
268 MLX5_SET(paos_reg, in, local_port, 1);
270 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
271 sizeof(out), MLX5_REG_PAOS, 0, 0);
275 *status = MLX5_GET(paos_reg, out, oper_status);
279 int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
280 enum mlx5_port_status *status)
282 u32 in[MLX5_ST_SZ_DW(paos_reg)] = {0};
283 u32 out[MLX5_ST_SZ_DW(paos_reg)];
286 MLX5_SET(paos_reg, in, local_port, 1);
287 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
288 sizeof(out), MLX5_REG_PAOS, 0, 0);
291 *status = MLX5_GET(paos_reg, out, admin_status);
294 EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status);
296 static int mlx5_query_port_mtu(struct mlx5_core_dev *dev,
297 int *admin_mtu, int *max_mtu, int *oper_mtu)
299 u32 in[MLX5_ST_SZ_DW(pmtu_reg)] = {0};
300 u32 out[MLX5_ST_SZ_DW(pmtu_reg)] = {0};
303 MLX5_SET(pmtu_reg, in, local_port, 1);
305 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
306 sizeof(out), MLX5_REG_PMTU, 0, 0);
311 *max_mtu = MLX5_GET(pmtu_reg, out, max_mtu);
313 *oper_mtu = MLX5_GET(pmtu_reg, out, oper_mtu);
315 *admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu);
320 int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu)
322 u32 in[MLX5_ST_SZ_DW(pmtu_reg)] = {0};
323 u32 out[MLX5_ST_SZ_DW(pmtu_reg)] = {0};
325 MLX5_SET(pmtu_reg, in, admin_mtu, mtu);
326 MLX5_SET(pmtu_reg, in, local_port, 1);
328 return mlx5_core_access_reg(dev, in, sizeof(in), out,
329 sizeof(out), MLX5_REG_PMTU, 0, 1);
331 EXPORT_SYMBOL_GPL(mlx5_set_port_mtu);
333 int mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu)
335 return mlx5_query_port_mtu(dev, NULL, max_mtu, NULL);
337 EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu);
339 int mlx5_set_port_pause_and_pfc(struct mlx5_core_dev *dev, u32 port,
340 u8 rx_pause, u8 tx_pause,
341 u8 pfc_en_rx, u8 pfc_en_tx)
343 u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
344 u32 out[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
346 if (pfc_en_rx || pfc_en_tx) {
347 /* PFC and global pauseframes are incompatible features */
348 if (tx_pause || rx_pause)
352 MLX5_SET(pfcc_reg, in, local_port, port);
353 MLX5_SET(pfcc_reg, in, pptx, tx_pause);
354 MLX5_SET(pfcc_reg, in, pprx, rx_pause);
355 MLX5_SET(pfcc_reg, in, pfctx, pfc_en_tx);
356 MLX5_SET(pfcc_reg, in, pfcrx, pfc_en_rx);
357 MLX5_SET(pfcc_reg, in, prio_mask_tx, pfc_en_tx);
358 MLX5_SET(pfcc_reg, in, prio_mask_rx, pfc_en_rx);
360 return mlx5_core_access_reg(dev, in, sizeof(in), out,
361 sizeof(out), MLX5_REG_PFCC, 0, 1);
364 int mlx5_query_port_pause(struct mlx5_core_dev *dev, u32 port,
365 u32 *rx_pause, u32 *tx_pause)
367 u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
368 u32 out[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
371 MLX5_SET(pfcc_reg, in, local_port, port);
373 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
374 sizeof(out), MLX5_REG_PFCC, 0, 0);
378 *rx_pause = MLX5_GET(pfcc_reg, out, pprx);
379 *tx_pause = MLX5_GET(pfcc_reg, out, pptx);
384 int mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx, u8 *pfc_en_rx)
386 u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {};
387 u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
390 MLX5_SET(pfcc_reg, in, local_port, 1);
391 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
392 sizeof(out), MLX5_REG_PFCC, 0, 0);
396 if (pfc_en_tx != NULL)
397 *pfc_en_tx = MLX5_GET(pfcc_reg, out, pfctx);
398 if (pfc_en_rx != NULL)
399 *pfc_en_rx = MLX5_GET(pfcc_reg, out, pfcrx);
402 EXPORT_SYMBOL_GPL(mlx5_query_port_pfc);
404 int mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu)
406 return mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu);
408 EXPORT_SYMBOL_GPL(mlx5_query_port_oper_mtu);
410 u8 mlx5_is_wol_supported(struct mlx5_core_dev *dev)
412 u8 wol_supported = 0;
414 if (MLX5_CAP_GEN(dev, wol_s))
415 wol_supported |= MLX5_WOL_SECURED_MAGIC;
416 if (MLX5_CAP_GEN(dev, wol_g))
417 wol_supported |= MLX5_WOL_MAGIC;
418 if (MLX5_CAP_GEN(dev, wol_a))
419 wol_supported |= MLX5_WOL_ARP;
420 if (MLX5_CAP_GEN(dev, wol_b))
421 wol_supported |= MLX5_WOL_BROADCAST;
422 if (MLX5_CAP_GEN(dev, wol_m))
423 wol_supported |= MLX5_WOL_MULTICAST;
424 if (MLX5_CAP_GEN(dev, wol_u))
425 wol_supported |= MLX5_WOL_UNICAST;
426 if (MLX5_CAP_GEN(dev, wol_p))
427 wol_supported |= MLX5_WOL_PHY_ACTIVITY;
429 return wol_supported;
431 EXPORT_SYMBOL_GPL(mlx5_is_wol_supported);
433 int mlx5_set_wol(struct mlx5_core_dev *dev, u8 wol_mode)
435 u32 in[MLX5_ST_SZ_DW(set_wol_rol_in)] = {0};
436 u32 out[MLX5_ST_SZ_DW(set_wol_rol_out)] = {0};
438 MLX5_SET(set_wol_rol_in, in, opcode, MLX5_CMD_OP_SET_WOL_ROL);
439 MLX5_SET(set_wol_rol_in, in, wol_mode_valid, 1);
440 MLX5_SET(set_wol_rol_in, in, wol_mode, wol_mode);
442 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
444 EXPORT_SYMBOL_GPL(mlx5_set_wol);
446 int mlx5_query_dropless_mode(struct mlx5_core_dev *dev, u16 *timeout)
448 u32 in[MLX5_ST_SZ_DW(query_delay_drop_params_in)] = {0};
449 u32 out[MLX5_ST_SZ_DW(query_delay_drop_params_out)] = {0};
452 MLX5_SET(query_delay_drop_params_in, in, opcode,
453 MLX5_CMD_OP_QUERY_DELAY_DROP_PARAMS);
455 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
459 *timeout = MLX5_GET(query_delay_drop_params_out, out,
464 EXPORT_SYMBOL_GPL(mlx5_query_dropless_mode);
466 int mlx5_set_dropless_mode(struct mlx5_core_dev *dev, u16 timeout)
468 u32 in[MLX5_ST_SZ_DW(set_delay_drop_params_in)] = {0};
469 u32 out[MLX5_ST_SZ_DW(set_delay_drop_params_out)] = {0};
471 MLX5_SET(set_delay_drop_params_in, in, opcode,
472 MLX5_CMD_OP_SET_DELAY_DROP_PARAMS);
473 MLX5_SET(set_delay_drop_params_in, in, delay_drop_timeout, timeout);
475 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
477 EXPORT_SYMBOL_GPL(mlx5_set_dropless_mode);
479 int mlx5_core_access_pvlc(struct mlx5_core_dev *dev,
480 struct mlx5_pvlc_reg *pvlc, int write)
482 int sz = MLX5_ST_SZ_BYTES(pvlc_reg);
483 u8 in[MLX5_ST_SZ_BYTES(pvlc_reg)] = {0};
484 u8 out[MLX5_ST_SZ_BYTES(pvlc_reg)] = {0};
487 MLX5_SET(pvlc_reg, in, local_port, pvlc->local_port);
489 MLX5_SET(pvlc_reg, in, vl_admin, pvlc->vl_admin);
491 err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PVLC, 0,
497 pvlc->local_port = MLX5_GET(pvlc_reg, out, local_port);
498 pvlc->vl_hw_cap = MLX5_GET(pvlc_reg, out, vl_hw_cap);
499 pvlc->vl_admin = MLX5_GET(pvlc_reg, out, vl_admin);
500 pvlc->vl_operational = MLX5_GET(pvlc_reg, out, vl_operational);
505 EXPORT_SYMBOL_GPL(mlx5_core_access_pvlc);
507 int mlx5_core_access_ptys(struct mlx5_core_dev *dev,
508 struct mlx5_ptys_reg *ptys, int write)
510 int sz = MLX5_ST_SZ_BYTES(ptys_reg);
515 in = mlx5_vzalloc(sz);
519 out = mlx5_vzalloc(sz);
525 MLX5_SET(ptys_reg, in, local_port, ptys->local_port);
526 MLX5_SET(ptys_reg, in, proto_mask, ptys->proto_mask);
528 MLX5_SET(ptys_reg, in, eth_proto_capability,
529 ptys->eth_proto_cap);
530 MLX5_SET(ptys_reg, in, ib_link_width_capability,
531 ptys->ib_link_width_cap);
532 MLX5_SET(ptys_reg, in, ib_proto_capability,
534 MLX5_SET(ptys_reg, in, eth_proto_admin, ptys->eth_proto_admin);
535 MLX5_SET(ptys_reg, in, ib_link_width_admin,
536 ptys->ib_link_width_admin);
537 MLX5_SET(ptys_reg, in, ib_proto_admin, ptys->ib_proto_admin);
538 MLX5_SET(ptys_reg, in, eth_proto_oper, ptys->eth_proto_oper);
539 MLX5_SET(ptys_reg, in, ib_link_width_oper,
540 ptys->ib_link_width_oper);
541 MLX5_SET(ptys_reg, in, ib_proto_oper, ptys->ib_proto_oper);
542 MLX5_SET(ptys_reg, in, eth_proto_lp_advertise,
543 ptys->eth_proto_lp_advertise);
546 err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PTYS, 0,
552 ptys->local_port = MLX5_GET(ptys_reg, out, local_port);
553 ptys->proto_mask = MLX5_GET(ptys_reg, out, proto_mask);
554 ptys->eth_proto_cap = MLX5_GET(ptys_reg, out,
555 eth_proto_capability);
556 ptys->ib_link_width_cap = MLX5_GET(ptys_reg, out,
557 ib_link_width_capability);
558 ptys->ib_proto_cap = MLX5_GET(ptys_reg, out,
559 ib_proto_capability);
560 ptys->eth_proto_admin = MLX5_GET(ptys_reg, out,
562 ptys->ib_link_width_admin = MLX5_GET(ptys_reg, out,
563 ib_link_width_admin);
564 ptys->ib_proto_admin = MLX5_GET(ptys_reg, out, ib_proto_admin);
565 ptys->eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
566 ptys->ib_link_width_oper = MLX5_GET(ptys_reg, out,
568 ptys->ib_proto_oper = MLX5_GET(ptys_reg, out, ib_proto_oper);
569 ptys->eth_proto_lp_advertise = MLX5_GET(ptys_reg, out,
570 eth_proto_lp_advertise);
578 EXPORT_SYMBOL_GPL(mlx5_core_access_ptys);
580 static int mtu_to_ib_mtu(int mtu)
589 printf("mlx5_core: WARN: ""invalid mtu\n");
594 int mlx5_core_access_pmtu(struct mlx5_core_dev *dev,
595 struct mlx5_pmtu_reg *pmtu, int write)
597 int sz = MLX5_ST_SZ_BYTES(pmtu_reg);
602 in = mlx5_vzalloc(sz);
606 out = mlx5_vzalloc(sz);
612 MLX5_SET(pmtu_reg, in, local_port, pmtu->local_port);
614 MLX5_SET(pmtu_reg, in, admin_mtu, pmtu->admin_mtu);
616 err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PMTU, 0,
622 pmtu->local_port = MLX5_GET(pmtu_reg, out, local_port);
623 pmtu->max_mtu = mtu_to_ib_mtu(MLX5_GET(pmtu_reg, out,
625 pmtu->admin_mtu = mtu_to_ib_mtu(MLX5_GET(pmtu_reg, out,
627 pmtu->oper_mtu = mtu_to_ib_mtu(MLX5_GET(pmtu_reg, out,
636 EXPORT_SYMBOL_GPL(mlx5_core_access_pmtu);
638 int mlx5_query_module_num(struct mlx5_core_dev *dev, int *module_num)
640 u32 in[MLX5_ST_SZ_DW(pmlp_reg)] = {0};
641 u32 out[MLX5_ST_SZ_DW(pmlp_reg)] = {0};
645 MLX5_SET(pmlp_reg, in, local_port, 1);
647 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
648 sizeof(out), MLX5_REG_PMLP, 0, 0);
652 lane = MLX5_GET(pmlp_reg, out, lane0_module_mapping);
653 *module_num = lane & MLX5_EEPROM_IDENTIFIER_BYTE_MASK;
657 EXPORT_SYMBOL_GPL(mlx5_query_module_num);
659 int mlx5_query_eeprom(struct mlx5_core_dev *dev,
660 int i2c_addr, int page_num, int device_addr,
661 int size, int module_num, u32 *data, int *size_read)
663 u32 in[MLX5_ST_SZ_DW(mcia_reg)] = {0};
664 u32 out[MLX5_ST_SZ_DW(mcia_reg)] = {0};
665 u32 *ptr = (u32 *)MLX5_ADDR_OF(mcia_reg, out, dword_0);
669 size = min_t(int, size, MLX5_EEPROM_MAX_BYTES);
671 MLX5_SET(mcia_reg, in, l, 0);
672 MLX5_SET(mcia_reg, in, module, module_num);
673 MLX5_SET(mcia_reg, in, i2c_device_address, i2c_addr);
674 MLX5_SET(mcia_reg, in, page_number, page_num);
675 MLX5_SET(mcia_reg, in, device_address, device_addr);
676 MLX5_SET(mcia_reg, in, size, size);
678 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
679 sizeof(out), MLX5_REG_MCIA, 0, 0);
683 status = MLX5_GET(mcia_reg, out, status);
687 memcpy(data, ptr, size);
691 EXPORT_SYMBOL_GPL(mlx5_query_eeprom);
693 int mlx5_vxlan_udp_port_add(struct mlx5_core_dev *dev, u16 port)
695 u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)] = {0};
696 u32 out[MLX5_ST_SZ_DW(add_vxlan_udp_dport_out)] = {0};
699 MLX5_SET(add_vxlan_udp_dport_in, in, opcode,
700 MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT);
701 MLX5_SET(add_vxlan_udp_dport_in, in, vxlan_udp_port, port);
703 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
705 mlx5_core_err(dev, "Failed %s, port %u, err - %d",
706 mlx5_command_str(MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT),
713 int mlx5_vxlan_udp_port_delete(struct mlx5_core_dev *dev, u16 port)
715 u32 in[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_in)] = {0};
716 u32 out[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_out)] = {0};
719 MLX5_SET(delete_vxlan_udp_dport_in, in, opcode,
720 MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT);
721 MLX5_SET(delete_vxlan_udp_dport_in, in, vxlan_udp_port, port);
723 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
725 mlx5_core_err(dev, "Failed %s, port %u, err - %d",
726 mlx5_command_str(MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT),
733 int mlx5_query_wol(struct mlx5_core_dev *dev, u8 *wol_mode)
735 u32 in[MLX5_ST_SZ_DW(query_wol_rol_in)] = {0};
736 u32 out[MLX5_ST_SZ_DW(query_wol_rol_out)] = {0};
739 MLX5_SET(query_wol_rol_in, in, opcode, MLX5_CMD_OP_QUERY_WOL_ROL);
741 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
744 *wol_mode = MLX5_GET(query_wol_rol_out, out, wol_mode);
748 EXPORT_SYMBOL_GPL(mlx5_query_wol);
750 int mlx5_query_port_cong_status(struct mlx5_core_dev *mdev, int protocol,
751 int priority, int *is_enable)
753 u32 in[MLX5_ST_SZ_DW(query_cong_status_in)] = {0};
754 u32 out[MLX5_ST_SZ_DW(query_cong_status_out)] = {0};
759 MLX5_SET(query_cong_status_in, in, opcode,
760 MLX5_CMD_OP_QUERY_CONG_STATUS);
761 MLX5_SET(query_cong_status_in, in, cong_protocol, protocol);
762 MLX5_SET(query_cong_status_in, in, priority, priority);
764 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
766 *is_enable = MLX5_GET(query_cong_status_out, out, enable);
770 int mlx5_modify_port_cong_status(struct mlx5_core_dev *mdev, int protocol,
771 int priority, int enable)
773 u32 in[MLX5_ST_SZ_DW(modify_cong_status_in)] = {0};
774 u32 out[MLX5_ST_SZ_DW(modify_cong_status_out)] = {0};
776 MLX5_SET(modify_cong_status_in, in, opcode,
777 MLX5_CMD_OP_MODIFY_CONG_STATUS);
778 MLX5_SET(modify_cong_status_in, in, cong_protocol, protocol);
779 MLX5_SET(modify_cong_status_in, in, priority, priority);
780 MLX5_SET(modify_cong_status_in, in, enable, enable);
782 return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
785 int mlx5_query_port_cong_params(struct mlx5_core_dev *mdev, int protocol,
786 void *out, int out_size)
788 u32 in[MLX5_ST_SZ_DW(query_cong_params_in)] = {0};
790 MLX5_SET(query_cong_params_in, in, opcode,
791 MLX5_CMD_OP_QUERY_CONG_PARAMS);
792 MLX5_SET(query_cong_params_in, in, cong_protocol, protocol);
794 return mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size);
797 static int mlx5_query_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *out,
800 u32 in[MLX5_ST_SZ_DW(qtct_reg)];
802 if (!MLX5_CAP_GEN(mdev, ets))
805 memset(in, 0, sizeof(in));
806 return mlx5_core_access_reg(mdev, in, sizeof(in), out, outlen,
807 MLX5_REG_QETCR, 0, 0);
810 int mlx5_max_tc(struct mlx5_core_dev *mdev)
812 u8 num_tc = MLX5_CAP_GEN(mdev, max_tc) ? : 8;
816 EXPORT_SYMBOL_GPL(mlx5_max_tc);
818 static int mlx5_set_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *in,
821 u32 out[MLX5_ST_SZ_DW(qtct_reg)];
823 if (!MLX5_CAP_GEN(mdev, ets))
826 return mlx5_core_access_reg(mdev, in, inlen, out, sizeof(out),
827 MLX5_REG_QETCR, 0, 1);
830 int mlx5_query_port_tc_rate_limit(struct mlx5_core_dev *mdev,
834 u32 out[MLX5_ST_SZ_DW(qetc_reg)];
839 err = mlx5_query_port_qetcr_reg(mdev, out, sizeof(out));
843 for (i = 0; i <= mlx5_max_tc(mdev); i++) {
844 ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, out, tc_configuration[i]);
846 max_bw_value[i] = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf,
848 max_bw_units[i] = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf,
854 EXPORT_SYMBOL_GPL(mlx5_query_port_tc_rate_limit);
856 int mlx5_modify_port_tc_rate_limit(struct mlx5_core_dev *mdev,
857 const u8 *max_bw_value,
858 const u8 *max_bw_units)
860 u32 in[MLX5_ST_SZ_DW(qetc_reg)] = {};
864 MLX5_SET(qetc_reg, in, port_number, 1);
866 for (i = 0; i <= mlx5_max_tc(mdev); i++) {
867 ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, in, tc_configuration[i]);
869 MLX5_SET(ets_tcn_config_reg, ets_tcn_conf, r, 1);
870 MLX5_SET(ets_tcn_config_reg, ets_tcn_conf, max_bw_units,
872 MLX5_SET(ets_tcn_config_reg, ets_tcn_conf, max_bw_value,
876 return mlx5_set_port_qetcr_reg(mdev, in, sizeof(in));
878 EXPORT_SYMBOL_GPL(mlx5_modify_port_tc_rate_limit);
880 int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
883 u32 in[MLX5_ST_SZ_DW(qtct_reg)];
884 u32 out[MLX5_ST_SZ_DW(qtct_reg)];
887 memset(in, 0, sizeof(in));
888 memset(out, 0, sizeof(out));
890 MLX5_SET(qtct_reg, in, port_number, 1);
891 MLX5_SET(qtct_reg, in, prio, prio);
893 err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
894 sizeof(out), MLX5_REG_QTCT, 0, 0);
896 *tc = MLX5_GET(qtct_reg, out, tclass);
900 EXPORT_SYMBOL_GPL(mlx5_query_port_prio_tc);
902 int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, int prio_index,
905 u32 in[MLX5_ST_SZ_DW(qtct_reg)] = {};
906 u32 out[MLX5_ST_SZ_DW(qtct_reg)];
909 if (prio_tc > mlx5_max_tc(mdev))
912 MLX5_SET(qtct_reg, in, prio, prio_index);
913 MLX5_SET(qtct_reg, in, tclass, prio_tc);
915 err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
916 sizeof(out), MLX5_REG_QTCT, 0, 1);
920 EXPORT_SYMBOL_GPL(mlx5_set_port_prio_tc);
922 int mlx5_modify_port_cong_params(struct mlx5_core_dev *mdev,
923 void *in, int in_size)
925 u32 out[MLX5_ST_SZ_DW(modify_cong_params_out)] = {0};
927 MLX5_SET(modify_cong_params_in, in, opcode,
928 MLX5_CMD_OP_MODIFY_CONG_PARAMS);
930 return mlx5_cmd_exec(mdev, in, in_size, out, sizeof(out));
933 int mlx5_query_port_cong_statistics(struct mlx5_core_dev *mdev, int clear,
934 void *out, int out_size)
936 u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = {0};
938 MLX5_SET(query_cong_statistics_in, in, opcode,
939 MLX5_CMD_OP_QUERY_CONG_STATISTICS);
940 MLX5_SET(query_cong_statistics_in, in, clear, clear);
942 return mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size);
945 int mlx5_set_diagnostic_params(struct mlx5_core_dev *mdev, void *in,
948 u32 out[MLX5_ST_SZ_DW(set_diagnostic_params_out)] = {0};
950 MLX5_SET(set_diagnostic_params_in, in, opcode,
951 MLX5_CMD_OP_SET_DIAGNOSTICS);
953 return mlx5_cmd_exec(mdev, in, in_size, out, sizeof(out));
956 int mlx5_query_diagnostic_counters(struct mlx5_core_dev *mdev,
957 u8 num_of_samples, u16 sample_index,
958 void *out, int out_size)
960 u32 in[MLX5_ST_SZ_DW(query_diagnostic_counters_in)] = {0};
962 MLX5_SET(query_diagnostic_counters_in, in, opcode,
963 MLX5_CMD_OP_QUERY_DIAGNOSTICS);
964 MLX5_SET(query_diagnostic_counters_in, in, num_of_samples,
966 MLX5_SET(query_diagnostic_counters_in, in, sample_index, sample_index);
968 return mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size);