.. | .. |
---|
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); |
---|