From nobody Sun Feb 8 09:27:11 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2CF1338F244; Wed, 14 Jan 2026 22:57:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431481; cv=none; b=YlHLWMuftkrt/vxFCMYObQqPRKM0cQzd+EHxF3OXwQ1hUHB323XQFy4cywnP32YPEj4u7tUFfAipip4pobLmgJ4ZWuo11LykvqXjBQnI8LS9xsevUzvAq+UWeN3E4Y7wckzoisQ8WSIJRK4uErcW6iIpAKb0u7j3ExYDEwjjrOs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431481; c=relaxed/simple; bh=vRRIhHFPxtzThZZQkWphkJSxIn6V0oCyMNSakYsx6Oo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YpnsFLHx+XnBPZyXTZTL2hqyphM/cnybn+e27btIfx6ZfvXBQqRCR4bhYdcnLKYsH5gWOPPLaKdNHlZfBpjAumezrMnukciT3qD5dLIrgqJ/u3jdKEWuVAhOYT+A5/Xwx9kTq11hOJLB1uadovuuGLcLipzscCt/+H7Zcy/Z0W0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=krrboD/U; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="krrboD/U" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id B8F081A286C; Wed, 14 Jan 2026 22:57:49 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 8DF536074A; Wed, 14 Jan 2026 22:57:49 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 63EBE10B68428; Wed, 14 Jan 2026 23:57:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1768431468; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=vGkT6kUPV4XCoAV2sMfIa4glGoO0PPY84FW31CL588M=; b=krrboD/U0c0msIeHbPyU/Q1VZnhGftw7G9KU3HY/JcJtST9GXoGxRNrOrcXzdCz7XUKLnR h7D7z9DnvM4IinXd9rf+5iGd9bPLHxw+oWEDuUiiAW0Hw6v+J7muWODIeSik+fCws6OI4V 6Ulegra5k2Xw4BrTPq2Um8ems14miJZPdxv52H6qD+POXiW9DWfEV/L6h4Nnxlsbe3JL7F bPn2wEMvf+skrEK0jl7552pCvPWk9ikGZKOdWPG8RSkrGsTgiFX37zNfm16vG/1T9cwJk+ /f10LJVGwom20uhHJO6uPerckXZOMcArJLV/nu9nndvJqmpXYqUXfSvBbrtIJg== From: Maxime Chevallier To: davem@davemloft.net, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , Jonas Jelonek , Florian Fainelli , Heiner Kallweit Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Simon Horman , Romain Gantois , =?UTF-8?q?Marek=20Beh=C3=BAn?= , bcm-kernel-feedback-list@broadcom.com Subject: [PATCH net-next 1/6] net: sfp: Add support for SGMII to 100FX modules Date: Wed, 14 Jan 2026 23:57:23 +0100 Message-ID: <20260114225731.811993-2-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20260114225731.811993-1-maxime.chevallier@bootlin.com> References: <20260114225731.811993-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" There exist some SFP modules that rely on a built-in PHY (usually a Broadcom BCM5461) to output 100baseFX, using SGMII as the phy_interface. This is relevant as there are devices that support SGMII and 1000BaseX, but not 100FX natively on their SFP cages. SGMII can be used to convey 100Mbps links with symbol repetition, but the serdes lane stays clocked at 1.25GHz. We therefore absolutely need a media-converter to adapt this to 100BaseFX, that runs at 125MHz. What this means for the sfp-bus infrastructure is that we may have a PHY to probe when dealing with a 100FX (and possibly a 100LX) module, and if this PHY exist it will use SGMII. Signed-off-by: Maxime Chevallier --- drivers/net/phy/sfp-bus.c | 11 +++++++++++ drivers/net/phy/sfp.c | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c index b945d75966d5..85c9f21af69b 100644 --- a/drivers/net/phy/sfp-bus.c +++ b/drivers/net/phy/sfp-bus.c @@ -105,6 +105,14 @@ static void sfp_module_parse_may_have_phy(struct sfp_b= us *bus, return; } =20 + /* Some 100M fiber modules have a PHY, acting as an SGMII to 100FX + * media converter. + */ + if (id->base.e100_base_fx || id->base.e100_base_lx) { + bus->caps.may_have_phy =3D true; + return; + } + if (id->base.phys_id !=3D SFF8024_ID_DWDM_SFP) { switch (id->base.extended_cc) { case SFF8024_ECC_10GBASE_T_SFI: @@ -188,6 +196,9 @@ static void sfp_module_parse_support(struct sfp_bus *bu= s, if (id->base.e100_base_fx || id->base.e100_base_lx) { phylink_set(modes, 100baseFX_Full); __set_bit(PHY_INTERFACE_MODE_100BASEX, interfaces); + + /* SGMII to 100Base-FX modules with internal PHY */ + __set_bit(PHY_INTERFACE_MODE_SGMII, interfaces); } if ((id->base.e_base_px || id->base.e_base_bx10) && br_nom =3D=3D 100) { phylink_set(modes, 100baseFX_Full); diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 84bef5099dda..5b42af1cf6aa 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -2446,7 +2446,8 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool rep= ort) sfp->id.base.extended_cc =3D=3D SFF8024_ECC_5GBASE_T || sfp->id.base.extended_cc =3D=3D SFF8024_ECC_2_5GBASE_T) sfp->mdio_protocol =3D MDIO_I2C_C45; - else if (sfp->id.base.e1000_base_t) + else if (sfp->id.base.e1000_base_t || sfp->id.base.e100_base_fx || + sfp->id.base.e100_base_lx) sfp->mdio_protocol =3D MDIO_I2C_MARVELL_C22; else sfp->mdio_protocol =3D MDIO_I2C_NONE; --=20 2.49.0 From nobody Sun Feb 8 09:27:11 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D93738A9B9; Wed, 14 Jan 2026 22:57:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431482; cv=none; b=cVvl216LD8+vLBRCirbyJ2auCUdGN19/3k/g50pjMlS7jgYXCx7YL2rBstB0DL+cEUJDFsIsYkSGd+Z1KI8wQfh9nfcmWS2DGoIto3DpE+e+MEZKkunsYsssIubwCWaORmAl4E6oFIZq3DD6WeNvz1RZgguYrzmp4GrUdvLjGq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431482; c=relaxed/simple; bh=tFQX9lnNDiRM0fQOJbkTfE+NhfLRa+xgPNzuQfqM65Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p7Bs7ultR36UGbn/zKg3nwdH9ukLtaJPdLD+7Pdo7N5AGav2IoH+sZxti8lQfzOp6cL3NJAmxZnbFq0hWakp9UOCPnvZty3HG7Kv5evNm6DUVznSiOaxxl8wBp9ub13jWqmGAXHUzUuvsN4NWEYYBKwYK4zhkwNiiFA2FnlVv5w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=TYHJiCVR; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="TYHJiCVR" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 9F8FA1A286D; Wed, 14 Jan 2026 22:57:51 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 755E76074A; Wed, 14 Jan 2026 22:57:51 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 1E91010B6844D; Wed, 14 Jan 2026 23:57:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1768431470; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=uYA6wVCtRdWQWw+IybQzQvnWtQbLpvNWV0ujt0iJQw8=; b=TYHJiCVRzVzVJPV4+QH3mlcDkGN/i6HICnDsAXPjEQ6dyEVUwbJ8/JboZRuZLZZ3IlnmUL rejXt+fskzojknGO7Kips1KLoaTQ3nXu924dZ3s80y32afkOixqY4jMIjfNRfBdYKNUvi5 hKuH8TCc7d71Q4sjkOcUSqXpUBvr1JR7uwoQWTqG2SBkvj6FVV26X88JzXjuqQPBZH1kkF wbZ2390KSOJ6DnHKZ3ty98sR1i8JmBTZyo/gm/SkWE7zzI34OxdcWcJxJ/P2cEZLX7jxII HbjC5bOnU+Zm5LE/GTTHbiNccl3N6OcNbM9RhQvJHcjGp0YaI8FeZm85Aj2JwA== From: Maxime Chevallier To: davem@davemloft.net, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , Jonas Jelonek , Florian Fainelli , Heiner Kallweit Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Simon Horman , Romain Gantois , =?UTF-8?q?Marek=20Beh=C3=BAn?= , bcm-kernel-feedback-list@broadcom.com Subject: [PATCH net-next 2/6] net: phylink: Allow more interfaces in SFP interface selection Date: Wed, 14 Jan 2026 23:57:24 +0100 Message-ID: <20260114225731.811993-3-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20260114225731.811993-1-maxime.chevallier@bootlin.com> References: <20260114225731.811993-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" When phylink handles an SFP module that contains a PHY, it selects a phy_interface to use to communicate with it. This selection ensures that the highest speed gets achieved, based on the linkmodes we want to support in the module. This approach doesn't take into account the supported interfaces reported by the module, but also doesn't handle the fact that the same linkmode may be achieved using different phy_interface modes. It becomes an issue when trying to support SGMII to 100FX modules. We can't feed it 100BaseX, and its MDI isn't 1000BaseT (the modes we expect for SGMII to be selected). Let's therefore use a different approach : - Get the common interfaces between what the module and the SFP Bus support - From that common interface list, select the one that can allow us to achieve the highest speed Signed-off-by: Maxime Chevallier --- drivers/net/phy/phy-caps.h | 5 ++++ drivers/net/phy/phy_caps.c | 47 ++++++++++++++++++++++++++++++++++++++ drivers/net/phy/phylink.c | 24 ++++++------------- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/drivers/net/phy/phy-caps.h b/drivers/net/phy/phy-caps.h index 5f3f757e0b2f..4a07ac74ef13 100644 --- a/drivers/net/phy/phy-caps.h +++ b/drivers/net/phy/phy-caps.h @@ -10,6 +10,7 @@ #include #include =20 +/* this must be sorted by speed */ enum { LINK_CAPA_10HD =3D 0, LINK_CAPA_10FD, @@ -66,4 +67,8 @@ void phy_caps_medium_get_supported(unsigned long *support= ed, int lanes); u32 phy_caps_mediums_from_linkmodes(unsigned long *linkmodes); =20 +phy_interface_t +phy_caps_select_fastest_interface(const unsigned long *interfaces, + const unsigned long *linkmodes); + #endif /* __PHY_CAPS_H */ diff --git a/drivers/net/phy/phy_caps.c b/drivers/net/phy/phy_caps.c index 17a63c931335..11e7a1efcf30 100644 --- a/drivers/net/phy/phy_caps.c +++ b/drivers/net/phy/phy_caps.c @@ -443,3 +443,50 @@ u32 phy_caps_mediums_from_linkmodes(unsigned long *lin= kmodes) return mediums; } EXPORT_SYMBOL_GPL(phy_caps_mediums_from_linkmodes); + +/** + * phy_caps_select_fastest_interface - Select the fastest interface that c= an + * support the fastest of the given + * linkmodes + * @interfaces: The interface list to lookup from + * @linkmodes: Linkmodes we want to support + * + * Returns: The fastest matching interface, PHY_INTERFACE_MODE_NA otherwis= e. + */ +phy_interface_t +phy_caps_select_fastest_interface(const unsigned long *interfaces, + const unsigned long *linkmodes) +{ + phy_interface_t interface =3D PHY_INTERFACE_MODE_NA; + u32 target_link_caps =3D 0; + int i, max_capa =3D 0; + + /* Link caps from the linkmodes */ + for_each_set_bit(i, linkmodes, __ETHTOOL_LINK_MODE_MASK_NBITS) { + const struct link_mode_info *linkmode; + + linkmode =3D &link_mode_params[i]; + target_link_caps |=3D speed_duplex_to_capa(linkmode->speed, + linkmode->duplex); + } + + for_each_set_bit(i, interfaces, PHY_INTERFACE_MODE_MAX) { + u32 interface_caps =3D phy_caps_from_interface(i); + u32 interface_max_capa; + + /* Can we achieve at least one mode with this interface ? */ + if (!(interface_caps & target_link_caps)) + continue; + + /* Biggest link_capa we can achieve with this interface */ + interface_max_capa =3D fls(interface_caps & target_link_caps); + + if (interface_max_capa > max_capa) { + max_capa =3D interface_max_capa; + interface =3D i; + } + } + + return interface; +} +EXPORT_SYMBOL_GPL(phy_caps_select_fastest_interface); diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 43d8380aaefb..18fa417b87dd 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -2808,27 +2808,19 @@ EXPORT_SYMBOL_GPL(phylink_ethtool_set_wol); static phy_interface_t phylink_sfp_select_interface(struct phylink *pl, const unsigned long *link_modes) { - phy_interface_t interface; + DECLARE_PHY_INTERFACE_MASK(common_interfaces); =20 - interface =3D sfp_select_interface(pl->sfp_bus, link_modes); - if (interface =3D=3D PHY_INTERFACE_MODE_NA) { - phylink_err(pl, - "selection of interface failed, advertisement %*pb\n", - __ETHTOOL_LINK_MODE_MASK_NBITS, - link_modes); - return interface; - } + /* Interfaces supported both by the module and the bus */ + phy_interface_and(common_interfaces, pl->sfp_interfaces, + pl->config->supported_interfaces); =20 - if (!test_bit(interface, pl->config->supported_interfaces)) { + if (phy_interface_empty(common_interfaces)) { phylink_err(pl, - "selection of interface failed, SFP selected %s (%u) but MAC suppor= ts %*pbl\n", - phy_modes(interface), interface, - (int)PHY_INTERFACE_MODE_MAX, - pl->config->supported_interfaces); + "selection of interface failed, no common interface between MAC and= SFP\n"); return PHY_INTERFACE_MODE_NA; } =20 - return interface; + return phy_caps_select_fastest_interface(common_interfaces, link_modes); } =20 static phy_interface_t phylink_sfp_select_interface_speed(struct phylink *= pl, @@ -3697,8 +3689,6 @@ static int phylink_sfp_config_phy(struct phylink *pl,= struct phy_device *phy) struct phylink_link_state config; int ret; =20 - /* We're not using pl->sfp_interfaces, so clear it. */ - phy_interface_zero(pl->sfp_interfaces); linkmode_copy(support, phy->supported); =20 memset(&config, 0, sizeof(config)); --=20 2.49.0 From nobody Sun Feb 8 09:27:11 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 51FB5326D76 for ; Wed, 14 Jan 2026 22:58:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431483; cv=none; b=JYvPEXmunC2kpd3nzpD6ZVuTalThV2Cr4zaPlt+/hou8tmY/Vbn9JJaCeUINU7JGNAKKDNQr7zpUSOXVbtps/CNzvHuLVMOcVy1wjN5C7SQLgAE1qdSi3muoNEj8z86QEiU/9UQqUTAvCXqDcqlzsZJhFEjG5Tscc4G5z6p+UGA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431483; c=relaxed/simple; bh=cEX56O7lFKginQnkeWC5k3VQ5cnyMT/ZHcHCaKr+ehw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WqhafCqrjLCNPOtcQb5TJDCSr2q0JITFDR7ik+rhLrEtuvAKk+CEg6vXYvpDMPT2b4W9OrdxliCdfVBwaWM5j0L3AIWiUPmYMGbaITTeXsQSoEMwbk1vdddWO1JcIRX835NGfOy8WDFuh4TUXRmiY/LMAdlUvbANPkTikLpI/0c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=x5Yl7BWn; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="x5Yl7BWn" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 920D81A286E; Wed, 14 Jan 2026 22:57:53 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 65C746074A; Wed, 14 Jan 2026 22:57:53 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id F0EBC10B68410; Wed, 14 Jan 2026 23:57:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1768431472; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=+/6GTR/lJRvxq7OYqByep9cN9DNBMPgL+lC49ZimkbA=; b=x5Yl7BWnN863GrXNmtdIwijhs2RcnvC2ZsHGN5T74+4fSVbGFJ+mTS0wUaeycV0VkN+QM0 bss2jf72KyQgkIl47EuuyXz/f1TytJLNj9SA9DRbiQjnYcwqP9XWmyT4j5COecGM0iVCiI Tz0reOEDhjJQTmgJYAI7UMmkNMAAxpc+jOda6QO/JeI7BDh+dy+2N3LrDRl/pCAAg2R6Xi St+zukWadf2dninDaNmEztOZbjg21SEeiSbxIDXTs3NrzY4Kd//7dIymNQcZ48ZxXa78xp iBlqe29faCIoRV07nLwB0RObrltffkQ3JW856OyY2aIDh+El9XW0HOFdMkTpoQ== From: Maxime Chevallier To: davem@davemloft.net, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , Jonas Jelonek , Florian Fainelli , Heiner Kallweit Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Simon Horman , Romain Gantois , =?UTF-8?q?Marek=20Beh=C3=BAn?= , bcm-kernel-feedback-list@broadcom.com Subject: [PATCH net-next 3/6] net: phy: Store module caps for PHYs embedded in SFP Date: Wed, 14 Jan 2026 23:57:25 +0100 Message-ID: <20260114225731.811993-4-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20260114225731.811993-1-maxime.chevallier@bootlin.com> References: <20260114225731.811993-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" When a PHY device is embedded in an SFP module, the PHY driver doesn't have any information about the module. Most of the SGMII to 100BaseFX modules seem to contain a Broadcom BCM5461 PHY. This device seems to support a wide range of possible configurations, with RGMII or SGMII inputs, and BaseT, 100BaseFX and possibly 1000BaseX output. However, there doesn't seem to be a capability register that returns reliable-enough values to detect from the PHY driver what configuration we are in. On the Prolabs or FS SGMII to 100FX modules for example, the PHY returns 10/100/1000BaseT capabilities. We can know the exact configuration by looking at the SFP eeprom, and the list of linkmodes built by parsing it and applying the quirks and fixups. Let's make that information available to PHY drivers, so that they may use that in their .get_features() and configuration process. Signed-off-by: Maxime Chevallier --- drivers/net/phy/sfp.c | 5 +++++ include/linux/phy.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 5b42af1cf6aa..1f9112efef62 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -1895,6 +1895,11 @@ static int sfp_sm_probe_phy(struct sfp *sfp, int add= r, bool is_c45) /* Mark this PHY as being on a SFP module */ phy->is_on_sfp_module =3D true; =20 + /* We need to populate the parent_sfp_caps now, as it may be used during + * the phy registering process, such as in phydrv->get_features() + */ + phy->parent_sfp_caps =3D sfp_get_module_caps(sfp->sfp_bus); + err =3D phy_device_register(phy); if (err) { phy_device_free(phy); diff --git a/include/linux/phy.h b/include/linux/phy.h index 3beb5dbba791..a515c014679e 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -649,6 +649,8 @@ struct phy_oatc14_sqi_capability { * @ports: List of PHY ports structures * @n_ports: Number of ports currently attached to the PHY * @max_n_ports: Max number of ports this PHY can expose + * @parent_sfp_caps: Capabilities of the SFP module that embeds this PHY. = Only + * valid when is_on_sfp_module is true. * @lock: Mutex for serialization access to PHY * @state_queue: Work queue for state machine * @link_down_events: Number of times link was lost @@ -791,6 +793,8 @@ struct phy_device { int n_ports; int max_n_ports; =20 + const struct sfp_module_caps *parent_sfp_caps; + u8 mdix; u8 mdix_ctrl; =20 --=20 2.49.0 From nobody Sun Feb 8 09:27:11 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2CC4838F233; Wed, 14 Jan 2026 22:57:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431484; cv=none; b=pXvSLx9IEzBF6DKitLK/nvVKuL3YfotIY1Xp9gGZHzBt2pEZXdkKY1y2wjEvzIUAwRzEXa2lfzUoTpuoCqDNdr0i2ahHbPVg3GmRROvllYX0MZ534828wF0vWLbdQalHI+jpCMnAFyjIfp6VCFyl/Xfpe8gIZOEH1mHkXdyYiKE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431484; c=relaxed/simple; bh=zjE11OdrpdIYORzL7p98BWkcLHYUKy4ikScJetEeEbk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KNqDWffQ+FvXba9nA7eU4golR11bl9/9s8FqnE5o1COCzRfM+z+lay7AUfJnrmkA08m+ranKmYpKtfPr/vvQPGHrHbD9y/3OlgMluwubJHGLBcfti+M8iae9AAP6gg6k4+Nw92V0y0Et97i6/5R4sPfW+aHnViX0IelkMX/+/n0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=kPDQCcKv; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="kPDQCcKv" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 5A0724E420E4; Wed, 14 Jan 2026 22:57:55 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2F1A46074A; Wed, 14 Jan 2026 22:57:55 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D766210B68428; Wed, 14 Jan 2026 23:57:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1768431474; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=R0IomDMS8ECUCELWItPyizADN17LB+B8jCYycdfWEZ4=; b=kPDQCcKvv6t7spx9O1C7GxmsJqQIH/ru/XwhuG6+wI52g9AdcMY0Ar5c/klP/3wNSjS4LE EtQ/2ryqdrKgbsOmOFHHvdGl7XeIySonsoCd/cDzixiGq1tXQKtCTQQhaELWLZZXE3WQjW goW+Q3AE7A3ub9xdLX03ZTxFAbUAFSSOaCIkGKFGgTZkMkfslgbmEIURnBrJ6i/L5Ijzfz IAeTi76lEyqRO0ffuFa5IkXZOpKL2SG8fXh7bWsGeXB7aUX1hMDXRlVdRew1+CpP5hVnSF 7Aq08kQsKpR91bviYxC918bygqspsso2kAhG1Ns6nAw2i+qBHiHFnentJq5xPw== From: Maxime Chevallier To: davem@davemloft.net, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , Jonas Jelonek , Florian Fainelli , Heiner Kallweit Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Simon Horman , Romain Gantois , =?UTF-8?q?Marek=20Beh=C3=BAn?= , bcm-kernel-feedback-list@broadcom.com Subject: [PATCH net-next 4/6] net: phy: broadcom: Support SGMII to 100FX on BCM5461 Date: Wed, 14 Jan 2026 23:57:26 +0100 Message-ID: <20260114225731.811993-5-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20260114225731.811993-1-maxime.chevallier@bootlin.com> References: <20260114225731.811993-1-maxime.chevallier@bootlin.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 X-Last-TLS-Session-Version: TLSv1.3 Multiple SFP modules of the type "SGMII to 100BaseFX" appear to be using a Broadcom BCM5461 PHY as a media converter inside the module. This is the case for at least the Prolabs GLC-GE-100FX-C, and the FS SFP-GE-100FX modules. Out of the box, these modules don't work, and need the PHY to be configured. Florian Fainelli has helped a lot, and provided some programming instructions to use this mode in the PHY. Implement support for that mode, based on Florian's instructions and some more tweaks found by trial and error. There's no register we can read from the PHY to know that the PHY is operating in SGMII to 100FX, so we also add a .get_features() callback that populates the PHY's supported linkmodes according to the module caps parsed from the eeprom. Signed-off-by: Maxime Chevallier --- drivers/net/phy/broadcom.c | 94 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index cb306f9e80cc..bcdd6ed70b6b 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -455,6 +456,78 @@ static int bcm54811_config_init(struct phy_device *phy= dev) return bcm5481x_set_brrmode(phydev, priv->brr_mode); } =20 +static int bcm5461_config_init(struct phy_device *phydev) +{ + int rc, val; + + /* We don't have any special steps to follow for anything other than + * SGMII to 100BaseFX + */ + if (phydev->interface !=3D PHY_INTERFACE_MODE_SGMII || + !linkmode_test_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, + phydev->supported)) + return 0; + + /* Select 1000BASE-X register set (primary SerDes) */ + val =3D bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE); + if (val < 0) + return val; + val |=3D BCM54XX_SHD_MODE_1000BX; + rc =3D bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val); + if (rc < 0) + return rc; + + /* Power down SerDes interface */ + rc =3D phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN); + if (rc < 0) + return rc; + + /* Select proper interface mode */ + val &=3D ~BCM54XX_SHD_INTF_SEL_MASK; + val |=3D phydev->interface =3D=3D PHY_INTERFACE_MODE_SGMII ? + BCM54XX_SHD_INTF_SEL_SGMII : + BCM54XX_SHD_INTF_SEL_GBIC; + rc =3D bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val); + if (rc < 0) + return rc; + + /* Power up SerDes interface */ + rc =3D phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN); + if (rc < 0) + return rc; + + /* For 100BaseFX, the signal detection is configured in bit 5 of the shad= ow + * 0b01100 in the 0x1C register. + * + * 0 to use EN_10B/SD as CMOS/TTL signal detect (default) + * 1 to use SD_100FX=C2=B1 as PECL signal detect + */ + rc =3D bcm_phy_write_shadow(phydev, 0xC, BIT(5)); + if (rc < 0) + return rc; + + /* You can use either copper or SGMII interface for 100BaseFX and that wi= ll + * be configured this way: + * + * - in register 0x1C, shadow 0b10 (1000Base-T/100Base-TX/10Base-T Spare + * Control 1), set bit 4 to 1 to enable 100BaseFX + */ + rc =3D bcm_phy_write_shadow(phydev, 0x2, BIT(4)); + if (rc < 0) + return rc; + + /* disable auto-negotiation with register 0x00 =3D 0x2100 */ + phy_write(phydev, MII_BMCR, 0x2100); + + /* set register 0x18 to 0x430 (bit 10 -> normal mode, bits 5:4 control + * the edge rate. 0b00 -> 4ns, 0b01 -> 5ns, 0b10 -> 3ns, 0b11 -> 0ns. This + * is the auxiliary control register (MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL). + */ + phy_write(phydev, 0x18, 0x430); + + return 0; +} + static int bcm54xx_config_init(struct phy_device *phydev) { int reg, err, val; @@ -492,6 +565,9 @@ static int bcm54xx_config_init(struct phy_device *phyde= v) case PHY_ID_BCM54210E: err =3D bcm54210e_config_init(phydev); break; + case PHY_ID_BCM5461: + err =3D bcm5461_config_init(phydev); + break; case PHY_ID_BCM54612E: err =3D bcm54612e_config_init(phydev); break; @@ -1255,6 +1331,23 @@ static void bcm54xx_link_change_notify(struct phy_de= vice *phydev) bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, ret); } =20 +static int bcm5461_get_features(struct phy_device *phydev) +{ + if (!phy_on_sfp(phydev)) + return genphy_read_abilities(phydev); + + if (!phydev->parent_sfp_caps) + return -EINVAL; + + /* For SGMII to 100FX modules, the reported linkmodes from + * genphy_read_abilities() are incorrect. Let's repy on the SFP module + * caps + */ + linkmode_copy(phydev->supported, phydev->parent_sfp_caps->link_modes); + + return 0; +} + static int lre_read_master_slave(struct phy_device *phydev) { int cfg =3D MASTER_SLAVE_CFG_UNKNOWN, state; @@ -1505,6 +1598,7 @@ static struct phy_driver broadcom_drivers[] =3D { .probe =3D bcm54xx_phy_probe, .config_init =3D bcm54xx_config_init, .config_intr =3D bcm_phy_config_intr, + .get_features =3D bcm5461_get_features, .handle_interrupt =3D bcm_phy_handle_interrupt, .link_change_notify =3D bcm54xx_link_change_notify, .led_brightness_set =3D bcm_phy_led_brightness_set, --=20 2.49.0 From nobody Sun Feb 8 09:27:11 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F4B438B98D; Wed, 14 Jan 2026 22:58:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431485; cv=none; b=aa83aFr71PCQjbhH7dZZyFo9qWMyWoUQJsseqglcBmvidKXAxzbf/LWQ0w7fIPU3gTTPXwngXmJ4cH8YHCfit/9tEx0fgeA6yj2S/wRM1MX5YP30Ri77MWI/wSn1gFuDtdSfYC7yZ8TZSz2A4eZ1DfcqhBW8/kK4h+fGrWPiJjQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431485; c=relaxed/simple; bh=z4WqN2kh5qmAt21Q277EcIgqW0dOmQxzf7nNvly+CsY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XDbNsKLLpObz6ZfBpZHf6H8bX+N1X9o6kGBdsqZABA5r61XIdLeRxDjV+Ki7MoUWihUkrYRSGGhUqqX5r1ut1GOYSjI/iGIA9ejQuB7yfggHcmgVS1WtOiyBVzWEKikdXLjJf85V08QZE3LCR7bsVdGRcipYeEm9hCILBgN+hyI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=TCMS1gX8; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="TCMS1gX8" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 389A41A2870; Wed, 14 Jan 2026 22:57:57 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0ECEF6074A; Wed, 14 Jan 2026 22:57:57 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B522A10B68450; Wed, 14 Jan 2026 23:57:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1768431476; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Jrfj5FZfYx7TZar0UsYfofe6PTAJ+saTzQzi5V7Is9I=; b=TCMS1gX8OD9n7qRPEOnqKvI8QBs15gRU9Ar58RkcY98JNuvAp4BP8bEYyE1DINXC6sux3x h4Oohx5k28UU5/WEGhYkuB7e0D/VGg6/7lmLpcgsKHUHsGIFcflCe8utX0SWaaWx8WBG3L 7f8zG+96cKFVnSBQg9VXGx1co0zyOg+sTRb0n+7t8qx9+GZpfffJYdsXdhIRS+EWHXCXCw pdCFWuEf7/OLGY/gW9qoAxDhoBECrYj0sbVz0rZ0pEkRVlMf1JnZd9R35OFh/HQiDwPLLL VVHrJY8fv3DyAvUNwLMniv6yw6otInXpiZ2lsc4R4t44KJLSNCAR4Zfcf8Oevw== From: Maxime Chevallier To: davem@davemloft.net, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , Jonas Jelonek , Florian Fainelli , Heiner Kallweit Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Simon Horman , Romain Gantois , =?UTF-8?q?Marek=20Beh=C3=BAn?= , bcm-kernel-feedback-list@broadcom.com Subject: [PATCH net-next 5/6] net: mdio: mdio-i2c: Add single-byte C22 MDIO protocol Date: Wed, 14 Jan 2026 23:57:27 +0100 Message-ID: <20260114225731.811993-6-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20260114225731.811993-1-maxime.chevallier@bootlin.com> References: <20260114225731.811993-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" In commit d4bd3aca33c2 ("net: mdio: mdio-i2c: Add support for single-byte SMBus operations"), we introduced single-byte SMBus support for the mdio-i2c. This was intended to deal with the case where the I2C adapter that accesses the SFP module is limited to single-byte smbus accesses. We find this type of adapters in some PHY devices such as the VSC8552. It was discovered that some SFP modules have a built-in PHY that only reply to single-byte smbus accesses. This is the case for the Prolabs GLC-GE-100FX-C SGMII to 100FX module, which contains a Broadcom BCM5461 PHY. In that case, trying to access the PHY with regular 16-bit transactions with the mdio-i2c driver causes the PHY to stall the i2c bus completely, without any way to recover. Accessing it in single-byte mode however, works fine. Add a dedicated MDIO_I2C_SINGLE_BYTE_C22 protocol type, so that we can setup the mdio-i2c driver accordingly. The good news here is that this should work on pretty much every setup, as a true I2C adapter is also capable of single-byte accesses thanks to the i2c smbus emulation layer. Some care will need to be taken should we add support for word-only smbus adapters. Signed-off-by: Maxime Chevallier --- drivers/net/mdio/mdio-i2c.c | 12 ++++++++---- drivers/net/phy/sfp.c | 1 + include/linux/mdio/mdio-i2c.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/mdio/mdio-i2c.c b/drivers/net/mdio/mdio-i2c.c index ed20352a589a..86ae8a5c0ebd 100644 --- a/drivers/net/mdio/mdio-i2c.c +++ b/drivers/net/mdio/mdio-i2c.c @@ -452,7 +452,8 @@ static bool mdio_i2c_check_functionality(struct i2c_ada= pter *i2c, return true; =20 if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA) && - protocol =3D=3D MDIO_I2C_MARVELL_C22) + (protocol =3D=3D MDIO_I2C_MARVELL_C22 || + protocol =3D=3D MDIO_I2C_SINGLE_BYTE_C22)) return true; =20 return false; @@ -475,9 +476,12 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, = struct i2c_adapter *i2c, mii->parent =3D parent; mii->priv =3D i2c; =20 - /* Only use SMBus if we have no other choice */ - if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA) && - !i2c_check_functionality(i2c, I2C_FUNC_I2C)) { + /* Only use single-byte SMBus if explicitly asked, or if we have no + * other choice. + */ + if (protocol =3D=3D MDIO_I2C_SINGLE_BYTE_C22 || + (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA) && + !i2c_check_functionality(i2c, I2C_FUNC_I2C))) { mii->read =3D smbus_byte_mii_read_default_c22; mii->write =3D smbus_byte_mii_write_default_c22; return mii; diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 1f9112efef62..bff91735f681 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -2016,6 +2016,7 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp) break; =20 case MDIO_I2C_MARVELL_C22: + case MDIO_I2C_SINGLE_BYTE_C22: err =3D sfp_sm_probe_phy(sfp, SFP_PHY_ADDR, false); break; =20 diff --git a/include/linux/mdio/mdio-i2c.h b/include/linux/mdio/mdio-i2c.h index 65b550a6fc32..f51c474da5b1 100644 --- a/include/linux/mdio/mdio-i2c.h +++ b/include/linux/mdio/mdio-i2c.h @@ -16,6 +16,7 @@ enum mdio_i2c_proto { MDIO_I2C_MARVELL_C22, MDIO_I2C_C45, MDIO_I2C_ROLLBALL, + MDIO_I2C_SINGLE_BYTE_C22, }; =20 struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *= i2c, --=20 2.49.0 From nobody Sun Feb 8 09:27:11 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA7D238B9B1 for ; Wed, 14 Jan 2026 22:58:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431484; cv=none; b=LtS/AvF/04kFNBGhwy3KDfx5XsS7Uqmo4w4CVyIrpUEiec57yilVP4UTxIZbtzevPIuedOiKEWO5gxlAvV4s0bKrXRNbqYX9AMRMNFEXIRSS3Pyta+tZ0LVRn7f92KN4gMJj7Tds0IIj3ecwKiq081CA+c32C/rWlPzL5Q4BxAc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768431484; c=relaxed/simple; bh=UZFF7EGigj87tKtghH3PWskqYcKPnK8/xYSbYkt24Rw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RC6vAqhlmSP/H2RsmawaVsnWkEQvfPBYdzCdl8DQdpgOZmmf8G75nT9sHJXpg1jHngMrG6X05aXFF4QXvFPafwGLV4+0Ri7fO1PEKpH+MqT02Vylq5Oo15b7hXjYOaugjTxj+DClltTZG4HyVyAlSs3eYKm/42Vzqpz4F3UVYBM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=ejeddw9K; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="ejeddw9K" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id CE3FC4E420E2; Wed, 14 Jan 2026 22:57:58 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id A56756074A; Wed, 14 Jan 2026 22:57:58 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 942CD10B6844D; Wed, 14 Jan 2026 23:57:56 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1768431477; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=WG7VCGaZSEoU/lQqsDROfaKQGjsZRjDe86EKvqK3pMw=; b=ejeddw9KqV5IZSGnRaayg/QWKIoUc4XZA6OKXqqwzmqz6PDwKxfevINCcSEQoS80SXVKAl Mtcq6sUIJvRYVR0AO66EWAKHn1aU5uGT2Iayd17bngJIYdzteBwC//CQTAQWdtn039sG1h H1fYI9Ozf8nauI8aJUKHIrQtXKlntGF9h9EjtbZ33B14y6op/F2h1IEEipoC4IT2M7+xSa V72l5OtojjdmJBuT6puoAxpHmFh9CbhI2OfqWRnh4AOkzW/YhKfqGtQwvDb0GOMBYgUH4V Impl+r1SjBfVhbURHGPK/c25Os/K7diL2My2ni94+Yr8knAPXS6olXBlFR0rmA== From: Maxime Chevallier To: davem@davemloft.net, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , Jonas Jelonek , Florian Fainelli , Heiner Kallweit Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Simon Horman , Romain Gantois , =?UTF-8?q?Marek=20Beh=C3=BAn?= , bcm-kernel-feedback-list@broadcom.com Subject: [PATCH net-next 6/6] net: sfp: Add support for some BCM5461-based SGMII to 100FX modules Date: Wed, 14 Jan 2026 23:57:28 +0100 Message-ID: <20260114225731.811993-7-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20260114225731.811993-1-maxime.chevallier@bootlin.com> References: <20260114225731.811993-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The Prolabs GLC-GE-100FX-C SFP module is a 100BaseFX module that plugs into a Cisco SGMII capable cage, thus allowing to use 100M fiber on ports that would usually only support SGMII and 1000BaseX. This module contains a Broadcom BCM5461 PHY, but fails to properly indicate support for e.100_fx mode. The FS SFP-GE-100FX-C is a similar module, but this one does have the e.100_fx bit set. Add a quirk and fixup for these modules, to have a consistent linkmode set, and make sure we use SGMII as the PHY interface. The Prolabs module absolutely needs single-byte mdio accesses, otherwise it freezes the i2c bus. Signed-off-by: Maxime Chevallier --- drivers/net/phy/sfp.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index bff91735f681..fb12616a67c1 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -481,6 +481,23 @@ static void sfp_quirk_ubnt_uf_instant(const struct sfp= _eeprom_id *id, caps->link_modes); } =20 +static void sfp_fixup_sgmii_100fx(struct sfp *sfp) +{ + sfp->mdio_protocol =3D MDIO_I2C_SINGLE_BYTE_C22; + sfp->module_t_wait =3D msecs_to_jiffies(500); +} + +static void sfp_quirk_sgmii_100fx(const struct sfp_eeprom_id *id, + struct sfp_module_caps *caps) +{ + /* Prolabs GLC-GE-100FX-C SGMII to 100FX module doesn't set the + * base.e100_base_fx bit. + */ + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, + caps->link_modes); + __set_bit(PHY_INTERFACE_MODE_SGMII, caps->interfaces); +} + #define SFP_QUIRK(_v, _p, _s, _f) \ { .vendor =3D _v, .part =3D _p, .support =3D _s, .fixup =3D _f, } #define SFP_QUIRK_S(_v, _p, _s) SFP_QUIRK(_v, _p, _s, NULL) @@ -553,6 +570,11 @@ static const struct sfp_quirk sfp_quirks[] =3D { SFP_QUIRK_F("Turris", "RTSFP-2.5G", sfp_fixup_rollball), SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball), SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball), + + SFP_QUIRK("CISCO-PROLABS", "GLC-GE-100FX-C", + sfp_quirk_sgmii_100fx, sfp_fixup_sgmii_100fx), + SFP_QUIRK("FS", "SFP-GE-100FX", + sfp_quirk_sgmii_100fx, sfp_fixup_sgmii_100fx), }; =20 static size_t sfp_strlen(const char *str, size_t maxlen) --=20 2.49.0