1 /*-
2 * Copyright (c) 2013-2018, 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
26 #include "opt_rss.h"
27 #include "opt_ratelimit.h"
28
29 #include <linux/module.h>
30 #include <dev/mlx5/port.h>
31 #include <dev/mlx5/mlx5_core/mlx5_core.h>
32
mlx5_core_access_reg(struct mlx5_core_dev * dev,void * data_in,int size_in,void * data_out,int size_out,u16 reg_num,int arg,int write)33 int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in,
34 int size_in, void *data_out, int size_out,
35 u16 reg_num, int arg, int write)
36 {
37 int outlen = MLX5_ST_SZ_BYTES(access_register_out) + size_out;
38 int inlen = MLX5_ST_SZ_BYTES(access_register_in) + size_in;
39 int err = -ENOMEM;
40 u32 *out = NULL;
41 u32 *in = NULL;
42 void *data;
43
44 in = mlx5_vzalloc(inlen);
45 out = mlx5_vzalloc(outlen);
46 if (!in || !out)
47 goto out;
48
49 data = MLX5_ADDR_OF(access_register_in, in, register_data);
50 memcpy(data, data_in, size_in);
51
52 MLX5_SET(access_register_in, in, opcode, MLX5_CMD_OP_ACCESS_REG);
53 MLX5_SET(access_register_in, in, op_mod, !write);
54 MLX5_SET(access_register_in, in, argument, arg);
55 MLX5_SET(access_register_in, in, register_id, reg_num);
56
57 err = mlx5_cmd_exec(dev, in, inlen, out, outlen);
58 if (err)
59 goto out;
60 data = MLX5_ADDR_OF(access_register_out, out, register_data);
61 memcpy(data_out, data, size_out);
62
63 out:
64 kvfree(out);
65 kvfree(in);
66 return err;
67 }
68 EXPORT_SYMBOL_GPL(mlx5_core_access_reg);
69
mlx5_query_qcam_reg(struct mlx5_core_dev * mdev,u32 * qcam,u8 feature_group,u8 access_reg_group)70 int mlx5_query_qcam_reg(struct mlx5_core_dev *mdev, u32 *qcam,
71 u8 feature_group, u8 access_reg_group)
72 {
73 u32 in[MLX5_ST_SZ_DW(qcam_reg)] = {};
74 int sz = MLX5_ST_SZ_BYTES(qcam_reg);
75
76 MLX5_SET(qcam_reg, in, feature_group, feature_group);
77 MLX5_SET(qcam_reg, in, access_reg_group, access_reg_group);
78
79 return mlx5_core_access_reg(mdev, in, sz, qcam, sz, MLX5_REG_QCAM, 0, 0);
80 }
81 EXPORT_SYMBOL_GPL(mlx5_query_qcam_reg);
82
mlx5_query_pcam_reg(struct mlx5_core_dev * dev,u32 * pcam,u8 feature_group,u8 access_reg_group)83 int mlx5_query_pcam_reg(struct mlx5_core_dev *dev, u32 *pcam, u8 feature_group,
84 u8 access_reg_group)
85 {
86 u32 in[MLX5_ST_SZ_DW(pcam_reg)] = {};
87 int sz = MLX5_ST_SZ_BYTES(pcam_reg);
88
89 MLX5_SET(pcam_reg, in, feature_group, feature_group);
90 MLX5_SET(pcam_reg, in, access_reg_group, access_reg_group);
91
92 return mlx5_core_access_reg(dev, in, sz, pcam, sz, MLX5_REG_PCAM, 0, 0);
93 }
94
mlx5_query_mcam_reg(struct mlx5_core_dev * dev,u32 * mcam,u8 feature_group,u8 access_reg_group)95 int mlx5_query_mcam_reg(struct mlx5_core_dev *dev, u32 *mcam, u8 feature_group,
96 u8 access_reg_group)
97 {
98 u32 in[MLX5_ST_SZ_DW(mcam_reg)] = {};
99 int sz = MLX5_ST_SZ_BYTES(mcam_reg);
100
101 MLX5_SET(mcam_reg, in, feature_group, feature_group);
102 MLX5_SET(mcam_reg, in, access_reg_group, access_reg_group);
103
104 return mlx5_core_access_reg(dev, in, sz, mcam, sz, MLX5_REG_MCAM, 0, 0);
105 }
106
107 struct mlx5_reg_pcap {
108 u8 rsvd0;
109 u8 port_num;
110 u8 rsvd1[2];
111 __be32 caps_127_96;
112 __be32 caps_95_64;
113 __be32 caps_63_32;
114 __be32 caps_31_0;
115 };
116
117 /* This function should be used after setting a port register only */
mlx5_toggle_port_link(struct mlx5_core_dev * dev)118 void mlx5_toggle_port_link(struct mlx5_core_dev *dev)
119 {
120 enum mlx5_port_status ps;
121
122 mlx5_query_port_admin_status(dev, &ps);
123 mlx5_set_port_status(dev, MLX5_PORT_DOWN);
124 if (ps == MLX5_PORT_UP)
125 mlx5_set_port_status(dev, MLX5_PORT_UP);
126 }
127 EXPORT_SYMBOL_GPL(mlx5_toggle_port_link);
128
mlx5_set_port_caps(struct mlx5_core_dev * dev,u8 port_num,u32 caps)129 int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps)
130 {
131 struct mlx5_reg_pcap in;
132 struct mlx5_reg_pcap out;
133 int err;
134
135 memset(&in, 0, sizeof(in));
136 in.caps_127_96 = cpu_to_be32(caps);
137 in.port_num = port_num;
138
139 err = mlx5_core_access_reg(dev, &in, sizeof(in), &out,
140 sizeof(out), MLX5_REG_PCAP, 0, 1);
141
142 return err;
143 }
144 EXPORT_SYMBOL_GPL(mlx5_set_port_caps);
145
mlx5_query_port_ptys(struct mlx5_core_dev * dev,u32 * ptys,int ptys_size,int proto_mask,u8 local_port)146 int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
147 int ptys_size, int proto_mask, u8 local_port)
148 {
149 u32 in[MLX5_ST_SZ_DW(ptys_reg)];
150 int err;
151
152 memset(in, 0, sizeof(in));
153 MLX5_SET(ptys_reg, in, local_port, local_port);
154 MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
155
156 err = mlx5_core_access_reg(dev, in, sizeof(in), ptys,
157 ptys_size, MLX5_REG_PTYS, 0, 0);
158
159 return err;
160 }
161 EXPORT_SYMBOL_GPL(mlx5_query_port_ptys);
162
mlx5_query_port_proto_cap(struct mlx5_core_dev * dev,u32 * proto_cap,int proto_mask)163 int mlx5_query_port_proto_cap(struct mlx5_core_dev *dev,
164 u32 *proto_cap, int proto_mask)
165 {
166 u32 out[MLX5_ST_SZ_DW(ptys_reg)];
167 int err;
168
169 err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask, 1);
170 if (err)
171 return err;
172
173 if (proto_mask == MLX5_PTYS_EN)
174 *proto_cap = MLX5_GET(ptys_reg, out, eth_proto_capability);
175 else
176 *proto_cap = MLX5_GET(ptys_reg, out, ib_proto_capability);
177
178 return 0;
179 }
180 EXPORT_SYMBOL_GPL(mlx5_query_port_proto_cap);
181
mlx5_query_port_autoneg(struct mlx5_core_dev * dev,int proto_mask,u8 * an_disable_cap,u8 * an_disable_status)182 int mlx5_query_port_autoneg(struct mlx5_core_dev *dev, int proto_mask,
183 u8 *an_disable_cap, u8 *an_disable_status)
184 {
185 u32 out[MLX5_ST_SZ_DW(ptys_reg)];
186 int err;
187
188 err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask, 1);
189 if (err)
190 return err;
191
192 *an_disable_status = MLX5_GET(ptys_reg, out, an_disable_admin);
193 *an_disable_cap = MLX5_GET(ptys_reg, out, an_disable_cap);
194
195 return 0;
196 }
197 EXPORT_SYMBOL_GPL(mlx5_query_port_autoneg);
198
mlx5_set_port_autoneg(struct mlx5_core_dev * dev,bool disable,u32 eth_proto_admin,int proto_mask)199 int mlx5_set_port_autoneg(struct mlx5_core_dev *dev, bool disable,
200 u32 eth_proto_admin, int proto_mask)
201 {
202 u32 in[MLX5_ST_SZ_DW(ptys_reg)] = {0};
203 u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0};
204 u8 an_disable_cap;
205 u8 an_disable_status;
206 int err;
207
208 err = mlx5_query_port_autoneg(dev, proto_mask, &an_disable_cap,
209 &an_disable_status);
210 if (err)
211 return err;
212 if (!an_disable_cap)
213 return -EPERM;
214
215 MLX5_SET(ptys_reg, in, local_port, 1);
216 MLX5_SET(ptys_reg, in, an_disable_admin, disable);
217 MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
218 if (proto_mask == MLX5_PTYS_EN)
219 MLX5_SET(ptys_reg, in, eth_proto_admin, eth_proto_admin);
220
221 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
222 sizeof(out), MLX5_REG_PTYS, 0, 1);
223 return err;
224 }
225 EXPORT_SYMBOL_GPL(mlx5_set_port_autoneg);
226
mlx5_query_port_proto_admin(struct mlx5_core_dev * dev,u32 * proto_admin,int proto_mask)227 int mlx5_query_port_proto_admin(struct mlx5_core_dev *dev,
228 u32 *proto_admin, int proto_mask)
229 {
230 u32 out[MLX5_ST_SZ_DW(ptys_reg)];
231 int err;
232
233 err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask, 1);
234 if (err)
235 return err;
236
237 if (proto_mask == MLX5_PTYS_EN)
238 *proto_admin = MLX5_GET(ptys_reg, out, eth_proto_admin);
239 else
240 *proto_admin = MLX5_GET(ptys_reg, out, ib_proto_admin);
241
242 return 0;
243 }
244 EXPORT_SYMBOL_GPL(mlx5_query_port_proto_admin);
245
mlx5_query_port_eth_proto_oper(struct mlx5_core_dev * dev,u32 * proto_oper,u8 local_port)246 int mlx5_query_port_eth_proto_oper(struct mlx5_core_dev *dev,
247 u32 *proto_oper, u8 local_port)
248 {
249 u32 out[MLX5_ST_SZ_DW(ptys_reg)];
250 int err;
251
252 err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN,
253 local_port);
254 if (err)
255 return err;
256
257 *proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
258
259 return 0;
260 }
261 EXPORT_SYMBOL(mlx5_query_port_eth_proto_oper);
262
mlx5_set_port_proto(struct mlx5_core_dev * dev,u32 proto_admin,int proto_mask,bool ext)263 int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
264 int proto_mask, bool ext)
265 {
266 u32 in[MLX5_ST_SZ_DW(ptys_reg)] = {0};
267 u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0};
268 int err;
269
270 MLX5_SET(ptys_reg, in, local_port, 1);
271 MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
272 if (proto_mask == MLX5_PTYS_EN) {
273 if (ext)
274 MLX5_SET(ptys_reg, in, ext_eth_proto_admin, proto_admin);
275 else
276 MLX5_SET(ptys_reg, in, eth_proto_admin, proto_admin);
277 } else {
278 MLX5_SET(ptys_reg, in, ib_proto_admin, proto_admin);
279 }
280
281 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
282 sizeof(out), MLX5_REG_PTYS, 0, 1);
283 return err;
284 }
285 EXPORT_SYMBOL_GPL(mlx5_set_port_proto);
286
mlx5_set_port_status(struct mlx5_core_dev * dev,enum mlx5_port_status status)287 int mlx5_set_port_status(struct mlx5_core_dev *dev,
288 enum mlx5_port_status status)
289 {
290 u32 in[MLX5_ST_SZ_DW(paos_reg)] = {0};
291 u32 out[MLX5_ST_SZ_DW(paos_reg)] = {0};
292 int err;
293
294 MLX5_SET(paos_reg, in, local_port, 1);
295
296 MLX5_SET(paos_reg, in, admin_status, status);
297 MLX5_SET(paos_reg, in, ase, 1);
298
299 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
300 sizeof(out), MLX5_REG_PAOS, 0, 1);
301 return err;
302 }
303
mlx5_query_port_status(struct mlx5_core_dev * dev,u8 * status)304 int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
305 {
306 u32 in[MLX5_ST_SZ_DW(paos_reg)] = {0};
307 u32 out[MLX5_ST_SZ_DW(paos_reg)] = {0};
308 int err;
309
310 MLX5_SET(paos_reg, in, local_port, 1);
311
312 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
313 sizeof(out), MLX5_REG_PAOS, 0, 0);
314 if (err)
315 return err;
316
317 *status = MLX5_GET(paos_reg, out, oper_status);
318 return err;
319 }
320
mlx5_query_port_admin_status(struct mlx5_core_dev * dev,enum mlx5_port_status * status)321 int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
322 enum mlx5_port_status *status)
323 {
324 u32 in[MLX5_ST_SZ_DW(paos_reg)] = {0};
325 u32 out[MLX5_ST_SZ_DW(paos_reg)];
326 int err;
327
328 MLX5_SET(paos_reg, in, local_port, 1);
329 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
330 sizeof(out), MLX5_REG_PAOS, 0, 0);
331 if (err)
332 return err;
333 *status = MLX5_GET(paos_reg, out, admin_status);
334 return 0;
335 }
336 EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status);
337
mlx5_query_port_mtu(struct mlx5_core_dev * dev,int * admin_mtu,int * max_mtu,int * oper_mtu)338 static int mlx5_query_port_mtu(struct mlx5_core_dev *dev,
339 int *admin_mtu, int *max_mtu, int *oper_mtu)
340 {
341 u32 in[MLX5_ST_SZ_DW(pmtu_reg)] = {0};
342 u32 out[MLX5_ST_SZ_DW(pmtu_reg)] = {0};
343 int err;
344
345 MLX5_SET(pmtu_reg, in, local_port, 1);
346
347 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
348 sizeof(out), MLX5_REG_PMTU, 0, 0);
349 if (err)
350 return err;
351
352 if (max_mtu)
353 *max_mtu = MLX5_GET(pmtu_reg, out, max_mtu);
354 if (oper_mtu)
355 *oper_mtu = MLX5_GET(pmtu_reg, out, oper_mtu);
356 if (admin_mtu)
357 *admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu);
358
359 return err;
360 }
361
mlx5_set_port_mtu(struct mlx5_core_dev * dev,int mtu)362 int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu)
363 {
364 u32 in[MLX5_ST_SZ_DW(pmtu_reg)] = {0};
365 u32 out[MLX5_ST_SZ_DW(pmtu_reg)] = {0};
366
367 MLX5_SET(pmtu_reg, in, admin_mtu, mtu);
368 MLX5_SET(pmtu_reg, in, local_port, 1);
369
370 return mlx5_core_access_reg(dev, in, sizeof(in), out,
371 sizeof(out), MLX5_REG_PMTU, 0, 1);
372 }
373 EXPORT_SYMBOL_GPL(mlx5_set_port_mtu);
374
mlx5_query_port_max_mtu(struct mlx5_core_dev * dev,int * max_mtu)375 int mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu)
376 {
377 return mlx5_query_port_mtu(dev, NULL, max_mtu, NULL);
378 }
379 EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu);
380
mlx5_set_port_pause_and_pfc(struct mlx5_core_dev * dev,u32 port,u8 rx_pause,u8 tx_pause,u8 pfc_en_rx,u8 pfc_en_tx)381 int mlx5_set_port_pause_and_pfc(struct mlx5_core_dev *dev, u32 port,
382 u8 rx_pause, u8 tx_pause,
383 u8 pfc_en_rx, u8 pfc_en_tx)
384 {
385 u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
386 u32 out[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
387
388 if (pfc_en_rx || pfc_en_tx) {
389 /* PFC and global pauseframes are incompatible features */
390 if (tx_pause || rx_pause)
391 return -EINVAL;
392 }
393
394 MLX5_SET(pfcc_reg, in, local_port, port);
395 MLX5_SET(pfcc_reg, in, pptx, tx_pause);
396 MLX5_SET(pfcc_reg, in, pprx, rx_pause);
397 MLX5_SET(pfcc_reg, in, pfctx, pfc_en_tx);
398 MLX5_SET(pfcc_reg, in, pfcrx, pfc_en_rx);
399 MLX5_SET(pfcc_reg, in, prio_mask_tx, pfc_en_tx);
400 MLX5_SET(pfcc_reg, in, prio_mask_rx, pfc_en_rx);
401
402 return mlx5_core_access_reg(dev, in, sizeof(in), out,
403 sizeof(out), MLX5_REG_PFCC, 0, 1);
404 }
405
mlx5_query_port_pause(struct mlx5_core_dev * dev,u32 port,u32 * rx_pause,u32 * tx_pause)406 int mlx5_query_port_pause(struct mlx5_core_dev *dev, u32 port,
407 u32 *rx_pause, u32 *tx_pause)
408 {
409 u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
410 u32 out[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
411 int err;
412
413 MLX5_SET(pfcc_reg, in, local_port, port);
414
415 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
416 sizeof(out), MLX5_REG_PFCC, 0, 0);
417 if (err)
418 return err;
419
420 *rx_pause = MLX5_GET(pfcc_reg, out, pprx);
421 *tx_pause = MLX5_GET(pfcc_reg, out, pptx);
422
423 return 0;
424 }
425
mlx5_query_port_pfc(struct mlx5_core_dev * dev,u8 * pfc_en_tx,u8 * pfc_en_rx)426 int mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx, u8 *pfc_en_rx)
427 {
428 u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {};
429 u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
430 int err;
431
432 MLX5_SET(pfcc_reg, in, local_port, 1);
433 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
434 sizeof(out), MLX5_REG_PFCC, 0, 0);
435 if (err)
436 return err;
437
438 if (pfc_en_tx != NULL)
439 *pfc_en_tx = MLX5_GET(pfcc_reg, out, pfctx);
440 if (pfc_en_rx != NULL)
441 *pfc_en_rx = MLX5_GET(pfcc_reg, out, pfcrx);
442 return 0;
443 }
444 EXPORT_SYMBOL_GPL(mlx5_query_port_pfc);
445
mlx5_query_port_oper_mtu(struct mlx5_core_dev * dev,int * oper_mtu)446 int mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu)
447 {
448 return mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu);
449 }
450 EXPORT_SYMBOL_GPL(mlx5_query_port_oper_mtu);
451
mlx5_is_wol_supported(struct mlx5_core_dev * dev)452 u8 mlx5_is_wol_supported(struct mlx5_core_dev *dev)
453 {
454 u8 wol_supported = 0;
455
456 if (MLX5_CAP_GEN(dev, wol_s))
457 wol_supported |= MLX5_WOL_SECURED_MAGIC;
458 if (MLX5_CAP_GEN(dev, wol_g))
459 wol_supported |= MLX5_WOL_MAGIC;
460 if (MLX5_CAP_GEN(dev, wol_a))
461 wol_supported |= MLX5_WOL_ARP;
462 if (MLX5_CAP_GEN(dev, wol_b))
463 wol_supported |= MLX5_WOL_BROADCAST;
464 if (MLX5_CAP_GEN(dev, wol_m))
465 wol_supported |= MLX5_WOL_MULTICAST;
466 if (MLX5_CAP_GEN(dev, wol_u))
467 wol_supported |= MLX5_WOL_UNICAST;
468 if (MLX5_CAP_GEN(dev, wol_p))
469 wol_supported |= MLX5_WOL_PHY_ACTIVITY;
470
471 return wol_supported;
472 }
473 EXPORT_SYMBOL_GPL(mlx5_is_wol_supported);
474
mlx5_set_wol(struct mlx5_core_dev * dev,u8 wol_mode)475 int mlx5_set_wol(struct mlx5_core_dev *dev, u8 wol_mode)
476 {
477 u32 in[MLX5_ST_SZ_DW(set_wol_rol_in)] = {0};
478 u32 out[MLX5_ST_SZ_DW(set_wol_rol_out)] = {0};
479
480 MLX5_SET(set_wol_rol_in, in, opcode, MLX5_CMD_OP_SET_WOL_ROL);
481 MLX5_SET(set_wol_rol_in, in, wol_mode_valid, 1);
482 MLX5_SET(set_wol_rol_in, in, wol_mode, wol_mode);
483
484 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
485 }
486 EXPORT_SYMBOL_GPL(mlx5_set_wol);
487
mlx5_query_dropless_mode(struct mlx5_core_dev * dev,u16 * timeout)488 int mlx5_query_dropless_mode(struct mlx5_core_dev *dev, u16 *timeout)
489 {
490 u32 in[MLX5_ST_SZ_DW(query_delay_drop_params_in)] = {0};
491 u32 out[MLX5_ST_SZ_DW(query_delay_drop_params_out)] = {0};
492 int err = 0;
493
494 MLX5_SET(query_delay_drop_params_in, in, opcode,
495 MLX5_CMD_OP_QUERY_DELAY_DROP_PARAMS);
496
497 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
498 if (err)
499 return err;
500
501 *timeout = MLX5_GET(query_delay_drop_params_out, out,
502 delay_drop_timeout);
503
504 return 0;
505 }
506 EXPORT_SYMBOL_GPL(mlx5_query_dropless_mode);
507
mlx5_set_dropless_mode(struct mlx5_core_dev * dev,u16 timeout)508 int mlx5_set_dropless_mode(struct mlx5_core_dev *dev, u16 timeout)
509 {
510 u32 in[MLX5_ST_SZ_DW(set_delay_drop_params_in)] = {0};
511 u32 out[MLX5_ST_SZ_DW(set_delay_drop_params_out)] = {0};
512
513 MLX5_SET(set_delay_drop_params_in, in, opcode,
514 MLX5_CMD_OP_SET_DELAY_DROP_PARAMS);
515 MLX5_SET(set_delay_drop_params_in, in, delay_drop_timeout, timeout);
516
517 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
518 }
519 EXPORT_SYMBOL_GPL(mlx5_set_dropless_mode);
520
mlx5_core_access_pvlc(struct mlx5_core_dev * dev,struct mlx5_pvlc_reg * pvlc,int write)521 int mlx5_core_access_pvlc(struct mlx5_core_dev *dev,
522 struct mlx5_pvlc_reg *pvlc, int write)
523 {
524 int sz = MLX5_ST_SZ_BYTES(pvlc_reg);
525 u8 in[MLX5_ST_SZ_BYTES(pvlc_reg)] = {0};
526 u8 out[MLX5_ST_SZ_BYTES(pvlc_reg)] = {0};
527 int err;
528
529 MLX5_SET(pvlc_reg, in, local_port, pvlc->local_port);
530 if (write)
531 MLX5_SET(pvlc_reg, in, vl_admin, pvlc->vl_admin);
532
533 err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PVLC, 0,
534 !!write);
535 if (err)
536 return err;
537
538 if (!write) {
539 pvlc->local_port = MLX5_GET(pvlc_reg, out, local_port);
540 pvlc->vl_hw_cap = MLX5_GET(pvlc_reg, out, vl_hw_cap);
541 pvlc->vl_admin = MLX5_GET(pvlc_reg, out, vl_admin);
542 pvlc->vl_operational = MLX5_GET(pvlc_reg, out, vl_operational);
543 }
544
545 return 0;
546 }
547 EXPORT_SYMBOL_GPL(mlx5_core_access_pvlc);
548
mlx5_core_access_ptys(struct mlx5_core_dev * dev,struct mlx5_ptys_reg * ptys,int write)549 int mlx5_core_access_ptys(struct mlx5_core_dev *dev,
550 struct mlx5_ptys_reg *ptys, int write)
551 {
552 int sz = MLX5_ST_SZ_BYTES(ptys_reg);
553 void *out = NULL;
554 void *in = NULL;
555 int err;
556
557 in = mlx5_vzalloc(sz);
558 if (!in)
559 return -ENOMEM;
560
561 out = mlx5_vzalloc(sz);
562 if (!out) {
563 kfree(in);
564 return -ENOMEM;
565 }
566
567 MLX5_SET(ptys_reg, in, local_port, ptys->local_port);
568 MLX5_SET(ptys_reg, in, proto_mask, ptys->proto_mask);
569 if (write) {
570 MLX5_SET(ptys_reg, in, eth_proto_capability,
571 ptys->eth_proto_cap);
572 MLX5_SET(ptys_reg, in, ib_link_width_capability,
573 ptys->ib_link_width_cap);
574 MLX5_SET(ptys_reg, in, ib_proto_capability,
575 ptys->ib_proto_cap);
576 MLX5_SET(ptys_reg, in, eth_proto_admin, ptys->eth_proto_admin);
577 MLX5_SET(ptys_reg, in, ib_link_width_admin,
578 ptys->ib_link_width_admin);
579 MLX5_SET(ptys_reg, in, ib_proto_admin, ptys->ib_proto_admin);
580 MLX5_SET(ptys_reg, in, eth_proto_oper, ptys->eth_proto_oper);
581 MLX5_SET(ptys_reg, in, ib_link_width_oper,
582 ptys->ib_link_width_oper);
583 MLX5_SET(ptys_reg, in, ib_proto_oper, ptys->ib_proto_oper);
584 MLX5_SET(ptys_reg, in, eth_proto_lp_advertise,
585 ptys->eth_proto_lp_advertise);
586 }
587
588 err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PTYS, 0,
589 !!write);
590 if (err)
591 goto out;
592
593 if (!write) {
594 ptys->local_port = MLX5_GET(ptys_reg, out, local_port);
595 ptys->proto_mask = MLX5_GET(ptys_reg, out, proto_mask);
596 ptys->eth_proto_cap = MLX5_GET(ptys_reg, out,
597 eth_proto_capability);
598 ptys->ib_link_width_cap = MLX5_GET(ptys_reg, out,
599 ib_link_width_capability);
600 ptys->ib_proto_cap = MLX5_GET(ptys_reg, out,
601 ib_proto_capability);
602 ptys->eth_proto_admin = MLX5_GET(ptys_reg, out,
603 eth_proto_admin);
604 ptys->ib_link_width_admin = MLX5_GET(ptys_reg, out,
605 ib_link_width_admin);
606 ptys->ib_proto_admin = MLX5_GET(ptys_reg, out, ib_proto_admin);
607 ptys->eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
608 ptys->ib_link_width_oper = MLX5_GET(ptys_reg, out,
609 ib_link_width_oper);
610 ptys->ib_proto_oper = MLX5_GET(ptys_reg, out, ib_proto_oper);
611 ptys->eth_proto_lp_advertise = MLX5_GET(ptys_reg, out,
612 eth_proto_lp_advertise);
613 }
614
615 out:
616 kvfree(in);
617 kvfree(out);
618 return err;
619 }
620 EXPORT_SYMBOL_GPL(mlx5_core_access_ptys);
621
mtu_to_ib_mtu(struct mlx5_core_dev * dev,int mtu)622 static int mtu_to_ib_mtu(struct mlx5_core_dev *dev, int mtu)
623 {
624 switch (mtu) {
625 case 256: return 1;
626 case 512: return 2;
627 case 1024: return 3;
628 case 2048: return 4;
629 case 4096: return 5;
630 default:
631 mlx5_core_warn(dev, "invalid mtu\n");
632 return -1;
633 }
634 }
635
mlx5_core_access_pmtu(struct mlx5_core_dev * dev,struct mlx5_pmtu_reg * pmtu,int write)636 int mlx5_core_access_pmtu(struct mlx5_core_dev *dev,
637 struct mlx5_pmtu_reg *pmtu, int write)
638 {
639 int sz = MLX5_ST_SZ_BYTES(pmtu_reg);
640 void *out = NULL;
641 void *in = NULL;
642 int err;
643
644 in = mlx5_vzalloc(sz);
645 if (!in)
646 return -ENOMEM;
647
648 out = mlx5_vzalloc(sz);
649 if (!out) {
650 kfree(in);
651 return -ENOMEM;
652 }
653
654 MLX5_SET(pmtu_reg, in, local_port, pmtu->local_port);
655 if (write)
656 MLX5_SET(pmtu_reg, in, admin_mtu, pmtu->admin_mtu);
657
658 err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PMTU, 0,
659 !!write);
660 if (err)
661 goto out;
662
663 if (!write) {
664 pmtu->local_port = MLX5_GET(pmtu_reg, out, local_port);
665 pmtu->max_mtu = mtu_to_ib_mtu(dev, MLX5_GET(pmtu_reg, out,
666 max_mtu));
667 pmtu->admin_mtu = mtu_to_ib_mtu(dev, MLX5_GET(pmtu_reg, out,
668 admin_mtu));
669 pmtu->oper_mtu = mtu_to_ib_mtu(dev, MLX5_GET(pmtu_reg, out,
670 oper_mtu));
671 }
672
673 out:
674 kvfree(in);
675 kvfree(out);
676 return err;
677 }
678 EXPORT_SYMBOL_GPL(mlx5_core_access_pmtu);
679
mlx5_query_module_num(struct mlx5_core_dev * dev,int * module_num)680 int mlx5_query_module_num(struct mlx5_core_dev *dev, int *module_num)
681 {
682 u32 in[MLX5_ST_SZ_DW(pmlp_reg)] = {0};
683 u32 out[MLX5_ST_SZ_DW(pmlp_reg)] = {0};
684 int lane = 0;
685 int err;
686
687 MLX5_SET(pmlp_reg, in, local_port, 1);
688
689 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
690 sizeof(out), MLX5_REG_PMLP, 0, 0);
691 if (err)
692 return err;
693
694 lane = MLX5_GET(pmlp_reg, out, lane0_module_mapping);
695 *module_num = lane & MLX5_EEPROM_IDENTIFIER_BYTE_MASK;
696
697 return 0;
698 }
699 EXPORT_SYMBOL_GPL(mlx5_query_module_num);
700
mlx5_query_eeprom(struct mlx5_core_dev * dev,int i2c_addr,int page_num,int device_addr,int size,int module_num,u32 * data,int * size_read)701 int mlx5_query_eeprom(struct mlx5_core_dev *dev,
702 int i2c_addr, int page_num, int device_addr,
703 int size, int module_num, u32 *data, int *size_read)
704 {
705 u32 in[MLX5_ST_SZ_DW(mcia_reg)] = {0};
706 u32 out[MLX5_ST_SZ_DW(mcia_reg)] = {0};
707 u32 *ptr = (u32 *)MLX5_ADDR_OF(mcia_reg, out, dword_0);
708 int status;
709 int err;
710
711 size = min_t(int, size, MLX5_EEPROM_MAX_BYTES);
712
713 MLX5_SET(mcia_reg, in, l, 0);
714 MLX5_SET(mcia_reg, in, module, module_num);
715 MLX5_SET(mcia_reg, in, i2c_device_address, i2c_addr);
716 MLX5_SET(mcia_reg, in, page_number, page_num);
717 MLX5_SET(mcia_reg, in, device_address, device_addr);
718 MLX5_SET(mcia_reg, in, size, size);
719
720 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
721 sizeof(out), MLX5_REG_MCIA, 0, 0);
722 if (err)
723 return err;
724
725 status = MLX5_GET(mcia_reg, out, status);
726 if (status)
727 return status;
728
729 memcpy(data, ptr, size);
730 *size_read = size;
731 return 0;
732 }
733 EXPORT_SYMBOL_GPL(mlx5_query_eeprom);
734
mlx5_vxlan_udp_port_add(struct mlx5_core_dev * dev,u16 port)735 int mlx5_vxlan_udp_port_add(struct mlx5_core_dev *dev, u16 port)
736 {
737 u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)] = {0};
738 u32 out[MLX5_ST_SZ_DW(add_vxlan_udp_dport_out)] = {0};
739 int err;
740
741 MLX5_SET(add_vxlan_udp_dport_in, in, opcode,
742 MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT);
743 MLX5_SET(add_vxlan_udp_dport_in, in, vxlan_udp_port, port);
744
745 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
746 if (err) {
747 mlx5_core_err(dev, "Failed %s, port %u, err - %d",
748 mlx5_command_str(MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT),
749 port, err);
750 }
751
752 return err;
753 }
754
mlx5_vxlan_udp_port_delete(struct mlx5_core_dev * dev,u16 port)755 int mlx5_vxlan_udp_port_delete(struct mlx5_core_dev *dev, u16 port)
756 {
757 u32 in[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_in)] = {0};
758 u32 out[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_out)] = {0};
759 int err;
760
761 MLX5_SET(delete_vxlan_udp_dport_in, in, opcode,
762 MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT);
763 MLX5_SET(delete_vxlan_udp_dport_in, in, vxlan_udp_port, port);
764
765 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
766 if (err) {
767 mlx5_core_err(dev, "Failed %s, port %u, err - %d",
768 mlx5_command_str(MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT),
769 port, err);
770 }
771
772 return err;
773 }
774
mlx5_query_wol(struct mlx5_core_dev * dev,u8 * wol_mode)775 int mlx5_query_wol(struct mlx5_core_dev *dev, u8 *wol_mode)
776 {
777 u32 in[MLX5_ST_SZ_DW(query_wol_rol_in)] = {0};
778 u32 out[MLX5_ST_SZ_DW(query_wol_rol_out)] = {0};
779 int err;
780
781 MLX5_SET(query_wol_rol_in, in, opcode, MLX5_CMD_OP_QUERY_WOL_ROL);
782
783 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
784
785 if (!err)
786 *wol_mode = MLX5_GET(query_wol_rol_out, out, wol_mode);
787
788 return err;
789 }
790 EXPORT_SYMBOL_GPL(mlx5_query_wol);
791
mlx5_query_port_cong_status(struct mlx5_core_dev * mdev,int protocol,int priority,int * is_enable)792 int mlx5_query_port_cong_status(struct mlx5_core_dev *mdev, int protocol,
793 int priority, int *is_enable)
794 {
795 u32 in[MLX5_ST_SZ_DW(query_cong_status_in)] = {0};
796 u32 out[MLX5_ST_SZ_DW(query_cong_status_out)] = {0};
797 int err;
798
799 *is_enable = 0;
800
801 MLX5_SET(query_cong_status_in, in, opcode,
802 MLX5_CMD_OP_QUERY_CONG_STATUS);
803 MLX5_SET(query_cong_status_in, in, cong_protocol, protocol);
804 MLX5_SET(query_cong_status_in, in, priority, priority);
805
806 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
807 if (!err)
808 *is_enable = MLX5_GET(query_cong_status_out, out, enable);
809 return err;
810 }
811
mlx5_modify_port_cong_status(struct mlx5_core_dev * mdev,int protocol,int priority,int enable)812 int mlx5_modify_port_cong_status(struct mlx5_core_dev *mdev, int protocol,
813 int priority, int enable)
814 {
815 u32 in[MLX5_ST_SZ_DW(modify_cong_status_in)] = {0};
816 u32 out[MLX5_ST_SZ_DW(modify_cong_status_out)] = {0};
817
818 MLX5_SET(modify_cong_status_in, in, opcode,
819 MLX5_CMD_OP_MODIFY_CONG_STATUS);
820 MLX5_SET(modify_cong_status_in, in, cong_protocol, protocol);
821 MLX5_SET(modify_cong_status_in, in, priority, priority);
822 MLX5_SET(modify_cong_status_in, in, enable, enable);
823
824 return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
825 }
826
mlx5_query_port_cong_params(struct mlx5_core_dev * mdev,int protocol,void * out,int out_size)827 int mlx5_query_port_cong_params(struct mlx5_core_dev *mdev, int protocol,
828 void *out, int out_size)
829 {
830 u32 in[MLX5_ST_SZ_DW(query_cong_params_in)] = {0};
831
832 MLX5_SET(query_cong_params_in, in, opcode,
833 MLX5_CMD_OP_QUERY_CONG_PARAMS);
834 MLX5_SET(query_cong_params_in, in, cong_protocol, protocol);
835
836 return mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size);
837 }
838
mlx5_query_port_qetcr_reg(struct mlx5_core_dev * mdev,u32 * out,int outlen)839 static int mlx5_query_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *out,
840 int outlen)
841 {
842 u32 in[MLX5_ST_SZ_DW(qetc_reg)];
843
844 if (!MLX5_CAP_GEN(mdev, ets))
845 return -ENOTSUPP;
846
847 memset(in, 0, sizeof(in));
848 return mlx5_core_access_reg(mdev, in, sizeof(in), out, outlen,
849 MLX5_REG_QETCR, 0, 0);
850 }
851
mlx5_max_tc(struct mlx5_core_dev * mdev)852 int mlx5_max_tc(struct mlx5_core_dev *mdev)
853 {
854 u8 num_tc = MLX5_CAP_GEN(mdev, max_tc) ? : 8;
855
856 return num_tc - 1;
857 }
858 EXPORT_SYMBOL_GPL(mlx5_max_tc);
859
mlx5_set_port_qetcr_reg(struct mlx5_core_dev * mdev,u32 * in,int inlen)860 static int mlx5_set_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *in,
861 int inlen)
862 {
863 u32 out[MLX5_ST_SZ_DW(qetc_reg)];
864
865 if (!MLX5_CAP_GEN(mdev, ets))
866 return -ENOTSUPP;
867
868 return mlx5_core_access_reg(mdev, in, inlen, out, sizeof(out),
869 MLX5_REG_QETCR, 0, 1);
870 }
871
mlx5_query_port_tc_rate_limit(struct mlx5_core_dev * mdev,u8 * max_bw_value,u8 * max_bw_units)872 int mlx5_query_port_tc_rate_limit(struct mlx5_core_dev *mdev,
873 u8 *max_bw_value,
874 u8 *max_bw_units)
875 {
876 u32 out[MLX5_ST_SZ_DW(qetc_reg)];
877 void *ets_tcn_conf;
878 int err;
879 int i;
880
881 err = mlx5_query_port_qetcr_reg(mdev, out, sizeof(out));
882 if (err)
883 return err;
884
885 for (i = 0; i <= mlx5_max_tc(mdev); i++) {
886 ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, out, tc_configuration[i]);
887
888 max_bw_value[i] = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf,
889 max_bw_value);
890 max_bw_units[i] = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf,
891 max_bw_units);
892 }
893
894 return 0;
895 }
896 EXPORT_SYMBOL_GPL(mlx5_query_port_tc_rate_limit);
897
mlx5_modify_port_tc_rate_limit(struct mlx5_core_dev * mdev,const u8 * max_bw_value,const u8 * max_bw_units)898 int mlx5_modify_port_tc_rate_limit(struct mlx5_core_dev *mdev,
899 const u8 *max_bw_value,
900 const u8 *max_bw_units)
901 {
902 u32 in[MLX5_ST_SZ_DW(qetc_reg)] = {};
903 void *ets_tcn_conf;
904 int i;
905
906 MLX5_SET(qetc_reg, in, port_number, 1);
907
908 for (i = 0; i <= mlx5_max_tc(mdev); i++) {
909 ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, in, tc_configuration[i]);
910
911 MLX5_SET(ets_tcn_config_reg, ets_tcn_conf, r, 1);
912 MLX5_SET(ets_tcn_config_reg, ets_tcn_conf, max_bw_units,
913 max_bw_units[i]);
914 MLX5_SET(ets_tcn_config_reg, ets_tcn_conf, max_bw_value,
915 max_bw_value[i]);
916 }
917
918 return mlx5_set_port_qetcr_reg(mdev, in, sizeof(in));
919 }
920 EXPORT_SYMBOL_GPL(mlx5_modify_port_tc_rate_limit);
921
mlx5_query_port_prio_tc(struct mlx5_core_dev * mdev,u8 prio,u8 * tc)922 int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
923 u8 prio, u8 *tc)
924 {
925 u32 in[MLX5_ST_SZ_DW(qtct_reg)];
926 u32 out[MLX5_ST_SZ_DW(qtct_reg)];
927 int err;
928
929 memset(in, 0, sizeof(in));
930 memset(out, 0, sizeof(out));
931
932 MLX5_SET(qtct_reg, in, port_number, 1);
933 MLX5_SET(qtct_reg, in, prio, prio);
934
935 err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
936 sizeof(out), MLX5_REG_QTCT, 0, 0);
937 if (!err)
938 *tc = MLX5_GET(qtct_reg, out, tclass);
939
940 return err;
941 }
942 EXPORT_SYMBOL_GPL(mlx5_query_port_prio_tc);
943
mlx5_set_port_prio_tc(struct mlx5_core_dev * mdev,int prio_index,const u8 prio_tc)944 int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, int prio_index,
945 const u8 prio_tc)
946 {
947 u32 in[MLX5_ST_SZ_DW(qtct_reg)] = {};
948 u32 out[MLX5_ST_SZ_DW(qtct_reg)];
949 int err;
950
951 if (prio_tc > mlx5_max_tc(mdev))
952 return -EINVAL;
953
954 MLX5_SET(qtct_reg, in, prio, prio_index);
955 MLX5_SET(qtct_reg, in, tclass, prio_tc);
956
957 err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
958 sizeof(out), MLX5_REG_QTCT, 0, 1);
959
960 return (err);
961 }
962 EXPORT_SYMBOL_GPL(mlx5_set_port_prio_tc);
963
mlx5_set_port_tc_group(struct mlx5_core_dev * mdev,const u8 * tc_group)964 int mlx5_set_port_tc_group(struct mlx5_core_dev *mdev, const u8 *tc_group)
965 {
966 u32 in[MLX5_ST_SZ_DW(qetc_reg)] = {};
967 int i;
968
969 for (i = 0; i <= mlx5_max_tc(mdev); i++) {
970 MLX5_SET(qetc_reg, in, tc_configuration[i].g, 1);
971 MLX5_SET(qetc_reg, in, tc_configuration[i].group, tc_group[i]);
972 }
973
974 return mlx5_set_port_qetcr_reg(mdev, in, sizeof(in));
975 }
976 EXPORT_SYMBOL_GPL(mlx5_set_port_tc_group);
977
mlx5_query_port_tc_group(struct mlx5_core_dev * mdev,u8 tc,u8 * tc_group)978 int mlx5_query_port_tc_group(struct mlx5_core_dev *mdev,
979 u8 tc, u8 *tc_group)
980 {
981 u32 out[MLX5_ST_SZ_DW(qetc_reg)];
982 void *ets_tcn_conf;
983 int err;
984
985 err = mlx5_query_port_qetcr_reg(mdev, out, sizeof(out));
986 if (err)
987 return err;
988
989 ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, out,
990 tc_configuration[tc]);
991
992 *tc_group = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf,
993 group);
994
995 return 0;
996 }
997 EXPORT_SYMBOL_GPL(mlx5_query_port_tc_group);
998
mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev * mdev,const u8 * tc_bw)999 int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, const u8 *tc_bw)
1000 {
1001 u32 in[MLX5_ST_SZ_DW(qetc_reg)] = {};
1002 int i;
1003
1004 for (i = 0; i <= mlx5_max_tc(mdev); i++) {
1005 MLX5_SET(qetc_reg, in, tc_configuration[i].b, 1);
1006 MLX5_SET(qetc_reg, in, tc_configuration[i].bw_allocation, tc_bw[i]);
1007 }
1008
1009 return mlx5_set_port_qetcr_reg(mdev, in, sizeof(in));
1010 }
1011 EXPORT_SYMBOL_GPL(mlx5_set_port_tc_bw_alloc);
1012
mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev * mdev,u8 * bw_pct)1013 int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *bw_pct)
1014 {
1015 u32 out[MLX5_ST_SZ_DW(qetc_reg)];
1016 void *ets_tcn_conf;
1017 int err;
1018 int i;
1019
1020 err = mlx5_query_port_qetcr_reg(mdev, out, sizeof(out));
1021 if (err)
1022 return err;
1023
1024 for (i = 0; i <= mlx5_max_tc(mdev); i++) {
1025 ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, out, tc_configuration[i]);
1026 bw_pct[i] = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf, bw_allocation);
1027 }
1028 return 0;
1029 }
1030 EXPORT_SYMBOL_GPL(mlx5_query_port_tc_bw_alloc);
1031
mlx5_modify_port_cong_params(struct mlx5_core_dev * mdev,void * in,int in_size)1032 int mlx5_modify_port_cong_params(struct mlx5_core_dev *mdev,
1033 void *in, int in_size)
1034 {
1035 u32 out[MLX5_ST_SZ_DW(modify_cong_params_out)] = {0};
1036
1037 MLX5_SET(modify_cong_params_in, in, opcode,
1038 MLX5_CMD_OP_MODIFY_CONG_PARAMS);
1039
1040 return mlx5_cmd_exec(mdev, in, in_size, out, sizeof(out));
1041 }
1042
mlx5_query_port_cong_statistics(struct mlx5_core_dev * mdev,int clear,void * out,int out_size)1043 int mlx5_query_port_cong_statistics(struct mlx5_core_dev *mdev, int clear,
1044 void *out, int out_size)
1045 {
1046 u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = {0};
1047
1048 MLX5_SET(query_cong_statistics_in, in, opcode,
1049 MLX5_CMD_OP_QUERY_CONG_STATISTICS);
1050 MLX5_SET(query_cong_statistics_in, in, clear, clear);
1051
1052 return mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size);
1053 }
1054
mlx5_set_diagnostic_params(struct mlx5_core_dev * mdev,void * in,int in_size)1055 int mlx5_set_diagnostic_params(struct mlx5_core_dev *mdev, void *in,
1056 int in_size)
1057 {
1058 u32 out[MLX5_ST_SZ_DW(set_diagnostic_params_out)] = {0};
1059
1060 MLX5_SET(set_diagnostic_params_in, in, opcode,
1061 MLX5_CMD_OP_SET_DIAGNOSTICS);
1062
1063 return mlx5_cmd_exec(mdev, in, in_size, out, sizeof(out));
1064 }
1065
mlx5_query_diagnostic_counters(struct mlx5_core_dev * mdev,u8 num_of_samples,u16 sample_index,void * out,int out_size)1066 int mlx5_query_diagnostic_counters(struct mlx5_core_dev *mdev,
1067 u8 num_of_samples, u16 sample_index,
1068 void *out, int out_size)
1069 {
1070 u32 in[MLX5_ST_SZ_DW(query_diagnostic_counters_in)] = {0};
1071
1072 MLX5_SET(query_diagnostic_counters_in, in, opcode,
1073 MLX5_CMD_OP_QUERY_DIAGNOSTICS);
1074 MLX5_SET(query_diagnostic_counters_in, in, num_of_samples,
1075 num_of_samples);
1076 MLX5_SET(query_diagnostic_counters_in, in, sample_index, sample_index);
1077
1078 return mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size);
1079 }
1080
mlx5_set_trust_state(struct mlx5_core_dev * mdev,u8 trust_state)1081 int mlx5_set_trust_state(struct mlx5_core_dev *mdev, u8 trust_state)
1082 {
1083 u32 out[MLX5_ST_SZ_DW(qpts_reg)] = {};
1084 u32 in[MLX5_ST_SZ_DW(qpts_reg)] = {};
1085 int err;
1086
1087 MLX5_SET(qpts_reg, in, local_port, 1);
1088 MLX5_SET(qpts_reg, in, trust_state, trust_state);
1089
1090 err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
1091 sizeof(out), MLX5_REG_QPTS, 0, 1);
1092 return err;
1093 }
1094
mlx5_query_trust_state(struct mlx5_core_dev * mdev,u8 * trust_state)1095 int mlx5_query_trust_state(struct mlx5_core_dev *mdev, u8 *trust_state)
1096 {
1097 u32 out[MLX5_ST_SZ_DW(qpts_reg)] = {};
1098 u32 in[MLX5_ST_SZ_DW(qpts_reg)] = {};
1099 int err;
1100
1101 MLX5_SET(qpts_reg, in, local_port, 1);
1102
1103 err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
1104 sizeof(out), MLX5_REG_QPTS, 0, 0);
1105 if (!err)
1106 *trust_state = MLX5_GET(qpts_reg, out, trust_state);
1107
1108 return err;
1109 }
1110
mlx5_set_dscp2prio(struct mlx5_core_dev * mdev,const u8 * dscp2prio)1111 int mlx5_set_dscp2prio(struct mlx5_core_dev *mdev, const u8 *dscp2prio)
1112 {
1113 int sz = MLX5_ST_SZ_BYTES(qpdpm_reg);
1114 void *qpdpm_dscp;
1115 void *out;
1116 void *in;
1117 int err;
1118 int i;
1119
1120 in = kzalloc(sz, GFP_KERNEL);
1121 out = kzalloc(sz, GFP_KERNEL);
1122 if (!in || !out) {
1123 err = -ENOMEM;
1124 goto out;
1125 }
1126
1127 MLX5_SET(qpdpm_reg, in, local_port, 1);
1128 err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_QPDPM, 0, 0);
1129 if (err)
1130 goto out;
1131
1132 memcpy(in, out, sz);
1133 MLX5_SET(qpdpm_reg, in, local_port, 1);
1134
1135 /* Update the corresponding dscp entry */
1136 for (i = 0; i < MLX5_MAX_SUPPORTED_DSCP; i++) {
1137 qpdpm_dscp = MLX5_ADDR_OF(qpdpm_reg, in, dscp[i]);
1138 MLX5_SET16(qpdpm_dscp_reg, qpdpm_dscp, prio, dscp2prio[i]);
1139 MLX5_SET16(qpdpm_dscp_reg, qpdpm_dscp, e, 1);
1140 }
1141 err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_QPDPM, 0, 1);
1142 out:
1143 kfree(in);
1144 kfree(out);
1145 return err;
1146 }
1147
mlx5_query_dscp2prio(struct mlx5_core_dev * mdev,u8 * dscp2prio)1148 int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio)
1149 {
1150 int sz = MLX5_ST_SZ_BYTES(qpdpm_reg);
1151 void *qpdpm_dscp;
1152 void *out;
1153 void *in;
1154 int err;
1155 int i;
1156
1157 in = kzalloc(sz, GFP_KERNEL);
1158 out = kzalloc(sz, GFP_KERNEL);
1159 if (!in || !out) {
1160 err = -ENOMEM;
1161 goto out;
1162 }
1163
1164 MLX5_SET(qpdpm_reg, in, local_port, 1);
1165 err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_QPDPM, 0, 0);
1166 if (err)
1167 goto out;
1168
1169 for (i = 0; i < MLX5_MAX_SUPPORTED_DSCP; i++) {
1170 qpdpm_dscp = MLX5_ADDR_OF(qpdpm_reg, out, dscp[i]);
1171 dscp2prio[i] = MLX5_GET16(qpdpm_dscp_reg, qpdpm_dscp, prio);
1172 }
1173 out:
1174 kfree(in);
1175 kfree(out);
1176 return err;
1177 }
1178
mlx5_query_pddr(struct mlx5_core_dev * mdev,u8 local_port,int page_select,u32 * out,int outlen)1179 static int mlx5_query_pddr(struct mlx5_core_dev *mdev,
1180 u8 local_port, int page_select, u32 *out, int outlen)
1181 {
1182 u32 in[MLX5_ST_SZ_DW(pddr_reg)] = {0};
1183
1184 if (!MLX5_CAP_PCAM_REG(mdev, pddr))
1185 return -EOPNOTSUPP;
1186
1187 MLX5_SET(pddr_reg, in, local_port, local_port);
1188 MLX5_SET(pddr_reg, in, page_select, page_select);
1189
1190 return mlx5_core_access_reg(mdev, in, sizeof(in), out, outlen, MLX5_REG_PDDR, 0, 0);
1191 }
1192
mlx5_query_pddr_range_info(struct mlx5_core_dev * mdev,u8 local_port,u8 * is_er_type)1193 int mlx5_query_pddr_range_info(struct mlx5_core_dev *mdev, u8 local_port, u8 *is_er_type)
1194 {
1195 u32 pddr_reg[MLX5_ST_SZ_DW(pddr_reg)] = {};
1196 int error;
1197 u8 ecc;
1198 u8 ci;
1199
1200 error = mlx5_query_pddr(mdev, local_port, MLX5_PDDR_MODULE_INFO_PAGE,
1201 pddr_reg, sizeof(pddr_reg));
1202 if (error != 0)
1203 return (error);
1204
1205 ecc = MLX5_GET(pddr_reg, pddr_reg, page_data.pddr_module_info.ethernet_compliance_code);
1206 ci = MLX5_GET(pddr_reg, pddr_reg, page_data.pddr_module_info.cable_identifier);
1207
1208 switch (ci) {
1209 case 0: /* QSFP28 */
1210 case 1: /* QSFP+ */
1211 *is_er_type = 0;
1212 break;
1213 case 2: /* SFP28/SFP+ */
1214 case 3: /* QSA (QSFP->SFP) */
1215 *is_er_type = ((ecc & (1 << 7)) != 0);
1216 break;
1217 default:
1218 *is_er_type = 0;
1219 break;
1220 }
1221 return (0);
1222 }
1223 EXPORT_SYMBOL_GPL(mlx5_query_pddr_range_info);
1224
mlx5_query_pddr_cable_type(struct mlx5_core_dev * mdev,u8 local_port,u8 * cable_type)1225 int mlx5_query_pddr_cable_type(struct mlx5_core_dev *mdev, u8 local_port, u8 *cable_type)
1226 {
1227 u32 pddr_reg[MLX5_ST_SZ_DW(pddr_reg)] = {};
1228 int error;
1229
1230 error = mlx5_query_pddr(mdev, local_port, MLX5_PDDR_MODULE_INFO_PAGE,
1231 pddr_reg, sizeof(pddr_reg));
1232 if (error != 0)
1233 return (error);
1234
1235 *cable_type = MLX5_GET(pddr_reg, pddr_reg, page_data.pddr_module_info.cable_type);
1236 return (0);
1237 }
1238 EXPORT_SYMBOL_GPL(mlx5_query_pddr_cable_type);
1239
mlx5_query_pddr_troubleshooting_info(struct mlx5_core_dev * mdev,u16 * monitor_opcode,u8 * status_message,size_t sm_len)1240 int mlx5_query_pddr_troubleshooting_info(struct mlx5_core_dev *mdev,
1241 u16 *monitor_opcode, u8 *status_message, size_t sm_len)
1242 {
1243 int outlen = MLX5_ST_SZ_BYTES(pddr_reg);
1244 u32 out[MLX5_ST_SZ_DW(pddr_reg)] = {0};
1245 int err;
1246
1247 err = mlx5_query_pddr(mdev, MLX5_PDDR_TROUBLESHOOTING_INFO_PAGE, 1,
1248 out, outlen);
1249 if (err != 0)
1250 return err;
1251 if (monitor_opcode != NULL) {
1252 *monitor_opcode = MLX5_GET(pddr_reg, out,
1253 page_data.troubleshooting_info_page.status_opcode.
1254 monitor_opcodes);
1255 }
1256 if (status_message != NULL) {
1257 strlcpy(status_message,
1258 MLX5_ADDR_OF(pddr_reg, out,
1259 page_data.troubleshooting_info_page.status_message),
1260 sm_len);
1261 }
1262 return (0);
1263 }
1264
1265 int
mlx5_query_mfrl_reg(struct mlx5_core_dev * mdev,u8 * reset_level)1266 mlx5_query_mfrl_reg(struct mlx5_core_dev *mdev, u8 *reset_level)
1267 {
1268 u32 mfrl[MLX5_ST_SZ_DW(mfrl_reg)] = {};
1269 int sz = MLX5_ST_SZ_BYTES(mfrl_reg);
1270 int err;
1271
1272 err = mlx5_core_access_reg(mdev, mfrl, sz, mfrl, sz, MLX5_REG_MFRL,
1273 0, 0);
1274 if (err == 0)
1275 *reset_level = MLX5_GET(mfrl_reg, mfrl, reset_level);
1276 return (err);
1277 }
1278
1279 int
mlx5_set_mfrl_reg(struct mlx5_core_dev * mdev,u8 reset_level)1280 mlx5_set_mfrl_reg(struct mlx5_core_dev *mdev, u8 reset_level)
1281 {
1282 u32 mfrl[MLX5_ST_SZ_DW(mfrl_reg)] = {};
1283 int sz = MLX5_ST_SZ_BYTES(mfrl_reg);
1284
1285 MLX5_SET(mfrl_reg, mfrl, reset_level, reset_level);
1286
1287 return (mlx5_core_access_reg(mdev, mfrl, sz, mfrl, sz, MLX5_REG_MFRL,
1288 0, 1));
1289 }
1290
1291 /* speed in units of 1Mb */
1292 static const u32 mlx5e_link_speed[/*MLX5E_LINK_MODES_NUMBER*/] = {
1293 [MLX5E_1000BASE_CX_SGMII] = 1000,
1294 [MLX5E_1000BASE_KX] = 1000,
1295 [MLX5E_10GBASE_CX4] = 10000,
1296 [MLX5E_10GBASE_KX4] = 10000,
1297 [MLX5E_10GBASE_KR] = 10000,
1298 [MLX5E_20GBASE_KR2] = 20000,
1299 [MLX5E_40GBASE_CR4] = 40000,
1300 [MLX5E_40GBASE_KR4] = 40000,
1301 [MLX5E_56GBASE_R4] = 56000,
1302 [MLX5E_10GBASE_CR] = 10000,
1303 [MLX5E_10GBASE_SR] = 10000,
1304 [MLX5E_10GBASE_ER_LR] = 10000,
1305 [MLX5E_40GBASE_SR4] = 40000,
1306 [MLX5E_40GBASE_LR4_ER4] = 40000,
1307 [MLX5E_50GBASE_SR2] = 50000,
1308 [MLX5E_100GBASE_CR4] = 100000,
1309 [MLX5E_100GBASE_SR4] = 100000,
1310 [MLX5E_100GBASE_KR4] = 100000,
1311 [MLX5E_100GBASE_LR4] = 100000,
1312 [MLX5E_100BASE_TX] = 100,
1313 [MLX5E_1000BASE_T] = 1000,
1314 [MLX5E_10GBASE_T] = 10000,
1315 [MLX5E_25GBASE_CR] = 25000,
1316 [MLX5E_25GBASE_KR] = 25000,
1317 [MLX5E_25GBASE_SR] = 25000,
1318 [MLX5E_50GBASE_CR2] = 50000,
1319 [MLX5E_50GBASE_KR2] = 50000,
1320 };
1321
1322 static const u32 mlx5e_ext_link_speed[/*MLX5E_EXT_LINK_MODES_NUMBER*/] = {
1323 [MLX5E_SGMII_100M] = 100,
1324 [MLX5E_1000BASE_X_SGMII] = 1000,
1325 [MLX5E_5GBASE_R] = 5000,
1326 [MLX5E_10GBASE_XFI_XAUI_1] = 10000,
1327 [MLX5E_40GBASE_XLAUI_4_XLPPI_4] = 40000,
1328 [MLX5E_25GAUI_1_25GBASE_CR_KR] = 25000,
1329 [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = 50000,
1330 [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = 50000,
1331 [MLX5E_CAUI_4_100GBASE_CR4_KR4] = 100000,
1332 [MLX5E_200GAUI_4_200GBASE_CR4_KR4] = 200000,
1333 [MLX5E_400GAUI_8] = 400000,
1334 };
1335
mlx5e_port_get_speed_arr(struct mlx5_core_dev * mdev,const u32 ** arr,u32 * size)1336 static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev,
1337 const u32 **arr, u32 *size)
1338 {
1339 bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
1340
1341 *size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) :
1342 ARRAY_SIZE(mlx5e_link_speed);
1343 *arr = ext ? mlx5e_ext_link_speed : mlx5e_link_speed;
1344 }
1345
mlx5e_port_ptys2speed(struct mlx5_core_dev * mdev,u32 eth_proto_oper)1346 u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper)
1347 {
1348 unsigned long temp = eth_proto_oper;
1349 const u32 *table;
1350 u32 speed = 0;
1351 u32 max_size;
1352 int i;
1353
1354 mlx5e_port_get_speed_arr(mdev, &table, &max_size);
1355 i = find_first_bit(&temp, max_size);
1356 if (i < max_size)
1357 speed = table[i];
1358 return speed;
1359 }
1360
mlx5_port_query_eth_proto(struct mlx5_core_dev * dev,u8 port,bool ext,struct mlx5e_port_eth_proto * eproto)1361 int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
1362 struct mlx5e_port_eth_proto *eproto)
1363 {
1364 u32 out[MLX5_ST_SZ_DW(ptys_reg)];
1365 int err;
1366
1367 if (!eproto)
1368 return -EINVAL;
1369
1370 err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, port);
1371 if (err)
1372 return err;
1373
1374 eproto->cap = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
1375 eth_proto_capability);
1376 eproto->admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_admin);
1377 eproto->oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_oper);
1378 return 0;
1379 }
1380
mlx5e_port_linkspeed(struct mlx5_core_dev * mdev,u32 * speed)1381 int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
1382 {
1383 struct mlx5e_port_eth_proto eproto;
1384 bool ext;
1385 int err;
1386
1387 ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
1388 err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
1389 if (err)
1390 goto out;
1391
1392 *speed = mlx5e_port_ptys2speed(mdev, eproto.oper);
1393 if (!(*speed))
1394 err = -EINVAL;
1395
1396 out:
1397 return err;
1398 }
1399
mlx5e_port_query_pbmc(struct mlx5_core_dev * mdev,void * out)1400 int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out)
1401 {
1402 int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
1403 void *in;
1404 int err;
1405
1406 in = kzalloc(sz, GFP_KERNEL);
1407 if (!in)
1408 return -ENOMEM;
1409
1410 MLX5_SET(pbmc_reg, in, local_port, 1);
1411 err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PBMC, 0, 0);
1412
1413 kfree(in);
1414 return err;
1415 }
1416
mlx5e_port_set_pbmc(struct mlx5_core_dev * mdev,void * in)1417 int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in)
1418 {
1419 int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
1420 void *out;
1421 int err;
1422
1423 out = kzalloc(sz, GFP_KERNEL);
1424 if (!out)
1425 return -ENOMEM;
1426
1427 MLX5_SET(pbmc_reg, in, local_port, 1);
1428 err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PBMC, 0, 1);
1429
1430 kfree(out);
1431 return err;
1432 }
1433
1434 /* buffer[i]: buffer that priority i mapped to */
mlx5e_port_query_priority2buffer(struct mlx5_core_dev * mdev,u8 * buffer)1435 int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
1436 {
1437 int sz = MLX5_ST_SZ_BYTES(pptb_reg);
1438 u32 prio_x_buff;
1439 void *out;
1440 void *in;
1441 int prio;
1442 int err;
1443
1444 in = kzalloc(sz, GFP_KERNEL);
1445 out = kzalloc(sz, GFP_KERNEL);
1446 if (!in || !out) {
1447 err = -ENOMEM;
1448 goto out;
1449 }
1450
1451 MLX5_SET(pptb_reg, in, local_port, 1);
1452 err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 0);
1453 if (err)
1454 goto out;
1455
1456 prio_x_buff = MLX5_GET(pptb_reg, out, prio_x_buff);
1457 for (prio = 0; prio < 8; prio++) {
1458 buffer[prio] = (u8)(prio_x_buff >> (4 * prio)) & 0xF;
1459 mlx5_core_dbg(mdev, "prio %d, buffer %d\n", prio, buffer[prio]);
1460 }
1461 out:
1462 kfree(in);
1463 kfree(out);
1464 return err;
1465 }
1466
mlx5e_port_set_priority2buffer(struct mlx5_core_dev * mdev,u8 * buffer)1467 int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
1468 {
1469 int sz = MLX5_ST_SZ_BYTES(pptb_reg);
1470 u32 prio_x_buff;
1471 void *out;
1472 void *in;
1473 int prio;
1474 int err;
1475
1476 in = kzalloc(sz, GFP_KERNEL);
1477 out = kzalloc(sz, GFP_KERNEL);
1478 if (!in || !out) {
1479 err = -ENOMEM;
1480 goto out;
1481 }
1482
1483 /* First query the pptb register */
1484 MLX5_SET(pptb_reg, in, local_port, 1);
1485 err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 0);
1486 if (err)
1487 goto out;
1488
1489 memcpy(in, out, sz);
1490 MLX5_SET(pptb_reg, in, local_port, 1);
1491
1492 /* Update the pm and prio_x_buff */
1493 MLX5_SET(pptb_reg, in, pm, 0xFF);
1494
1495 prio_x_buff = 0;
1496 for (prio = 0; prio < 8; prio++)
1497 prio_x_buff |= (buffer[prio] << (4 * prio));
1498 MLX5_SET(pptb_reg, in, prio_x_buff, prio_x_buff);
1499
1500 err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 1);
1501
1502 out:
1503 kfree(in);
1504 kfree(out);
1505 return err;
1506 }
1507