mlx5_vport.c revision 292196
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 292196 2015-12-14 10:31:03Z 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 33u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod) 34{ 35 u32 in[MLX5_ST_SZ_DW(query_vport_state_in)]; 36 u32 out[MLX5_ST_SZ_DW(query_vport_state_out)]; 37 int err; 38 39 memset(in, 0, sizeof(in)); 40 41 MLX5_SET(query_vport_state_in, in, opcode, 42 MLX5_CMD_OP_QUERY_VPORT_STATE); 43 MLX5_SET(query_vport_state_in, in, op_mod, opmod); 44 45 err = mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out, 46 sizeof(out)); 47 if (err) 48 mlx5_core_warn(mdev, "MLX5_CMD_OP_QUERY_VPORT_STATE failed\n"); 49 50 return MLX5_GET(query_vport_state_out, out, state); 51} 52EXPORT_SYMBOL_GPL(mlx5_query_vport_state); 53 54static int mlx5_query_nic_vport_context(struct mlx5_core_dev *mdev, u32 vport, 55 u32 *out, int outlen) 56{ 57 u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)]; 58 59 memset(in, 0, sizeof(in)); 60 61 MLX5_SET(query_nic_vport_context_in, in, opcode, 62 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT); 63 64 MLX5_SET(query_nic_vport_context_in, in, vport_number, vport); 65 if (vport) 66 MLX5_SET(query_nic_vport_context_in, in, other_vport, 1); 67 68 return mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out, outlen); 69} 70 71int mlx5_vport_alloc_q_counter(struct mlx5_core_dev *mdev, int *counter_set_id) 72{ 73 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)]; 74 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_in)]; 75 int err; 76 77 memset(in, 0, sizeof(in)); 78 memset(out, 0, sizeof(out)); 79 80 MLX5_SET(alloc_q_counter_in, in, opcode, 81 MLX5_CMD_OP_ALLOC_Q_COUNTER); 82 83 err = mlx5_cmd_exec_check_status(mdev, in, sizeof(in), 84 out, sizeof(out)); 85 86 if (err) 87 return err; 88 89 *counter_set_id = MLX5_GET(alloc_q_counter_out, out, 90 counter_set_id); 91 return err; 92} 93 94int mlx5_vport_dealloc_q_counter(struct mlx5_core_dev *mdev, 95 int counter_set_id) 96{ 97 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)]; 98 u32 out[MLX5_ST_SZ_DW(dealloc_q_counter_out)]; 99 100 memset(in, 0, sizeof(in)); 101 memset(out, 0, sizeof(out)); 102 103 MLX5_SET(dealloc_q_counter_in, in, opcode, 104 MLX5_CMD_OP_DEALLOC_Q_COUNTER); 105 MLX5_SET(dealloc_q_counter_in, in, counter_set_id, 106 counter_set_id); 107 108 return mlx5_cmd_exec_check_status(mdev, in, sizeof(in), 109 out, sizeof(out)); 110} 111 112static int mlx5_vport_query_q_counter(struct mlx5_core_dev *mdev, 113 int counter_set_id, 114 int reset, 115 void *out, 116 int out_size) 117{ 118 u32 in[MLX5_ST_SZ_DW(query_q_counter_in)]; 119 120 memset(in, 0, sizeof(in)); 121 122 MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER); 123 MLX5_SET(query_q_counter_in, in, clear, reset); 124 MLX5_SET(query_q_counter_in, in, counter_set_id, counter_set_id); 125 126 return mlx5_cmd_exec_check_status(mdev, in, sizeof(in), 127 out, out_size); 128} 129 130int mlx5_vport_query_out_of_rx_buffer(struct mlx5_core_dev *mdev, 131 int counter_set_id, 132 u32 *out_of_rx_buffer) 133{ 134 u32 out[MLX5_ST_SZ_DW(query_q_counter_out)]; 135 int err; 136 137 memset(out, 0, sizeof(out)); 138 139 err = mlx5_vport_query_q_counter(mdev, counter_set_id, 0, out, 140 sizeof(out)); 141 142 if (err) 143 return err; 144 145 *out_of_rx_buffer = MLX5_GET(query_q_counter_out, out, 146 out_of_buffer); 147 return err; 148} 149 150int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, 151 u32 vport, u8 *addr) 152{ 153 u32 *out; 154 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); 155 u8 *out_addr; 156 int err; 157 158 out = mlx5_vzalloc(outlen); 159 if (!out) 160 return -ENOMEM; 161 162 out_addr = MLX5_ADDR_OF(query_nic_vport_context_out, out, 163 nic_vport_context.permanent_address); 164 165 err = mlx5_query_nic_vport_context(mdev, vport, out, outlen); 166 if (err) 167 goto out; 168 169 ether_addr_copy(addr, &out_addr[2]); 170 171out: 172 kvfree(out); 173 return err; 174} 175EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_address); 176 177int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev, 178 u64 *system_image_guid) 179{ 180 u32 *out; 181 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); 182 int err; 183 184 out = mlx5_vzalloc(outlen); 185 if (!out) 186 return -ENOMEM; 187 188 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen); 189 if (err) 190 goto out; 191 192 *system_image_guid = MLX5_GET64(query_nic_vport_context_out, out, 193 nic_vport_context.system_image_guid); 194out: 195 kvfree(out); 196 return err; 197} 198EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_system_image_guid); 199 200int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid) 201{ 202 u32 *out; 203 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); 204 int err; 205 206 out = mlx5_vzalloc(outlen); 207 if (!out) 208 return -ENOMEM; 209 210 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen); 211 if (err) 212 goto out; 213 214 *node_guid = MLX5_GET64(query_nic_vport_context_out, out, 215 nic_vport_context.node_guid); 216 217out: 218 kvfree(out); 219 return err; 220} 221EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_node_guid); 222 223int mlx5_query_nic_vport_port_guid(struct mlx5_core_dev *mdev, u64 *port_guid) 224{ 225 u32 *out; 226 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); 227 int err; 228 229 out = mlx5_vzalloc(outlen); 230 if (!out) 231 return -ENOMEM; 232 233 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen); 234 if (err) 235 goto out; 236 237 *port_guid = MLX5_GET64(query_nic_vport_context_out, out, 238 nic_vport_context.port_guid); 239 240out: 241 kvfree(out); 242 return err; 243} 244EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_port_guid); 245 246int mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev *mdev, 247 u16 *qkey_viol_cntr) 248{ 249 u32 *out; 250 int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); 251 int err; 252 253 out = mlx5_vzalloc(outlen); 254 if (!out) 255 return -ENOMEM; 256 257 err = mlx5_query_nic_vport_context(mdev, 0, out, outlen); 258 if (err) 259 goto out; 260 261 *qkey_viol_cntr = MLX5_GET(query_nic_vport_context_out, out, 262 nic_vport_context.qkey_violation_counter); 263 264out: 265 kvfree(out); 266 return err; 267} 268EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_qkey_viol_cntr); 269 270static int mlx5_modify_nic_vport_context(struct mlx5_core_dev *mdev, void *in, 271 int inlen) 272{ 273 u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)]; 274 275 MLX5_SET(modify_nic_vport_context_in, in, opcode, 276 MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT); 277 278 memset(out, 0, sizeof(out)); 279 return mlx5_cmd_exec_check_status(mdev, in, inlen, out, sizeof(out)); 280} 281 282static int mlx5_nic_vport_enable_disable_roce(struct mlx5_core_dev *mdev, 283 int enable_disable) 284{ 285 void *in; 286 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in); 287 int err; 288 289 in = mlx5_vzalloc(inlen); 290 if (!in) { 291 mlx5_core_warn(mdev, "failed to allocate inbox\n"); 292 return -ENOMEM; 293 } 294 295 MLX5_SET(modify_nic_vport_context_in, in, field_select.roce_en, 1); 296 MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.roce_en, 297 enable_disable); 298 299 err = mlx5_modify_nic_vport_context(mdev, in, inlen); 300 301 kvfree(in); 302 303 return err; 304} 305 306int mlx5_set_nic_vport_current_mac(struct mlx5_core_dev *mdev, int vport, 307 bool other_vport, u8 *addr) 308{ 309 void *in; 310 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) 311 + MLX5_ST_SZ_BYTES(mac_address_layout); 312 u8 *mac_layout; 313 u8 *mac_ptr; 314 int err; 315 316 in = mlx5_vzalloc(inlen); 317 if (!in) { 318 mlx5_core_warn(mdev, "failed to allocate inbox\n"); 319 return -ENOMEM; 320 } 321 322 MLX5_SET(modify_nic_vport_context_in, in, 323 opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT); 324 MLX5_SET(modify_nic_vport_context_in, in, 325 vport_number, vport); 326 MLX5_SET(modify_nic_vport_context_in, in, 327 other_vport, other_vport); 328 MLX5_SET(modify_nic_vport_context_in, in, 329 field_select.addresses_list, 1); 330 MLX5_SET(modify_nic_vport_context_in, in, 331 nic_vport_context.allowed_list_type, 332 MLX5_NIC_VPORT_LIST_TYPE_UC); 333 MLX5_SET(modify_nic_vport_context_in, in, 334 nic_vport_context.allowed_list_size, 1); 335 336 mac_layout = (u8 *)MLX5_ADDR_OF(modify_nic_vport_context_in, in, 337 nic_vport_context.current_uc_mac_address); 338 mac_ptr = (u8 *)MLX5_ADDR_OF(mac_address_layout, mac_layout, 339 mac_addr_47_32); 340 ether_addr_copy(mac_ptr, addr); 341 342 err = mlx5_modify_nic_vport_context(mdev, in, inlen); 343 344 kvfree(in); 345 346 return err; 347} 348EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_current_mac); 349 350int mlx5_set_nic_vport_vlan_list(struct mlx5_core_dev *dev, u32 vport, 351 u16 *vlan_list, int list_len) 352{ 353 void *in, *ctx; 354 int i, err; 355 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) 356 + MLX5_ST_SZ_BYTES(vlan_layout) * (int)list_len; 357 358 int max_list_size = 1 << MLX5_CAP_GEN_MAX(dev, log_max_vlan_list); 359 360 if (list_len > max_list_size) { 361 mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n", 362 list_len, max_list_size); 363 return -ENOSPC; 364 } 365 366 in = mlx5_vzalloc(inlen); 367 if (!in) { 368 mlx5_core_warn(dev, "failed to allocate inbox\n"); 369 return -ENOMEM; 370 } 371 372 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); 373 if (vport) 374 MLX5_SET(modify_nic_vport_context_in, in, 375 other_vport, 1); 376 MLX5_SET(modify_nic_vport_context_in, in, 377 field_select.addresses_list, 1); 378 379 ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context); 380 381 MLX5_SET(nic_vport_context, ctx, allowed_list_type, 382 MLX5_NIC_VPORT_LIST_TYPE_VLAN); 383 MLX5_SET(nic_vport_context, ctx, allowed_list_size, list_len); 384 385 for (i = 0; i < list_len; i++) { 386 u8 *vlan_lout = MLX5_ADDR_OF(nic_vport_context, ctx, 387 current_uc_mac_address[i]); 388 MLX5_SET(vlan_layout, vlan_lout, vlan, vlan_list[i]); 389 } 390 391 err = mlx5_modify_nic_vport_context(dev, in, inlen); 392 393 kvfree(in); 394 return err; 395} 396EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_vlan_list); 397 398int mlx5_set_nic_vport_mc_list(struct mlx5_core_dev *mdev, int vport, 399 u64 *addr_list, size_t addr_list_len) 400{ 401 void *in, *ctx; 402 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) 403 + MLX5_ST_SZ_BYTES(mac_address_layout) * (int)addr_list_len; 404 int err; 405 size_t i; 406 int max_list_sz = 1 << MLX5_CAP_GEN_MAX(mdev, log_max_current_mc_list); 407 408 if ((int)addr_list_len > max_list_sz) { 409 mlx5_core_warn(mdev, "Requested list size (%d) > (%d) max_list_size\n", 410 (int)addr_list_len, max_list_sz); 411 return -ENOSPC; 412 } 413 414 in = mlx5_vzalloc(inlen); 415 if (!in) { 416 mlx5_core_warn(mdev, "failed to allocate inbox\n"); 417 return -ENOMEM; 418 } 419 420 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); 421 if (vport) 422 MLX5_SET(modify_nic_vport_context_in, in, 423 other_vport, 1); 424 MLX5_SET(modify_nic_vport_context_in, in, 425 field_select.addresses_list, 1); 426 427 ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context); 428 429 MLX5_SET(nic_vport_context, ctx, allowed_list_type, 430 MLX5_NIC_VPORT_LIST_TYPE_MC); 431 MLX5_SET(nic_vport_context, ctx, allowed_list_size, addr_list_len); 432 433 for (i = 0; i < addr_list_len; i++) { 434 u8 *mac_lout = (u8 *)MLX5_ADDR_OF(nic_vport_context, ctx, 435 current_uc_mac_address[i]); 436 u8 *mac_ptr = (u8 *)MLX5_ADDR_OF(mac_address_layout, mac_lout, 437 mac_addr_47_32); 438 ether_addr_copy(mac_ptr, (u8 *)&addr_list[i]); 439 } 440 441 err = mlx5_modify_nic_vport_context(mdev, in, inlen); 442 443 kvfree(in); 444 445 return err; 446} 447EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_mc_list); 448 449int mlx5_set_nic_vport_promisc(struct mlx5_core_dev *mdev, int vport, 450 bool promisc_mc, bool promisc_uc, 451 bool promisc_all) 452{ 453 u8 in[MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)]; 454 u8 *ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, 455 nic_vport_context); 456 457 memset(in, 0, MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)); 458 459 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); 460 if (vport) 461 MLX5_SET(modify_nic_vport_context_in, in, 462 other_vport, 1); 463 MLX5_SET(modify_nic_vport_context_in, in, field_select.promisc, 1); 464 if (promisc_mc) 465 MLX5_SET(nic_vport_context, ctx, promisc_mc, 1); 466 if (promisc_uc) 467 MLX5_SET(nic_vport_context, ctx, promisc_uc, 1); 468 if (promisc_all) 469 MLX5_SET(nic_vport_context, ctx, promisc_all, 1); 470 471 return mlx5_modify_nic_vport_context(mdev, in, sizeof(in)); 472} 473EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_promisc); 474int mlx5_set_nic_vport_permanent_mac(struct mlx5_core_dev *mdev, int vport, 475 u8 *addr) 476{ 477 void *in; 478 int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in); 479 u8 *mac_ptr; 480 int err; 481 482 in = mlx5_vzalloc(inlen); 483 if (!in) { 484 mlx5_core_warn(mdev, "failed to allocate inbox\n"); 485 return -ENOMEM; 486 } 487 488 MLX5_SET(modify_nic_vport_context_in, in, 489 opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT); 490 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); 491 MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1); 492 MLX5_SET(modify_nic_vport_context_in, in, 493 field_select.permanent_address, 1); 494 mac_ptr = (u8 *)MLX5_ADDR_OF(modify_nic_vport_context_in, in, 495 nic_vport_context.permanent_address.mac_addr_47_32); 496 ether_addr_copy(mac_ptr, addr); 497 498 err = mlx5_modify_nic_vport_context(mdev, in, inlen); 499 500 kvfree(in); 501 502 return err; 503} 504EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_permanent_mac); 505 506int mlx5_nic_vport_enable_roce(struct mlx5_core_dev *mdev) 507{ 508 return mlx5_nic_vport_enable_disable_roce(mdev, 1); 509} 510EXPORT_SYMBOL_GPL(mlx5_nic_vport_enable_roce); 511 512int mlx5_nic_vport_disable_roce(struct mlx5_core_dev *mdev) 513{ 514 return mlx5_nic_vport_enable_disable_roce(mdev, 0); 515} 516EXPORT_SYMBOL_GPL(mlx5_nic_vport_disable_roce); 517 518int mlx5_query_hca_vport_context(struct mlx5_core_dev *mdev, 519 u8 port_num, u8 vport_num, u32 *out, 520 int outlen) 521{ 522 u32 in[MLX5_ST_SZ_DW(query_hca_vport_context_in)]; 523 int is_group_manager; 524 525 is_group_manager = MLX5_CAP_GEN(mdev, vport_group_manager); 526 527 memset(in, 0, sizeof(in)); 528 529 MLX5_SET(query_hca_vport_context_in, in, opcode, 530 MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT); 531 532 if (vport_num) { 533 if (is_group_manager) { 534 MLX5_SET(query_hca_vport_context_in, in, other_vport, 535 1); 536 MLX5_SET(query_hca_vport_context_in, in, vport_number, 537 vport_num); 538 } else { 539 return -EPERM; 540 } 541 } 542 543 if (MLX5_CAP_GEN(mdev, num_ports) == 2) 544 MLX5_SET(query_hca_vport_context_in, in, port_num, port_num); 545 546 return mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out, outlen); 547} 548 549int mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev *mdev, 550 u64 *system_image_guid) 551{ 552 u32 *out; 553 int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out); 554 int err; 555 556 out = mlx5_vzalloc(outlen); 557 if (!out) 558 return -ENOMEM; 559 560 err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen); 561 if (err) 562 goto out; 563 564 *system_image_guid = MLX5_GET64(query_hca_vport_context_out, out, 565 hca_vport_context.system_image_guid); 566 567out: 568 kvfree(out); 569 return err; 570} 571EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_system_image_guid); 572 573int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid) 574{ 575 u32 *out; 576 int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out); 577 int err; 578 579 out = mlx5_vzalloc(outlen); 580 if (!out) 581 return -ENOMEM; 582 583 err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen); 584 if (err) 585 goto out; 586 587 *node_guid = MLX5_GET64(query_hca_vport_context_out, out, 588 hca_vport_context.node_guid); 589 590out: 591 kvfree(out); 592 return err; 593} 594EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_node_guid); 595 596int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 port_num, 597 u16 vport_num, u16 gid_index, union ib_gid *gid) 598{ 599 int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_in); 600 int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_out); 601 int is_group_manager; 602 void *out = NULL; 603 void *in = NULL; 604 union ib_gid *tmp; 605 int tbsz; 606 int nout; 607 int err; 608 609 is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager); 610 tbsz = mlx5_get_gid_table_len(MLX5_CAP_GEN(dev, gid_table_size)); 611 612 if (gid_index > tbsz && gid_index != 0xffff) 613 return -EINVAL; 614 615 if (gid_index == 0xffff) 616 nout = tbsz; 617 else 618 nout = 1; 619 620 out_sz += nout * sizeof(*gid); 621 622 in = mlx5_vzalloc(in_sz); 623 out = mlx5_vzalloc(out_sz); 624 if (!in || !out) { 625 err = -ENOMEM; 626 goto out; 627 } 628 629 MLX5_SET(query_hca_vport_gid_in, in, opcode, 630 MLX5_CMD_OP_QUERY_HCA_VPORT_GID); 631 if (vport_num) { 632 if (is_group_manager) { 633 MLX5_SET(query_hca_vport_gid_in, in, vport_number, 634 vport_num); 635 MLX5_SET(query_hca_vport_gid_in, in, other_vport, 1); 636 } else { 637 err = -EPERM; 638 goto out; 639 } 640 } 641 642 MLX5_SET(query_hca_vport_gid_in, in, gid_index, gid_index); 643 644 if (MLX5_CAP_GEN(dev, num_ports) == 2) 645 MLX5_SET(query_hca_vport_gid_in, in, port_num, port_num); 646 647 err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz); 648 if (err) 649 goto out; 650 651 err = mlx5_cmd_status_to_err_v2(out); 652 if (err) 653 goto out; 654 655 tmp = (union ib_gid *)MLX5_ADDR_OF(query_hca_vport_gid_out, out, gid); 656 gid->global.subnet_prefix = tmp->global.subnet_prefix; 657 gid->global.interface_id = tmp->global.interface_id; 658 659out: 660 kvfree(in); 661 kvfree(out); 662 return err; 663} 664EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_gid); 665 666int mlx5_query_hca_vport_pkey(struct mlx5_core_dev *dev, u8 other_vport, 667 u8 port_num, u16 vf_num, u16 pkey_index, 668 u16 *pkey) 669{ 670 int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_in); 671 int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_out); 672 int is_group_manager; 673 void *out = NULL; 674 void *in = NULL; 675 void *pkarr; 676 int nout; 677 int tbsz; 678 int err; 679 int i; 680 681 is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager); 682 683 tbsz = mlx5_to_sw_pkey_sz(MLX5_CAP_GEN(dev, pkey_table_size)); 684 if (pkey_index > tbsz && pkey_index != 0xffff) 685 return -EINVAL; 686 687 if (pkey_index == 0xffff) 688 nout = tbsz; 689 else 690 nout = 1; 691 692 out_sz += nout * MLX5_ST_SZ_BYTES(pkey); 693 694 in = kzalloc(in_sz, GFP_KERNEL); 695 out = kzalloc(out_sz, GFP_KERNEL); 696 697 MLX5_SET(query_hca_vport_pkey_in, in, opcode, 698 MLX5_CMD_OP_QUERY_HCA_VPORT_PKEY); 699 if (other_vport) { 700 if (is_group_manager) { 701 MLX5_SET(query_hca_vport_pkey_in, in, vport_number, 702 vf_num); 703 MLX5_SET(query_hca_vport_pkey_in, in, other_vport, 1); 704 } else { 705 err = -EPERM; 706 goto out; 707 } 708 } 709 MLX5_SET(query_hca_vport_pkey_in, in, pkey_index, pkey_index); 710 711 if (MLX5_CAP_GEN(dev, num_ports) == 2) 712 MLX5_SET(query_hca_vport_pkey_in, in, port_num, port_num); 713 714 err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz); 715 if (err) 716 goto out; 717 718 err = mlx5_cmd_status_to_err_v2(out); 719 if (err) 720 goto out; 721 722 pkarr = MLX5_ADDR_OF(query_hca_vport_pkey_out, out, pkey); 723 for (i = 0; i < nout; i++, pkey++, 724 pkarr += MLX5_ST_SZ_BYTES(pkey)) 725 *pkey = MLX5_GET_PR(pkey, pkarr, pkey); 726 727out: 728 kfree(in); 729 kfree(out); 730 return err; 731} 732EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_pkey); 733 734static int mlx5_modify_eswitch_vport_context(struct mlx5_core_dev *mdev, 735 u16 vport, void *in, int inlen) 736{ 737 u32 out[MLX5_ST_SZ_DW(modify_esw_vport_context_out)]; 738 int err; 739 740 memset(out, 0, sizeof(out)); 741 742 MLX5_SET(modify_esw_vport_context_in, in, vport_number, vport); 743 if (vport) 744 MLX5_SET(modify_esw_vport_context_in, in, other_vport, 1); 745 746 MLX5_SET(modify_esw_vport_context_in, in, opcode, 747 MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT); 748 749 err = mlx5_cmd_exec_check_status(mdev, in, inlen, 750 out, sizeof(out)); 751 if (err) 752 mlx5_core_warn(mdev, "MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT failed\n"); 753 754 return err; 755} 756 757int mlx5_set_eswitch_cvlan_info(struct mlx5_core_dev *mdev, u8 vport, 758 u8 insert_mode, u8 strip_mode, 759 u16 vlan, u8 cfi, u8 pcp) 760{ 761 u32 in[MLX5_ST_SZ_DW(modify_esw_vport_context_in)]; 762 763 memset(in, 0, sizeof(in)); 764 765 if (insert_mode != MLX5_MODIFY_ESW_VPORT_CONTEXT_CVLAN_INSERT_NONE) { 766 MLX5_SET(modify_esw_vport_context_in, in, 767 esw_vport_context.cvlan_cfi, cfi); 768 MLX5_SET(modify_esw_vport_context_in, in, 769 esw_vport_context.cvlan_pcp, pcp); 770 MLX5_SET(modify_esw_vport_context_in, in, 771 esw_vport_context.cvlan_id, vlan); 772 } 773 774 MLX5_SET(modify_esw_vport_context_in, in, 775 esw_vport_context.vport_cvlan_insert, insert_mode); 776 777 MLX5_SET(modify_esw_vport_context_in, in, 778 esw_vport_context.vport_cvlan_strip, strip_mode); 779 780 MLX5_SET(modify_esw_vport_context_in, in, field_select, 781 MLX5_MODIFY_ESW_VPORT_CONTEXT_FIELD_SELECT_CVLAN_STRIP | 782 MLX5_MODIFY_ESW_VPORT_CONTEXT_FIELD_SELECT_CVLAN_INSERT); 783 784 return mlx5_modify_eswitch_vport_context(mdev, vport, in, sizeof(in)); 785} 786EXPORT_SYMBOL_GPL(mlx5_set_eswitch_cvlan_info); 787 788int mlx5_query_vport_counter(struct mlx5_core_dev *dev, 789 u8 port_num, u16 vport_num, 790 void *out, int out_size) 791{ 792 int in_sz = MLX5_ST_SZ_BYTES(query_vport_counter_in); 793 int is_group_manager; 794 void *in; 795 int err; 796 797 is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager); 798 799 in = mlx5_vzalloc(in_sz); 800 if (!in) 801 return -ENOMEM; 802 803 MLX5_SET(query_vport_counter_in, in, opcode, 804 MLX5_CMD_OP_QUERY_VPORT_COUNTER); 805 if (vport_num) { 806 if (is_group_manager) { 807 MLX5_SET(query_vport_counter_in, in, other_vport, 1); 808 MLX5_SET(query_vport_counter_in, in, vport_number, 809 vport_num); 810 } else { 811 err = -EPERM; 812 goto ex; 813 } 814 } 815 if (MLX5_CAP_GEN(dev, num_ports) == 2) 816 MLX5_SET(query_vport_counter_in, in, port_num, port_num); 817 818 err = mlx5_cmd_exec(dev, in, in_sz, out, out_size); 819 if (err) 820 goto ex; 821 err = mlx5_cmd_status_to_err_v2(out); 822 if (err) 823 goto ex; 824 825ex: 826 kvfree(in); 827 return err; 828} 829EXPORT_SYMBOL_GPL(mlx5_query_vport_counter); 830 831int mlx5_get_vport_counters(struct mlx5_core_dev *dev, u8 port_num, 832 struct mlx5_vport_counters *vc) 833{ 834 int out_sz = MLX5_ST_SZ_BYTES(query_vport_counter_out); 835 void *out; 836 int err; 837 838 out = mlx5_vzalloc(out_sz); 839 if (!out) 840 return -ENOMEM; 841 842 err = mlx5_query_vport_counter(dev, port_num, 0, out, out_sz); 843 if (err) 844 goto ex; 845 846 vc->received_errors.packets = 847 MLX5_GET64(query_vport_counter_out, 848 out, received_errors.packets); 849 vc->received_errors.octets = 850 MLX5_GET64(query_vport_counter_out, 851 out, received_errors.octets); 852 vc->transmit_errors.packets = 853 MLX5_GET64(query_vport_counter_out, 854 out, transmit_errors.packets); 855 vc->transmit_errors.octets = 856 MLX5_GET64(query_vport_counter_out, 857 out, transmit_errors.octets); 858 vc->received_ib_unicast.packets = 859 MLX5_GET64(query_vport_counter_out, 860 out, received_ib_unicast.packets); 861 vc->received_ib_unicast.octets = 862 MLX5_GET64(query_vport_counter_out, 863 out, received_ib_unicast.octets); 864 vc->transmitted_ib_unicast.packets = 865 MLX5_GET64(query_vport_counter_out, 866 out, transmitted_ib_unicast.packets); 867 vc->transmitted_ib_unicast.octets = 868 MLX5_GET64(query_vport_counter_out, 869 out, transmitted_ib_unicast.octets); 870 vc->received_ib_multicast.packets = 871 MLX5_GET64(query_vport_counter_out, 872 out, received_ib_multicast.packets); 873 vc->received_ib_multicast.octets = 874 MLX5_GET64(query_vport_counter_out, 875 out, received_ib_multicast.octets); 876 vc->transmitted_ib_multicast.packets = 877 MLX5_GET64(query_vport_counter_out, 878 out, transmitted_ib_multicast.packets); 879 vc->transmitted_ib_multicast.octets = 880 MLX5_GET64(query_vport_counter_out, 881 out, transmitted_ib_multicast.octets); 882 vc->received_eth_broadcast.packets = 883 MLX5_GET64(query_vport_counter_out, 884 out, received_eth_broadcast.packets); 885 vc->received_eth_broadcast.octets = 886 MLX5_GET64(query_vport_counter_out, 887 out, received_eth_broadcast.octets); 888 vc->transmitted_eth_broadcast.packets = 889 MLX5_GET64(query_vport_counter_out, 890 out, transmitted_eth_broadcast.packets); 891 vc->transmitted_eth_broadcast.octets = 892 MLX5_GET64(query_vport_counter_out, 893 out, transmitted_eth_broadcast.octets); 894 vc->received_eth_unicast.octets = 895 MLX5_GET64(query_vport_counter_out, 896 out, received_eth_unicast.octets); 897 vc->received_eth_unicast.packets = 898 MLX5_GET64(query_vport_counter_out, 899 out, received_eth_unicast.packets); 900 vc->transmitted_eth_unicast.octets = 901 MLX5_GET64(query_vport_counter_out, 902 out, transmitted_eth_unicast.octets); 903 vc->transmitted_eth_unicast.packets = 904 MLX5_GET64(query_vport_counter_out, 905 out, transmitted_eth_unicast.packets); 906 vc->received_eth_multicast.octets = 907 MLX5_GET64(query_vport_counter_out, 908 out, received_eth_multicast.octets); 909 vc->received_eth_multicast.packets = 910 MLX5_GET64(query_vport_counter_out, 911 out, received_eth_multicast.packets); 912 vc->transmitted_eth_multicast.octets = 913 MLX5_GET64(query_vport_counter_out, 914 out, transmitted_eth_multicast.octets); 915 vc->transmitted_eth_multicast.packets = 916 MLX5_GET64(query_vport_counter_out, 917 out, transmitted_eth_multicast.packets); 918 919ex: 920 kvfree(out); 921 return err; 922} 923