Commit 813cf9d1 authored by Jonathan Cooper's avatar Jonathan Cooper Committed by David S. Miller

sfc: Split STATE_READY in to STATE_NET_DOWN and STATE_NET_UP.

This patch splits the READY state in to NET_UP and NET_DOWN. This
is to prepare for future work to delay resource allocation until
interface up so that we can use resources more efficiently in
SRIOV environments, and also to lay the ground work for an extra
PROBED state where we don't create a network interface,
for VDPA operation.
Signed-off-by: default avatarJonathan Cooper <jonathan.s.cooper@amd.com>
Acked-by: default avatarMartin Habets <habetsm.xilinx@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent da8ff2a2
......@@ -96,6 +96,8 @@ static int ef100_net_stop(struct net_device *net_dev)
efx_mcdi_free_vis(efx);
efx_remove_interrupts(efx);
efx->state = STATE_NET_DOWN;
return 0;
}
......@@ -172,6 +174,8 @@ static int ef100_net_open(struct net_device *net_dev)
efx_link_status_changed(efx);
mutex_unlock(&efx->mac_lock);
efx->state = STATE_NET_UP;
return 0;
fail:
......@@ -271,7 +275,7 @@ int ef100_register_netdev(struct efx_nic *efx)
/* Always start with carrier off; PHY events will detect the link */
netif_carrier_off(net_dev);
efx->state = STATE_READY;
efx->state = STATE_NET_DOWN;
rtnl_unlock();
efx_init_mcdi_logging(efx);
......
......@@ -106,14 +106,6 @@ static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp);
static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs,
u32 flags);
#define EFX_ASSERT_RESET_SERIALISED(efx) \
do { \
if ((efx->state == STATE_READY) || \
(efx->state == STATE_RECOVERY) || \
(efx->state == STATE_DISABLED)) \
ASSERT_RTNL(); \
} while (0)
/**************************************************************************
*
* Port handling
......@@ -378,6 +370,8 @@ static int efx_probe_all(struct efx_nic *efx)
if (rc)
goto fail5;
efx->state = STATE_NET_DOWN;
return 0;
fail5:
......@@ -544,6 +538,9 @@ int efx_net_open(struct net_device *net_dev)
efx_start_all(efx);
if (efx->state == STATE_DISABLED || efx->reset_pending)
netif_device_detach(efx->net_dev);
else
efx->state = STATE_NET_UP;
efx_selftest_async_start(efx);
return 0;
}
......@@ -720,8 +717,6 @@ static int efx_register_netdev(struct efx_nic *efx)
* already requested. If so, the NIC is probably hosed so we
* abort.
*/
efx->state = STATE_READY;
smp_mb(); /* ensure we change state before checking reset_pending */
if (efx->reset_pending) {
pci_err(efx->pci_dev, "aborting probe due to scheduled reset\n");
rc = -EIO;
......@@ -748,6 +743,8 @@ static int efx_register_netdev(struct efx_nic *efx)
efx_associate(efx);
efx->state = STATE_NET_DOWN;
rtnl_unlock();
rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type);
......@@ -845,7 +842,7 @@ static void efx_pci_remove_main(struct efx_nic *efx)
/* Flush reset_work. It can no longer be scheduled since we
* are not READY.
*/
BUG_ON(efx->state == STATE_READY);
WARN_ON(efx_net_active(efx->state));
efx_flush_reset_workqueue(efx);
efx_disable_interrupts(efx);
......@@ -1150,13 +1147,13 @@ static int efx_pm_freeze(struct device *dev)
rtnl_lock();
if (efx->state != STATE_DISABLED) {
efx->state = STATE_UNINIT;
if (efx_net_active(efx->state)) {
efx_device_detach_sync(efx);
efx_stop_all(efx);
efx_disable_interrupts(efx);
efx->state = efx_freeze(efx->state);
}
rtnl_unlock();
......@@ -1171,7 +1168,7 @@ static int efx_pm_thaw(struct device *dev)
rtnl_lock();
if (efx->state != STATE_DISABLED) {
if (efx_frozen(efx->state)) {
rc = efx_enable_interrupts(efx);
if (rc)
goto fail;
......@@ -1184,7 +1181,7 @@ static int efx_pm_thaw(struct device *dev)
efx_device_attach_if_not_resetting(efx);
efx->state = STATE_READY;
efx->state = efx_thaw(efx->state);
efx->type->resume_wol(efx);
}
......
......@@ -898,7 +898,7 @@ static void efx_reset_work(struct work_struct *data)
* have changed by now. Now that we have the RTNL lock,
* it cannot change again.
*/
if (efx->state == STATE_READY)
if (efx_net_active(efx->state))
(void)efx_reset(efx, method);
rtnl_unlock();
......@@ -908,7 +908,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
{
enum reset_type method;
if (efx->state == STATE_RECOVERY) {
if (efx_recovering(efx->state)) {
netif_dbg(efx, drv, efx->net_dev,
"recovering: skip scheduling %s reset\n",
RESET_TYPE(type));
......@@ -943,7 +943,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
/* If we're not READY then just leave the flags set as the cue
* to abort probing or reschedule the reset later.
*/
if (READ_ONCE(efx->state) != STATE_READY)
if (!efx_net_active(READ_ONCE(efx->state)))
return;
/* efx_process_channel() will no longer read events once a
......@@ -1217,7 +1217,7 @@ static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev,
rtnl_lock();
if (efx->state != STATE_DISABLED) {
efx->state = STATE_RECOVERY;
efx->state = efx_recover(efx->state);
efx->reset_pending = 0;
efx_device_detach_sync(efx);
......@@ -1271,7 +1271,7 @@ static void efx_io_resume(struct pci_dev *pdev)
netif_err(efx, hw, efx->net_dev,
"efx_reset failed after PCI error (%d)\n", rc);
} else {
efx->state = STATE_READY;
efx->state = efx_recovered(efx->state);
netif_dbg(efx, hw, efx->net_dev,
"Done resetting and resuming IO after PCI error.\n");
}
......
......@@ -45,9 +45,7 @@ int efx_reconfigure_port(struct efx_nic *efx);
#define EFX_ASSERT_RESET_SERIALISED(efx) \
do { \
if ((efx->state == STATE_READY) || \
(efx->state == STATE_RECOVERY) || \
(efx->state == STATE_DISABLED)) \
if (efx->state != STATE_UNINIT) \
ASSERT_RTNL(); \
} while (0)
......@@ -64,7 +62,7 @@ void efx_port_dummy_op_void(struct efx_nic *efx);
static inline int efx_check_disabled(struct efx_nic *efx)
{
if (efx->state == STATE_DISABLED || efx->state == STATE_RECOVERY) {
if (efx->state == STATE_DISABLED || efx_recovering(efx->state)) {
netif_err(efx, drv, efx->net_dev,
"device is disabled due to earlier errors\n");
return -EIO;
......
......@@ -137,7 +137,7 @@ void efx_ethtool_self_test(struct net_device *net_dev,
if (!efx_tests)
goto fail;
if (efx->state != STATE_READY) {
if (!efx_net_active(efx->state)) {
rc = -EBUSY;
goto out;
}
......
......@@ -622,12 +622,54 @@ enum efx_int_mode {
#define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI)
enum nic_state {
STATE_UNINIT = 0, /* device being probed/removed or is frozen */
STATE_READY = 1, /* hardware ready and netdev registered */
STATE_DISABLED = 2, /* device disabled due to hardware errors */
STATE_RECOVERY = 3, /* device recovering from PCI error */
STATE_UNINIT = 0, /* device being probed/removed */
STATE_NET_DOWN, /* hardware probed and netdev registered */
STATE_NET_UP, /* ready for traffic */
STATE_DISABLED, /* device disabled due to hardware errors */
STATE_RECOVERY = 0x100,/* recovering from PCI error */
STATE_FROZEN = 0x200, /* frozen by power management */
};
static inline bool efx_net_active(enum nic_state state)
{
return state == STATE_NET_DOWN || state == STATE_NET_UP;
}
static inline bool efx_frozen(enum nic_state state)
{
return state & STATE_FROZEN;
}
static inline bool efx_recovering(enum nic_state state)
{
return state & STATE_RECOVERY;
}
static inline enum nic_state efx_freeze(enum nic_state state)
{
WARN_ON(!efx_net_active(state));
return state | STATE_FROZEN;
}
static inline enum nic_state efx_thaw(enum nic_state state)
{
WARN_ON(!efx_frozen(state));
return state & ~STATE_FROZEN;
}
static inline enum nic_state efx_recover(enum nic_state state)
{
WARN_ON(!efx_net_active(state));
return state | STATE_RECOVERY;
}
static inline enum nic_state efx_recovered(enum nic_state state)
{
WARN_ON(!efx_recovering(state));
return state & ~STATE_RECOVERY;
}
/* Forward declaration */
struct efx_nic;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment