diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-22 15:58:00 -1000 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-22 15:58:00 -1000 |
| commit | 734bef548a96e8774d6eef5dfa2026c6edc4e80b (patch) | |
| tree | ce2520b2602ce3b82f9842490d21836f9838d441 /drivers/net/phy/realtek | |
| parent | 864c07de0c7dcbca58b61625dfa2e461ae63b242 (diff) | |
| parent | 1a2c35c49cc7c6be860038b8442b52424a8f123c (diff) | |
| download | linux-next-stable.tar.gz linux-next-stable.zip | |
Merge tag 'net-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-nextstable
Pull networking updates from Paolo Abeni:
"This includes a significant number of low-priority fixes - especially
in the NIC drivers area - that we deferred from the last few RCs in
the previous cycle, which can't be easily outlined in the synopsis
below.
Core & protocols:
- Continue the work on removing rtnl_lock dependencies:
- per-netns ARP and ND neighbour tables, with the default settings
now configurable per netns (inheritance from init_net is
controlled by the new net.core.neigh_inherit_init_net sysctl)
- RCU-protected configuration and rtnl_lock-less fill_info() for
hsr, netkit, sit, vlan and vxlan devices
- per-netns device unregistration for ip tunnel and gre devices
- use the netdev instance lock instead of rtnl_lock when reading
speed and duplex via sysfs
- batch the flushing of uncached routes at device unregistration
time, relieving rtnl_lock contention on netns dismantle.
- Add hardware pacing offload support, admin-controlled via a new
rtnetlink attribute, with sch_fq integration (implemented in idpf).
- Re-segment BIG TCP GSO packets into GSO packets fitting the egress
device limits instead of plain MSS-sized segments, improving
throughput for mixed BIG TCP / non-BIG TCP paths by up to 70%.
- Generate RSS keys that spread flows over all the RX queues; the
previous random keys could leave some queues unused.
- Optimize the bridge VLAN forwarding paths: cache the port-VLAN in
fdb entries and consider only VLAN members when flooding, for ~10%
more Mpps in the fdb forwarding path.
- A few TCP/IP performance improvements aimed at efficient cache
usage and reducing contention.
- Add the TCP ROCCET congestion control, a CUBIC variant aimed at
avoiding bufferbloat in cellular networks.
- Continue the conversion of getsockopt callbacks to sockopt_t.
- Add an ethtool command to list the front-facing ports of an
interface, including SFP cages and modules, using the phy_port
representation.
- Enable BIG TCP support for bareudp tunnels.
- Remove the IPV6_ADDRFORM socket option and disallow buggy TCP state
transitions (listen() + shutdown() + connect() and connect() +
connect(AF_UNSPEC) + listen()).
- Remove most BUG_ON()s from core packet processing, replacing them
with error paths.
Wireless:
- Latency improvements, including lockless station get/dump and
beacon updates, plus RTNL reduction and locking cleanups.
- Infrastructure for non-station TX/RX with MLO.
- NAN (Wi-Fi Aware) Instant Communication support and other NAN
improvements.
- Control frame Integrity Protocol (CIP) and protected TWT support.
- Improvements for AP regulatory checks.
Netfilter:
- Disable br_netfilter in user namespaces and schedule it for removal
in 2027.
- Restrict the raw table in nft_compat to the specific family, hook
and priority.
- Prepare the flowtable for mixed IPv4-over-IPv6 tunneling (and vice
versa).
- Use GFP_KERNEL_ACCOUNT for most netfilter allocations, for better
integration with memcg.
- Allow discovering conntrack zone filtering support in ctnetlink
dumps, and fix nfnetlink_hook handling of large dumps.
Deletions:
- Move the LLC type 2 sockets out of tree. There are no known users
and the code attracts a never-ending stream of LLM-driven fixes.
Device drivers:
- New drivers:
- Meta Platforms NIC (mpnic), the second-generation NIC from Meta
- initial skeleton of the Nebula-matrix NICs driver (nbl)
- X-Powers AC200/AC300 Fast Ethernet PHYs
- Ethernet high-speed NICs:
- Intel:
- i40e: XDP metadata support for RX hash and VLAN tag
- ice: expose the E825 TSPLL state via the DPLL subsystem
- nVidia/Mellanox:
- move the data direct infrastructure from IB to core, in
preparation for netdev support.
- reduce the memory used per offloaded TC rule
- Meta (fbnic):
- support large io_uring zero-copy RX buffers
- Microsoft vNIC (mana):
- add BQL support
- Ethernet NICs consumer, and embedded:
- Airoha:
- LRO offload support
- Cadence (macb):
- context swapping for ringparam and MTU changes, avoiding
buffer loss under memory pressure
- Mucse (rnpgbe):
- TX/RX and link status support
- NXP (enetc):
- SR-IOV improvements and VF support for ENETC v4
- Qualcomm (ppe):
- IPQ5424 support
- Realtek PCI (r8169):
- phylink support
- RSS support for RTL8127
- Renesas (ravb):
- gPTP support for R-Car Gen4
- Synopsys (stmmac):
- XDP multi-buffer support on the TX side
- tc mqprio hw queue priority offload
- support for RK3568 SGMII, Allwinner H616 EMAC1, UltraRISC
DP1000 and Qualcomm sa8255p
- Ethernet switches:
- Mediatek (mt7530):
- fast age and change conduit support
- Microchip (ksz):
- support for KSZ8995XA/KS8995XA
- Microchip (lan966x):
- PCIe FDMA support, ~20x throughput increase in PCIe endpoint
- Microchip (sparx5):
- Time Aware Shaper (taprio) offload
- Motorcomm (yt921x):
- LED and SerDes PCS support
- Realtek (rtl8365mb):
- EEE support
- Ethernet PHYs:
- Broadcom:
- enable jumbo frames on BCM54xx
- Realtek:
- support for RTL8261CE_CG and RTL8261D_VM
- MDIO support for RTL838x and RTL839x
- WiFi drivers:
- Broadcom (brcmfmac):
- FT/OKC roaming offload
- Intel (iwlwifi):
- UHR sniffer support
- support for newer UEFI/BIOS tables
- MediaTek (mt76):
- mt7925 NAN improvements
- offchannel/scan improvements and MLO fixes
- Morse Micro (mm81x):
- monitor mode support
- Qualcomm (ath12k):
- IPQ5332 platform infrastructure
- Realtek (rtw88):
- RTL8723BS support
- SDIO TX performance improvements
- Realtek (rtw89):
- P2P_DEVICE support
- BT-coex updates for RTL8922D
- Bluetooth:
- move H:4 reassembly into the Bluetooth core
- add generic support for vendor packets
- MGMT: add security level changed event
- Bluetooth drivers:
- btusb: support Bulk Serialization Mode
- Intel: support Draco and Titan Lake, allow unsigned firmware
- Mediatek: MT7928 support
- Qualcomm: QCC2072 support
- Broadcom: Synaptics 4384 support"
* tag 'net-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2126 commits)
Bluetooth: btusb: disable by default Qualcomm multi-subsystem
tipc: fix broadcast sender hang on last acker departure
tipc: fix use-after-free of broadcast reception link at node release
r8169: clear TX LPI on RTL8168h at link up after phylink conversion
tun: Require CAP_NET_ADMIN to attach to an ownerless device
net/sched/sch_cake: drop dead nla_nest_end() error check
net/sched/sch_cake: widen buffer_used to u64
net/sched/sch_cake: reduce parent backlog when clearing a tin
net/sched/sch_cake: serialize reconfiguration with the datapath
tg3: Add Datto SIRIS 5 1U Server to restart AER quirk table
net/mlx5e: Stop asserting for RTNL when closing channels
net: shrink the payload-only part of skb dataref to one bit
net: wwan: iosm: validate msg_head before indexing msg_ring
net: bgmac: rate limit RX error messages
selftests: net: veth: test XDP_TX to a peer with GRO enabled
veth: schedule the peer's NAPI after XDP_TX when only GRO is enabled
pppoe: delete session hash entries by pointer match
net: lan969x: don't disable hardirqs in fdma tx clear
net: sparx5/lan969x: do not clobber the PSFP cycle timer update period
net: lan969x: fix DSM calendar for empty taxis
...
Diffstat (limited to 'drivers/net/phy/realtek')
| -rw-r--r-- | drivers/net/phy/realtek/realtek_main.c | 213 |
1 files changed, 160 insertions, 53 deletions
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c index 177b62a7b2d1..4927ee838de2 100644 --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c @@ -19,7 +19,6 @@ #include <linux/delay.h> #include <linux/clk.h> #include <linux/string_choices.h> -#include <net/phy/realtek_phy.h> #include "../phylib.h" #include "realtek.h" @@ -240,6 +239,16 @@ #define RTL_PHYSR_MASTER BIT(11) #define RTL_PHYSR_SPEED_MASK (RTL_PHYSR_SPEEDL | RTL_PHYSR_SPEEDH) +/* MDI-X control and status of the RTL8365MB-VC internal PHY. The resolved + * MDI-X state is reported in RTL_PHYSR; the configuration lives in a + * chip-specific control register. Both are only known to apply to this model. + * On this chip a set select/resolved bit means MDI, not MDI-X (measured). + */ +#define RTL8365MB_VC_PHYCR1 0x18 +#define RTL8365MB_VC_PHYCR1_MDIX_FORCE BIT(9) +#define RTL8365MB_VC_PHYCR1_MDI BIT(8) +#define RTL8365MB_VC_PHYSR_MDI BIT(1) + #define RTL_MDIO_PCS_EEE_ABLE 0xa5c4 #define RTL_MDIO_AN_EEE_ADV 0xa5d0 #define RTL_MDIO_AN_EEE_LPABLE 0xa5d2 @@ -258,6 +267,8 @@ #define RTL_8251B 0x001cc862 #define RTL_8261C 0x001cc890 #define RTL_8261C_CG 0x001cc898 +#define RTL_8261CE_CG 0x001cc899 +#define RTL_8261D_VM 0x001cc89a #define RTL8261C_CE_MODEL 0x00 #define RTL8261D_MODEL 0x81 @@ -286,11 +297,15 @@ #define FW_MAIN_MAGIC 0x52544C38 #define FW_SUB_MAGIC_8261C 0x32363143 +#define FW_SUB_MAGIC_8261D 0x32363144 #define RTL8261X_POLL_TIMEOUT_MS 100 #define RTL8261X_MAX_MMD_DEV 31 #define RTL8261C_CE_FW_NAME "rtl_nic/rtl8261c.bin" +#define RTL8261D_FW_NAME "rtl_nic/rtl8261d.bin" + MODULE_FIRMWARE(RTL8261C_CE_FW_NAME); +MODULE_FIRMWARE(RTL8261D_FW_NAME); enum rtl8261x_fw_op { OP_WRITE = 0x00, /* Write */ @@ -342,6 +357,7 @@ struct rtl821x_priv { struct rtl8261x_priv { const char *fw_name; + u32 fw_sub_magic; bool fw_loaded; }; @@ -411,10 +427,13 @@ static int rtl8261x_probe(struct phy_device *phydev) switch (sub_phy_id) { case RTL8261C_CE_MODEL: priv->fw_name = RTL8261C_CE_FW_NAME; + priv->fw_sub_magic = FW_SUB_MAGIC_8261C; phydev_info(phydev, "RTL8261C detected (sub_id 0x%02x)\n", sub_phy_id); break; case RTL8261D_MODEL: + priv->fw_name = RTL8261D_FW_NAME; + priv->fw_sub_magic = FW_SUB_MAGIC_8261D; phydev_info(phydev, "RTL8261D detected (sub_id 0x%02x)\n", sub_phy_id); break; @@ -473,6 +492,7 @@ static int rtl8261x_read_status(struct phy_device *phydev) static int rtl8261x_verify_firmware(struct phy_device *phydev, const struct firmware *fw) { + struct rtl8261x_priv *priv = phydev->priv; const struct rtl8261x_fw_header *hdr; u32 main_magic, sub_magic; u32 calc_crc, file_crc; @@ -493,7 +513,7 @@ static int rtl8261x_verify_firmware(struct phy_device *phydev, const struct firm } sub_magic = le32_to_cpu(hdr->sub_magic); - if (sub_magic != FW_SUB_MAGIC_8261C) { + if (sub_magic != priv->fw_sub_magic) { phydev_err(phydev, "Invalid sub magic: 0x%08x\n", sub_magic); return -EINVAL; } @@ -549,8 +569,12 @@ static int rtl8261x_fw_execute_entry(struct phy_device *phydev, switch (entry->type) { case OP_WRITE: - ret = phy_modify_mmd(phydev, dev, addr, - GENMASK(msb, lsb), (value << lsb) & GENMASK(msb, lsb)); + if (msb != 15 || lsb != 0) + ret = phy_modify_mmd(phydev, dev, addr, GENMASK(msb, lsb), + (value << lsb) & GENMASK(msb, lsb)); + else + ret = phy_write_mmd(phydev, dev, addr, value); + if (ret) return ret; break; @@ -1375,7 +1399,7 @@ static int rtl821x_resume(struct phy_device *phydev) msleep(20); - return 0; + return rtl8211f_config_rgmii_delay(phydev); } static int rtl8211f_resume(struct phy_device *phydev) @@ -2696,10 +2720,35 @@ exit: return ret; } -static int rtl8224_mdi_config_order(struct phy_device *phydev) +static int rtl8224_get_base_addr(struct phy_device *phydev, u32 *base_addr) +{ + struct device *dev = &phydev->mdio.dev; + struct device_node *np; + int ret; + + *base_addr = phydev->mdio.addr & ~3; + np = of_get_parent(dev->of_node); + if (of_node_name_eq(np, "ethernet-phy-package")) { + ret = of_property_read_u32(np, "reg", base_addr); + of_node_put(np); + if (ret) + return dev_err_probe(dev, ret, + "Missing or invalid PHY package reg\n"); + + if (phydev->mdio.addr < *base_addr || + phydev->mdio.addr - *base_addr >= 4) + return dev_err_probe(dev, -EINVAL, + "PHY address outside RTL8224 package\n"); + } else { + of_node_put(np); + } + + return 0; +} + +static int rtl8224_mdi_config_order(struct phy_device *phydev, u8 port_offset) { struct device_node *np = phydev->mdio.dev.of_node; - u8 port_offset = phydev->mdio.addr & 3; u32 order = 0; int ret; @@ -2721,10 +2770,10 @@ static int rtl8224_mdi_config_order(struct phy_device *phydev) order ? BIT(port_offset) : 0); } -static int rtl8224_mdi_config_polarity(struct phy_device *phydev) +static int rtl8224_mdi_config_polarity(struct phy_device *phydev, u8 port_offset) { struct device_node *np = phydev->mdio.dev.of_node; - u8 offset = (phydev->mdio.addr & 3) * 4; + u8 offset = port_offset * 4; u32 polarity = 0; int ret; @@ -2748,20 +2797,33 @@ static int rtl8224_mdi_config_polarity(struct phy_device *phydev) static int rtl8224_config_init(struct phy_device *phydev) { + u32 base_addr; + u8 port_offset; int ret; - ret = rtl8224_mdi_config_order(phydev); + ret = rtl8224_get_base_addr(phydev, &base_addr); if (ret) return ret; - return rtl8224_mdi_config_polarity(phydev); + port_offset = phydev->mdio.addr - base_addr; + ret = rtl8224_mdi_config_order(phydev, port_offset); + if (ret) + return ret; + + return rtl8224_mdi_config_polarity(phydev, port_offset); } static int rtl8224_probe(struct phy_device *phydev) { - /* Chip exposes 4 ports, join all of them in the same package */ - return devm_phy_package_join(&phydev->mdio.dev, phydev, - phydev->mdio.addr & ~3, 0); + struct device *dev = &phydev->mdio.dev; + u32 base_addr; + int ret; + + ret = rtl8224_get_base_addr(phydev, &base_addr); + if (ret) + return ret; + + return devm_phy_package_join(dev, phydev, base_addr, 0); } static bool rtlgen_supports_2_5gbps(struct phy_device *phydev) @@ -3044,43 +3106,72 @@ static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev) return IRQ_HANDLED; } -static int rtlgen_sfp_get_features(struct phy_device *phydev) +static int rtl8365mb_config_mdix(struct phy_device *phydev) { - linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, - phydev->supported); - - /* set default mode */ - phydev->speed = SPEED_10000; - phydev->duplex = DUPLEX_FULL; + u16 val; - phydev->port = PORT_FIBRE; + switch (phydev->mdix_ctrl) { + case ETH_TP_MDI: + val = RTL8365MB_VC_PHYCR1_MDIX_FORCE | + RTL8365MB_VC_PHYCR1_MDI; + break; + case ETH_TP_MDI_X: + val = RTL8365MB_VC_PHYCR1_MDIX_FORCE; + break; + case ETH_TP_MDI_AUTO: + val = 0; + break; + default: + /* Leave the hardware configuration alone until user space + * asks for a specific mode. + */ + return 0; + } - return 0; + return phy_modify_changed(phydev, RTL8365MB_VC_PHYCR1, + RTL8365MB_VC_PHYCR1_MDIX_FORCE | + RTL8365MB_VC_PHYCR1_MDI, val); } -static int rtlgen_sfp_read_status(struct phy_device *phydev) +static int rtl8365mb_config_aneg(struct phy_device *phydev) { - int val, err; + int ret; - err = genphy_update_link(phydev); - if (err) - return err; + ret = rtl8365mb_config_mdix(phydev); + if (ret < 0) + return ret; - if (!phydev->link) - return 0; + /* The pair assignment is only evaluated while the link is brought up, + * so renegotiate if the crossover configuration changed. + */ + return __genphy_config_aneg(phydev, ret); +} - val = phy_read(phydev, RTL_PHYSR); - if (val < 0) - return val; +static int rtl8365mb_read_status(struct phy_device *phydev) +{ + int ret; - rtlgen_decode_physr(phydev, val); + ret = phy_read(phydev, RTL8365MB_VC_PHYCR1); + if (ret < 0) + return ret; - return 0; -} + if (ret & RTL8365MB_VC_PHYCR1_MDIX_FORCE) { + if (ret & RTL8365MB_VC_PHYCR1_MDI) + phydev->mdix_ctrl = ETH_TP_MDI; + else + phydev->mdix_ctrl = ETH_TP_MDI_X; + } else { + phydev->mdix_ctrl = ETH_TP_MDI_AUTO; + } -static int rtlgen_sfp_config_aneg(struct phy_device *phydev) -{ - return 0; + ret = phy_read(phydev, RTL_PHYSR); + if (ret < 0) + return ret; + + phydev->mdix = (ret & RTL8365MB_VC_PHYSR_MDI) ? ETH_TP_MDI : + ETH_TP_MDI_X; + + return genphy_read_status(phydev); } static struct phy_driver realtek_drvs[] = { @@ -3333,20 +3424,6 @@ static struct phy_driver realtek_drvs[] = { .read_mmd = rtl822x_read_mmd, .write_mmd = rtl822x_write_mmd, }, { - PHY_ID_MATCH_EXACT(PHY_ID_RTL_DUMMY_SFP), - .name = "Realtek SFP PHY Mode", - .flags = PHY_IS_INTERNAL, - .probe = rtl822x_probe, - .get_features = rtlgen_sfp_get_features, - .config_aneg = rtlgen_sfp_config_aneg, - .read_status = rtlgen_sfp_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .read_mmd = rtl822x_read_mmd, - .write_mmd = rtl822x_write_mmd, - }, { PHY_ID_MATCH_EXACT(0x001ccad0), .name = "RTL8224 2.5Gbps PHY", .flags = PHY_POLL_CABLE_TEST, @@ -3388,9 +3465,13 @@ static struct phy_driver realtek_drvs[] = { }, { PHY_ID_MATCH_EXACT(0x001cc942), .name = "RTL8365MB-VC Gigabit Ethernet", + .read_mmd = genphy_read_mmd_c45, + .write_mmd = genphy_write_mmd_c45, /* Interrupt handling analogous to RTL8366RB */ .config_intr = genphy_no_config_intr, .handle_interrupt = genphy_handle_interrupt_no_ack, + .config_aneg = rtl8365mb_config_aneg, + .read_status = rtl8365mb_read_status, .suspend = genphy_suspend, .resume = genphy_resume, }, { @@ -3413,6 +3494,32 @@ static struct phy_driver realtek_drvs[] = { .soft_reset = genphy_c45_pma_soft_reset, .suspend = genphy_c45_pma_suspend, .resume = genphy_c45_pma_resume, + }, { + PHY_ID_MATCH_EXACT(RTL_8261CE_CG), + .name = "Realtek RTL8261CE 10Gbps PHY", + .probe = rtl8261x_probe, + .config_init = rtl8261x_config_init, + .get_features = rtl8261x_get_features, + .config_aneg = rtl8261x_config_aneg, + .read_status = rtl8261x_read_status, + .config_intr = rtl8261x_config_intr, + .handle_interrupt = rtl8261x_handle_interrupt, + .soft_reset = genphy_c45_pma_soft_reset, + .suspend = genphy_c45_pma_suspend, + .resume = genphy_c45_pma_resume, + }, { + PHY_ID_MATCH_EXACT(RTL_8261D_VM), + .name = "Realtek RTL8261D_VM 10Gbps PHY", + .probe = rtl8261x_probe, + .config_init = rtl8261x_config_init, + .get_features = rtl8261x_get_features, + .config_aneg = rtl8261x_config_aneg, + .read_status = rtl8261x_read_status, + .config_intr = rtl8261x_config_intr, + .handle_interrupt = rtl8261x_handle_interrupt, + .soft_reset = genphy_c45_pma_soft_reset, + .suspend = genphy_c45_pma_suspend, + .resume = genphy_c45_pma_resume, }, }; |
