sfc: Disable VF queues during register self-test
Currently VF queues and drivers may remain active during this test. This could cause memory corruption or spurious test failures. Therefore we reset the port/function before running these tests on Siena. On Falcon this doesn't work: we have to do some additional initialisation before some blocks will work again. So refactor the reset/register-test sequence into an efx_nic_type method so efx_selftest() doesn't have to consider such quirks. In the process, fix another minor bug: Siena does not have an 'invisible' reset and the self-test currently fails to push the PHY configuration after resetting. Passing RESET_TYPE_ALL to efx_reset_{down,up}() fixes this. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
This commit is contained in:
@@ -25,9 +25,12 @@
|
||||
#include "io.h"
|
||||
#include "phy.h"
|
||||
#include "workarounds.h"
|
||||
#include "selftest.h"
|
||||
|
||||
/* Hardware control for SFC4000 (aka Falcon). */
|
||||
|
||||
static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method);
|
||||
|
||||
static const unsigned int
|
||||
/* "Large" EEPROM device: Atmel AT25640 or similar
|
||||
* 8 KB, 16-bit address, 32 B write block */
|
||||
@@ -1034,10 +1037,34 @@ static const struct efx_nic_register_test falcon_b0_register_tests[] = {
|
||||
EFX_OWORD32(0x0003FF0F, 0x00000000, 0x00000000, 0x00000000) },
|
||||
};
|
||||
|
||||
static int falcon_b0_test_registers(struct efx_nic *efx)
|
||||
static int
|
||||
falcon_b0_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
|
||||
{
|
||||
return efx_nic_test_registers(efx, falcon_b0_register_tests,
|
||||
ARRAY_SIZE(falcon_b0_register_tests));
|
||||
enum reset_type reset_method = RESET_TYPE_INVISIBLE;
|
||||
int rc, rc2;
|
||||
|
||||
mutex_lock(&efx->mac_lock);
|
||||
if (efx->loopback_modes) {
|
||||
/* We need the 312 clock from the PHY to test the XMAC
|
||||
* registers, so move into XGMII loopback if available */
|
||||
if (efx->loopback_modes & (1 << LOOPBACK_XGMII))
|
||||
efx->loopback_mode = LOOPBACK_XGMII;
|
||||
else
|
||||
efx->loopback_mode = __ffs(efx->loopback_modes);
|
||||
}
|
||||
__efx_reconfigure_port(efx);
|
||||
mutex_unlock(&efx->mac_lock);
|
||||
|
||||
efx_reset_down(efx, reset_method);
|
||||
|
||||
tests->registers =
|
||||
efx_nic_test_registers(efx, falcon_b0_register_tests,
|
||||
ARRAY_SIZE(falcon_b0_register_tests))
|
||||
? -1 : 1;
|
||||
|
||||
rc = falcon_reset_hw(efx, reset_method);
|
||||
rc2 = efx_reset_up(efx, reset_method, rc == 0);
|
||||
return rc ? rc : rc2;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
@@ -1818,7 +1845,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
|
||||
.get_wol = falcon_get_wol,
|
||||
.set_wol = falcon_set_wol,
|
||||
.resume_wol = efx_port_dummy_op_void,
|
||||
.test_registers = falcon_b0_test_registers,
|
||||
.test_chip = falcon_b0_test_chip,
|
||||
.test_nvram = falcon_test_nvram,
|
||||
|
||||
.revision = EFX_REV_FALCON_B0,
|
||||
|
Reference in New Issue
Block a user