Skip to content

Commit

Permalink
sfc: Extend self-tests
Browse files Browse the repository at this point in the history
Include PMA/PMD in loopback self-tests as intended.

Add NVRAM checksum validation and include it in self-tests.

Add register self-tests.

Run PHY self-tests where available.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
  • Loading branch information
Ben Hutchings authored and Jeff Garzik committed Sep 3, 2008
1 parent a515089 commit 8c8661e
Show file tree
Hide file tree
Showing 12 changed files with 429 additions and 184 deletions.
19 changes: 18 additions & 1 deletion drivers/net/sfc/bitfield.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,12 +416,23 @@ typedef union efx_oword {
* for read-modify-write operations.
*
*/

#define EFX_INVERT_OWORD(oword) do { \
(oword).u64[0] = ~((oword).u64[0]); \
(oword).u64[1] = ~((oword).u64[1]); \
} while (0)

#define EFX_AND_OWORD(oword, from, mask) \
do { \
(oword).u64[0] = (from).u64[0] & (mask).u64[0]; \
(oword).u64[1] = (from).u64[1] & (mask).u64[1]; \
} while (0)

#define EFX_OR_OWORD(oword, from, mask) \
do { \
(oword).u64[0] = (from).u64[0] | (mask).u64[0]; \
(oword).u64[1] = (from).u64[1] | (mask).u64[1]; \
} while (0)

#define EFX_INSERT64(min, max, low, high, value) \
cpu_to_le64(EFX_INSERT_NATIVE(min, max, low, high, value))

Expand Down Expand Up @@ -529,4 +540,10 @@ typedef union efx_oword {
#define EFX_DMA_TYPE_WIDTH(width) \
(((width) < DMA_ADDR_T_WIDTH) ? (width) : DMA_ADDR_T_WIDTH)


/* Static initialiser */
#define EFX_OWORD32(a, b, c, d) \
{ .u32 = { __constant_cpu_to_le32(a), __constant_cpu_to_le32(b), \
__constant_cpu_to_le32(c), __constant_cpu_to_le32(d) } }

#endif /* EFX_BITFIELD_H */
20 changes: 14 additions & 6 deletions drivers/net/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,11 @@ static void efx_link_status_changed(struct efx_nic *efx)
if (!netif_running(efx->net_dev))
return;

if (efx->port_inhibited) {
netif_carrier_off(efx->net_dev);
return;
}

if (efx->link_up != netif_carrier_ok(efx->net_dev)) {
efx->n_link_state_changes++;

Expand Down Expand Up @@ -549,7 +554,7 @@ static void efx_link_status_changed(struct efx_nic *efx)

/* This call reinitialises the MAC to pick up new PHY settings. The
* caller must hold the mac_lock */
static void __efx_reconfigure_port(struct efx_nic *efx)
void __efx_reconfigure_port(struct efx_nic *efx)
{
WARN_ON(!mutex_is_locked(&efx->mac_lock));

Expand Down Expand Up @@ -634,6 +639,7 @@ static int efx_init_port(struct efx_nic *efx)
return rc;

efx->port_initialized = true;
efx->stats_enabled = true;

/* Reconfigure port to program MAC registers */
falcon_reconfigure_xmac(efx);
Expand Down Expand Up @@ -1311,7 +1317,7 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
*/
if (!spin_trylock(&efx->stats_lock))
return stats;
if (efx->state == STATE_RUNNING) {
if (efx->stats_enabled) {
falcon_update_stats_xmac(efx);
falcon_update_nic_stats(efx);
}
Expand Down Expand Up @@ -1529,7 +1535,7 @@ static void efx_unregister_netdev(struct efx_nic *efx)

/* Tears down the entire software state and most of the hardware state
* before reset. */
static void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
int rc;

Expand All @@ -1538,6 +1544,7 @@ static void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
/* The net_dev->get_stats handler is quite slow, and will fail
* if a fetch is pending over reset. Serialise against it. */
spin_lock(&efx->stats_lock);
efx->stats_enabled = false;
spin_unlock(&efx->stats_lock);

efx_stop_all(efx);
Expand All @@ -1555,8 +1562,7 @@ static void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
* that we were unable to reinitialise the hardware, and the
* driver should be disabled. If ok is false, then the rx and tx
* engines are not restarted, pending a RESET_DISABLE. */
static int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
bool ok)
int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
{
int rc;

Expand All @@ -1577,8 +1583,10 @@ static int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,

mutex_unlock(&efx->mac_lock);

if (ok)
if (ok) {
efx_start_all(efx);
efx->stats_enabled = true;
}
return rc;
}

Expand Down
6 changes: 6 additions & 0 deletions drivers/net/sfc/efx.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ extern void efx_flush_queues(struct efx_nic *efx);

/* Ports */
extern void efx_reconfigure_port(struct efx_nic *efx);
extern void __efx_reconfigure_port(struct efx_nic *efx);

/* Reset handling */
extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd);
extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
bool ok);

/* Global */
extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
Expand Down
22 changes: 10 additions & 12 deletions drivers/net/sfc/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,10 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
unsigned int n = 0;
enum efx_loopback_mode mode;

/* Interrupt */
efx_fill_test(n++, strings, data, &tests->mii,
"core", 0, "mii", NULL);
efx_fill_test(n++, strings, data, &tests->nvram,
"core", 0, "nvram", NULL);
efx_fill_test(n++, strings, data, &tests->interrupt,
"core", 0, "interrupt", NULL);

Expand All @@ -353,16 +356,17 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
"eventq.poll", NULL);
}

/* PHY presence */
efx_fill_test(n++, strings, data, &tests->phy_ok,
EFX_PORT_NAME, "phy_ok", NULL);
efx_fill_test(n++, strings, data, &tests->registers,
"core", 0, "registers", NULL);
efx_fill_test(n++, strings, data, &tests->phy,
EFX_PORT_NAME, "phy", NULL);

/* Loopback tests */
efx_fill_test(n++, strings, data, &tests->loopback_speed,
EFX_PORT_NAME, "loopback.speed", NULL);
efx_fill_test(n++, strings, data, &tests->loopback_full_duplex,
EFX_PORT_NAME, "loopback.full_duplex", NULL);
for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) {
for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) {
if (!(efx->loopback_modes & (1 << mode)))
continue;
n = efx_fill_loopback_test(efx,
Expand Down Expand Up @@ -500,15 +504,9 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
goto out;

/* Perform offline tests only if online tests passed */
if (offline) {
/* Stop the kernel from sending packets during the test. */
efx_stop_queue(efx);
efx_flush_queues(efx);

if (offline)
rc = efx_offline_test(efx, &efx_tests,
efx->loopback_modes);
efx_wake_queue(efx);
}

out:
if (!already_up)
Expand Down
Loading

0 comments on commit 8c8661e

Please sign in to comment.