}
 EXPORT_SYMBOL_GPL(sfp_module_remove);
 
+int sfp_module_start(struct sfp_bus *bus)
+{
+       const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
+       int ret = 0;
+
+       if (ops && ops->module_start)
+               ret = ops->module_start(bus->upstream);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(sfp_module_start);
+
+void sfp_module_stop(struct sfp_bus *bus)
+{
+       const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
+
+       if (ops && ops->module_stop)
+               ops->module_stop(bus->upstream);
+}
+EXPORT_SYMBOL_GPL(sfp_module_stop);
+
 static void sfp_socket_clear(struct sfp_bus *bus)
 {
        bus->sfp_dev = NULL;
 
        SFP_DEV_UP,
 
        SFP_S_DOWN = 0,
+       SFP_S_FAIL,
        SFP_S_WAIT,
        SFP_S_INIT,
        SFP_S_INIT_TX_FAULT,
 
 static const char * const sm_state_strings[] = {
        [SFP_S_DOWN] = "down",
+       [SFP_S_FAIL] = "fail",
        [SFP_S_WAIT] = "wait",
        [SFP_S_INIT] = "init",
        [SFP_S_INIT_TX_FAULT] = "init_tx_fault",
                if (sfp->sm_state == SFP_S_LINK_UP &&
                    sfp->sm_dev_state == SFP_DEV_UP)
                        sfp_sm_link_down(sfp);
+               if (sfp->sm_state > SFP_S_INIT)
+                       sfp_module_stop(sfp->sfp_bus);
                if (sfp->mod_phy)
                        sfp_sm_phy_detach(sfp);
                sfp_module_tx_disable(sfp);
                         * clear.  Probe for the PHY and check the LOS state.
                         */
                        sfp_sm_probe_for_phy(sfp);
+                       if (sfp_module_start(sfp->sfp_bus)) {
+                               sfp_sm_next(sfp, SFP_S_FAIL, 0);
+                               break;
+                       }
                        sfp_sm_link_check_los(sfp);
 
                        /* Reset the fault retry count */
 
 void sfp_link_down(struct sfp_bus *bus);
 int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
 void sfp_module_remove(struct sfp_bus *bus);
+int sfp_module_start(struct sfp_bus *bus);
+void sfp_module_stop(struct sfp_bus *bus);
 int sfp_link_configure(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
 struct sfp_bus *sfp_register_socket(struct device *dev, struct sfp *sfp,
                                    const struct sfp_socket_ops *ops);
 
  * @module_insert: called after a module has been detected to determine
  *   whether the module is supported for the upstream device.
  * @module_remove: called after the module has been removed.
+ * @module_start: called after the PHY probe step
+ * @module_stop: called before the PHY is removed
  * @link_down: called when the link is non-operational for whatever
  *   reason.
  * @link_up: called when the link is operational.
        void (*detach)(void *priv, struct sfp_bus *bus);
        int (*module_insert)(void *priv, const struct sfp_eeprom_id *id);
        void (*module_remove)(void *priv);
+       int (*module_start)(void *priv);
+       void (*module_stop)(void *priv);
        void (*link_down)(void *priv);
        void (*link_up)(void *priv);
        int (*connect_phy)(void *priv, struct phy_device *);