On Monday 11 January 2021 06:00:43 Marek Behún wrote: > Instead of configuring the I2C mdiobus when SFP driver is probed, > create/destroy the mdiobus before the PHY is probed for/after it is > released. > > This way we can tell the mdio-i2c code which protocol to use for each > SFP transceiver. > > Signed-off-by: Marek Behún <ka...@kernel.org> > Cc: Andrew Lunn <and...@lunn.ch> > Cc: Russell King <rmk+ker...@armlinux.org.uk>
Reviewed-by: Pali Rohár <p...@kernel.org> > --- > drivers/net/phy/sfp.c | 30 ++++++++++++++++++++++++++---- > 1 file changed, 26 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c > index 958fd514a3b4..0621d12cf878 100644 > --- a/drivers/net/phy/sfp.c > +++ b/drivers/net/phy/sfp.c > @@ -217,6 +217,7 @@ struct sfp { > struct i2c_adapter *i2c; > struct mii_bus *i2c_mii; > struct sfp_bus *sfp_bus; > + enum mdio_i2c_proto mdio_protocol; > struct phy_device *mod_phy; > const struct sff_data *type; > size_t i2c_block_size; > @@ -409,9 +410,6 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 > dev_addr, void *buf, > > static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) > { > - struct mii_bus *i2c_mii; > - int ret; > - > if (!i2c_check_functionality(i2c, I2C_FUNC_I2C)) > return -EINVAL; > > @@ -419,7 +417,15 @@ static int sfp_i2c_configure(struct sfp *sfp, struct > i2c_adapter *i2c) > sfp->read = sfp_i2c_read; > sfp->write = sfp_i2c_write; > > - i2c_mii = mdio_i2c_alloc(sfp->dev, i2c, MDIO_I2C_DEFAULT); > + return 0; > +} > + > +static int sfp_i2c_mdiobus_create(struct sfp *sfp) > +{ > + struct mii_bus *i2c_mii; > + int ret; > + > + i2c_mii = mdio_i2c_alloc(sfp->dev, sfp->i2c, sfp->mdio_protocol); > if (IS_ERR(i2c_mii)) > return PTR_ERR(i2c_mii); > > @@ -437,6 +443,12 @@ static int sfp_i2c_configure(struct sfp *sfp, struct > i2c_adapter *i2c) > return 0; > } > > +static void sfp_i2c_mdiobus_destroy(struct sfp *sfp) > +{ > + mdiobus_unregister(sfp->i2c_mii); > + sfp->i2c_mii = NULL; > +} > + > /* Interface */ > static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) > { > @@ -1821,6 +1833,8 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool > report) > else > sfp->module_t_start_up = T_START_UP; > > + sfp->mdio_protocol = MDIO_I2C_DEFAULT; > + > return 0; > } > > @@ -1991,6 +2005,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int > event) > sfp_module_stop(sfp->sfp_bus); > if (sfp->mod_phy) > sfp_sm_phy_detach(sfp); > + if (sfp->i2c_mii) > + sfp_i2c_mdiobus_destroy(sfp); > sfp_module_tx_disable(sfp); > sfp_soft_stop_poll(sfp); > sfp_sm_next(sfp, SFP_S_DOWN, 0); > @@ -2053,6 +2069,12 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int > event) > sfp->sm_fault_retries == N_FAULT_INIT); > } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) { > init_done: > + /* Create mdiobus and start trying for PHY */ > + ret = sfp_i2c_mdiobus_create(sfp); > + if (ret < 0) { > + sfp_sm_next(sfp, SFP_S_FAIL, 0); > + break; > + } > sfp->sm_phy_retries = R_PHY_RETRY; > goto phy_probe; > } > -- > 2.26.2 >