Skip to content

Commit e85b134

Browse files
elkablodavem330
authored andcommitted
net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY release
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. Move the code that determines MDIO I2C protocol from sfp_sm_probe_for_phy() to sfp_sm_mod_probe(), where most of the SFP ID parsing is done. Don't allocate I2C bus if no PHY is expected. Signed-off-by: Marek Behún <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 13c8adc commit e85b134

File tree

2 files changed

+57
-13
lines changed

2 files changed

+57
-13
lines changed

drivers/net/phy/sfp.c

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ struct sfp {
218218
struct i2c_adapter *i2c;
219219
struct mii_bus *i2c_mii;
220220
struct sfp_bus *sfp_bus;
221+
enum mdio_i2c_proto mdio_protocol;
221222
struct phy_device *mod_phy;
222223
const struct sff_data *type;
223224
size_t i2c_block_size;
@@ -530,17 +531,22 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
530531

531532
static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
532533
{
533-
struct mii_bus *i2c_mii;
534-
int ret;
535-
536534
if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
537535
return -EINVAL;
538536

539537
sfp->i2c = i2c;
540538
sfp->read = sfp_i2c_read;
541539
sfp->write = sfp_i2c_write;
542540

543-
i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
541+
return 0;
542+
}
543+
544+
static int sfp_i2c_mdiobus_create(struct sfp *sfp)
545+
{
546+
struct mii_bus *i2c_mii;
547+
int ret;
548+
549+
i2c_mii = mdio_i2c_alloc(sfp->dev, sfp->i2c);
544550
if (IS_ERR(i2c_mii))
545551
return PTR_ERR(i2c_mii);
546552

@@ -558,6 +564,12 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
558564
return 0;
559565
}
560566

567+
static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
568+
{
569+
mdiobus_unregister(sfp->i2c_mii);
570+
sfp->i2c_mii = NULL;
571+
}
572+
561573
/* Interface */
562574
static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
563575
{
@@ -1674,6 +1686,14 @@ static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
16741686
}
16751687
}
16761688

1689+
static int sfp_sm_add_mdio_bus(struct sfp *sfp)
1690+
{
1691+
if (sfp->mdio_protocol != MDIO_I2C_NONE)
1692+
return sfp_i2c_mdiobus_create(sfp);
1693+
1694+
return 0;
1695+
}
1696+
16771697
/* Probe a SFP for a PHY device if the module supports copper - the PHY
16781698
* normally sits at I2C bus address 0x56, and may either be a clause 22
16791699
* or clause 45 PHY.
@@ -1689,19 +1709,19 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp)
16891709
{
16901710
int err = 0;
16911711

1692-
switch (sfp->id.base.extended_cc) {
1693-
case SFF8024_ECC_10GBASE_T_SFI:
1694-
case SFF8024_ECC_10GBASE_T_SR:
1695-
case SFF8024_ECC_5GBASE_T:
1696-
case SFF8024_ECC_2_5GBASE_T:
1697-
err = sfp_sm_probe_phy(sfp, true);
1712+
switch (sfp->mdio_protocol) {
1713+
case MDIO_I2C_NONE:
16981714
break;
16991715

1700-
default:
1701-
if (sfp->id.base.e1000_base_t)
1702-
err = sfp_sm_probe_phy(sfp, false);
1716+
case MDIO_I2C_MARVELL_C22:
1717+
err = sfp_sm_probe_phy(sfp, false);
1718+
break;
1719+
1720+
case MDIO_I2C_C45:
1721+
err = sfp_sm_probe_phy(sfp, true);
17031722
break;
17041723
}
1724+
17051725
return err;
17061726
}
17071727

@@ -2028,6 +2048,16 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
20282048

20292049
sfp->tx_fault_ignore = false;
20302050

2051+
if (sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SFI ||
2052+
sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SR ||
2053+
sfp->id.base.extended_cc == SFF8024_ECC_5GBASE_T ||
2054+
sfp->id.base.extended_cc == SFF8024_ECC_2_5GBASE_T)
2055+
sfp->mdio_protocol = MDIO_I2C_C45;
2056+
else if (sfp->id.base.e1000_base_t)
2057+
sfp->mdio_protocol = MDIO_I2C_MARVELL_C22;
2058+
else
2059+
sfp->mdio_protocol = MDIO_I2C_NONE;
2060+
20312061
sfp->quirk = sfp_lookup_quirk(&id);
20322062
if (sfp->quirk && sfp->quirk->fixup)
20332063
sfp->quirk->fixup(sfp);
@@ -2204,6 +2234,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
22042234
sfp_module_stop(sfp->sfp_bus);
22052235
if (sfp->mod_phy)
22062236
sfp_sm_phy_detach(sfp);
2237+
if (sfp->i2c_mii)
2238+
sfp_i2c_mdiobus_destroy(sfp);
22072239
sfp_module_tx_disable(sfp);
22082240
sfp_soft_stop_poll(sfp);
22092241
sfp_sm_next(sfp, SFP_S_DOWN, 0);
@@ -2266,6 +2298,12 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
22662298
sfp->sm_fault_retries == N_FAULT_INIT);
22672299
} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
22682300
init_done:
2301+
/* Create mdiobus and start trying for PHY */
2302+
ret = sfp_sm_add_mdio_bus(sfp);
2303+
if (ret < 0) {
2304+
sfp_sm_next(sfp, SFP_S_FAIL, 0);
2305+
break;
2306+
}
22692307
sfp->sm_phy_retries = R_PHY_RETRY;
22702308
goto phy_probe;
22712309
}

include/linux/mdio/mdio-i2c.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ struct device;
1111
struct i2c_adapter;
1212
struct mii_bus;
1313

14+
enum mdio_i2c_proto {
15+
MDIO_I2C_NONE,
16+
MDIO_I2C_MARVELL_C22,
17+
MDIO_I2C_C45,
18+
};
19+
1420
struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
1521

1622
#endif

0 commit comments

Comments
 (0)