Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 315447
b: refs/heads/master
c: d4f2cec
h: refs/heads/master
i:
  315445: dbc7eab
  315443: 5fd819f
  315439: 9048ec6
v: v3
  • Loading branch information
Ben Hutchings committed Jul 17, 2012
1 parent 9d7f7b4 commit d8c4eb4
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 61 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f1e54ae52b950ed79074ae794d027d6c97fd34e
refs/heads/master: d4f2cecce138c34960c467d0ae38a6d4bcd6af7b
35 changes: 31 additions & 4 deletions trunk/drivers/net/ethernet/sfc/falcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}

/**************************************************************************
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 5 additions & 2 deletions trunk/drivers/net/ethernet/sfc/net_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
#define EFX_TXQ_TYPES 4
#define EFX_MAX_TX_QUEUES (EFX_TXQ_TYPES * EFX_MAX_CHANNELS)

struct efx_self_tests;

/**
* struct efx_special_buffer - An Efx special buffer
* @addr: CPU base address of the buffer
Expand Down Expand Up @@ -901,7 +903,8 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* @get_wol: Get WoL configuration from driver state
* @set_wol: Push WoL configuration to the NIC
* @resume_wol: Synchronise WoL state between driver and MC (e.g. after resume)
* @test_registers: Test read/write functionality of control registers
* @test_chip: Test registers. Should use efx_nic_test_registers(), and is
* expected to reset the NIC.
* @test_nvram: Test validity of NVRAM contents
* @revision: Hardware architecture revision
* @mem_map_size: Memory BAR mapped size
Expand Down Expand Up @@ -946,7 +949,7 @@ struct efx_nic_type {
void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol);
int (*set_wol)(struct efx_nic *efx, u32 type);
void (*resume_wol)(struct efx_nic *efx);
int (*test_registers)(struct efx_nic *efx);
int (*test_chip)(struct efx_nic *efx, struct efx_self_tests *tests);
int (*test_nvram)(struct efx_nic *efx);

int revision;
Expand Down
3 changes: 0 additions & 3 deletions trunk/drivers/net/ethernet/sfc/nic.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,6 @@ int efx_nic_test_registers(struct efx_nic *efx,
unsigned address = 0, i, j;
efx_oword_t mask, imask, original, reg, buf;

/* Falcon should be in loopback to isolate the XMAC from the PHY */
WARN_ON(!LOOPBACK_INTERNAL(efx));

for (i = 0; i < n_regs; ++i) {
address = regs[i].address;
mask = imask = regs[i].mask;
Expand Down
62 changes: 15 additions & 47 deletions trunk/drivers/net/ethernet/sfc/selftest.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,6 @@ static int efx_test_nvram(struct efx_nic *efx, struct efx_self_tests *tests)
return rc;
}

static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
{
int rc = 0;

/* Test register access */
if (efx->type->test_registers) {
rc = efx->type->test_registers(efx);
tests->registers = rc ? -1 : 1;
}

return rc;
}

/**************************************************************************
*
* Interrupt and event queue testing
Expand Down Expand Up @@ -699,8 +686,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
{
enum efx_loopback_mode loopback_mode = efx->loopback_mode;
int phy_mode = efx->phy_mode;
enum reset_type reset_method = RESET_TYPE_INVISIBLE;
int rc_test = 0, rc_reset = 0, rc;
int rc_test = 0, rc_reset, rc;

efx_selftest_async_cancel(efx);

Expand Down Expand Up @@ -737,44 +723,26 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
*/
netif_device_detach(efx->net_dev);

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);

/* free up all consumers of SRAM (including all the queues) */
efx_reset_down(efx, reset_method);

rc = efx_test_chip(efx, tests);
if (rc && !rc_test)
rc_test = rc;
if (efx->type->test_chip) {
rc_reset = efx->type->test_chip(efx, tests);
if (rc_reset) {
netif_err(efx, hw, efx->net_dev,
"Unable to recover from chip test\n");
efx_schedule_reset(efx, RESET_TYPE_DISABLE);
return rc_reset;
}

/* reset the chip to recover from the register test */
rc_reset = efx->type->reset(efx, reset_method);
if ((tests->registers < 0) && !rc_test)
rc_test = -EIO;
}

/* Ensure that the phy is powered and out of loopback
* for the bist and loopback tests */
mutex_lock(&efx->mac_lock);
efx->phy_mode &= ~PHY_MODE_LOW_POWER;
efx->loopback_mode = LOOPBACK_NONE;

rc = efx_reset_up(efx, reset_method, rc_reset == 0);
if (rc && !rc_reset)
rc_reset = rc;

if (rc_reset) {
netif_err(efx, drv, efx->net_dev,
"Unable to recover from chip test\n");
efx_schedule_reset(efx, RESET_TYPE_DISABLE);
return rc_reset;
}
__efx_reconfigure_port(efx);
mutex_unlock(&efx->mac_lock);

rc = efx_test_phy(efx, tests, flags);
if (rc && !rc_test)
Expand Down
29 changes: 25 additions & 4 deletions trunk/drivers/net/ethernet/sfc/siena.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}

/**************************************************************************
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit d8c4eb4

Please sign in to comment.