Merge branch 'net-phy-sfp-fix-mii_bus-leak-and-revert-rollball-bridge-probe'

Petr Wozniak says:

====================
net: phy: sfp: fix mii_bus leak and revert RollBall bridge probe

v4 tried to fix the RollBall regression from 8fe125892f by deferring the
bridge probe to PHY discovery time. Maxime Chevallier and Aleksander
Bajkowski both tested that on genuine RollBall hardware and confirmed it
does not restore PHY detection (the module still is not ready when the
probe runs), and the Sashiko static review flagged the same path.

So this version drops the deferred-probe patch and instead reverts
8fe125892f, restoring the pre-regression behaviour for genuine RollBall
modules. A proper fix for slow-initializing modules needs per-module init
timing (a longer module_t_wait / a per-module quirk) and genuine RollBall
hardware to validate; that is better owned as a follow-up by someone with
such a module.
====================

Link: https://patch.msgid.link/cover.1782581445.git.petr.wozniak@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-06-29 19:07:44 -07:00
commit 9282abe196
2 changed files with 11 additions and 63 deletions

View File

@ -419,50 +419,6 @@ static int i2c_mii_write_rollball(struct mii_bus *bus, int phy_id, int devad,
return 0;
}
static int i2c_mii_probe_rollball(struct i2c_adapter *i2c)
{
u8 data_buf[] = { ROLLBALL_DATA_ADDR, 0x01, 0x00, 0x00 };
u8 cmd_buf[] = { ROLLBALL_CMD_ADDR, ROLLBALL_CMD_READ };
u8 cmd_addr = ROLLBALL_CMD_ADDR;
struct i2c_msg msgs[2];
u8 result;
int ret;
int i;
msgs[0].addr = ROLLBALL_PHY_I2C_ADDR;
msgs[0].flags = 0;
msgs[0].len = sizeof(data_buf);
msgs[0].buf = data_buf;
msgs[1].addr = ROLLBALL_PHY_I2C_ADDR;
msgs[1].flags = 0;
msgs[1].len = sizeof(cmd_buf);
msgs[1].buf = cmd_buf;
ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
if (ret < 0)
return -ENODEV;
msgs[0].addr = ROLLBALL_PHY_I2C_ADDR;
msgs[0].flags = 0;
msgs[0].len = 1;
msgs[0].buf = &cmd_addr;
msgs[1].addr = ROLLBALL_PHY_I2C_ADDR;
msgs[1].flags = I2C_M_RD;
msgs[1].len = 1;
msgs[1].buf = &result;
for (i = 0; i < 10; i++) {
msleep(20);
ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
if (ret < 0)
return -ENODEV;
if (result == ROLLBALL_CMD_DONE)
return 0;
}
return -ENODEV;
}
static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
{
struct i2c_msg msg;
@ -482,11 +438,11 @@ static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
ret = i2c_transfer(i2c, &msg, 1);
if (ret < 0)
return -ENODEV;
if (ret != 1)
return ret;
else if (ret != 1)
return -EIO;
return i2c_mii_probe_rollball(i2c);
else
return 0;
}
static bool mdio_i2c_check_functionality(struct i2c_adapter *i2c,
@ -531,10 +487,9 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
case MDIO_I2C_ROLLBALL:
ret = i2c_mii_init_rollball(i2c);
if (ret < 0) {
if (ret != -ENODEV)
dev_err(parent,
"Cannot initialize RollBall MDIO I2C protocol: %d\n",
ret);
dev_err(parent,
"Cannot initialize RollBall MDIO I2C protocol: %d\n",
ret);
mdiobus_free(mii);
return ERR_PTR(ret);
}

View File

@ -597,7 +597,6 @@ static const struct sfp_quirk sfp_quirks[] = {
// OEM SFP-GE-T is a 1000Base-T module with broken TX_FAULT indicator
SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
SFP_QUIRK_F("OEM", "SFP-10G-T-I", sfp_fixup_rollball),
SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
SFP_QUIRK_S("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
SFP_QUIRK_S("OEM", "SFP-2.5G-BX10-D", sfp_quirk_2500basex),
@ -963,6 +962,7 @@ static int sfp_i2c_mdiobus_create(struct sfp *sfp)
static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
{
mdiobus_unregister(sfp->i2c_mii);
mdiobus_free(sfp->i2c_mii);
sfp->i2c_mii = NULL;
}
@ -2173,17 +2173,10 @@ static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
static int sfp_sm_add_mdio_bus(struct sfp *sfp)
{
int ret;
if (sfp->mdio_protocol != MDIO_I2C_NONE)
return sfp_i2c_mdiobus_create(sfp);
if (sfp->mdio_protocol == MDIO_I2C_NONE)
return 0;
ret = sfp_i2c_mdiobus_create(sfp);
if (ret == -ENODEV) {
sfp->mdio_protocol = MDIO_I2C_NONE;
return 0;
}
return ret;
return 0;
}
/* Probe a SFP for a PHY device if the module supports copper - the PHY