]> git.baikalelectronics.ru Git - kernel.git/commitdiff
sfc: Split STATE_READY in to STATE_NET_DOWN and STATE_NET_UP.
authorJonathan Cooper <jonathan.s.cooper@amd.com>
Tue, 28 Jun 2022 13:58:55 +0000 (14:58 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 29 Jun 2022 12:40:46 +0000 (13:40 +0100)
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: Jonathan Cooper <jonathan.s.cooper@amd.com>
Acked-by: Martin Habets <habetsm.xilinx@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/ef100_netdev.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/efx_common.c
drivers/net/ethernet/sfc/efx_common.h
drivers/net/ethernet/sfc/ethtool_common.c
drivers/net/ethernet/sfc/net_driver.h

index 67fe44db6b6124438291cf20b2f828d8d559035c..b9106ce678d9f3b4d4a53bfd53cdc9b521322d7f 100644 (file)
@@ -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);
 
index 5a772354da831ecfdd92c90d99d34f66e40c6b68..7f4e96a422e68364964690c187a2f8be505f5773 100644 (file)
@@ -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);
        }
index f6577e74d6e6fc80be761ba1c4c5f7ae407fa46c..f6baebd9d6323cc5528831d89bbb28fb5d8828e4 100644 (file)
@@ -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");
        }
index 65513fd0cf6c469fe25aca8260924298e320956e..c72e819da8fd358d5c3cd495e2edf62e18d600a6 100644 (file)
@@ -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;
index bd552c7dffcb1b2c30a92f7c15d1e985129472e1..3846b76b89720d07b706bbf2626866a141bb822d 100644 (file)
@@ -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;
        }
index 723bbeea5d0c98036b884432bbcb3c9de35fe885..95069125931a441c30644a9ee62d8e9b8b25c193 100644 (file)
@@ -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;