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