From nobody Mon Jun 8 07:24:44 2026 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (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 4B10876026 for ; Fri, 5 Jun 2026 05:31:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780637464; cv=none; b=Q1RIOXmgLI/IQnBdh29wzWH/GszQ7PuSOVC3wqqdjgS8XxsOxCCErK8Y1Uk3s+ld9gZ9Cr1TdXChjVQRxD6IP31Umyt8nPt9eWACupIdkoeLB+BUeHNpQSBs8E0MVaHRlTCreAXg2g7669VUPa5rmNE7X9hfXDbxlhsSMLl7tA0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780637464; c=relaxed/simple; bh=6KkI5MZZbDclc8igv7Jmkuhhc3G1Kn/GhoYh9WlzOFE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fzxy2AW95l8LMv7x80Ce3/TIv5Lugh3vB0KIXxwj545gxzENEMSOQGMDLWMGq1/8pr3tt19Kg6/Asuym40ZDPjiAULurrQ1c4FYhybAbMYEZzwPq5W9S6g/60aF3clZreIfkYJO7SXq7lZPS0piy6McqenJewi/T2hc0yPonCyE= 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=MqihekrR; arc=none smtp.client-ip=209.85.128.50 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="MqihekrR" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-4903d730b1fso15296305e9.2 for ; Thu, 04 Jun 2026 22:31:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780637460; x=1781242260; 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=vuvdhqAuePBbJyQdMyyPcU8SDSteetKe1IJhuqarnPk=; b=MqihekrRfuOfW+tty/TXvzHHBIvHlnPBGCae6Wz7T075FAfKXKQpZ+UOWZ7Z+Y54lF RTe84Y+vlbk/HpOxclOUmMMvyfjgCA/l8LSgnGLLT6TrzUteFrplsOwCfGDnI7UybaNm vSZSJrbwGJidcgzfW9yxmk+NKBc+awwEkGJbVq5eeriT0Y5BmEo4xXsZAZBmqlClj9JW 3JuPhFUEfpIIMAPhlT51FrTrLu8pbBH0M20M/W76CbLUxPe9bNXIDUU8iLg3FW5PDl1o aj3K1Dsz/SUUiemvwH/4yIyuMOikb4Ta9GCs8w62TnpAXGgArRl0yRoLybD+NIciVL8C N0Gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780637460; x=1781242260; 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=vuvdhqAuePBbJyQdMyyPcU8SDSteetKe1IJhuqarnPk=; b=cSNdZGXvCuyAKFbFni5BaF4AErIIZJ1KrLqmFy90t//mDFg/Ljmwg8NZQTZ8Kx4Tnu Kr+la/Zcun1Nvr32npK0qQ6fMSCtCN8B22g6sksfOxLILBlFYoxcVcd0ehEHlsSEWSV/ rIf74BYWtsEyGKLhlWKu+Z0D7oCTpGZPxgKqDVV21QPSnmzo4v2ObrFG88KCtHcriTaW N6UuVJog4TmvBhUbr+nEEKoQPc3DTbPJGXNC9FNNuZWWZIXe6G2GocBbuJJ7bJPyxqRO S3YDTSxDu+h3xMcpP55eWRxZ6XWzLRP9yuD5o++1AKcmaQdXdTiecFAJQOMrzCQEAQMR 3rxg== X-Forwarded-Encrypted: i=1; AFNElJ/6JP/BXTReGOWi1oFoI6qQ3UPYoNtMJLvH5oRebASxX66pOyDbw5BnDs88xHuYkpA0uLm65OWZ/G1NJRc=@vger.kernel.org X-Gm-Message-State: AOJu0YzZ4D1yqHorh8ehZEMRSp6jrdNnGFevfHZJekagu1EghPndf4py je2hQ6JFLede4rMXLVZ1VI0Sev2EhvZREi+hpi9+fpYM5XVrQVQ/aBOH X-Gm-Gg: Acq92OE+xoLAeowjw8mrnhcS9J8NKC2FjjDr9ZHtqCWLKydRytp+arUDdHK7i2k7gSE RkKqkQBSt593J+R1bYNvqF/LX10SG2RL0UWKhtSAcfmyYQI8A83F0S2RCb+6XfaWGkEBVr8Lthl 2Sa1a+CamDdj59XqPrY57zKeTErWz3bAJ9Z3GFXx8Z/dUKYoT+y8P3//9nKXZXWXZmCsGdl0ydi F4TNmAPtVTKM/cd7q+Fy+Esj6NQcJXG/NiWEUcCvJ25TkfpYjp1N2784woOGoEO4iM5kkGjVE6T VtJzfBUyC3P1Rgv5ADMmtRDorMVo/J0lYRy17/XJ9AoTgzUBnWdsXukuBZ4knUhv/6XzbtUTOmt AICCghn9XtfmTy26JiBb3VCU7MEqCUbfWHhwATGYisEbMUqYckOlfQ8tRYKaCHJ/w4M/LLzjWR1 dKS4Nd6Hu8Bktn/2geTjk8FG9PblbNBfHvImndol9ZA78uLTU51wzjdWIRbNR1KGsXuu0PQ57b2 qyeZ86Kd1yHqxFv001K+4QcV1H4 X-Received: by 2002:a05:600c:4e09:b0:488:9bf8:7f17 with SMTP id 5b1f17b1804b1-490c25acd18mr28114225e9.14.1780637459481; Thu, 04 Jun 2026 22:30:59 -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 5b1f17b1804b1-490bc413541sm128414495e9.14.2026.06.04.22.30.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 22:30:59 -0700 (PDT) From: Petr Wozniak To: netdev@vger.kernel.org Cc: kuba@kernel.org, andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk, davem@davemloft.net, edumazet@google.com, pabeni@redhat.com, linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org, maxime.chevallier@bootlin.com, bjorn@mork.no, olek2@wp.pl, Petr Wozniak Subject: [PATCH v2 net-next] net: phy: mdio-i2c: defer RollBall bridge probe to PHY discovery Date: Fri, 5 Jun 2026 07:30:56 +0200 Message-ID: <20260605053056.1977-1-petr.wozniak@gmail.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260604181207.17468-1-petr.wozniak@gmail.com> References: <20260604181207.17468-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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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 =3D 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 =E2=80=94 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() =E2=80=94 called at bus-creation time =E2=80=94 to sfp_sm_probe_for_phy() in sfp.c, where it runs after the = SFP state machine's 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 =E2=80=94 eliminating the 5+ minute PHY probe retry l= oop. 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 =E2=80=94 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 --- Changes in v2: - Generalize scope: regression affects both boot-inserted and hotplugged modules on hardware where bridge init exceeds 200 ms; Aleksander Bajkowski confirmed FLYPRO SFP-10GT-CS-30M / AQR113C broken even when hotplugged - Correct state machine description: probe runs in SFP_S_INIT (which follows SFP_S_WAIT), not "before initialization delays" (Jan Hoffmann) - No code changes from v1 drivers/net/mdio/mdio-i2c.c | 18 ++++-------------- drivers/net/phy/sfp.c | 18 ++++++++++++------ include/linux/mdio/mdio-i2c.h | 1 + 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/net/mdio/mdio-i2c.c b/drivers/net/mdio/mdio-i2c.c --- a/drivers/net/mdio/mdio-i2c.c +++ b/drivers/net/mdio/mdio-i2c.c @@ -352,7 +352,7 @@ return 0; } -static int i2c_mii_probe_rollball(struct i2c_adapter *i2c) +int mdio_i2c_probe_rollball(struct i2c_adapter *i2c) { u8 data_buf[] =3D { ROLLBALL_DATA_ADDR, 0x01, 0x00, 0x00 }; u8 cmd_buf[] =3D { ROLLBALL_CMD_ADDR, ROLLBALL_CMD_READ }; @@ -397,9 +397,11 @@ 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; @@ -419,7 +421,7 @@ if (ret !=3D 1) return -EIO; - return i2c_mii_probe_rollball(i2c); + return 0; } struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *= i2c, @@ -444,12 +446,8 @@ case MDIO_I2C_ROLLBALL: ret =3D i2c_mii_init_rollball(i2c); if (ret < 0) { - if (ret !=3D -ENODEV) - dev_err(parent, - "Cannot initialize RollBall MDIO I2C protocol: %d\n", - ret); - /* -ENODEV propagates to caller: no bridge present, - * PHY probing should be skipped for this module. */ + 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 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -2028,17 +2028,8 @@ static int sfp_sm_add_mdio_bus(struct sfp *sfp) dev_info(sfp->dev, "probing phy device through the [%s] protocol\n", mdio_i2c_proto_type(sfp->mdio_protocol)); - int ret; - if (sfp->mdio_protocol =3D=3D MDIO_I2C_NONE) return 0; - ret =3D sfp_i2c_mdiobus_create(sfp); - if (ret =3D=3D -ENODEV) { - /* Probe confirmed no bridge present; skip PHY discovery. */ - sfp->mdio_protocol =3D 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 @@ -2058,8 +2049,23 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp) case MDIO_I2C_ROLLBALL: - err =3D 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 =3D mdio_i2c_probe_rollball(sfp->i2c); + if (err =3D=3D -ENODEV) { + sfp_i2c_mdiobus_destroy(sfp); + sfp->mdio_protocol =3D MDIO_I2C_NONE; + break; + } + if (!err) + err =3D 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 --- a/include/linux/mdio/mdio-i2c.h +++ b/include/linux/mdio/mdio-i2c.h @@ -33,5 +33,6 @@ 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