From nobody Wed Sep 10 05:16:07 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (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 5A1F230499B for ; Mon, 8 Sep 2025 12:46:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757335591; cv=none; b=VNqOGKoqJA3W2BCUomkd/kqTG/K29XzCNTxWv9Sas1SB1hP/nBvQw9Pu9J2YT1NOBOmib6e2MIqD6jJ1h+rllxtcfXJsT78BpTqpfi8T16d7g9LE3hNr+rmNZf7CYbMz/ZyKmfFbE20Y06mloM+Ql9gIr73Wb1oEaQLKdp1tWXM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757335591; c=relaxed/simple; bh=eqi5cWxql2GFQOQrFamav+SZLeSxTtB7OrfG1LHpA/g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QFnYGWV2XeNkteyWn1kw8oJACLCZL3PY4Gl6bhQTbGmIIKsvOoIXWpkUjo8AsRvt+hKynBbmiFDrcoiha6uETzdS4pL592J2Dh/hIEoXbOGGqY8DTqSXBZUu5PYHNtP4a54TZ3ssgHgfNyU+iiaO4/WuIYNzk8n3qgR9v9huBUE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1uvbG9-0003S9-F8; Mon, 08 Sep 2025 14:46:13 +0200 Received: from dude04.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::ac]) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uvbG7-000Fis-2h; Mon, 08 Sep 2025 14:46:11 +0200 Received: from ore by dude04.red.stw.pengutronix.de with local (Exim 4.98.2) (envelope-from ) id 1uvbG7-0000000CKJo-34Ag; Mon, 08 Sep 2025 14:46:11 +0200 From: Oleksij Rempel To: Andrew Lunn , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Donald Hunter , Jonathan Corbet , Heiner Kallweit , Russell King , Kory Maincent , Maxime Chevallier , Nishanth Menon Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, UNGLinuxDriver@microchip.com, linux-doc@vger.kernel.org, Michal Kubecek , Roan van Dijk Subject: [PATCH net-next v5 4/5] net: phy: micrel: add MSE interface support for KSZ9477 family Date: Mon, 8 Sep 2025 14:46:09 +0200 Message-ID: <20250908124610.2937939-5-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20250908124610.2937939-1-o.rempel@pengutronix.de> References: <20250908124610.2937939-1-o.rempel@pengutronix.de> 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-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Implement the get_mse_config() and get_mse_snapshot() PHY driver ops for KSZ9477-series integrated PHYs to demonstrate the new PHY MSE UAPI. These PHYs do not expose a documented direct MSE register, but the Signal Quality Indicator (SQI) registers are derived from the internal MSE computation. This hook maps SQI readings into the MSE interface so that tooling can retrieve the raw value together with metadata for correct interpretation in userspace. Behaviour: - For 1000BASE-T, report per-channel (A=E2=80=93D) values and support a WORST channel selector. - For 100BASE-TX, only LINK-wide measurements are available. - Report average MSE only, with a max scale based on KSZ9477_MMD_SQI_MASK and a fixed refresh rate of 2 =C2=B5s. This mapping differs from the OPEN Alliance SQI definition, which assigns thresholds such as pre-fail indices; the MSE interface instead provides the raw measurement, leaving interpretation to userspace. Signed-off-by: Oleksij Rempel --- drivers/net/phy/micrel.c | 76 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index e403cbbcead5..075ac5093390 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -2320,6 +2320,80 @@ static int kszphy_get_sqi_max(struct phy_device *phy= dev) return KSZ9477_SQI_MAX; } =20 +static int kszphy_get_mse_config(struct phy_device *phydev, + struct phy_mse_config *config) +{ + if (phydev->speed =3D=3D SPEED_1000) + config->supported_caps |=3D PHY_MSE_CAP_CHANNEL_A | + PHY_MSE_CAP_CHANNEL_B | + PHY_MSE_CAP_CHANNEL_C | + PHY_MSE_CAP_CHANNEL_D | + PHY_MSE_CAP_WORST_CHANNEL; + else if (phydev->speed =3D=3D SPEED_100) + config->supported_caps |=3D PHY_MSE_CAP_LINK; + else + return -EOPNOTSUPP; + + config->max_average_mse =3D FIELD_MAX(KSZ9477_MMD_SQI_MASK); + config->refresh_rate_ps =3D 2000000; /* 2 us */ + /* Estimated from link modulation (125 MBd per channel) and documented + * refresh rate of 2 =C2=B5s + */ + config->num_symbols =3D 250; + + config->supported_caps |=3D PHY_MSE_CAP_AVG; + + return 0; +} + +static int kszphy_get_mse_snapshot(struct phy_device *phydev, u32 channel, + struct phy_mse_snapshot *snapshot) +{ + u8 num_channels; + int ret; + + if (phydev->speed =3D=3D SPEED_1000) + num_channels =3D 4; + else if (phydev->speed =3D=3D SPEED_100) + num_channels =3D 1; + else + return -EOPNOTSUPP; + + if (channel =3D=3D PHY_MSE_CHANNEL_WORST) { + u32 worst_val =3D 0; + int i; + + for (i =3D 0; i < num_channels; i++) { + ret =3D phy_read_mmd(phydev, MDIO_MMD_PMAPMD, + KSZ9477_MMD_SIGNAL_QUALITY_CHAN_A + i); + if (ret < 0) + return ret; + + ret =3D FIELD_GET(KSZ9477_MMD_SQI_MASK, ret); + if (ret > worst_val) + worst_val =3D ret; + } + snapshot->average_mse =3D worst_val; + } else if (channel =3D=3D PHY_MSE_CHANNEL_LINK && num_channels =3D=3D 1) { + ret =3D phy_read_mmd(phydev, MDIO_MMD_PMAPMD, + KSZ9477_MMD_SIGNAL_QUALITY_CHAN_A); + if (ret < 0) + return ret; + snapshot->average_mse =3D FIELD_GET(KSZ9477_MMD_SQI_MASK, ret); + } else if (channel >=3D PHY_MSE_CHANNEL_A && + channel <=3D PHY_MSE_CHANNEL_D) { + ret =3D phy_read_mmd(phydev, MDIO_MMD_PMAPMD, + KSZ9477_MMD_SIGNAL_QUALITY_CHAN_A + channel); + if (ret < 0) + return ret; + snapshot->average_mse =3D FIELD_GET(KSZ9477_MMD_SQI_MASK, ret); + } else { + return -EINVAL; + } + + return 0; +} + static void kszphy_enable_clk(struct phy_device *phydev) { struct kszphy_priv *priv =3D phydev->priv; @@ -6369,6 +6443,8 @@ static struct phy_driver ksphy_driver[] =3D { .cable_test_get_status =3D ksz9x31_cable_test_get_status, .get_sqi =3D kszphy_get_sqi, .get_sqi_max =3D kszphy_get_sqi_max, + .get_mse_config =3D kszphy_get_mse_config, + .get_mse_snapshot =3D kszphy_get_mse_snapshot, } }; =20 module_phy_driver(ksphy_driver); --=20 2.47.3