summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/sfc/siena.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-07-04 06:58:33 +0400
committerBen Hutchings <bhutchings@solarflare.com>2012-07-17 19:12:33 +0400
commitd4f2cecce138c34960c467d0ae38a6d4bcd6af7b (patch)
tree19a93bad8f6a56361b3b2f12beecae97be4d8ea0 /drivers/net/ethernet/sfc/siena.c
parent0f1e54ae52b950ed79074ae794d027d6c97fd34e (diff)
downloadlinux-d4f2cecce138c34960c467d0ae38a6d4bcd6af7b.tar.xz
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>
Diffstat (limited to 'drivers/net/ethernet/sfc/siena.c')
-rw-r--r--drivers/net/ethernet/sfc/siena.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index 9f8d7cea3967..2354886293db 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -25,10 +25,12 @@
#include "workarounds.h"
#include "mcdi.h"
#include "mcdi_pcol.h"
+#include "selftest.h"
/* Hardware control for SFC9000 family including SFL9021 (aka Siena). */
static void siena_init_wol(struct efx_nic *efx);
+static int siena_reset_hw(struct efx_nic *efx, enum reset_type method);
static void siena_push_irq_moderation(struct efx_channel *channel)
@@ -154,10 +156,29 @@ static const struct efx_nic_register_test siena_register_tests[] = {
EFX_OWORD32(0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000) },
};
-static int siena_test_registers(struct efx_nic *efx)
+static int siena_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
{
- return efx_nic_test_registers(efx, siena_register_tests,
- ARRAY_SIZE(siena_register_tests));
+ enum reset_type reset_method = reset_method;
+ int rc, rc2;
+
+ efx_reset_down(efx, reset_method);
+
+ /* Reset the chip immediately so that it is completely
+ * quiescent regardless of what any VF driver does.
+ */
+ rc = siena_reset_hw(efx, reset_method);
+ if (rc)
+ goto out;
+
+ tests->registers =
+ efx_nic_test_registers(efx, siena_register_tests,
+ ARRAY_SIZE(siena_register_tests))
+ ? -1 : 1;
+
+ rc = siena_reset_hw(efx, reset_method);
+out:
+ rc2 = efx_reset_up(efx, reset_method, rc == 0);
+ return rc ? rc : rc2;
}
/**************************************************************************
@@ -649,7 +670,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.get_wol = siena_get_wol,
.set_wol = siena_set_wol,
.resume_wol = siena_init_wol,
- .test_registers = siena_test_registers,
+ .test_chip = siena_test_chip,
.test_nvram = efx_mcdi_nvram_test_all,
.revision = EFX_REV_SIENA_A0,