Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'r8169-add-support-for-rtl8127atf-10g-fiber-sfp'

Heiner Kallweit says:

====================
r8169: add support for RTL8127ATF (10G Fiber SFP)

RTL8127ATF supports a SFP+ port for fiber modules (10GBASE-SR/LR/ER/ZR and
DAC). The list of supported modes was provided by Realtek. According to the
r8127 vendor driver also 1G modules are supported, but this needs some more
complexity in the driver, and only 10G mode has been tested so far.
Therefore mainline support will be limited to 10G for now.
The SFP port signals are hidden in the chip IP and driven by firmware.
Therefore mainline SFP support can't be used here.
The PHY driver is used by the RTL8127ATF support in r8169.
RTL8127ATF reports the same PHY ID as the TP version. Therefore use a dummy
PHY ID.
====================

Link: https://patch.msgid.link/c2ad7819-85f5-4df8-8ecf-571dbee8931b@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+147 -4
+1
MAINTAINERS
··· 9417 9417 F: include/linux/phylib_stubs.h 9418 9418 F: include/linux/platform_data/mdio-bcm-unimac.h 9419 9419 F: include/linux/platform_data/mdio-gpio.h 9420 + F: include/net/phy/ 9420 9421 F: include/trace/events/mdio.h 9421 9422 F: include/uapi/linux/mdio.h 9422 9423 F: include/uapi/linux/mii.h
+85 -4
drivers/net/ethernet/realtek/r8169_main.c
··· 31 31 #include <linux/unaligned.h> 32 32 #include <net/ip6_checksum.h> 33 33 #include <net/netdev_queues.h> 34 + #include <net/phy/realtek_phy.h> 34 35 35 36 #include "r8169.h" 36 37 #include "r8169_firmware.h" ··· 734 733 unsigned supports_gmii:1; 735 734 unsigned aspm_manageable:1; 736 735 unsigned dash_enabled:1; 736 + bool sfp_mode:1; 737 737 dma_addr_t counters_phys_addr; 738 738 struct rtl8169_counters *counters; 739 739 struct rtl8169_tc_offsets tc_offset; ··· 1099 1097 if (rtl_ocp_reg_failure(reg)) 1100 1098 return 0; 1101 1099 1100 + /* Return dummy MII_PHYSID2 in SFP mode to match SFP PHY driver */ 1101 + if (tp->sfp_mode && reg == (OCP_STD_PHY_BASE + 2 * MII_PHYSID2)) 1102 + return PHY_ID_RTL_DUMMY_SFP & 0xffff; 1103 + 1102 1104 RTL_W32(tp, GPHY_OCP, reg << 15); 1103 1105 1104 1106 return rtl_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ? ··· 1158 1152 data = __r8168_mac_ocp_read(tp, reg); 1159 1153 __r8168_mac_ocp_write(tp, reg, (data & ~mask) | set); 1160 1154 raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags); 1155 + } 1156 + 1157 + static void r8127_sfp_sds_phy_reset(struct rtl8169_private *tp) 1158 + { 1159 + RTL_W8(tp, 0x2350, RTL_R8(tp, 0x2350) & ~BIT(0)); 1160 + udelay(1); 1161 + 1162 + RTL_W16(tp, 0x233a, 0x801f); 1163 + RTL_W8(tp, 0x2350, RTL_R8(tp, 0x2350) | BIT(0)); 1164 + usleep_range(10, 20); 1165 + } 1166 + 1167 + static void r8127_sfp_init_10g(struct rtl8169_private *tp) 1168 + { 1169 + int val; 1170 + 1171 + r8127_sfp_sds_phy_reset(tp); 1172 + 1173 + RTL_W16(tp, 0x233a, 0x801a); 1174 + RTL_W16(tp, 0x233e, (RTL_R16(tp, 0x233e) & ~0x3003) | 0x1000); 1175 + 1176 + r8168_phy_ocp_write(tp, 0xc40a, 0x0000); 1177 + r8168_phy_ocp_write(tp, 0xc466, 0x0003); 1178 + r8168_phy_ocp_write(tp, 0xc808, 0x0000); 1179 + r8168_phy_ocp_write(tp, 0xc80a, 0x0000); 1180 + 1181 + val = r8168_phy_ocp_read(tp, 0xc804); 1182 + r8168_phy_ocp_write(tp, 0xc804, (val & ~0x000f) | 0x000c); 1183 + } 1184 + 1185 + static void rtl_sfp_init(struct rtl8169_private *tp) 1186 + { 1187 + if (tp->mac_version == RTL_GIGA_MAC_VER_80) 1188 + r8127_sfp_init_10g(tp); 1189 + } 1190 + 1191 + static void rtl_sfp_reset(struct rtl8169_private *tp) 1192 + { 1193 + if (tp->mac_version == RTL_GIGA_MAC_VER_80) 1194 + r8127_sfp_sds_phy_reset(tp); 1161 1195 } 1162 1196 1163 1197 /* Work around a hw issue with RTL8168g PHY, the quirk disables ··· 2354 2308 le32_to_cpu(tp->counters->rx_unknown_opcode); 2355 2309 } 2356 2310 2311 + static int rtl8169_set_link_ksettings(struct net_device *ndev, 2312 + const struct ethtool_link_ksettings *cmd) 2313 + { 2314 + struct rtl8169_private *tp = netdev_priv(ndev); 2315 + struct phy_device *phydev = tp->phydev; 2316 + int duplex = cmd->base.duplex; 2317 + int speed = cmd->base.speed; 2318 + 2319 + if (!tp->sfp_mode) 2320 + return phy_ethtool_ksettings_set(phydev, cmd); 2321 + 2322 + if (cmd->base.autoneg != AUTONEG_DISABLE) 2323 + return -EINVAL; 2324 + 2325 + if (!phy_check_valid(speed, duplex, phydev->supported)) 2326 + return -EINVAL; 2327 + 2328 + mutex_lock(&phydev->lock); 2329 + 2330 + phydev->autoneg = AUTONEG_DISABLE; 2331 + phydev->speed = speed; 2332 + phydev->duplex = duplex; 2333 + 2334 + rtl_sfp_init(tp); 2335 + 2336 + mutex_unlock(&phydev->lock); 2337 + 2338 + return 0; 2339 + } 2340 + 2357 2341 static const struct ethtool_ops rtl8169_ethtool_ops = { 2358 2342 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 2359 2343 ETHTOOL_COALESCE_MAX_FRAMES, ··· 2403 2327 .get_eee = rtl8169_get_eee, 2404 2328 .set_eee = rtl8169_set_eee, 2405 2329 .get_link_ksettings = phy_ethtool_get_link_ksettings, 2406 - .set_link_ksettings = phy_ethtool_set_link_ksettings, 2330 + .set_link_ksettings = rtl8169_set_link_ksettings, 2407 2331 .get_ringparam = rtl8169_get_ringparam, 2408 2332 .get_pause_stats = rtl8169_get_pause_stats, 2409 2333 .get_pauseparam = rtl8169_get_pauseparam, ··· 2510 2434 tp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_GIGABYTE && 2511 2435 tp->pci_dev->subsystem_device == 0xe000) 2512 2436 phy_write_paged(tp->phydev, 0x0001, 0x10, 0xf01b); 2437 + 2438 + if (tp->sfp_mode) 2439 + rtl_sfp_init(tp); 2513 2440 2514 2441 /* We may have called phy_speed_down before */ 2515 2442 phy_speed_up(tp->phydev); ··· 4879 4800 4880 4801 phy_stop(tp->phydev); 4881 4802 4803 + /* Reset SerDes PHY to bring down fiber link */ 4804 + if (tp->sfp_mode) 4805 + rtl_sfp_reset(tp); 4806 + 4882 4807 rtl8169_update_counters(tp); 4883 4808 4884 4809 pci_clear_master(tp->pci_dev); ··· 5542 5459 } 5543 5460 tp->aspm_manageable = !rc; 5544 5461 5545 - /* Fiber mode on RTL8127AF isn't supported */ 5546 5462 if (rtl_is_8125(tp)) { 5547 5463 u16 data = r8168_mac_ocp_read(tp, 0xd006); 5548 5464 5549 5465 if ((data & 0xff) == 0x07) 5550 - return dev_err_probe(&pdev->dev, -ENODEV, 5551 - "Fiber mode not supported\n"); 5466 + tp->sfp_mode = true; 5552 5467 } 5553 5468 5554 5469 tp->dash_type = rtl_get_dash_type(tp);
+54
drivers/net/phy/realtek/realtek_main.c
··· 17 17 #include <linux/delay.h> 18 18 #include <linux/clk.h> 19 19 #include <linux/string_choices.h> 20 + #include <net/phy/realtek_phy.h> 20 21 21 22 #include "../phylib.h" 22 23 #include "realtek.h" ··· 2101 2100 return IRQ_HANDLED; 2102 2101 } 2103 2102 2103 + static int rtlgen_sfp_get_features(struct phy_device *phydev) 2104 + { 2105 + linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, 2106 + phydev->supported); 2107 + 2108 + /* set default mode */ 2109 + phydev->speed = SPEED_10000; 2110 + phydev->duplex = DUPLEX_FULL; 2111 + 2112 + phydev->port = PORT_FIBRE; 2113 + 2114 + return 0; 2115 + } 2116 + 2117 + static int rtlgen_sfp_read_status(struct phy_device *phydev) 2118 + { 2119 + int val, err; 2120 + 2121 + err = genphy_update_link(phydev); 2122 + if (err) 2123 + return err; 2124 + 2125 + if (!phydev->link) 2126 + return 0; 2127 + 2128 + val = rtlgen_read_vend2(phydev, RTL_VND2_PHYSR); 2129 + if (val < 0) 2130 + return val; 2131 + 2132 + rtlgen_decode_physr(phydev, val); 2133 + 2134 + return 0; 2135 + } 2136 + 2137 + static int rtlgen_sfp_config_aneg(struct phy_device *phydev) 2138 + { 2139 + return 0; 2140 + } 2141 + 2104 2142 static struct phy_driver realtek_drvs[] = { 2105 2143 { 2106 2144 PHY_ID_MATCH_EXACT(0x00008201), ··· 2395 2355 .get_features = rtl822x_get_features, 2396 2356 .config_aneg = rtl822x_config_aneg, 2397 2357 .read_status = rtl822x_read_status, 2358 + .suspend = genphy_suspend, 2359 + .resume = rtlgen_resume, 2360 + .read_page = rtl821x_read_page, 2361 + .write_page = rtl821x_write_page, 2362 + .read_mmd = rtl822x_read_mmd, 2363 + .write_mmd = rtl822x_write_mmd, 2364 + }, { 2365 + PHY_ID_MATCH_EXACT(PHY_ID_RTL_DUMMY_SFP), 2366 + .name = "Realtek SFP PHY Mode", 2367 + .flags = PHY_IS_INTERNAL, 2368 + .probe = rtl822x_probe, 2369 + .get_features = rtlgen_sfp_get_features, 2370 + .config_aneg = rtlgen_sfp_config_aneg, 2371 + .read_status = rtlgen_sfp_read_status, 2398 2372 .suspend = genphy_suspend, 2399 2373 .resume = rtlgen_resume, 2400 2374 .read_page = rtl821x_read_page,
+7
include/net/phy/realtek_phy.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _REALTEK_PHY_H 3 + #define _REALTEK_PHY_H 4 + 5 + #define PHY_ID_RTL_DUMMY_SFP 0x001ccbff 6 + 7 + #endif /* _REALTEK_PHY_H */