static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, unsigned int loopback_modes) { enum efx_loopback_mode mode; struct efx_loopback_state *state; struct efx_tx_queue *tx_queue; int rc = 0; /* Set the port loopback_selftest member. From this point on * all received packets will be dropped. Mark the state as * "flushing" so all inflight packets are dropped */ state = kzalloc(sizeof(*state), GFP_KERNEL); if (state == NULL) return -ENOMEM; BUG_ON(efx->loopback_selftest); state->flush = true; efx->loopback_selftest = state; /* Test all supported loopback modes */ for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { if (!(loopback_modes & (1 << mode))) continue; /* Move the port into the specified loopback mode. */ state->flush = true; mutex_lock(&efx->mac_lock); efx->loopback_mode = mode; rc = __efx_reconfigure_port(efx); mutex_unlock(&efx->mac_lock); if (rc) { EFX_ERR(efx, "unable to move into %s loopback\n", LOOPBACK_MODE(efx)); goto out; } rc = efx_wait_for_link(efx); if (rc) { EFX_ERR(efx, "loopback %s never came up\n", LOOPBACK_MODE(efx)); goto out; } /* Test every TX queue */ efx_for_each_tx_queue(tx_queue, efx) { state->offload_csum = (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM); rc = efx_test_loopback(tx_queue, &tests->loopback[mode]); if (rc) goto out; } }
static void falcon_monitor(struct efx_nic *efx) { bool link_changed; int rc; BUG_ON(!mutex_is_locked(&efx->mac_lock)); rc = falcon_board(efx)->type->monitor(efx); if (rc) { netif_err(efx, hw, efx->net_dev, "Board sensor %s; shutting down PHY\n", (rc == -ERANGE) ? "reported fault" : "failed"); efx->phy_mode |= PHY_MODE_LOW_POWER; rc = __efx_reconfigure_port(efx); WARN_ON(rc); } if (LOOPBACK_INTERNAL(efx)) link_changed = falcon_loopback_link_poll(efx); else link_changed = efx->phy_op->poll(efx); if (link_changed) { falcon_stop_nic_stats(efx); falcon_deconfigure_mac_wrapper(efx); falcon_reset_macs(efx); rc = falcon_reconfigure_xmac(efx); BUG_ON(rc); falcon_start_nic_stats(efx); efx_link_status_changed(efx); } falcon_poll_xmac(efx); }