void (*init)(struct r8152 *);
                int (*enable)(struct r8152 *);
                void (*disable)(struct r8152 *);
+               void (*up)(struct r8152 *);
                void (*down)(struct r8152 *);
                void (*unload)(struct r8152 *);
        } rtl_ops;
        }
 
        r8152b_disable_aldps(tp);
+
+       rtl_clear_bp(tp);
+
+       r8152b_enable_aldps(tp);
        set_bit(PHY_RESET, &tp->flags);
 }
 
        ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 
        rxdy_gated_en(tp, true);
+       r8152b_hw_phy_cfg(tp);
 
        ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
        ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, 0x00);
                r8152_mdio_write(tp, MII_BMCR, data);
        }
 
+       r8153_clear_bp(tp);
+
        if (tp->version == RTL_VER_03) {
                data = ocp_reg_read(tp, OCP_EEE_CFG);
                data &= ~CTAP_SHORT_EN;
        struct r8152 *tp = netdev_priv(netdev);
        int res = 0;
 
+       res = alloc_all_mem(tp);
+       if (res)
+               goto out;
+
+       tp->rtl_ops.up(tp);
+
        rtl8152_set_speed(tp, AUTONEG_ENABLE,
                          tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
                          DUPLEX_FULL);
                        netif_device_detach(tp->netdev);
                netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n",
                           res);
+               free_all_mem(tp);
        }
 
 
+out:
        return res;
 }
 
        cancel_delayed_work_sync(&tp->schedule);
        netif_stop_queue(netdev);
        tasklet_disable(&tp->tl);
-       tp->rtl_ops.disable(tp);
+       tp->rtl_ops.down(tp);
        tasklet_enable(&tp->tl);
 
+       free_all_mem(tp);
+
        return res;
 }
 
 {
        u32 ocp_data;
 
-       rtl_clear_bp(tp);
-
        if (tp->version == RTL_VER_01) {
                ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE);
                ocp_data &= ~LED_MODE_MASK;
                ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data);
        }
 
-       r8152b_hw_phy_cfg(tp);
-
        r8152_power_cut_en(tp, false);
 
-
-       r8152b_exit_oob(tp);
-
        ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR);
        ocp_data |= TX_10M_IDLE_EN | PFM_PWM_SWITCH;
        ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data);
        ocp_data &= ~TIMER11_EN;
        ocp_write_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL, ocp_data);
 
-       r8153_clear_bp(tp);
-
        ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE);
        ocp_data &= ~LED_MODE_MASK;
        ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data);
        r8153_power_cut_en(tp, false);
        r8153_u1u2en(tp, true);
 
-       r8153_first_init(tp);
-
        ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, ALDPS_SPDWN_RATIO);
        ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, EEE_SPDWN_RATIO);
        ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3,
                usb_kill_urb(tp->intr_urb);
                cancel_delayed_work_sync(&tp->schedule);
                tasklet_disable(&tp->tl);
+               tp->rtl_ops.down(tp);
+               tasklet_enable(&tp->tl);
        }
 
-       tp->rtl_ops.down(tp);
-
        return 0;
 }
 
        tp->rtl_ops.init(tp);
        netif_device_attach(tp->netdev);
        if (netif_running(tp->netdev)) {
+               tp->rtl_ops.up(tp);
                rtl8152_set_speed(tp, AUTONEG_ENABLE,
                                tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
                                DUPLEX_FULL);
                netif_carrier_off(tp->netdev);
                set_bit(WORK_ENABLE, &tp->flags);
                usb_submit_urb(tp->intr_urb, GFP_KERNEL);
-               tasklet_enable(&tp->tl);
        }
 
        return 0;
                        ops->init               = r8152b_init;
                        ops->enable             = rtl8152_enable;
                        ops->disable            = rtl8152_disable;
+                       ops->up                 = r8152b_exit_oob;
                        ops->down               = rtl8152_down;
                        ops->unload             = rtl8152_unload;
                        ret = 0;
                        ops->init               = r8153_init;
                        ops->enable             = rtl8153_enable;
                        ops->disable            = rtl8152_disable;
+                       ops->up                 = r8153_first_init;
                        ops->down               = rtl8153_down;
                        ops->unload             = rtl8153_unload;
                        ret = 0;
                        ops->init               = r8153_init;
                        ops->enable             = rtl8153_enable;
                        ops->disable            = rtl8152_disable;
+                       ops->up                 = r8153_first_init;
                        ops->down               = rtl8153_down;
                        ops->unload             = rtl8153_unload;
                        ret = 0;
        tp->rtl_ops.init(tp);
        set_ethernet_addr(tp);
 
-       ret = alloc_all_mem(tp);
-       if (ret)
-               goto out;
-
        usb_set_intfdata(intf, tp);
 
        ret = register_netdev(netdev);
                tasklet_kill(&tp->tl);
                unregister_netdev(tp->netdev);
                tp->rtl_ops.unload(tp);
-               free_all_mem(tp);
                free_netdev(tp->netdev);
        }
 }