From: Javen <javen_xu@realsil.com.cn>
To: Heiner Kallweit <hkallweit1@gmail.com>,
"nic_swsd@realtek.com" <nic_swsd@realtek.com>,
"andrew+netdev@lunn.ch" <andrew+netdev@lunn.ch>,
"davem@davemloft.net" <davem@davemloft.net>,
"edumazet@google.com" <edumazet@google.com>,
"kuba@kernel.org" <kuba@kernel.org>,
"pabeni@redhat.com" <pabeni@redhat.com>,
"horms@kernel.org" <horms@kernel.org>
Cc: "netdev@vger.kernel.org" <netdev@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: RE: [PATCH net-next v1 2/4] r8169: add sfp mode for RTL8116af
Date: Tue, 17 Mar 2026 03:14:54 +0000 [thread overview]
Message-ID: <761cc11222bc4f4cb206629a76292c97@realsil.com.cn> (raw)
In-Reply-To: <fcb72518-24f7-4e16-8208-fb38441408d2@gmail.com>
>On 13.03.2026 08:25, Javen wrote:
>>> On 02.03.2026 07:32, javen wrote:
>>>> From: Javen Xu <javen_xu@realsil.com.cn>
>>>>
>>>> RTL8116af is a variation of RTL8168fp. It uses SerDes instead of PHY.
>>>> But SerDes status will not relect to PHY. So it needs to add sfp
>>>> mode for quirk to help reflect SerDes status during PHY read.
>>>>
>>>
>>> Is there any mass market device using this chip version? As far as
>>> possible I'd like to avoid adding support for chip versions that
>>> never make it to the mass market. This just makes driver maintenance
>harder.
>>>
>>> The patch includes support for 100Mbps fiber mode. Is there any use
>>> case for such legacy modes?
>>>
>>>
>>>> Signed-off-by: Javen Xu <javen_xu@realsil.com.cn>
>>>> ---
>>>> drivers/net/ethernet/realtek/r8169_main.c | 71
>>>> ++++++++++++++++++++---
>>>> 1 file changed, 62 insertions(+), 9 deletions(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/realtek/r8169_main.c
>>>> b/drivers/net/ethernet/realtek/r8169_main.c
>>>> index fb2247a20c36..a5c0d3995328 100644
>>>> --- a/drivers/net/ethernet/realtek/r8169_main.c
>>>> +++ b/drivers/net/ethernet/realtek/r8169_main.c
>>>> @@ -726,6 +726,12 @@ enum rtl_dash_type {
>>>> RTL_DASH_25_BP,
>>>> };
>>>>
>>>> +enum rtl_sfp_mode {
>>>> + RTL_SFP_NONE,
>>>> + RTL_SFP_8168_AF,
>>>> + RTL_SFP_8127_ATF,
>>>> +};
>>>> +
>>>> struct rtl8169_private {
>>>> void __iomem *mmio_addr; /* memory map physical address */
>>>> struct pci_dev *pci_dev;
>>>> @@ -734,6 +740,7 @@ struct rtl8169_private {
>>>> struct napi_struct napi;
>>>> enum mac_version mac_version;
>>>> enum rtl_dash_type dash_type;
>>>> + enum rtl_sfp_mode sfp_mode;
>>>> u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
>>>> u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
>>>> u32 dirty_tx;
>>>> @@ -760,7 +767,6 @@ struct rtl8169_private {
>>>> unsigned supports_gmii:1;
>>>> unsigned aspm_manageable:1;
>>>> unsigned dash_enabled:1;
>>>> - bool sfp_mode:1;
>>>> dma_addr_t counters_phys_addr;
>>>> struct rtl8169_counters *counters;
>>>> struct rtl8169_tc_offsets tc_offset; @@ -1126,7 +1132,7 @@
>>>> static int r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg)
>>>> return 0;
>>>>
>>>> /* Return dummy MII_PHYSID2 in SFP mode to match SFP PHY driver
>*/
>>>> - if (tp->sfp_mode && reg == (OCP_STD_PHY_BASE + 2 * MII_PHYSID2))
>>>> + if (tp->sfp_mode == RTL_SFP_8127_ATF && reg ==
>>> (OCP_STD_PHY_BASE
>>>> + + 2 * MII_PHYSID2))
>>>> return PHY_ID_RTL_DUMMY_SFP & 0xffff;
>>>>
>>>> RTL_W32(tp, GPHY_OCP, reg << 15); @@ -1270,6 +1276,34 @@
>>>> static int r8168g_mdio_read(struct rtl8169_private *tp, int reg)
>>>> return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2); }
>>>>
>>>> +/* The quirk reflects RTL8116af SerDes status. */ static int
>>>> +r8116af_mdio_read_quirk(struct rtl8169_private *tp, int reg) {
>>>> + u8 phyStatus = RTL_R8(tp, PHYstatus);
>>>> +
>>>> + if (!(phyStatus & LinkStatus))
>>>> + return 0;
>>>> +
>>>> + /* BMSR */
>>>> + if (tp->ocp_base == OCP_STD_PHY_BASE && reg == MII_BMSR)
>>>> + return BMSR_ANEGCOMPLETE | BMSR_LSTATUS;
>>>> +
>>>> + /* PHYSR */
>>>> + if (tp->ocp_base == 0xa430 && reg == 0x12) {
>>>> + if (phyStatus & _1000bpsF)
>>>> + return 0x0028;
>>>> + else if (phyStatus & _100bps)
>>>> + return 0x0018;
>>>
>>> This is a complete hack. Any means to access the SerDes directly?
>>
>> Hi, Heiner
>> Now we find a indirect access to serdes reg. The serdes reg is designed
>according to IEEE 802.3.
>> BIT 2 means Link Status and BIT 5 means ANEGCOMPLETE. We can access it
>> through read mac ocp 0xeb14, I wonder whether this indirect access can be
>accepted?
>>
>Based on the bit numbers this seems to be the BMSR register. Can all clause
>22 registers be accessed in a similar way so that a MII bus can be implemented
>for accessing the SerDes?
We checked our chip documentation and confirmed that the SerDes register file maps
all clause 22 registers(e.g. WR 0xeb10<reg_addr>, RD 0xeb14. reg_addr 0x40 is for BMCR,
0x41 for BMSR, 0x42 for PHYSID1, 0x43 for PHYSID2, etc.)
As you suggested, I wonder whether the proper approach is to implement a virtual mii_bus
and map the standard serdes reg in the new map.
Thanks,
Javen Xu
>In general it's hard to provide a statement w/o knowing the internal layout of
>the IP blocks.
>Can you provide any chip documentation / datasheet?
>For proper support of such a component chain between MAC and SFP port
>the driver would have to be converted to use phylink, what requires access to
>the involved components, incl. the SFP I2C bus.
>
>
>> Thanks,
>> Javen Xu
>>
>>>
>>>> + }
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static int r8116af_mdio_read(struct rtl8169_private *tp, int reg) {
>>>> + return r8168g_mdio_read(tp, reg) | r8116af_mdio_read_quirk(tp,
>>>> +reg); }
>>>> +
>>>> static void mac_mcu_write(struct rtl8169_private *tp, int reg, int
>>>> value) {
>>>> if (reg == 0x1f) {
>>>> @@ -1280,6 +1314,13 @@ static void mac_mcu_write(struct
>>>> rtl8169_private
>>> *tp, int reg, int value)
>>>> r8168_mac_ocp_write(tp, tp->ocp_base + reg, value); }
>>>>
>>>> +static bool rtl_is_8116af(struct rtl8169_private *tp) {
>>>> + return tp->mac_version == RTL_GIGA_MAC_VER_52 &&
>>>> + (r8168_mac_ocp_read(tp, 0xdc00) & 0x0078) == 0x0030 &&
>>>> + (r8168_mac_ocp_read(tp, 0xd006) & 0x00ff) == 0x0000; }
>>>> +
>>>> static int mac_mcu_read(struct rtl8169_private *tp, int reg) {
>>>> return r8168_mac_ocp_read(tp, tp->ocp_base + reg); @@ -1386,7
>>>> +1427,10 @@ static int rtl_readphy(struct rtl8169_private *tp, int
>>>> +location)
>>>> case RTL_GIGA_MAC_VER_31:
>>>> return r8168dp_2_mdio_read(tp, location);
>>>> case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST:
>>>> - return r8168g_mdio_read(tp, location);
>>>> + if (tp->sfp_mode == RTL_SFP_8168_AF)
>>>> + return r8116af_mdio_read(tp, location);
>>>> + else
>>>> + return r8168g_mdio_read(tp, location);
>>>> default:
>>>> return r8169_mdio_read(tp, location);
>>>> }
>>>> @@ -1575,6 +1619,20 @@ static bool rtl_dash_is_enabled(struct
>>> rtl8169_private *tp)
>>>> }
>>>> }
>>>>
>>>> +static enum rtl_sfp_mode rtl_get_sfp_mode(struct rtl8169_private
>>>> +*tp) {
>>>> + if (rtl_is_8125(tp)) {
>>>> + u16 data = r8168_mac_ocp_read(tp, 0xd006);
>>>> +
>>>> + if ((data & 0xff) == 0x07)
>>>> + return RTL_SFP_8127_ATF;
>>>> + } else if (rtl_is_8116af(tp)) {
>>>> + return RTL_SFP_8168_AF;
>>>> + }
>>>> +
>>>> + return RTL_SFP_NONE;
>>>> +}
>>>> +
>>>> static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private
>>>> *tp) {
>>>> switch (tp->mac_version) {
>>>> @@ -5693,12 +5751,7 @@ static int rtl_init_one(struct pci_dev *pdev,
>>>> const
>>> struct pci_device_id *ent)
>>>> }
>>>> tp->aspm_manageable = !rc;
>>>>
>>>> - if (rtl_is_8125(tp)) {
>>>> - u16 data = r8168_mac_ocp_read(tp, 0xd006);
>>>> -
>>>> - if ((data & 0xff) == 0x07)
>>>> - tp->sfp_mode = true;
>>>> - }
>>>> + tp->sfp_mode = rtl_get_sfp_mode(tp);
>>>>
>>>> tp->dash_type = rtl_get_dash_type(tp);
>>>> tp->dash_enabled = rtl_dash_is_enabled(tp);
>>
next prev parent reply other threads:[~2026-03-17 3:15 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-02 6:32 [PATCH net-next v1 0/4] r8169: add ltr and c10 support for RTL8116af javen
2026-03-02 6:32 ` [PATCH net-next v1 1/4] r8169: add ltr " javen
2026-03-02 6:32 ` [PATCH net-next v1 2/4] r8169: add sfp mode " javen
2026-03-02 22:07 ` Heiner Kallweit
2026-03-04 8:16 ` 许俊伟
2026-03-04 21:42 ` Heiner Kallweit
2026-03-13 7:25 ` Javen
2026-03-13 21:21 ` Heiner Kallweit
2026-03-17 3:14 ` Javen [this message]
2026-03-18 21:45 ` Heiner Kallweit
2026-03-19 17:09 ` Andrew Lunn
2026-03-02 6:32 ` [PATCH net-next v1 3/4] r8169: move DECLARE_RTL_COND() javen
2026-03-02 6:32 ` [PATCH net-next v1 4/4] r8169: enable system enter c10 with RTL8116af javen
2026-03-02 21:53 ` Heiner Kallweit
2026-03-04 9:43 ` 许俊伟
2026-03-04 21:51 ` Heiner Kallweit
2026-03-05 10:58 ` Javen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=761cc11222bc4f4cb206629a76292c97@realsil.com.cn \
--to=javen_xu@realsil.com.cn \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hkallweit1@gmail.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=nic_swsd@realtek.com \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox