Skip to content

Commit 57502f6

Browse files
mosheshemesh2kuba-moo
authored andcommitted
net/mlx5: Add support for sync reset using hot reset
On device that supports sync reset for firmware activate using hot reset, the driver queries the required reset method while handling the sync reset request. If the required reset method is hot reset, the driver will use pci_reset_bus() to reset the PCI link instead of the link toggle. Signed-off-by: Moshe Shemesh <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 9947204 commit 57502f6

File tree

2 files changed

+69
-16
lines changed

2 files changed

+69
-16
lines changed

drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct mlx5_fw_reset {
2626
struct work_struct reset_now_work;
2727
struct work_struct reset_abort_work;
2828
unsigned long reset_flags;
29+
u8 reset_method;
2930
struct timer_list timer;
3031
struct completion done;
3132
int ret;
@@ -95,7 +96,7 @@ static int mlx5_reg_mfrl_set(struct mlx5_core_dev *dev, u8 reset_level,
9596
}
9697

9798
static int mlx5_reg_mfrl_query(struct mlx5_core_dev *dev, u8 *reset_level,
98-
u8 *reset_type, u8 *reset_state)
99+
u8 *reset_type, u8 *reset_state, u8 *reset_method)
99100
{
100101
u32 out[MLX5_ST_SZ_DW(mfrl_reg)] = {};
101102
u32 in[MLX5_ST_SZ_DW(mfrl_reg)] = {};
@@ -111,21 +112,34 @@ static int mlx5_reg_mfrl_query(struct mlx5_core_dev *dev, u8 *reset_level,
111112
*reset_type = MLX5_GET(mfrl_reg, out, reset_type);
112113
if (reset_state)
113114
*reset_state = MLX5_GET(mfrl_reg, out, reset_state);
115+
if (reset_method)
116+
*reset_method = MLX5_GET(mfrl_reg, out, pci_reset_req_method);
114117

115118
return 0;
116119
}
117120

118121
int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_type)
119122
{
120-
return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL);
123+
return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL, NULL);
124+
}
125+
126+
static int mlx5_fw_reset_get_reset_method(struct mlx5_core_dev *dev,
127+
u8 *reset_method)
128+
{
129+
if (!MLX5_CAP_GEN(dev, pcie_reset_using_hotreset_method)) {
130+
*reset_method = MLX5_MFRL_REG_PCI_RESET_METHOD_LINK_TOGGLE;
131+
return 0;
132+
}
133+
134+
return mlx5_reg_mfrl_query(dev, NULL, NULL, NULL, reset_method);
121135
}
122136

123137
static int mlx5_fw_reset_get_reset_state_err(struct mlx5_core_dev *dev,
124138
struct netlink_ext_ack *extack)
125139
{
126140
u8 reset_state;
127141

128-
if (mlx5_reg_mfrl_query(dev, NULL, NULL, &reset_state))
142+
if (mlx5_reg_mfrl_query(dev, NULL, NULL, &reset_state, NULL))
129143
goto out;
130144

131145
if (!reset_state)
@@ -427,7 +441,11 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
427441
struct mlx5_core_dev *dev = fw_reset->dev;
428442
int err;
429443

430-
if (test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
444+
err = mlx5_fw_reset_get_reset_method(dev, &fw_reset->reset_method);
445+
if (err)
446+
mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err);
447+
448+
if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
431449
!mlx5_is_reset_now_capable(dev)) {
432450
err = mlx5_fw_reset_set_reset_sync_nack(dev);
433451
mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s",
@@ -444,21 +462,15 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
444462
mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack. Device reset is expected.\n");
445463
}
446464

447-
static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
465+
static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev, u16 dev_id)
448466
{
449467
struct pci_bus *bridge_bus = dev->pdev->bus;
450468
struct pci_dev *bridge = bridge_bus->self;
451469
unsigned long timeout;
452470
struct pci_dev *sdev;
453-
u16 reg16, dev_id;
454471
int cap, err;
472+
u16 reg16;
455473

456-
err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
457-
if (err)
458-
return pcibios_err_to_errno(err);
459-
err = mlx5_check_dev_ids(dev, dev_id);
460-
if (err)
461-
return err;
462474
cap = pci_find_capability(bridge, PCI_CAP_ID_EXP);
463475
if (!cap)
464476
return -EOPNOTSUPP;
@@ -528,6 +540,44 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
528540
return err;
529541
}
530542

543+
static int mlx5_pci_reset_bus(struct mlx5_core_dev *dev)
544+
{
545+
if (!MLX5_CAP_GEN(dev, pcie_reset_using_hotreset_method))
546+
return -EOPNOTSUPP;
547+
548+
return pci_reset_bus(dev->pdev);
549+
}
550+
551+
static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
552+
{
553+
u16 dev_id;
554+
int err;
555+
556+
err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
557+
if (err)
558+
return pcibios_err_to_errno(err);
559+
err = mlx5_check_dev_ids(dev, dev_id);
560+
if (err)
561+
return err;
562+
563+
switch (reset_method) {
564+
case MLX5_MFRL_REG_PCI_RESET_METHOD_LINK_TOGGLE:
565+
err = mlx5_pci_link_toggle(dev, dev_id);
566+
if (err)
567+
mlx5_core_warn(dev, "mlx5_pci_link_toggle failed\n");
568+
break;
569+
case MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET:
570+
err = mlx5_pci_reset_bus(dev);
571+
if (err)
572+
mlx5_core_warn(dev, "mlx5_pci_reset_bus failed\n");
573+
break;
574+
default:
575+
return -EOPNOTSUPP;
576+
}
577+
578+
return err;
579+
}
580+
531581
static void mlx5_sync_reset_now_event(struct work_struct *work)
532582
{
533583
struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
@@ -546,9 +596,9 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
546596
goto done;
547597
}
548598

549-
err = mlx5_pci_link_toggle(dev);
599+
err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
550600
if (err) {
551-
mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, no reset done, err %d\n", err);
601+
mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, no reset done, err %d\n", err);
552602
set_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags);
553603
}
554604

@@ -610,9 +660,9 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
610660

611661
mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state);
612662
if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
613-
err = mlx5_pci_link_toggle(dev);
663+
err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
614664
if (err) {
615-
mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, err %d\n", err);
665+
mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err);
616666
fw_reset->ret = err;
617667
}
618668
}

drivers/net/ethernet/mellanox/mlx5/core/main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,9 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
619619
if (MLX5_CAP_GEN_MAX(dev, pci_sync_for_fw_update_with_driver_unload))
620620
MLX5_SET(cmd_hca_cap, set_hca_cap,
621621
pci_sync_for_fw_update_with_driver_unload, 1);
622+
if (MLX5_CAP_GEN_MAX(dev, pcie_reset_using_hotreset_method))
623+
MLX5_SET(cmd_hca_cap, set_hca_cap,
624+
pcie_reset_using_hotreset_method, 1);
622625

623626
if (MLX5_CAP_GEN_MAX(dev, num_vhca_ports))
624627
MLX5_SET(cmd_hca_cap,

0 commit comments

Comments
 (0)