Commit 5a1a00f6ac320659fcc6240bd88fb9731a7c7b90

Authored by Ido Schimmel
Committed by Greg Kroah-Hartman
1 parent 6e75284e24

mlxsw: pci: Only issue reset when system is ready

[ Upstream commit 6002059d7882c3512e6ac52fa82424272ddfcd5c ]

During initialization the driver issues a software reset command and
then waits for the system status to change back to "ready" state.

However, before issuing the reset command the driver does not check that
the system is actually in "ready" state. On Spectrum-{1,2} systems this
was always the case as the hardware initialization time is very short.
On Spectrum-3 systems this is no longer the case. This results in the
software reset command timing-out and the driver failing to load:

[ 6.347591] mlxsw_spectrum3 0000:06:00.0: Cmd exec timed-out (opcode=40(ACCESS_REG),opcode_mod=0,in_mod=0)
[ 6.358382] mlxsw_spectrum3 0000:06:00.0: Reg cmd access failed (reg_id=9023(mrsr),type=write)
[ 6.368028] mlxsw_spectrum3 0000:06:00.0: cannot register bus device
[ 6.375274] mlxsw_spectrum3: probe of 0000:06:00.0 failed with error -110

Fix this by waiting for the system to become ready both before issuing
the reset command and afterwards. In case of failure, print the last
system status to aid in debugging.

Fixes: da382875c616 ("mlxsw: spectrum: Extend to support Spectrum-3 ASIC")
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 39 additions and 11 deletions Side-by-side Diff

drivers/net/ethernet/mellanox/mlxsw/pci.c
... ... @@ -1318,34 +1318,62 @@
1318 1318 mbox->mapaddr);
1319 1319 }
1320 1320  
1321   -static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci,
1322   - const struct pci_device_id *id)
  1321 +static int mlxsw_pci_sys_ready_wait(struct mlxsw_pci *mlxsw_pci,
  1322 + const struct pci_device_id *id,
  1323 + u32 *p_sys_status)
1323 1324 {
1324 1325 unsigned long end;
1325   - char mrsr_pl[MLXSW_REG_MRSR_LEN];
1326   - int err;
  1326 + u32 val;
1327 1327  
1328   - mlxsw_reg_mrsr_pack(mrsr_pl);
1329   - err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl);
1330   - if (err)
1331   - return err;
1332 1328 if (id->device == PCI_DEVICE_ID_MELLANOX_SWITCHX2) {
1333 1329 msleep(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS);
1334 1330 return 0;
1335 1331 }
1336 1332  
1337   - /* We must wait for the HW to become responsive once again. */
  1333 + /* We must wait for the HW to become responsive. */
1338 1334 msleep(MLXSW_PCI_SW_RESET_WAIT_MSECS);
1339 1335  
1340 1336 end = jiffies + msecs_to_jiffies(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS);
1341 1337 do {
1342   - u32 val = mlxsw_pci_read32(mlxsw_pci, FW_READY);
1343   -
  1338 + val = mlxsw_pci_read32(mlxsw_pci, FW_READY);
1344 1339 if ((val & MLXSW_PCI_FW_READY_MASK) == MLXSW_PCI_FW_READY_MAGIC)
1345 1340 return 0;
1346 1341 cond_resched();
1347 1342 } while (time_before(jiffies, end));
  1343 +
  1344 + *p_sys_status = val & MLXSW_PCI_FW_READY_MASK;
  1345 +
1348 1346 return -EBUSY;
  1347 +}
  1348 +
  1349 +static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci,
  1350 + const struct pci_device_id *id)
  1351 +{
  1352 + struct pci_dev *pdev = mlxsw_pci->pdev;
  1353 + char mrsr_pl[MLXSW_REG_MRSR_LEN];
  1354 + u32 sys_status;
  1355 + int err;
  1356 +
  1357 + err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status);
  1358 + if (err) {
  1359 + dev_err(&pdev->dev, "Failed to reach system ready status before reset. Status is 0x%x\n",
  1360 + sys_status);
  1361 + return err;
  1362 + }
  1363 +
  1364 + mlxsw_reg_mrsr_pack(mrsr_pl);
  1365 + err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl);
  1366 + if (err)
  1367 + return err;
  1368 +
  1369 + err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status);
  1370 + if (err) {
  1371 + dev_err(&pdev->dev, "Failed to reach system ready status after reset. Status is 0x%x\n",
  1372 + sys_status);
  1373 + return err;
  1374 + }
  1375 +
  1376 + return 0;
1349 1377 }
1350 1378  
1351 1379 static int mlxsw_pci_alloc_irq_vectors(struct mlxsw_pci *mlxsw_pci)