Skip to content

Commit 0602697

Browse files
idoschdavem330
authored andcommitted
mlxsw: pci: Fix driver initialization with Spectrum-4
Cited commit added support for a new reset flow ("all reset") which is deeper than the existing reset flow ("software reset") and allows the device's PCI firmware to be upgraded. In the new flow the driver first tells the firmware that "all reset" is required by issuing a new reset command (i.e., MRSR.command=6) and then triggers the reset by having the PCI core issue a secondary bus reset (SBR). However, due to a race condition in the device's firmware the device is not always able to recover from this reset, resulting in initialization failures [1]. New firmware versions include a fix for the bug and advertise it using a new capability bit in the Management Capabilities Mask (MCAM) register. Avoid initialization failures by reading the new capability bit and triggering the new reset flow only if the bit is set. If the bit is not set, trigger a normal PCI hot reset by skipping the call to the Management Reset and Shutdown Register (MRSR). Normal PCI hot reset is weaker than "all reset", but it results in a fully operational driver and allows users to flash a new firmware, if they want to. [1] mlxsw_spectrum4 0000:01:00.0: not ready 1023ms after bus reset; waiting mlxsw_spectrum4 0000:01:00.0: not ready 2047ms after bus reset; waiting mlxsw_spectrum4 0000:01:00.0: not ready 4095ms after bus reset; waiting mlxsw_spectrum4 0000:01:00.0: not ready 8191ms after bus reset; waiting mlxsw_spectrum4 0000:01:00.0: not ready 16383ms after bus reset; waiting mlxsw_spectrum4 0000:01:00.0: not ready 32767ms after bus reset; waiting mlxsw_spectrum4 0000:01:00.0: not ready 65535ms after bus reset; giving up mlxsw_spectrum4 0000:01:00.0: PCI function reset failed with -25 mlxsw_spectrum4 0000:01:00.0: cannot register bus device mlxsw_spectrum4: probe of 0000:01:00.0 failed with error -25 Fixes: f257c73 ("mlxsw: pci: Add support for new reset flow") Reported-by: Maksym Yaremchuk <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Tested-by: Maksym Yaremchuk <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: Petr Machata <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 11b006d commit 0602697

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

drivers/net/ethernet/mellanox/mlxsw/pci.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,18 +1594,25 @@ static int mlxsw_pci_sys_ready_wait(struct mlxsw_pci *mlxsw_pci,
15941594
return -EBUSY;
15951595
}
15961596

1597-
static int mlxsw_pci_reset_at_pci_disable(struct mlxsw_pci *mlxsw_pci)
1597+
static int mlxsw_pci_reset_at_pci_disable(struct mlxsw_pci *mlxsw_pci,
1598+
bool pci_reset_sbr_supported)
15981599
{
15991600
struct pci_dev *pdev = mlxsw_pci->pdev;
16001601
char mrsr_pl[MLXSW_REG_MRSR_LEN];
16011602
int err;
16021603

1604+
if (!pci_reset_sbr_supported) {
1605+
pci_dbg(pdev, "Performing PCI hot reset instead of \"all reset\"\n");
1606+
goto sbr;
1607+
}
1608+
16031609
mlxsw_reg_mrsr_pack(mrsr_pl,
16041610
MLXSW_REG_MRSR_COMMAND_RESET_AT_PCI_DISABLE);
16051611
err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl);
16061612
if (err)
16071613
return err;
16081614

1615+
sbr:
16091616
device_lock_assert(&pdev->dev);
16101617

16111618
pci_cfg_access_lock(pdev);
@@ -1633,6 +1640,7 @@ static int
16331640
mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)
16341641
{
16351642
struct pci_dev *pdev = mlxsw_pci->pdev;
1643+
bool pci_reset_sbr_supported = false;
16361644
char mcam_pl[MLXSW_REG_MCAM_LEN];
16371645
bool pci_reset_supported = false;
16381646
u32 sys_status;
@@ -1652,13 +1660,17 @@ mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)
16521660
mlxsw_reg_mcam_pack(mcam_pl,
16531661
MLXSW_REG_MCAM_FEATURE_GROUP_ENHANCED_FEATURES);
16541662
err = mlxsw_reg_query(mlxsw_pci->core, MLXSW_REG(mcam), mcam_pl);
1655-
if (!err)
1663+
if (!err) {
16561664
mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_PCI_RESET,
16571665
&pci_reset_supported);
1666+
mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_PCI_RESET_SBR,
1667+
&pci_reset_sbr_supported);
1668+
}
16581669

16591670
if (pci_reset_supported) {
16601671
pci_dbg(pdev, "Starting PCI reset flow\n");
1661-
err = mlxsw_pci_reset_at_pci_disable(mlxsw_pci);
1672+
err = mlxsw_pci_reset_at_pci_disable(mlxsw_pci,
1673+
pci_reset_sbr_supported);
16621674
} else {
16631675
pci_dbg(pdev, "Starting software reset flow\n");
16641676
err = mlxsw_pci_reset_sw(mlxsw_pci);

drivers/net/ethernet/mellanox/mlxsw/reg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10671,6 +10671,8 @@ enum mlxsw_reg_mcam_mng_feature_cap_mask_bits {
1067110671
MLXSW_REG_MCAM_MCIA_128B = 34,
1067210672
/* If set, MRSR.command=6 is supported. */
1067310673
MLXSW_REG_MCAM_PCI_RESET = 48,
10674+
/* If set, MRSR.command=6 is supported with Secondary Bus Reset. */
10675+
MLXSW_REG_MCAM_PCI_RESET_SBR = 67,
1067410676
};
1067510677

1067610678
#define MLXSW_REG_BYTES_PER_DWORD 0x4

0 commit comments

Comments
 (0)