Re: [PATCH net-next v4 13/16] onsemi: s2500: Add driver support for TS2500 MAC-PHY
From: Randy Dunlap
Date: Sun Jun 07 2026 - 01:56:28 EST
On 6/5/26 10:42 PM, Selvamani Rajagopal via B4 Relay wrote:
> From: Selvamani Rajagopal <Selvamani.Rajagopal@xxxxxxxxxx>
>
> Support for onsemi's S2500, 802.3 cg compliant Ethernet
> transceiver with integrated MAC-PHY. Works with
> Open Alliance TC6 framework.
>
> adjtime callback is implemented using adjfine. If time
> delta is too big, bigger than 1 second, using adjtime
> would take long to reduce the delta. In those cases,
> settime callback is used to reduce the delta. Once delta
> becomes less than a second, it uses adjfine to reduce
> the drift further.
>
> Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@xxxxxxxxxx>
> ---
> MAINTAINERS | 7 +
> drivers/net/ethernet/oa_tc6/oa_tc6_std_def.h | 2 +-
> drivers/net/ethernet/onsemi/Kconfig | 21 +
> drivers/net/ethernet/onsemi/Makefile | 7 +
> drivers/net/ethernet/onsemi/s2500/Kconfig | 21 +
> drivers/net/ethernet/onsemi/s2500/Makefile | 7 +
> drivers/net/ethernet/onsemi/s2500/s2500_ethtool.c | 347 ++++++++++++
> drivers/net/ethernet/onsemi/s2500/s2500_hw_def.h | 225 ++++++++
> drivers/net/ethernet/onsemi/s2500/s2500_main.c | 632 ++++++++++++++++++++++
> drivers/net/ethernet/onsemi/s2500/s2500_ptp.c | 233 ++++++++
> 10 files changed, 1501 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/onsemi/Kconfig b/drivers/net/ethernet/onsemi/Kconfig
> new file mode 100644
> index 000000000000..8dd3a3f074a2
> --- /dev/null
> +++ b/drivers/net/ethernet/onsemi/Kconfig
> @@ -0,0 +1,21 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# onsemi network device configuration
> +#
> +
> +config NET_VENDOR_ONSEMI
> + bool "onsemi network devices"
> + help
> + If you have a network card belonging to this class, say Y.
> +
> + Note that the answer to this question doesn't directly affect the
> + kernel: saying N will just cause the configurator to skip all
> + the questions about onsemi ethernet devices. If you say Y, you
> + will be asked for your specific card in the following questions.
Above line should be indented with one tab + spaces.
> +
> +if NET_VENDOR_ONSEMI
> +
> +source "drivers/net/ethernet/onsemi/s2500/Kconfig"
> +
> +endif # NET_VENDOR_ONSEMI
> +
> diff --git a/drivers/net/ethernet/onsemi/s2500/Kconfig b/drivers/net/ethernet/onsemi/s2500/Kconfig
> new file mode 100644
> index 000000000000..22b0afad7a21
> --- /dev/null
> +++ b/drivers/net/ethernet/onsemi/s2500/Kconfig
> @@ -0,0 +1,21 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# onsemi S2500 Driver Support
> +#
> +
> +if NET_VENDOR_ONSEMI
> +
> +config S2500_MACPHY
> + help
> + tristate "S2500 support"
> + depends on SPI
> + select NCN26000_PHY
> + select OA_TC6
> + Support for the onsemi TS2500 MACPHY Ethernet chip.
> + It works under the framework that conform to OPEN Alliance
> + 10BASE-T1x Serial Interface specification.
> +
> + To compile this driver as a module, choose M here. The module will be
> + called s2500.
Kconfig help text should be indented with one tab + 2 spaces (applies to
all lines following the "Support for the ..." line).
> +
> +endif # NET_VENDOR_ONSEMI
> diff --git a/drivers/net/ethernet/onsemi/s2500/s2500_ptp.c b/drivers/net/ethernet/onsemi/s2500/s2500_ptp.c
> new file mode 100644
> index 000000000000..fd6617c7ac79
> --- /dev/null
> +++ b/drivers/net/ethernet/onsemi/s2500/s2500_ptp.c
> +static int s2500_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
> +{
> + struct s2500_info *priv = container_of(ptp, struct s2500_info,
> + ptp_clock_info);
> + u32 sign_bit = 0;
> + long adj;
> + u32 val;
> + u64 ppm;
> +
> + if (scaled_ppm < 0) {
> + /* split sign / mod */
> + sign_bit = 1U << 31;
> + scaled_ppm = ~scaled_ppm + 1;
> + }
> +
> + /**
Use /*
since this is not a kernel-doc comment.
> + * Convert unsigned scaled_ppm to atto-seconds per clock cycles.
> + * The scaled_ppm format is Qx.16 --> 1 lsb = 1/65536 ppm.
> + * The clock period of the S2500 is 8ns (125 MHz), so 1 lsb of
> + * adj register LSB is 1 atto-sec / 8ns = 0.000125 ppm.
> + * Represented in Qx.16 format, this is 0.000125 * 2^16 = 8(.192)
> + * To convert scaled_ppm into a register value we need to divide
> + * it by the LSB value, hence adj = (scaled_ppm * 1000) / 8192 to
> + * minimize the precision loss due to the integer arithmetic.
> + * That further reduces to (scaled_ppm * 125) / 1024.
> + */
> + ppm = (u64)scaled_ppm * 125;
> + do_div(ppm, 1024);
> + adj = (long)ppm;
> +
> + /* check overflow */
> + if (adj >= (1L << 28))
> + return -ERANGE;
> +
> + val = (u32)adj | sign_bit;
> + return oa_tc6_write_register_mms(priv->tc6, S2500_REG_VS_PTP_ADJ,
> + OA_TC6_PHY_C45_VS_MMS12, val);
> +}
--
~Randy