1 /*-
2 * Copyright (c) 2013-2017, 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$
26 */
27
28 #include <linux/etherdevice.h>
29 #include <dev/mlx5/driver.h>
30 #include <dev/mlx5/vport.h>
31 #include "mlx5_core.h"
32
33 static int mlx5_modify_nic_vport_context(struct mlx5_core_dev *mdev, void *in,
34 int inlen);
35
_mlx5_query_vport_state(struct mlx5_core_dev * mdev,u8 opmod,u16 vport,u32 * out,int outlen)36 static int _mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod,
37 u16 vport, u32 *out, int outlen)
38 {
39 int err;
40 u32 in[MLX5_ST_SZ_DW(query_vport_state_in)] = {0};
41
42 MLX5_SET(query_vport_state_in, in, opcode,
43 MLX5_CMD_OP_QUERY_VPORT_STATE);
44 MLX5_SET(query_vport_state_in, in, op_mod, opmod);
45 MLX5_SET(query_vport_state_in, in, vport_number, vport);
46 if (vport)
47 MLX5_SET(query_vport_state_in, in, other_vport, 1);
48
49 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
50 if (err)
51 mlx5_core_warn(mdev, "MLX5_CMD_OP_QUERY_VPORT_STATE failed\n");
52
53 return err;
54 }
55
mlx5_query_vport_state(struct mlx5_core_dev * mdev,u8 opmod,u16 vport)56 u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport)
57 {
58 u32 out[MLX5_ST_SZ_DW(query_vport_state_out)] = {0};
59
60 _mlx5_query_vport_state(mdev, opmod, vport, out, sizeof(out));
61
62 return MLX5_GET(query_vport_state_out, out, state);
63 }
64 EXPORT_SYMBOL_GPL(mlx5_query_vport_state);
65
mlx5_query_vport_admin_state(struct mlx5_core_dev * mdev,u8 opmod,u16 vport)66 u8 mlx5_query_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport)
67 {
68 u32 out[MLX5_ST_SZ_DW(query_vport_state_out)] = {0};
69
70 _mlx5_query_vport_state(mdev, opmod, vport, out, sizeof(out));
71
72 return MLX5_GET(query_vport_state_out, out, admin_state);
73 }
74 EXPORT_SYMBOL(mlx5_query_vport_admin_state);
75
mlx5_modify_vport_admin_state(struct mlx5_core_dev * mdev,u8 opmod,u16 vport,u8 state)76 int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
77 u16 vport, u8 state)
78 {
79 u32 in[MLX5_ST_SZ_DW(modify_vport_state_in)] = {0};
80 u32 out[MLX5_ST_SZ_DW(modify_vport_state_out)] = {0};
81 int err;
82
83 MLX5_SET(modify_vport_state_in, in, opcode,
84 MLX5_CMD_OP_MODIFY_VPORT_STATE);
85 MLX5_SET(modify_vport_state_in, in, op_mod, opmod);
86 MLX5_SET(modify_vport_state_in, in, vport_number, vport);
87
88 if (vport)
89 MLX5_SET(modify_vport_state_in, in, other_vport, 1);
90
91 MLX5_SET(modify_vport_state_in, in, admin_state, state);
92
93 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
94 if (err)
95 mlx5_core_warn(mdev, "MLX5_CMD_OP_MODIFY_VPORT_STATE failed\n");
96
97 return err;
98 }
99 EXPORT_SYMBOL(mlx5_modify_vport_admin_state);
100
mlx5_query_nic_vport_context(struct mlx5_core_dev * mdev,u16 vport,u32 * out,int outlen)101 static int mlx5_query_nic_vport_context(struct mlx5_core_dev *mdev, u16 vport,
102 u32 *out, int outlen)
103 {
104 u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
105
106 MLX5_SET(query_nic_vport_context_in, in, opcode,
107 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
108
109 MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
110 if (vport)
111 MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
112
113 return mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
114 }
115
mlx5_vport_max_q_counter_allocator(struct mlx5_core_dev * mdev,int client_id)116 static u32 mlx5_vport_max_q_counter_allocator(struct mlx5_core_dev *mdev,
117 int client_id)
118 {
119 switch (client_id) {
120 case MLX5_INTERFACE_PROTOCOL_IB:
121 return (MLX5_CAP_GEN(mdev, max_qp_cnt) -
122 MLX5_QCOUNTER_SETS_NETDEV);
123 case MLX5_INTERFACE_PROTOCOL_ETH:
124 return MLX5_QCOUNTER_SETS_NETDEV;
125 default:
126 mlx5_core_warn(mdev, "Unknown Client: %d\n", client_id);
127 return 0;
128 }
129 }
130
mlx5_vport_alloc_q_counter(struct mlx5_core_dev * mdev,int client_id,u16 * counter_set_id)131 int mlx5_vport_alloc_q_counter(struct mlx5_core_dev *mdev,
132 int client_id, u16 *counter_set_id)
133 {
134 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {0};
135 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {0};
136 int err;
137
138 if (mdev->num_q_counter_allocated[client_id] >
139 mlx5_vport_max_q_counter_allocator(mdev, client_id))
140 return -EINVAL;
141
142 MLX5_SET(alloc_q_counter_in, in, opcode,
143 MLX5_CMD_OP_ALLOC_Q_COUNTER);
144
145 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
146
147 if (!err)
148 *counter_set_id = MLX5_GET(alloc_q_counter_out, out,
149 counter_set_id);
150
151 mdev->num_q_counter_allocated[client_id]++;
152
153 return err;
154 }
155
mlx5_vport_dealloc_q_counter(struct mlx5_core_dev * mdev,int client_id,u16 counter_set_id)156 int mlx5_vport_dealloc_q_counter(struct mlx5_core_dev *mdev,
157 int client_id, u16 counter_set_id)
158 {
159 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {0};
160 u32 out[MLX5_ST_SZ_DW(dealloc_q_counter_out)] = {0};
161 int err;
162
163 if (mdev->num_q_counter_allocated[client_id] <= 0)
164 return -EINVAL;
165
166 MLX5_SET(dealloc_q_counter_in, in, opcode,
167 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
168 MLX5_SET(dealloc_q_counter_in, in, counter_set_id,
169 counter_set_id);
170
171 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
172
173 mdev->num_q_counter_allocated[client_id]--;
174
175 return err;
176 }
177
mlx5_vport_query_q_counter(struct mlx5_core_dev * mdev,u16 counter_set_id,int reset,void * out,int out_size)178 int mlx5_vport_query_q_counter(struct mlx5_core_dev *mdev,
179 u16 counter_set_id,
180 int reset,
181 void *out,
182 int out_size)
183 {
184 u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {0};
185
186 MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
187 MLX5_SET(query_q_counter_in, in, clear, reset);
188 MLX5_SET(query_q_counter_in, in, counter_set_id, counter_set_id);
189
190 return mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size);
191 }
192
mlx5_vport_query_out_of_rx_buffer(struct mlx5_core_dev * mdev,u16 counter_set_id,u32 * out_of_rx_buffer)193 int mlx5_vport_query_out_of_rx_buffer(struct mlx5_core_dev *mdev,
194 u16 counter_set_id,
195 u32 *out_of_rx_buffer)
196 {
197 u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {0};
198 int err;
199
200 err = mlx5_vport_query_q_counter(mdev, counter_set_id, 0, out,
201 sizeof(out));
202
203 if (err)
204 return err;
205
206 *out_of_rx_buffer = MLX5_GET(query_q_counter_out, out,
207 out_of_buffer);
208 return err;
209 }
210
mlx5_query_nic_vport_min_inline(struct mlx5_core_dev * mdev,u16 vport,u8 * min_inline)211 int mlx5_query_nic_vport_min_inline(struct mlx5_core_dev *mdev,
212 u16 vport, u8 *min_inline)
213 {
214 u32 out[MLX5_ST_SZ_DW(query_nic_vport_context_out)] = {0};
215 int err;
216
217 err = mlx5_query_nic_vport_context(mdev, vport, out, sizeof(out));
218 if (!err)
219 *min_inline = MLX5_GET(query_nic_vport_context_out, out,
220 nic_vport_context.min_wqe_inline_mode);
221 return err;
222 }
223 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_min_inline);
224
mlx5_query_min_inline(struct mlx5_core_dev * mdev,u8 * min_inline_mode)225 int mlx5_query_min_inline(struct mlx5_core_dev *mdev,
226 u8 *min_inline_mode)
227 {
228 int err;
229
230 switch (MLX5_CAP_ETH(mdev, wqe_inline_mode)) {
231 case MLX5_CAP_INLINE_MODE_L2:
232 *min_inline_mode = MLX5_INLINE_MODE_L2;
233 err = 0;
234 break;
235 case MLX5_CAP_INLINE_MODE_VPORT_CONTEXT:
236 err = mlx5_query_nic_vport_min_inline(mdev, 0, min_inline_mode);
237 break;
238 case MLX5_CAP_INLINE_MODE_NOT_REQUIRED:
239 *min_inline_mode = MLX5_INLINE_MODE_NONE;
240 err = 0;
241 break;
242 default:
243 err = -EINVAL;
244 break;
245 }
246 return err;
247 }
248 EXPORT_SYMBOL_GPL(mlx5_query_min_inline);
249
mlx5_modify_nic_vport_min_inline(struct mlx5_core_dev * mdev,u16 vport,u8 min_inline)250 int mlx5_modify_nic_vport_min_inline(struct mlx5_core_dev *mdev,
251 u16 vport, u8 min_inline)
252 {
253 u32 in[MLX5_ST_SZ_DW(modify_nic_vport_context_in)] = {0};
254 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
255 void *nic_vport_ctx;
256
257 MLX5_SET(modify_nic_vport_context_in, in,
258 field_select.min_wqe_inline_mode, 1);
259 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
260 MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
261
262 nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
263 in, nic_vport_context);
264 MLX5_SET(nic_vport_context, nic_vport_ctx,
265 min_wqe_inline_mode, min_inline);
266
267 return mlx5_modify_nic_vport_context(mdev, in, inlen);
268 }
269 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_min_inline);
270
mlx5_query_nic_vport_mac_address(struct mlx5_core_dev * mdev,u16 vport,u8 * addr)271 int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
272 u16 vport, u8 *addr)
273 {
274 u32 *out;
275 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
276 u8 *out_addr;
277 int err;
278
279 out = mlx5_vzalloc(outlen);
280 if (!out)
281 return -ENOMEM;
282
283 out_addr = MLX5_ADDR_OF(query_nic_vport_context_out, out,
284 nic_vport_context.permanent_address);
285
286 err = mlx5_query_nic_vport_context(mdev, vport, out, outlen);
287 if (err)
288 goto out;
289
290 ether_addr_copy(addr, &out_addr[2]);
291
292 out:
293 kvfree(out);
294 return err;
295 }
296 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_address);
297
mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev * mdev,u16 vport,u8 * addr)298 int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev,
299 u16 vport, u8 *addr)
300 {
301 void *in;
302 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
303 int err;
304 void *nic_vport_ctx;
305 u8 *perm_mac;
306
307 in = mlx5_vzalloc(inlen);
308 if (!in) {
309 mlx5_core_warn(mdev, "failed to allocate inbox\n");
310 return -ENOMEM;
311 }
312
313 MLX5_SET(modify_nic_vport_context_in, in,
314 field_select.permanent_address, 1);
315 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
316
317 if (vport)
318 MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
319
320 nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
321 in, nic_vport_context);
322 perm_mac = MLX5_ADDR_OF(nic_vport_context, nic_vport_ctx,
323 permanent_address);
324
325 ether_addr_copy(&perm_mac[2], addr);
326
327 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
328
329 kvfree(in);
330
331 return err;
332 }
333 EXPORT_SYMBOL(mlx5_modify_nic_vport_mac_address);
334
mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev * mdev,u64 * system_image_guid)335 int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev,
336 u64 *system_image_guid)
337 {
338 u32 *out;
339 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
340 int err;
341
342 out = mlx5_vzalloc(outlen);
343 if (!out)
344 return -ENOMEM;
345
346 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
347 if (err)
348 goto out;
349
350 *system_image_guid = MLX5_GET64(query_nic_vport_context_out, out,
351 nic_vport_context.system_image_guid);
352 out:
353 kvfree(out);
354 return err;
355 }
356 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_system_image_guid);
357
mlx5_query_nic_vport_node_guid(struct mlx5_core_dev * mdev,u64 * node_guid)358 int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid)
359 {
360 u32 *out;
361 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
362 int err;
363
364 out = mlx5_vzalloc(outlen);
365 if (!out)
366 return -ENOMEM;
367
368 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
369 if (err)
370 goto out;
371
372 *node_guid = MLX5_GET64(query_nic_vport_context_out, out,
373 nic_vport_context.node_guid);
374
375 out:
376 kvfree(out);
377 return err;
378 }
379 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_node_guid);
380
mlx5_query_nic_vport_port_guid(struct mlx5_core_dev * mdev,u64 * port_guid)381 static int mlx5_query_nic_vport_port_guid(struct mlx5_core_dev *mdev,
382 u64 *port_guid)
383 {
384 u32 *out;
385 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
386 int err;
387
388 out = mlx5_vzalloc(outlen);
389 if (!out)
390 return -ENOMEM;
391
392 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
393 if (err)
394 goto out;
395
396 *port_guid = MLX5_GET64(query_nic_vport_context_out, out,
397 nic_vport_context.port_guid);
398
399 out:
400 kvfree(out);
401 return err;
402 }
403
mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev * mdev,u16 * qkey_viol_cntr)404 int mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev *mdev,
405 u16 *qkey_viol_cntr)
406 {
407 u32 *out;
408 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
409 int err;
410
411 out = mlx5_vzalloc(outlen);
412 if (!out)
413 return -ENOMEM;
414
415 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
416 if (err)
417 goto out;
418
419 *qkey_viol_cntr = MLX5_GET(query_nic_vport_context_out, out,
420 nic_vport_context.qkey_violation_counter);
421
422 out:
423 kvfree(out);
424 return err;
425 }
426 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_qkey_viol_cntr);
427
mlx5_modify_nic_vport_context(struct mlx5_core_dev * mdev,void * in,int inlen)428 static int mlx5_modify_nic_vport_context(struct mlx5_core_dev *mdev, void *in,
429 int inlen)
430 {
431 u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)] = {0};
432
433 MLX5_SET(modify_nic_vport_context_in, in, opcode,
434 MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
435
436 return mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
437 }
438
mlx5_nic_vport_enable_disable_roce(struct mlx5_core_dev * mdev,int enable_disable)439 static int mlx5_nic_vport_enable_disable_roce(struct mlx5_core_dev *mdev,
440 int enable_disable)
441 {
442 void *in;
443 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
444 int err;
445
446 in = mlx5_vzalloc(inlen);
447 if (!in) {
448 mlx5_core_warn(mdev, "failed to allocate inbox\n");
449 return -ENOMEM;
450 }
451
452 MLX5_SET(modify_nic_vport_context_in, in, field_select.roce_en, 1);
453 MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.roce_en,
454 enable_disable);
455
456 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
457
458 kvfree(in);
459
460 return err;
461 }
462
mlx5_set_nic_vport_current_mac(struct mlx5_core_dev * mdev,int vport,bool other_vport,u8 * addr)463 int mlx5_set_nic_vport_current_mac(struct mlx5_core_dev *mdev, int vport,
464 bool other_vport, u8 *addr)
465 {
466 void *in;
467 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)
468 + MLX5_ST_SZ_BYTES(mac_address_layout);
469 u8 *mac_layout;
470 u8 *mac_ptr;
471 int err;
472
473 in = mlx5_vzalloc(inlen);
474 if (!in) {
475 mlx5_core_warn(mdev, "failed to allocate inbox\n");
476 return -ENOMEM;
477 }
478
479 MLX5_SET(modify_nic_vport_context_in, in,
480 opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
481 MLX5_SET(modify_nic_vport_context_in, in,
482 vport_number, vport);
483 MLX5_SET(modify_nic_vport_context_in, in,
484 other_vport, other_vport);
485 MLX5_SET(modify_nic_vport_context_in, in,
486 field_select.addresses_list, 1);
487 MLX5_SET(modify_nic_vport_context_in, in,
488 nic_vport_context.allowed_list_type,
489 MLX5_NIC_VPORT_LIST_TYPE_UC);
490 MLX5_SET(modify_nic_vport_context_in, in,
491 nic_vport_context.allowed_list_size, 1);
492
493 mac_layout = (u8 *)MLX5_ADDR_OF(modify_nic_vport_context_in, in,
494 nic_vport_context.current_uc_mac_address);
495 mac_ptr = (u8 *)MLX5_ADDR_OF(mac_address_layout, mac_layout,
496 mac_addr_47_32);
497 ether_addr_copy(mac_ptr, addr);
498
499 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
500
501 kvfree(in);
502
503 return err;
504 }
505 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_current_mac);
506
mlx5_modify_nic_vport_node_guid(struct mlx5_core_dev * mdev,u32 vport,u64 node_guid)507 int mlx5_modify_nic_vport_node_guid(struct mlx5_core_dev *mdev,
508 u32 vport, u64 node_guid)
509 {
510 void *in;
511 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
512 int err;
513 void *nic_vport_context;
514
515 if (!vport)
516 return -EINVAL;
517 if (!MLX5_CAP_GEN(mdev, vport_group_manager))
518 return -EPERM;
519 if (!MLX5_CAP_ESW(mdev, nic_vport_node_guid_modify))
520 return -ENOTSUPP;
521
522 in = mlx5_vzalloc(inlen);
523 if (!in) {
524 mlx5_core_warn(mdev, "failed to allocate inbox\n");
525 return -ENOMEM;
526 }
527
528 MLX5_SET(modify_nic_vport_context_in, in,
529 field_select.node_guid, 1);
530 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
531
532 MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
533
534 nic_vport_context = MLX5_ADDR_OF(modify_nic_vport_context_in,
535 in, nic_vport_context);
536 MLX5_SET64(nic_vport_context, nic_vport_context, node_guid, node_guid);
537
538 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
539
540 kvfree(in);
541
542 return err;
543 }
544 EXPORT_SYMBOL(mlx5_modify_nic_vport_node_guid);
545
mlx5_modify_nic_vport_port_guid(struct mlx5_core_dev * mdev,u32 vport,u64 port_guid)546 int mlx5_modify_nic_vport_port_guid(struct mlx5_core_dev *mdev,
547 u32 vport, u64 port_guid)
548 {
549 void *in;
550 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
551 int err;
552 void *nic_vport_context;
553
554 if (!vport)
555 return -EINVAL;
556 if (!MLX5_CAP_GEN(mdev, vport_group_manager))
557 return -EPERM;
558 if (!MLX5_CAP_ESW(mdev, nic_vport_port_guid_modify))
559 return -ENOTSUPP;
560
561 in = mlx5_vzalloc(inlen);
562 if (!in) {
563 mlx5_core_warn(mdev, "failed to allocate inbox\n");
564 return -ENOMEM;
565 }
566
567 MLX5_SET(modify_nic_vport_context_in, in,
568 field_select.port_guid, 1);
569 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
570
571 MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
572
573 nic_vport_context = MLX5_ADDR_OF(modify_nic_vport_context_in,
574 in, nic_vport_context);
575 MLX5_SET64(nic_vport_context, nic_vport_context, port_guid, port_guid);
576
577 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
578
579 kvfree(in);
580
581 return err;
582 }
583 EXPORT_SYMBOL(mlx5_modify_nic_vport_port_guid);
584
mlx5_set_nic_vport_vlan_list(struct mlx5_core_dev * dev,u16 vport,u16 * vlan_list,int list_len)585 int mlx5_set_nic_vport_vlan_list(struct mlx5_core_dev *dev, u16 vport,
586 u16 *vlan_list, int list_len)
587 {
588 void *in, *ctx;
589 int i, err;
590 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)
591 + MLX5_ST_SZ_BYTES(vlan_layout) * (int)list_len;
592
593 int max_list_size = 1 << MLX5_CAP_GEN_MAX(dev, log_max_vlan_list);
594
595 if (list_len > max_list_size) {
596 mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
597 list_len, max_list_size);
598 return -ENOSPC;
599 }
600
601 in = mlx5_vzalloc(inlen);
602 if (!in) {
603 mlx5_core_warn(dev, "failed to allocate inbox\n");
604 return -ENOMEM;
605 }
606
607 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
608 if (vport)
609 MLX5_SET(modify_nic_vport_context_in, in,
610 other_vport, 1);
611 MLX5_SET(modify_nic_vport_context_in, in,
612 field_select.addresses_list, 1);
613
614 ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context);
615
616 MLX5_SET(nic_vport_context, ctx, allowed_list_type,
617 MLX5_NIC_VPORT_LIST_TYPE_VLAN);
618 MLX5_SET(nic_vport_context, ctx, allowed_list_size, list_len);
619
620 for (i = 0; i < list_len; i++) {
621 u8 *vlan_lout = MLX5_ADDR_OF(nic_vport_context, ctx,
622 current_uc_mac_address[i]);
623 MLX5_SET(vlan_layout, vlan_lout, vlan, vlan_list[i]);
624 }
625
626 err = mlx5_modify_nic_vport_context(dev, in, inlen);
627
628 kvfree(in);
629 return err;
630 }
631 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_vlan_list);
632
mlx5_set_nic_vport_mc_list(struct mlx5_core_dev * mdev,int vport,u64 * addr_list,size_t addr_list_len)633 int mlx5_set_nic_vport_mc_list(struct mlx5_core_dev *mdev, int vport,
634 u64 *addr_list, size_t addr_list_len)
635 {
636 void *in, *ctx;
637 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)
638 + MLX5_ST_SZ_BYTES(mac_address_layout) * (int)addr_list_len;
639 int err;
640 size_t i;
641 int max_list_sz = 1 << MLX5_CAP_GEN_MAX(mdev, log_max_current_mc_list);
642
643 if ((int)addr_list_len > max_list_sz) {
644 mlx5_core_warn(mdev, "Requested list size (%d) > (%d) max_list_size\n",
645 (int)addr_list_len, max_list_sz);
646 return -ENOSPC;
647 }
648
649 in = mlx5_vzalloc(inlen);
650 if (!in) {
651 mlx5_core_warn(mdev, "failed to allocate inbox\n");
652 return -ENOMEM;
653 }
654
655 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
656 if (vport)
657 MLX5_SET(modify_nic_vport_context_in, in,
658 other_vport, 1);
659 MLX5_SET(modify_nic_vport_context_in, in,
660 field_select.addresses_list, 1);
661
662 ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context);
663
664 MLX5_SET(nic_vport_context, ctx, allowed_list_type,
665 MLX5_NIC_VPORT_LIST_TYPE_MC);
666 MLX5_SET(nic_vport_context, ctx, allowed_list_size, addr_list_len);
667
668 for (i = 0; i < addr_list_len; i++) {
669 u8 *mac_lout = (u8 *)MLX5_ADDR_OF(nic_vport_context, ctx,
670 current_uc_mac_address[i]);
671 u8 *mac_ptr = (u8 *)MLX5_ADDR_OF(mac_address_layout, mac_lout,
672 mac_addr_47_32);
673 ether_addr_copy(mac_ptr, (u8 *)&addr_list[i]);
674 }
675
676 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
677
678 kvfree(in);
679
680 return err;
681 }
682 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_mc_list);
683
mlx5_set_nic_vport_promisc(struct mlx5_core_dev * mdev,int vport,bool promisc_mc,bool promisc_uc,bool promisc_all)684 int mlx5_set_nic_vport_promisc(struct mlx5_core_dev *mdev, int vport,
685 bool promisc_mc, bool promisc_uc,
686 bool promisc_all)
687 {
688 u8 in[MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)];
689 u8 *ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
690 nic_vport_context);
691
692 memset(in, 0, MLX5_ST_SZ_BYTES(modify_nic_vport_context_in));
693
694 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
695 if (vport)
696 MLX5_SET(modify_nic_vport_context_in, in,
697 other_vport, 1);
698 MLX5_SET(modify_nic_vport_context_in, in, field_select.promisc, 1);
699 if (promisc_mc)
700 MLX5_SET(nic_vport_context, ctx, promisc_mc, 1);
701 if (promisc_uc)
702 MLX5_SET(nic_vport_context, ctx, promisc_uc, 1);
703 if (promisc_all)
704 MLX5_SET(nic_vport_context, ctx, promisc_all, 1);
705
706 return mlx5_modify_nic_vport_context(mdev, in, sizeof(in));
707 }
708 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_promisc);
709
mlx5_query_nic_vport_mac_list(struct mlx5_core_dev * dev,u16 vport,enum mlx5_list_type list_type,u8 addr_list[][ETH_ALEN],int * list_size)710 int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
711 u16 vport,
712 enum mlx5_list_type list_type,
713 u8 addr_list[][ETH_ALEN],
714 int *list_size)
715 {
716 u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
717 void *nic_vport_ctx;
718 int max_list_size;
719 int req_list_size;
720 int out_sz;
721 void *out;
722 int err;
723 int i;
724
725 req_list_size = *list_size;
726
727 max_list_size = (list_type == MLX5_NIC_VPORT_LIST_TYPE_UC) ?
728 1 << MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list) :
729 1 << MLX5_CAP_GEN_MAX(dev, log_max_current_mc_list);
730
731 if (req_list_size > max_list_size) {
732 mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
733 req_list_size, max_list_size);
734 req_list_size = max_list_size;
735 }
736
737 out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
738 req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
739
740 out = kzalloc(out_sz, GFP_KERNEL);
741 if (!out)
742 return -ENOMEM;
743
744 MLX5_SET(query_nic_vport_context_in, in, opcode,
745 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
746 MLX5_SET(query_nic_vport_context_in, in, allowed_list_type, list_type);
747 MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
748
749 if (vport)
750 MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
751
752 err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz);
753 if (err)
754 goto out;
755
756 nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
757 nic_vport_context);
758 req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
759 allowed_list_size);
760
761 *list_size = req_list_size;
762 for (i = 0; i < req_list_size; i++) {
763 u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
764 nic_vport_ctx,
765 current_uc_mac_address[i]) + 2;
766 ether_addr_copy(addr_list[i], mac_addr);
767 }
768 out:
769 kfree(out);
770 return err;
771 }
772 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_list);
773
mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev * dev,enum mlx5_list_type list_type,u8 addr_list[][ETH_ALEN],int list_size)774 int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
775 enum mlx5_list_type list_type,
776 u8 addr_list[][ETH_ALEN],
777 int list_size)
778 {
779 u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)] = {0};
780 void *nic_vport_ctx;
781 int max_list_size;
782 int in_sz;
783 void *in;
784 int err;
785 int i;
786
787 max_list_size = list_type == MLX5_NIC_VPORT_LIST_TYPE_UC ?
788 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
789 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
790
791 if (list_size > max_list_size)
792 return -ENOSPC;
793
794 in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
795 list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
796
797 in = kzalloc(in_sz, GFP_KERNEL);
798 if (!in)
799 return -ENOMEM;
800
801 MLX5_SET(modify_nic_vport_context_in, in, opcode,
802 MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
803 MLX5_SET(modify_nic_vport_context_in, in,
804 field_select.addresses_list, 1);
805
806 nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
807 nic_vport_context);
808
809 MLX5_SET(nic_vport_context, nic_vport_ctx,
810 allowed_list_type, list_type);
811 MLX5_SET(nic_vport_context, nic_vport_ctx,
812 allowed_list_size, list_size);
813
814 for (i = 0; i < list_size; i++) {
815 u8 *curr_mac = MLX5_ADDR_OF(nic_vport_context,
816 nic_vport_ctx,
817 current_uc_mac_address[i]) + 2;
818 ether_addr_copy(curr_mac, addr_list[i]);
819 }
820
821 err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
822 kfree(in);
823 return err;
824 }
825 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_list);
826
mlx5_query_nic_vport_vlans(struct mlx5_core_dev * dev,u16 vport,u16 vlans[],int * size)827 int mlx5_query_nic_vport_vlans(struct mlx5_core_dev *dev,
828 u16 vport,
829 u16 vlans[],
830 int *size)
831 {
832 u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
833 void *nic_vport_ctx;
834 int req_list_size;
835 int max_list_size;
836 int out_sz;
837 void *out;
838 int err;
839 int i;
840
841 req_list_size = *size;
842 max_list_size = 1 << MLX5_CAP_GEN(dev, log_max_vlan_list);
843 if (req_list_size > max_list_size) {
844 mlx5_core_warn(dev, "Requested list size (%d) > (%d) max list size\n",
845 req_list_size, max_list_size);
846 req_list_size = max_list_size;
847 }
848
849 out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
850 req_list_size * MLX5_ST_SZ_BYTES(vlan_layout);
851
852 out = kzalloc(out_sz, GFP_KERNEL);
853 if (!out)
854 return -ENOMEM;
855
856 MLX5_SET(query_nic_vport_context_in, in, opcode,
857 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
858 MLX5_SET(query_nic_vport_context_in, in, allowed_list_type,
859 MLX5_NIC_VPORT_CONTEXT_ALLOWED_LIST_TYPE_VLAN_LIST);
860 MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
861
862 if (vport)
863 MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
864
865 err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz);
866 if (err)
867 goto out;
868
869 nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
870 nic_vport_context);
871 req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
872 allowed_list_size);
873
874 *size = req_list_size;
875 for (i = 0; i < req_list_size; i++) {
876 void *vlan_addr = MLX5_ADDR_OF(nic_vport_context,
877 nic_vport_ctx,
878 current_uc_mac_address[i]);
879 vlans[i] = MLX5_GET(vlan_layout, vlan_addr, vlan);
880 }
881 out:
882 kfree(out);
883 return err;
884 }
885 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_vlans);
886
mlx5_modify_nic_vport_vlans(struct mlx5_core_dev * dev,u16 vlans[],int list_size)887 int mlx5_modify_nic_vport_vlans(struct mlx5_core_dev *dev,
888 u16 vlans[],
889 int list_size)
890 {
891 u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)] = {0};
892 void *nic_vport_ctx;
893 int max_list_size;
894 int in_sz;
895 void *in;
896 int err;
897 int i;
898
899 max_list_size = 1 << MLX5_CAP_GEN(dev, log_max_vlan_list);
900
901 if (list_size > max_list_size)
902 return -ENOSPC;
903
904 in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
905 list_size * MLX5_ST_SZ_BYTES(vlan_layout);
906
907 in = kzalloc(in_sz, GFP_KERNEL);
908 if (!in)
909 return -ENOMEM;
910
911 MLX5_SET(modify_nic_vport_context_in, in, opcode,
912 MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
913 MLX5_SET(modify_nic_vport_context_in, in,
914 field_select.addresses_list, 1);
915
916 nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
917 nic_vport_context);
918
919 MLX5_SET(nic_vport_context, nic_vport_ctx,
920 allowed_list_type, MLX5_NIC_VPORT_LIST_TYPE_VLAN);
921 MLX5_SET(nic_vport_context, nic_vport_ctx,
922 allowed_list_size, list_size);
923
924 for (i = 0; i < list_size; i++) {
925 void *vlan_addr = MLX5_ADDR_OF(nic_vport_context,
926 nic_vport_ctx,
927 current_uc_mac_address[i]);
928 MLX5_SET(vlan_layout, vlan_addr, vlan, vlans[i]);
929 }
930
931 err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
932 kfree(in);
933 return err;
934 }
935 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_vlans);
936
mlx5_query_nic_vport_roce_en(struct mlx5_core_dev * mdev,u8 * enable)937 int mlx5_query_nic_vport_roce_en(struct mlx5_core_dev *mdev, u8 *enable)
938 {
939 u32 *out;
940 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
941 int err;
942
943 out = kzalloc(outlen, GFP_KERNEL);
944 if (!out)
945 return -ENOMEM;
946
947 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
948 if (err)
949 goto out;
950
951 *enable = MLX5_GET(query_nic_vport_context_out, out,
952 nic_vport_context.roce_en);
953
954 out:
955 kfree(out);
956 return err;
957 }
958 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_roce_en);
959
mlx5_set_nic_vport_permanent_mac(struct mlx5_core_dev * mdev,int vport,u8 * addr)960 int mlx5_set_nic_vport_permanent_mac(struct mlx5_core_dev *mdev, int vport,
961 u8 *addr)
962 {
963 void *in;
964 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
965 u8 *mac_ptr;
966 int err;
967
968 in = mlx5_vzalloc(inlen);
969 if (!in) {
970 mlx5_core_warn(mdev, "failed to allocate inbox\n");
971 return -ENOMEM;
972 }
973
974 MLX5_SET(modify_nic_vport_context_in, in,
975 opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
976 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
977 MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
978 MLX5_SET(modify_nic_vport_context_in, in,
979 field_select.permanent_address, 1);
980 mac_ptr = (u8 *)MLX5_ADDR_OF(modify_nic_vport_context_in, in,
981 nic_vport_context.permanent_address.mac_addr_47_32);
982 ether_addr_copy(mac_ptr, addr);
983
984 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
985
986 kvfree(in);
987
988 return err;
989 }
990 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_permanent_mac);
991
mlx5_nic_vport_enable_roce(struct mlx5_core_dev * mdev)992 int mlx5_nic_vport_enable_roce(struct mlx5_core_dev *mdev)
993 {
994 return mlx5_nic_vport_enable_disable_roce(mdev, 1);
995 }
996 EXPORT_SYMBOL_GPL(mlx5_nic_vport_enable_roce);
997
mlx5_nic_vport_disable_roce(struct mlx5_core_dev * mdev)998 int mlx5_nic_vport_disable_roce(struct mlx5_core_dev *mdev)
999 {
1000 return mlx5_nic_vport_enable_disable_roce(mdev, 0);
1001 }
1002 EXPORT_SYMBOL_GPL(mlx5_nic_vport_disable_roce);
1003
mlx5_core_query_vport_counter(struct mlx5_core_dev * dev,u8 other_vport,int vf,u8 port_num,void * out,size_t out_sz)1004 int mlx5_core_query_vport_counter(struct mlx5_core_dev *dev, u8 other_vport,
1005 int vf, u8 port_num, void *out,
1006 size_t out_sz)
1007 {
1008 int in_sz = MLX5_ST_SZ_BYTES(query_vport_counter_in);
1009 int is_group_manager;
1010 void *in;
1011 int err;
1012
1013 is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
1014 in = mlx5_vzalloc(in_sz);
1015 if (!in) {
1016 err = -ENOMEM;
1017 return err;
1018 }
1019
1020 MLX5_SET(query_vport_counter_in, in, opcode,
1021 MLX5_CMD_OP_QUERY_VPORT_COUNTER);
1022 if (other_vport) {
1023 if (is_group_manager) {
1024 MLX5_SET(query_vport_counter_in, in, other_vport, 1);
1025 MLX5_SET(query_vport_counter_in, in, vport_number, vf + 1);
1026 } else {
1027 err = -EPERM;
1028 goto free;
1029 }
1030 }
1031 if (MLX5_CAP_GEN(dev, num_ports) == 2)
1032 MLX5_SET(query_vport_counter_in, in, port_num, port_num);
1033
1034 err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
1035 free:
1036 kvfree(in);
1037 return err;
1038 }
1039 EXPORT_SYMBOL_GPL(mlx5_core_query_vport_counter);
1040
mlx5_query_hca_vport_context(struct mlx5_core_dev * mdev,u8 port_num,u8 vport_num,u32 * out,int outlen)1041 int mlx5_query_hca_vport_context(struct mlx5_core_dev *mdev,
1042 u8 port_num, u8 vport_num, u32 *out,
1043 int outlen)
1044 {
1045 u32 in[MLX5_ST_SZ_DW(query_hca_vport_context_in)] = {0};
1046 int is_group_manager;
1047
1048 is_group_manager = MLX5_CAP_GEN(mdev, vport_group_manager);
1049
1050 MLX5_SET(query_hca_vport_context_in, in, opcode,
1051 MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT);
1052
1053 if (vport_num) {
1054 if (is_group_manager) {
1055 MLX5_SET(query_hca_vport_context_in, in, other_vport,
1056 1);
1057 MLX5_SET(query_hca_vport_context_in, in, vport_number,
1058 vport_num);
1059 } else {
1060 return -EPERM;
1061 }
1062 }
1063
1064 if (MLX5_CAP_GEN(mdev, num_ports) == 2)
1065 MLX5_SET(query_hca_vport_context_in, in, port_num, port_num);
1066
1067 return mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
1068 }
1069
mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev * mdev,u64 * system_image_guid)1070 int mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev *mdev,
1071 u64 *system_image_guid)
1072 {
1073 u32 *out;
1074 int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
1075 int err;
1076
1077 out = mlx5_vzalloc(outlen);
1078 if (!out)
1079 return -ENOMEM;
1080
1081 err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen);
1082 if (err)
1083 goto out;
1084
1085 *system_image_guid = MLX5_GET64(query_hca_vport_context_out, out,
1086 hca_vport_context.system_image_guid);
1087
1088 out:
1089 kvfree(out);
1090 return err;
1091 }
1092 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_system_image_guid);
1093
mlx5_query_hca_vport_node_guid(struct mlx5_core_dev * mdev,u64 * node_guid)1094 int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid)
1095 {
1096 u32 *out;
1097 int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
1098 int err;
1099
1100 out = mlx5_vzalloc(outlen);
1101 if (!out)
1102 return -ENOMEM;
1103
1104 err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen);
1105 if (err)
1106 goto out;
1107
1108 *node_guid = MLX5_GET64(query_hca_vport_context_out, out,
1109 hca_vport_context.node_guid);
1110
1111 out:
1112 kvfree(out);
1113 return err;
1114 }
1115 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_node_guid);
1116
mlx5_query_hca_vport_port_guid(struct mlx5_core_dev * mdev,u64 * port_guid)1117 static int mlx5_query_hca_vport_port_guid(struct mlx5_core_dev *mdev,
1118 u64 *port_guid)
1119 {
1120 u32 *out;
1121 int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
1122 int err;
1123
1124 out = mlx5_vzalloc(outlen);
1125 if (!out)
1126 return -ENOMEM;
1127
1128 err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen);
1129 if (err)
1130 goto out;
1131
1132 *port_guid = MLX5_GET64(query_hca_vport_context_out, out,
1133 hca_vport_context.port_guid);
1134
1135 out:
1136 kvfree(out);
1137 return err;
1138 }
1139
mlx5_query_hca_vport_gid(struct mlx5_core_dev * dev,u8 port_num,u16 vport_num,u16 gid_index,union ib_gid * gid)1140 int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 port_num,
1141 u16 vport_num, u16 gid_index, union ib_gid *gid)
1142 {
1143 int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_in);
1144 int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_out);
1145 int is_group_manager;
1146 void *out = NULL;
1147 void *in = NULL;
1148 union ib_gid *tmp;
1149 int tbsz;
1150 int nout;
1151 int err;
1152
1153 is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
1154 tbsz = mlx5_get_gid_table_len(MLX5_CAP_GEN(dev, gid_table_size));
1155
1156 if (gid_index > tbsz && gid_index != 0xffff)
1157 return -EINVAL;
1158
1159 if (gid_index == 0xffff)
1160 nout = tbsz;
1161 else
1162 nout = 1;
1163
1164 out_sz += nout * sizeof(*gid);
1165
1166 in = mlx5_vzalloc(in_sz);
1167 out = mlx5_vzalloc(out_sz);
1168 if (!in || !out) {
1169 err = -ENOMEM;
1170 goto out;
1171 }
1172
1173 MLX5_SET(query_hca_vport_gid_in, in, opcode,
1174 MLX5_CMD_OP_QUERY_HCA_VPORT_GID);
1175 if (vport_num) {
1176 if (is_group_manager) {
1177 MLX5_SET(query_hca_vport_gid_in, in, vport_number,
1178 vport_num);
1179 MLX5_SET(query_hca_vport_gid_in, in, other_vport, 1);
1180 } else {
1181 err = -EPERM;
1182 goto out;
1183 }
1184 }
1185
1186 MLX5_SET(query_hca_vport_gid_in, in, gid_index, gid_index);
1187
1188 if (MLX5_CAP_GEN(dev, num_ports) == 2)
1189 MLX5_SET(query_hca_vport_gid_in, in, port_num, port_num);
1190
1191 err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
1192 if (err)
1193 goto out;
1194
1195 tmp = (union ib_gid *)MLX5_ADDR_OF(query_hca_vport_gid_out, out, gid);
1196 gid->global.subnet_prefix = tmp->global.subnet_prefix;
1197 gid->global.interface_id = tmp->global.interface_id;
1198
1199 out:
1200 kvfree(in);
1201 kvfree(out);
1202 return err;
1203 }
1204 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_gid);
1205
mlx5_query_hca_vport_pkey(struct mlx5_core_dev * dev,u8 other_vport,u8 port_num,u16 vf_num,u16 pkey_index,u16 * pkey)1206 int mlx5_query_hca_vport_pkey(struct mlx5_core_dev *dev, u8 other_vport,
1207 u8 port_num, u16 vf_num, u16 pkey_index,
1208 u16 *pkey)
1209 {
1210 int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_in);
1211 int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_out);
1212 int is_group_manager;
1213 void *out = NULL;
1214 void *in = NULL;
1215 void *pkarr;
1216 int nout;
1217 int tbsz;
1218 int err;
1219 int i;
1220
1221 is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
1222
1223 tbsz = mlx5_to_sw_pkey_sz(MLX5_CAP_GEN(dev, pkey_table_size));
1224 if (pkey_index > tbsz && pkey_index != 0xffff)
1225 return -EINVAL;
1226
1227 if (pkey_index == 0xffff)
1228 nout = tbsz;
1229 else
1230 nout = 1;
1231
1232 out_sz += nout * MLX5_ST_SZ_BYTES(pkey);
1233
1234 in = kzalloc(in_sz, GFP_KERNEL);
1235 out = kzalloc(out_sz, GFP_KERNEL);
1236
1237 MLX5_SET(query_hca_vport_pkey_in, in, opcode,
1238 MLX5_CMD_OP_QUERY_HCA_VPORT_PKEY);
1239 if (other_vport) {
1240 if (is_group_manager) {
1241 MLX5_SET(query_hca_vport_pkey_in, in, vport_number,
1242 vf_num);
1243 MLX5_SET(query_hca_vport_pkey_in, in, other_vport, 1);
1244 } else {
1245 err = -EPERM;
1246 goto out;
1247 }
1248 }
1249 MLX5_SET(query_hca_vport_pkey_in, in, pkey_index, pkey_index);
1250
1251 if (MLX5_CAP_GEN(dev, num_ports) == 2)
1252 MLX5_SET(query_hca_vport_pkey_in, in, port_num, port_num);
1253
1254 err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
1255 if (err)
1256 goto out;
1257
1258 pkarr = MLX5_ADDR_OF(query_hca_vport_pkey_out, out, pkey);
1259 for (i = 0; i < nout; i++, pkey++,
1260 pkarr += MLX5_ST_SZ_BYTES(pkey))
1261 *pkey = MLX5_GET_PR(pkey, pkarr, pkey);
1262
1263 out:
1264 kfree(in);
1265 kfree(out);
1266 return err;
1267 }
1268 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_pkey);
1269
mlx5_query_hca_min_wqe_header(struct mlx5_core_dev * mdev,int * min_header)1270 static int mlx5_query_hca_min_wqe_header(struct mlx5_core_dev *mdev,
1271 int *min_header)
1272 {
1273 u32 *out;
1274 u32 outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
1275 int err;
1276
1277 out = mlx5_vzalloc(outlen);
1278 if (!out)
1279 return -ENOMEM;
1280
1281 err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen);
1282 if (err)
1283 goto out;
1284
1285 *min_header = MLX5_GET(query_hca_vport_context_out, out,
1286 hca_vport_context.min_wqe_inline_mode);
1287
1288 out:
1289 kvfree(out);
1290 return err;
1291 }
1292
mlx5_modify_eswitch_vport_context(struct mlx5_core_dev * mdev,u16 vport,void * in,int inlen)1293 static int mlx5_modify_eswitch_vport_context(struct mlx5_core_dev *mdev,
1294 u16 vport, void *in, int inlen)
1295 {
1296 u32 out[MLX5_ST_SZ_DW(modify_esw_vport_context_out)] = {0};
1297 int err;
1298
1299 MLX5_SET(modify_esw_vport_context_in, in, vport_number, vport);
1300 if (vport)
1301 MLX5_SET(modify_esw_vport_context_in, in, other_vport, 1);
1302
1303 MLX5_SET(modify_esw_vport_context_in, in, opcode,
1304 MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT);
1305
1306 err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
1307 if (err)
1308 mlx5_core_warn(mdev, "MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT failed\n");
1309
1310 return err;
1311 }
1312
mlx5_set_eswitch_cvlan_info(struct mlx5_core_dev * mdev,u8 vport,u8 insert_mode,u8 strip_mode,u16 vlan,u8 cfi,u8 pcp)1313 int mlx5_set_eswitch_cvlan_info(struct mlx5_core_dev *mdev, u8 vport,
1314 u8 insert_mode, u8 strip_mode,
1315 u16 vlan, u8 cfi, u8 pcp)
1316 {
1317 u32 in[MLX5_ST_SZ_DW(modify_esw_vport_context_in)];
1318
1319 memset(in, 0, sizeof(in));
1320
1321 if (insert_mode != MLX5_MODIFY_ESW_VPORT_CONTEXT_CVLAN_INSERT_NONE) {
1322 MLX5_SET(modify_esw_vport_context_in, in,
1323 esw_vport_context.cvlan_cfi, cfi);
1324 MLX5_SET(modify_esw_vport_context_in, in,
1325 esw_vport_context.cvlan_pcp, pcp);
1326 MLX5_SET(modify_esw_vport_context_in, in,
1327 esw_vport_context.cvlan_id, vlan);
1328 }
1329
1330 MLX5_SET(modify_esw_vport_context_in, in,
1331 esw_vport_context.vport_cvlan_insert, insert_mode);
1332
1333 MLX5_SET(modify_esw_vport_context_in, in,
1334 esw_vport_context.vport_cvlan_strip, strip_mode);
1335
1336 MLX5_SET(modify_esw_vport_context_in, in, field_select,
1337 MLX5_MODIFY_ESW_VPORT_CONTEXT_FIELD_SELECT_CVLAN_STRIP |
1338 MLX5_MODIFY_ESW_VPORT_CONTEXT_FIELD_SELECT_CVLAN_INSERT);
1339
1340 return mlx5_modify_eswitch_vport_context(mdev, vport, in, sizeof(in));
1341 }
1342 EXPORT_SYMBOL_GPL(mlx5_set_eswitch_cvlan_info);
1343
mlx5_query_vport_mtu(struct mlx5_core_dev * mdev,int * mtu)1344 int mlx5_query_vport_mtu(struct mlx5_core_dev *mdev, int *mtu)
1345 {
1346 u32 *out;
1347 u32 outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
1348 int err;
1349
1350 out = mlx5_vzalloc(outlen);
1351 if (!out)
1352 return -ENOMEM;
1353
1354 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
1355 if (err)
1356 goto out;
1357
1358 *mtu = MLX5_GET(query_nic_vport_context_out, out,
1359 nic_vport_context.mtu);
1360
1361 out:
1362 kvfree(out);
1363 return err;
1364 }
1365 EXPORT_SYMBOL_GPL(mlx5_query_vport_mtu);
1366
mlx5_set_vport_mtu(struct mlx5_core_dev * mdev,int mtu)1367 int mlx5_set_vport_mtu(struct mlx5_core_dev *mdev, int mtu)
1368 {
1369 u32 *in;
1370 u32 inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
1371 int err;
1372
1373 in = mlx5_vzalloc(inlen);
1374 if (!in)
1375 return -ENOMEM;
1376
1377 MLX5_SET(modify_nic_vport_context_in, in, field_select.mtu, 1);
1378 MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.mtu, mtu);
1379
1380 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
1381
1382 kvfree(in);
1383 return err;
1384 }
1385 EXPORT_SYMBOL_GPL(mlx5_set_vport_mtu);
1386
mlx5_query_vport_min_wqe_header(struct mlx5_core_dev * mdev,int * min_header)1387 static int mlx5_query_vport_min_wqe_header(struct mlx5_core_dev *mdev,
1388 int *min_header)
1389 {
1390 u32 *out;
1391 u32 outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
1392 int err;
1393
1394 out = mlx5_vzalloc(outlen);
1395 if (!out)
1396 return -ENOMEM;
1397
1398 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
1399 if (err)
1400 goto out;
1401
1402 *min_header = MLX5_GET(query_nic_vport_context_out, out,
1403 nic_vport_context.min_wqe_inline_mode);
1404
1405 out:
1406 kvfree(out);
1407 return err;
1408 }
1409
mlx5_set_vport_min_wqe_header(struct mlx5_core_dev * mdev,u8 vport,int min_header)1410 int mlx5_set_vport_min_wqe_header(struct mlx5_core_dev *mdev,
1411 u8 vport, int min_header)
1412 {
1413 u32 *in;
1414 u32 inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
1415 int err;
1416
1417 in = mlx5_vzalloc(inlen);
1418 if (!in)
1419 return -ENOMEM;
1420
1421 MLX5_SET(modify_nic_vport_context_in, in,
1422 field_select.min_wqe_inline_mode, 1);
1423 MLX5_SET(modify_nic_vport_context_in, in,
1424 nic_vport_context.min_wqe_inline_mode, min_header);
1425 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
1426 MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
1427
1428 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
1429
1430 kvfree(in);
1431 return err;
1432 }
1433 EXPORT_SYMBOL_GPL(mlx5_set_vport_min_wqe_header);
1434
mlx5_query_min_wqe_header(struct mlx5_core_dev * dev,int * min_header)1435 int mlx5_query_min_wqe_header(struct mlx5_core_dev *dev, int *min_header)
1436 {
1437 switch (MLX5_CAP_GEN(dev, port_type)) {
1438 case MLX5_CMD_HCA_CAP_PORT_TYPE_IB:
1439 return mlx5_query_hca_min_wqe_header(dev, min_header);
1440
1441 case MLX5_CMD_HCA_CAP_PORT_TYPE_ETHERNET:
1442 return mlx5_query_vport_min_wqe_header(dev, min_header);
1443
1444 default:
1445 return -EINVAL;
1446 }
1447 }
1448 EXPORT_SYMBOL_GPL(mlx5_query_min_wqe_header);
1449
mlx5_query_nic_vport_promisc(struct mlx5_core_dev * mdev,u16 vport,int * promisc_uc,int * promisc_mc,int * promisc_all)1450 int mlx5_query_nic_vport_promisc(struct mlx5_core_dev *mdev,
1451 u16 vport,
1452 int *promisc_uc,
1453 int *promisc_mc,
1454 int *promisc_all)
1455 {
1456 u32 *out;
1457 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
1458 int err;
1459
1460 out = kzalloc(outlen, GFP_KERNEL);
1461 if (!out)
1462 return -ENOMEM;
1463
1464 err = mlx5_query_nic_vport_context(mdev, vport, out, outlen);
1465 if (err)
1466 goto out;
1467
1468 *promisc_uc = MLX5_GET(query_nic_vport_context_out, out,
1469 nic_vport_context.promisc_uc);
1470 *promisc_mc = MLX5_GET(query_nic_vport_context_out, out,
1471 nic_vport_context.promisc_mc);
1472 *promisc_all = MLX5_GET(query_nic_vport_context_out, out,
1473 nic_vport_context.promisc_all);
1474
1475 out:
1476 kfree(out);
1477 return err;
1478 }
1479 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_promisc);
1480
mlx5_modify_nic_vport_promisc(struct mlx5_core_dev * mdev,int promisc_uc,int promisc_mc,int promisc_all)1481 int mlx5_modify_nic_vport_promisc(struct mlx5_core_dev *mdev,
1482 int promisc_uc,
1483 int promisc_mc,
1484 int promisc_all)
1485 {
1486 void *in;
1487 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
1488 int err;
1489
1490 in = mlx5_vzalloc(inlen);
1491 if (!in) {
1492 mlx5_core_err(mdev, "failed to allocate inbox\n");
1493 return -ENOMEM;
1494 }
1495
1496 MLX5_SET(modify_nic_vport_context_in, in, field_select.promisc, 1);
1497 MLX5_SET(modify_nic_vport_context_in, in,
1498 nic_vport_context.promisc_uc, promisc_uc);
1499 MLX5_SET(modify_nic_vport_context_in, in,
1500 nic_vport_context.promisc_mc, promisc_mc);
1501 MLX5_SET(modify_nic_vport_context_in, in,
1502 nic_vport_context.promisc_all, promisc_all);
1503
1504 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
1505 kvfree(in);
1506 return err;
1507 }
1508 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_promisc);
1509
mlx5_nic_vport_modify_local_lb(struct mlx5_core_dev * mdev,enum mlx5_local_lb_selection selection,u8 value)1510 int mlx5_nic_vport_modify_local_lb(struct mlx5_core_dev *mdev,
1511 enum mlx5_local_lb_selection selection,
1512 u8 value)
1513 {
1514 void *in;
1515 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
1516 int err;
1517
1518 in = mlx5_vzalloc(inlen);
1519 if (!in) {
1520 mlx5_core_warn(mdev, "failed to allocate inbox\n");
1521 return -ENOMEM;
1522 }
1523
1524 MLX5_SET(modify_nic_vport_context_in, in, vport_number, 0);
1525
1526 if (selection == MLX5_LOCAL_MC_LB) {
1527 MLX5_SET(modify_nic_vport_context_in, in,
1528 field_select.disable_mc_local_lb, 1);
1529 MLX5_SET(modify_nic_vport_context_in, in,
1530 nic_vport_context.disable_mc_local_lb,
1531 value);
1532 } else {
1533 MLX5_SET(modify_nic_vport_context_in, in,
1534 field_select.disable_uc_local_lb, 1);
1535 MLX5_SET(modify_nic_vport_context_in, in,
1536 nic_vport_context.disable_uc_local_lb,
1537 value);
1538 }
1539
1540 err = mlx5_modify_nic_vport_context(mdev, in, inlen);
1541
1542 kvfree(in);
1543 return err;
1544 }
1545 EXPORT_SYMBOL_GPL(mlx5_nic_vport_modify_local_lb);
1546
mlx5_nic_vport_query_local_lb(struct mlx5_core_dev * mdev,enum mlx5_local_lb_selection selection,u8 * value)1547 int mlx5_nic_vport_query_local_lb(struct mlx5_core_dev *mdev,
1548 enum mlx5_local_lb_selection selection,
1549 u8 *value)
1550 {
1551 void *out;
1552 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
1553 int err;
1554
1555 out = kzalloc(outlen, GFP_KERNEL);
1556 if (!out)
1557 return -ENOMEM;
1558
1559 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
1560 if (err)
1561 goto done;
1562
1563 if (selection == MLX5_LOCAL_MC_LB)
1564 *value = MLX5_GET(query_nic_vport_context_out, out,
1565 nic_vport_context.disable_mc_local_lb);
1566 else
1567 *value = MLX5_GET(query_nic_vport_context_out, out,
1568 nic_vport_context.disable_uc_local_lb);
1569
1570 done:
1571 kfree(out);
1572 return err;
1573 }
1574 EXPORT_SYMBOL_GPL(mlx5_nic_vport_query_local_lb);
1575
mlx5_query_vport_counter(struct mlx5_core_dev * dev,u8 port_num,u16 vport_num,void * out,int out_size)1576 int mlx5_query_vport_counter(struct mlx5_core_dev *dev,
1577 u8 port_num, u16 vport_num,
1578 void *out, int out_size)
1579 {
1580 int in_sz = MLX5_ST_SZ_BYTES(query_vport_counter_in);
1581 int is_group_manager;
1582 void *in;
1583 int err;
1584
1585 is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
1586
1587 in = mlx5_vzalloc(in_sz);
1588 if (!in)
1589 return -ENOMEM;
1590
1591 MLX5_SET(query_vport_counter_in, in, opcode,
1592 MLX5_CMD_OP_QUERY_VPORT_COUNTER);
1593 if (vport_num) {
1594 if (is_group_manager) {
1595 MLX5_SET(query_vport_counter_in, in, other_vport, 1);
1596 MLX5_SET(query_vport_counter_in, in, vport_number,
1597 vport_num);
1598 } else {
1599 err = -EPERM;
1600 goto ex;
1601 }
1602 }
1603 if (MLX5_CAP_GEN(dev, num_ports) == 2)
1604 MLX5_SET(query_vport_counter_in, in, port_num, port_num);
1605
1606 err = mlx5_cmd_exec(dev, in, in_sz, out, out_size);
1607
1608 ex:
1609 kvfree(in);
1610 return err;
1611 }
1612 EXPORT_SYMBOL_GPL(mlx5_query_vport_counter);
1613
mlx5_get_vport_counters(struct mlx5_core_dev * dev,u8 port_num,struct mlx5_vport_counters * vc)1614 int mlx5_get_vport_counters(struct mlx5_core_dev *dev, u8 port_num,
1615 struct mlx5_vport_counters *vc)
1616 {
1617 int out_sz = MLX5_ST_SZ_BYTES(query_vport_counter_out);
1618 void *out;
1619 int err;
1620
1621 out = mlx5_vzalloc(out_sz);
1622 if (!out)
1623 return -ENOMEM;
1624
1625 err = mlx5_query_vport_counter(dev, port_num, 0, out, out_sz);
1626 if (err)
1627 goto ex;
1628
1629 vc->received_errors.packets =
1630 MLX5_GET64(query_vport_counter_out,
1631 out, received_errors.packets);
1632 vc->received_errors.octets =
1633 MLX5_GET64(query_vport_counter_out,
1634 out, received_errors.octets);
1635 vc->transmit_errors.packets =
1636 MLX5_GET64(query_vport_counter_out,
1637 out, transmit_errors.packets);
1638 vc->transmit_errors.octets =
1639 MLX5_GET64(query_vport_counter_out,
1640 out, transmit_errors.octets);
1641 vc->received_ib_unicast.packets =
1642 MLX5_GET64(query_vport_counter_out,
1643 out, received_ib_unicast.packets);
1644 vc->received_ib_unicast.octets =
1645 MLX5_GET64(query_vport_counter_out,
1646 out, received_ib_unicast.octets);
1647 vc->transmitted_ib_unicast.packets =
1648 MLX5_GET64(query_vport_counter_out,
1649 out, transmitted_ib_unicast.packets);
1650 vc->transmitted_ib_unicast.octets =
1651 MLX5_GET64(query_vport_counter_out,
1652 out, transmitted_ib_unicast.octets);
1653 vc->received_ib_multicast.packets =
1654 MLX5_GET64(query_vport_counter_out,
1655 out, received_ib_multicast.packets);
1656 vc->received_ib_multicast.octets =
1657 MLX5_GET64(query_vport_counter_out,
1658 out, received_ib_multicast.octets);
1659 vc->transmitted_ib_multicast.packets =
1660 MLX5_GET64(query_vport_counter_out,
1661 out, transmitted_ib_multicast.packets);
1662 vc->transmitted_ib_multicast.octets =
1663 MLX5_GET64(query_vport_counter_out,
1664 out, transmitted_ib_multicast.octets);
1665 vc->received_eth_broadcast.packets =
1666 MLX5_GET64(query_vport_counter_out,
1667 out, received_eth_broadcast.packets);
1668 vc->received_eth_broadcast.octets =
1669 MLX5_GET64(query_vport_counter_out,
1670 out, received_eth_broadcast.octets);
1671 vc->transmitted_eth_broadcast.packets =
1672 MLX5_GET64(query_vport_counter_out,
1673 out, transmitted_eth_broadcast.packets);
1674 vc->transmitted_eth_broadcast.octets =
1675 MLX5_GET64(query_vport_counter_out,
1676 out, transmitted_eth_broadcast.octets);
1677 vc->received_eth_unicast.octets =
1678 MLX5_GET64(query_vport_counter_out,
1679 out, received_eth_unicast.octets);
1680 vc->received_eth_unicast.packets =
1681 MLX5_GET64(query_vport_counter_out,
1682 out, received_eth_unicast.packets);
1683 vc->transmitted_eth_unicast.octets =
1684 MLX5_GET64(query_vport_counter_out,
1685 out, transmitted_eth_unicast.octets);
1686 vc->transmitted_eth_unicast.packets =
1687 MLX5_GET64(query_vport_counter_out,
1688 out, transmitted_eth_unicast.packets);
1689 vc->received_eth_multicast.octets =
1690 MLX5_GET64(query_vport_counter_out,
1691 out, received_eth_multicast.octets);
1692 vc->received_eth_multicast.packets =
1693 MLX5_GET64(query_vport_counter_out,
1694 out, received_eth_multicast.packets);
1695 vc->transmitted_eth_multicast.octets =
1696 MLX5_GET64(query_vport_counter_out,
1697 out, transmitted_eth_multicast.octets);
1698 vc->transmitted_eth_multicast.packets =
1699 MLX5_GET64(query_vport_counter_out,
1700 out, transmitted_eth_multicast.packets);
1701
1702 ex:
1703 kvfree(out);
1704 return err;
1705 }
1706
mlx5_query_vport_system_image_guid(struct mlx5_core_dev * dev,u64 * sys_image_guid)1707 int mlx5_query_vport_system_image_guid(struct mlx5_core_dev *dev,
1708 u64 *sys_image_guid)
1709 {
1710 switch (MLX5_CAP_GEN(dev, port_type)) {
1711 case MLX5_CMD_HCA_CAP_PORT_TYPE_IB:
1712 return mlx5_query_hca_vport_system_image_guid(dev,
1713 sys_image_guid);
1714
1715 case MLX5_CMD_HCA_CAP_PORT_TYPE_ETHERNET:
1716 return mlx5_query_nic_vport_system_image_guid(dev,
1717 sys_image_guid);
1718
1719 default:
1720 return -EINVAL;
1721 }
1722 }
1723 EXPORT_SYMBOL_GPL(mlx5_query_vport_system_image_guid);
1724
mlx5_query_vport_node_guid(struct mlx5_core_dev * dev,u64 * node_guid)1725 int mlx5_query_vport_node_guid(struct mlx5_core_dev *dev, u64 *node_guid)
1726 {
1727 switch (MLX5_CAP_GEN(dev, port_type)) {
1728 case MLX5_CMD_HCA_CAP_PORT_TYPE_IB:
1729 return mlx5_query_hca_vport_node_guid(dev, node_guid);
1730
1731 case MLX5_CMD_HCA_CAP_PORT_TYPE_ETHERNET:
1732 return mlx5_query_nic_vport_node_guid(dev, node_guid);
1733
1734 default:
1735 return -EINVAL;
1736 }
1737 }
1738 EXPORT_SYMBOL_GPL(mlx5_query_vport_node_guid);
1739
mlx5_query_vport_port_guid(struct mlx5_core_dev * dev,u64 * port_guid)1740 int mlx5_query_vport_port_guid(struct mlx5_core_dev *dev, u64 *port_guid)
1741 {
1742 switch (MLX5_CAP_GEN(dev, port_type)) {
1743 case MLX5_CMD_HCA_CAP_PORT_TYPE_IB:
1744 return mlx5_query_hca_vport_port_guid(dev, port_guid);
1745
1746 case MLX5_CMD_HCA_CAP_PORT_TYPE_ETHERNET:
1747 return mlx5_query_nic_vport_port_guid(dev, port_guid);
1748
1749 default:
1750 return -EINVAL;
1751 }
1752 }
1753 EXPORT_SYMBOL_GPL(mlx5_query_vport_port_guid);
1754
mlx5_query_hca_vport_state(struct mlx5_core_dev * dev,u8 * vport_state)1755 int mlx5_query_hca_vport_state(struct mlx5_core_dev *dev, u8 *vport_state)
1756 {
1757 u32 *out;
1758 int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
1759 int err;
1760
1761 out = mlx5_vzalloc(outlen);
1762 if (!out)
1763 return -ENOMEM;
1764
1765 err = mlx5_query_hca_vport_context(dev, 1, 0, out, outlen);
1766 if (err)
1767 goto out;
1768
1769 *vport_state = MLX5_GET(query_hca_vport_context_out, out,
1770 hca_vport_context.vport_state);
1771
1772 out:
1773 kvfree(out);
1774 return err;
1775 }
1776 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_state);
1777
mlx5_core_query_ib_ppcnt(struct mlx5_core_dev * dev,u8 port_num,void * out,size_t sz)1778 int mlx5_core_query_ib_ppcnt(struct mlx5_core_dev *dev,
1779 u8 port_num, void *out, size_t sz)
1780 {
1781 u32 *in;
1782 int err;
1783
1784 in = mlx5_vzalloc(sz);
1785 if (!in) {
1786 err = -ENOMEM;
1787 return err;
1788 }
1789
1790 MLX5_SET(ppcnt_reg, in, local_port, port_num);
1791
1792 MLX5_SET(ppcnt_reg, in, grp, MLX5_INFINIBAND_PORT_COUNTERS_GROUP);
1793 err = mlx5_core_access_reg(dev, in, sz, out,
1794 sz, MLX5_REG_PPCNT, 0, 0);
1795
1796 kvfree(in);
1797 return err;
1798 }
1799