rc = efx->phy_op->init(efx);
        if (rc)
                return rc;
-       efx->phy_op->reconfigure(efx);
-
        mutex_lock(&efx->mac_lock);
+       efx->phy_op->reconfigure(efx);
        rc = falcon_switch_mac(efx);
        mutex_unlock(&efx->mac_lock);
        if (rc)
 
 /* Tears down the entire software state and most of the hardware state
  * before reset.  */
-void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+                   struct ethtool_cmd *ecmd)
 {
        EFX_ASSERT_RESET_SERIALISED(efx);
 
        efx->phy_op->get_settings(efx, ecmd);
 
        efx_fini_channels(efx);
+       if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
+               efx->phy_op->fini(efx);
 }
 
 /* This function will always ensure that the locks acquired in
  * 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. */
-int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
+int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+                struct ethtool_cmd *ecmd, bool ok)
 {
        int rc;
 
                ok = false;
        }
 
+       if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) {
+               if (ok) {
+                       rc = efx->phy_op->init(efx);
+                       if (rc)
+                               ok = false;
+               } else
+                       efx->port_initialized = false;
+       }
+
        if (ok) {
                efx_init_channels(efx);
 
 
        EFX_INFO(efx, "resetting (%d)\n", method);
 
-       efx_reset_down(efx, &ecmd);
+       efx_reset_down(efx, method, &ecmd);
 
        rc = falcon_reset_hw(efx, method);
        if (rc) {
 
        /* Leave device stopped if necessary */
        if (method == RESET_TYPE_DISABLE) {
-               efx_reset_up(efx, &ecmd, false);
+               efx_reset_up(efx, method, &ecmd, false);
                rc = -EIO;
        } else {
-               rc = efx_reset_up(efx, &ecmd, true);
+               rc = efx_reset_up(efx, method, &ecmd, true);
        }
 
 out_disable:
 
 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);
+extern void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+                          struct ethtool_cmd *ecmd);
+extern int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+                       struct ethtool_cmd *ecmd, bool ok);
 
 /* Global */
 extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
 
 {
        enum efx_loopback_mode loopback_mode = efx->loopback_mode;
        int phy_mode = efx->phy_mode;
+       enum reset_type reset_method = RESET_TYPE_INVISIBLE;
        struct ethtool_cmd ecmd;
        struct efx_channel *channel;
        int rc_test = 0, rc_reset = 0, rc;
        mutex_unlock(&efx->mac_lock);
 
        /* free up all consumers of SRAM (including all the queues) */
-       efx_reset_down(efx, &ecmd);
+       efx_reset_down(efx, reset_method, &ecmd);
 
        rc = efx_test_chip(efx, tests);
        if (rc && !rc_test)
                rc_test = rc;
 
        /* reset the chip to recover from the register test */
-       rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL);
+       rc_reset = falcon_reset_hw(efx, reset_method);
 
        /* Ensure that the phy is powered and out of loopback
         * for the bist and loopback tests */
        efx->phy_mode &= ~PHY_MODE_LOW_POWER;
        efx->loopback_mode = LOOPBACK_NONE;
 
-       rc = efx_reset_up(efx, &ecmd, rc_reset == 0);
+       rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0);
        if (rc && !rc_reset)
                rc_reset = rc;