From nobody Tue Dec 2 01:51:17 2025 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (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 4E3081A316E for ; Thu, 20 Nov 2025 19:51:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763668264; cv=none; b=fRIXg4lhIER7w3JGmEpZV7nd/GdfgeBptJiLdbh4Y0wPSIHb2Y9/vVNYm/zONwvh9903WYyB5hZRqtdILbKYfeiLLN4w0y9SC6gfauZkVwTAM7wxUquZcwc+gYXsGErfpRZduRO0Fsz1B5yi60BIi66nSNASKSSqz3xfFoYyf74= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763668264; c=relaxed/simple; bh=AC3XIuUJXRJWedH3cQ7AriKmum/CB3i3Hw86x/suSDo=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=j2AcJIdlQX/7FuinV2BtWWnEeHK6fISMJZhmlcJgvoKMunCyRMhSCVqiC7OoF7OjB1i191NiWajz1jiXgvfI1rpQyYFdq/VoIxHtibiPMYHiU5yiB6lCQpFkSBd3ra+hj7funSE2AZxeUVNhGiKlv0OvrrbtVh/r/Zu3zgL7Adk= 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=ko6uKONu; arc=none smtp.client-ip=209.85.128.43 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="ko6uKONu" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-47795f6f5c0so8980675e9.1 for ; Thu, 20 Nov 2025 11:51:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763668261; x=1764273061; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=kppobf+HfqrnKfgCmTsw8ifBKt7BpqlOrevM3P0J6K8=; b=ko6uKONub60tYodmmkaH0Wb/cxYILfufXUXeBacK7QCrM2Wi9HsVSX476i9GVsWW/L XgnpE8jjvWAN2MYPxhsi0/7RXla85GbOmNn9UkoP7EA+IpALyrKRsFWpN8mWuZR9mYaV 4bElan2WGUrbFgZYtWNV9Qu+yyjNSjyACD0L3HT6p4Z1Myyd/BxZRBzDKJe3fdazw1+8 0B+uAq6KA6wxFz5XkY6lmp2ASSmqY7K9lKpyrgKEE4nlM55+K1VxGNOaKbwkQe/PPb8K 9DsVioQUBF1VtulcLKUskDyAytucFNpUnpBvSpcrgdo47Qp/RVxwX8KShrRKwupWasJU qS3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763668261; x=1764273061; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=kppobf+HfqrnKfgCmTsw8ifBKt7BpqlOrevM3P0J6K8=; b=CLA3MDaeL1g9h9LyKbov+VfeJlMrTpnSN0eB6tZde2oZnXqpisprGeoc1bF4JAkang 98JAlKiM/Crv5bZWa6xXl0iSdXYBxncIjLYXBwPraG60YNtGMWP762xK6/qLee3ouIiT eZ+MkIPHThMA+nHnviyq5vaoSeIhYpF4uN9mO28+4OlU0qdGNTH131/59hMdSBrqvMSn /SQJEqkMQVZZZWjE5oCkCpd8vysm6VRpje5GL740+GTnD3IIR+2QLSYoXdWdCiQh6p85 bP/x3c224dyn+9LBm+jJnvqpiP9mbxr1ZJS1nboZYr0PpZSwiaEYFJC3r7gftD+wZzeK W5pw== X-Forwarded-Encrypted: i=1; AJvYcCWggWsFjilSAVrwl6m7yyExK7uHz9JENiuO0IagYx1zqiZedotqfGJurP01+A6N+HpsW0haPb+OEnnNEo4=@vger.kernel.org X-Gm-Message-State: AOJu0YxrkO5hROEjLylX7R7ltXL2psOIVsrjRK8ec2Dt9zvJKVYanc/1 Qnky8uHs515ulpKMVUdGqoJz4iafo2bvm19RzlhR71DiBgUX1XnAWeBEyu1BtnZdrLI= X-Gm-Gg: ASbGncv2mMm9DG7LorFYVjFUTjxGCzcmF+dPYl9LvrHVkYmn6j5wwaw/ldWiv0RIOe4 aU+jQRfVupjE6soo3OqHwcwjfroO7B36kbuSLcGduYSrM4JMJpxg4JjFxHkKqzGtSYFX72w4Swh HKgWheeBhlpfPIN9/weMPaH2LpelhrNA8I99x7CCKAHGGtn656ml3ZQzJ7X/8X2JkIAfFzJIjL4 StMP9mloYFvEkUSjQVNcmIhZGwEIWBY6lIJyDu3m7fdZ4gwEhPsQsnaFoni41SaUZgC7ToUsTw4 Tc/BCVAssZ/dA8DwAx+JQftMlm8cULAgc4CIJq6gxE4tb47qjM2/d4Uy1+rLmNB2QeTukDeYLVR XYrj5HabMFzwg+FoviNmGVz/mH28N2PjZPRU96iBDyaa5xQcrn4tPvTYz3qmosyL4sp5mfz/i4a noWL07AI9JYISQsbkelE5bI9XyYsta0g== X-Google-Smtp-Source: AGHT+IENBLk0dQNZRsMkCQ2uReAjBiprjlbsAn/Xo5XqqTbFie50c0omTcUmw7Kww3d4abSbhugR4Q== X-Received: by 2002:a05:600c:458e:b0:46e:396b:f5ae with SMTP id 5b1f17b1804b1-477bac0cfb5mr40650755e9.16.1763668260113; Thu, 20 Nov 2025 11:51:00 -0800 (PST) Received: from localhost.localdomain ([37.228.206.31]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-477a9739964sm73324225e9.1.2025.11.20.11.50.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Nov 2025 11:50:59 -0800 (PST) From: Fabio Baltieri To: Heiner Kallweit , nic_swsd@realtek.com, Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Michael Zimmermann , Paolo Abeni Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Fabio Baltieri Subject: [PATCH v2] r8169: add support for RTL8127ATF Date: Thu, 20 Nov 2025 19:50:55 +0000 Message-ID: <20251120195055.3127-1-fabio.baltieri@gmail.com> X-Mailer: git-send-email 2.47.3 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 Content-Type: text/plain; charset="utf-8" Add support for ATF variant of the RTL8127, this uses an SFP transceiver instead of the twisted pair one and only runs at 1Gbps or 10Gbps, only 10Gbps is supported with this patch. The change is based on the r8127 driver package version 11.015.00 available on the Realtek website and also on https://github.com/openwrt/rtl8127. There's no public datasheet for the chip so this is just porting over the original vendor code to the API and style of the upstream one. Signed-off-by: Fabio Baltieri --- Hi, did more tests with 1g mode on the v1 of this patch, the setting itself works but triggering it from ethtool reliably seems problematic due to some weird behavior of the phy code which end up reporting a specific link speed when the link is down, making it impossible to set it with ethool as it thinks it's already set. Since it seems like supporting 1g properly needs expanding the scope of the patch, I'm taking the suggestion from Heiner in v1 review and stripped this down so it only supports 10g, which is likely what the vast majority of the users need anyway. Also tested this on suspend/resume, this is also affected by the wol issue but with that bit set it now works correctly. v1 -> v2 - stripped out 1g support - moved the sds settings in rtl8169_init_phy() so it get called on resume - renamed fiber_mode to sfp_mode to avoid confusion Cheers, Fabio drivers/net/ethernet/realtek/r8169_main.c | 128 +++++++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethern= et/realtek/r8169_main.c index d18734fe12e..e19518c7b98 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -729,6 +729,7 @@ struct rtl8169_private { unsigned supports_gmii:1; unsigned aspm_manageable:1; unsigned dash_enabled:1; + unsigned sfp_mode:1; dma_addr_t counters_phys_addr; struct rtl8169_counters *counters; struct rtl8169_tc_offsets tc_offset; @@ -842,7 +843,8 @@ static bool rtl_supports_eee(struct rtl8169_private *tp) { return tp->mac_version >=3D RTL_GIGA_MAC_VER_34 && tp->mac_version !=3D RTL_GIGA_MAC_VER_37 && - tp->mac_version !=3D RTL_GIGA_MAC_VER_39; + tp->mac_version !=3D RTL_GIGA_MAC_VER_39 && + !tp->sfp_mode; } =20 static void rtl_read_mac_from_reg(struct rtl8169_private *tp, u8 *mac, int= reg) @@ -1399,6 +1401,95 @@ DECLARE_RTL_COND(rtl_ocp_tx_cond) return RTL_R8(tp, IBISR0) & 0x20; } =20 +#define R8127_SDS_CMD 0x2348 +#define R8127_SDS_ADDR 0x234a +#define R8127_SDS_DATA_IN 0x234c +#define R8127_SDS_DATA_OUT 0x234e + +#define R8127_MAKE_SDS_ADDR(_index, _page, _reg) \ + (((_index) << 11) | ((_page) << 5) | (_reg)) + +#define R8127_SDS_CMD_IN BIT(0) +#define R8127_SDS_WE_IN BIT(1) + +DECLARE_RTL_COND(rtl_sds_cmd_done) +{ + return RTL_R16(tp, R8127_SDS_CMD) & R8127_SDS_CMD_IN; +} + +static u16 rtl8127_sds_phy_read(struct rtl8169_private *tp, + u16 index, u16 page, u16 reg) +{ + RTL_W16(tp, R8127_SDS_ADDR, R8127_MAKE_SDS_ADDR(index, page, reg)); + RTL_W16(tp, R8127_SDS_CMD, R8127_SDS_CMD_IN); + + if (rtl_loop_wait_low(tp, &rtl_sds_cmd_done, 1, 100)) + return RTL_R16(tp, R8127_SDS_DATA_OUT); + else + return 0xffff; +} + +static void rtl8127_sds_phy_write(struct rtl8169_private *tp, + u16 index, u16 page, u16 reg, u16 val) +{ + RTL_W16(tp, R8127_SDS_DATA_IN, val); + RTL_W16(tp, R8127_SDS_ADDR, R8127_MAKE_SDS_ADDR(index, page, reg)); + RTL_W16(tp, R8127_SDS_CMD, R8127_SDS_CMD_IN | R8127_SDS_WE_IN); + + rtl_loop_wait_low(tp, &rtl_sds_cmd_done, 1, 100); +} + +static void rtl8127_sds_phy_modify(struct rtl8169_private *tp, + u16 index, u16 page, u16 addr, + u16 mask, u16 set) +{ + u16 val; + + val =3D rtl8127_sds_phy_read(tp, index, page, addr); + val =3D (val & ~mask) | set; + rtl8127_sds_phy_write(tp, index, page, addr, val); +} + +static void rtl8127_sds_phy_reset(struct rtl8169_private *tp) +{ + RTL_W8(tp, 0x2350, RTL_R8(tp, 0x2350) & ~BIT(0)); + udelay(1); + + RTL_W16(tp, 0x233a, 0x801f); + RTL_W8(tp, 0x2350, RTL_R8(tp, 0x2350) | BIT(0)); + udelay(10); +} + +static void rtl8127_sds_phy_exit_1g(struct rtl8169_private *tp) +{ + rtl8127_sds_phy_modify(tp, 0, 1, 31, BIT(3), 0); + rtl8127_sds_phy_modify(tp, 0, 2, 0, + BIT(13) | BIT(12) | BIT(6), + BIT(6)); + + rtl8127_sds_phy_reset(tp); +} + +static void rtl8127_set_sds_phy_caps_10g(struct rtl8169_private *tp) +{ + u16 val; + + RTL_W16(tp, 0x233a, 0x801a); + + val =3D RTL_R16(tp, 0x233e); + val &=3D BIT(13) | BIT(12) | BIT(1) | BIT(0); + val |=3D BIT(12); + RTL_W16(tp, 0x233e, val); + + r8169_mdio_write(tp, 0xc40a, 0x0); + r8169_mdio_write(tp, 0xc466, 0x3); + r8169_mdio_write(tp, 0xc808, 0x0); + r8169_mdio_write(tp, 0xc80a, 0x0); + + val =3D r8168_phy_ocp_read(tp, 0xc804); + r8168_phy_ocp_write(tp, 0xc804, (val & ~0x000f) | 0x000c); +} + static void rtl8168ep_stop_cmac(struct rtl8169_private *tp) { RTL_W8(tp, IBCR2, RTL_R8(tp, IBCR2) & ~0x01); @@ -1512,6 +1603,15 @@ static enum rtl_dash_type rtl_get_dash_type(struct r= tl8169_private *tp) } } =20 +static bool rtl_sfp_mode(struct rtl8169_private *tp) +{ + if (tp->mac_version =3D=3D RTL_GIGA_MAC_VER_80 && + (r8168_mac_ocp_read(tp, 0xd006) & 0xff) =3D=3D 0x07) + return true; + + return false; +} + static void rtl_set_d3_pll_down(struct rtl8169_private *tp, bool enable) { if (tp->mac_version >=3D RTL_GIGA_MAC_VER_25 && @@ -2390,7 +2490,10 @@ static void rtl8125a_config_eee_mac(struct rtl8169_p= rivate *tp) =20 static void rtl8125b_config_eee_mac(struct rtl8169_private *tp) { - r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0)); + if (tp->sfp_mode) + r8168_mac_ocp_modify(tp, 0xe040, BIT(1) | BIT(0), 0); + else + r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0)); } =20 static void rtl_rar_exgmac_set(struct rtl8169_private *tp, const u8 *addr) @@ -2440,6 +2543,25 @@ static void rtl8169_init_phy(struct rtl8169_private = *tp) tp->pci_dev->subsystem_device =3D=3D 0xe000) phy_write_paged(tp->phydev, 0x0001, 0x10, 0xf01b); =20 + if (tp->sfp_mode) { + rtl8127_sds_phy_exit_1g(tp); + rtl8127_set_sds_phy_caps_10g(tp); + + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT); + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_1000baseT_Full_BIT); + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_2500baseT_Full_BIT); + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_5000baseT_Full_BIT); + + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_Autoneg_BIT); + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_Pause_BIT); + phy_remove_link_mode(tp->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); + + tp->phydev->autoneg =3D 0; + } + /* We may have called phy_speed_down before */ phy_speed_up(tp->phydev); =20 @@ -5453,6 +5575,8 @@ static int rtl_init_one(struct pci_dev *pdev, const s= truct pci_device_id *ent) tp->dash_type =3D rtl_get_dash_type(tp); tp->dash_enabled =3D rtl_dash_is_enabled(tp); =20 + tp->sfp_mode =3D rtl_sfp_mode(tp); + tp->cp_cmd =3D RTL_R16(tp, CPlusCmd) & CPCMD_MASK; =20 if (sizeof(dma_addr_t) > 4 && tp->mac_version >=3D RTL_GIGA_MAC_VER_18 && --=20 2.47.3