summaryrefslogtreecommitdiff
path: root/drivers/net/phy/dp83867.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-22 15:58:00 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-22 15:58:00 -1000
commit734bef548a96e8774d6eef5dfa2026c6edc4e80b (patch)
treece2520b2602ce3b82f9842490d21836f9838d441 /drivers/net/phy/dp83867.c
parent864c07de0c7dcbca58b61625dfa2e461ae63b242 (diff)
parent1a2c35c49cc7c6be860038b8442b52424a8f123c (diff)
downloadlinux-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/dp83867.c')
-rw-r--r--drivers/net/phy/dp83867.c111
1 files changed, 98 insertions, 13 deletions
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index 61a941aa02d9..a3cd5cb11ea0 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/mii.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/phy.h>
#include <linux/delay.h>
@@ -196,6 +197,16 @@ struct dp83867_private {
bool set_clk_output;
u32 clk_output_sel;
bool sgmii_ref_clk_en;
+
+ /* Shadow of the LED registers, replayed after a soft reset. led_lock
+ * serializes the shadow and its replay against the LED callbacks,
+ * because dp83867_config_init() does the replay off phydev->lock.
+ */
+ struct mutex led_lock;
+ u16 ledcr1;
+ u16 ledcr1_mask;
+ u16 ledcr2;
+ u16 ledcr2_mask;
};
static int dp83867_ack_interrupt(struct phy_device *phydev)
@@ -722,6 +733,7 @@ static int dp83867_resume(struct phy_device *phydev)
static int dp83867_probe(struct phy_device *phydev)
{
struct dp83867_private *dp83867;
+ int ret;
dp83867 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83867),
GFP_KERNEL);
@@ -730,9 +742,60 @@ static int dp83867_probe(struct phy_device *phydev)
phydev->priv = dp83867;
+ ret = devm_mutex_init(&phydev->mdio.dev, &dp83867->led_lock);
+ if (ret)
+ return ret;
+
return dp83867_of_init(phydev);
}
+/* Update an LED register and mirror the change into the shadow, so that
+ * dp83867_config_init() can replay it after a soft reset. Caller must hold
+ * dp83867->led_lock.
+ */
+static int __dp83867_led_modify(struct phy_device *phydev, u32 reg,
+ u16 mask, u16 val)
+{
+ struct dp83867_private *dp83867 = phydev->priv;
+ int ret;
+
+ ret = phy_modify(phydev, reg, mask, val);
+ if (ret)
+ return ret;
+
+ if (reg == DP83867_LEDCR1) {
+ dp83867->ledcr1 = (dp83867->ledcr1 & ~mask) | (val & mask);
+ dp83867->ledcr1_mask |= mask;
+ } else if (reg == DP83867_LEDCR2) {
+ dp83867->ledcr2 = (dp83867->ledcr2 & ~mask) | (val & mask);
+ dp83867->ledcr2_mask |= mask;
+ } else {
+ WARN_ON_ONCE(1);
+ }
+
+ return 0;
+}
+
+/* Restore the LED registers the driver has programmed, cleared by the soft
+ * reset in dp83867_phy_reset().
+ */
+static int dp83867_led_restore(struct phy_device *phydev)
+{
+ struct dp83867_private *dp83867 = phydev->priv;
+ int ret = 0;
+
+ mutex_lock(&dp83867->led_lock);
+ if (dp83867->ledcr1_mask)
+ ret = phy_modify(phydev, DP83867_LEDCR1,
+ dp83867->ledcr1_mask, dp83867->ledcr1);
+ if (!ret && dp83867->ledcr2_mask)
+ ret = phy_modify(phydev, DP83867_LEDCR2,
+ dp83867->ledcr2_mask, dp83867->ledcr2);
+ mutex_unlock(&dp83867->led_lock);
+
+ return ret;
+}
+
static int dp83867_config_init(struct phy_device *phydev)
{
struct dp83867_private *dp83867 = phydev->priv;
@@ -896,6 +959,10 @@ static int dp83867_config_init(struct phy_device *phydev)
mask, val);
}
+ ret = dp83867_led_restore(phydev);
+ if (ret)
+ phydev_warn(phydev, "failed to restore LED config: %d\n", ret);
+
return 0;
}
@@ -1004,7 +1071,9 @@ static int
dp83867_led_brightness_set(struct phy_device *phydev,
u8 index, enum led_brightness brightness)
{
- u32 val;
+ struct dp83867_private *dp83867 = phydev->priv;
+ u16 val;
+ int ret;
if (index >= DP83867_LED_COUNT)
return -EINVAL;
@@ -1015,10 +1084,13 @@ dp83867_led_brightness_set(struct phy_device *phydev,
if (brightness)
val |= DP83867_LED_DRV_VAL(index);
- return phy_modify(phydev, DP83867_LEDCR2,
- DP83867_LED_DRV_VAL(index) |
- DP83867_LED_DRV_EN(index),
- val);
+ mutex_lock(&dp83867->led_lock);
+ ret = __dp83867_led_modify(phydev, DP83867_LEDCR2,
+ DP83867_LED_DRV_VAL(index) |
+ DP83867_LED_DRV_EN(index), val);
+ mutex_unlock(&dp83867->led_lock);
+
+ return ret;
}
static int dp83867_led_mode(u8 index, unsigned long rules)
@@ -1069,18 +1141,24 @@ static int dp83867_led_hw_is_supported(struct phy_device *phydev, u8 index,
static int dp83867_led_hw_control_set(struct phy_device *phydev, u8 index,
unsigned long rules)
{
+ struct dp83867_private *dp83867 = phydev->priv;
int mode, ret;
mode = dp83867_led_mode(index, rules);
if (mode < 0)
return mode;
- ret = phy_modify(phydev, DP83867_LEDCR1, DP83867_LED_FN_MASK(index),
- DP83867_LED_FN(index, mode));
- if (ret)
- return ret;
-
- return phy_modify(phydev, DP83867_LEDCR2, DP83867_LED_DRV_EN(index), 0);
+ mutex_lock(&dp83867->led_lock);
+ ret = __dp83867_led_modify(phydev, DP83867_LEDCR1,
+ DP83867_LED_FN_MASK(index),
+ DP83867_LED_FN(index, mode));
+ if (!ret)
+ ret = __dp83867_led_modify(phydev, DP83867_LEDCR2,
+ DP83867_LED_DRV_EN(index) |
+ DP83867_LED_DRV_VAL(index), 0);
+ mutex_unlock(&dp83867->led_lock);
+
+ return ret;
}
static int dp83867_led_hw_control_get(struct phy_device *phydev, u8 index,
@@ -1141,9 +1219,11 @@ static int dp83867_led_hw_control_get(struct phy_device *phydev, u8 index,
static int dp83867_led_polarity_set(struct phy_device *phydev, int index,
unsigned long modes)
{
+ struct dp83867_private *dp83867 = phydev->priv;
/* Default active high */
u16 polarity = DP83867_LED_POLARITY(index);
u32 mode;
+ int ret;
for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
switch (mode) {
@@ -1157,8 +1237,13 @@ static int dp83867_led_polarity_set(struct phy_device *phydev, int index,
return -EINVAL;
}
}
- return phy_modify(phydev, DP83867_LEDCR2,
- DP83867_LED_POLARITY(index), polarity);
+
+ mutex_lock(&dp83867->led_lock);
+ ret = __dp83867_led_modify(phydev, DP83867_LEDCR2,
+ DP83867_LED_POLARITY(index), polarity);
+ mutex_unlock(&dp83867->led_lock);
+
+ return ret;
}
static unsigned int dp83867_inband_caps(struct phy_device *phydev,