* [PATCH v7 0/3] PCI: AtomicOps: Fix pci_enable_atomic_ops_to_root()
From: Gerd Bayer @ 2026-03-30 13:09 UTC (permalink / raw)
To: Bjorn Helgaas, Jay Cornwall, Felix Kuehling, Ilpo Järvinen,
Christian Borntraeger, Niklas Schnelle
Cc: Gerald Schaefer, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Sven Schnelle, Leon Romanovsky, Alexander Schmidt, linux-s390,
linux-pci, linux-kernel, netdev, linux-rdma, Gerd Bayer, stable
Hi Bjorn et al.
On s390, AtomicOp Requests are enabled on a PCI function that supports
them, despite the helper being ignorant about the root port's capability
to supporting their completion.
Patch 1: Do not enable AtomicOps Requests on RCiEPs
Patch 2: Fix the logic in pci_enable_atomic_ops_to_root()
Patch 3: Update references to PCIe spec in that function.
I did test that the issue is fixed with these patches. Also, I verified
that on a Mellanox/Nvidia ConnectX-6 adapter plugged straight into the
root port of a x86 system still gets AtomicOp Requests enabled.
Due to a lack of the required hardware, I did not test this with any PCIe
switches between root port and endpoint. So test exposure in other
environments is highly appreciated.
Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com>
---
Changes in v7:
- Prepend series with a patch to explicitly exclude RCiEPs from
enablement of AtomicOps Requests
- Limit the core patch 2 to enforce a full check of the entire
PCIe hierarchy for support of AtomicOps capabilities.
- Rebase to v7.0-rc6
- Link to v6: https://lore.kernel.org/r/20260325-fix_pciatops-v6-0-10bf19d76dd1@linux.ibm.com
Changes in v6:
- Incorporate Ilpo's editorial comments.
- Correct logic in pci_is_atomicops_capable_rp() (annotated by Sashiko)
- Link to v5: https://lore.kernel.org/r/20260323-fix_pciatops-v5-0-fada7233aea8@linux.ibm.com
Changes in v5:
- Introduce new pcibios_connects_to_atomicops_capable_rc() so arch's can
declare AtomicOps support outside of PCIe config space. Defaults to
"true" - except s390.
- rebase to 7.0-rc5
- Link to v4: https://lore.kernel.org/r/20260313-fix_pciatops-v4-0-93bc70a63935@linux.ibm.com
Changes in v4:
- drop patch 1 - it will become the base of a new series
- previous patch 2, now 1: reword commit message
- add a new patch to update references to PCI spec within
pci_enable_atomic_ops_to_root()
- rebase to latest master
- Link to v3: https://lore.kernel.org/r/20260306-fix_pciatops-v3-0-99d12bcafb19@linux.ibm.com
Changes in v3:
- rebase to 7.0-rc2
- gentle ping
- add netdev and rdma lists for awareness
- Link to v2: https://lore.kernel.org/r/20251216-fix_pciatops-v2-0-d013e9b7e2ee@linux.ibm.com
Changes in v2:
- rebase to 6.19-rc1
- otherwise unchanged to v1
- Link to v1: https://lore.kernel.org/r/20251110-fix_pciatops-v1-0-edc58a57b62e@linux.ibm.com
---
Gerd Bayer (3):
PCI: AtomicOps: Do not enable requests by RCiEPs
PCI: AtomicOps: Do not enable without support in root port
PCI: AtomicOps: Update references to PCIe spec
drivers/pci/pci.c | 48 ++++++++++++++++++++++++++----------------------
1 file changed, 26 insertions(+), 22 deletions(-)
---
base-commit: 7aaa8047eafd0bd628065b15757d9b48c5f9c07d
change-id: 20251106-fix_pciatops-7e8608eccb03
Best regards,
--
Gerd Bayer <gbayer@linux.ibm.com>
^ permalink raw reply
* [PATCH v7 2/3] PCI: AtomicOps: Do not enable without support in root port
From: Gerd Bayer @ 2026-03-30 13:09 UTC (permalink / raw)
To: Bjorn Helgaas, Jay Cornwall, Felix Kuehling, Ilpo Järvinen,
Christian Borntraeger, Niklas Schnelle
Cc: Gerald Schaefer, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Sven Schnelle, Leon Romanovsky, Alexander Schmidt, linux-s390,
linux-pci, linux-kernel, netdev, linux-rdma, Gerd Bayer, stable
In-Reply-To: <20260330-fix_pciatops-v7-0-f601818417e8@linux.ibm.com>
When inspecting the config space of a Connect-X physical function in an
s390 system after it was initialized by the mlx5_core device driver, we
found the function to be enabled to request AtomicOps despite the
system's root-complex lacking support for completing them:
1ed0:00:00.1 Ethernet controller: Mellanox Technologies MT2894 Family [ConnectX-6 Lx]
Subsystem: Mellanox Technologies Device 0002
[...]
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
AtomicOpsCtl: ReqEn+
IDOReq- IDOCompl- LTR- EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
Turns out the device driver calls pci_enable_atomic_ops_to_root() which
defaulted to enable AtomicOps requests even if it had no information
about the root port that the PCIe device is attached to.
Change the logic of pci_enable_atomic_ops_to_root() to fully traverse the
PCIe tree upwards, check that the bridge devices support delivering
AtomicOps transactions, and finally check that there is a root port at
the end that does support completing AtomicOps.
Reported-by: Alexander Schmidt <alexs@linux.ibm.com>
Cc: stable@vger.kernel.org
Fixes: 430a23689dea ("PCI: Add pci_enable_atomic_ops_to_root()")
Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com>
---
drivers/pci/pci.c | 39 ++++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 17 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 135e5b591df405e87e7f520a618d7e2ccba55ce1..57af00ecdc97086a32c063ff86f8a39087ad1f5e 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3660,6 +3660,14 @@ void pci_acs_init(struct pci_dev *dev)
pci_disable_broken_acs_cap(dev);
}
+static bool pci_is_atomicops_capable_rp(struct pci_dev *dev, u32 cap, u32 cap_mask)
+{
+ if (!dev || !(pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT))
+ return false;
+
+ return (cap & cap_mask) == cap_mask;
+}
+
/**
* pci_enable_atomic_ops_to_root - enable AtomicOp requests to root port
* @dev: the PCI device
@@ -3676,8 +3684,9 @@ void pci_acs_init(struct pci_dev *dev)
int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask)
{
struct pci_bus *bus = dev->bus;
- struct pci_dev *bridge;
- u32 cap, ctl2;
+ struct pci_dev *bridge = NULL;
+ u32 cap = 0;
+ u32 ctl2;
/*
* Per PCIe r5.0, sec 9.3.5.10, the AtomicOp Requester Enable bit
@@ -3713,29 +3722,25 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask)
switch (pci_pcie_type(bridge)) {
/* Ensure switch ports support AtomicOp routing */
case PCI_EXP_TYPE_UPSTREAM:
- case PCI_EXP_TYPE_DOWNSTREAM:
- if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE))
- return -EINVAL;
- break;
-
- /* Ensure root port supports all the sizes we care about */
- case PCI_EXP_TYPE_ROOT_PORT:
- if ((cap & cap_mask) != cap_mask)
- return -EINVAL;
- break;
- }
-
- /* Ensure upstream ports don't block AtomicOps on egress */
- if (pci_pcie_type(bridge) == PCI_EXP_TYPE_UPSTREAM) {
+ /* Upstream ports must not block AtomicOps on egress */
pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2,
&ctl2);
if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK)
return -EINVAL;
+ fallthrough;
+ /* All switch ports need to route AtomicOps */
+ case PCI_EXP_TYPE_DOWNSTREAM:
+ if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE))
+ return -EINVAL;
+ break;
}
-
bus = bus->parent;
}
+ /* Finally, last bridge must be root port and support requested sizes */
+ if (!(pci_is_atomicops_capable_rp(bridge, cap, cap_mask)))
+ return -EINVAL;
+
pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
PCI_EXP_DEVCTL2_ATOMIC_REQ);
return 0;
--
2.51.0
^ permalink raw reply related
* Re: [PATCH net-next v4 0/2] e1000e: add XDP support
From: Maciej Fijalkowski @ 2026-03-30 13:17 UTC (permalink / raw)
To: Matteo Croce
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
Mohsin Bashir, netdev, bpf, intel-wired-lan, linux-kernel
In-Reply-To: <20260323182823.5813-1-teknoraver@meta.com>
On Mon, Mar 23, 2026 at 07:28:21PM +0100, Matteo Croce wrote:
> Add XDP support to e1000e driver. First patch adds basic XDP support,
> while the second one adds support for AF_XDP.
This set has nothing to do with AF_XDP.
> Tested on an Intel 82574L Gigabit card with xdp-bench and xdp-trafficgen
>
> v2: added a missing 'select PAGE_POOL' which triggered a build failure
> with some configurations.
> v3: removed a leftover file.
> v4: bugfixes
>
> Matteo Croce (2):
> e1000e: add basic XDP support
> e1000e: add XDP_REDIRECT support
>
> drivers/net/ethernet/intel/Kconfig | 1 +
> drivers/net/ethernet/intel/e1000e/e1000.h | 18 +-
> drivers/net/ethernet/intel/e1000e/netdev.c | 610 ++++++++++++++++++++-
> 3 files changed, 617 insertions(+), 12 deletions(-)
>
> --
> 2.53.0
>
>
^ permalink raw reply
* Re: [PATCH net-next v4 13/15] net/mlx5: Add a shared devlink instance for PFs on same chip
From: Jiri Pirko @ 2026-03-30 13:19 UTC (permalink / raw)
To: Mark Brown; +Cc: Ben Copeland, jiri, netdev, kuba
In-Reply-To: <4cc597da-4742-4437-93b3-686124396517@sirena.org.uk>
Mon, Mar 30, 2026 at 02:40:08PM +0200, broonie@kernel.org wrote:
>On Tue, Mar 24, 2026 at 03:37:20PM +0000, Ben Copeland wrote:
>> On Tue, 24 Mar 2026 at 15:21, Jiri Pirko <jiri@resnulli.us> wrote:
>> > Tue, Mar 24, 2026 at 04:10:14PM +0100, ben.copeland@linaro.org wrote:
>
>> > >@@ -33,7 +33,7 @@ int mlx5_shd_init(struct mlx5_core_dev *dev)
>> > > start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size,
>> > > PCI_VPD_RO_KEYWORD_SERIALNO, &kw_len);
>> > > if (start < 0)
>> > >- return -ENOENT;
>> > >+ return 0;
>
>> > Okay. That is probably the best fall-back. Do you want to send the fix,
>> > or should I?
>
>> I will leave it with you.
>
>Any news on this, the problem still seems to be showing up?
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=b8f9410aefc15e55304788b958a796d22bcabb7e
^ permalink raw reply
* Re: [PATCH v6 phy-next 03/28] usb: add missing headers transitively included by <linux/phy/phy.h>
From: Greg Kroah-Hartman @ 2026-03-30 13:19 UTC (permalink / raw)
To: Vladimir Oltean
Cc: linux-phy, Vinod Koul, Neil Armstrong, dri-devel, freedreno,
linux-arm-kernel, linux-arm-msm, linux-can, linux-gpio, linux-ide,
linux-kernel, linux-media, linux-pci, linux-renesas-soc,
linux-riscv, linux-rockchip, linux-samsung-soc, linux-scsi,
linux-sunxi, linux-tegra, linux-usb, netdev, spacemit,
UNGLinuxDriver, Thinh Nguyen, Peter Chen, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
In-Reply-To: <20260327184706.1600329-4-vladimir.oltean@nxp.com>
On Fri, Mar 27, 2026 at 08:46:41PM +0200, Vladimir Oltean wrote:
> The chipidea ci_hdrc_imx driver uses regulator consumer API like
> regulator_enable() but does not include <linux/regulator/consumer.h>.
>
> The core USB HCD driver calls invalidate_kernel_vmap_range() and
> flush_kernel_vmap_range(), but does not include <linux/highmem.h>.
>
> The DWC3 gadget driver calls:
> - device_property_present()
> - device_property_count_u8()
> - device_property_read_u8_array()
> but does not include <linux/property.h>
>
> The dwc3-generic-plat driver uses of_device_get_match_data() but does
> not include <linux/of.h>.
>
> In all these cases, the necessary includes were still provided somehow,
> directly or indirectly, through <linux/phy/phy.h>. The latter header
> wants to drop those includes, so fill in the required headers to avoid
> any breakage.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> # dwc3
> ---
> Cc: Peter Chen <peter.chen@kernel.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Frank Li <Frank.Li@nxp.com>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
>
> v2->v6: none
> v1->v2: collect tag
> ---
> drivers/usb/chipidea/ci_hdrc_imx.c | 1 +
> drivers/usb/core/hcd.c | 1 +
> drivers/usb/dwc3/dwc3-generic-plat.c | 1 +
> drivers/usb/dwc3/gadget.c | 1 +
> 4 files changed, 4 insertions(+)
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* Re: [PATCH RFC net-next] net: stmmac: qcom-ethqos: set clk_csr
From: Russell King (Oracle) @ 2026-03-30 13:21 UTC (permalink / raw)
To: Andrew Lunn
Cc: Konrad Dybcio, Mohd Ayaan Anwar, Alexandre Torgue, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, linux-arm-kernel,
linux-arm-msm, linux-stm32, netdev, Paolo Abeni
In-Reply-To: <0d650de4-eb45-481b-8c39-1bf455b948c9@lunn.ch>
On Mon, Mar 30, 2026 at 02:35:39PM +0200, Andrew Lunn wrote:
> On Mon, Mar 30, 2026 at 01:20:18PM +0100, Russell King (Oracle) wrote:
> > On Mon, Mar 30, 2026 at 01:18:56PM +0200, Konrad Dybcio wrote:
> > > On 3/27/26 6:02 PM, Russell King (Oracle) wrote:
> > > > The clocks for qcom-ethqos return a rate of zero as firmware manages
> > > > their rate. According to hardware documentation, the clock which is
> > > > fed to the slave AHB interface can crange between 50 and 100MHz.
> > >
> > > FWIW this __may__ possibly differ between platforms, but I'm not sure
> > > to what degree. Will there be visible impact if we e.g. have a 200 or
> > > 300 MHz clock somewhere?
> >
> > When you add other platforms, you're going to have to deal with their
> > differences.
> >
> > IEEE 802.3 states that the maximum clock rate for the MDIO bus is
> > 2.5MHz. You need to ensure that is the case.
> >
> > Current qcom-ethqos code doesn't set clk_csr, and returns zero for
> > clk_get_rate() on the stmmac clocks because they are managed entirely
> > in firmware.
>
> Could a fixed clock be used in DT to represent clk_csr? Different
> platforms then set it to different frequencies, to represent whatever
> the firmware is doing.
Unfortunately, at hardware level, clk_csr isn't a separate clock input
as such. It can be one of many, depending on the synthesis options
chosen by the designer. It may be hclk (AHB clock), aclk (AXI clock)
clk_app (application clock) or a specific clk_csr input.
Nothing is simple with dwmac. :/
The problem with adding a ficticious clock to solve this is that it
adds to implementers confusion for what is already a very complicated
problem.
We've already seen that the stmmac clocks are a total trainwreck
because no one seems to really understnad what is what, and that goes
back to the days when that "apb" clock was added - and that made the
situation worse not better.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply
* Re: [PATCH net-next v4 1/2] e1000e: add basic XDP support
From: Maciej Fijalkowski @ 2026-03-30 13:24 UTC (permalink / raw)
To: Matteo Croce
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
Mohsin Bashir, netdev, bpf, intel-wired-lan, linux-kernel
In-Reply-To: <20260323182823.5813-2-teknoraver@meta.com>
On Mon, Mar 23, 2026 at 07:28:22PM +0100, Matteo Croce wrote:
> Add XDP support to the e1000e driver covering the actions defined by
> NETDEV_XDP_ACT_BASIC: XDP_DROP, XDP_PASS, XDP_TX and XDP_ABORTED.
>
> Infrastructure:
> - e1000_xdp_setup() / e1000_xdp() for program attach/detach with
> MTU validation and close/open cycle
> - ndo_bpf support in net_device_ops
> - xdp_rxq_info registration in setup/free_rx_resources
>
> Receive path:
> - e1000_alloc_rx_buffers_xdp() for page-based Rx buffer allocation
> with XDP_PACKET_HEADROOM
> - e1000_clean_rx_irq_xdp() as the XDP receive handler
Hi Matteo,
Since you started to look onto this driver, I think we should have a
single routine for cleaning buffers on rx. So I would ask for getting rid
of adapter->clean_rx (or at least convince reviewers it is not possible
for some reason) and then implement XDP support with approach as XDP being
a first class citizen.
Furthermore I believe all new implementations of XDP require to include
multi-buffer support.
Last but not least, this lives in intel directory so I assume
primitives/helpers from libie/libeth should be used for this work.
Thanks,
Maciej
> - e1000_run_xdp() to execute the XDP program on received packets
> - SKB building via napi_build_skb() for XDP_PASS with metadata,
> checksum offload and RSS hash support
>
> Transmit path:
> - e1000_xdp_xmit_ring() to DMA-map and enqueue an XDP frame
> - e1000_xdp_xmit_back() to convert an xdp_buff to a frame and send it
> - e1000_finalize_xdp() to flush the TX ring after XDP processing
> - TX completion via xdp_return_frame() with buffer type tracking
>
> Assisted-by: claude-opus-4-6
> Signed-off-by: Matteo Croce <teknoraver@meta.com>
> ---
> drivers/net/ethernet/intel/Kconfig | 1 +
> drivers/net/ethernet/intel/e1000e/e1000.h | 18 +-
> drivers/net/ethernet/intel/e1000e/netdev.c | 533 ++++++++++++++++++++-
> 3 files changed, 540 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
> index 288fa8ce53af..46e37cb68e70 100644
> --- a/drivers/net/ethernet/intel/Kconfig
> +++ b/drivers/net/ethernet/intel/Kconfig
> @@ -63,6 +63,7 @@ config E1000E
> depends on PCI && (!SPARC32 || BROKEN)
> depends on PTP_1588_CLOCK_OPTIONAL
> select CRC32
> + select PAGE_POOL
> help
> This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
> ethernet family of adapters. For PCI or PCI-X e1000 adapters,
> diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
> index 63ebe00376f5..4c1175d4e5cb 100644
> --- a/drivers/net/ethernet/intel/e1000e/e1000.h
> +++ b/drivers/net/ethernet/intel/e1000e/e1000.h
> @@ -19,10 +19,13 @@
> #include <linux/net_tstamp.h>
> #include <linux/ptp_clock_kernel.h>
> #include <linux/ptp_classify.h>
> +#include <linux/bpf.h>
> #include <linux/mii.h>
> #include <linux/mdio.h>
> #include <linux/mutex.h>
> #include <linux/pm_qos.h>
> +#include <net/page_pool/helpers.h>
> +#include <net/xdp.h>
> #include "hw.h"
>
> struct e1000_info;
> @@ -126,12 +129,21 @@ struct e1000_ps_page {
> u64 dma; /* must be u64 - written to hw */
> };
>
> +enum e1000_tx_buf_type {
> + E1000_TX_BUF_SKB = 0,
> + E1000_TX_BUF_XDP,
> +};
> +
> /* wrappers around a pointer to a socket buffer,
> * so a DMA handle can be stored along with the buffer
> */
> struct e1000_buffer {
> dma_addr_t dma;
> - struct sk_buff *skb;
> + union {
> + struct sk_buff *skb;
> + struct xdp_frame *xdpf;
> + };
> + enum e1000_tx_buf_type type;
> union {
> /* Tx */
> struct {
> @@ -259,6 +271,10 @@ struct e1000_adapter {
> gfp_t gfp);
> struct e1000_ring *rx_ring;
>
> + struct bpf_prog *xdp_prog;
> + struct xdp_rxq_info xdp_rxq;
> + struct page_pool *page_pool;
> +
> u32 rx_int_delay;
> u32 rx_abs_int_delay;
>
> diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
> index 9befdacd6730..d77f208f00cc 100644
> --- a/drivers/net/ethernet/intel/e1000e/netdev.c
> +++ b/drivers/net/ethernet/intel/e1000e/netdev.c
> @@ -25,6 +25,10 @@
> #include <linux/pm_runtime.h>
> #include <linux/prefetch.h>
> #include <linux/suspend.h>
> +#include <linux/bpf.h>
> +#include <linux/bpf_trace.h>
> +#include <net/page_pool/helpers.h>
> +#include <net/xdp.h>
>
> #include "e1000.h"
> #define CREATE_TRACE_POINTS
> @@ -33,6 +37,11 @@
> char e1000e_driver_name[] = "e1000e";
>
> #define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
> +
> +#define E1000_XDP_PASS 0
> +#define E1000_XDP_CONSUMED BIT(0)
> +#define E1000_XDP_TX BIT(1)
> +
> static int debug = -1;
> module_param(debug, int, 0);
> MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
> @@ -708,6 +717,370 @@ static void e1000_alloc_rx_buffers(struct e1000_ring *rx_ring,
> rx_ring->next_to_use = i;
> }
>
> +static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss,
> + struct sk_buff *skb)
> +{
> + if (netdev->features & NETIF_F_RXHASH)
> + skb_set_hash(skb, le32_to_cpu(rss), PKT_HASH_TYPE_L3);
> +}
> +
> +/**
> + * e1000_xdp_xmit_ring - transmit an XDP frame on the TX ring
> + * @adapter: board private structure
> + * @tx_ring: Tx descriptor ring
> + * @xdpf: XDP frame to transmit
> + *
> + * Returns E1000_XDP_TX on success, E1000_XDP_CONSUMED on failure
> + **/
> +static int e1000_xdp_xmit_ring(struct e1000_adapter *adapter,
> + struct e1000_ring *tx_ring,
> + struct xdp_frame *xdpf)
> +{
> + struct e1000_buffer *buffer_info;
> + struct e1000_tx_desc *tx_desc;
> + dma_addr_t dma;
> + u16 i;
> +
> + if (e1000_desc_unused(tx_ring) < 1)
> + return E1000_XDP_CONSUMED;
> +
> + i = tx_ring->next_to_use;
> + buffer_info = &tx_ring->buffer_info[i];
> +
> + dma = dma_map_single(&adapter->pdev->dev, xdpf->data, xdpf->len,
> + DMA_TO_DEVICE);
> + if (dma_mapping_error(&adapter->pdev->dev, dma))
> + return E1000_XDP_CONSUMED;
> +
> + buffer_info->xdpf = xdpf;
> + buffer_info->type = E1000_TX_BUF_XDP;
> + buffer_info->dma = dma;
> + buffer_info->length = xdpf->len;
> + buffer_info->time_stamp = jiffies;
> + buffer_info->next_to_watch = i;
> + buffer_info->segs = 1;
> + buffer_info->bytecount = xdpf->len;
> + buffer_info->mapped_as_page = 0;
> +
> + tx_desc = E1000_TX_DESC(*tx_ring, i);
> + tx_desc->buffer_addr = cpu_to_le64(dma);
> + tx_desc->lower.data = cpu_to_le32(adapter->txd_cmd |
> + E1000_TXD_CMD_IFCS |
> + xdpf->len);
> + tx_desc->upper.data = 0;
> +
> + i++;
> + if (i == tx_ring->count)
> + i = 0;
> + tx_ring->next_to_use = i;
> +
> + return E1000_XDP_TX;
> +}
> +
> +/**
> + * e1000_xdp_xmit_back - transmit an XDP buffer back on the same device
> + * @adapter: board private structure
> + * @xdp: XDP buffer to transmit
> + *
> + * Returns E1000_XDP_TX on success, E1000_XDP_CONSUMED on failure
> + **/
> +static int e1000_xdp_xmit_back(struct e1000_adapter *adapter,
> + struct xdp_buff *xdp)
> +{
> + struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp);
> +
> + if (unlikely(!xdpf))
> + return E1000_XDP_CONSUMED;
> +
> + return e1000_xdp_xmit_ring(adapter, adapter->tx_ring, xdpf);
> +}
> +
> +/**
> + * e1000_finalize_xdp - flush XDP operations after NAPI Rx loop
> + * @adapter: board private structure
> + * @xdp_xmit: bitmask of XDP actions taken during Rx processing
> + **/
> +static void e1000_finalize_xdp(struct e1000_adapter *adapter,
> + unsigned int xdp_xmit)
> +{
> + struct e1000_ring *tx_ring = adapter->tx_ring;
> +
> + if (xdp_xmit & E1000_XDP_TX) {
> + /* Force memory writes to complete before letting h/w
> + * know there are new descriptors to fetch.
> + */
> + wmb();
> + if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
> + e1000e_update_tdt_wa(tx_ring,
> + tx_ring->next_to_use);
> + else
> + writel(tx_ring->next_to_use, tx_ring->tail);
> + }
> +}
> +
> +/**
> + * e1000_run_xdp - run an XDP program on a received packet
> + * @adapter: board private structure
> + * @xdp: XDP buffer containing packet data
> + *
> + * Returns E1000_XDP_PASS, E1000_XDP_TX, or E1000_XDP_CONSUMED
> + **/
> +static int e1000_run_xdp(struct e1000_adapter *adapter, struct xdp_buff *xdp)
> +{
> + struct bpf_prog *xdp_prog = READ_ONCE(adapter->xdp_prog);
> + struct net_device *netdev = adapter->netdev;
> + int result = E1000_XDP_PASS;
> + u32 act;
> +
> + if (!xdp_prog)
> + return E1000_XDP_PASS;
> +
> + prefetchw(xdp->data_hard_start);
> +
> + act = bpf_prog_run_xdp(xdp_prog, xdp);
> + switch (act) {
> + case XDP_PASS:
> + break;
> + case XDP_TX:
> + result = e1000_xdp_xmit_back(adapter, xdp);
> + if (result == E1000_XDP_CONSUMED)
> + goto out_failure;
> + break;
> + default:
> + bpf_warn_invalid_xdp_action(netdev, xdp_prog, act);
> + fallthrough;
> + case XDP_ABORTED:
> +out_failure:
> + trace_xdp_exception(netdev, xdp_prog, act);
> + fallthrough;
> + case XDP_DROP:
> + result = E1000_XDP_CONSUMED;
> + break;
> + }
> +
> + return result;
> +}
> +
> +/**
> + * e1000_alloc_rx_buffers_xdp - Replace used receive buffers for XDP
> + * @rx_ring: Rx descriptor ring
> + * @cleaned_count: number to reallocate
> + * @gfp: flags for allocation
> + *
> + * Allocates page-based Rx buffers with XDP_PACKET_HEADROOM headroom.
> + **/
> +static void e1000_alloc_rx_buffers_xdp(struct e1000_ring *rx_ring,
> + int cleaned_count, gfp_t gfp)
> +{
> + struct e1000_adapter *adapter = rx_ring->adapter;
> + union e1000_rx_desc_extended *rx_desc;
> + struct e1000_buffer *buffer_info;
> + unsigned int i;
> +
> + i = rx_ring->next_to_use;
> + buffer_info = &rx_ring->buffer_info[i];
> +
> + while (cleaned_count--) {
> + if (!buffer_info->page) {
> + buffer_info->page = page_pool_alloc_pages(adapter->page_pool,
> + gfp);
> + if (!buffer_info->page) {
> + adapter->alloc_rx_buff_failed++;
> + break;
> + }
> + }
> +
> + if (!buffer_info->dma) {
> + buffer_info->dma = page_pool_get_dma_addr(buffer_info->page) +
> + XDP_PACKET_HEADROOM;
> + }
> +
> + rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
> + rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
> +
> + if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
> + /* Force memory writes to complete before letting
> + * h/w know there are new descriptors to fetch.
> + */
> + wmb();
> + if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
> + e1000e_update_rdt_wa(rx_ring, i);
> + else
> + writel(i, rx_ring->tail);
> + }
> + i++;
> + if (i == rx_ring->count)
> + i = 0;
> + buffer_info = &rx_ring->buffer_info[i];
> + }
> +
> + rx_ring->next_to_use = i;
> +}
> +
> +/**
> + * e1000_clean_rx_irq_xdp - Receive with XDP processing
> + * @rx_ring: Rx descriptor ring
> + * @work_done: output parameter for indicating completed work
> + * @work_to_do: how many packets we can clean
> + *
> + * Page-based receive path that runs an XDP program on each packet.
> + **/
> +static bool e1000_clean_rx_irq_xdp(struct e1000_ring *rx_ring, int *work_done,
> + int work_to_do)
> +{
> + struct e1000_adapter *adapter = rx_ring->adapter;
> + struct net_device *netdev = adapter->netdev;
> + struct pci_dev *pdev = adapter->pdev;
> + union e1000_rx_desc_extended *rx_desc, *next_rxd;
> + struct e1000_buffer *buffer_info, *next_buffer;
> + struct xdp_buff xdp;
> + u32 length, staterr;
> + unsigned int i, crc_len;
> + int cleaned_count = 0;
> + bool cleaned = false;
> + unsigned int total_rx_bytes = 0, total_rx_packets = 0;
> + unsigned int xdp_xmit = 0;
> +
> + xdp_init_buff(&xdp, PAGE_SIZE, &adapter->xdp_rxq);
> +
> + i = rx_ring->next_to_clean;
> + rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
> + staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
> + buffer_info = &rx_ring->buffer_info[i];
> +
> + while (staterr & E1000_RXD_STAT_DD) {
> + struct sk_buff *skb;
> + int xdp_res;
> +
> + crc_len = 0;
> + if (*work_done >= work_to_do)
> + break;
> + (*work_done)++;
> + dma_rmb();
> +
> + i++;
> + if (i == rx_ring->count)
> + i = 0;
> + next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
> + prefetch(next_rxd);
> +
> + next_buffer = &rx_ring->buffer_info[i];
> +
> + cleaned = true;
> + cleaned_count++;
> +
> + dma_sync_single_for_cpu(&pdev->dev, buffer_info->dma,
> + adapter->rx_buffer_len,
> + DMA_FROM_DEVICE);
> + buffer_info->dma = 0;
> +
> + length = le16_to_cpu(rx_desc->wb.upper.length);
> +
> + /* Multi-descriptor packets not supported with XDP */
> + if (unlikely(!(staterr & E1000_RXD_STAT_EOP)))
> + adapter->flags2 |= FLAG2_IS_DISCARDING;
> +
> + if (adapter->flags2 & FLAG2_IS_DISCARDING) {
> + if (staterr & E1000_RXD_STAT_EOP)
> + adapter->flags2 &= ~FLAG2_IS_DISCARDING;
> + page_pool_put_full_page(adapter->page_pool,
> + buffer_info->page, true);
> + buffer_info->page = NULL;
> + goto next_desc;
> + }
> +
> + if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
> + !(netdev->features & NETIF_F_RXALL))) {
> + page_pool_put_full_page(adapter->page_pool,
> + buffer_info->page, true);
> + buffer_info->page = NULL;
> + goto next_desc;
> + }
> +
> + /* adjust length to remove Ethernet CRC */
> + if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
> + if (netdev->features & NETIF_F_RXFCS)
> + crc_len = 4;
> + else
> + length -= 4;
> + }
> +
> + /* Setup xdp_buff pointing at the page data */
> + xdp_prepare_buff(&xdp, page_address(buffer_info->page),
> + XDP_PACKET_HEADROOM, length, true);
> + xdp_buff_clear_frags_flag(&xdp);
> +
> + xdp_res = e1000_run_xdp(adapter, &xdp);
> +
> + if (xdp_res == E1000_XDP_PASS) {
> + total_rx_bytes += length - crc_len;
> + total_rx_packets++;
> +
> + skb = napi_build_skb(xdp.data_hard_start, PAGE_SIZE);
> + if (unlikely(!skb)) {
> + page_pool_put_full_page(adapter->page_pool,
> + buffer_info->page,
> + true);
> + buffer_info->page = NULL;
> + goto next_desc;
> + }
> +
> + skb_mark_for_recycle(skb);
> + skb_reserve(skb,
> + xdp.data - xdp.data_hard_start);
> + skb_put(skb, xdp.data_end - xdp.data);
> +
> + if (xdp.data_meta != xdp.data)
> + skb_metadata_set(skb, xdp.data - xdp.data_meta);
> +
> + e1000_rx_checksum(adapter, staterr, skb);
> + e1000_rx_hash(netdev,
> + rx_desc->wb.lower.hi_dword.rss, skb);
> + e1000_receive_skb(adapter, netdev, skb, staterr,
> + rx_desc->wb.upper.vlan);
> +
> + /* page consumed by skb */
> + buffer_info->page = NULL;
> + } else if (xdp_res & E1000_XDP_TX) {
> + xdp_xmit |= xdp_res;
> + total_rx_bytes += length - crc_len;
> + total_rx_packets++;
> + /* page consumed by XDP TX */
> + buffer_info->page = NULL;
> + } else {
> + /* XDP_DROP / XDP_ABORTED - recycle page */
> + page_pool_put_full_page(adapter->page_pool,
> + buffer_info->page, true);
> + buffer_info->page = NULL;
> + }
> +
> +next_desc:
> + rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
> +
> + if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
> + adapter->alloc_rx_buf(rx_ring, cleaned_count,
> + GFP_ATOMIC);
> + cleaned_count = 0;
> + }
> +
> + rx_desc = next_rxd;
> + buffer_info = next_buffer;
> + staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
> + }
> + rx_ring->next_to_clean = i;
> +
> + if (xdp_xmit)
> + e1000_finalize_xdp(adapter, xdp_xmit);
> +
> + cleaned_count = e1000_desc_unused(rx_ring);
> + if (cleaned_count)
> + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
> +
> + adapter->total_rx_bytes += total_rx_bytes;
> + adapter->total_rx_packets += total_rx_packets;
> + return cleaned;
> +}
> +
> /**
> * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
> * @rx_ring: Rx descriptor ring
> @@ -896,13 +1269,6 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring,
> }
> }
>
> -static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss,
> - struct sk_buff *skb)
> -{
> - if (netdev->features & NETIF_F_RXHASH)
> - skb_set_hash(skb, le32_to_cpu(rss), PKT_HASH_TYPE_L3);
> -}
> -
> /**
> * e1000_clean_rx_irq - Send received data up the network stack
> * @rx_ring: Rx descriptor ring
> @@ -1075,13 +1441,17 @@ static void e1000_put_txbuf(struct e1000_ring *tx_ring,
> buffer_info->length, DMA_TO_DEVICE);
> buffer_info->dma = 0;
> }
> - if (buffer_info->skb) {
> + if (buffer_info->type == E1000_TX_BUF_XDP) {
> + xdp_return_frame(buffer_info->xdpf);
> + buffer_info->xdpf = NULL;
> + } else if (buffer_info->skb) {
> if (drop)
> dev_kfree_skb_any(buffer_info->skb);
> else
> dev_consume_skb_any(buffer_info->skb);
> buffer_info->skb = NULL;
> }
> + buffer_info->type = E1000_TX_BUF_SKB;
> buffer_info->time_stamp = 0;
> }
>
> @@ -1242,7 +1612,8 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
> if (cleaned) {
> total_tx_packets += buffer_info->segs;
> total_tx_bytes += buffer_info->bytecount;
> - if (buffer_info->skb) {
> + if (buffer_info->type == E1000_TX_BUF_SKB &&
> + buffer_info->skb) {
> bytes_compl += buffer_info->skb->len;
> pkts_compl++;
> }
> @@ -1696,7 +2067,12 @@ static void e1000_clean_rx_ring(struct e1000_ring *rx_ring)
> }
>
> if (buffer_info->page) {
> - put_page(buffer_info->page);
> + if (adapter->page_pool)
> + page_pool_put_full_page(adapter->page_pool,
> + buffer_info->page,
> + false);
> + else
> + put_page(buffer_info->page);
> buffer_info->page = NULL;
> }
>
> @@ -2350,6 +2726,30 @@ int e1000e_setup_tx_resources(struct e1000_ring *tx_ring)
> return err;
> }
>
> +static int e1000_create_page_pool(struct e1000_adapter *adapter)
> +{
> + struct page_pool_params pp_params = {
> + .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
> + .pool_size = adapter->rx_ring->count,
> + .nid = NUMA_NO_NODE,
> + .dev = &adapter->pdev->dev,
> + .napi = &adapter->napi,
> + .dma_dir = DMA_FROM_DEVICE,
> + .offset = XDP_PACKET_HEADROOM,
> + .max_len = adapter->rx_buffer_len,
> + };
> +
> + adapter->page_pool = page_pool_create(&pp_params);
> + if (IS_ERR(adapter->page_pool)) {
> + int err = PTR_ERR(adapter->page_pool);
> +
> + adapter->page_pool = NULL;
> + return err;
> + }
> +
> + return 0;
> +}
> +
> /**
> * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
> * @rx_ring: Rx descriptor ring
> @@ -2389,8 +2789,31 @@ int e1000e_setup_rx_resources(struct e1000_ring *rx_ring)
> rx_ring->next_to_use = 0;
> rx_ring->rx_skb_top = NULL;
>
> + /* XDP RX-queue info */
> + if (xdp_rxq_info_is_reg(&adapter->xdp_rxq))
> + xdp_rxq_info_unreg(&adapter->xdp_rxq);
> +
> + err = e1000_create_page_pool(adapter);
> + if (err)
> + goto err_pages;
> +
> + err = xdp_rxq_info_reg(&adapter->xdp_rxq, adapter->netdev, 0,
> + adapter->napi.napi_id);
> + if (err)
> + goto err_page_pool;
> + err = xdp_rxq_info_reg_mem_model(&adapter->xdp_rxq,
> + MEM_TYPE_PAGE_POOL,
> + adapter->page_pool);
> + if (err) {
> + xdp_rxq_info_unreg(&adapter->xdp_rxq);
> + goto err_page_pool;
> + }
> +
> return 0;
>
> +err_page_pool:
> + page_pool_destroy(adapter->page_pool);
> + adapter->page_pool = NULL;
> err_pages:
> for (i = 0; i < rx_ring->count; i++) {
> buffer_info = &rx_ring->buffer_info[i];
> @@ -2463,6 +2886,14 @@ void e1000e_free_rx_resources(struct e1000_ring *rx_ring)
>
> e1000_clean_rx_ring(rx_ring);
>
> + if (xdp_rxq_info_is_reg(&adapter->xdp_rxq))
> + xdp_rxq_info_unreg(&adapter->xdp_rxq);
> +
> + if (adapter->page_pool) {
> + page_pool_destroy(adapter->page_pool);
> + adapter->page_pool = NULL;
> + }
> +
> for (i = 0; i < rx_ring->count; i++)
> kfree(rx_ring->buffer_info[i].ps_pages);
>
> @@ -3185,7 +3616,11 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
> u64 rdba;
> u32 rdlen, rctl, rxcsum, ctrl_ext;
>
> - if (adapter->rx_ps_pages) {
> + if (adapter->xdp_prog) {
> + rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
> + adapter->clean_rx = e1000_clean_rx_irq_xdp;
> + adapter->alloc_rx_buf = e1000_alloc_rx_buffers_xdp;
> + } else if (adapter->rx_ps_pages) {
> /* this is a 32 byte descriptor */
> rdlen = rx_ring->count *
> sizeof(union e1000_rx_desc_packet_split);
> @@ -6049,6 +6484,12 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
> return -EINVAL;
> }
>
> + /* XDP requires standard MTU */
> + if (adapter->xdp_prog && new_mtu > ETH_DATA_LEN) {
> + e_err("Jumbo Frames not supported while XDP program is active.\n");
> + return -EINVAL;
> + }
> +
> /* Jumbo frame workaround on 82579 and newer requires CRC be stripped */
> if ((adapter->hw.mac.type >= e1000_pch2lan) &&
> !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
> @@ -7331,6 +7772,71 @@ static int e1000_set_features(struct net_device *netdev,
> return 1;
> }
>
> +/**
> + * e1000_xdp_setup - add/remove an XDP program
> + * @netdev: network interface device structure
> + * @bpf: XDP program setup structure
> + **/
> +static int e1000_xdp_setup(struct net_device *netdev, struct netdev_bpf *bpf)
> +{
> + struct e1000_adapter *adapter = netdev_priv(netdev);
> + struct bpf_prog *prog = bpf->prog, *old_prog;
> + bool running = netif_running(netdev);
> + bool need_reset;
> +
> + /* XDP is incompatible with jumbo frames */
> + if (prog && netdev->mtu > ETH_DATA_LEN) {
> + NL_SET_ERR_MSG_MOD(bpf->extack,
> + "XDP is not supported with jumbo frames");
> + return -EINVAL;
> + }
> +
> + /* Validate frame fits in a single page with XDP headroom */
> + if (prog && netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN +
> + XDP_PACKET_HEADROOM > PAGE_SIZE) {
> + NL_SET_ERR_MSG_MOD(bpf->extack,
> + "Frame size too large for XDP");
> + return -EINVAL;
> + }
> +
> + old_prog = xchg(&adapter->xdp_prog, prog);
> + need_reset = (!!prog != !!old_prog);
> +
> + /* Transition between XDP and non-XDP requires ring reconfiguration */
> + if (need_reset && running)
> + e1000e_close(netdev);
> +
> + if (old_prog)
> + bpf_prog_put(old_prog);
> +
> + if (!need_reset)
> + return 0;
> +
> + if (running) {
> + int err = e1000e_open(netdev);
> +
> + if (err) {
> + /* Remove the XDP program since interface is down */
> + xchg(&adapter->xdp_prog, NULL);
> + if (prog)
> + bpf_prog_put(prog);
> + return err;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int e1000_xdp(struct net_device *netdev, struct netdev_bpf *xdp)
> +{
> + switch (xdp->command) {
> + case XDP_SETUP_PROG:
> + return e1000_xdp_setup(netdev, xdp);
> + default:
> + return -EINVAL;
> + }
> +}
> +
> static const struct net_device_ops e1000e_netdev_ops = {
> .ndo_open = e1000e_open,
> .ndo_stop = e1000e_close,
> @@ -7353,6 +7859,7 @@ static const struct net_device_ops e1000e_netdev_ops = {
> .ndo_features_check = passthru_features_check,
> .ndo_hwtstamp_get = e1000e_hwtstamp_get,
> .ndo_hwtstamp_set = e1000e_hwtstamp_set,
> + .ndo_bpf = e1000_xdp,
> };
>
> /**
> @@ -7563,6 +8070,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> netdev->max_mtu = adapter->max_hw_frame_size -
> (VLAN_ETH_HLEN + ETH_FCS_LEN);
>
> + netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
> +
> if (e1000e_enable_mng_pass_thru(&adapter->hw))
> adapter->flags |= FLAG_MNG_PT_ENABLED;
>
> @@ -7776,6 +8285,8 @@ static void e1000_remove(struct pci_dev *pdev)
> e1000e_release_hw_control(adapter);
>
> e1000e_reset_interrupt_capability(adapter);
> + if (adapter->xdp_prog)
> + bpf_prog_put(adapter->xdp_prog);
> kfree(adapter->tx_ring);
> kfree(adapter->rx_ring);
>
> --
> 2.53.0
>
>
^ permalink raw reply
* RE: [PATCH v4 net-next 3/8] dpll: extend pin notifier and netlink events with notification source ID
From: Nitka, Grzegorz @ 2026-03-30 13:24 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
intel-wired-lan@lists.osuosl.org, Oros, Petr,
richardcochran@gmail.com, andrew+netdev@lunn.ch,
Kitszel, Przemyslaw, Nguyen, Anthony L,
Prathosh.Satish@microchip.com, Vecera, Ivan,
Kubalewski, Arkadiusz, vadim.fedorenko@linux.dev,
donald.hunter@gmail.com, horms@kernel.org, pabeni@redhat.com,
kuba@kernel.org, davem@davemloft.net, edumazet@google.com,
Loktionov, Aleksandr
In-Reply-To: <y5rjyaqyvmnyfaj7o2fari2t6i2klegklpnwi7xw7ld6rmajqb@uovrzb76cjs5>
> -----Original Message-----
> From: Jiri Pirko <jiri@resnulli.us>
> Sent: Sunday, March 29, 2026 1:25 PM
> To: Nitka, Grzegorz <grzegorz.nitka@intel.com>
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; intel-wired-
> lan@lists.osuosl.org; Oros, Petr <poros@redhat.com>;
> richardcochran@gmail.com; andrew+netdev@lunn.ch; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; Prathosh.Satish@microchip.com; Vecera,
> Ivan <ivecera@redhat.com>; Kubalewski, Arkadiusz
> <arkadiusz.kubalewski@intel.com>; vadim.fedorenko@linux.dev;
> donald.hunter@gmail.com; horms@kernel.org; pabeni@redhat.com;
> kuba@kernel.org; davem@davemloft.net; edumazet@google.com;
> Loktionov, Aleksandr <aleksandr.loktionov@intel.com>
> Subject: Re: [PATCH v4 net-next 3/8] dpll: extend pin notifier and netlink
> events with notification source ID
>
> Thu, Mar 26, 2026 at 05:28:27PM +0100, grzegorz.nitka@intel.com wrote:
> >Extend the DPLL pin notification API to include a source identifier
> >indicating where the notification originates. This allows notifier
> >consumers and netlink listeners to distinguish between notifications
> >coming from an associated DPLL instance, a parent pin, or the pin
> >itself.
> >
> >A new field, src_id, is added to struct dpll_pin_notifier_info and is
> >passed through all pin-related notification paths. Callers of
> >dpll_pin_notify() are updated to provide a meaningful source identifier
> >based on their context:
> > - pin registration/unregistration uses the DPLL's clock_id,
> > - pin-on-pin operations use the parent pin's clock_id,
> > - pin changes use the pin's own clock_id.
> >
> >As introduced in the commit ("dpll: allow registering FW-identified pin
> >with a different DPLL"), it is possible to share the same physical pin
> >via firmware description (fwnode) with DPLL objects from different
> >kernel modules. This means that a given pin can be registered multiple
> >times.
> >
> >Driver such as ICE (E825 devices) rely on this mechanism when listening
> >for the event where a shared-fwnode pin appears, while avoiding reacting
> >to events triggered by their own registration logic.
> >
> >This change only extends the notification metadata and does not alter
> >existing semantics for drivers that do not use the new field.
> >
> >Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> >Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> >Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> >---
> > drivers/dpll/dpll_core.c | 14 ++++++++------
> > drivers/dpll/dpll_core.h | 2 +-
> > drivers/dpll/dpll_netlink.c | 10 +++++-----
> > drivers/dpll/dpll_netlink.h | 4 ++--
> > include/linux/dpll.h | 1 +
> > 5 files changed, 17 insertions(+), 14 deletions(-)
> >
> >diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c
> >index 55ad03977d6d..c7fcae76c3f5 100644
> >--- a/drivers/dpll/dpll_core.c
> >+++ b/drivers/dpll/dpll_core.c
> >@@ -71,7 +71,8 @@ void dpll_device_notify(struct dpll_device *dpll,
> unsigned long action)
> > call_dpll_notifiers(action, &info);
> > }
> >
> >-void dpll_pin_notify(struct dpll_pin *pin, unsigned long action)
> >+void dpll_pin_notify(struct dpll_pin *pin, u64 ntfy_src,
>
> I don't see the reason for "ntfy_" prefix here. Also. It's src_clock_id.
>
> Could you perhaps consistently name this "src_clock_id" here and in the
> info struct as well?
>
> Thanks!
>
> [..]
Sure, will update it. Most likely it came from very early development, when
I wasn't 100% sure it will be clock_id.
To be updated in the next iteration.
Thanks!
Grzegorz
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v4 net-next 6/8] ice: implement CPI support for E825C
From: Nitka, Grzegorz @ 2026-03-30 13:27 UTC (permalink / raw)
To: Loktionov, Aleksandr, netdev@vger.kernel.org
Cc: Vecera, Ivan, vadim.fedorenko@linux.dev, kuba@kernel.org,
jiri@resnulli.us, edumazet@google.com, Kitszel, Przemyslaw,
richardcochran@gmail.com, donald.hunter@gmail.com,
linux-kernel@vger.kernel.org, Kubalewski, Arkadiusz,
andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org,
horms@kernel.org, Prathosh.Satish@microchip.com,
Nguyen, Anthony L, pabeni@redhat.com, davem@davemloft.net
In-Reply-To: <IA3PR11MB8986A25079EA6C95E701DCDBE557A@IA3PR11MB8986.namprd11.prod.outlook.com>
> -----Original Message-----
> From: Loktionov, Aleksandr <aleksandr.loktionov@intel.com>
> Sent: Friday, March 27, 2026 6:13 PM
> To: Nitka, Grzegorz <grzegorz.nitka@intel.com>; netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> Prathosh.Satish@microchip.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; pabeni@redhat.com;
> davem@davemloft.net
> Subject: RE: [Intel-wired-lan] [PATCH v4 net-next 6/8] ice: implement CPI
> support for E825C
>
>
>
> > -----Original Message-----
> > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> > Of Grzegorz Nitka
> > Sent: Thursday, March 26, 2026 5:29 PM
> > To: netdev@vger.kernel.org
> > Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> > kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> > Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> > donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> > Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> > intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> > Prathosh.Satish@microchip.com; Nguyen, Anthony L
> > <anthony.l.nguyen@intel.com>; pabeni@redhat.com;
> davem@davemloft.net
> > Subject: [Intel-wired-lan] [PATCH v4 net-next 6/8] ice: implement
> > CPI support for E825C
> >
> > Add full CPI (Converged PHY Interface) command handling required for
> > E825C devices. The CPI interface allows the driver to interact with
> > PHY-side control logic through the LM/PHY command registers,
> > including enabling/disabling/selection of PHY reference clock.
> >
> > This patch introduces:
> > - a new CPI subsystem (ice_cpi.c / ice_cpi.h) implementing the CPI
> > request/acknowledge state machine, including REQ/ACK protocol,
> > command execution, and response handling
> > - helper functions for reading/writing PHY registers over Sideband
> > Queue
> > - CPI command execution API (ice_cpi_exec) and a helper for
> > enabling or
> > disabling Tx reference clocks (CPI 0xF1 opcode 'Config PHY
> > clocking')
> > - addition of the non-posted write opcode (wr_np) to SBQ
> > - Makefile integration to build CPI support together with the PTP
> > stack
> >
> > This provides the infrastructure necessary to support PHY-side
> > configuration flows on E825C and is required for advanced link
> > control and Tx reference clock management.
> >
> > Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> > Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> > ---
> > drivers/net/ethernet/intel/ice/Makefile | 2 +-
> > drivers/net/ethernet/intel/ice/ice_cpi.c | 347
> > +++++++++++++++++++
> > drivers/net/ethernet/intel/ice/ice_cpi.h | 69 ++++
> > drivers/net/ethernet/intel/ice/ice_sbq_cmd.h | 5 +-
> > 4 files changed, 420 insertions(+), 3 deletions(-) create mode
> > 100644 drivers/net/ethernet/intel/ice/ice_cpi.c
> > create mode 100644 drivers/net/ethernet/intel/ice/ice_cpi.h
> >
> > diff --git a/drivers/net/ethernet/intel/ice/Makefile
> > b/drivers/net/ethernet/intel/ice/Makefile
> > index 5b2c666496e7..38db476ab2ec 100644
> > --- a/drivers/net/ethernet/intel/ice/Makefile
> > +++ b/drivers/net/ethernet/intel/ice/Makefile
> > @@ -54,7 +54,7 @@ ice-$(CONFIG_PCI_IOV) += \
> > ice_vf_mbx.o \
> > ice_vf_vsi_vlan_ops.o \
> > ice_vf_lib.o
>
> ...
>
> > +
> > +union cpi_reg_phy_cmd_data {
> > + struct {
> > + u16 data;
> > + u16 opcode : 8;
> > + u16 portlane : 3;
> > + u16 reserved_13_11: 3;
> > + u16 error : 1;
> > + u16 ack : 1;
> > + } __packed field;
> > + u32 val;
> > +};
> Why not use FIELD_GET()/FIELD_PREP() with GENMASK()? Bitfields are
> compiled differently on LE nd BE CPUs.
>
Thanks for your comment.
To be addressed in the next iteration.
Regards
Grzegorz
> > +
> > +union cpi_reg_lm_cmd_data {
> > + struct {
> > + u16 data;
> > + u16 opcode : 8;
> > + u16 portlane : 3;
> > + u16 reserved_12_11: 2;
> > + u16 get_set : 1;
> > + u16 cpi_reset : 1;
> > + u16 cpi_req : 1;
> > + } __packed field;
> > + u32 val;
> > +};
> Why not use FIELD_GET()/FIELD_PREP() with GENMASK()? Bitfields are
> compiled differently on LE nd BE CPUs.
>
>
> ...
>
> >
> > #define ICE_SBQ_MSG_FLAGS 0x40
> > --
> > 2.39.3
^ permalink raw reply
* [PATCH net-next v2 0/3] net: pse-pd: support module-based PSE controller drivers
From: Carlo Szelinsky @ 2026-03-30 13:29 UTC (permalink / raw)
To: Kory Maincent, Oleksij Rempel, Andrew Lunn
Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
Carlo Szelinsky
In-Reply-To: <20260329161014.2908509-1-github@szelinsky.de>
When a PSE controller driver is built as a module, it may not be probed
yet when PHYs are registered on the MDIO bus. This causes
of_pse_control_get() to return -EPROBE_DEFER, destroying the PHY device.
Later, regulator_late_cleanup disables the unclaimed PSE regulators,
permanently killing PoE.
This series fixes the issue in three steps:
1. Add an admin_state_synced flag to pse_pi so that pse_pi_is_enabled()
reports unclaimed PIs as disabled, preventing regulator_late_cleanup
from shutting them down. The existing dual-path behavior (software-
tracked vs. hardware-queried state) is preserved for claimed PIs.
2. Add pse_control_try_resolve() for lazy PSE control resolution on
first ethtool access, serialized by RTNL.
3. Treat -EPROBE_DEFER as non-fatal during PHY registration, allowing
the PHY to register with psec=NULL. This is ordered last because it
changes probe behavior and relies on patches 1 and 2 for correct
lazy resolution.
Thanks to Kory Maincent for the review and feedback on v1.
Changes in v2:
- Reordered patches: moved the EPROBE_DEFER patch last since it
changes probe behavior and depends on the other two patches for
correct lazy resolution (Kory Maincent)
- Added net-next to subject prefix (Kory Maincent)
- Collected Acked-by tags
Carlo Szelinsky (3):
net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE
PIs
net: pse-pd: add lazy PSE control resolution for modular drivers
net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
drivers/net/mdio/fwnode_mdio.c | 8 ++++--
drivers/net/pse-pd/pse_core.c | 49 ++++++++++++++++++++++++++++++++++
include/linux/pse-pd/pse.h | 6 +++++
net/ethtool/pse-pd.c | 4 +++
4 files changed, 65 insertions(+), 2 deletions(-)
base-commit: cf0d9080c6f795bc6be08babbffa29b62c06e9b0
--
2.43.0
^ permalink raw reply
* [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs
From: Carlo Szelinsky @ 2026-03-30 13:29 UTC (permalink / raw)
To: Kory Maincent, Oleksij Rempel, Andrew Lunn
Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
Carlo Szelinsky
In-Reply-To: <20260330132952.2950531-1-github@szelinsky.de>
When a PSE controller driver is loaded as a module, its PI regulators
are registered before any consumer (PHY) acquires the corresponding PSE
control via of_pse_control_get(). The regulator framework's
regulator_late_cleanup then calls pse_pi_is_enabled(), which queries
hardware and sees the PI is enabled. Since no consumer holds it
(use_count == 0), regulator_late_cleanup disables it, killing PoE.
Add an admin_state_synced flag to struct pse_pi that is set when a
consumer first acquires the PSE control and syncs admin_state_enabled
from hardware. In pse_pi_is_enabled(), report unsynchronized PIs as
disabled so regulator_late_cleanup skips them.
This preserves the existing dual-path behavior: software-tracked state
for software-controlled power domains, and hardware queries for
hardware-controlled domains. The admin_state_synced flag is only false
before the first consumer acquisition, which is the exact window where
regulator_late_cleanup could incorrectly disable the PI.
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Acked-by: Kory Maincent <kory.maincent@bootlin.com>
---
drivers/net/pse-pd/pse_core.c | 13 +++++++++++++
include/linux/pse-pd/pse.h | 1 +
2 files changed, 14 insertions(+)
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 3beaaaeec9e1..566b07c336bf 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -421,6 +421,18 @@ static int pse_pi_is_enabled(struct regulator_dev *rdev)
id = rdev_get_id(rdev);
mutex_lock(&pcdev->lock);
+
+ /*
+ * Report the PI as disabled until a consumer has acquired it
+ * and synced admin_state_enabled from hardware. This prevents
+ * regulator_late_cleanup from disabling unclaimed PSE PIs
+ * when the PSE controller driver loads as a module.
+ */
+ if (!pcdev->pi[id].admin_state_synced) {
+ ret = 0;
+ goto out;
+ }
+
if (pse_pw_d_is_sw_pw_control(pcdev, pcdev->pi[id].pw_d)) {
ret = pcdev->pi[id].admin_state_enabled;
goto out;
@@ -1431,6 +1443,7 @@ pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index,
goto free_psec;
pcdev->pi[index].admin_state_enabled = ret;
+ pcdev->pi[index].admin_state_synced = true;
psec->ps = devm_regulator_get_exclusive(pcdev->dev,
rdev_get_name(pcdev->pi[index].rdev));
if (IS_ERR(psec->ps)) {
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 4e5696cfade7..b86cce740551 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -260,6 +260,7 @@ struct pse_pi {
struct device_node *np;
struct regulator_dev *rdev;
bool admin_state_enabled;
+ bool admin_state_synced;
struct pse_power_domain *pw_d;
int prio;
bool isr_pd_detected;
--
2.43.0
^ permalink raw reply related
* RE: [Intel-wired-lan] [PATCH v4 net-next 8/8] ice: add TX reference clock (tx_clk) control for E825 devices
From: Nitka, Grzegorz @ 2026-03-30 13:30 UTC (permalink / raw)
To: Loktionov, Aleksandr, netdev@vger.kernel.org
Cc: Vecera, Ivan, vadim.fedorenko@linux.dev, kuba@kernel.org,
jiri@resnulli.us, edumazet@google.com, Kitszel, Przemyslaw,
richardcochran@gmail.com, donald.hunter@gmail.com,
linux-kernel@vger.kernel.org, Kubalewski, Arkadiusz,
andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org,
horms@kernel.org, Prathosh.Satish@microchip.com,
Nguyen, Anthony L, pabeni@redhat.com, davem@davemloft.net
In-Reply-To: <IA3PR11MB898696725A05CA82FA6ED1FEE557A@IA3PR11MB8986.namprd11.prod.outlook.com>
> -----Original Message-----
> From: Loktionov, Aleksandr <aleksandr.loktionov@intel.com>
> Sent: Friday, March 27, 2026 12:46 PM
> To: Nitka, Grzegorz <grzegorz.nitka@intel.com>; netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> Prathosh.Satish@microchip.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; pabeni@redhat.com;
> davem@davemloft.net
> Subject: RE: [Intel-wired-lan] [PATCH v4 net-next 8/8] ice: add TX reference
> clock (tx_clk) control for E825 devices
>
>
>
> > -----Original Message-----
> > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> > Of Grzegorz Nitka
> > Sent: Thursday, March 26, 2026 5:29 PM
> > To: netdev@vger.kernel.org
> > Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> > kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> > Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> > donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> > Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> > intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> > Prathosh.Satish@microchip.com; Nguyen, Anthony L
> > <anthony.l.nguyen@intel.com>; pabeni@redhat.com;
> davem@davemloft.net
> > Subject: [Intel-wired-lan] [PATCH v4 net-next 8/8] ice: add TX
> > reference clock (tx_clk) control for E825 devices
> >
> > Add full support for selecting and controlling the TX SERDES
> > reference clock on E825C hardware. E825C devicede supports selecting
> > among multiple SERDES transmit reference clock sources (ENET, SyncE,
> > EREF0), but imposes several routing constraints: on some paths a
> > reference must be enabled on both PHY complexes, and ports sharing a
> > PHY must coordinate usage so that a reference is not disabled while
> > still in active use. Until now the driver did not expose this domain
> > through the DPLL API, nor did it provide a coherent control layer
> > for enabling, switching, or tracking TX reference clocks.
> >
> > This patch implements full TX reference clock management for E825
> > devices. Compared to previous iterations, the logic is now separated
> > into a dedicated module (ice_txclk.c) which encapsulates all clock-
> > selection rules, cross‑PHY dependencies, and the bookkeeping needed
> > to ensure safe transitions. This allows the DPLL layer and the PTP
> > code to remain focused on their respective roles.
> >
> > Key additions:
> >
> > * A new txclk control module (`ice_txclk.c`) implementing:
> > - software usage tracking for each reference clock per PHY,
> > - peer‑PHY enable rules (SyncE required on both PHYs when used
> > on
> > PHY0, EREF0 required on both when used on PHY1),
> > - safe disabling of unused reference clocks after switching,
> > - a single, driver‑internal entry point for clock changes.
> >
> > * Integration with the DPLL pin ops:
> > - pin‑set now calls into `ice_txclk_set_clk()` to request a
> > hardware switch,
> > - pin‑get reports the current SERDES reference by reading back
> > the
> > active selector (`ice_get_serdes_ref_sel_e825c()`).
> >
> > * Wiring the requested reference clock into Auto‑Negotiation
> > restart
> > through the already‑extended `ice_aq_set_link_restart_an()`.
> >
> > * After each link-up the driver verifies the effective hardware
> > state
> > (`ice_txclk_verify()`) and updates its per‑PHY usage bitmaps,
> > correcting the requested/active state if the FW or AN flow
> > applied a
> > different reference.
> >
> > * PTP PF initialization now seeds the ENET reference clock as
> > enabled
> > by default for its port.
> >
> > All reference clock transitions are serialized through the DPLL
> > lock, and usage information is shared across all PFs belonging to
> > the same E825C controller PF. This ensures that concurrent changes
> > are coordinated and that shared PHYs never see an unexpected
> > disable.
> >
> > With this patch, E825 devices gain full userspace‑driven TXC
> > reference clock selection via the DPLL subsystem, enabling complete
> > SyncE support, precise multi‑clock setups, and predictable clock
> > routing behavior.
> >
> > Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> > Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> > ---
> > drivers/net/ethernet/intel/ice/Makefile | 2 +-
> > drivers/net/ethernet/intel/ice/ice.h | 12 +
> > drivers/net/ethernet/intel/ice/ice_dpll.c | 53 +++-
> > drivers/net/ethernet/intel/ice/ice_ptp.c | 27 ++-
> > drivers/net/ethernet/intel/ice/ice_ptp.h | 7 +
> > drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 37 +++
> > drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 27 +++
> > drivers/net/ethernet/intel/ice/ice_txclk.c | 256
> > ++++++++++++++++++++ drivers/net/ethernet/intel/ice/ice_txclk.h |
> > 41 ++++
> > 9 files changed, 445 insertions(+), 17 deletions(-) create mode
> > 100644 drivers/net/ethernet/intel/ice/ice_txclk.c
> > create mode 100644 drivers/net/ethernet/intel/ice/ice_txclk.h
> >
> > diff --git a/drivers/net/ethernet/intel/ice/Makefile
> > b/drivers/net/ethernet/intel/ice/Makefile
> > index 38db476ab2ec..95fd0c49800f 100644
> > --- a/drivers/net/ethernet/intel/ice/Makefile
> > +++ b/drivers/net/ethernet/intel/ice/Makefile
> > @@ -54,7 +54,7 @@ ice-$(CONFIG_PCI_IOV) += \
> > ice_vf_mbx.o \
> > ice_vf_vsi_vlan_ops.o \
> > ice_vf_lib.o
> > -ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o ice_dpll.o
> > ice_tspll.o ice_cpi.o
>
> ...
>
> > static const struct dpll_pin_ops ice_dpll_rclk_ops = { diff --git
> > a/drivers/net/ethernet/intel/ice/ice_ptp.c
> > b/drivers/net/ethernet/intel/ice/ice_ptp.c
> > index 094e96219f45..a75a1380097b 100644
> > --- a/drivers/net/ethernet/intel/ice/ice_ptp.c
> > +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
> > @@ -4,6 +4,7 @@
> > #include "ice.h"
> > #include "ice_lib.h"
> > #include "ice_trace.h"
> > +#include "ice_txclk.h"
> >
> > static const char ice_pin_names[][64] = {
> > "SDP0",
> > @@ -54,11 +55,6 @@ static const struct ice_ptp_pin_desc
> > ice_pin_desc_dpll[] = {
> > { SDP3, { 3, -1 }, { 0, 0 }},
> > };
> >
> > -static struct ice_pf *ice_get_ctrl_pf(struct ice_pf *pf) -{
> > - return !pf->adapter ? NULL : pf->adapter->ctrl_pf;
> > -}
> > -
> > static struct ice_ptp *ice_get_ctrl_ptp(struct ice_pf *pf) {
> > struct ice_pf *ctrl_pf = ice_get_ctrl_pf(pf); @@ -1325,6
> > +1321,10 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
> > return;
> > }
> > }
> > +
> > + if (linkup)
> > + ice_txclk_verify(pf);
> msleep() under mutex smels badly... /* ice_cpi_wait_req0_ack0() and
> ice_cpi_wait_ack() */
> pf->dplls.lock can be held ~2seconds blocking ice_dpll_periodic_work().
> Can CPI handshake happen outside the lock?
>
Agree. This is not a good practice.
I realized it also applies to DPLL 'tx-clk' interface knobs.
I will modify it with some worker approach in the next iteration.
Regards
Grzegorz
> > +
> > mutex_unlock(&pf->dplls.lock);
> > }
> >
>
> ...
>
> > */
> > --
> > 2.39.3
^ permalink raw reply
* [PATCH net-next v2 2/3] net: pse-pd: add lazy PSE control resolution for modular drivers
From: Carlo Szelinsky @ 2026-03-30 13:29 UTC (permalink / raw)
To: Kory Maincent, Oleksij Rempel, Andrew Lunn
Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
Carlo Szelinsky
In-Reply-To: <20260330132952.2950531-1-github@szelinsky.de>
When a PSE controller driver is built as a module and was not probed
during PHY registration, the PHY ends up with psec=NULL. Add
pse_control_try_resolve() to lazily resolve the PSE control on first
ethtool access.
Call pse_control_try_resolve() in both the GET and SET ethtool PSE
handlers, before checking phydev->psec. The function is serialized by
RTNL (enforced via ASSERT_RTNL), preventing concurrent callers from
double-allocating a PSE control.
If resolution fails (e.g. the module still has not loaded), a debug
message is emitted via phydev_dbg() and the handler falls through to
the existing "No PSE is attached" error path.
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Acked-by: Kory Maincent <kory.maincent@bootlin.com>
---
drivers/net/pse-pd/pse_core.c | 36 +++++++++++++++++++++++++++++++++++
include/linux/pse-pd/pse.h | 5 +++++
net/ethtool/pse-pd.c | 4 ++++
3 files changed, 45 insertions(+)
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 566b07c336bf..390df23a991c 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -1569,6 +1569,42 @@ struct pse_control *of_pse_control_get(struct device_node *node,
}
EXPORT_SYMBOL_GPL(of_pse_control_get);
+/**
+ * pse_control_try_resolve - attempt to resolve a deferred PSE control
+ * @phydev: the PHY device whose PSE control may need resolution
+ *
+ * When a PSE controller driver is built as a module, it may not have
+ * probed when PHYs were registered on the MDIO bus. This function
+ * retries PSE control acquisition and should be called before
+ * accessing phydev->psec in ethtool handlers.
+ *
+ * Context: Caller must hold RTNL.
+ */
+void pse_control_try_resolve(struct phy_device *phydev)
+{
+ struct device_node *np;
+ struct pse_control *psec;
+
+ ASSERT_RTNL();
+
+ if (phydev->psec)
+ return;
+
+ np = phydev->mdio.dev.of_node;
+ if (!np || !of_property_present(np, "pses"))
+ return;
+
+ psec = of_pse_control_get(np, phydev);
+ if (IS_ERR(psec)) {
+ phydev_dbg(phydev, "failed to resolve PSE control: %pe\n",
+ psec);
+ return;
+ }
+
+ phydev->psec = psec;
+}
+EXPORT_SYMBOL_GPL(pse_control_try_resolve);
+
/**
* pse_get_sw_admin_state - Convert the software admin state to c33 or podl
* admin state value used in the standard
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index b86cce740551..d2f9b7c1acdf 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -350,6 +350,7 @@ int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
struct pse_control *of_pse_control_get(struct device_node *node,
struct phy_device *phydev);
void pse_control_put(struct pse_control *psec);
+void pse_control_try_resolve(struct phy_device *phydev);
int pse_ethtool_get_status(struct pse_control *psec,
struct netlink_ext_ack *extack,
@@ -379,6 +380,10 @@ static inline void pse_control_put(struct pse_control *psec)
{
}
+static inline void pse_control_try_resolve(struct phy_device *phydev)
+{
+}
+
static inline int pse_ethtool_get_status(struct pse_control *psec,
struct netlink_ext_ack *extack,
struct ethtool_pse_control_status *status)
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index 2eb9bdc2dcb9..adffc230acd6 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -42,6 +42,8 @@ static int pse_get_pse_attributes(struct phy_device *phydev,
return -EOPNOTSUPP;
}
+ pse_control_try_resolve(phydev);
+
if (!phydev->psec) {
NL_SET_ERR_MSG(extack, "No PSE is attached");
return -EOPNOTSUPP;
@@ -249,6 +251,8 @@ ethnl_set_pse_validate(struct phy_device *phydev, struct genl_info *info)
return -EOPNOTSUPP;
}
+ pse_control_try_resolve(phydev);
+
if (!phydev->psec) {
NL_SET_ERR_MSG(info->extack, "No PSE is attached");
return -EOPNOTSUPP;
--
2.43.0
^ permalink raw reply related
* [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
From: Carlo Szelinsky @ 2026-03-30 13:29 UTC (permalink / raw)
To: Kory Maincent, Oleksij Rempel, Andrew Lunn
Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
Carlo Szelinsky
In-Reply-To: <20260330132952.2950531-1-github@szelinsky.de>
When a PSE controller driver is built as a module, it may not be probed
yet when PHYs are registered on the MDIO bus. This causes
fwnode_find_pse_control() -> of_pse_control_get() to return
-EPROBE_DEFER, which currently propagates up and destroys the PHY
device.
Treat -EPROBE_DEFER as non-fatal, allowing the PHY to register
successfully with psec=NULL. The PSE control can be resolved lazily
when first needed.
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Acked-by: Kory Maincent <kory.maincent@bootlin.com>
---
drivers/net/mdio/fwnode_mdio.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
index ba7091518265..2a03b3fc41e6 100644
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -161,8 +161,12 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
psec = fwnode_find_pse_control(child, phy);
if (IS_ERR(psec)) {
- rc = PTR_ERR(psec);
- goto unregister_phy;
+ if (PTR_ERR(psec) == -EPROBE_DEFER) {
+ psec = NULL;
+ } else {
+ rc = PTR_ERR(psec);
+ goto unregister_phy;
+ }
}
phy->psec = psec;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] netfilter: ctnetlink: validate expect class against master helper
From: Qi Tang @ 2026-03-30 13:32 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Florian Westphal, Phil Sutter, netfilter-devel, coreteam, netdev,
Qi Tang
In-Reply-To: <acpkPEJRvzeY863Y@chamomile>
On Mon, Mar 30, 2026 at 01:52:36PM +0200, Pablo Neira Ayuso wrote:
> Better to ignore the helper name proposed by userspace when creating
> the expectation.
>
> The master conntrack must already has a helper, and such helper must
> be the same that is specified here.
Agreed, your approach is much cleaner -- removing the separate helper
lookup entirely eliminates the mismatch class rather than just
patching the validation side.
Thanks for the quick fix!
Qi Tang
^ permalink raw reply
* Re: [PATCH] net/sched: skip reverse bind walk after failed class delete
From: Qi Tang @ 2026-03-30 13:40 UTC (permalink / raw)
To: Jamal Hadi Salim; +Cc: Jiri Pirko, netdev, Qi Tang
In-Reply-To: <CAM0EoMmVey4ayJBZgogMO4S3Z-_n5oDfasdZyiVryEqCNqu6bw@mail.gmail.com>
On Mon, Mar 30, 2026, Jamal Hadi Salim wrote:
> Try these patches:
> https://lore.kernel.org/netdev/CAM0EoMmVey4ayJBZgogMO4S3Z-_n5oDfasdZyiVryEqCNqu6bw@mail.gmail.com/T/#t
>
> Same for your other issue.
Thanks for the pointer, Jamal. Please disregard my two net/sched
patches.
Qi Tang
^ permalink raw reply
* Re: [PATCH bpf-next v2 1/2] net: clear the dst when performing encap / decap
From: Willem de Bruijn @ 2026-03-30 13:42 UTC (permalink / raw)
To: Jakub Kicinski, bpf
Cc: netdev, davem, edumazet, pabeni, andrew+netdev, horms,
Jakub Kicinski, maze, willemdebruijn.kernel, ast, daniel, andrii,
martin.lau, eddyz87, song, yonghong.song, john.fastabend, kpsingh,
sdf, haoluo, jolsa
In-Reply-To: <20260329180428.2657785-1-kuba@kernel.org>
Jakub Kicinski wrote:
> Commit ba9db6f907ac ("net: clear the dst when changing skb protocol")
> added dst clearing when a BPF program changes the skb protocol
> (e.g. IPv4 to IPv6). Since that was a fix we only cleared the dst when
> the L3 protocol actually changes to keep it minimal. As suggested during
> the discussion (see Link) encap or decap operation which wraps or unwraps
> a same-protocol header may also render the existing dst incorrect - even
> if that doesn't result in a crash, just the wrong route for the now-outermost
> IP dst.
>
> Make dropping dst unconditional for bpf_skb_change_proto() and all
> L3 encap / decap ops.
>
> Link: https://lore.kernel.org/CANP3RGfRaYwve_xgxH6Tp2zenzKn2-DjZ9tg023WVzfdJF3p_w@mail.gmail.com
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
^ permalink raw reply
* [PATCH net-next 0/3] Add OATC10 Sleep Wake-up support and LAN867x Rev.D0 handling
From: Parthiban Veerasooran @ 2026-03-30 13:42 UTC (permalink / raw)
To: parthiban.veerasooran, piergiorgio.beruto, andrew, hkallweit1,
linux, davem, edumazet, kuba, pabeni, steve.glendinning,
UNGLinuxDriver
Cc: netdev, linux-usb
This patch series adds support for 10BASE‑T1S Open Alliance TC10 (OATC10)
Sleep/Wake‑up to the generic Clause 45 PHY layer and integrates it with
the Microchip LAN867x Rev.D0 T1S PHY driver. It also ensures that PHY
suspend is properly invoked from the smsc95xx USB Ethernet driver so that
low‑power states are entered during system suspend.
Patch Summary:
1. add generic OATC10 suspend/resume helpers
- Add TC10 Sleep/Wake‑up MDIO register definitions
- Implement genphy_c45_oatc10_suspend() and genphy_c45_oatc10_resume()
- Cache PLCA configuration in struct phy_device for restore after wake
2. add LAN867x Rev.D0 TC10 suspend and Wake‑on‑PHY support
- Enable TC10 low‑power entry via generic helpers
- Restore configuration correctly on resume
- Add ethtool WoL support using PHY wake‑up pulse (WUP)
- Mark driver with PHY_ALWAYS_CALL_SUSPEND
3. suspend attached PHY on system suspend
- Call phy_suspend() before USB suspend
- Allows TC10‑capable PHYs to enter low‑power state
Testing:
Tested on EVB-LAN8670-USB Rev.D0 with suspend/resume cycles and verified:
- PLCA configuration is preserved across low-power transitions.
- Wake-up Pulse triggers proper resume.
- ethtool WOL operations function as expected.
Reference:
Open Alliance TC10 10BASE-T1S Sleep/Wake-up Specification:
https://opensig.org/wp-content/uploads/2024/01/TC14_TC10_JWG_10BASE-T1S-Sleep-Wake-up-Specification_1.0_final.pdf
Parthiban Veerasooran (3):
net: phy: phy-c45: add OATC10 Sleep/Wakeup support in 10BASE-T1S PHYs
net: phy: microchip_t1s: add suspend and WOL support for LAN867x
Rev.D0
net: usb: smsc95xx: suspend PHY during USB suspend
drivers/net/phy/mdio-open-alliance.h | 13 ++++
drivers/net/phy/microchip_t1s.c | 67 ++++++++++++++++++++-
drivers/net/phy/phy-c45.c | 82 ++++++++++++++++++++++++++
drivers/net/usb/smsc95xx.c | 6 ++
include/linux/phy.h | 88 +++++++++++++++-------------
5 files changed, 211 insertions(+), 45 deletions(-)
base-commit: cf0d9080c6f795bc6be08babbffa29b62c06e9b0
--
2.34.1
^ permalink raw reply
* [PATCH net-next 1/3] net: phy: phy-c45: add OATC10 Sleep/Wakeup support in 10BASE-T1S PHYs
From: Parthiban Veerasooran @ 2026-03-30 13:42 UTC (permalink / raw)
To: parthiban.veerasooran, piergiorgio.beruto, andrew, hkallweit1,
linux, davem, edumazet, kuba, pabeni, steve.glendinning,
UNGLinuxDriver
Cc: netdev, linux-usb
In-Reply-To: <20260330134222.67597-1-parthiban.veerasooran@microchip.com>
Add generic Clause 45 helpers to support the Open Alliance TC10
10BASE-T1S Sleep/Wake-up specification. This patch introduces
register definitions for the TC10 sleep/wake status and control
registers and adds generic suspend/resume helpers for
OATC10-compliant PHYs.
The new genphy_c45_oatc10_suspend() helper verifies low-power
capability, caches the current PLCA configuration, and requests entry
into the low-power sleep state. Since all PHY configuration is lost
while sleeping, the PLCA configuration is stored in the phy_device
structure for restoration after wake-up.
The corresponding genphy_c45_oatc10_resume() helper reinitializes the
PHY after wake-up and restores the cached PLCA configuration using
driver callbacks.
Additionally, the PLCA configuration structure is moved into
struct phy_device to allow persistent storage across suspend/resume
cycles.
These helpers allow PHY drivers for TC10 10BASE-T1S devices to
implement sleep and wake-up handling in a consistent way without
duplicating common logic.
Open Alliance TC10 10BASE-T1S Sleep/Wake-up Specification ref:
https://opensig.org/wp-content/uploads/2024/01/TC14_TC10_JWG_10BASE-T1S-Sleep-Wake-up-Specification_1.0_final.pdf
Signed-off-by: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
---
drivers/net/phy/mdio-open-alliance.h | 13 ++++
drivers/net/phy/phy-c45.c | 82 ++++++++++++++++++++++++++
include/linux/phy.h | 88 +++++++++++++++-------------
3 files changed, 141 insertions(+), 42 deletions(-)
diff --git a/drivers/net/phy/mdio-open-alliance.h b/drivers/net/phy/mdio-open-alliance.h
index 449d0fb67093..62946be9fb78 100644
--- a/drivers/net/phy/mdio-open-alliance.h
+++ b/drivers/net/phy/mdio-open-alliance.h
@@ -78,6 +78,19 @@
/* SQI is supported using 3 bits means 8 levels (0-7) */
#define OATC14_SQI_MAX_LEVEL 7
+/* Open Alliance 10BASE-T1S Sleep/Wake-up Registers
+ * Specification:
+ * "10BASE-T1S Sleep/Wake-up Specification"
+ * https://opensig.org/wp-content/uploads/2024/01/TC14_TC10_JWG_10BASE-T1S-Sleep-Wake-up-Specification_1.0_final.pdf
+ */
+/* Sleep/Wake-up Status Register */
+#define MDIO_OATC10_WS_STATUS 0xd000
+#define OATC10_WS_STATUS_LPCAP BIT(15) /* PM client capability */
+
+/* Sleep/Wake-up Control Register */
+#define MDIO_OATC10_WS_CONTROL 0xd001
+#define OATC10_WS_CONTROL_LPREQ BIT(15) /* Request low power */
+
/* Bus Short/Open Status:
* 0 0 - no fault; everything is ok. (Default)
* 0 1 - detected as an open or missing termination(s)
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index d48aa7231b37..627eaae9e60f 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -1832,3 +1832,85 @@ int genphy_c45_oatc14_get_sqi(struct phy_device *phydev)
return ret & OATC14_DCQ_SQI_VALUE;
}
EXPORT_SYMBOL(genphy_c45_oatc14_get_sqi);
+
+/**
+ * genphy_c45_oatc10_suspend - Suspend OATC10 PHY into low power state
+ * @phydev: PHY device to suspend
+ *
+ * Puts an OATC10 PHY into low power sleep state.
+ *
+ * The function performs the following steps:
+ * 1. Verify low power capability is supported
+ * 2. Cache current PLCA configuration for restoration on wake
+ * 3. Set the low power request bit to enter sleep state
+ *
+ * Return:
+ * * 0 on successful entry to low power state
+ * * -EOPNOTSUPP if PHY doesn't support low power capability
+ * * Negative error code on register read/write failures
+ */
+int genphy_c45_oatc10_suspend(struct phy_device *phydev)
+{
+ int ret;
+
+ /* Check for Low Power capability */
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC10_WS_STATUS);
+ if (ret < 0)
+ return ret;
+
+ if (!(ret & OATC10_WS_STATUS_LPCAP))
+ return -EOPNOTSUPP;
+
+ /* Cache PLCA settings for later use. These values must be restored when
+ * the PHY wakes up from the low-power sleep state, as all configured
+ * settings are lost.
+ */
+ ret = genphy_c45_plca_get_cfg(phydev, &phydev->plca_cfg);
+ if (ret)
+ return ret;
+
+ phydev->plca_cfg.version = -1;
+
+ if (phydev->state == PHY_UP)
+ /* Put the PHY into low power sleep state */
+ return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
+ MDIO_OATC10_WS_CONTROL,
+ OATC10_WS_CONTROL_LPREQ);
+
+ return 0;
+}
+EXPORT_SYMBOL(genphy_c45_oatc10_suspend);
+
+/**
+ * genphy_c45_oatc10_resume - Resume OATC10 PHY from low-power sleep state
+ * @phydev: PHY device to resume
+ *
+ * Resume a PHY from suspend state. When the PHY wakes up from the low-power
+ * sleep state, all configured settings are lost. This function reinitializes
+ * the PHY configuration settings.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int genphy_c45_oatc10_resume(struct phy_device *phydev)
+{
+ int ret;
+
+ if (!phydev->suspended)
+ return 0;
+
+ /* When the PHY wakes up from the low-power sleep state, it needs to be
+ * reinitialized as all configured settings are lost.
+ */
+ if (phydev->drv->config_init) {
+ ret = phydev->drv->config_init(phydev);
+ if (ret)
+ return ret;
+ }
+
+ /* Reconfigure the PHY with cached PLCA settings */
+ if (phydev->drv->set_plca_cfg)
+ return phydev->drv->set_plca_cfg(phydev, &phydev->plca_cfg);
+
+ return 0;
+}
+EXPORT_SYMBOL(genphy_c45_oatc10_resume);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 5de4b172cd0b..9bee520ac421 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -555,6 +555,48 @@ struct phy_oatc14_sqi_capability {
u8 sqiplus_bits;
};
+/**
+ * struct phy_plca_cfg - Configuration of the PLCA (Physical Layer Collision
+ * Avoidance) Reconciliation Sublayer.
+ *
+ * @version: read-only PLCA register map version. -1 = not available. Ignored
+ * when setting the configuration. Format is the same as reported by the PLCA
+ * IDVER register (31.CA00). -1 = not available.
+ * @enabled: PLCA configured mode (enabled/disabled). -1 = not available / don't
+ * set. 0 = disabled, anything else = enabled.
+ * @node_id: the PLCA local node identifier. -1 = not available / don't set.
+ * Allowed values [0 .. 254]. 255 = node disabled.
+ * @node_cnt: the PLCA node count (maximum number of nodes having a TO). Only
+ * meaningful for the coordinator (node_id = 0). -1 = not available / don't
+ * set. Allowed values [1 .. 255].
+ * @to_tmr: The value of the PLCA to_timer in bit-times, which determines the
+ * PLCA transmit opportunity window opening. See IEEE802.3 Clause 148 for
+ * more details. The to_timer shall be set equal over all nodes.
+ * -1 = not available / don't set. Allowed values [0 .. 255].
+ * @burst_cnt: controls how many additional frames a node is allowed to send in
+ * single transmit opportunity (TO). The default value of 0 means that the
+ * node is allowed exactly one frame per TO. A value of 1 allows two frames
+ * per TO, and so on. -1 = not available / don't set.
+ * Allowed values [0 .. 255].
+ * @burst_tmr: controls how many bit times to wait for the MAC to send a new
+ * frame before interrupting the burst. This value should be set to a value
+ * greater than the MAC inter-packet gap (which is typically 96 bits).
+ * -1 = not available / don't set. Allowed values [0 .. 255].
+ *
+ * A structure containing configuration parameters for setting/getting the PLCA
+ * RS configuration. The driver does not need to implement all the parameters,
+ * but should report what is actually used.
+ */
+struct phy_plca_cfg {
+ int version;
+ int enabled;
+ int node_id;
+ int node_cnt;
+ int to_tmr;
+ int burst_cnt;
+ int burst_tmr;
+};
+
/**
* struct phy_device - An instance of a PHY
*
@@ -655,6 +697,7 @@ struct phy_oatc14_sqi_capability {
* @shared: Pointer to private data shared by phys in one package
* @priv: Pointer to driver private data
* @oatc14_sqi_capability: SQI capability information for OATC14 10Base-T1S PHY
+ * @plca_cfg: Cache PLCA configuration for OATC10 compliance 10Base-T1S PHY
*
* interrupts currently only supports enabled or disabled,
* but could be changed in the future to support enabling
@@ -807,6 +850,7 @@ struct phy_device {
#endif
struct phy_oatc14_sqi_capability oatc14_sqi_capability;
+ struct phy_plca_cfg plca_cfg;
};
/* Generic phy_device::dev_flags */
@@ -858,48 +902,6 @@ enum link_inband_signalling {
LINK_INBAND_BYPASS = BIT(2),
};
-/**
- * struct phy_plca_cfg - Configuration of the PLCA (Physical Layer Collision
- * Avoidance) Reconciliation Sublayer.
- *
- * @version: read-only PLCA register map version. -1 = not available. Ignored
- * when setting the configuration. Format is the same as reported by the PLCA
- * IDVER register (31.CA00). -1 = not available.
- * @enabled: PLCA configured mode (enabled/disabled). -1 = not available / don't
- * set. 0 = disabled, anything else = enabled.
- * @node_id: the PLCA local node identifier. -1 = not available / don't set.
- * Allowed values [0 .. 254]. 255 = node disabled.
- * @node_cnt: the PLCA node count (maximum number of nodes having a TO). Only
- * meaningful for the coordinator (node_id = 0). -1 = not available / don't
- * set. Allowed values [1 .. 255].
- * @to_tmr: The value of the PLCA to_timer in bit-times, which determines the
- * PLCA transmit opportunity window opening. See IEEE802.3 Clause 148 for
- * more details. The to_timer shall be set equal over all nodes.
- * -1 = not available / don't set. Allowed values [0 .. 255].
- * @burst_cnt: controls how many additional frames a node is allowed to send in
- * single transmit opportunity (TO). The default value of 0 means that the
- * node is allowed exactly one frame per TO. A value of 1 allows two frames
- * per TO, and so on. -1 = not available / don't set.
- * Allowed values [0 .. 255].
- * @burst_tmr: controls how many bit times to wait for the MAC to send a new
- * frame before interrupting the burst. This value should be set to a value
- * greater than the MAC inter-packet gap (which is typically 96 bits).
- * -1 = not available / don't set. Allowed values [0 .. 255].
- *
- * A structure containing configuration parameters for setting/getting the PLCA
- * RS configuration. The driver does not need to implement all the parameters,
- * but should report what is actually used.
- */
-struct phy_plca_cfg {
- int version;
- int enabled;
- int node_id;
- int node_cnt;
- int to_tmr;
- int burst_cnt;
- int burst_tmr;
-};
-
/**
* struct phy_plca_status - Status of the PLCA (Physical Layer Collision
* Avoidance) Reconciliation Sublayer.
@@ -2333,6 +2335,8 @@ int genphy_c45_oatc14_cable_test_get_status(struct phy_device *phydev,
bool *finished);
int genphy_c45_oatc14_get_sqi_max(struct phy_device *phydev);
int genphy_c45_oatc14_get_sqi(struct phy_device *phydev);
+int genphy_c45_oatc10_suspend(struct phy_device *phydev);
+int genphy_c45_oatc10_resume(struct phy_device *phydev);
/* The gen10g_* functions are the old Clause 45 stub */
int gen10g_config_aneg(struct phy_device *phydev);
--
2.34.1
^ permalink raw reply related
* [PATCH net-next 3/3] net: usb: smsc95xx: suspend PHY during USB suspend
From: Parthiban Veerasooran @ 2026-03-30 13:42 UTC (permalink / raw)
To: parthiban.veerasooran, piergiorgio.beruto, andrew, hkallweit1,
linux, davem, edumazet, kuba, pabeni, steve.glendinning,
UNGLinuxDriver
Cc: netdev, linux-usb
In-Reply-To: <20260330134222.67597-1-parthiban.veerasooran@microchip.com>
The smsc95xx driver registers a PHY device but does not currently
propagate suspend events to it when the USB interface is suspended.
Call phy_suspend() from the driver's suspend callback so the attached
PHY can properly enter low-power state during system or runtime
suspend. This aligns smsc95xx suspend handling with other network
drivers that manage an external or integrated PHY.
Without this, the PHY may remain active and fail to execute its own
suspend procedure, leading to unnecessary power consumption or
incorrect resume behavior.
This change is also required for the EVB-LAN8670-USB Rev.D0 device to
support OATC10-compliant sleep and wake functionality.
Signed-off-by: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
---
drivers/net/usb/smsc95xx.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 42e4048b574b..3a6e03b7410a 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1550,6 +1550,12 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
pdata->pm_task = current;
+ if (pdata->phydev) {
+ ret = phy_suspend(pdata->phydev);
+ if (ret)
+ return ret;
+ }
+
ret = usbnet_suspend(intf, message);
if (ret < 0) {
netdev_warn(dev->net, "usbnet_suspend error\n");
--
2.34.1
^ permalink raw reply related
* [PATCH net-next 2/3] net: phy: microchip_t1s: add suspend and WOL support for LAN867x Rev.D0
From: Parthiban Veerasooran @ 2026-03-30 13:42 UTC (permalink / raw)
To: parthiban.veerasooran, piergiorgio.beruto, andrew, hkallweit1,
linux, davem, edumazet, kuba, pabeni, steve.glendinning,
UNGLinuxDriver
Cc: netdev, linux-usb
In-Reply-To: <20260330134222.67597-1-parthiban.veerasooran@microchip.com>
The LAN867x Rev.D0 PHY supports OATC10-compliant sleep and wake
functionality, which can be used for system suspend and wake-up via
MDI Wake-up Pulse (WUP).
Add suspend/resume handling and basic Wake-on-LAN support using
WAKE_PHY, enabling WUP as a wake source via the Sleep Control 0
register. The driver configures MDI wake before entering suspend
and reports/enables the wake source through ethtool WOL callbacks.
Also adjust the Rev.D0 configuration path to avoid checking the reset
completion status when resuming from suspend, as the reset status is
only valid after an explicit PHY reset and not after sleep.
This allows LAN867x Rev.D0 systems to reliably wake from suspend via
MDI activity while preserving correct initialization behavior.
Signed-off-by: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
---
drivers/net/phy/microchip_t1s.c | 67 +++++++++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 3 deletions(-)
diff --git a/drivers/net/phy/microchip_t1s.c b/drivers/net/phy/microchip_t1s.c
index e601d56b2507..6b158ae5fb16 100644
--- a/drivers/net/phy/microchip_t1s.c
+++ b/drivers/net/phy/microchip_t1s.c
@@ -38,6 +38,10 @@
#define LINK_STATUS_CONFIGURATION GENMASK(12, 11)
#define LINK_STATUS_SEMAPHORE BIT(0)
+/* Sleep Control 0 Register */
+#define LAN867X_REG_SLEEP_CTRL0 0x0080
+#define SLEEP_CTRL0_MDI_WAKEUP_EN BIT(14)
+
/* Link Status Configuration */
#define LINK_STATUS_CONFIG_PLCA_STATUS 0x1
#define LINK_STATUS_CONFIG_SEMAPHORE 0x2
@@ -472,9 +476,14 @@ static int lan867x_revd0_config_init(struct phy_device *phydev)
{
int ret;
- ret = lan867x_check_reset_complete(phydev);
- if (ret)
- return ret;
+ /* Reset status is only valid after an explicit PHY reset, it is not set
+ * when the PHY resumes from suspend/sleep state.
+ */
+ if (!phydev->suspended) {
+ ret = lan867x_check_reset_complete(phydev);
+ if (ret)
+ return ret;
+ }
for (int i = 0; i < ARRAY_SIZE(lan867x_revd0_fixup_regs); i++) {
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
@@ -491,6 +500,53 @@ static int lan867x_revd0_config_init(struct phy_device *phydev)
return lan867x_revd0_link_active_selection(phydev, false);
}
+static int lan867x_revd0_suspend(struct phy_device *phydev)
+{
+ int ret;
+
+ /* Configure WUP as wake source for system suspend */
+ ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
+ LAN867X_REG_SLEEP_CTRL0,
+ SLEEP_CTRL0_MDI_WAKEUP_EN);
+ if (ret)
+ return ret;
+
+ return genphy_c45_oatc10_suspend(phydev);
+}
+
+static int lan867x_revd0_set_wol(struct phy_device *phydev,
+ struct ethtool_wolinfo *wol)
+{
+ /* Only support WAKE_PHY via WUP (Wake-up Pulse) */
+ if (wol->wolopts & ~WAKE_PHY)
+ return -EOPNOTSUPP;
+
+ if (wol->wolopts & WAKE_PHY) {
+ return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
+ LAN867X_REG_SLEEP_CTRL0,
+ SLEEP_CTRL0_MDI_WAKEUP_EN);
+ } else {
+ /* Disable WUP wake source */
+ return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
+ LAN867X_REG_SLEEP_CTRL0,
+ SLEEP_CTRL0_MDI_WAKEUP_EN);
+ }
+}
+
+static void lan867x_revd0_get_wol(struct phy_device *phydev,
+ struct ethtool_wolinfo *wol)
+{
+ int ret;
+
+ wol->supported = WAKE_PHY;
+ wol->wolopts = 0;
+
+ /* Check if WUP wake source is currently enabled */
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, LAN867X_REG_SLEEP_CTRL0);
+ if (ret >= 0 && (ret & SLEEP_CTRL0_MDI_WAKEUP_EN))
+ wol->wolopts = WAKE_PHY;
+}
+
static int lan86xx_read_status(struct phy_device *phydev)
{
/* The phy has some limitations, namely:
@@ -569,6 +625,7 @@ static struct phy_driver microchip_t1s_driver[] = {
PHY_ID_MATCH_EXACT(PHY_ID_LAN867X_REVD0),
.name = "LAN867X Rev.D0",
.features = PHY_BASIC_T1S_P2MP_FEATURES,
+ .flags = PHY_ALWAYS_CALL_SUSPEND,
.config_init = lan867x_revd0_config_init,
.get_plca_cfg = genphy_c45_plca_get_cfg,
.set_plca_cfg = lan86xx_plca_set_cfg,
@@ -577,6 +634,10 @@ static struct phy_driver microchip_t1s_driver[] = {
.cable_test_get_status = genphy_c45_oatc14_cable_test_get_status,
.get_sqi = genphy_c45_oatc14_get_sqi,
.get_sqi_max = genphy_c45_oatc14_get_sqi_max,
+ .suspend = lan867x_revd0_suspend,
+ .resume = genphy_c45_oatc10_resume,
+ .get_wol = lan867x_revd0_get_wol,
+ .set_wol = lan867x_revd0_set_wol,
},
{
PHY_ID_MATCH_EXACT(PHY_ID_LAN865X_REVB),
--
2.34.1
^ permalink raw reply related
* Re: [PATCH 1/1] xskmap: reject TX-only AF_XDP sockets
From: Maciej Fijalkowski @ 2026-03-30 13:50 UTC (permalink / raw)
To: Linpu Yu
Cc: magnus.karlsson, netdev, bpf, sdf, davem, edumazet, kuba, pabeni,
horms, ast, daniel, hawk, john.fastabend, bjorn, linux-kernel,
yuantan098, yifanwucs
In-Reply-To: <6584463e576b7bb3619dc302cfecfb8ca56bc86a.1774701288.git.linpu5433@gmail.com>
On Mon, Mar 30, 2026 at 03:29:42AM +0800, Linpu Yu wrote:
> Reject TX-only AF_XDP sockets from XSKMAP updates. Redirected
> packets always enter the Rx path, where the kernel expects the
> selected socket to have an Rx ring. A TX-only socket can
> currently be inserted into an XSKMAP, and redirecting a packet
> to it crashes the kernel in xsk_generic_rcv().
This paragraph seems to be strictly related to veth nature. While the fix
makes sense to me, it should be stated that it is not a default behavior
but rather how veth works.
>
> Keep TX-only AF_XDP sockets valid for pure Tx use, but prevent
> them from being published through XSKMAP.
>
> Fixes: fbfc504a24f5 ("bpf: introduce new bpf AF_XDP map type BPF_MAP_TYPE_XSKMAP")
> Reported-by: Juefei Pu <tomapufckgml@gmail.com>
> Reported-by: Yuan Tan <yuantan098@gmail.com>
> Signed-off-by: Xin Liu <bird@lzu.edu.cn>
> Signed-off-by: Yifan Wu <yifanwucs@gmail.com>
> Signed-off-by: Linpu Yu <linpu5433@gmail.com>
> ---
> net/xdp/xskmap.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/net/xdp/xskmap.c b/net/xdp/xskmap.c
> index afa457506274c..6dac59ebb5cf0 100644
> --- a/net/xdp/xskmap.c
> +++ b/net/xdp/xskmap.c
> @@ -184,6 +184,10 @@ static long xsk_map_update_elem(struct bpf_map *map, void *key, void *value,
> }
>
> xs = (struct xdp_sock *)sock->sk;
> + if (!READ_ONCE(xs->rx)) {
> + sockfd_put(sock);
> + return -EINVAL;
> + }
>
> map_entry = &m->xsk_map[i];
> node = xsk_map_node_alloc(m, map_entry);
> --
> 2.53.0
>
^ permalink raw reply
* [PATCH 0/1] Fix kernel build failure with CONFIG_GCOV_PROFILE_ALL=y
From: Konstantin Khorenko @ 2026-03-30 13:53 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni
Cc: horms, arnd, linux, netdev, linux-kernel, Konstantin Khorenko
This patch fixes a build failure in net/core/skbuff.c that occurs when
CONFIG_GCOV_PROFILE_ALL=y is enabled. The issue manifests as a
BUILD_BUG_ON compile-time assertion failure, even though the actual
runtime value satisfies the constraint.
Build failure without this patch
---------------------------------
With the following configuration enabled:
CONFIG_GCOV_KERNEL=y
CONFIG_GCOV_PROFILE_ALL=y
# CONFIG_GCOV_PROFILE_FTRACE is not set
CONFIG_GCOV_PROFILE_RDS=y
CONFIG_GCOV_PROFILE_URING=y
The kernel fails to build with:
In file included from <command-line>:
In function 'skb_extensions_init',
inlined from 'skb_init' at net/core/skbuff.c:5214:2:
././include/linux/compiler_types.h:706:45: error: call to '__compiletime_assert_1490' declared with attribute error: BUILD_BUG_ON failed: skb_ext_total_length() > 255
706 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^
././include/linux/compiler_types.h:687:25: note: in definition of macro '__compiletime_assert'
687 | prefix ## suffix(); \
| ^~~~~~
././include/linux/compiler_types.h:706:9: note: in expansion of macro '_compiletime_assert'
706 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/linux/build_bug.h:40:37: note: in expansion of macro 'compiletime_assert'
40 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
./include/linux/build_bug.h:51:9: note: in expansion of macro 'BUILD_BUG_ON_MSG'
51 | BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
| ^~~~~~~~~~~~~~~~
net/core/skbuff.c:5163:9: note: in expansion of macro 'BUILD_BUG_ON'
5163 | BUILD_BUG_ON(skb_ext_total_length() > 255);
| ^~~~~~~~~~~~
make[4]: *** [scripts/Makefile.build:289: net/core/skbuff.o] Error 1
Root cause
----------
CONFIG_GCOV_PROFILE_ALL adds -fprofile-arcs -ftest-coverage -fno-tree-loop-im
to all kernel compilation units. The skb_ext_total_length() function uses
a __always_inline loop over skb_ext_type_len[] array. GCOV instrumentation
inserts branch counters, and -fno-tree-loop-im prevents loop optimization,
breaking the compiler's ability to constant-fold the result. BUILD_BUG_ON
requires a compile-time constant and fails.
The problem is more pronounced in recent kernels (7.0+) where the number of
SKB extensions grew from 4 to 5+ (with addition of SKB_EXT_CAN, SKB_EXT_PSP,
etc.). With 4 elements, GCC can still unroll and fold; with 5+, it gives up.
This affects both older and newer GCC versions (tested with GCC 11.4.1 and
GCC 16.0.1 20260327 experimental).
Solution
--------
Add a CONFIG_GCOV_PROFILE_ALL guard to the BUILD_BUG_ON, following the
existing pattern for CONFIG_KCOV_INSTRUMENT_ALL which has the same issue.
Konstantin Khorenko (1):
net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL
net/core/skbuff.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--
2.43.5
^ permalink raw reply
* [PATCH 1/1] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL
From: Konstantin Khorenko @ 2026-03-30 13:53 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni
Cc: horms, arnd, linux, netdev, linux-kernel, Konstantin Khorenko
In-Reply-To: <20260330135337.937540-1-khorenko@virtuozzo.com>
When CONFIG_GCOV_PROFILE_ALL=y is enabled, GCC inserts branch profiling
counters into skb_ext_total_length() and, combined with -fno-tree-loop-im
from GCOV, prevents the compiler from constant-folding the loop that
sums skb_ext_type_len[] array elements. This causes the compile-time
BUILD_BUG_ON(skb_ext_total_length() > 255) check to fail, even though
the actual computed value is well below 255.
The kernel already has a guard for CONFIG_KCOV_INSTRUMENT_ALL, which
causes the same problem. Add a similar guard for GCOV.
The number of loop iterations matters: with 4 extension types (as in
earlier kernels), GCC 11 can still constant-fold despite GCOV. With 5+
types (after SKB_EXT_CAN and other additions), it gives up. This is
why the issue only manifests in recent kernels with GCOV enabled.
Tested with GCC 11.4.1 and GCC 16.0.1 20260327 (experimental) - both
exhibit the same behavior.
Note that skb_ext_total_length() is still correct at runtime; this
change only allows the build to succeed when GCOV_PROFILE_ALL is
enabled for coverage analysis.
Fixes: 5d21d0a65b57 ("net: generalize calculation of skb extensions length")
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
net/core/skbuff.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 0e217041958a..98c3d4e63219 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -5159,7 +5159,7 @@ static __always_inline unsigned int skb_ext_total_length(void)
static void skb_extensions_init(void)
{
BUILD_BUG_ON(SKB_EXT_NUM > 8);
-#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL)
+#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL) && !IS_ENABLED(CONFIG_GCOV_PROFILE_ALL)
BUILD_BUG_ON(skb_ext_total_length() > 255);
#endif
--
2.43.5
^ permalink raw reply related
* Re: [PATCH net v4] mptcp: fix soft lockup in mptcp_recvmsg()
From: Matthieu Baerts @ 2026-03-30 13:54 UTC (permalink / raw)
To: Li Xiasong
Cc: netdev, mptcp, linux-kernel, yuehaibing, zhangchangzhong,
weiyongjun1, Mat Martineau, Geliang Tang, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman
In-Reply-To: <20260330120335.659027-1-lixiasong1@huawei.com>
Hi Li,
On 30/03/2026 14:03, Li Xiasong wrote:
> syzbot reported a soft lockup in mptcp_recvmsg() [0].
>
> When receiving data with MSG_PEEK | MSG_WAITALL flags, the skb is not
> removed from the sk_receive_queue. This causes sk_wait_data() to always
> find available data and never perform actual waiting, leading to a soft
> lockup.
>
> Fix this by adding a 'last' parameter to track the last peeked skb.
> This allows sk_wait_data() to make informed waiting decisions and prevent
> infinite loops when MSG_PEEK is used.
Thank you for this new version:
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
@netdev maintainers: this patch can be applied in 'net' directly, thank you!
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox