| .. | .. |
|---|
| 43 | 43 | #include <linux/mlx5/driver.h> |
|---|
| 44 | 44 | #include <linux/mlx5/cq.h> |
|---|
| 45 | 45 | #include <linux/mlx5/qp.h> |
|---|
| 46 | | -#include <linux/mlx5/srq.h> |
|---|
| 47 | 46 | #include <linux/debugfs.h> |
|---|
| 48 | 47 | #include <linux/kmod.h> |
|---|
| 49 | 48 | #include <linux/mlx5/mlx5_ifc.h> |
|---|
| .. | .. |
|---|
| 54 | 53 | #include <linux/version.h> |
|---|
| 55 | 54 | #include <net/devlink.h> |
|---|
| 56 | 55 | #include "mlx5_core.h" |
|---|
| 56 | +#include "lib/eq.h" |
|---|
| 57 | 57 | #include "fs_core.h" |
|---|
| 58 | 58 | #include "lib/mpfs.h" |
|---|
| 59 | 59 | #include "eswitch.h" |
|---|
| 60 | +#include "devlink.h" |
|---|
| 61 | +#include "fw_reset.h" |
|---|
| 60 | 62 | #include "lib/mlx5.h" |
|---|
| 61 | 63 | #include "fpga/core.h" |
|---|
| 62 | 64 | #include "fpga/ipsec.h" |
|---|
| .. | .. |
|---|
| 64 | 66 | #include "accel/tls.h" |
|---|
| 65 | 67 | #include "lib/clock.h" |
|---|
| 66 | 68 | #include "lib/vxlan.h" |
|---|
| 69 | +#include "lib/geneve.h" |
|---|
| 70 | +#include "lib/devcom.h" |
|---|
| 71 | +#include "lib/pci_vsc.h" |
|---|
| 67 | 72 | #include "diag/fw_tracer.h" |
|---|
| 73 | +#include "ecpf.h" |
|---|
| 74 | +#include "lib/hv_vhca.h" |
|---|
| 75 | +#include "diag/rsc_dump.h" |
|---|
| 68 | 76 | |
|---|
| 69 | 77 | MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>"); |
|---|
| 70 | 78 | MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) core driver"); |
|---|
| .. | .. |
|---|
| 168 | 176 | |
|---|
| 169 | 177 | #define FW_INIT_TIMEOUT_MILI 2000 |
|---|
| 170 | 178 | #define FW_INIT_WAIT_MS 2 |
|---|
| 171 | | -#define FW_PRE_INIT_TIMEOUT_MILI 10000 |
|---|
| 179 | +#define FW_PRE_INIT_TIMEOUT_MILI 120000 |
|---|
| 180 | +#define FW_INIT_WARN_MESSAGE_INTERVAL 20000 |
|---|
| 172 | 181 | |
|---|
| 173 | | -static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili) |
|---|
| 182 | +static int fw_initializing(struct mlx5_core_dev *dev) |
|---|
| 174 | 183 | { |
|---|
| 184 | + return ioread32be(&dev->iseg->initializing) >> 31; |
|---|
| 185 | +} |
|---|
| 186 | + |
|---|
| 187 | +static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili, |
|---|
| 188 | + u32 warn_time_mili) |
|---|
| 189 | +{ |
|---|
| 190 | + unsigned long warn = jiffies + msecs_to_jiffies(warn_time_mili); |
|---|
| 175 | 191 | unsigned long end = jiffies + msecs_to_jiffies(max_wait_mili); |
|---|
| 176 | 192 | int err = 0; |
|---|
| 193 | + |
|---|
| 194 | + BUILD_BUG_ON(FW_PRE_INIT_TIMEOUT_MILI < FW_INIT_WARN_MESSAGE_INTERVAL); |
|---|
| 177 | 195 | |
|---|
| 178 | 196 | while (fw_initializing(dev)) { |
|---|
| 179 | 197 | if (time_after(jiffies, end)) { |
|---|
| 180 | 198 | err = -EBUSY; |
|---|
| 181 | 199 | break; |
|---|
| 200 | + } |
|---|
| 201 | + if (warn_time_mili && time_after(jiffies, warn)) { |
|---|
| 202 | + mlx5_core_warn(dev, "Waiting for FW initialization, timeout abort in %ds\n", |
|---|
| 203 | + jiffies_to_msecs(end - warn) / 1000); |
|---|
| 204 | + warn = jiffies + msecs_to_jiffies(warn_time_mili); |
|---|
| 182 | 205 | } |
|---|
| 183 | 206 | msleep(FW_INIT_WAIT_MS); |
|---|
| 184 | 207 | } |
|---|
| .. | .. |
|---|
| 190 | 213 | { |
|---|
| 191 | 214 | int driver_ver_sz = MLX5_FLD_SZ_BYTES(set_driver_version_in, |
|---|
| 192 | 215 | driver_version); |
|---|
| 193 | | - u8 in[MLX5_ST_SZ_BYTES(set_driver_version_in)] = {0}; |
|---|
| 194 | | - u8 out[MLX5_ST_SZ_BYTES(set_driver_version_out)] = {0}; |
|---|
| 216 | + u8 in[MLX5_ST_SZ_BYTES(set_driver_version_in)] = {}; |
|---|
| 195 | 217 | int remaining_size = driver_ver_sz; |
|---|
| 196 | 218 | char *string; |
|---|
| 197 | 219 | |
|---|
| .. | .. |
|---|
| 221 | 243 | MLX5_SET(set_driver_version_in, in, opcode, |
|---|
| 222 | 244 | MLX5_CMD_OP_SET_DRIVER_VERSION); |
|---|
| 223 | 245 | |
|---|
| 224 | | - mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
|---|
| 246 | + mlx5_cmd_exec_in(dev, set_driver_version, in); |
|---|
| 225 | 247 | } |
|---|
| 226 | 248 | |
|---|
| 227 | 249 | static int set_dma_caps(struct pci_dev *pdev) |
|---|
| .. | .. |
|---|
| 303 | 325 | pci_release_regions(pdev); |
|---|
| 304 | 326 | } |
|---|
| 305 | 327 | |
|---|
| 306 | | -static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev) |
|---|
| 307 | | -{ |
|---|
| 308 | | - struct mlx5_priv *priv = &dev->priv; |
|---|
| 309 | | - struct mlx5_eq_table *table = &priv->eq_table; |
|---|
| 310 | | - int num_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ? |
|---|
| 311 | | - MLX5_CAP_GEN(dev, max_num_eqs) : |
|---|
| 312 | | - 1 << MLX5_CAP_GEN(dev, log_max_eq); |
|---|
| 313 | | - int nvec; |
|---|
| 314 | | - int err; |
|---|
| 315 | | - |
|---|
| 316 | | - nvec = MLX5_CAP_GEN(dev, num_ports) * num_online_cpus() + |
|---|
| 317 | | - MLX5_EQ_VEC_COMP_BASE; |
|---|
| 318 | | - nvec = min_t(int, nvec, num_eqs); |
|---|
| 319 | | - if (nvec <= MLX5_EQ_VEC_COMP_BASE) |
|---|
| 320 | | - return -ENOMEM; |
|---|
| 321 | | - |
|---|
| 322 | | - priv->irq_info = kcalloc(nvec, sizeof(*priv->irq_info), GFP_KERNEL); |
|---|
| 323 | | - if (!priv->irq_info) |
|---|
| 324 | | - return -ENOMEM; |
|---|
| 325 | | - |
|---|
| 326 | | - nvec = pci_alloc_irq_vectors(dev->pdev, |
|---|
| 327 | | - MLX5_EQ_VEC_COMP_BASE + 1, nvec, |
|---|
| 328 | | - PCI_IRQ_MSIX); |
|---|
| 329 | | - if (nvec < 0) { |
|---|
| 330 | | - err = nvec; |
|---|
| 331 | | - goto err_free_irq_info; |
|---|
| 332 | | - } |
|---|
| 333 | | - |
|---|
| 334 | | - table->num_comp_vectors = nvec - MLX5_EQ_VEC_COMP_BASE; |
|---|
| 335 | | - |
|---|
| 336 | | - return 0; |
|---|
| 337 | | - |
|---|
| 338 | | -err_free_irq_info: |
|---|
| 339 | | - kfree(priv->irq_info); |
|---|
| 340 | | - return err; |
|---|
| 341 | | -} |
|---|
| 342 | | - |
|---|
| 343 | | -static void mlx5_free_irq_vectors(struct mlx5_core_dev *dev) |
|---|
| 344 | | -{ |
|---|
| 345 | | - struct mlx5_priv *priv = &dev->priv; |
|---|
| 346 | | - |
|---|
| 347 | | - pci_free_irq_vectors(dev->pdev); |
|---|
| 348 | | - kfree(priv->irq_info); |
|---|
| 349 | | -} |
|---|
| 350 | | - |
|---|
| 351 | 328 | struct mlx5_reg_host_endianness { |
|---|
| 352 | 329 | u8 he; |
|---|
| 353 | 330 | u8 rsvd[15]; |
|---|
| .. | .. |
|---|
| 398 | 375 | |
|---|
| 399 | 376 | MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); |
|---|
| 400 | 377 | MLX5_SET(query_hca_cap_in, in, op_mod, opmod); |
|---|
| 401 | | - err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz); |
|---|
| 378 | + err = mlx5_cmd_exec_inout(dev, query_hca_cap, in, out); |
|---|
| 402 | 379 | if (err) { |
|---|
| 403 | 380 | mlx5_core_warn(dev, |
|---|
| 404 | 381 | "QUERY_HCA_CAP : type(%x) opmode(%x) Failed(%d)\n", |
|---|
| .. | .. |
|---|
| 439 | 416 | return mlx5_core_get_caps_mode(dev, cap_type, HCA_CAP_OPMOD_GET_MAX); |
|---|
| 440 | 417 | } |
|---|
| 441 | 418 | |
|---|
| 442 | | -static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz, int opmod) |
|---|
| 419 | +static int set_caps(struct mlx5_core_dev *dev, void *in, int opmod) |
|---|
| 443 | 420 | { |
|---|
| 444 | | - u32 out[MLX5_ST_SZ_DW(set_hca_cap_out)] = {0}; |
|---|
| 445 | | - |
|---|
| 446 | 421 | MLX5_SET(set_hca_cap_in, in, opcode, MLX5_CMD_OP_SET_HCA_CAP); |
|---|
| 447 | 422 | MLX5_SET(set_hca_cap_in, in, op_mod, opmod << 1); |
|---|
| 448 | | - return mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out)); |
|---|
| 423 | + return mlx5_cmd_exec_in(dev, set_hca_cap, in); |
|---|
| 449 | 424 | } |
|---|
| 450 | 425 | |
|---|
| 451 | | -static int handle_hca_cap_atomic(struct mlx5_core_dev *dev) |
|---|
| 426 | +static int handle_hca_cap_atomic(struct mlx5_core_dev *dev, void *set_ctx) |
|---|
| 452 | 427 | { |
|---|
| 453 | | - void *set_ctx; |
|---|
| 454 | 428 | void *set_hca_cap; |
|---|
| 455 | | - int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); |
|---|
| 456 | 429 | int req_endianness; |
|---|
| 457 | 430 | int err; |
|---|
| 458 | 431 | |
|---|
| 459 | | - if (MLX5_CAP_GEN(dev, atomic)) { |
|---|
| 460 | | - err = mlx5_core_get_caps(dev, MLX5_CAP_ATOMIC); |
|---|
| 461 | | - if (err) |
|---|
| 462 | | - return err; |
|---|
| 463 | | - } else { |
|---|
| 432 | + if (!MLX5_CAP_GEN(dev, atomic)) |
|---|
| 464 | 433 | return 0; |
|---|
| 465 | | - } |
|---|
| 434 | + |
|---|
| 435 | + err = mlx5_core_get_caps(dev, MLX5_CAP_ATOMIC); |
|---|
| 436 | + if (err) |
|---|
| 437 | + return err; |
|---|
| 466 | 438 | |
|---|
| 467 | 439 | req_endianness = |
|---|
| 468 | 440 | MLX5_CAP_ATOMIC(dev, |
|---|
| .. | .. |
|---|
| 471 | 443 | if (req_endianness != MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS) |
|---|
| 472 | 444 | return 0; |
|---|
| 473 | 445 | |
|---|
| 474 | | - set_ctx = kzalloc(set_sz, GFP_KERNEL); |
|---|
| 475 | | - if (!set_ctx) |
|---|
| 476 | | - return -ENOMEM; |
|---|
| 477 | | - |
|---|
| 478 | 446 | set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability); |
|---|
| 479 | 447 | |
|---|
| 480 | 448 | /* Set requestor to host endianness */ |
|---|
| 481 | 449 | MLX5_SET(atomic_caps, set_hca_cap, atomic_req_8B_endianness_mode, |
|---|
| 482 | 450 | MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS); |
|---|
| 483 | 451 | |
|---|
| 484 | | - err = set_caps(dev, set_ctx, set_sz, MLX5_SET_HCA_CAP_OP_MOD_ATOMIC); |
|---|
| 485 | | - |
|---|
| 486 | | - kfree(set_ctx); |
|---|
| 487 | | - return err; |
|---|
| 452 | + return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_ATOMIC); |
|---|
| 488 | 453 | } |
|---|
| 489 | 454 | |
|---|
| 490 | | -static int handle_hca_cap(struct mlx5_core_dev *dev) |
|---|
| 455 | +static int handle_hca_cap_odp(struct mlx5_core_dev *dev, void *set_ctx) |
|---|
| 491 | 456 | { |
|---|
| 492 | | - void *set_ctx = NULL; |
|---|
| 493 | | - struct mlx5_profile *prof = dev->profile; |
|---|
| 494 | | - int err = -ENOMEM; |
|---|
| 495 | | - int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); |
|---|
| 496 | 457 | void *set_hca_cap; |
|---|
| 458 | + bool do_set = false; |
|---|
| 459 | + int err; |
|---|
| 497 | 460 | |
|---|
| 498 | | - set_ctx = kzalloc(set_sz, GFP_KERNEL); |
|---|
| 499 | | - if (!set_ctx) |
|---|
| 500 | | - goto query_ex; |
|---|
| 461 | + if (!IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING) || |
|---|
| 462 | + !MLX5_CAP_GEN(dev, pg)) |
|---|
| 463 | + return 0; |
|---|
| 464 | + |
|---|
| 465 | + err = mlx5_core_get_caps(dev, MLX5_CAP_ODP); |
|---|
| 466 | + if (err) |
|---|
| 467 | + return err; |
|---|
| 468 | + |
|---|
| 469 | + set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability); |
|---|
| 470 | + memcpy(set_hca_cap, dev->caps.hca_cur[MLX5_CAP_ODP], |
|---|
| 471 | + MLX5_ST_SZ_BYTES(odp_cap)); |
|---|
| 472 | + |
|---|
| 473 | +#define ODP_CAP_SET_MAX(dev, field) \ |
|---|
| 474 | + do { \ |
|---|
| 475 | + u32 _res = MLX5_CAP_ODP_MAX(dev, field); \ |
|---|
| 476 | + if (_res) { \ |
|---|
| 477 | + do_set = true; \ |
|---|
| 478 | + MLX5_SET(odp_cap, set_hca_cap, field, _res); \ |
|---|
| 479 | + } \ |
|---|
| 480 | + } while (0) |
|---|
| 481 | + |
|---|
| 482 | + ODP_CAP_SET_MAX(dev, ud_odp_caps.srq_receive); |
|---|
| 483 | + ODP_CAP_SET_MAX(dev, rc_odp_caps.srq_receive); |
|---|
| 484 | + ODP_CAP_SET_MAX(dev, xrc_odp_caps.srq_receive); |
|---|
| 485 | + ODP_CAP_SET_MAX(dev, xrc_odp_caps.send); |
|---|
| 486 | + ODP_CAP_SET_MAX(dev, xrc_odp_caps.receive); |
|---|
| 487 | + ODP_CAP_SET_MAX(dev, xrc_odp_caps.write); |
|---|
| 488 | + ODP_CAP_SET_MAX(dev, xrc_odp_caps.read); |
|---|
| 489 | + ODP_CAP_SET_MAX(dev, xrc_odp_caps.atomic); |
|---|
| 490 | + ODP_CAP_SET_MAX(dev, dc_odp_caps.srq_receive); |
|---|
| 491 | + ODP_CAP_SET_MAX(dev, dc_odp_caps.send); |
|---|
| 492 | + ODP_CAP_SET_MAX(dev, dc_odp_caps.receive); |
|---|
| 493 | + ODP_CAP_SET_MAX(dev, dc_odp_caps.write); |
|---|
| 494 | + ODP_CAP_SET_MAX(dev, dc_odp_caps.read); |
|---|
| 495 | + ODP_CAP_SET_MAX(dev, dc_odp_caps.atomic); |
|---|
| 496 | + |
|---|
| 497 | + if (!do_set) |
|---|
| 498 | + return 0; |
|---|
| 499 | + |
|---|
| 500 | + return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_ODP); |
|---|
| 501 | +} |
|---|
| 502 | + |
|---|
| 503 | +static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx) |
|---|
| 504 | +{ |
|---|
| 505 | + struct mlx5_profile *prof = dev->profile; |
|---|
| 506 | + void *set_hca_cap; |
|---|
| 507 | + int err; |
|---|
| 501 | 508 | |
|---|
| 502 | 509 | err = mlx5_core_get_caps(dev, MLX5_CAP_GENERAL); |
|---|
| 503 | 510 | if (err) |
|---|
| 504 | | - goto query_ex; |
|---|
| 511 | + return err; |
|---|
| 505 | 512 | |
|---|
| 506 | 513 | set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, |
|---|
| 507 | 514 | capability); |
|---|
| .. | .. |
|---|
| 546 | 553 | if (MLX5_CAP_GEN_MAX(dev, dct)) |
|---|
| 547 | 554 | MLX5_SET(cmd_hca_cap, set_hca_cap, dct, 1); |
|---|
| 548 | 555 | |
|---|
| 556 | + if (MLX5_CAP_GEN_MAX(dev, pci_sync_for_fw_update_event)) |
|---|
| 557 | + MLX5_SET(cmd_hca_cap, set_hca_cap, pci_sync_for_fw_update_event, 1); |
|---|
| 558 | + |
|---|
| 549 | 559 | if (MLX5_CAP_GEN_MAX(dev, num_vhca_ports)) |
|---|
| 550 | 560 | MLX5_SET(cmd_hca_cap, |
|---|
| 551 | 561 | set_hca_cap, |
|---|
| 552 | 562 | num_vhca_ports, |
|---|
| 553 | 563 | MLX5_CAP_GEN_MAX(dev, num_vhca_ports)); |
|---|
| 554 | 564 | |
|---|
| 555 | | - err = set_caps(dev, set_ctx, set_sz, |
|---|
| 556 | | - MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE); |
|---|
| 565 | + if (MLX5_CAP_GEN_MAX(dev, release_all_pages)) |
|---|
| 566 | + MLX5_SET(cmd_hca_cap, set_hca_cap, release_all_pages, 1); |
|---|
| 557 | 567 | |
|---|
| 558 | | -query_ex: |
|---|
| 568 | + if (MLX5_CAP_GEN_MAX(dev, mkey_by_name)) |
|---|
| 569 | + MLX5_SET(cmd_hca_cap, set_hca_cap, mkey_by_name, 1); |
|---|
| 570 | + |
|---|
| 571 | + return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE); |
|---|
| 572 | +} |
|---|
| 573 | + |
|---|
| 574 | +static int handle_hca_cap_roce(struct mlx5_core_dev *dev, void *set_ctx) |
|---|
| 575 | +{ |
|---|
| 576 | + void *set_hca_cap; |
|---|
| 577 | + int err; |
|---|
| 578 | + |
|---|
| 579 | + if (!MLX5_CAP_GEN(dev, roce)) |
|---|
| 580 | + return 0; |
|---|
| 581 | + |
|---|
| 582 | + err = mlx5_core_get_caps(dev, MLX5_CAP_ROCE); |
|---|
| 583 | + if (err) |
|---|
| 584 | + return err; |
|---|
| 585 | + |
|---|
| 586 | + if (MLX5_CAP_ROCE(dev, sw_r_roce_src_udp_port) || |
|---|
| 587 | + !MLX5_CAP_ROCE_MAX(dev, sw_r_roce_src_udp_port)) |
|---|
| 588 | + return 0; |
|---|
| 589 | + |
|---|
| 590 | + set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability); |
|---|
| 591 | + memcpy(set_hca_cap, dev->caps.hca_cur[MLX5_CAP_ROCE], |
|---|
| 592 | + MLX5_ST_SZ_BYTES(roce_cap)); |
|---|
| 593 | + MLX5_SET(roce_cap, set_hca_cap, sw_r_roce_src_udp_port, 1); |
|---|
| 594 | + |
|---|
| 595 | + err = set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_ROCE); |
|---|
| 596 | + return err; |
|---|
| 597 | +} |
|---|
| 598 | + |
|---|
| 599 | +static int set_hca_cap(struct mlx5_core_dev *dev) |
|---|
| 600 | +{ |
|---|
| 601 | + int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); |
|---|
| 602 | + void *set_ctx; |
|---|
| 603 | + int err; |
|---|
| 604 | + |
|---|
| 605 | + set_ctx = kzalloc(set_sz, GFP_KERNEL); |
|---|
| 606 | + if (!set_ctx) |
|---|
| 607 | + return -ENOMEM; |
|---|
| 608 | + |
|---|
| 609 | + err = handle_hca_cap(dev, set_ctx); |
|---|
| 610 | + if (err) { |
|---|
| 611 | + mlx5_core_err(dev, "handle_hca_cap failed\n"); |
|---|
| 612 | + goto out; |
|---|
| 613 | + } |
|---|
| 614 | + |
|---|
| 615 | + memset(set_ctx, 0, set_sz); |
|---|
| 616 | + err = handle_hca_cap_atomic(dev, set_ctx); |
|---|
| 617 | + if (err) { |
|---|
| 618 | + mlx5_core_err(dev, "handle_hca_cap_atomic failed\n"); |
|---|
| 619 | + goto out; |
|---|
| 620 | + } |
|---|
| 621 | + |
|---|
| 622 | + memset(set_ctx, 0, set_sz); |
|---|
| 623 | + err = handle_hca_cap_odp(dev, set_ctx); |
|---|
| 624 | + if (err) { |
|---|
| 625 | + mlx5_core_err(dev, "handle_hca_cap_odp failed\n"); |
|---|
| 626 | + goto out; |
|---|
| 627 | + } |
|---|
| 628 | + |
|---|
| 629 | + memset(set_ctx, 0, set_sz); |
|---|
| 630 | + err = handle_hca_cap_roce(dev, set_ctx); |
|---|
| 631 | + if (err) { |
|---|
| 632 | + mlx5_core_err(dev, "handle_hca_cap_roce failed\n"); |
|---|
| 633 | + goto out; |
|---|
| 634 | + } |
|---|
| 635 | + |
|---|
| 636 | +out: |
|---|
| 559 | 637 | kfree(set_ctx); |
|---|
| 560 | 638 | return err; |
|---|
| 561 | 639 | } |
|---|
| .. | .. |
|---|
| 590 | 668 | |
|---|
| 591 | 669 | int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id) |
|---|
| 592 | 670 | { |
|---|
| 593 | | - u32 out[MLX5_ST_SZ_DW(enable_hca_out)] = {0}; |
|---|
| 594 | | - u32 in[MLX5_ST_SZ_DW(enable_hca_in)] = {0}; |
|---|
| 671 | + u32 in[MLX5_ST_SZ_DW(enable_hca_in)] = {}; |
|---|
| 595 | 672 | |
|---|
| 596 | 673 | MLX5_SET(enable_hca_in, in, opcode, MLX5_CMD_OP_ENABLE_HCA); |
|---|
| 597 | 674 | MLX5_SET(enable_hca_in, in, function_id, func_id); |
|---|
| 598 | | - return mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); |
|---|
| 675 | + MLX5_SET(enable_hca_in, in, embedded_cpu_function, |
|---|
| 676 | + dev->caps.embedded_cpu); |
|---|
| 677 | + return mlx5_cmd_exec_in(dev, enable_hca, in); |
|---|
| 599 | 678 | } |
|---|
| 600 | 679 | |
|---|
| 601 | 680 | int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id) |
|---|
| 602 | 681 | { |
|---|
| 603 | | - u32 out[MLX5_ST_SZ_DW(disable_hca_out)] = {0}; |
|---|
| 604 | | - u32 in[MLX5_ST_SZ_DW(disable_hca_in)] = {0}; |
|---|
| 682 | + u32 in[MLX5_ST_SZ_DW(disable_hca_in)] = {}; |
|---|
| 605 | 683 | |
|---|
| 606 | 684 | MLX5_SET(disable_hca_in, in, opcode, MLX5_CMD_OP_DISABLE_HCA); |
|---|
| 607 | 685 | MLX5_SET(disable_hca_in, in, function_id, func_id); |
|---|
| 608 | | - return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
|---|
| 609 | | -} |
|---|
| 610 | | - |
|---|
| 611 | | -u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev) |
|---|
| 612 | | -{ |
|---|
| 613 | | - u32 timer_h, timer_h1, timer_l; |
|---|
| 614 | | - |
|---|
| 615 | | - timer_h = ioread32be(&dev->iseg->internal_timer_h); |
|---|
| 616 | | - timer_l = ioread32be(&dev->iseg->internal_timer_l); |
|---|
| 617 | | - timer_h1 = ioread32be(&dev->iseg->internal_timer_h); |
|---|
| 618 | | - if (timer_h != timer_h1) /* wrap around */ |
|---|
| 619 | | - timer_l = ioread32be(&dev->iseg->internal_timer_l); |
|---|
| 620 | | - |
|---|
| 621 | | - return (u64)timer_l | (u64)timer_h1 << 32; |
|---|
| 622 | | -} |
|---|
| 623 | | - |
|---|
| 624 | | -static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) |
|---|
| 625 | | -{ |
|---|
| 626 | | - struct mlx5_priv *priv = &mdev->priv; |
|---|
| 627 | | - int vecidx = MLX5_EQ_VEC_COMP_BASE + i; |
|---|
| 628 | | - int irq = pci_irq_vector(mdev->pdev, vecidx); |
|---|
| 629 | | - |
|---|
| 630 | | - if (!zalloc_cpumask_var(&priv->irq_info[vecidx].mask, GFP_KERNEL)) { |
|---|
| 631 | | - mlx5_core_warn(mdev, "zalloc_cpumask_var failed"); |
|---|
| 632 | | - return -ENOMEM; |
|---|
| 633 | | - } |
|---|
| 634 | | - |
|---|
| 635 | | - cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), |
|---|
| 636 | | - priv->irq_info[vecidx].mask); |
|---|
| 637 | | - |
|---|
| 638 | | - if (IS_ENABLED(CONFIG_SMP) && |
|---|
| 639 | | - irq_set_affinity_hint(irq, priv->irq_info[vecidx].mask)) |
|---|
| 640 | | - mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq); |
|---|
| 641 | | - |
|---|
| 642 | | - return 0; |
|---|
| 643 | | -} |
|---|
| 644 | | - |
|---|
| 645 | | -static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i) |
|---|
| 646 | | -{ |
|---|
| 647 | | - int vecidx = MLX5_EQ_VEC_COMP_BASE + i; |
|---|
| 648 | | - struct mlx5_priv *priv = &mdev->priv; |
|---|
| 649 | | - int irq = pci_irq_vector(mdev->pdev, vecidx); |
|---|
| 650 | | - |
|---|
| 651 | | - irq_set_affinity_hint(irq, NULL); |
|---|
| 652 | | - free_cpumask_var(priv->irq_info[vecidx].mask); |
|---|
| 653 | | -} |
|---|
| 654 | | - |
|---|
| 655 | | -static int mlx5_irq_set_affinity_hints(struct mlx5_core_dev *mdev) |
|---|
| 656 | | -{ |
|---|
| 657 | | - int err; |
|---|
| 658 | | - int i; |
|---|
| 659 | | - |
|---|
| 660 | | - for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) { |
|---|
| 661 | | - err = mlx5_irq_set_affinity_hint(mdev, i); |
|---|
| 662 | | - if (err) |
|---|
| 663 | | - goto err_out; |
|---|
| 664 | | - } |
|---|
| 665 | | - |
|---|
| 666 | | - return 0; |
|---|
| 667 | | - |
|---|
| 668 | | -err_out: |
|---|
| 669 | | - for (i--; i >= 0; i--) |
|---|
| 670 | | - mlx5_irq_clear_affinity_hint(mdev, i); |
|---|
| 671 | | - |
|---|
| 672 | | - return err; |
|---|
| 673 | | -} |
|---|
| 674 | | - |
|---|
| 675 | | -static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev) |
|---|
| 676 | | -{ |
|---|
| 677 | | - int i; |
|---|
| 678 | | - |
|---|
| 679 | | - for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) |
|---|
| 680 | | - mlx5_irq_clear_affinity_hint(mdev, i); |
|---|
| 681 | | -} |
|---|
| 682 | | - |
|---|
| 683 | | -int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, |
|---|
| 684 | | - unsigned int *irqn) |
|---|
| 685 | | -{ |
|---|
| 686 | | - struct mlx5_eq_table *table = &dev->priv.eq_table; |
|---|
| 687 | | - struct mlx5_eq *eq, *n; |
|---|
| 688 | | - int err = -ENOENT; |
|---|
| 689 | | - |
|---|
| 690 | | - spin_lock(&table->lock); |
|---|
| 691 | | - list_for_each_entry_safe(eq, n, &table->comp_eqs_list, list) { |
|---|
| 692 | | - if (eq->index == vector) { |
|---|
| 693 | | - *eqn = eq->eqn; |
|---|
| 694 | | - *irqn = eq->irqn; |
|---|
| 695 | | - err = 0; |
|---|
| 696 | | - break; |
|---|
| 697 | | - } |
|---|
| 698 | | - } |
|---|
| 699 | | - spin_unlock(&table->lock); |
|---|
| 700 | | - |
|---|
| 701 | | - return err; |
|---|
| 702 | | -} |
|---|
| 703 | | -EXPORT_SYMBOL(mlx5_vector2eqn); |
|---|
| 704 | | - |
|---|
| 705 | | -struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn) |
|---|
| 706 | | -{ |
|---|
| 707 | | - struct mlx5_eq_table *table = &dev->priv.eq_table; |
|---|
| 708 | | - struct mlx5_eq *eq; |
|---|
| 709 | | - |
|---|
| 710 | | - spin_lock(&table->lock); |
|---|
| 711 | | - list_for_each_entry(eq, &table->comp_eqs_list, list) |
|---|
| 712 | | - if (eq->eqn == eqn) { |
|---|
| 713 | | - spin_unlock(&table->lock); |
|---|
| 714 | | - return eq; |
|---|
| 715 | | - } |
|---|
| 716 | | - |
|---|
| 717 | | - spin_unlock(&table->lock); |
|---|
| 718 | | - |
|---|
| 719 | | - return ERR_PTR(-ENOENT); |
|---|
| 720 | | -} |
|---|
| 721 | | - |
|---|
| 722 | | -static void free_comp_eqs(struct mlx5_core_dev *dev) |
|---|
| 723 | | -{ |
|---|
| 724 | | - struct mlx5_eq_table *table = &dev->priv.eq_table; |
|---|
| 725 | | - struct mlx5_eq *eq, *n; |
|---|
| 726 | | - |
|---|
| 727 | | -#ifdef CONFIG_RFS_ACCEL |
|---|
| 728 | | - if (dev->rmap) { |
|---|
| 729 | | - free_irq_cpu_rmap(dev->rmap); |
|---|
| 730 | | - dev->rmap = NULL; |
|---|
| 731 | | - } |
|---|
| 732 | | -#endif |
|---|
| 733 | | - spin_lock(&table->lock); |
|---|
| 734 | | - list_for_each_entry_safe(eq, n, &table->comp_eqs_list, list) { |
|---|
| 735 | | - list_del(&eq->list); |
|---|
| 736 | | - spin_unlock(&table->lock); |
|---|
| 737 | | - if (mlx5_destroy_unmap_eq(dev, eq)) |
|---|
| 738 | | - mlx5_core_warn(dev, "failed to destroy EQ 0x%x\n", |
|---|
| 739 | | - eq->eqn); |
|---|
| 740 | | - kfree(eq); |
|---|
| 741 | | - spin_lock(&table->lock); |
|---|
| 742 | | - } |
|---|
| 743 | | - spin_unlock(&table->lock); |
|---|
| 744 | | -} |
|---|
| 745 | | - |
|---|
| 746 | | -static int alloc_comp_eqs(struct mlx5_core_dev *dev) |
|---|
| 747 | | -{ |
|---|
| 748 | | - struct mlx5_eq_table *table = &dev->priv.eq_table; |
|---|
| 749 | | - char name[MLX5_MAX_IRQ_NAME]; |
|---|
| 750 | | - struct mlx5_eq *eq; |
|---|
| 751 | | - int ncomp_vec; |
|---|
| 752 | | - int nent; |
|---|
| 753 | | - int err; |
|---|
| 754 | | - int i; |
|---|
| 755 | | - |
|---|
| 756 | | - INIT_LIST_HEAD(&table->comp_eqs_list); |
|---|
| 757 | | - ncomp_vec = table->num_comp_vectors; |
|---|
| 758 | | - nent = MLX5_COMP_EQ_SIZE; |
|---|
| 759 | | -#ifdef CONFIG_RFS_ACCEL |
|---|
| 760 | | - dev->rmap = alloc_irq_cpu_rmap(ncomp_vec); |
|---|
| 761 | | - if (!dev->rmap) |
|---|
| 762 | | - return -ENOMEM; |
|---|
| 763 | | -#endif |
|---|
| 764 | | - for (i = 0; i < ncomp_vec; i++) { |
|---|
| 765 | | - eq = kzalloc(sizeof(*eq), GFP_KERNEL); |
|---|
| 766 | | - if (!eq) { |
|---|
| 767 | | - err = -ENOMEM; |
|---|
| 768 | | - goto clean; |
|---|
| 769 | | - } |
|---|
| 770 | | - |
|---|
| 771 | | -#ifdef CONFIG_RFS_ACCEL |
|---|
| 772 | | - irq_cpu_rmap_add(dev->rmap, pci_irq_vector(dev->pdev, |
|---|
| 773 | | - MLX5_EQ_VEC_COMP_BASE + i)); |
|---|
| 774 | | -#endif |
|---|
| 775 | | - snprintf(name, MLX5_MAX_IRQ_NAME, "mlx5_comp%d", i); |
|---|
| 776 | | - err = mlx5_create_map_eq(dev, eq, |
|---|
| 777 | | - i + MLX5_EQ_VEC_COMP_BASE, nent, 0, |
|---|
| 778 | | - name, MLX5_EQ_TYPE_COMP); |
|---|
| 779 | | - if (err) { |
|---|
| 780 | | - kfree(eq); |
|---|
| 781 | | - goto clean; |
|---|
| 782 | | - } |
|---|
| 783 | | - mlx5_core_dbg(dev, "allocated completion EQN %d\n", eq->eqn); |
|---|
| 784 | | - eq->index = i; |
|---|
| 785 | | - spin_lock(&table->lock); |
|---|
| 786 | | - list_add_tail(&eq->list, &table->comp_eqs_list); |
|---|
| 787 | | - spin_unlock(&table->lock); |
|---|
| 788 | | - } |
|---|
| 789 | | - |
|---|
| 790 | | - return 0; |
|---|
| 791 | | - |
|---|
| 792 | | -clean: |
|---|
| 793 | | - free_comp_eqs(dev); |
|---|
| 794 | | - return err; |
|---|
| 686 | + MLX5_SET(enable_hca_in, in, embedded_cpu_function, |
|---|
| 687 | + dev->caps.embedded_cpu); |
|---|
| 688 | + return mlx5_cmd_exec_in(dev, disable_hca, in); |
|---|
| 795 | 689 | } |
|---|
| 796 | 690 | |
|---|
| 797 | 691 | static int mlx5_core_set_issi(struct mlx5_core_dev *dev) |
|---|
| 798 | 692 | { |
|---|
| 799 | | - u32 query_in[MLX5_ST_SZ_DW(query_issi_in)] = {0}; |
|---|
| 800 | | - u32 query_out[MLX5_ST_SZ_DW(query_issi_out)] = {0}; |
|---|
| 693 | + u32 query_out[MLX5_ST_SZ_DW(query_issi_out)] = {}; |
|---|
| 694 | + u32 query_in[MLX5_ST_SZ_DW(query_issi_in)] = {}; |
|---|
| 801 | 695 | u32 sup_issi; |
|---|
| 802 | 696 | int err; |
|---|
| 803 | 697 | |
|---|
| 804 | 698 | MLX5_SET(query_issi_in, query_in, opcode, MLX5_CMD_OP_QUERY_ISSI); |
|---|
| 805 | | - err = mlx5_cmd_exec(dev, query_in, sizeof(query_in), |
|---|
| 806 | | - query_out, sizeof(query_out)); |
|---|
| 699 | + err = mlx5_cmd_exec_inout(dev, query_issi, query_in, query_out); |
|---|
| 807 | 700 | if (err) { |
|---|
| 808 | 701 | u32 syndrome; |
|---|
| 809 | 702 | u8 status; |
|---|
| .. | .. |
|---|
| 823 | 716 | sup_issi = MLX5_GET(query_issi_out, query_out, supported_issi_dw0); |
|---|
| 824 | 717 | |
|---|
| 825 | 718 | if (sup_issi & (1 << 1)) { |
|---|
| 826 | | - u32 set_in[MLX5_ST_SZ_DW(set_issi_in)] = {0}; |
|---|
| 827 | | - u32 set_out[MLX5_ST_SZ_DW(set_issi_out)] = {0}; |
|---|
| 719 | + u32 set_in[MLX5_ST_SZ_DW(set_issi_in)] = {}; |
|---|
| 828 | 720 | |
|---|
| 829 | 721 | MLX5_SET(set_issi_in, set_in, opcode, MLX5_CMD_OP_SET_ISSI); |
|---|
| 830 | 722 | MLX5_SET(set_issi_in, set_in, current_issi, 1); |
|---|
| 831 | | - err = mlx5_cmd_exec(dev, set_in, sizeof(set_in), |
|---|
| 832 | | - set_out, sizeof(set_out)); |
|---|
| 723 | + err = mlx5_cmd_exec_in(dev, set_issi, set_in); |
|---|
| 833 | 724 | if (err) { |
|---|
| 834 | 725 | mlx5_core_err(dev, "Failed to set ISSI to 1 err(%d)\n", |
|---|
| 835 | 726 | err); |
|---|
| .. | .. |
|---|
| 846 | 737 | return -EOPNOTSUPP; |
|---|
| 847 | 738 | } |
|---|
| 848 | 739 | |
|---|
| 849 | | -static int mlx5_pci_init(struct mlx5_core_dev *dev, struct mlx5_priv *priv) |
|---|
| 740 | +static int mlx5_pci_init(struct mlx5_core_dev *dev, struct pci_dev *pdev, |
|---|
| 741 | + const struct pci_device_id *id) |
|---|
| 850 | 742 | { |
|---|
| 851 | | - struct pci_dev *pdev = dev->pdev; |
|---|
| 743 | + struct mlx5_priv *priv = &dev->priv; |
|---|
| 852 | 744 | int err = 0; |
|---|
| 853 | 745 | |
|---|
| 746 | + mutex_init(&dev->pci_status_mutex); |
|---|
| 854 | 747 | pci_set_drvdata(dev->pdev, dev); |
|---|
| 855 | | - strncpy(priv->name, dev_name(&pdev->dev), MLX5_MAX_NAME_LEN); |
|---|
| 856 | | - priv->name[MLX5_MAX_NAME_LEN - 1] = 0; |
|---|
| 857 | 748 | |
|---|
| 858 | | - mutex_init(&priv->pgdir_mutex); |
|---|
| 859 | | - INIT_LIST_HEAD(&priv->pgdir_list); |
|---|
| 860 | | - spin_lock_init(&priv->mkey_lock); |
|---|
| 861 | | - |
|---|
| 862 | | - mutex_init(&priv->alloc_mutex); |
|---|
| 863 | | - |
|---|
| 864 | | - priv->numa_node = dev_to_node(&dev->pdev->dev); |
|---|
| 865 | | - |
|---|
| 866 | | - if (mlx5_debugfs_root) |
|---|
| 867 | | - priv->dbg_root = |
|---|
| 868 | | - debugfs_create_dir(pci_name(pdev), mlx5_debugfs_root); |
|---|
| 749 | + dev->bar_addr = pci_resource_start(pdev, 0); |
|---|
| 750 | + priv->numa_node = dev_to_node(mlx5_core_dma_dev(dev)); |
|---|
| 869 | 751 | |
|---|
| 870 | 752 | err = mlx5_pci_enable_device(dev); |
|---|
| 871 | 753 | if (err) { |
|---|
| 872 | | - dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n"); |
|---|
| 873 | | - goto err_dbg; |
|---|
| 754 | + mlx5_core_err(dev, "Cannot enable PCI device, aborting\n"); |
|---|
| 755 | + return err; |
|---|
| 874 | 756 | } |
|---|
| 875 | 757 | |
|---|
| 876 | 758 | err = request_bar(pdev); |
|---|
| 877 | 759 | if (err) { |
|---|
| 878 | | - dev_err(&pdev->dev, "error requesting BARs, aborting\n"); |
|---|
| 760 | + mlx5_core_err(dev, "error requesting BARs, aborting\n"); |
|---|
| 879 | 761 | goto err_disable; |
|---|
| 880 | 762 | } |
|---|
| 881 | 763 | |
|---|
| .. | .. |
|---|
| 883 | 765 | |
|---|
| 884 | 766 | err = set_dma_caps(pdev); |
|---|
| 885 | 767 | if (err) { |
|---|
| 886 | | - dev_err(&pdev->dev, "Failed setting DMA capabilities mask, aborting\n"); |
|---|
| 768 | + mlx5_core_err(dev, "Failed setting DMA capabilities mask, aborting\n"); |
|---|
| 887 | 769 | goto err_clr_master; |
|---|
| 888 | 770 | } |
|---|
| 889 | 771 | |
|---|
| 890 | | - dev->iseg_base = pci_resource_start(dev->pdev, 0); |
|---|
| 772 | + if (pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP32) && |
|---|
| 773 | + pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP64) && |
|---|
| 774 | + pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP128)) |
|---|
| 775 | + mlx5_core_dbg(dev, "Enabling pci atomics failed\n"); |
|---|
| 776 | + |
|---|
| 777 | + dev->iseg_base = dev->bar_addr; |
|---|
| 891 | 778 | dev->iseg = ioremap(dev->iseg_base, sizeof(*dev->iseg)); |
|---|
| 892 | 779 | if (!dev->iseg) { |
|---|
| 893 | 780 | err = -ENOMEM; |
|---|
| 894 | | - dev_err(&pdev->dev, "Failed mapping initialization segment, aborting\n"); |
|---|
| 781 | + mlx5_core_err(dev, "Failed mapping initialization segment, aborting\n"); |
|---|
| 895 | 782 | goto err_clr_master; |
|---|
| 896 | 783 | } |
|---|
| 897 | 784 | |
|---|
| 785 | + mlx5_pci_vsc_init(dev); |
|---|
| 898 | 786 | return 0; |
|---|
| 899 | 787 | |
|---|
| 900 | 788 | err_clr_master: |
|---|
| .. | .. |
|---|
| 902 | 790 | release_bar(dev->pdev); |
|---|
| 903 | 791 | err_disable: |
|---|
| 904 | 792 | mlx5_pci_disable_device(dev); |
|---|
| 905 | | - |
|---|
| 906 | | -err_dbg: |
|---|
| 907 | | - debugfs_remove(priv->dbg_root); |
|---|
| 908 | 793 | return err; |
|---|
| 909 | 794 | } |
|---|
| 910 | 795 | |
|---|
| 911 | | -static void mlx5_pci_close(struct mlx5_core_dev *dev, struct mlx5_priv *priv) |
|---|
| 796 | +static void mlx5_pci_close(struct mlx5_core_dev *dev) |
|---|
| 912 | 797 | { |
|---|
| 798 | + /* health work might still be active, and it needs pci bar in |
|---|
| 799 | + * order to know the NIC state. Therefore, drain the health WQ |
|---|
| 800 | + * before removing the pci bars |
|---|
| 801 | + */ |
|---|
| 802 | + mlx5_drain_health_wq(dev); |
|---|
| 913 | 803 | iounmap(dev->iseg); |
|---|
| 914 | 804 | pci_clear_master(dev->pdev); |
|---|
| 915 | 805 | release_bar(dev->pdev); |
|---|
| 916 | 806 | mlx5_pci_disable_device(dev); |
|---|
| 917 | | - debugfs_remove_recursive(priv->dbg_root); |
|---|
| 918 | 807 | } |
|---|
| 919 | 808 | |
|---|
| 920 | | -static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv) |
|---|
| 809 | +static int mlx5_init_once(struct mlx5_core_dev *dev) |
|---|
| 921 | 810 | { |
|---|
| 922 | | - struct pci_dev *pdev = dev->pdev; |
|---|
| 923 | 811 | int err; |
|---|
| 812 | + |
|---|
| 813 | + dev->priv.devcom = mlx5_devcom_register_device(dev); |
|---|
| 814 | + if (IS_ERR(dev->priv.devcom)) |
|---|
| 815 | + mlx5_core_err(dev, "failed to register with devcom (0x%p)\n", |
|---|
| 816 | + dev->priv.devcom); |
|---|
| 924 | 817 | |
|---|
| 925 | 818 | err = mlx5_query_board_id(dev); |
|---|
| 926 | 819 | if (err) { |
|---|
| 927 | | - dev_err(&pdev->dev, "query board id failed\n"); |
|---|
| 928 | | - goto out; |
|---|
| 820 | + mlx5_core_err(dev, "query board id failed\n"); |
|---|
| 821 | + goto err_devcom; |
|---|
| 929 | 822 | } |
|---|
| 930 | 823 | |
|---|
| 931 | | - err = mlx5_eq_init(dev); |
|---|
| 824 | + err = mlx5_irq_table_init(dev); |
|---|
| 932 | 825 | if (err) { |
|---|
| 933 | | - dev_err(&pdev->dev, "failed to initialize eq\n"); |
|---|
| 934 | | - goto out; |
|---|
| 826 | + mlx5_core_err(dev, "failed to initialize irq table\n"); |
|---|
| 827 | + goto err_devcom; |
|---|
| 935 | 828 | } |
|---|
| 936 | 829 | |
|---|
| 937 | | - err = mlx5_cq_debugfs_init(dev); |
|---|
| 830 | + err = mlx5_eq_table_init(dev); |
|---|
| 938 | 831 | if (err) { |
|---|
| 939 | | - dev_err(&pdev->dev, "failed to initialize cq debugfs\n"); |
|---|
| 832 | + mlx5_core_err(dev, "failed to initialize eq\n"); |
|---|
| 833 | + goto err_irq_cleanup; |
|---|
| 834 | + } |
|---|
| 835 | + |
|---|
| 836 | + err = mlx5_events_init(dev); |
|---|
| 837 | + if (err) { |
|---|
| 838 | + mlx5_core_err(dev, "failed to initialize events\n"); |
|---|
| 940 | 839 | goto err_eq_cleanup; |
|---|
| 941 | 840 | } |
|---|
| 942 | 841 | |
|---|
| 943 | | - mlx5_init_qp_table(dev); |
|---|
| 842 | + err = mlx5_fw_reset_init(dev); |
|---|
| 843 | + if (err) { |
|---|
| 844 | + mlx5_core_err(dev, "failed to initialize fw reset events\n"); |
|---|
| 845 | + goto err_events_cleanup; |
|---|
| 846 | + } |
|---|
| 944 | 847 | |
|---|
| 945 | | - mlx5_init_srq_table(dev); |
|---|
| 946 | | - |
|---|
| 947 | | - mlx5_init_mkey_table(dev); |
|---|
| 848 | + mlx5_cq_debugfs_init(dev); |
|---|
| 948 | 849 | |
|---|
| 949 | 850 | mlx5_init_reserved_gids(dev); |
|---|
| 950 | 851 | |
|---|
| 951 | 852 | mlx5_init_clock(dev); |
|---|
| 952 | 853 | |
|---|
| 953 | 854 | dev->vxlan = mlx5_vxlan_create(dev); |
|---|
| 855 | + dev->geneve = mlx5_geneve_create(dev); |
|---|
| 954 | 856 | |
|---|
| 955 | 857 | err = mlx5_init_rl_table(dev); |
|---|
| 956 | 858 | if (err) { |
|---|
| 957 | | - dev_err(&pdev->dev, "Failed to init rate limiting\n"); |
|---|
| 859 | + mlx5_core_err(dev, "Failed to init rate limiting\n"); |
|---|
| 958 | 860 | goto err_tables_cleanup; |
|---|
| 959 | 861 | } |
|---|
| 960 | 862 | |
|---|
| 961 | 863 | err = mlx5_mpfs_init(dev); |
|---|
| 962 | 864 | if (err) { |
|---|
| 963 | | - dev_err(&pdev->dev, "Failed to init l2 table %d\n", err); |
|---|
| 865 | + mlx5_core_err(dev, "Failed to init l2 table %d\n", err); |
|---|
| 964 | 866 | goto err_rl_cleanup; |
|---|
| 965 | | - } |
|---|
| 966 | | - |
|---|
| 967 | | - err = mlx5_eswitch_init(dev); |
|---|
| 968 | | - if (err) { |
|---|
| 969 | | - dev_err(&pdev->dev, "Failed to init eswitch %d\n", err); |
|---|
| 970 | | - goto err_mpfs_cleanup; |
|---|
| 971 | 867 | } |
|---|
| 972 | 868 | |
|---|
| 973 | 869 | err = mlx5_sriov_init(dev); |
|---|
| 974 | 870 | if (err) { |
|---|
| 975 | | - dev_err(&pdev->dev, "Failed to init sriov %d\n", err); |
|---|
| 976 | | - goto err_eswitch_cleanup; |
|---|
| 871 | + mlx5_core_err(dev, "Failed to init sriov %d\n", err); |
|---|
| 872 | + goto err_mpfs_cleanup; |
|---|
| 873 | + } |
|---|
| 874 | + |
|---|
| 875 | + err = mlx5_eswitch_init(dev); |
|---|
| 876 | + if (err) { |
|---|
| 877 | + mlx5_core_err(dev, "Failed to init eswitch %d\n", err); |
|---|
| 878 | + goto err_sriov_cleanup; |
|---|
| 977 | 879 | } |
|---|
| 978 | 880 | |
|---|
| 979 | 881 | err = mlx5_fpga_init(dev); |
|---|
| 980 | 882 | if (err) { |
|---|
| 981 | | - dev_err(&pdev->dev, "Failed to init fpga device %d\n", err); |
|---|
| 982 | | - goto err_sriov_cleanup; |
|---|
| 883 | + mlx5_core_err(dev, "Failed to init fpga device %d\n", err); |
|---|
| 884 | + goto err_eswitch_cleanup; |
|---|
| 983 | 885 | } |
|---|
| 984 | 886 | |
|---|
| 887 | + dev->dm = mlx5_dm_create(dev); |
|---|
| 888 | + if (IS_ERR(dev->dm)) |
|---|
| 889 | + mlx5_core_warn(dev, "Failed to init device memory %ld\n", PTR_ERR(dev->dm)); |
|---|
| 890 | + |
|---|
| 985 | 891 | dev->tracer = mlx5_fw_tracer_create(dev); |
|---|
| 892 | + dev->hv_vhca = mlx5_hv_vhca_create(dev); |
|---|
| 893 | + dev->rsc_dump = mlx5_rsc_dump_create(dev); |
|---|
| 986 | 894 | |
|---|
| 987 | 895 | return 0; |
|---|
| 988 | 896 | |
|---|
| 989 | | -err_sriov_cleanup: |
|---|
| 990 | | - mlx5_sriov_cleanup(dev); |
|---|
| 991 | 897 | err_eswitch_cleanup: |
|---|
| 992 | 898 | mlx5_eswitch_cleanup(dev->priv.eswitch); |
|---|
| 899 | +err_sriov_cleanup: |
|---|
| 900 | + mlx5_sriov_cleanup(dev); |
|---|
| 993 | 901 | err_mpfs_cleanup: |
|---|
| 994 | 902 | mlx5_mpfs_cleanup(dev); |
|---|
| 995 | 903 | err_rl_cleanup: |
|---|
| 996 | 904 | mlx5_cleanup_rl_table(dev); |
|---|
| 997 | 905 | err_tables_cleanup: |
|---|
| 906 | + mlx5_geneve_destroy(dev->geneve); |
|---|
| 998 | 907 | mlx5_vxlan_destroy(dev->vxlan); |
|---|
| 999 | | - mlx5_cleanup_mkey_table(dev); |
|---|
| 1000 | | - mlx5_cleanup_srq_table(dev); |
|---|
| 1001 | | - mlx5_cleanup_qp_table(dev); |
|---|
| 908 | + mlx5_cleanup_clock(dev); |
|---|
| 909 | + mlx5_cleanup_reserved_gids(dev); |
|---|
| 1002 | 910 | mlx5_cq_debugfs_cleanup(dev); |
|---|
| 1003 | | - |
|---|
| 911 | + mlx5_fw_reset_cleanup(dev); |
|---|
| 912 | +err_events_cleanup: |
|---|
| 913 | + mlx5_events_cleanup(dev); |
|---|
| 1004 | 914 | err_eq_cleanup: |
|---|
| 1005 | | - mlx5_eq_cleanup(dev); |
|---|
| 915 | + mlx5_eq_table_cleanup(dev); |
|---|
| 916 | +err_irq_cleanup: |
|---|
| 917 | + mlx5_irq_table_cleanup(dev); |
|---|
| 918 | +err_devcom: |
|---|
| 919 | + mlx5_devcom_unregister_device(dev->priv.devcom); |
|---|
| 1006 | 920 | |
|---|
| 1007 | | -out: |
|---|
| 1008 | 921 | return err; |
|---|
| 1009 | 922 | } |
|---|
| 1010 | 923 | |
|---|
| 1011 | 924 | static void mlx5_cleanup_once(struct mlx5_core_dev *dev) |
|---|
| 1012 | 925 | { |
|---|
| 926 | + mlx5_rsc_dump_destroy(dev); |
|---|
| 927 | + mlx5_hv_vhca_destroy(dev->hv_vhca); |
|---|
| 1013 | 928 | mlx5_fw_tracer_destroy(dev->tracer); |
|---|
| 929 | + mlx5_dm_cleanup(dev); |
|---|
| 1014 | 930 | mlx5_fpga_cleanup(dev); |
|---|
| 1015 | | - mlx5_sriov_cleanup(dev); |
|---|
| 1016 | 931 | mlx5_eswitch_cleanup(dev->priv.eswitch); |
|---|
| 932 | + mlx5_sriov_cleanup(dev); |
|---|
| 1017 | 933 | mlx5_mpfs_cleanup(dev); |
|---|
| 1018 | 934 | mlx5_cleanup_rl_table(dev); |
|---|
| 935 | + mlx5_geneve_destroy(dev->geneve); |
|---|
| 1019 | 936 | mlx5_vxlan_destroy(dev->vxlan); |
|---|
| 1020 | 937 | mlx5_cleanup_clock(dev); |
|---|
| 1021 | 938 | mlx5_cleanup_reserved_gids(dev); |
|---|
| 1022 | | - mlx5_cleanup_mkey_table(dev); |
|---|
| 1023 | | - mlx5_cleanup_srq_table(dev); |
|---|
| 1024 | | - mlx5_cleanup_qp_table(dev); |
|---|
| 1025 | 939 | mlx5_cq_debugfs_cleanup(dev); |
|---|
| 1026 | | - mlx5_eq_cleanup(dev); |
|---|
| 940 | + mlx5_fw_reset_cleanup(dev); |
|---|
| 941 | + mlx5_events_cleanup(dev); |
|---|
| 942 | + mlx5_eq_table_cleanup(dev); |
|---|
| 943 | + mlx5_irq_table_cleanup(dev); |
|---|
| 944 | + mlx5_devcom_unregister_device(dev->priv.devcom); |
|---|
| 1027 | 945 | } |
|---|
| 1028 | 946 | |
|---|
| 1029 | | -static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, |
|---|
| 1030 | | - bool boot) |
|---|
| 947 | +static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot) |
|---|
| 1031 | 948 | { |
|---|
| 1032 | | - struct pci_dev *pdev = dev->pdev; |
|---|
| 1033 | 949 | int err; |
|---|
| 1034 | 950 | |
|---|
| 1035 | | - mutex_lock(&dev->intf_state_mutex); |
|---|
| 1036 | | - if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { |
|---|
| 1037 | | - dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n", |
|---|
| 1038 | | - __func__); |
|---|
| 1039 | | - goto out; |
|---|
| 1040 | | - } |
|---|
| 1041 | | - |
|---|
| 1042 | | - dev_info(&pdev->dev, "firmware version: %d.%d.%d\n", fw_rev_maj(dev), |
|---|
| 1043 | | - fw_rev_min(dev), fw_rev_sub(dev)); |
|---|
| 951 | + mlx5_core_info(dev, "firmware version: %d.%d.%d\n", fw_rev_maj(dev), |
|---|
| 952 | + fw_rev_min(dev), fw_rev_sub(dev)); |
|---|
| 1044 | 953 | |
|---|
| 1045 | 954 | /* Only PFs hold the relevant PCIe information for this query */ |
|---|
| 1046 | 955 | if (mlx5_core_is_pf(dev)) |
|---|
| 1047 | 956 | pcie_print_link_status(dev->pdev); |
|---|
| 1048 | 957 | |
|---|
| 1049 | | - /* on load removing any previous indication of internal error, device is |
|---|
| 1050 | | - * up |
|---|
| 1051 | | - */ |
|---|
| 1052 | | - dev->state = MLX5_DEVICE_STATE_UP; |
|---|
| 1053 | | - |
|---|
| 1054 | 958 | /* wait for firmware to accept initialization segments configurations |
|---|
| 1055 | 959 | */ |
|---|
| 1056 | | - err = wait_fw_init(dev, FW_PRE_INIT_TIMEOUT_MILI); |
|---|
| 960 | + err = wait_fw_init(dev, FW_PRE_INIT_TIMEOUT_MILI, FW_INIT_WARN_MESSAGE_INTERVAL); |
|---|
| 1057 | 961 | if (err) { |
|---|
| 1058 | | - dev_err(&dev->pdev->dev, "Firmware over %d MS in pre-initializing state, aborting\n", |
|---|
| 1059 | | - FW_PRE_INIT_TIMEOUT_MILI); |
|---|
| 1060 | | - goto out_err; |
|---|
| 962 | + mlx5_core_err(dev, "Firmware over %d MS in pre-initializing state, aborting\n", |
|---|
| 963 | + FW_PRE_INIT_TIMEOUT_MILI); |
|---|
| 964 | + return err; |
|---|
| 1061 | 965 | } |
|---|
| 1062 | 966 | |
|---|
| 1063 | 967 | err = mlx5_cmd_init(dev); |
|---|
| 1064 | 968 | if (err) { |
|---|
| 1065 | | - dev_err(&pdev->dev, "Failed initializing command interface, aborting\n"); |
|---|
| 1066 | | - goto out_err; |
|---|
| 969 | + mlx5_core_err(dev, "Failed initializing command interface, aborting\n"); |
|---|
| 970 | + return err; |
|---|
| 1067 | 971 | } |
|---|
| 1068 | 972 | |
|---|
| 1069 | | - err = wait_fw_init(dev, FW_INIT_TIMEOUT_MILI); |
|---|
| 973 | + err = wait_fw_init(dev, FW_INIT_TIMEOUT_MILI, 0); |
|---|
| 1070 | 974 | if (err) { |
|---|
| 1071 | | - dev_err(&dev->pdev->dev, "Firmware over %d MS in initializing state, aborting\n", |
|---|
| 1072 | | - FW_INIT_TIMEOUT_MILI); |
|---|
| 975 | + mlx5_core_err(dev, "Firmware over %d MS in initializing state, aborting\n", |
|---|
| 976 | + FW_INIT_TIMEOUT_MILI); |
|---|
| 1073 | 977 | goto err_cmd_cleanup; |
|---|
| 1074 | 978 | } |
|---|
| 1075 | 979 | |
|---|
| 980 | + dev->caps.embedded_cpu = mlx5_read_embedded_cpu(dev); |
|---|
| 981 | + mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP); |
|---|
| 982 | + |
|---|
| 1076 | 983 | err = mlx5_core_enable_hca(dev, 0); |
|---|
| 1077 | 984 | if (err) { |
|---|
| 1078 | | - dev_err(&pdev->dev, "enable hca failed\n"); |
|---|
| 985 | + mlx5_core_err(dev, "enable hca failed\n"); |
|---|
| 1079 | 986 | goto err_cmd_cleanup; |
|---|
| 1080 | 987 | } |
|---|
| 1081 | 988 | |
|---|
| 1082 | 989 | err = mlx5_core_set_issi(dev); |
|---|
| 1083 | 990 | if (err) { |
|---|
| 1084 | | - dev_err(&pdev->dev, "failed to set issi\n"); |
|---|
| 991 | + mlx5_core_err(dev, "failed to set issi\n"); |
|---|
| 1085 | 992 | goto err_disable_hca; |
|---|
| 1086 | 993 | } |
|---|
| 1087 | 994 | |
|---|
| 1088 | 995 | err = mlx5_satisfy_startup_pages(dev, 1); |
|---|
| 1089 | 996 | if (err) { |
|---|
| 1090 | | - dev_err(&pdev->dev, "failed to allocate boot pages\n"); |
|---|
| 997 | + mlx5_core_err(dev, "failed to allocate boot pages\n"); |
|---|
| 1091 | 998 | goto err_disable_hca; |
|---|
| 1092 | 999 | } |
|---|
| 1093 | 1000 | |
|---|
| 1094 | 1001 | err = set_hca_ctrl(dev); |
|---|
| 1095 | 1002 | if (err) { |
|---|
| 1096 | | - dev_err(&pdev->dev, "set_hca_ctrl failed\n"); |
|---|
| 1003 | + mlx5_core_err(dev, "set_hca_ctrl failed\n"); |
|---|
| 1097 | 1004 | goto reclaim_boot_pages; |
|---|
| 1098 | 1005 | } |
|---|
| 1099 | 1006 | |
|---|
| 1100 | | - err = handle_hca_cap(dev); |
|---|
| 1007 | + err = set_hca_cap(dev); |
|---|
| 1101 | 1008 | if (err) { |
|---|
| 1102 | | - dev_err(&pdev->dev, "handle_hca_cap failed\n"); |
|---|
| 1103 | | - goto reclaim_boot_pages; |
|---|
| 1104 | | - } |
|---|
| 1105 | | - |
|---|
| 1106 | | - err = handle_hca_cap_atomic(dev); |
|---|
| 1107 | | - if (err) { |
|---|
| 1108 | | - dev_err(&pdev->dev, "handle_hca_cap_atomic failed\n"); |
|---|
| 1009 | + mlx5_core_err(dev, "set_hca_cap failed\n"); |
|---|
| 1109 | 1010 | goto reclaim_boot_pages; |
|---|
| 1110 | 1011 | } |
|---|
| 1111 | 1012 | |
|---|
| 1112 | 1013 | err = mlx5_satisfy_startup_pages(dev, 0); |
|---|
| 1113 | 1014 | if (err) { |
|---|
| 1114 | | - dev_err(&pdev->dev, "failed to allocate init pages\n"); |
|---|
| 1115 | | - goto reclaim_boot_pages; |
|---|
| 1116 | | - } |
|---|
| 1117 | | - |
|---|
| 1118 | | - err = mlx5_pagealloc_start(dev); |
|---|
| 1119 | | - if (err) { |
|---|
| 1120 | | - dev_err(&pdev->dev, "mlx5_pagealloc_start failed\n"); |
|---|
| 1015 | + mlx5_core_err(dev, "failed to allocate init pages\n"); |
|---|
| 1121 | 1016 | goto reclaim_boot_pages; |
|---|
| 1122 | 1017 | } |
|---|
| 1123 | 1018 | |
|---|
| 1124 | 1019 | err = mlx5_cmd_init_hca(dev, sw_owner_id); |
|---|
| 1125 | 1020 | if (err) { |
|---|
| 1126 | | - dev_err(&pdev->dev, "init hca failed\n"); |
|---|
| 1127 | | - goto err_pagealloc_stop; |
|---|
| 1021 | + mlx5_core_err(dev, "init hca failed\n"); |
|---|
| 1022 | + goto reclaim_boot_pages; |
|---|
| 1128 | 1023 | } |
|---|
| 1129 | 1024 | |
|---|
| 1130 | 1025 | mlx5_set_driver_version(dev); |
|---|
| .. | .. |
|---|
| 1133 | 1028 | |
|---|
| 1134 | 1029 | err = mlx5_query_hca_caps(dev); |
|---|
| 1135 | 1030 | if (err) { |
|---|
| 1136 | | - dev_err(&pdev->dev, "query hca failed\n"); |
|---|
| 1137 | | - goto err_stop_poll; |
|---|
| 1031 | + mlx5_core_err(dev, "query hca failed\n"); |
|---|
| 1032 | + goto stop_health; |
|---|
| 1138 | 1033 | } |
|---|
| 1139 | 1034 | |
|---|
| 1140 | | - if (boot) { |
|---|
| 1141 | | - err = mlx5_init_once(dev, priv); |
|---|
| 1142 | | - if (err) { |
|---|
| 1143 | | - dev_err(&pdev->dev, "sw objs init failed\n"); |
|---|
| 1144 | | - goto err_stop_poll; |
|---|
| 1145 | | - } |
|---|
| 1146 | | - } |
|---|
| 1035 | + return 0; |
|---|
| 1147 | 1036 | |
|---|
| 1148 | | - err = mlx5_alloc_irq_vectors(dev); |
|---|
| 1037 | +stop_health: |
|---|
| 1038 | + mlx5_stop_health_poll(dev, boot); |
|---|
| 1039 | +reclaim_boot_pages: |
|---|
| 1040 | + mlx5_reclaim_startup_pages(dev); |
|---|
| 1041 | +err_disable_hca: |
|---|
| 1042 | + mlx5_core_disable_hca(dev, 0); |
|---|
| 1043 | +err_cmd_cleanup: |
|---|
| 1044 | + mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); |
|---|
| 1045 | + mlx5_cmd_cleanup(dev); |
|---|
| 1046 | + |
|---|
| 1047 | + return err; |
|---|
| 1048 | +} |
|---|
| 1049 | + |
|---|
| 1050 | +static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot) |
|---|
| 1051 | +{ |
|---|
| 1052 | + int err; |
|---|
| 1053 | + |
|---|
| 1054 | + mlx5_stop_health_poll(dev, boot); |
|---|
| 1055 | + err = mlx5_cmd_teardown_hca(dev); |
|---|
| 1149 | 1056 | if (err) { |
|---|
| 1150 | | - dev_err(&pdev->dev, "alloc irq vectors failed\n"); |
|---|
| 1151 | | - goto err_cleanup_once; |
|---|
| 1057 | + mlx5_core_err(dev, "tear_down_hca failed, skip cleanup\n"); |
|---|
| 1058 | + return err; |
|---|
| 1152 | 1059 | } |
|---|
| 1060 | + mlx5_reclaim_startup_pages(dev); |
|---|
| 1061 | + mlx5_core_disable_hca(dev, 0); |
|---|
| 1062 | + mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); |
|---|
| 1063 | + mlx5_cmd_cleanup(dev); |
|---|
| 1064 | + |
|---|
| 1065 | + return 0; |
|---|
| 1066 | +} |
|---|
| 1067 | + |
|---|
| 1068 | +static int mlx5_load(struct mlx5_core_dev *dev) |
|---|
| 1069 | +{ |
|---|
| 1070 | + int err; |
|---|
| 1153 | 1071 | |
|---|
| 1154 | 1072 | dev->priv.uar = mlx5_get_uars_page(dev); |
|---|
| 1155 | 1073 | if (IS_ERR(dev->priv.uar)) { |
|---|
| 1156 | | - dev_err(&pdev->dev, "Failed allocating uar, aborting\n"); |
|---|
| 1074 | + mlx5_core_err(dev, "Failed allocating uar, aborting\n"); |
|---|
| 1157 | 1075 | err = PTR_ERR(dev->priv.uar); |
|---|
| 1158 | | - goto err_disable_msix; |
|---|
| 1076 | + return err; |
|---|
| 1159 | 1077 | } |
|---|
| 1160 | 1078 | |
|---|
| 1161 | | - err = mlx5_start_eqs(dev); |
|---|
| 1079 | + mlx5_events_start(dev); |
|---|
| 1080 | + mlx5_pagealloc_start(dev); |
|---|
| 1081 | + |
|---|
| 1082 | + err = mlx5_irq_table_create(dev); |
|---|
| 1162 | 1083 | if (err) { |
|---|
| 1163 | | - dev_err(&pdev->dev, "Failed to start pages and async EQs\n"); |
|---|
| 1164 | | - goto err_put_uars; |
|---|
| 1084 | + mlx5_core_err(dev, "Failed to alloc IRQs\n"); |
|---|
| 1085 | + goto err_irq_table; |
|---|
| 1086 | + } |
|---|
| 1087 | + |
|---|
| 1088 | + err = mlx5_eq_table_create(dev); |
|---|
| 1089 | + if (err) { |
|---|
| 1090 | + mlx5_core_err(dev, "Failed to create EQs\n"); |
|---|
| 1091 | + goto err_eq_table; |
|---|
| 1165 | 1092 | } |
|---|
| 1166 | 1093 | |
|---|
| 1167 | 1094 | err = mlx5_fw_tracer_init(dev->tracer); |
|---|
| 1168 | 1095 | if (err) { |
|---|
| 1169 | | - dev_err(&pdev->dev, "Failed to init FW tracer\n"); |
|---|
| 1096 | + mlx5_core_err(dev, "Failed to init FW tracer\n"); |
|---|
| 1170 | 1097 | goto err_fw_tracer; |
|---|
| 1171 | 1098 | } |
|---|
| 1172 | 1099 | |
|---|
| 1173 | | - err = alloc_comp_eqs(dev); |
|---|
| 1174 | | - if (err) { |
|---|
| 1175 | | - dev_err(&pdev->dev, "Failed to alloc completion EQs\n"); |
|---|
| 1176 | | - goto err_comp_eqs; |
|---|
| 1177 | | - } |
|---|
| 1100 | + mlx5_fw_reset_events_start(dev); |
|---|
| 1101 | + mlx5_hv_vhca_init(dev->hv_vhca); |
|---|
| 1178 | 1102 | |
|---|
| 1179 | | - err = mlx5_irq_set_affinity_hints(dev); |
|---|
| 1103 | + err = mlx5_rsc_dump_init(dev); |
|---|
| 1180 | 1104 | if (err) { |
|---|
| 1181 | | - dev_err(&pdev->dev, "Failed to alloc affinity hint cpumask\n"); |
|---|
| 1182 | | - goto err_affinity_hints; |
|---|
| 1105 | + mlx5_core_err(dev, "Failed to init Resource dump\n"); |
|---|
| 1106 | + goto err_rsc_dump; |
|---|
| 1183 | 1107 | } |
|---|
| 1184 | 1108 | |
|---|
| 1185 | 1109 | err = mlx5_fpga_device_start(dev); |
|---|
| 1186 | 1110 | if (err) { |
|---|
| 1187 | | - dev_err(&pdev->dev, "fpga device start failed %d\n", err); |
|---|
| 1111 | + mlx5_core_err(dev, "fpga device start failed %d\n", err); |
|---|
| 1188 | 1112 | goto err_fpga_start; |
|---|
| 1189 | 1113 | } |
|---|
| 1190 | 1114 | |
|---|
| 1191 | | - err = mlx5_accel_ipsec_init(dev); |
|---|
| 1192 | | - if (err) { |
|---|
| 1193 | | - dev_err(&pdev->dev, "IPSec device start failed %d\n", err); |
|---|
| 1194 | | - goto err_ipsec_start; |
|---|
| 1195 | | - } |
|---|
| 1115 | + mlx5_accel_ipsec_init(dev); |
|---|
| 1196 | 1116 | |
|---|
| 1197 | 1117 | err = mlx5_accel_tls_init(dev); |
|---|
| 1198 | 1118 | if (err) { |
|---|
| 1199 | | - dev_err(&pdev->dev, "TLS device start failed %d\n", err); |
|---|
| 1119 | + mlx5_core_err(dev, "TLS device start failed %d\n", err); |
|---|
| 1200 | 1120 | goto err_tls_start; |
|---|
| 1201 | 1121 | } |
|---|
| 1202 | 1122 | |
|---|
| 1203 | 1123 | err = mlx5_init_fs(dev); |
|---|
| 1204 | 1124 | if (err) { |
|---|
| 1205 | | - dev_err(&pdev->dev, "Failed to init flow steering\n"); |
|---|
| 1125 | + mlx5_core_err(dev, "Failed to init flow steering\n"); |
|---|
| 1206 | 1126 | goto err_fs; |
|---|
| 1207 | 1127 | } |
|---|
| 1208 | 1128 | |
|---|
| 1209 | 1129 | err = mlx5_core_set_hca_defaults(dev); |
|---|
| 1210 | 1130 | if (err) { |
|---|
| 1211 | | - dev_err(&pdev->dev, "Failed to set hca defaults\n"); |
|---|
| 1212 | | - goto err_fs; |
|---|
| 1131 | + mlx5_core_err(dev, "Failed to set hca defaults\n"); |
|---|
| 1132 | + goto err_sriov; |
|---|
| 1213 | 1133 | } |
|---|
| 1214 | 1134 | |
|---|
| 1215 | 1135 | err = mlx5_sriov_attach(dev); |
|---|
| 1216 | 1136 | if (err) { |
|---|
| 1217 | | - dev_err(&pdev->dev, "sriov init failed %d\n", err); |
|---|
| 1137 | + mlx5_core_err(dev, "sriov init failed %d\n", err); |
|---|
| 1218 | 1138 | goto err_sriov; |
|---|
| 1219 | 1139 | } |
|---|
| 1220 | 1140 | |
|---|
| 1221 | | - if (mlx5_device_registered(dev)) { |
|---|
| 1222 | | - mlx5_attach_device(dev); |
|---|
| 1223 | | - } else { |
|---|
| 1224 | | - err = mlx5_register_device(dev); |
|---|
| 1225 | | - if (err) { |
|---|
| 1226 | | - dev_err(&pdev->dev, "mlx5_register_device failed %d\n", err); |
|---|
| 1227 | | - goto err_reg_dev; |
|---|
| 1228 | | - } |
|---|
| 1141 | + err = mlx5_ec_init(dev); |
|---|
| 1142 | + if (err) { |
|---|
| 1143 | + mlx5_core_err(dev, "Failed to init embedded CPU\n"); |
|---|
| 1144 | + goto err_ec; |
|---|
| 1229 | 1145 | } |
|---|
| 1230 | | - |
|---|
| 1231 | | - set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); |
|---|
| 1232 | | -out: |
|---|
| 1233 | | - mutex_unlock(&dev->intf_state_mutex); |
|---|
| 1234 | 1146 | |
|---|
| 1235 | 1147 | return 0; |
|---|
| 1236 | 1148 | |
|---|
| 1237 | | -err_reg_dev: |
|---|
| 1149 | +err_ec: |
|---|
| 1238 | 1150 | mlx5_sriov_detach(dev); |
|---|
| 1239 | | - |
|---|
| 1240 | 1151 | err_sriov: |
|---|
| 1241 | 1152 | mlx5_cleanup_fs(dev); |
|---|
| 1242 | | - |
|---|
| 1243 | 1153 | err_fs: |
|---|
| 1244 | 1154 | mlx5_accel_tls_cleanup(dev); |
|---|
| 1245 | | - |
|---|
| 1246 | 1155 | err_tls_start: |
|---|
| 1247 | 1156 | mlx5_accel_ipsec_cleanup(dev); |
|---|
| 1248 | | - |
|---|
| 1249 | | -err_ipsec_start: |
|---|
| 1250 | 1157 | mlx5_fpga_device_stop(dev); |
|---|
| 1251 | | - |
|---|
| 1252 | 1158 | err_fpga_start: |
|---|
| 1253 | | - mlx5_irq_clear_affinity_hints(dev); |
|---|
| 1254 | | - |
|---|
| 1255 | | -err_affinity_hints: |
|---|
| 1256 | | - free_comp_eqs(dev); |
|---|
| 1257 | | - |
|---|
| 1258 | | -err_comp_eqs: |
|---|
| 1159 | + mlx5_rsc_dump_cleanup(dev); |
|---|
| 1160 | +err_rsc_dump: |
|---|
| 1161 | + mlx5_hv_vhca_cleanup(dev->hv_vhca); |
|---|
| 1162 | + mlx5_fw_reset_events_stop(dev); |
|---|
| 1259 | 1163 | mlx5_fw_tracer_cleanup(dev->tracer); |
|---|
| 1260 | | - |
|---|
| 1261 | 1164 | err_fw_tracer: |
|---|
| 1262 | | - mlx5_stop_eqs(dev); |
|---|
| 1263 | | - |
|---|
| 1264 | | -err_put_uars: |
|---|
| 1265 | | - mlx5_put_uars_page(dev, priv->uar); |
|---|
| 1266 | | - |
|---|
| 1267 | | -err_disable_msix: |
|---|
| 1268 | | - mlx5_free_irq_vectors(dev); |
|---|
| 1269 | | - |
|---|
| 1270 | | -err_cleanup_once: |
|---|
| 1271 | | - if (boot) |
|---|
| 1272 | | - mlx5_cleanup_once(dev); |
|---|
| 1273 | | - |
|---|
| 1274 | | -err_stop_poll: |
|---|
| 1275 | | - mlx5_stop_health_poll(dev, boot); |
|---|
| 1276 | | - if (mlx5_cmd_teardown_hca(dev)) { |
|---|
| 1277 | | - dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n"); |
|---|
| 1278 | | - goto out_err; |
|---|
| 1279 | | - } |
|---|
| 1280 | | - |
|---|
| 1281 | | -err_pagealloc_stop: |
|---|
| 1165 | + mlx5_eq_table_destroy(dev); |
|---|
| 1166 | +err_eq_table: |
|---|
| 1167 | + mlx5_irq_table_destroy(dev); |
|---|
| 1168 | +err_irq_table: |
|---|
| 1282 | 1169 | mlx5_pagealloc_stop(dev); |
|---|
| 1283 | | - |
|---|
| 1284 | | -reclaim_boot_pages: |
|---|
| 1285 | | - mlx5_reclaim_startup_pages(dev); |
|---|
| 1286 | | - |
|---|
| 1287 | | -err_disable_hca: |
|---|
| 1288 | | - mlx5_core_disable_hca(dev, 0); |
|---|
| 1289 | | - |
|---|
| 1290 | | -err_cmd_cleanup: |
|---|
| 1291 | | - mlx5_cmd_cleanup(dev); |
|---|
| 1292 | | - |
|---|
| 1293 | | -out_err: |
|---|
| 1294 | | - dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; |
|---|
| 1295 | | - mutex_unlock(&dev->intf_state_mutex); |
|---|
| 1296 | | - |
|---|
| 1170 | + mlx5_events_stop(dev); |
|---|
| 1171 | + mlx5_put_uars_page(dev, dev->priv.uar); |
|---|
| 1297 | 1172 | return err; |
|---|
| 1298 | 1173 | } |
|---|
| 1299 | 1174 | |
|---|
| 1300 | | -static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, |
|---|
| 1301 | | - bool cleanup) |
|---|
| 1175 | +static void mlx5_unload(struct mlx5_core_dev *dev) |
|---|
| 1176 | +{ |
|---|
| 1177 | + mlx5_ec_cleanup(dev); |
|---|
| 1178 | + mlx5_sriov_detach(dev); |
|---|
| 1179 | + mlx5_cleanup_fs(dev); |
|---|
| 1180 | + mlx5_accel_ipsec_cleanup(dev); |
|---|
| 1181 | + mlx5_accel_tls_cleanup(dev); |
|---|
| 1182 | + mlx5_fpga_device_stop(dev); |
|---|
| 1183 | + mlx5_rsc_dump_cleanup(dev); |
|---|
| 1184 | + mlx5_hv_vhca_cleanup(dev->hv_vhca); |
|---|
| 1185 | + mlx5_fw_reset_events_stop(dev); |
|---|
| 1186 | + mlx5_fw_tracer_cleanup(dev->tracer); |
|---|
| 1187 | + mlx5_eq_table_destroy(dev); |
|---|
| 1188 | + mlx5_irq_table_destroy(dev); |
|---|
| 1189 | + mlx5_pagealloc_stop(dev); |
|---|
| 1190 | + mlx5_events_stop(dev); |
|---|
| 1191 | + mlx5_put_uars_page(dev, dev->priv.uar); |
|---|
| 1192 | +} |
|---|
| 1193 | + |
|---|
| 1194 | +int mlx5_load_one(struct mlx5_core_dev *dev, bool boot) |
|---|
| 1302 | 1195 | { |
|---|
| 1303 | 1196 | int err = 0; |
|---|
| 1304 | 1197 | |
|---|
| 1305 | | - if (cleanup) |
|---|
| 1306 | | - mlx5_drain_health_recovery(dev); |
|---|
| 1307 | | - |
|---|
| 1308 | 1198 | mutex_lock(&dev->intf_state_mutex); |
|---|
| 1199 | + if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { |
|---|
| 1200 | + mlx5_core_warn(dev, "interface is up, NOP\n"); |
|---|
| 1201 | + goto out; |
|---|
| 1202 | + } |
|---|
| 1203 | + /* remove any previous indication of internal error */ |
|---|
| 1204 | + dev->state = MLX5_DEVICE_STATE_UP; |
|---|
| 1205 | + |
|---|
| 1206 | + err = mlx5_function_setup(dev, boot); |
|---|
| 1207 | + if (err) |
|---|
| 1208 | + goto err_function; |
|---|
| 1209 | + |
|---|
| 1210 | + if (boot) { |
|---|
| 1211 | + err = mlx5_init_once(dev); |
|---|
| 1212 | + if (err) { |
|---|
| 1213 | + mlx5_core_err(dev, "sw objs init failed\n"); |
|---|
| 1214 | + goto function_teardown; |
|---|
| 1215 | + } |
|---|
| 1216 | + } |
|---|
| 1217 | + |
|---|
| 1218 | + err = mlx5_load(dev); |
|---|
| 1219 | + if (err) |
|---|
| 1220 | + goto err_load; |
|---|
| 1221 | + |
|---|
| 1222 | + set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); |
|---|
| 1223 | + |
|---|
| 1224 | + if (boot) { |
|---|
| 1225 | + err = mlx5_devlink_register(priv_to_devlink(dev), dev->device); |
|---|
| 1226 | + if (err) |
|---|
| 1227 | + goto err_devlink_reg; |
|---|
| 1228 | + mlx5_register_device(dev); |
|---|
| 1229 | + } else { |
|---|
| 1230 | + mlx5_attach_device(dev); |
|---|
| 1231 | + } |
|---|
| 1232 | + |
|---|
| 1233 | + mutex_unlock(&dev->intf_state_mutex); |
|---|
| 1234 | + return 0; |
|---|
| 1235 | + |
|---|
| 1236 | +err_devlink_reg: |
|---|
| 1237 | + clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); |
|---|
| 1238 | + mlx5_unload(dev); |
|---|
| 1239 | +err_load: |
|---|
| 1240 | + if (boot) |
|---|
| 1241 | + mlx5_cleanup_once(dev); |
|---|
| 1242 | +function_teardown: |
|---|
| 1243 | + mlx5_function_teardown(dev, boot); |
|---|
| 1244 | +err_function: |
|---|
| 1245 | + dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; |
|---|
| 1246 | +out: |
|---|
| 1247 | + mutex_unlock(&dev->intf_state_mutex); |
|---|
| 1248 | + return err; |
|---|
| 1249 | +} |
|---|
| 1250 | + |
|---|
| 1251 | +void mlx5_unload_one(struct mlx5_core_dev *dev, bool cleanup) |
|---|
| 1252 | +{ |
|---|
| 1253 | + mutex_lock(&dev->intf_state_mutex); |
|---|
| 1254 | + |
|---|
| 1255 | + if (cleanup) { |
|---|
| 1256 | + mlx5_unregister_device(dev); |
|---|
| 1257 | + mlx5_devlink_unregister(priv_to_devlink(dev)); |
|---|
| 1258 | + } else { |
|---|
| 1259 | + mlx5_detach_device(dev); |
|---|
| 1260 | + } |
|---|
| 1261 | + |
|---|
| 1309 | 1262 | if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { |
|---|
| 1310 | | - dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", |
|---|
| 1311 | | - __func__); |
|---|
| 1263 | + mlx5_core_warn(dev, "%s: interface is down, NOP\n", |
|---|
| 1264 | + __func__); |
|---|
| 1312 | 1265 | if (cleanup) |
|---|
| 1313 | 1266 | mlx5_cleanup_once(dev); |
|---|
| 1314 | 1267 | goto out; |
|---|
| .. | .. |
|---|
| 1316 | 1269 | |
|---|
| 1317 | 1270 | clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); |
|---|
| 1318 | 1271 | |
|---|
| 1319 | | - if (mlx5_device_registered(dev)) |
|---|
| 1320 | | - mlx5_detach_device(dev); |
|---|
| 1272 | + mlx5_unload(dev); |
|---|
| 1321 | 1273 | |
|---|
| 1322 | | - mlx5_sriov_detach(dev); |
|---|
| 1323 | | - mlx5_cleanup_fs(dev); |
|---|
| 1324 | | - mlx5_accel_ipsec_cleanup(dev); |
|---|
| 1325 | | - mlx5_accel_tls_cleanup(dev); |
|---|
| 1326 | | - mlx5_fpga_device_stop(dev); |
|---|
| 1327 | | - mlx5_irq_clear_affinity_hints(dev); |
|---|
| 1328 | | - free_comp_eqs(dev); |
|---|
| 1329 | | - mlx5_fw_tracer_cleanup(dev->tracer); |
|---|
| 1330 | | - mlx5_stop_eqs(dev); |
|---|
| 1331 | | - mlx5_put_uars_page(dev, priv->uar); |
|---|
| 1332 | | - mlx5_free_irq_vectors(dev); |
|---|
| 1333 | 1274 | if (cleanup) |
|---|
| 1334 | 1275 | mlx5_cleanup_once(dev); |
|---|
| 1335 | | - mlx5_stop_health_poll(dev, cleanup); |
|---|
| 1336 | | - err = mlx5_cmd_teardown_hca(dev); |
|---|
| 1337 | | - if (err) { |
|---|
| 1338 | | - dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n"); |
|---|
| 1339 | | - goto out; |
|---|
| 1340 | | - } |
|---|
| 1341 | | - mlx5_pagealloc_stop(dev); |
|---|
| 1342 | | - mlx5_reclaim_startup_pages(dev); |
|---|
| 1343 | | - mlx5_core_disable_hca(dev, 0); |
|---|
| 1344 | | - mlx5_cmd_cleanup(dev); |
|---|
| 1345 | 1276 | |
|---|
| 1277 | + mlx5_function_teardown(dev, cleanup); |
|---|
| 1346 | 1278 | out: |
|---|
| 1347 | 1279 | mutex_unlock(&dev->intf_state_mutex); |
|---|
| 1348 | | - return err; |
|---|
| 1349 | 1280 | } |
|---|
| 1350 | 1281 | |
|---|
| 1351 | | -struct mlx5_core_event_handler { |
|---|
| 1352 | | - void (*event)(struct mlx5_core_dev *dev, |
|---|
| 1353 | | - enum mlx5_dev_event event, |
|---|
| 1354 | | - void *data); |
|---|
| 1355 | | -}; |
|---|
| 1356 | | - |
|---|
| 1357 | | -static const struct devlink_ops mlx5_devlink_ops = { |
|---|
| 1358 | | -#ifdef CONFIG_MLX5_ESWITCH |
|---|
| 1359 | | - .eswitch_mode_set = mlx5_devlink_eswitch_mode_set, |
|---|
| 1360 | | - .eswitch_mode_get = mlx5_devlink_eswitch_mode_get, |
|---|
| 1361 | | - .eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set, |
|---|
| 1362 | | - .eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get, |
|---|
| 1363 | | - .eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set, |
|---|
| 1364 | | - .eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get, |
|---|
| 1365 | | -#endif |
|---|
| 1366 | | -}; |
|---|
| 1367 | | - |
|---|
| 1368 | | -#define MLX5_IB_MOD "mlx5_ib" |
|---|
| 1369 | | -static int init_one(struct pci_dev *pdev, |
|---|
| 1370 | | - const struct pci_device_id *id) |
|---|
| 1282 | +static int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx) |
|---|
| 1371 | 1283 | { |
|---|
| 1372 | | - struct mlx5_core_dev *dev; |
|---|
| 1373 | | - struct devlink *devlink; |
|---|
| 1374 | | - struct mlx5_priv *priv; |
|---|
| 1284 | + struct mlx5_priv *priv = &dev->priv; |
|---|
| 1375 | 1285 | int err; |
|---|
| 1376 | 1286 | |
|---|
| 1377 | | - devlink = devlink_alloc(&mlx5_devlink_ops, sizeof(*dev)); |
|---|
| 1378 | | - if (!devlink) { |
|---|
| 1379 | | - dev_err(&pdev->dev, "kzalloc failed\n"); |
|---|
| 1380 | | - return -ENOMEM; |
|---|
| 1381 | | - } |
|---|
| 1382 | | - |
|---|
| 1383 | | - dev = devlink_priv(devlink); |
|---|
| 1384 | | - priv = &dev->priv; |
|---|
| 1385 | | - priv->pci_dev_data = id->driver_data; |
|---|
| 1386 | | - |
|---|
| 1387 | | - pci_set_drvdata(pdev, dev); |
|---|
| 1388 | | - |
|---|
| 1389 | | - dev->pdev = pdev; |
|---|
| 1390 | | - dev->event = mlx5_core_event; |
|---|
| 1391 | | - dev->profile = &profile[prof_sel]; |
|---|
| 1287 | + dev->profile = &profile[profile_idx]; |
|---|
| 1392 | 1288 | |
|---|
| 1393 | 1289 | INIT_LIST_HEAD(&priv->ctx_list); |
|---|
| 1394 | 1290 | spin_lock_init(&priv->ctx_lock); |
|---|
| 1395 | | - mutex_init(&dev->pci_status_mutex); |
|---|
| 1396 | 1291 | mutex_init(&dev->intf_state_mutex); |
|---|
| 1397 | 1292 | |
|---|
| 1398 | | - INIT_LIST_HEAD(&priv->waiting_events_list); |
|---|
| 1399 | | - priv->is_accum_events = false; |
|---|
| 1400 | | - |
|---|
| 1401 | | -#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING |
|---|
| 1402 | | - err = init_srcu_struct(&priv->pfault_srcu); |
|---|
| 1403 | | - if (err) { |
|---|
| 1404 | | - dev_err(&pdev->dev, "init_srcu_struct failed with error code %d\n", |
|---|
| 1405 | | - err); |
|---|
| 1406 | | - goto clean_dev; |
|---|
| 1407 | | - } |
|---|
| 1408 | | -#endif |
|---|
| 1409 | 1293 | mutex_init(&priv->bfregs.reg_head.lock); |
|---|
| 1410 | 1294 | mutex_init(&priv->bfregs.wc_head.lock); |
|---|
| 1411 | 1295 | INIT_LIST_HEAD(&priv->bfregs.reg_head.list); |
|---|
| 1412 | 1296 | INIT_LIST_HEAD(&priv->bfregs.wc_head.list); |
|---|
| 1413 | 1297 | |
|---|
| 1414 | | - err = mlx5_pci_init(dev, priv); |
|---|
| 1415 | | - if (err) { |
|---|
| 1416 | | - dev_err(&pdev->dev, "mlx5_pci_init failed with error code %d\n", err); |
|---|
| 1417 | | - goto clean_srcu; |
|---|
| 1418 | | - } |
|---|
| 1298 | + mutex_init(&priv->alloc_mutex); |
|---|
| 1299 | + mutex_init(&priv->pgdir_mutex); |
|---|
| 1300 | + INIT_LIST_HEAD(&priv->pgdir_list); |
|---|
| 1419 | 1301 | |
|---|
| 1302 | + priv->dbg_root = debugfs_create_dir(dev_name(dev->device), |
|---|
| 1303 | + mlx5_debugfs_root); |
|---|
| 1420 | 1304 | err = mlx5_health_init(dev); |
|---|
| 1421 | | - if (err) { |
|---|
| 1422 | | - dev_err(&pdev->dev, "mlx5_health_init failed with error code %d\n", err); |
|---|
| 1423 | | - goto close_pci; |
|---|
| 1305 | + if (err) |
|---|
| 1306 | + goto err_health_init; |
|---|
| 1307 | + |
|---|
| 1308 | + err = mlx5_pagealloc_init(dev); |
|---|
| 1309 | + if (err) |
|---|
| 1310 | + goto err_pagealloc_init; |
|---|
| 1311 | + |
|---|
| 1312 | + return 0; |
|---|
| 1313 | + |
|---|
| 1314 | +err_pagealloc_init: |
|---|
| 1315 | + mlx5_health_cleanup(dev); |
|---|
| 1316 | +err_health_init: |
|---|
| 1317 | + debugfs_remove(dev->priv.dbg_root); |
|---|
| 1318 | + mutex_destroy(&priv->pgdir_mutex); |
|---|
| 1319 | + mutex_destroy(&priv->alloc_mutex); |
|---|
| 1320 | + mutex_destroy(&priv->bfregs.wc_head.lock); |
|---|
| 1321 | + mutex_destroy(&priv->bfregs.reg_head.lock); |
|---|
| 1322 | + mutex_destroy(&dev->intf_state_mutex); |
|---|
| 1323 | + return err; |
|---|
| 1324 | +} |
|---|
| 1325 | + |
|---|
| 1326 | +static void mlx5_mdev_uninit(struct mlx5_core_dev *dev) |
|---|
| 1327 | +{ |
|---|
| 1328 | + struct mlx5_priv *priv = &dev->priv; |
|---|
| 1329 | + |
|---|
| 1330 | + mlx5_pagealloc_cleanup(dev); |
|---|
| 1331 | + mlx5_health_cleanup(dev); |
|---|
| 1332 | + debugfs_remove_recursive(dev->priv.dbg_root); |
|---|
| 1333 | + mutex_destroy(&priv->pgdir_mutex); |
|---|
| 1334 | + mutex_destroy(&priv->alloc_mutex); |
|---|
| 1335 | + mutex_destroy(&priv->bfregs.wc_head.lock); |
|---|
| 1336 | + mutex_destroy(&priv->bfregs.reg_head.lock); |
|---|
| 1337 | + mutex_destroy(&dev->intf_state_mutex); |
|---|
| 1338 | +} |
|---|
| 1339 | + |
|---|
| 1340 | +#define MLX5_IB_MOD "mlx5_ib" |
|---|
| 1341 | +static int init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
|---|
| 1342 | +{ |
|---|
| 1343 | + struct mlx5_core_dev *dev; |
|---|
| 1344 | + struct devlink *devlink; |
|---|
| 1345 | + int err; |
|---|
| 1346 | + |
|---|
| 1347 | + devlink = mlx5_devlink_alloc(); |
|---|
| 1348 | + if (!devlink) { |
|---|
| 1349 | + dev_err(&pdev->dev, "devlink alloc failed\n"); |
|---|
| 1350 | + return -ENOMEM; |
|---|
| 1424 | 1351 | } |
|---|
| 1425 | 1352 | |
|---|
| 1426 | | - mlx5_pagealloc_init(dev); |
|---|
| 1353 | + dev = devlink_priv(devlink); |
|---|
| 1354 | + dev->device = &pdev->dev; |
|---|
| 1355 | + dev->pdev = pdev; |
|---|
| 1427 | 1356 | |
|---|
| 1428 | | - err = mlx5_load_one(dev, priv, true); |
|---|
| 1357 | + dev->coredev_type = id->driver_data & MLX5_PCI_DEV_IS_VF ? |
|---|
| 1358 | + MLX5_COREDEV_VF : MLX5_COREDEV_PF; |
|---|
| 1359 | + |
|---|
| 1360 | + err = mlx5_mdev_init(dev, prof_sel); |
|---|
| 1361 | + if (err) |
|---|
| 1362 | + goto mdev_init_err; |
|---|
| 1363 | + |
|---|
| 1364 | + err = mlx5_pci_init(dev, pdev, id); |
|---|
| 1429 | 1365 | if (err) { |
|---|
| 1430 | | - dev_err(&pdev->dev, "mlx5_load_one failed with error code %d\n", err); |
|---|
| 1431 | | - goto clean_health; |
|---|
| 1366 | + mlx5_core_err(dev, "mlx5_pci_init failed with error code %d\n", |
|---|
| 1367 | + err); |
|---|
| 1368 | + goto pci_init_err; |
|---|
| 1369 | + } |
|---|
| 1370 | + |
|---|
| 1371 | + err = mlx5_load_one(dev, true); |
|---|
| 1372 | + if (err) { |
|---|
| 1373 | + mlx5_core_err(dev, "mlx5_load_one failed with error code %d\n", |
|---|
| 1374 | + err); |
|---|
| 1375 | + goto err_load_one; |
|---|
| 1432 | 1376 | } |
|---|
| 1433 | 1377 | |
|---|
| 1434 | 1378 | request_module_nowait(MLX5_IB_MOD); |
|---|
| 1435 | 1379 | |
|---|
| 1436 | | - err = devlink_register(devlink, &pdev->dev); |
|---|
| 1380 | + err = mlx5_crdump_enable(dev); |
|---|
| 1437 | 1381 | if (err) |
|---|
| 1438 | | - goto clean_load; |
|---|
| 1382 | + dev_err(&pdev->dev, "mlx5_crdump_enable failed with error code %d\n", err); |
|---|
| 1439 | 1383 | |
|---|
| 1440 | 1384 | pci_save_state(pdev); |
|---|
| 1385 | + if (!mlx5_core_is_mp_slave(dev)) |
|---|
| 1386 | + devlink_reload_enable(devlink); |
|---|
| 1441 | 1387 | return 0; |
|---|
| 1442 | 1388 | |
|---|
| 1443 | | -clean_load: |
|---|
| 1444 | | - mlx5_unload_one(dev, priv, true); |
|---|
| 1445 | | -clean_health: |
|---|
| 1446 | | - mlx5_pagealloc_cleanup(dev); |
|---|
| 1447 | | - mlx5_health_cleanup(dev); |
|---|
| 1448 | | -close_pci: |
|---|
| 1449 | | - mlx5_pci_close(dev, priv); |
|---|
| 1450 | | -clean_srcu: |
|---|
| 1451 | | -#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING |
|---|
| 1452 | | - cleanup_srcu_struct(&priv->pfault_srcu); |
|---|
| 1453 | | -clean_dev: |
|---|
| 1454 | | -#endif |
|---|
| 1455 | | - devlink_free(devlink); |
|---|
| 1389 | +err_load_one: |
|---|
| 1390 | + mlx5_pci_close(dev); |
|---|
| 1391 | +pci_init_err: |
|---|
| 1392 | + mlx5_mdev_uninit(dev); |
|---|
| 1393 | +mdev_init_err: |
|---|
| 1394 | + mlx5_devlink_free(devlink); |
|---|
| 1456 | 1395 | |
|---|
| 1457 | 1396 | return err; |
|---|
| 1458 | 1397 | } |
|---|
| .. | .. |
|---|
| 1461 | 1400 | { |
|---|
| 1462 | 1401 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); |
|---|
| 1463 | 1402 | struct devlink *devlink = priv_to_devlink(dev); |
|---|
| 1464 | | - struct mlx5_priv *priv = &dev->priv; |
|---|
| 1465 | 1403 | |
|---|
| 1466 | | - devlink_unregister(devlink); |
|---|
| 1467 | | - mlx5_unregister_device(dev); |
|---|
| 1468 | | - |
|---|
| 1469 | | - if (mlx5_unload_one(dev, priv, true)) { |
|---|
| 1470 | | - dev_err(&dev->pdev->dev, "mlx5_unload_one failed\n"); |
|---|
| 1471 | | - mlx5_health_cleanup(dev); |
|---|
| 1472 | | - return; |
|---|
| 1473 | | - } |
|---|
| 1474 | | - |
|---|
| 1475 | | - mlx5_pagealloc_cleanup(dev); |
|---|
| 1476 | | - mlx5_health_cleanup(dev); |
|---|
| 1477 | | - mlx5_pci_close(dev, priv); |
|---|
| 1478 | | -#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING |
|---|
| 1479 | | - cleanup_srcu_struct(&priv->pfault_srcu); |
|---|
| 1480 | | -#endif |
|---|
| 1481 | | - devlink_free(devlink); |
|---|
| 1404 | + devlink_reload_disable(devlink); |
|---|
| 1405 | + mlx5_crdump_disable(dev); |
|---|
| 1406 | + mlx5_drain_health_wq(dev); |
|---|
| 1407 | + mlx5_unload_one(dev, true); |
|---|
| 1408 | + mlx5_pci_close(dev); |
|---|
| 1409 | + mlx5_mdev_uninit(dev); |
|---|
| 1410 | + mlx5_devlink_free(devlink); |
|---|
| 1482 | 1411 | } |
|---|
| 1483 | 1412 | |
|---|
| 1484 | 1413 | static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev, |
|---|
| 1485 | 1414 | pci_channel_state_t state) |
|---|
| 1486 | 1415 | { |
|---|
| 1487 | 1416 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); |
|---|
| 1488 | | - struct mlx5_priv *priv = &dev->priv; |
|---|
| 1489 | 1417 | |
|---|
| 1490 | | - dev_info(&pdev->dev, "%s was called\n", __func__); |
|---|
| 1418 | + mlx5_core_info(dev, "%s was called\n", __func__); |
|---|
| 1491 | 1419 | |
|---|
| 1492 | 1420 | mlx5_enter_error_state(dev, false); |
|---|
| 1493 | | - mlx5_unload_one(dev, priv, false); |
|---|
| 1494 | | - /* In case of kernel call drain the health wq */ |
|---|
| 1495 | | - if (state) { |
|---|
| 1496 | | - mlx5_drain_health_wq(dev); |
|---|
| 1497 | | - mlx5_pci_disable_device(dev); |
|---|
| 1498 | | - } |
|---|
| 1421 | + mlx5_error_sw_reset(dev); |
|---|
| 1422 | + mlx5_unload_one(dev, false); |
|---|
| 1423 | + mlx5_drain_health_wq(dev); |
|---|
| 1424 | + mlx5_pci_disable_device(dev); |
|---|
| 1499 | 1425 | |
|---|
| 1500 | 1426 | return state == pci_channel_io_perm_failure ? |
|---|
| 1501 | 1427 | PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; |
|---|
| .. | .. |
|---|
| 1517 | 1443 | count = ioread32be(health->health_counter); |
|---|
| 1518 | 1444 | if (count && count != 0xffffffff) { |
|---|
| 1519 | 1445 | if (last_count && last_count != count) { |
|---|
| 1520 | | - dev_info(&pdev->dev, "Counter value 0x%x after %d iterations\n", count, i); |
|---|
| 1446 | + mlx5_core_info(dev, |
|---|
| 1447 | + "wait vital counter value 0x%x after %d iterations\n", |
|---|
| 1448 | + count, i); |
|---|
| 1521 | 1449 | return 0; |
|---|
| 1522 | 1450 | } |
|---|
| 1523 | 1451 | last_count = count; |
|---|
| .. | .. |
|---|
| 1533 | 1461 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); |
|---|
| 1534 | 1462 | int err; |
|---|
| 1535 | 1463 | |
|---|
| 1536 | | - dev_info(&pdev->dev, "%s was called\n", __func__); |
|---|
| 1464 | + mlx5_core_info(dev, "%s was called\n", __func__); |
|---|
| 1537 | 1465 | |
|---|
| 1538 | 1466 | err = mlx5_pci_enable_device(dev); |
|---|
| 1539 | 1467 | if (err) { |
|---|
| 1540 | | - dev_err(&pdev->dev, "%s: mlx5_pci_enable_device failed with error code: %d\n" |
|---|
| 1541 | | - , __func__, err); |
|---|
| 1468 | + mlx5_core_err(dev, "%s: mlx5_pci_enable_device failed with error code: %d\n", |
|---|
| 1469 | + __func__, err); |
|---|
| 1542 | 1470 | return PCI_ERS_RESULT_DISCONNECT; |
|---|
| 1543 | 1471 | } |
|---|
| 1544 | 1472 | |
|---|
| .. | .. |
|---|
| 1547 | 1475 | pci_save_state(pdev); |
|---|
| 1548 | 1476 | |
|---|
| 1549 | 1477 | if (wait_vital(pdev)) { |
|---|
| 1550 | | - dev_err(&pdev->dev, "%s: wait_vital timed out\n", __func__); |
|---|
| 1478 | + mlx5_core_err(dev, "%s: wait_vital timed out\n", __func__); |
|---|
| 1551 | 1479 | return PCI_ERS_RESULT_DISCONNECT; |
|---|
| 1552 | 1480 | } |
|---|
| 1553 | 1481 | |
|---|
| .. | .. |
|---|
| 1557 | 1485 | static void mlx5_pci_resume(struct pci_dev *pdev) |
|---|
| 1558 | 1486 | { |
|---|
| 1559 | 1487 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); |
|---|
| 1560 | | - struct mlx5_priv *priv = &dev->priv; |
|---|
| 1561 | 1488 | int err; |
|---|
| 1562 | 1489 | |
|---|
| 1563 | | - dev_info(&pdev->dev, "%s was called\n", __func__); |
|---|
| 1490 | + mlx5_core_info(dev, "%s was called\n", __func__); |
|---|
| 1564 | 1491 | |
|---|
| 1565 | | - err = mlx5_load_one(dev, priv, false); |
|---|
| 1492 | + err = mlx5_load_one(dev, false); |
|---|
| 1566 | 1493 | if (err) |
|---|
| 1567 | | - dev_err(&pdev->dev, "%s: mlx5_load_one failed with error code: %d\n" |
|---|
| 1568 | | - , __func__, err); |
|---|
| 1494 | + mlx5_core_err(dev, "%s: mlx5_load_one failed with error code: %d\n", |
|---|
| 1495 | + __func__, err); |
|---|
| 1569 | 1496 | else |
|---|
| 1570 | | - dev_info(&pdev->dev, "%s: device recovered\n", __func__); |
|---|
| 1497 | + mlx5_core_info(dev, "%s: device recovered\n", __func__); |
|---|
| 1571 | 1498 | } |
|---|
| 1572 | 1499 | |
|---|
| 1573 | 1500 | static const struct pci_error_handlers mlx5_err_handler = { |
|---|
| .. | .. |
|---|
| 1578 | 1505 | |
|---|
| 1579 | 1506 | static int mlx5_try_fast_unload(struct mlx5_core_dev *dev) |
|---|
| 1580 | 1507 | { |
|---|
| 1581 | | - int ret; |
|---|
| 1508 | + bool fast_teardown = false, force_teardown = false; |
|---|
| 1509 | + int ret = 1; |
|---|
| 1582 | 1510 | |
|---|
| 1583 | | - if (!MLX5_CAP_GEN(dev, force_teardown)) { |
|---|
| 1584 | | - mlx5_core_dbg(dev, "force teardown is not supported in the firmware\n"); |
|---|
| 1511 | + fast_teardown = MLX5_CAP_GEN(dev, fast_teardown); |
|---|
| 1512 | + force_teardown = MLX5_CAP_GEN(dev, force_teardown); |
|---|
| 1513 | + |
|---|
| 1514 | + mlx5_core_dbg(dev, "force teardown firmware support=%d\n", force_teardown); |
|---|
| 1515 | + mlx5_core_dbg(dev, "fast teardown firmware support=%d\n", fast_teardown); |
|---|
| 1516 | + |
|---|
| 1517 | + if (!fast_teardown && !force_teardown) |
|---|
| 1585 | 1518 | return -EOPNOTSUPP; |
|---|
| 1586 | | - } |
|---|
| 1587 | 1519 | |
|---|
| 1588 | 1520 | if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { |
|---|
| 1589 | 1521 | mlx5_core_dbg(dev, "Device in internal error state, giving up\n"); |
|---|
| .. | .. |
|---|
| 1596 | 1528 | mlx5_drain_health_wq(dev); |
|---|
| 1597 | 1529 | mlx5_stop_health_poll(dev, false); |
|---|
| 1598 | 1530 | |
|---|
| 1599 | | - ret = mlx5_cmd_force_teardown_hca(dev); |
|---|
| 1600 | | - if (ret) { |
|---|
| 1601 | | - mlx5_core_dbg(dev, "Firmware couldn't do fast unload error: %d\n", ret); |
|---|
| 1602 | | - mlx5_start_health_poll(dev); |
|---|
| 1603 | | - return ret; |
|---|
| 1604 | | - } |
|---|
| 1531 | + ret = mlx5_cmd_fast_teardown_hca(dev); |
|---|
| 1532 | + if (!ret) |
|---|
| 1533 | + goto succeed; |
|---|
| 1605 | 1534 | |
|---|
| 1535 | + ret = mlx5_cmd_force_teardown_hca(dev); |
|---|
| 1536 | + if (!ret) |
|---|
| 1537 | + goto succeed; |
|---|
| 1538 | + |
|---|
| 1539 | + mlx5_core_dbg(dev, "Firmware couldn't do fast unload error: %d\n", ret); |
|---|
| 1540 | + mlx5_start_health_poll(dev); |
|---|
| 1541 | + return ret; |
|---|
| 1542 | + |
|---|
| 1543 | +succeed: |
|---|
| 1606 | 1544 | mlx5_enter_error_state(dev, true); |
|---|
| 1607 | 1545 | |
|---|
| 1608 | 1546 | /* Some platforms requiring freeing the IRQ's in the shutdown |
|---|
| .. | .. |
|---|
| 1610 | 1548 | * kexec. There is no need to cleanup the mlx5_core software |
|---|
| 1611 | 1549 | * contexts. |
|---|
| 1612 | 1550 | */ |
|---|
| 1613 | | - mlx5_irq_clear_affinity_hints(dev); |
|---|
| 1614 | 1551 | mlx5_core_eq_free_irqs(dev); |
|---|
| 1615 | 1552 | |
|---|
| 1616 | 1553 | return 0; |
|---|
| .. | .. |
|---|
| 1619 | 1556 | static void shutdown(struct pci_dev *pdev) |
|---|
| 1620 | 1557 | { |
|---|
| 1621 | 1558 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); |
|---|
| 1622 | | - struct mlx5_priv *priv = &dev->priv; |
|---|
| 1623 | 1559 | int err; |
|---|
| 1624 | 1560 | |
|---|
| 1625 | | - dev_info(&pdev->dev, "Shutdown was called\n"); |
|---|
| 1561 | + mlx5_core_info(dev, "Shutdown was called\n"); |
|---|
| 1626 | 1562 | err = mlx5_try_fast_unload(dev); |
|---|
| 1627 | 1563 | if (err) |
|---|
| 1628 | | - mlx5_unload_one(dev, priv, false); |
|---|
| 1564 | + mlx5_unload_one(dev, false); |
|---|
| 1629 | 1565 | mlx5_pci_disable_device(dev); |
|---|
| 1566 | +} |
|---|
| 1567 | + |
|---|
| 1568 | +static int mlx5_suspend(struct pci_dev *pdev, pm_message_t state) |
|---|
| 1569 | +{ |
|---|
| 1570 | + struct mlx5_core_dev *dev = pci_get_drvdata(pdev); |
|---|
| 1571 | + |
|---|
| 1572 | + mlx5_unload_one(dev, false); |
|---|
| 1573 | + |
|---|
| 1574 | + return 0; |
|---|
| 1575 | +} |
|---|
| 1576 | + |
|---|
| 1577 | +static int mlx5_resume(struct pci_dev *pdev) |
|---|
| 1578 | +{ |
|---|
| 1579 | + struct mlx5_core_dev *dev = pci_get_drvdata(pdev); |
|---|
| 1580 | + |
|---|
| 1581 | + return mlx5_load_one(dev, false); |
|---|
| 1630 | 1582 | } |
|---|
| 1631 | 1583 | |
|---|
| 1632 | 1584 | static const struct pci_device_id mlx5_core_pci_table[] = { |
|---|
| .. | .. |
|---|
| 1642 | 1594 | { PCI_VDEVICE(MELLANOX, 0x101a), MLX5_PCI_DEV_IS_VF}, /* ConnectX-5 Ex VF */ |
|---|
| 1643 | 1595 | { PCI_VDEVICE(MELLANOX, 0x101b) }, /* ConnectX-6 */ |
|---|
| 1644 | 1596 | { PCI_VDEVICE(MELLANOX, 0x101c), MLX5_PCI_DEV_IS_VF}, /* ConnectX-6 VF */ |
|---|
| 1597 | + { PCI_VDEVICE(MELLANOX, 0x101d) }, /* ConnectX-6 Dx */ |
|---|
| 1598 | + { PCI_VDEVICE(MELLANOX, 0x101e), MLX5_PCI_DEV_IS_VF}, /* ConnectX Family mlx5Gen Virtual Function */ |
|---|
| 1599 | + { PCI_VDEVICE(MELLANOX, 0x101f) }, /* ConnectX-6 LX */ |
|---|
| 1600 | + { PCI_VDEVICE(MELLANOX, 0x1021) }, /* ConnectX-7 */ |
|---|
| 1645 | 1601 | { PCI_VDEVICE(MELLANOX, 0xa2d2) }, /* BlueField integrated ConnectX-5 network controller */ |
|---|
| 1646 | 1602 | { PCI_VDEVICE(MELLANOX, 0xa2d3), MLX5_PCI_DEV_IS_VF}, /* BlueField integrated ConnectX-5 network controller VF */ |
|---|
| 1647 | 1603 | { PCI_VDEVICE(MELLANOX, 0xa2d6) }, /* BlueField-2 integrated ConnectX-6 Dx network controller */ |
|---|
| .. | .. |
|---|
| 1652 | 1608 | |
|---|
| 1653 | 1609 | void mlx5_disable_device(struct mlx5_core_dev *dev) |
|---|
| 1654 | 1610 | { |
|---|
| 1655 | | - mlx5_pci_err_detected(dev->pdev, 0); |
|---|
| 1611 | + mlx5_error_sw_reset(dev); |
|---|
| 1612 | + mlx5_unload_one(dev, false); |
|---|
| 1656 | 1613 | } |
|---|
| 1657 | 1614 | |
|---|
| 1658 | 1615 | void mlx5_recover_device(struct mlx5_core_dev *dev) |
|---|
| .. | .. |
|---|
| 1667 | 1624 | .id_table = mlx5_core_pci_table, |
|---|
| 1668 | 1625 | .probe = init_one, |
|---|
| 1669 | 1626 | .remove = remove_one, |
|---|
| 1627 | + .suspend = mlx5_suspend, |
|---|
| 1628 | + .resume = mlx5_resume, |
|---|
| 1670 | 1629 | .shutdown = shutdown, |
|---|
| 1671 | 1630 | .err_handler = &mlx5_err_handler, |
|---|
| 1672 | 1631 | .sriov_configure = mlx5_core_sriov_configure, |
|---|
| .. | .. |
|---|
| 1683 | 1642 | } |
|---|
| 1684 | 1643 | } |
|---|
| 1685 | 1644 | |
|---|
| 1686 | | -static int __init init(void) |
|---|
| 1645 | +static int __init mlx5_init(void) |
|---|
| 1687 | 1646 | { |
|---|
| 1688 | 1647 | int err; |
|---|
| 1689 | 1648 | |
|---|
| .. | .. |
|---|
| 1708 | 1667 | return err; |
|---|
| 1709 | 1668 | } |
|---|
| 1710 | 1669 | |
|---|
| 1711 | | -static void __exit cleanup(void) |
|---|
| 1670 | +static void __exit mlx5_cleanup(void) |
|---|
| 1712 | 1671 | { |
|---|
| 1713 | 1672 | #ifdef CONFIG_MLX5_CORE_EN |
|---|
| 1714 | 1673 | mlx5e_cleanup(); |
|---|
| .. | .. |
|---|
| 1717 | 1676 | mlx5_unregister_debugfs(); |
|---|
| 1718 | 1677 | } |
|---|
| 1719 | 1678 | |
|---|
| 1720 | | -module_init(init); |
|---|
| 1721 | | -module_exit(cleanup); |
|---|
| 1679 | +module_init(mlx5_init); |
|---|
| 1680 | +module_exit(mlx5_cleanup); |
|---|