From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A04883C9EE6 for ; Tue, 23 Jun 2026 08:05:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.42 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782201947; cv=none; b=q5KNTpO7kr13jVUwyYGVeuFeKYKNKccj9BBpGPC1OsYGSYyYqZH6F5RY/0/Q6whIpWWjgyHM4RsYUyz3f3jsqWcfl1eSZOoPzDDnVBxCICKFU/jjRzaMbRWR3leaB6zC6/R8Ksi4NdyTGlTk5/30+Q8+GZiLB3BHE9EG85Wic/M= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782201947; c=relaxed/simple; bh=963pITVs9Rjb81Ci2uL3NJ/HsVakcZ3k4mlbk16oCok=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T4G9nBh2hRnC2Svtex3xbtSVvm0bMNHvu0VsjOWmYqYmcKTBxarbC6yKCO9ZFkOqCijLnfDsed5kCurLGxAmvHSdER3JPwpDfKWJ3bMbggGbpYE7xEtW3jFyQ1xeM2NVJHhnUiuNRHIttj9pG+IG/ZLZ3H/GkPXU5jK1rf587+Y= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IUrzX1/D; arc=none smtp.client-ip=209.85.221.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IUrzX1/D" Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-460166910e6so2906588f8f.2 for ; Tue, 23 Jun 2026 01:05:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782201944; x=1782806744; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hDgSh5umR4LQMz2jeGs6QRx4dsp/V9xsfSzq9kWYIeg=; b=IUrzX1/DEn+G9jGmx8a1V0iY4AVfgUFdxsC0/TbYeuPP0+FMu6YrFI+e8i3kqSm+gY Zjp30c8Wx7J7F66f/KB6233i8X0D3W4ZZeBc1aYdDWrF5xPUjwEvPV8xijW4ZYEPfNwF 0kJ0X9M1lOGSaXXDzeP2UImFgnDr7XC+bNpzI4RHjhW5cf/wIuaRfzac2xB75ORGJ+v4 iDmDGz/sAZVqTHv7n5+OjkNcNFGhoK5fKof7wRcq8egIvIrN5mSyBNi5z/g/dI/giAhJ liGtUBxpUhX6wOXws6KjnuVhF1JNEneT8gIJeYRtSAK/uGtn6Cne4hXCMByuKT5HBzmb 04bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782201944; x=1782806744; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=hDgSh5umR4LQMz2jeGs6QRx4dsp/V9xsfSzq9kWYIeg=; b=djdEgFTsmgfbGnkCxxw1FwcUFDF6+AvAc8ZHroOiTUnjXS9r7ZPIb0oXKlpHp7vm1J 00iSThyOoeRMKVN48+pZhpxcIZpwlAJ/ZwVer8MywTZ6eZGSb7hzUtN7HfximQginZ7t IapJwneMI2vLQ6QJ4WwNZc0dVLSwhtCjJiBPhrqBKkGpgCCpl6s0Q8b4Q4Z51fn5yi9l XNwde5m9+CElzt0DRDVXGaN885uGERZk2BOeTmsm56BFVAgyyN02ZWW7Mr4mmnNrscE2 WXr5TMCpm4xnE1E/Ljdidk8novm4VXNpr9SMthV7ymjhBTJ/xUJQ2Njs9OPrVj5pKt8+ 0UEg== X-Forwarded-Encrypted: i=1; AHgh+RopSZDq1dVQmzw3UWZHlXstE1XuVSthgREjQd4uiXdW1HCe8ZIBABktZsDA2upsn15lbkwmaM2vITFmt6c=@vger.kernel.org X-Gm-Message-State: AOJu0YzVSlC5rhJu06s2bWtPjQitlGSo1A3lx05yKQbaa/e8lDggTJ+2 nn0CtqYomSgFtSOjnFXkzGkDNccOD5DbZyK9BlUagJHUimUUX5ua5eSC X-Gm-Gg: AfdE7ckeLzRrZg8vznipOYdpndwpdnFIi+2G0BQC1cnxNSZdmTGD0sXjKUDHehMrydQ w+SdkiqTb8tnIg5kYU26JWft2j8XknTT1rh7E+80K/f6avKd4xU5dndCAciTYcRhi9WvBqB4nDa FkvTeTbYkhQApMzQBPAejrhS3VinIp+Li5Qr9kIsWRSk3/Wr1c1aZV90HIq8+z8v3cMrhCOpirg x7qoyLVcp+7iShYyK+yY9Nor8fUE6mZrdJ7bJLOixNPXO7s78onVYWcMvzqi6F36G4xcP+uJUb3 GgGPhQpefwhg63oZPHyHoyzZWsPiUtJ2QGsuMlbJdpA9YE9xygRWhznnarTIL0ExhnABw4vKMdG w5dmxEDRXJAMuUQmanwmHKl8flGFxYE9Ur70XxkQjSaIqozBcG2/jW1EIy9as76Cl2oFPC8kwkp kCiiSafmczhUCmtucii649U0M3cfyrIw1OHy9GUqk/LbPTdEYqEQosPfp8+ZgpswhDdH62qqcRz fm9dv4= X-Received: by 2002:adf:f78f:0:b0:460:70ae:f1af with SMTP id ffacd0b85a97d-46add36e36bmr1861389f8f.27.1782201943954; Tue, 23 Jun 2026 01:05:43 -0700 (PDT) Received: from localhost.localdomain (ip-89-176-136-191.bb.vodafone.cz. [89.176.136.191]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-46667221de7sm32486503f8f.33.2026.06.23.01.05.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 01:05:43 -0700 (PDT) From: Petr Wozniak To: linux@armlinux.org.uk, andrew@lunn.ch, hkallweit1@gmail.com Cc: kuba@kernel.org, davem@davemloft.net, edumazet@google.com, pabeni@redhat.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, maxime.chevallier@bootlin.com, bjorn@mork.no, olek2@wp.pl, kabel@kernel.org, Petr Wozniak Subject: [PATCH net-next v3 2/2] net: phy: mdio-i2c: defer RollBall bridge probe to PHY discovery Date: Tue, 23 Jun 2026 10:05:38 +0200 Message-ID: <20260623080538.7646-3-petr.wozniak@gmail.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260623080538.7646-1-petr.wozniak@gmail.com> References: <20260623080538.7646-1-petr.wozniak@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit commit 8fe125892f40 ("net: phy: sfp: probe for RollBall I2C-to-MDIO bridge in mdio-i2c") introduced a regression: the RollBall I2C-to-MDIO bridge is not yet ready to respond to CMD_READ/CMD_DONE cycles when sfp_sm_add_mdio_bus() runs in SFP_S_INIT. The 200 ms probe times out, i2c_mii_probe_rollball() returns -ENODEV, and sfp_sm_add_mdio_bus() sets mdio_protocol = MDIO_I2C_NONE. By the time sfp_sm_probe_for_phy() runs (up to ~17 s later on affected hardware), the bridge is fully initialized but PHY probing is skipped because the protocol has already been changed to NONE. This affects both modules inserted before boot and hotplugged modules on hardware where bridge initialization exceeds the 200 ms probe window (confirmed: FLYPRO SFP-10GT-CS-30M with Aquantia AQR113C, hotplugged). Move the probe from i2c_mii_init_rollball(), called at bus-creation time, to sfp_sm_probe_for_phy() in sfp.c, where it runs after the SFP state machine module initialization delays. Export the probe function as mdio_i2c_probe_rollball() so sfp.c can call it. For RTL8261BE-based modules the probe correctly returns -ENODEV at PHY discovery time, causing sfp_sm_probe_for_phy() to destroy the MDIO bus and set MDIO_I2C_NONE, eliminating the 5+ minute PHY probe retry loop. For genuine RollBall modules (e.g. FLYPRO SFP-10GT-CS-30M with Aquantia AQR113C) the probe now runs after initialization is complete and correctly returns 0, so PHY detection proceeds normally. Reported-by: Aleksander Bajkowski Fixes: 8fe125892f40 ("net: phy: sfp: probe for RollBall I2C-to-MDIO bridge in mdio-i2c") Signed-off-by: Petr Wozniak --- v3: regenerated against net-next (v2 failed to apply due to transit corruption); fixed block comment style (checkpatch); no functional change. v2: commit message only - generalized scope (Aleksander Bajkowski); corrected SM description (Jan Hoffmann); no code change from v1. v1: initial. drivers/net/mdio/mdio-i2c.c | 15 +++++++++------ drivers/net/phy/sfp.c | 22 +++++++++++++--------- include/linux/mdio/mdio-i2c.h | 1 + 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/net/mdio/mdio-i2c.c b/drivers/net/mdio/mdio-i2c.c index b88f63234b4e..2a3a418c1369 100644 --- a/drivers/net/mdio/mdio-i2c.c +++ b/drivers/net/mdio/mdio-i2c.c @@ -419,7 +419,7 @@ 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) +int mdio_i2c_probe_rollball(struct i2c_adapter *i2c) { u8 data_buf[] = { ROLLBALL_DATA_ADDR, 0x01, 0x00, 0x00 }; u8 cmd_buf[] = { ROLLBALL_CMD_ADDR, ROLLBALL_CMD_READ }; @@ -462,9 +462,13 @@ static int i2c_mii_probe_rollball(struct i2c_adapter *i2c) return -ENODEV; } +EXPORT_SYMBOL_GPL(mdio_i2c_probe_rollball); static int i2c_mii_init_rollball(struct i2c_adapter *i2c) { + /* Send the RollBall unlock password; bridge presence is verified + * later, in sfp_sm_probe_for_phy(), after module initialization. + */ struct i2c_msg msg; u8 pw[5]; int ret; @@ -486,7 +490,7 @@ static int i2c_mii_init_rollball(struct i2c_adapter *i2c) if (ret != 1) return -EIO; - return i2c_mii_probe_rollball(i2c); + return 0; } static bool mdio_i2c_check_functionality(struct i2c_adapter *i2c, @@ -531,10 +535,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); } diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index c4d274ab651e..bbfaa0450798 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -2174,17 +2174,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 0; - ret = sfp_i2c_mdiobus_create(sfp); - if (ret == -ENODEV) { - sfp->mdio_protocol = MDIO_I2C_NONE; - return 0; - } - return ret; + return sfp_i2c_mdiobus_create(sfp); } /* Probe a SFP for a PHY device if the module supports copper - the PHY @@ -2215,7 +2208,18 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp) break; case MDIO_I2C_ROLLBALL: - err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR_ROLLBALL, true); + /* Probe here, after module initialization delays, so that + * genuine RollBall bridges have had time to start up. + * Modules without a bridge (e.g. RTL8261BE) return -ENODEV. + */ + err = mdio_i2c_probe_rollball(sfp->i2c); + if (err == -ENODEV) { + sfp_i2c_mdiobus_destroy(sfp); + sfp->mdio_protocol = MDIO_I2C_NONE; + break; + } + if (!err) + err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR_ROLLBALL, true); break; } diff --git a/include/linux/mdio/mdio-i2c.h b/include/linux/mdio/mdio-i2c.h index 65b550a6fc32..5cf14f45c94b 100644 --- a/include/linux/mdio/mdio-i2c.h +++ b/include/linux/mdio/mdio-i2c.h @@ -20,5 +20,6 @@ enum mdio_i2c_proto { struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c, enum mdio_i2c_proto protocol); +int mdio_i2c_probe_rollball(struct i2c_adapter *i2c); #endif -- 2.51.0