Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 5/5] arm64: defconfig: Enable Qualcomm Shikra SoC Global clock controller
From: Krzysztof Kozlowski @ 2026-04-29 14:32 UTC (permalink / raw)
  To: Imran Shaik, Bjorn Andersson, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran
  Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
	devicetree, linux-kernel, netdev
In-Reply-To: <20260429-shikra-gcc-rpmcc-clks-v1-5-c3cd77558b7a@oss.qualcomm.com>

On 29/04/2026 12:51, Imran Shaik wrote:
> Enable the Global clock controller driver on Qualcomm Shikra EVK board.
> 
> Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
> ---
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index dd1ac01ee29bf631d517c38486f6896ffd82dcc9..13e04080b37160129ccd47b0148a64277b8e0e4c 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -1461,6 +1461,7 @@ CONFIG_CLK_IMX8QXP=y
>  CONFIG_CLK_IMX8ULP=y
>  CONFIG_CLK_IMX93=y
>  CONFIG_CLK_IMX95_BLK_CTL=y
> +CONFIG_CLK_SHIKRA_GCC=y

Beside some really odd order, this patch should not be needed.

Best regards,
Krzysztof

^ permalink raw reply

* Re: [RFC Patch net-next v2 4/8] r8169: add support for new interrupt mapping
From: Vadim Fedorenko @ 2026-04-29 14:32 UTC (permalink / raw)
  To: javen, hkallweit1, nic_swsd, andrew+netdev, davem, edumazet, kuba,
	pabeni, horms
  Cc: netdev, linux-kernel
In-Reply-To: <20260429070750.1477-5-javen_xu@realsil.com.cn>

On 29/04/2026 08:07, javen wrote:
> From: Javen Xu <javen_xu@realsil.com.cn>
> 
> To support RSS, the number of hardware interrupt bits should match the
> interrupt of software. So we add support for new interrupt mapping here.
> ISR_VER_MAP_REG is the hardware register to indicate interrupt status.
> IMR_SET_VEC_MAP_REG is interrupt mask which is set to enable irq.
> 
> Signed-off-by: Javen Xu <javen_xu@realsil.com.cn>

[...]

>   
>   		napi = &tp->r8169napi[i];
>   		snprintf(irq->name, len, "%s-%d", dev->name, i);
> @@ -5664,10 +5717,17 @@ static const struct net_device_ops rtl_netdev_ops = {
>   
>   static void rtl_set_irq_mask(struct rtl8169_private *tp)
>   {
> -	tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg;
> +	if (tp->features & RTL_VEC_MAP_ENABLE) {
> +		tp->irq_mask = ISRIMR_LINKCHG;
> +		tp->irq_mask |= ISRIMR_TOK_Q0;

       nit: you can set it in one line

> +		for (int i = 0; i < tp->num_rx_rings; i++)
> +			tp->irq_mask |= ISRIMR_ROK_Q0 << i;
> +	} else {
> +		tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg;
>   
> -	if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
> -		tp->irq_mask |= SYSErr | RxFIFOOver;
> +		if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
> +			tp->irq_mask |= SYSErr | RxFIFOOver;
> +	}
>   }
>   
>   static int rtl_alloc_irq(struct rtl8169_private *tp)
> @@ -5695,6 +5755,16 @@ static int rtl_alloc_irq(struct rtl8169_private *tp)
>   	if (nvecs < 0)
>   		nvecs = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
>   
> +	tp->features &= ~RTL_VEC_MAP_ENABLE;
> +
> +	if (nvecs > 0) {
> +		tp->irq_nvecs = nvecs;
> +		tp->irq = pci_irq_vector(pdev, 0);
> +		if (nvecs > 1)
> +			tp->features |= RTL_VEC_MAP_ENABLE;
> +		return 0;
> +	}
> +
>   	tp->irq = pdev->irq;
>   	tp->irq_nvecs = 1;

now these 2 lines are not needed, because in success they are never
executed, but in error path they provide wrong information.

the whole can be rewritten with error path in case both tries of
pci_alloc_irq_vectors failed and the common code for success path:

	if (nvecs < 0)
		nvecs = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);

	if (nvecs < 0)
		return nvecs;

	tp->irq_nvecs = nvecs;
	tp->irq = pci_irq_vector(pdev, 0);

	if (nvecs > 1)
		tp->features |= RTL_VEC_MAP_ENABLE;

	return 0;

>   
> @@ -5965,6 +6035,53 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
>   	return false;
>   }
>   
> +static int rtl8169_poll_msix_rx(struct napi_struct *napi, int budget)
> +{
> +	struct rtl8169_napi *r8169_napi = container_of(napi, struct rtl8169_napi, napi);
> +	struct rtl8169_private *tp = r8169_napi->priv;
> +	struct net_device *dev = tp->dev;
> +	const int message_id = r8169_napi->index;

reverse xmass tree, please

> +	int work_done = 0;
> +
> +	if (message_id < tp->num_rx_rings)
> +		work_done += rtl_rx(dev, tp, &tp->rx_ring[message_id], budget);
> +
> +	if (work_done < budget && napi_complete_done(napi, work_done))
> +		rtl8169_enable_hw_interrupt_msix(tp, message_id);
> +
> +	return work_done;
> +}
> +
> +static int rtl8169_poll_msix_tx(struct napi_struct *napi, int budget)
> +{
> +	struct rtl8169_napi *r8169_napi = container_of(napi, struct rtl8169_napi, napi);
> +	struct rtl8169_private *tp = r8169_napi->priv;
> +	struct net_device *dev = tp->dev;
> +	unsigned int work_done = 0;
> +	const int message_id = r8169_napi->index;
> +	int tx_ring_idx = message_id - 8;

ditto

> +
> +	if (tx_ring_idx >= 0)
> +		rtl_tx(dev, tp, budget);
> +
> +	if (work_done < budget && napi_complete_done(napi, work_done))
> +		rtl8169_enable_hw_interrupt_msix(tp, message_id);
> +
> +	return work_done;
> +}
> +
> +static int rtl8169_poll_msix_other(struct napi_struct *napi, int budget)
> +{
> +	struct rtl8169_napi *r8169_napi = container_of(napi, struct rtl8169_napi, napi);
> +	struct rtl8169_private *tp = r8169_napi->priv;
> +	const int message_id = r8169_napi->index;
> +
> +	napi_complete_done(napi, budget);
> +	rtl8169_enable_hw_interrupt_msix(tp, message_id);
> +
> +	return 1;
> +}
> +
>   static void r8169_init_napi(struct rtl8169_private *tp)
>   {
>   	for (int i = 0; i < tp->irq_nvecs; i++) {
> @@ -5972,6 +6089,20 @@ static void r8169_init_napi(struct rtl8169_private *tp)
>   		int (*poll)(struct napi_struct *napi, int budget);
>   
>   		poll = rtl8169_poll;
> +		if (tp->features & RTL_VEC_MAP_ENABLE) {
> +			switch (tp->hw_curr_isr_ver) {
> +			case 6:
> +				if (i < R8127_MAX_RX_QUEUES)
> +					poll = rtl8169_poll_msix_rx;
> +				else if (i > 7 && i < 16)

	magic constants?

> +					poll = rtl8169_poll_msix_tx;
> +				else
> +					poll = rtl8169_poll_msix_other;
> +				break;
> +			default:
> +				break;
> +			}
> +		}
>   		netif_napi_add(tp->dev, &r8169napi->napi, poll);
>   		r8169napi->priv = tp;
>   		r8169napi->index = i;


^ permalink raw reply

* [PATCH net-next 1/2] net: cs89x0: remove ISA bus probing
From: Arnd Bergmann @ 2026-04-29 14:55 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Jonathan Corbet, Andrew Lunn
  Cc: Arnd Bergmann, Andrew Morton, Simon Horman, Shuah Khan,
	Mengyuan Lou, netdev, linux-doc, linux-kernel

From: Arnd Bergmann <arnd@arndb.de>

The cs89x0 driver is really two in one, and they are mutually exclusive:

 - the ISA driver was used on 486-era PCs. It likely has no remaining
   users, like the other ethernet drivers that got removed in
   linux-7.1. The DMA support in here is the last device driver use of
   the deprecated isa_bus_to_virt() interface, all other users are either
   x86 specific or or got converted to the normal dma-mapping interface.
   The driver was maintained by Andrew Morton at the time, based on
   the linux-2.2 vendor driver from Cirrus Logic.

 - the platform_driver instance was used on some embedded Arm boards
   around the same time, such as the EP7211 Development Kit. This
   is the same chip, but uses modern devicetree based probing and no DMA.
   This was added by Alexander Shiyan.

Remove the ISA driver as a cleanup, including all of the outdated
documentation referring to its configuration.

Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 .../device_drivers/ethernet/cirrus/cs89x0.rst | 647 ------------------
 .../device_drivers/ethernet/index.rst         |   1 -
 drivers/net/Space.c                           |   3 -
 drivers/net/ethernet/cirrus/Kconfig           |  20 +-
 drivers/net/ethernet/cirrus/cs89x0.c          | 636 +----------------
 include/net/Space.h                           |   1 -
 6 files changed, 6 insertions(+), 1302 deletions(-)
 delete mode 100644 Documentation/networking/device_drivers/ethernet/cirrus/cs89x0.rst

diff --git a/Documentation/networking/device_drivers/ethernet/cirrus/cs89x0.rst b/Documentation/networking/device_drivers/ethernet/cirrus/cs89x0.rst
deleted file mode 100644
index e5c283940ac5..000000000000
--- a/Documentation/networking/device_drivers/ethernet/cirrus/cs89x0.rst
+++ /dev/null
@@ -1,647 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-================================================
-Cirrus Logic LAN CS8900/CS8920 Ethernet Adapters
-================================================
-
-.. note::
-
-   This document was contributed by Cirrus Logic for kernel 2.2.5.  This version
-   has been updated for 2.3.48 by Andrew Morton.
-
-   Still, this is too outdated! A major cleanup is needed here.
-
-Cirrus make a copy of this driver available at their website, as
-described below.  In general, you should use the driver version which
-comes with your Linux distribution.
-
-
-Linux Network Interface Driver ver. 2.00 <kernel 2.3.48>
-
-
-.. TABLE OF CONTENTS
-
-   1.0 CIRRUS LOGIC LAN CS8900/CS8920 ETHERNET ADAPTERS
-	1.1 Product Overview
-	1.2 Driver Description
-	    1.2.1 Driver Name
-	    1.2.2 File in the Driver Package
-	1.3 System Requirements
-	1.4 Licensing Information
-
-   2.0 ADAPTER INSTALLATION and CONFIGURATION
-	2.1 CS8900-based Adapter Configuration
-	2.2 CS8920-based Adapter Configuration
-
-   3.0 LOADING THE DRIVER AS A MODULE
-
-   4.0 COMPILING THE DRIVER
-	4.1 Compiling the Driver as a Loadable Module
-	4.2 Compiling the driver to support memory mode
-	4.3 Compiling the driver to support Rx DMA
-
-   5.0 TESTING AND TROUBLESHOOTING
-	5.1 Known Defects and Limitations
-	5.2 Testing the Adapter
-	    5.2.1 Diagnostic Self-Test
-	    5.2.2 Diagnostic Network Test
-	5.3 Using the Adapter's LEDs
-	5.4 Resolving I/O Conflicts
-
-   6.0 TECHNICAL SUPPORT
-	6.1 Contacting Cirrus Logic's Technical Support
-	6.2 Information Required Before Contacting Technical Support
-	6.3 Obtaining the Latest Driver Version
-	6.4 Current maintainer
-	6.5 Kernel boot parameters
-
-
-1. Cirrus Logic LAN CS8900/CS8920 Ethernet Adapters
-===================================================
-
-
-1.1. Product Overview
-=====================
-
-The CS8900-based ISA Ethernet Adapters from Cirrus Logic follow
-IEEE 802.3 standards and support half or full-duplex operation in ISA bus
-computers on 10 Mbps Ethernet networks.  The adapters are designed for operation
-in 16-bit ISA or EISA bus expansion slots and are available in
-10BaseT-only or 3-media configurations (10BaseT, 10Base2, and AUI for 10Base-5
-or fiber networks).
-
-CS8920-based adapters are similar to the CS8900-based adapter with additional
-features for Plug and Play (PnP) support and Wakeup Frame recognition.  As
-such, the configuration procedures differ somewhat between the two types of
-adapters.  Refer to the "Adapter Configuration" section for details on
-configuring both types of adapters.
-
-
-1.2. Driver Description
-=======================
-
-The CS8900/CS8920 Ethernet Adapter driver for Linux supports the Linux
-v2.3.48 or greater kernel.  It can be compiled directly into the kernel
-or loaded at run-time as a device driver module.
-
-1.2.1 Driver Name: cs89x0
-
-1.2.2 Files in the Driver Archive:
-
-The files in the driver at Cirrus' website include:
-
-  ===================  ====================================================
-  readme.txt           this file
-  build                batch file to compile cs89x0.c.
-  cs89x0.c             driver C code
-  cs89x0.h             driver header file
-  cs89x0.o             pre-compiled module (for v2.2.5 kernel)
-  config/Config.in     sample file to include cs89x0 driver in the kernel.
-  config/Makefile      sample file to include cs89x0 driver in the kernel.
-  config/Space.c       sample file to include cs89x0 driver in the kernel.
-  ===================  ====================================================
-
-
-
-1.3. System Requirements
-------------------------
-
-The following hardware is required:
-
-   * Cirrus Logic LAN (CS8900/20-based) Ethernet ISA Adapter
-
-   * IBM or IBM-compatible PC with:
-     * An 80386 or higher processor
-     * 16 bytes of contiguous IO space available between 210h - 370h
-     * One available IRQ (5,10,11,or 12 for the CS8900, 3-7,9-15 for CS8920).
-
-   * Appropriate cable (and connector for AUI, 10BASE-2) for your network
-     topology.
-
-The following software is required:
-
-* LINUX kernel version 2.3.48 or higher
-
-   * CS8900/20 Setup Utility (DOS-based)
-
-   * LINUX kernel sources for your kernel (if compiling into kernel)
-
-   * GNU Toolkit (gcc and make) v2.6 or above (if compiling into kernel
-     or a module)
-
-
-
-1.4. Licensing Information
---------------------------
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation, version 1.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-more details.
-
-For a full copy of the GNU General Public License, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-
-2. Adapter Installation and Configuration
-=========================================
-
-Both the CS8900 and CS8920-based adapters can be configured using parameters
-stored in an on-board EEPROM. You must use the DOS-based CS8900/20 Setup
-Utility if you want to change the adapter's configuration in EEPROM.
-
-When loading the driver as a module, you can specify many of the adapter's
-configuration parameters on the command-line to override the EEPROM's settings
-or for interface configuration when an EEPROM is not used. (CS8920-based
-adapters must use an EEPROM.) See Section 3.0 LOADING THE DRIVER AS A MODULE.
-
-Since the CS8900/20 Setup Utility is a DOS-based application, you must install
-and configure the adapter in a DOS-based system using the CS8900/20 Setup
-Utility before installation in the target LINUX system.  (Not required if
-installing a CS8900-based adapter and the default configuration is acceptable.)
-
-
-2.1. CS8900-based Adapter Configuration
----------------------------------------
-
-CS8900-based adapters shipped from Cirrus Logic have been configured
-with the following "default" settings::
-
-  Operation Mode:      Memory Mode
-  IRQ:                 10
-  Base I/O Address:    300
-  Memory Base Address: D0000
-  Optimization:	       DOS Client
-  Transmission Mode:   Half-duplex
-  BootProm:            None
-  Media Type:	       Autodetect (3-media cards) or
-		       10BASE-T (10BASE-T only adapter)
-
-You should only change the default configuration settings if conflicts with
-another adapter exists. To change the adapter's configuration, run the
-CS8900/20 Setup Utility.
-
-
-2.2. CS8920-based Adapter Configuration
----------------------------------------
-
-CS8920-based adapters are shipped from Cirrus Logic configured as Plug
-and Play (PnP) enabled.  However, since the cs89x0 driver does NOT
-support PnP, you must install the CS8920 adapter in a DOS-based PC and
-run the CS8900/20 Setup Utility to disable PnP and configure the
-adapter before installation in the target Linux system.  Failure to do
-this will leave the adapter inactive and the driver will be unable to
-communicate with the adapter.
-
-::
-
-	****************************************************************
-	*                    CS8920-BASED ADAPTERS:                    *
-	*                                                              *
-	* CS8920-BASED ADAPTERS ARE PLUG and PLAY ENABLED BY DEFAULT.  *
-	* THE CS89X0 DRIVER DOES NOT SUPPORT PnP. THEREFORE, YOU MUST  *
-	* RUN THE CS8900/20 SETUP UTILITY TO DISABLE PnP SUPPORT AND   *
-	* TO ACTIVATE THE ADAPTER.                                     *
-	****************************************************************
-
-
-
-
-3. Loading the Driver as a Module
-=================================
-
-If the driver is compiled as a loadable module, you can load the driver module
-with the 'modprobe' command.  Many of the adapter's configuration parameters can
-be specified as command-line arguments to the load command.  This facility
-provides a means to override the EEPROM's settings or for interface
-configuration when an EEPROM is not used.
-
-Example::
-
-    insmod cs89x0.o io=0x200 irq=0xA media=aui
-
-This example loads the module and configures the adapter to use an IO port base
-address of 200h, interrupt 10, and use the AUI media connection.  The following
-configuration options are available on the command line::
-
-  io=###               - specify IO address (200h-360h)
-  irq=##               - specify interrupt level
-  use_dma=1            - Enable DMA
-  dma=#                - specify dma channel (Driver is compiled to support
-			 Rx DMA only)
-  dmasize=# (16 or 64) - DMA size 16K or 64K.  Default value is set to 16.
-  media=rj45           - specify media type
-   or media=bnc
-   or media=aui
-   or media=auto
-  duplex=full          - specify forced half/full/autonegotiate duplex
-   or duplex=half
-   or duplex=auto
-  debug=#              - debug level (only available if the driver was compiled
-			 for debugging)
-
-**Notes:**
-
-a) If an EEPROM is present, any specified command-line parameter
-   will override the corresponding configuration value stored in
-   EEPROM.
-
-b) The "io" parameter must be specified on the command-line.
-
-c) The driver's hardware probe routine is designed to avoid
-   writing to I/O space until it knows that there is a cs89x0
-   card at the written addresses.  This could cause problems
-   with device probing.  To avoid this behaviour, add one
-   to the ``io=`` module parameter.  This doesn't actually change
-   the I/O address, but it is a flag to tell the driver
-   to partially initialise the hardware before trying to
-   identify the card.  This could be dangerous if you are
-   not sure that there is a cs89x0 card at the provided address.
-
-   For example, to scan for an adapter located at IO base 0x300,
-   specify an IO address of 0x301.
-
-d) The "duplex=auto" parameter is only supported for the CS8920.
-
-e) The minimum command-line configuration required if an EEPROM is
-   not present is:
-
-   io
-   irq
-   media type (no autodetect)
-
-f) The following additional parameters are CS89XX defaults (values
-   used with no EEPROM or command-line argument).
-
-   * DMA Burst = enabled
-   * IOCHRDY Enabled = enabled
-   * UseSA = enabled
-   * CS8900 defaults to half-duplex if not specified on command-line
-   * CS8920 defaults to autoneg if not specified on command-line
-   * Use reset defaults for other config parameters
-   * dma_mode = 0
-
-g) You can use ifconfig to set the adapter's Ethernet address.
-
-h) Many Linux distributions use the 'modprobe' command to load
-   modules.  This program uses the '/etc/conf.modules' file to
-   determine configuration information which is passed to a driver
-   module when it is loaded.  All the configuration options which are
-   described above may be placed within /etc/conf.modules.
-
-   For example::
-
-     > cat /etc/conf.modules
-     ...
-     alias eth0 cs89x0
-     options cs89x0 io=0x0200 dma=5 use_dma=1
-     ...
-
-   In this example we are telling the module system that the
-   ethernet driver for this machine should use the cs89x0 driver.  We
-   are asking 'modprobe' to pass the 'io', 'dma' and 'use_dma'
-   arguments to the driver when it is loaded.
-
-i) Cirrus recommend that the cs89x0 use the ISA DMA channels 5, 6 or
-   7.  You will probably find that other DMA channels will not work.
-
-j) The cs89x0 supports DMA for receiving only.  DMA mode is
-   significantly more efficient.  Flooding a 400 MHz Celeron machine
-   with large ping packets consumes 82% of its CPU capacity in non-DMA
-   mode.  With DMA this is reduced to 45%.
-
-k) If your Linux kernel was compiled with inbuilt plug-and-play
-   support you will be able to find information about the cs89x0 card
-   with the command::
-
-     cat /proc/isapnp
-
-l) If during DMA operation you find erratic behavior or network data
-   corruption you should use your PC's BIOS to slow the EISA bus clock.
-
-m) If the cs89x0 driver is compiled directly into the kernel
-   (non-modular) then its I/O address is automatically determined by
-   ISA bus probing.  The IRQ number, media options, etc are determined
-   from the card's EEPROM.
-
-n) If the cs89x0 driver is compiled directly into the kernel, DMA
-   mode may be selected by providing the kernel with a boot option
-   'cs89x0_dma=N' where 'N' is the desired DMA channel number (5, 6 or 7).
-
-   Kernel boot options may be provided on the LILO command line::
-
-	LILO boot: linux cs89x0_dma=5
-
-   or they may be placed in /etc/lilo.conf::
-
-	image=/boot/bzImage-2.3.48
-	  append="cs89x0_dma=5"
-	  label=linux
-	  root=/dev/hda5
-	  read-only
-
-   The DMA Rx buffer size is hardwired to 16 kbytes in this mode.
-   (64k mode is not available).
-
-
-4. Compiling the Driver
-=======================
-
-The cs89x0 driver can be compiled directly into the kernel or compiled into
-a loadable device driver module.
-
-Just use the standard way to configure the driver and compile the Kernel.
-
-
-4.1. Compiling the Driver to Support Rx DMA
--------------------------------------------
-
-The compile-time optionality for DMA was removed in the 2.3 kernel
-series.  DMA support is now unconditionally part of the driver.  It is
-enabled by the 'use_dma=1' module option.
-
-
-5. Testing and Troubleshooting
-==============================
-
-5.1. Known Defects and Limitations
-----------------------------------
-
-Refer to the RELEASE.TXT file distributed as part of this archive for a list of
-known defects, driver limitations, and work arounds.
-
-
-5.2. Testing the Adapter
-------------------------
-
-Once the adapter has been installed and configured, the diagnostic option of
-the CS8900/20 Setup Utility can be used to test the functionality of the
-adapter and its network connection.  Use the diagnostics 'Self Test' option to
-test the functionality of the adapter with the hardware configuration you have
-assigned. You can use the diagnostics 'Network Test' to test the ability of the
-adapter to communicate across the Ethernet with another PC equipped with a
-CS8900/20-based adapter card (it must also be running the CS8900/20 Setup
-Utility).
-
-.. note::
-
-	 The Setup Utility's diagnostics are designed to run in a
-	 DOS-only operating system environment.  DO NOT run the diagnostics
-	 from a DOS or command prompt session under Windows 95, Windows NT,
-	 OS/2, or other operating system.
-
-To run the diagnostics tests on the CS8900/20 adapter:
-
-   1.  Boot DOS on the PC and start the CS8900/20 Setup Utility.
-
-   2.  The adapter's current configuration is displayed.  Hit the ENTER key to
-       get to the main menu.
-
-   4.  Select 'Diagnostics' (ALT-G) from the main menu.
-       * Select 'Self-Test' to test the adapter's basic functionality.
-       * Select 'Network Test' to test the network connection and cabling.
-
-
-5.2.1. Diagnostic Self-test
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The diagnostic self-test checks the adapter's basic functionality as well as
-its ability to communicate across the ISA bus based on the system resources
-assigned during hardware configuration.  The following tests are performed:
-
-   * IO Register Read/Write Test
-
-     The IO Register Read/Write test insures that the CS8900/20 can be
-     accessed in IO mode, and that the IO base address is correct.
-
-   * Shared Memory Test
-
-     The Shared Memory test insures the CS8900/20 can be accessed in memory
-     mode and that the range of memory addresses assigned does not conflict
-     with other devices in the system.
-
-   * Interrupt Test
-
-     The Interrupt test insures there are no conflicts with the assigned IRQ
-     signal.
-
-   * EEPROM Test
-
-     The EEPROM test insures the EEPROM can be read.
-
-   * Chip RAM Test
-
-     The Chip RAM test insures the 4K of memory internal to the CS8900/20 is
-     working properly.
-
-   * Internal Loop-back Test
-
-     The Internal Loop Back test insures the adapter's transmitter and
-     receiver are operating properly.  If this test fails, make sure the
-     adapter's cable is connected to the network (check for LED activity for
-     example).
-
-   * Boot PROM Test
-
-     The Boot PROM  test insures the Boot PROM is present, and can be read.
-     Failure indicates the Boot PROM  was not successfully read due to a
-     hardware problem or due to a conflicts on the Boot PROM address
-     assignment. (Test only applies if the adapter is configured to use the
-     Boot PROM option.)
-
-Failure of a test item indicates a possible system resource conflict with
-another device on the ISA bus.  In this case, you should use the Manual Setup
-option to reconfigure the adapter by selecting a different value for the system
-resource that failed.
-
-
-5.2.2. Diagnostic Network Test
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The Diagnostic Network Test verifies a working network connection by
-transferring data between two CS8900/20 adapters installed in different PCs
-on the same network. (Note: the diagnostic network test should not be run
-between two nodes across a router.)
-
-This test requires that each of the two PCs have a CS8900/20-based adapter
-installed and have the CS8900/20 Setup Utility running.  The first PC is
-configured as a Responder and the other PC is configured as an Initiator.
-Once the Initiator is started, it sends data frames to the Responder which
-returns the frames to the Initiator.
-
-The total number of frames received and transmitted are displayed on the
-Initiator's display, along with a count of the number of frames received and
-transmitted OK or in error.  The test can be terminated anytime by the user at
-either PC.
-
-To setup the Diagnostic Network Test:
-
-    1.  Select a PC with a CS8900/20-based adapter and a known working network
-	connection to act as the Responder.  Run the CS8900/20 Setup Utility
-	and select 'Diagnostics -> Network Test -> Responder' from the main
-	menu.  Hit ENTER to start the Responder.
-
-    2.  Return to the PC with the CS8900/20-based adapter you want to test and
-	start the CS8900/20 Setup Utility.
-
-    3.  From the main menu, Select 'Diagnostic -> Network Test -> Initiator'.
-	Hit ENTER to start the test.
-
-You may stop the test on the Initiator at any time while allowing the Responder
-to continue running.  In this manner, you can move to additional PCs and test
-them by starting the Initiator on another PC without having to stop/start the
-Responder.
-
-
-
-5.3. Using the Adapter's LEDs
------------------------------
-
-The 2 and 3-media adapters have two LEDs visible on the back end of the board
-located near the 10Base-T connector.
-
-Link Integrity LED: A "steady" ON of the green LED indicates a valid 10Base-T
-connection.  (Only applies to 10Base-T.  The green LED has no significance for
-a 10Base-2 or AUI connection.)
-
-TX/RX LED: The yellow LED lights briefly each time the adapter transmits or
-receives data. (The yellow LED will appear to "flicker" on a typical network.)
-
-
-5.4. Resolving I/O Conflicts
-----------------------------
-
-An IO conflict occurs when two or more adapter use the same ISA resource (IO
-address, memory address or IRQ).  You can usually detect an IO conflict in one
-of four ways after installing and or configuring the CS8900/20-based adapter:
-
-    1.  The system does not boot properly (or at all).
-
-    2.  The driver cannot communicate with the adapter, reporting an "Adapter
-	not found" error message.
-
-    3.  You cannot connect to the network or the driver will not load.
-
-    4.  If you have configured the adapter to run in memory mode but the driver
-	reports it is using IO mode when loading, this is an indication of a
-	memory address conflict.
-
-If an IO conflict occurs, run the CS8900/20 Setup Utility and perform a
-diagnostic self-test.  Normally, the ISA resource in conflict will fail the
-self-test.  If so, reconfigure the adapter selecting another choice for the
-resource in conflict.  Run the diagnostics again to check for further IO
-conflicts.
-
-In some cases, such as when the PC will not boot, it may be necessary to remove
-the adapter and reconfigure it by installing it in another PC to run the
-CS8900/20 Setup Utility.  Once reinstalled in the target system, run the
-diagnostics self-test to ensure the new configuration is free of conflicts
-before loading the driver again.
-
-When manually configuring the adapter, keep in mind the typical ISA system
-resource usage as indicated in the tables below.
-
-::
-
-  I/O Address    	Device                        IRQ      Device
-  -----------    	--------                      ---      --------
-     200-20F       	Game I/O adapter               3       COM2, Bus Mouse
-     230-23F       	Bus Mouse                      4       COM1
-     270-27F       	LPT3: third parallel port      5       LPT2
-     2F0-2FF       	COM2: second serial port       6       Floppy Disk controller
-     320-32F       	Fixed disk controller          7       LPT1
-							 8       Real-time Clock
-						     9       EGA/VGA display adapter
-						    12       Mouse (PS/2)
-  Memory Address  Device                          13       Math Coprocessor
-  --------------  ---------------------           14       Hard Disk controller
-  A000-BFFF	EGA Graphics Adapter
-  A000-C7FF	VGA Graphics Adapter
-  B000-BFFF	Mono Graphics Adapter
-  B800-BFFF	Color Graphics Adapter
-  E000-FFFF	AT BIOS
-
-
-
-
-6. Technical Support
-====================
-
-6.1. Contacting Cirrus Logic's Technical Support
-------------------------------------------------
-
-Cirrus Logic's CS89XX Technical Application Support can be reached at::
-
-  Telephone  :(800) 888-5016 (from inside U.S. and Canada)
-	     :(512) 442-7555 (from outside the U.S. and Canada)
-  Fax        :(512) 912-3871
-  Email      :ethernet@crystal.cirrus.com
-  WWW        :http://www.cirrus.com
-
-
-6.2. Information Required before Contacting Technical Support
--------------------------------------------------------------
-
-Before contacting Cirrus Logic for technical support, be prepared to provide as
-Much of the following information as possible.
-
-1.) Adapter type (CRD8900, CDB8900, CDB8920, etc.)
-
-2.) Adapter configuration
-
-    * IO Base, Memory Base, IO or memory mode enabled, IRQ, DMA channel
-    * Plug and Play enabled/disabled (CS8920-based adapters only)
-    * Configured for media auto-detect or specific media type (which type).
-
-3.) PC System's Configuration
-
-    * Plug and Play system (yes/no)
-    * BIOS (make and version)
-    * System make and model
-    * CPU (type and speed)
-    * System RAM
-    * SCSI Adapter
-
-4.) Software
-
-    * CS89XX driver and version
-    * Your network operating system and version
-    * Your system's OS version
-    * Version of all protocol support files
-
-5.) Any Error Message displayed.
-
-
-
-6.3 Obtaining the Latest Driver Version
----------------------------------------
-
-You can obtain the latest CS89XX drivers and support software from Cirrus Logic's
-Web site.  You can also contact Cirrus Logic's Technical Support (email:
-ethernet@crystal.cirrus.com) and request that you be registered for automatic
-software-update notification.
-
-Cirrus Logic maintains a web page at http://www.cirrus.com with the
-latest drivers and technical publications.
-
-
-6.4. Current maintainer
------------------------
-
-In February 2000 the maintenance of this driver was assumed by Andrew
-Morton.
-
-6.5 Kernel module parameters
-----------------------------
-
-For use in embedded environments with no cs89x0 EEPROM, the kernel boot
-parameter ``cs89x0_media=`` has been implemented.  Usage is::
-
-	cs89x0_media=rj45    or
-	cs89x0_media=aui     or
-	cs89x0_media=bnc
diff --git a/Documentation/networking/device_drivers/ethernet/index.rst b/Documentation/networking/device_drivers/ethernet/index.rst
index 64621c21fd78..fd3be5d20397 100644
--- a/Documentation/networking/device_drivers/ethernet/index.rst
+++ b/Documentation/networking/device_drivers/ethernet/index.rst
@@ -18,7 +18,6 @@ Contents:
    amd/pds_vfio_pci
    aquantia/atlantic
    chelsio/cxgb
-   cirrus/cs89x0
    dlink/dl2k
    davicom/dm9000
    dec/dmfe
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 305f0a712a64..c3ce960110b9 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -202,9 +202,6 @@ static int __init probe_list2(int unit, struct devprobe2 *p, int autoprobe)
 static struct devprobe2 isa_probes[] __initdata = {
 #if defined(CONFIG_NE2000) /* ISA (use ne2k-pci for PCI cards) */
 	{ne_probe, 0},
-#endif
-#ifdef CONFIG_CS89x0_ISA
-	{cs89x0_probe, 0},
 #endif
 	{NULL, 0},
 };
diff --git a/drivers/net/ethernet/cirrus/Kconfig b/drivers/net/ethernet/cirrus/Kconfig
index 5bdf731d9503..d76f9cd6bc2d 100644
--- a/drivers/net/ethernet/cirrus/Kconfig
+++ b/drivers/net/ethernet/cirrus/Kconfig
@@ -6,7 +6,7 @@
 config NET_VENDOR_CIRRUS
 	bool "Cirrus devices"
 	default y
-	depends on ISA || EISA || ARM || MAC || COMPILE_TEST
+	depends on ARM || MAC || COMPILE_TEST
 	help
 	  If you have a network (Ethernet) card belonging to this class, say Y.
 
@@ -20,25 +20,9 @@ if NET_VENDOR_CIRRUS
 config CS89x0
 	tristate
 
-config CS89x0_ISA
-	tristate "CS89x0 ISA driver support"
-	depends on HAS_IOPORT_MAP
-	depends on ISA
-	depends on !PPC32
-	depends on CS89x0_PLATFORM=n
-	select NETDEV_LEGACY_INIT
-	select CS89x0
-	help
-	  Support for CS89x0 chipset based Ethernet cards. If you have a
-	  network (Ethernet) card of this type, say Y and read the file
-	  <file:Documentation/networking/device_drivers/ethernet/cirrus/cs89x0.rst>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called cs89x0.
-
 config CS89x0_PLATFORM
 	tristate "CS89x0 platform driver support"
-	depends on ARM || (COMPILE_TEST && !PPC)
+	depends on ARM || COMPILE_TEST
 	select CS89x0
 	help
 	  Say Y to compile the cs89x0 platform driver. This makes this driver
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c
index fa5857923db4..8ab4b899d0ca 100644
--- a/drivers/net/ethernet/cirrus/cs89x0.c
+++ b/drivers/net/ethernet/cirrus/cs89x0.c
@@ -22,19 +22,6 @@
  * Domenico Andreoli : cavokz@gmail.com
  */
 
-
-/*
- * Set this to zero to disable DMA code
- *
- * Note that even if DMA is turned off we still support the 'dma' and  'use_dma'
- * module options so we don't break any startup scripts.
- */
-#ifndef CONFIG_ISA_DMA_API
-#define ALLOW_DMA	0
-#else
-#define ALLOW_DMA	1
-#endif
-
 /*
  * Set this to zero to remove all the debug statements via
  * dead code elimination
@@ -71,13 +58,8 @@
 #include <linux/gfp.h>
 #include <linux/io.h>
 
-#include <net/Space.h>
-
 #include <asm/irq.h>
 #include <linux/atomic.h>
-#if ALLOW_DMA
-#include <asm/dma.h>
-#endif
 
 #include "cs89x0.h"
 
@@ -91,30 +73,6 @@ static char version[] __initdata =
 	"v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton";
 
 #define DRV_NAME "cs89x0"
-
-/* First, a few definitions that the brave might change.
- * A zero-terminated list of I/O addresses to be probed. Some special flags..
- * Addr & 1 = Read back the address port, look for signature and reset
- * the page window before probing
- * Addr & 3 = Reset the page window and probe
- * The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space,
- * but it is possible that a Cirrus board could be plugged into the ISA
- * slots.
- */
-/* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps
- * them to system IRQ numbers. This mapping is card specific and is set to
- * the configuration of the Cirrus Eval board for this chip.
- */
-#if IS_ENABLED(CONFIG_CS89x0_ISA)
-static unsigned int netcard_portlist[] __used __initdata = {
-	0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240,
-	0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0
-};
-static unsigned int cs8900_irq_map[] = {
-	10, 11, 12, 5
-};
-#endif
-
 #if DEBUGGING
 static unsigned int net_debug = DEBUGGING;
 #else
@@ -149,14 +107,6 @@ struct net_local {
 	int force;		/* force various values; see FORCE* above. */
 	spinlock_t lock;
 	void __iomem *virt_addr;/* CS89x0 virtual address. */
-#if ALLOW_DMA
-	int use_dma;		/* Flag: we're using dma */
-	int dma;		/* DMA channel */
-	int dmasize;		/* 16 or 64 */
-	unsigned char *dma_buff;	/* points to the beginning of the buffer */
-	unsigned char *end_dma_buff;	/* points to the end of the buffer */
-	unsigned char *rx_dma_ptr;	/* points to the next packet  */
-#endif
 };
 
 /* Example routines you must write ;->. */
@@ -166,18 +116,6 @@ struct net_local {
  * Permit 'cs89x0_dma=N' in the kernel boot environment
  */
 #if !defined(MODULE)
-#if ALLOW_DMA
-static int g_cs89x0_dma;
-
-static int __init dma_fn(char *str)
-{
-	g_cs89x0_dma = simple_strtol(str, NULL, 0);
-	return 1;
-}
-
-__setup("cs89x0_dma=", dma_fn);
-#endif	/* ALLOW_DMA */
-
 static int g_cs89x0_media__force;
 
 static int __init media_fn(char *str)
@@ -290,22 +228,9 @@ get_eeprom_cksum(int off, int len, int *buffer)
 static void
 write_irq(struct net_device *dev, int chip_type, int irq)
 {
-	int i;
-
 	if (chip_type == CS8900) {
-#if IS_ENABLED(CONFIG_CS89x0_ISA)
-		/* Search the mapping table for the corresponding IRQ pin. */
-		for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
-			if (cs8900_irq_map[i] == irq)
-				break;
-		/* Not found */
-		if (i == ARRAY_SIZE(cs8900_irq_map))
-			i = 3;
-#else
 		/* INTRQ0 pin is used for interrupt generation. */
-		i = 0;
-#endif
-		writereg(dev, PP_CS8900_ISAINT, i);
+		writereg(dev, PP_CS8900_ISAINT, 0);
 	} else {
 		writereg(dev, PP_CS8920_ISAINT, irq);
 	}
@@ -326,163 +251,6 @@ count_rx_errors(int status, struct net_device *dev)
 		dev->stats.rx_frame_errors++;
 }
 
-/*********************************
- * This page contains DMA routines
- *********************************/
-
-#if ALLOW_DMA
-
-#define dma_page_eq(ptr1, ptr2) ((long)(ptr1) >> 17 == (long)(ptr2) >> 17)
-
-static void
-get_dma_channel(struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-
-	if (lp->dma) {
-		dev->dma = lp->dma;
-		lp->isa_config |= ISA_RxDMA;
-	} else {
-		if ((lp->isa_config & ANY_ISA_DMA) == 0)
-			return;
-		dev->dma = lp->isa_config & DMA_NO_MASK;
-		if (lp->chip_type == CS8900)
-			dev->dma += 5;
-		if (dev->dma < 5 || dev->dma > 7) {
-			lp->isa_config &= ~ANY_ISA_DMA;
-			return;
-		}
-	}
-}
-
-static void
-write_dma(struct net_device *dev, int chip_type, int dma)
-{
-	struct net_local *lp = netdev_priv(dev);
-	if ((lp->isa_config & ANY_ISA_DMA) == 0)
-		return;
-	if (chip_type == CS8900)
-		writereg(dev, PP_CS8900_ISADMA, dma - 5);
-	else
-		writereg(dev, PP_CS8920_ISADMA, dma);
-}
-
-static void
-set_dma_cfg(struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-
-	if (lp->use_dma) {
-		if ((lp->isa_config & ANY_ISA_DMA) == 0) {
-			cs89_dbg(3, err, "set_dma_cfg(): no DMA\n");
-			return;
-		}
-		if (lp->isa_config & ISA_RxDMA) {
-			lp->curr_rx_cfg |= RX_DMA_ONLY;
-			cs89_dbg(3, info, "set_dma_cfg(): RX_DMA_ONLY\n");
-		} else {
-			lp->curr_rx_cfg |= AUTO_RX_DMA;	/* not that we support it... */
-			cs89_dbg(3, info, "set_dma_cfg(): AUTO_RX_DMA\n");
-		}
-	}
-}
-
-static int
-dma_bufcfg(struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-	if (lp->use_dma)
-		return (lp->isa_config & ANY_ISA_DMA) ? RX_DMA_ENBL : 0;
-	else
-		return 0;
-}
-
-static int
-dma_busctl(struct net_device *dev)
-{
-	int retval = 0;
-	struct net_local *lp = netdev_priv(dev);
-	if (lp->use_dma) {
-		if (lp->isa_config & ANY_ISA_DMA)
-			retval |= RESET_RX_DMA; /* Reset the DMA pointer */
-		if (lp->isa_config & DMA_BURST)
-			retval |= DMA_BURST_MODE; /* Does ISA config specify DMA burst ? */
-		if (lp->dmasize == 64)
-			retval |= RX_DMA_SIZE_64K; /* did they ask for 64K? */
-		retval |= MEMORY_ON;	/* we need memory enabled to use DMA. */
-	}
-	return retval;
-}
-
-static void
-dma_rx(struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-	struct sk_buff *skb;
-	int status, length;
-	unsigned char *bp = lp->rx_dma_ptr;
-
-	status = bp[0] + (bp[1] << 8);
-	length = bp[2] + (bp[3] << 8);
-	bp += 4;
-
-	cs89_dbg(5, debug, "%s: receiving DMA packet at %lx, status %x, length %x\n",
-		 dev->name, (unsigned long)bp, status, length);
-
-	if ((status & RX_OK) == 0) {
-		count_rx_errors(status, dev);
-		goto skip_this_frame;
-	}
-
-	/* Malloc up new buffer. */
-	skb = netdev_alloc_skb(dev, length + 2);
-	if (skb == NULL) {
-		dev->stats.rx_dropped++;
-
-		/* AKPM: advance bp to the next frame */
-skip_this_frame:
-		bp += (length + 3) & ~3;
-		if (bp >= lp->end_dma_buff)
-			bp -= lp->dmasize * 1024;
-		lp->rx_dma_ptr = bp;
-		return;
-	}
-	skb_reserve(skb, 2);	/* longword align L3 header */
-
-	if (bp + length > lp->end_dma_buff) {
-		int semi_cnt = lp->end_dma_buff - bp;
-		skb_put_data(skb, bp, semi_cnt);
-		skb_put_data(skb, lp->dma_buff, length - semi_cnt);
-	} else {
-		skb_put_data(skb, bp, length);
-	}
-	bp += (length + 3) & ~3;
-	if (bp >= lp->end_dma_buff)
-		bp -= lp->dmasize*1024;
-	lp->rx_dma_ptr = bp;
-
-	cs89_dbg(3, info, "%s: received %d byte DMA packet of type %x\n",
-		 dev->name, length,
-		 ((skb->data[ETH_ALEN + ETH_ALEN] << 8) |
-		  skb->data[ETH_ALEN + ETH_ALEN + 1]));
-
-	skb->protocol = eth_type_trans(skb, dev);
-	netif_rx(skb);
-	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += length;
-}
-
-static void release_dma_buff(struct net_local *lp)
-{
-	if (lp->dma_buff) {
-		free_pages((unsigned long)(lp->dma_buff),
-			   get_order(lp->dmasize * 1024));
-		lp->dma_buff = NULL;
-	}
-}
-
-#endif	/* ALLOW_DMA */
-
 static void
 control_dc_dc(struct net_device *dev, int on_not_off)
 {
@@ -781,27 +549,6 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
 				 */
 				netif_wake_queue(dev);	/* Inform upper layers. */
 			}
-#if ALLOW_DMA
-			if (lp->use_dma && (status & RX_DMA)) {
-				int count = readreg(dev, PP_DmaFrameCnt);
-				while (count) {
-					cs89_dbg(5, debug,
-						 "%s: receiving %d DMA frames\n",
-						 dev->name, count);
-					if (count > 1)
-						cs89_dbg(2, debug,
-							 "%s: receiving %d DMA frames\n",
-							 dev->name, count);
-					dma_rx(dev);
-					if (--count == 0)
-						count = readreg(dev, PP_DmaFrameCnt);
-					if (count > 0)
-						cs89_dbg(2, debug,
-							 "%s: continuing with %d DMA frames\n",
-							 dev->name, count);
-				}
-			}
-#endif
 			break;
 		case ISQ_RX_MISS_EVENT:
 			dev->stats.rx_missed_errors += (status >> 6);
@@ -860,14 +607,6 @@ net_open(struct net_device *dev)
 			goto bad_out;
 		}
 	} else {
-#if IS_ENABLED(CONFIG_CS89x0_ISA)
-		if (((1 << dev->irq) & lp->irq_map) == 0) {
-			pr_err("%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
-			       dev->name, dev->irq, lp->irq_map);
-			ret = -EAGAIN;
-			goto bad_out;
-		}
-#endif
 /* FIXME: Cirrus' release had this: */
 		writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ);
 /* And 2.3.47 had this: */
@@ -882,46 +621,6 @@ net_open(struct net_device *dev)
 		}
 	}
 
-#if ALLOW_DMA
-	if (lp->use_dma && (lp->isa_config & ANY_ISA_DMA)) {
-		unsigned long flags;
-		lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL,
-								get_order(lp->dmasize * 1024));
-		if (!lp->dma_buff) {
-			pr_err("%s: cannot get %dK memory for DMA\n",
-			       dev->name, lp->dmasize);
-			goto release_irq;
-		}
-		cs89_dbg(1, debug, "%s: dma %lx %lx\n",
-			 dev->name,
-			 (unsigned long)lp->dma_buff,
-			 (unsigned long)isa_virt_to_bus(lp->dma_buff));
-		if ((unsigned long)lp->dma_buff >= MAX_DMA_ADDRESS ||
-		    !dma_page_eq(lp->dma_buff,
-				 lp->dma_buff + lp->dmasize * 1024 - 1)) {
-			pr_err("%s: not usable as DMA buffer\n", dev->name);
-			goto release_irq;
-		}
-		memset(lp->dma_buff, 0, lp->dmasize * 1024);	/* Why? */
-		if (request_dma(dev->dma, dev->name)) {
-			pr_err("%s: cannot get dma channel %d\n",
-			       dev->name, dev->dma);
-			goto release_irq;
-		}
-		write_dma(dev, lp->chip_type, dev->dma);
-		lp->rx_dma_ptr = lp->dma_buff;
-		lp->end_dma_buff = lp->dma_buff + lp->dmasize * 1024;
-		spin_lock_irqsave(&lp->lock, flags);
-		disable_dma(dev->dma);
-		clear_dma_ff(dev->dma);
-		set_dma_mode(dev->dma, DMA_RX_MODE); /* auto_init as well */
-		set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff));
-		set_dma_count(dev->dma, lp->dmasize * 1024);
-		enable_dma(dev->dma);
-		spin_unlock_irqrestore(&lp->lock, flags);
-	}
-#endif	/* ALLOW_DMA */
-
 	/* set the Ethernet address */
 	for (i = 0; i < ETH_ALEN / 2; i++)
 		writereg(dev, PP_IA + i * 2,
@@ -958,11 +657,6 @@ net_open(struct net_device *dev)
 		pr_err("%s: EEPROM is configured for unavailable media\n",
 		       dev->name);
 release_dma:
-#if ALLOW_DMA
-		free_dma(dev->dma);
-release_irq:
-		release_dma_buff(lp);
-#endif
 		writereg(dev, PP_LineCTL,
 			 readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
 		free_irq(dev->irq, dev);
@@ -1048,9 +742,6 @@ net_open(struct net_device *dev)
 
 	if (lp->isa_config & STREAM_TRANSFER)
 		lp->curr_rx_cfg |= RX_STREAM_ENBL;
-#if ALLOW_DMA
-	set_dma_cfg(dev);
-#endif
 	writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
 
 	writereg(dev, PP_TxCFG, (TX_LOST_CRS_ENBL |
@@ -1063,19 +754,12 @@ net_open(struct net_device *dev)
 
 	writereg(dev, PP_BufCFG, (READY_FOR_TX_ENBL |
 				  RX_MISS_COUNT_OVRFLOW_ENBL |
-#if ALLOW_DMA
-				  dma_bufcfg(dev) |
-#endif
 				  TX_COL_COUNT_OVRFLOW_ENBL |
 				  TX_UNDERRUN_ENBL));
 
 	/* now that we've got our act together, enable everything */
-	writereg(dev, PP_BusCTL, (ENABLE_IRQ
-				  | (dev->mem_start ? MEMORY_ON : 0) /* turn memory on */
-#if ALLOW_DMA
-				  | dma_busctl(dev)
-#endif
-			 ));
+	writereg(dev, PP_BusCTL,
+		 (ENABLE_IRQ | (dev->mem_start ? MEMORY_ON : 0))); /* turn memory on */
 	netif_start_queue(dev);
 	cs89_dbg(1, debug, "net_open() succeeded\n");
 	return 0;
@@ -1087,10 +771,6 @@ net_open(struct net_device *dev)
 static int
 net_close(struct net_device *dev)
 {
-#if ALLOW_DMA
-	struct net_local *lp = netdev_priv(dev);
-#endif
-
 	netif_stop_queue(dev);
 
 	writereg(dev, PP_RxCFG, 0);
@@ -1100,13 +780,6 @@ net_close(struct net_device *dev)
 
 	free_irq(dev->irq, dev);
 
-#if ALLOW_DMA
-	if (lp->use_dma && lp->dma) {
-		free_dma(dev->dma);
-		release_dma_buff(lp);
-	}
-#endif
-
 	/* Update the statistics here. */
 	return 0;
 }
@@ -1323,13 +996,6 @@ cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
 		memset(lp, 0, sizeof(*lp));
 		spin_lock_init(&lp->lock);
 #ifndef MODULE
-#if ALLOW_DMA
-		if (g_cs89x0_dma) {
-			lp->use_dma = 1;
-			lp->dma = g_cs89x0_dma;
-			lp->dmasize = 16;	/* Could make this an option... */
-		}
-#endif
 		lp->force = g_cs89x0_media__force;
 #endif
 	}
@@ -1527,40 +1193,12 @@ cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
 			dev->irq = i;
 	} else {
 		i = lp->isa_config & INT_NO_MASK;
-#if IS_ENABLED(CONFIG_CS89x0_ISA)
-		if (lp->chip_type == CS8900) {
-			/* Translate the IRQ using the IRQ mapping table. */
-			if (i >= ARRAY_SIZE(cs8900_irq_map))
-				pr_err("invalid ISA interrupt number %d\n", i);
-			else
-				i = cs8900_irq_map[i];
-
-			lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */
-		} else {
-			int irq_map_buff[IRQ_MAP_LEN/2];
-
-			if (get_eeprom_data(dev, IRQ_MAP_EEPROM_DATA,
-					    IRQ_MAP_LEN / 2,
-					    irq_map_buff) >= 0) {
-				if ((irq_map_buff[0] & 0xff) == PNP_IRQ_FRMT)
-					lp->irq_map = ((irq_map_buff[0] >> 8) |
-						       (irq_map_buff[1] << 8));
-			}
-		}
-#endif
 		if (!dev->irq)
 			dev->irq = i;
 	}
 
 	pr_cont(" IRQ %d", dev->irq);
-
-#if ALLOW_DMA
-	if (lp->use_dma) {
-		get_dma_channel(dev);
-		pr_cont(", DMA %d", dev->dma);
-	} else
-#endif
-		pr_cont(", programmed I/O");
+	pr_cont(", programmed I/O");
 
 	/* print the ethernet address. */
 	pr_cont(", MAC %pM\n", dev->dev_addr);
@@ -1580,270 +1218,6 @@ cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
 	return retval;
 }
 
-#if IS_ENABLED(CONFIG_CS89x0_ISA)
-/*
- * This function converts the I/O port address used by the cs89x0_probe() and
- * init_module() functions to the I/O memory address used by the
- * cs89x0_probe1() function.
- */
-static int __init
-cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular)
-{
-	struct net_local *lp = netdev_priv(dev);
-	int ret;
-	void __iomem *io_mem;
-
-	if (!lp)
-		return -ENOMEM;
-
-	dev->base_addr = ioport;
-
-	if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-	io_mem = ioport_map(ioport & ~3, NETCARD_IO_EXTENT);
-	if (!io_mem) {
-		ret = -ENOMEM;
-		goto release;
-	}
-
-	/* if they give us an odd I/O address, then do ONE write to
-	 * the address port, to get it back to address zero, where we
-	 * expect to find the EISA signature word. An IO with a base of 0x3
-	 * will skip the test for the ADD_PORT.
-	 */
-	if (ioport & 1) {
-		cs89_dbg(1, info, "%s: odd ioaddr 0x%lx\n", dev->name, ioport);
-		if ((ioport & 2) != 2) {
-			if ((ioread16(io_mem + ADD_PORT) & ADD_MASK) !=
-			    ADD_SIG) {
-				pr_err("%s: bad signature 0x%x\n",
-				       dev->name, ioread16(io_mem + ADD_PORT));
-				ret = -ENODEV;
-				goto unmap;
-			}
-		}
-	}
-
-	ret = cs89x0_probe1(dev, io_mem, modular);
-	if (!ret)
-		goto out;
-unmap:
-	ioport_unmap(io_mem);
-release:
-	release_region(ioport, NETCARD_IO_EXTENT);
-out:
-	return ret;
-}
-
-#ifndef MODULE
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- * If dev->base_addr == 2, allocate space for the device and return success
- * (detachable devices only).
- * Return 0 on success.
- */
-
-struct net_device * __init cs89x0_probe(int unit)
-{
-	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
-	unsigned *port;
-	int err = 0;
-	int irq;
-	int io;
-
-	if (!dev)
-		return ERR_PTR(-ENODEV);
-
-	sprintf(dev->name, "eth%d", unit);
-	netdev_boot_setup_check(dev);
-	io = dev->base_addr;
-	irq = dev->irq;
-
-	cs89_dbg(0, info, "cs89x0_probe(0x%x)\n", io);
-
-	if (io > 0x1ff)	{	/* Check a single specified location. */
-		err = cs89x0_ioport_probe(dev, io, 0);
-	} else if (io != 0) {	/* Don't probe at all. */
-		err = -ENXIO;
-	} else {
-		for (port = netcard_portlist; *port; port++) {
-			if (cs89x0_ioport_probe(dev, *port, 0) == 0)
-				break;
-			dev->irq = irq;
-		}
-		if (!*port)
-			err = -ENODEV;
-	}
-	if (err)
-		goto out;
-	return dev;
-out:
-	free_netdev(dev);
-	pr_warn("no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP\n");
-	return ERR_PTR(err);
-}
-#else
-static struct net_device *dev_cs89x0;
-
-/* Support the 'debug' module parm even if we're compiled for non-debug to
- * avoid breaking someone's startup scripts
- */
-
-static int io;
-static int irq;
-static int debug;
-static char media[8];
-static int duplex = -1;
-
-static int use_dma;			/* These generate unused var warnings if ALLOW_DMA = 0 */
-static int dma;
-static int dmasize = 16;		/* or 64 */
-
-module_param_hw(io, int, ioport, 0);
-module_param_hw(irq, int, irq, 0);
-module_param(debug, int, 0);
-module_param_string(media, media, sizeof(media), 0);
-module_param(duplex, int, 0);
-module_param_hw(dma , int, dma, 0);
-module_param(dmasize , int, 0);
-module_param(use_dma , int, 0);
-MODULE_PARM_DESC(io, "cs89x0 I/O base address");
-MODULE_PARM_DESC(irq, "cs89x0 IRQ number");
-#if DEBUGGING
-MODULE_PARM_DESC(debug, "cs89x0 debug level (0-6)");
-#else
-MODULE_PARM_DESC(debug, "(ignored)");
-#endif
-MODULE_PARM_DESC(media, "Set cs89x0 adapter(s) media type(s) (rj45,bnc,aui)");
-/* No other value than -1 for duplex seems to be currently interpreted */
-MODULE_PARM_DESC(duplex, "(ignored)");
-#if ALLOW_DMA
-MODULE_PARM_DESC(dma , "cs89x0 ISA DMA channel; ignored if use_dma=0");
-MODULE_PARM_DESC(dmasize , "cs89x0 DMA size in kB (16,64); ignored if use_dma=0");
-MODULE_PARM_DESC(use_dma , "cs89x0 using DMA (0-1)");
-#else
-MODULE_PARM_DESC(dma , "(ignored)");
-MODULE_PARM_DESC(dmasize , "(ignored)");
-MODULE_PARM_DESC(use_dma , "(ignored)");
-#endif
-
-MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton");
-MODULE_LICENSE("GPL");
-
-/*
- * media=t             - specify media type
- * or media=2
- * or media=aui
- * or medai=auto
- * duplex=0            - specify forced half/full/autonegotiate duplex
- * debug=#             - debug level
- *
- * Default Chip Configuration:
- * DMA Burst = enabled
- * IOCHRDY Enabled = enabled
- * UseSA = enabled
- * CS8900 defaults to half-duplex if not specified on command-line
- * CS8920 defaults to autoneg if not specified on command-line
- * Use reset defaults for other config parameters
- *
- * Assumptions:
- * media type specified is supported (circuitry is present)
- * if memory address is > 1MB, then required mem decode hw is present
- * if 10B-2, then agent other than driver will enable DC/DC converter
- * (hw or software util)
- */
-
-static int __init cs89x0_isa_init_module(void)
-{
-	struct net_device *dev;
-	struct net_local *lp;
-	int ret = 0;
-
-#if DEBUGGING
-	net_debug = debug;
-#else
-	debug = 0;
-#endif
-	dev = alloc_etherdev(sizeof(struct net_local));
-	if (!dev)
-		return -ENOMEM;
-
-	dev->irq = irq;
-	dev->base_addr = io;
-	lp = netdev_priv(dev);
-
-#if ALLOW_DMA
-	if (use_dma) {
-		lp->use_dma = use_dma;
-		lp->dma = dma;
-		lp->dmasize = dmasize;
-	}
-#endif
-
-	spin_lock_init(&lp->lock);
-
-	/* boy, they'd better get these right */
-	if (!strcmp(media, "rj45"))
-		lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
-	else if (!strcmp(media, "aui"))
-		lp->adapter_cnf = A_CNF_MEDIA_AUI   | A_CNF_AUI;
-	else if (!strcmp(media, "bnc"))
-		lp->adapter_cnf = A_CNF_MEDIA_10B_2 | A_CNF_10B_2;
-	else
-		lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
-
-	if (duplex == -1)
-		lp->auto_neg_cnf = AUTO_NEG_ENABLE;
-
-	if (io == 0) {
-		pr_err("Module autoprobing not allowed\n");
-		pr_err("Append io=0xNNN\n");
-		ret = -EPERM;
-		goto out;
-	} else if (io <= 0x1ff) {
-		ret = -ENXIO;
-		goto out;
-	}
-
-#if ALLOW_DMA
-	if (use_dma && dmasize != 16 && dmasize != 64) {
-		pr_err("dma size must be either 16K or 64K, not %dK\n",
-		       dmasize);
-		ret = -EPERM;
-		goto out;
-	}
-#endif
-	ret = cs89x0_ioport_probe(dev, io, 1);
-	if (ret)
-		goto out;
-
-	dev_cs89x0 = dev;
-	return 0;
-out:
-	free_netdev(dev);
-	return ret;
-}
-module_init(cs89x0_isa_init_module);
-
-static void __exit cs89x0_isa_cleanup_module(void)
-{
-	struct net_local *lp = netdev_priv(dev_cs89x0);
-
-	unregister_netdev(dev_cs89x0);
-	iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
-	ioport_unmap(lp->virt_addr);
-	release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
-	free_netdev(dev_cs89x0);
-}
-module_exit(cs89x0_isa_cleanup_module);
-#endif /* MODULE */
-#endif /* CONFIG_CS89x0_ISA */
-
-#if IS_ENABLED(CONFIG_CS89x0_PLATFORM)
 static int __init cs89x0_platform_probe(struct platform_device *pdev)
 {
 	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
@@ -1908,8 +1282,6 @@ static struct platform_driver cs89x0_driver = {
 
 module_platform_driver_probe(cs89x0_driver, cs89x0_platform_probe);
 
-#endif /* CONFIG_CS89x0_PLATFORM */
-
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Crystal Semiconductor (Now Cirrus Logic) CS89[02]0 network driver");
 MODULE_AUTHOR("Russell Nelson <nelson@crynwr.com>");
diff --git a/include/net/Space.h b/include/net/Space.h
index 6a0b6674d930..1b9ab0da5a03 100644
--- a/include/net/Space.h
+++ b/include/net/Space.h
@@ -4,4 +4,3 @@
  */
 
 struct net_device *ne_probe(int unit);
-struct net_device *cs89x0_probe(int unit);
-- 
2.39.5


^ permalink raw reply related

* [PATCH net-next 2/2] ne2k: fold drivers/net/Space.c into ne.c
From: Arnd Bergmann @ 2026-04-29 14:55 UTC (permalink / raw)
  To: Jonathan Corbet, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: Arnd Bergmann, Shuah Khan, Simon Horman, Andrew Morton,
	Borislav Petkov (AMD), linux-doc, linux-kernel, netdev
In-Reply-To: <20260429145624.2948432-1-arnd@kernel.org>

From: Arnd Bergmann <arnd@arndb.de>

drivers/net/Space.c is the last remnant of the linux-2.4.x driver model
that required each subsystem and device driver init function to be called
from init/main.c explicitly, before the introduction of initcall levels.

In linux-7.0, this was only used for a handful of ISA network drivers,
with the ne2000 driver being the last one.

Fold the code into ne.c directly, with minimal changes to preserve
the existing command line parsing.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 .../admin-guide/kernel-parameters.txt         |   6 +-
 Documentation/arch/m68k/kernel-options.rst    |  24 +-
 drivers/net/Kconfig                           |   7 -
 drivers/net/Makefile                          |   1 -
 drivers/net/Space.c                           | 234 -----------------
 drivers/net/ethernet/8390/Kconfig             |   1 -
 drivers/net/ethernet/8390/ne.c                | 237 ++++++++++++++++--
 include/linux/netdevice.h                     |   1 -
 include/net/Space.h                           |   6 -
 9 files changed, 220 insertions(+), 297 deletions(-)
 delete mode 100644 drivers/net/Space.c
 delete mode 100644 include/net/Space.h

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 41c657cd362c..f739e0aae337 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4266,12 +4266,8 @@ Kernel parameters
 
 	n2=		[NET] SDL Inc. RISCom/N2 synchronous serial card
 
-	netdev=		[NET] Network devices parameters
+	netdev=		[NET] NE2000 ISA network devices parameters
 			Format: <irq>,<io>,<mem_start>,<mem_end>,<name>
-			Note that mem_start is often overloaded to mean
-			something different and driver-specific.
-			This usage is only documented in each driver source
-			file if at all.
 
 	netpoll.carrier_timeout=
 			[NET] Specifies amount of time (in seconds) that
diff --git a/Documentation/arch/m68k/kernel-options.rst b/Documentation/arch/m68k/kernel-options.rst
index 2008a20b4329..c59e7aaed44e 100644
--- a/Documentation/arch/m68k/kernel-options.rst
+++ b/Documentation/arch/m68k/kernel-options.rst
@@ -244,23 +244,7 @@ drive (with "root=").
 3) General Device Options (Amiga and Atari)
 ===========================================
 
-3.1) ether=
------------
-
-:Syntax: ether=[<irq>[,<base_addr>[,<mem_start>[,<mem_end>]]]],<dev-name>
-
-<dev-name> is the name of a net driver, as specified in
-drivers/net/Space.c in the Linux source. Most prominent are eth0, ...
-eth3, sl0, ... sl3, ppp0, ..., ppp3, dummy, and lo.
-
-The non-ethernet drivers (sl, ppp, dummy, lo) obviously ignore the
-settings by this options. Also, the existing ethernet drivers for
-Linux/m68k (ariadne, a2065, hydra) don't use them because Zorro boards
-are really Plug-'n-Play, so the "ether=" option is useless altogether
-for Linux/m68k.
-
-
-3.2) hd=
+3.1) hd=
 --------
 
 :Syntax: hd=<cylinders>,<heads>,<sectors>
@@ -273,7 +257,7 @@ itself. It exists just for the case that this fails for one of your
 disks.
 
 
-3.3) max_scsi_luns=
+3.2) max_scsi_luns=
 -------------------
 
 :Syntax: max_scsi_luns=<n>
@@ -284,7 +268,7 @@ be scanned. Valid values for <n> are between 1 and 8. Default is 8 if
 configuration, else 1.
 
 
-3.4) st=
+3.3) st=
 --------
 
 :Syntax: st=<buffer_size>,[<write_thres>,[<max_buffers>]]
@@ -297,7 +281,7 @@ total number of buffers. <max_buffer> limits the total number of
 buffers allocated for all tape devices.
 
 
-3.5) dmasound=
+3.4) dmasound=
 --------------
 
 :Syntax: dmasound=[<buffers>,<buffer-size>[,<catch-radius>]]
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 8ec98f6dfef9..ff79c466712d 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -630,11 +630,4 @@ config NET_FAILOVER
 	  a VM with direct attached VF by failing over to the paravirtual
 	  datapath when the VF is unplugged.
 
-config NETDEV_LEGACY_INIT
-	bool
-	depends on ISA
-	help
-	  Drivers that call netdev_boot_setup_check() should select this
-	  symbol, everything else no longer needs it.
-
 endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b87a741fc952..88e4c485d6b2 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_MACVTAP) += macvtap.o
 obj-$(CONFIG_MII) += mii.o
 obj-$(CONFIG_MDIO) += mdio.o
 obj-$(CONFIG_NET) += loopback.o
-obj-$(CONFIG_NETDEV_LEGACY_INIT) += Space.o
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
 obj-$(CONFIG_NETKIT) += netkit.o
 obj-y += phy/
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
deleted file mode 100644
index c3ce960110b9..000000000000
--- a/drivers/net/Space.c
+++ /dev/null
@@ -1,234 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		Holds initial configuration information for devices.
- *
- * Version:	@(#)Space.c	1.0.7	08/12/93
- *
- * Authors:	Ross Biro
- *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Donald J. Becker, <becker@scyld.com>
- *
- * Changelog:
- *		Stephen Hemminger (09/2003)
- *		- get rid of pre-linked dev list, dynamic device allocation
- *		Paul Gortmaker (03/2002)
- *		- struct init cleanup, enable multiple ISA autoprobes.
- *		Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 09/1999
- *		- fix sbni: s/device/net_device/
- *		Paul Gortmaker (06/98):
- *		 - sort probes in a sane way, make sure all (safe) probes
- *		   get run once & failed autoprobes don't autoprobe again.
- */
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/netlink.h>
-#include <net/Space.h>
-
-/*
- * This structure holds boot-time configured netdevice settings. They
- * are then used in the device probing.
- */
-struct netdev_boot_setup {
-	char name[IFNAMSIZ];
-	struct ifmap map;
-};
-#define NETDEV_BOOT_SETUP_MAX 8
-
-
-/******************************************************************************
- *
- *		      Device Boot-time Settings Routines
- *
- ******************************************************************************/
-
-/* Boot time configuration table */
-static struct netdev_boot_setup dev_boot_setup[NETDEV_BOOT_SETUP_MAX];
-
-/**
- *	netdev_boot_setup_add	- add new setup entry
- *	@name: name of the device
- *	@map: configured settings for the device
- *
- *	Adds new setup entry to the dev_boot_setup list.  The function
- *	returns 0 on error and 1 on success.  This is a generic routine to
- *	all netdevices.
- */
-static int netdev_boot_setup_add(char *name, struct ifmap *map)
-{
-	struct netdev_boot_setup *s;
-	int i;
-
-	s = dev_boot_setup;
-	for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
-		if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {
-			strscpy_pad(s[i].name, name);
-			memcpy(&s[i].map, map, sizeof(s[i].map));
-			break;
-		}
-	}
-
-	return i >= NETDEV_BOOT_SETUP_MAX ? 0 : 1;
-}
-
-/**
- * netdev_boot_setup_check	- check boot time settings
- * @dev: the netdevice
- *
- * Check boot time settings for the device.
- * The found settings are set for the device to be used
- * later in the device probing.
- * Returns 0 if no settings found, 1 if they are.
- */
-int netdev_boot_setup_check(struct net_device *dev)
-{
-	struct netdev_boot_setup *s = dev_boot_setup;
-	int i;
-
-	for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
-		if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
-		    !strcmp(dev->name, s[i].name)) {
-			dev->irq = s[i].map.irq;
-			dev->base_addr = s[i].map.base_addr;
-			dev->mem_start = s[i].map.mem_start;
-			dev->mem_end = s[i].map.mem_end;
-			return 1;
-		}
-	}
-	return 0;
-}
-EXPORT_SYMBOL(netdev_boot_setup_check);
-
-/**
- * netdev_boot_base	- get address from boot time settings
- * @prefix: prefix for network device
- * @unit: id for network device
- *
- * Check boot time settings for the base address of device.
- * The found settings are set for the device to be used
- * later in the device probing.
- * Returns 0 if no settings found.
- */
-static unsigned long netdev_boot_base(const char *prefix, int unit)
-{
-	const struct netdev_boot_setup *s = dev_boot_setup;
-	char name[IFNAMSIZ];
-	int i;
-
-	sprintf(name, "%s%d", prefix, unit);
-
-	/*
-	 * If device already registered then return base of 1
-	 * to indicate not to probe for this interface
-	 */
-	if (__dev_get_by_name(&init_net, name))
-		return 1;
-
-	for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
-		if (!strcmp(name, s[i].name))
-			return s[i].map.base_addr;
-	return 0;
-}
-
-/*
- * Saves at boot time configured settings for any netdevice.
- */
-static int __init netdev_boot_setup(char *str)
-{
-	int ints[5];
-	struct ifmap map;
-
-	str = get_options(str, ARRAY_SIZE(ints), ints);
-	if (!str || !*str)
-		return 0;
-
-	/* Save settings */
-	memset(&map, 0, sizeof(map));
-	if (ints[0] > 0)
-		map.irq = ints[1];
-	if (ints[0] > 1)
-		map.base_addr = ints[2];
-	if (ints[0] > 2)
-		map.mem_start = ints[3];
-	if (ints[0] > 3)
-		map.mem_end = ints[4];
-
-	/* Add new entry to the list */
-	return netdev_boot_setup_add(str, &map);
-}
-
-__setup("netdev=", netdev_boot_setup);
-
-static int __init ether_boot_setup(char *str)
-{
-	return netdev_boot_setup(str);
-}
-__setup("ether=", ether_boot_setup);
-
-
-/* A unified ethernet device probe.  This is the easiest way to have every
- * ethernet adaptor have the name "eth[0123...]".
- */
-
-struct devprobe2 {
-	struct net_device *(*probe)(int unit);
-	int status;	/* non-zero if autoprobe has failed */
-};
-
-static int __init probe_list2(int unit, struct devprobe2 *p, int autoprobe)
-{
-	struct net_device *dev;
-
-	for (; p->probe; p++) {
-		if (autoprobe && p->status)
-			continue;
-		dev = p->probe(unit);
-		if (!IS_ERR(dev))
-			return 0;
-		if (autoprobe)
-			p->status = PTR_ERR(dev);
-	}
-	return -ENODEV;
-}
-
-/* ISA probes that touch addresses < 0x400 (including those that also
- * look for EISA/PCI cards in addition to ISA cards).
- */
-static struct devprobe2 isa_probes[] __initdata = {
-#if defined(CONFIG_NE2000) /* ISA (use ne2k-pci for PCI cards) */
-	{ne_probe, 0},
-#endif
-	{NULL, 0},
-};
-
-/* Unified ethernet device probe, segmented per architecture and
- * per bus interface. This drives the legacy devices only for now.
- */
-
-static void __init ethif_probe2(int unit)
-{
-	unsigned long base_addr = netdev_boot_base("eth", unit);
-
-	if (base_addr == 1)
-		return;
-
-	probe_list2(unit, isa_probes, base_addr == 0);
-}
-
-/*  Statically configured drivers -- order matters here. */
-static int __init net_olddevs_init(void)
-{
-	int num;
-
-	for (num = 0; num < 8; ++num)
-		ethif_probe2(num);
-
-	return 0;
-}
-
-device_initcall(net_olddevs_init);
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig
index 5d12a595ab19..57d73a7747ec 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -90,7 +90,6 @@ config MCF8390
 config NE2000
 	tristate "NE2000/NE1000 support"
 	depends on (ISA || (Q40 && m) || MACH_TX49XX || ATARI_ETHERNEC)
-	select NETDEV_LEGACY_INIT if ISA
 	select CRC32
 	help
 	  If you have a network (Ethernet) card of this type, say Y here.
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c
index 961019c32842..1cbd5a4977ce 100644
--- a/drivers/net/ethernet/8390/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -50,7 +50,6 @@ static const char version2[] =
 #include <linux/etherdevice.h>
 #include <linux/jiffies.h>
 #include <linux/platform_device.h>
-#include <net/Space.h>
 
 #include <asm/io.h>
 
@@ -182,7 +181,6 @@ static void ne_block_input(struct net_device *dev, int count,
 static void ne_block_output(struct net_device *dev, const int count,
 		const unsigned char *buf, const int start_page);
 
-
 /*  Probe for various non-shared-memory ethercards.
 
    NEx000-clone boards have a Station Address PROM (SAPROM) in the packet
@@ -918,31 +916,47 @@ static void __init ne_add_devices(void)
 	}
 }
 
-static int __init ne_init(void)
+/*
+ * This structure holds boot-time configured netdevice settings. They
+ * are then used in the device probing.
+ */
+struct netdev_boot_setup {
+	char name[IFNAMSIZ];
+	struct ifmap map;
+};
+#define NETDEV_BOOT_SETUP_MAX 8
+
+/* Boot time configuration table */
+static struct netdev_boot_setup dev_boot_setup[NETDEV_BOOT_SETUP_MAX];
+
+/**
+ * netdev_boot_setup_check	- check boot time settings
+ * @dev: the netdevice
+ *
+ * Check boot time settings for the device.
+ * The found settings are set for the device to be used
+ * later in the device probing.
+ * Returns 0 if no settings found, 1 if they are.
+ */
+static int netdev_boot_setup_check(struct net_device *dev)
 {
-	int retval;
-
-	if (IS_MODULE(CONFIG_NE2000))
-		ne_add_devices();
-
-	retval = platform_driver_probe(&ne_driver, ne_drv_probe);
+	struct netdev_boot_setup *s = dev_boot_setup;
+	int i;
 
-	if (IS_MODULE(CONFIG_NE2000) && retval) {
-		if (io[0] == 0)
-			pr_notice("ne.c: You must supply \"io=0xNNN\""
-			       " value(s) for ISA cards.\n");
-		ne_loop_rm_unreg(1);
-		return retval;
+	for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
+		if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
+		    !strcmp(dev->name, s[i].name)) {
+			dev->irq = s[i].map.irq;
+			dev->base_addr = s[i].map.base_addr;
+			dev->mem_start = s[i].map.mem_start;
+			dev->mem_end = s[i].map.mem_end;
+			return 1;
+		}
 	}
-
-	/* Unregister unused platform_devices. */
-	ne_loop_rm_unreg(0);
-	return retval;
+	return 0;
 }
-module_init(ne_init);
 
-#if !defined(MODULE) && defined(CONFIG_NETDEV_LEGACY_INIT)
-struct net_device * __init ne_probe(int unit)
+static struct net_device * __init ne_probe(int unit)
 {
 	int this_dev;
 	struct net_device *dev;
@@ -982,8 +996,187 @@ struct net_device * __init ne_probe(int unit)
 
 	return ERR_PTR(-ENODEV);
 }
+
+/******************************************************************************
+ *
+ *		      Device Boot-time Settings Routines
+ *
+ ******************************************************************************/
+
+/**
+ * netdev_boot_base	- get address from boot time settings
+ * @prefix: prefix for network device
+ * @unit: id for network device
+ *
+ * Check boot time settings for the base address of device.
+ * The found settings are set for the device to be used
+ * later in the device probing.
+ * Returns 0 if no settings found.
+ */
+static unsigned long netdev_boot_base(const char *prefix, int unit)
+{
+	const struct netdev_boot_setup *s = dev_boot_setup;
+	char name[IFNAMSIZ];
+	int i;
+
+	sprintf(name, "%s%d", prefix, unit);
+
+	/*
+	 * If device already registered then return base of 1
+	 * to indicate not to probe for this interface
+	 */
+	if (__dev_get_by_name(&init_net, name))
+		return 1;
+
+	for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
+		if (!strcmp(name, s[i].name))
+			return s[i].map.base_addr;
+	return 0;
+}
+
+#if !defined(MODULE) && defined(CONFIG_ISA)
+/**
+ *	netdev_boot_setup_add	- add new setup entry
+ *	@name: name of the device
+ *	@map: configured settings for the device
+ *
+ *	Adds new setup entry to the dev_boot_setup list.  The function
+ *	returns 0 on error and 1 on success.  This is a generic routine to
+ *	all netdevices.
+ */
+static int netdev_boot_setup_add(char *name, struct ifmap *map)
+{
+	struct netdev_boot_setup *s;
+	int i;
+
+	s = dev_boot_setup;
+	for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
+		if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {
+			strscpy_pad(s[i].name, name);
+			memcpy(&s[i].map, map, sizeof(s[i].map));
+			break;
+		}
+	}
+
+	return i >= NETDEV_BOOT_SETUP_MAX ? 0 : 1;
+}
+
+/*
+ * Saves at boot time configured settings for any netdevice.
+ */
+static int __init netdev_boot_setup(char *str)
+{
+	int ints[5];
+	struct ifmap map;
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+	if (!str || !*str)
+		return 0;
+
+	/* Save settings */
+	memset(&map, 0, sizeof(map));
+	if (ints[0] > 0)
+		map.irq = ints[1];
+	if (ints[0] > 1)
+		map.base_addr = ints[2];
+	if (ints[0] > 2)
+		map.mem_start = ints[3];
+	if (ints[0] > 3)
+		map.mem_end = ints[4];
+
+	/* Add new entry to the list */
+	return netdev_boot_setup_add(str, &map);
+}
+
+__setup("netdev=", netdev_boot_setup);
+
+static int __init ether_boot_setup(char *str)
+{
+	return netdev_boot_setup(str);
+}
+__setup("ether=", ether_boot_setup);
 #endif
 
+/* A unified ethernet device probe.  This is the easiest way to have every
+ * ethernet adaptor have the name "eth[0123...]".
+ */
+
+struct devprobe2 {
+	struct net_device *(*probe)(int unit);
+	int status;	/* non-zero if autoprobe has failed */
+};
+
+static int __init probe_list2(int unit, struct devprobe2 *p, int autoprobe)
+{
+	struct net_device *dev;
+
+	for (; p->probe; p++) {
+		if (autoprobe && p->status)
+			continue;
+		dev = p->probe(unit);
+		if (!IS_ERR(dev))
+			return 0;
+		if (autoprobe)
+			p->status = PTR_ERR(dev);
+	}
+	return -ENODEV;
+}
+
+static struct devprobe2 isa_probes[] __initdata = {
+	{ne_probe, 0},
+	{NULL, 0},
+};
+
+/* Unified ethernet device probe, segmented per architecture and
+ * per bus interface. This drives the legacy devices only for now.
+ */
+
+static void __init ethif_probe2(int unit)
+{
+	unsigned long base_addr = netdev_boot_base("eth", unit);
+
+	if (base_addr == 1)
+		return;
+
+	probe_list2(unit, isa_probes, base_addr == 0);
+}
+
+/*  Statically configured drivers -- order matters here. */
+static int __init net_olddevs_init(void)
+{
+	int num;
+
+	for (num = 0; num < 8; ++num)
+		ethif_probe2(num);
+
+	return 0;
+}
+
+static int __init ne_init(void)
+{
+	int retval;
+
+	if (IS_MODULE(CONFIG_NE2000))
+		ne_add_devices();
+	else
+		net_olddevs_init();
+
+	retval = platform_driver_probe(&ne_driver, ne_drv_probe);
+
+	if (IS_MODULE(CONFIG_NE2000) && retval) {
+		if (io[0] == 0)
+			pr_notice("ne.c: You must supply \"io=0xNNN\""
+			       " value(s) for ISA cards.\n");
+		ne_loop_rm_unreg(1);
+		return retval;
+	}
+
+	/* Unregister unused platform_devices. */
+	ne_loop_rm_unreg(0);
+	return retval;
+}
+module_init(ne_init);
+
 static void __exit ne_exit(void)
 {
 	platform_driver_unregister(&ne_driver);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 99fcb5ac45bc..2f5de3e83ed6 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3384,7 +3384,6 @@ static inline struct net_device *first_net_device(struct net *net)
 		net_device_entry(net->dev_base_head.next);
 }
 
-int netdev_boot_setup_check(struct net_device *dev);
 struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type,
 				   const char *hwaddr);
 struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
diff --git a/include/net/Space.h b/include/net/Space.h
deleted file mode 100644
index 1b9ab0da5a03..000000000000
--- a/include/net/Space.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* A unified ethernet device probe.  This is the easiest way to have every
- * ethernet adaptor have the name "eth[0123...]".
- */
-
-struct net_device *ne_probe(int unit);
-- 
2.39.5


^ permalink raw reply related

* [PATCH net] net: eth: fbnic: Fix addr validation in pcs write
From: mike.marciniszyn @ 2026-04-29 15:00 UTC (permalink / raw)
  To: Alexander Duyck, Jakub Kicinski, kernel-team, Andrew Lunn,
	David S. Miller, Eric Dumazet, Paolo Abeni
  Cc: mike.marciniszyn, netdev, linux-kernel, stable

From: "Mike Marciniszyn (Meta)" <mike.marciniszyn@gmail.com>

This patch contains a fix for addr validation in fbnic_mdio_write_pcs().

Cc: stable@vger.kernel.org
Fixes: d0ce9fd7eae0 ("fbnic: Add SW shim for MDIO interface to PMD and PCS")
Signed-off-by: Mike Marciniszyn (Meta) <mike.marciniszyn@gmail.com>
---
 drivers/net/ethernet/meta/fbnic/fbnic_mdio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c b/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c
index 709041f7fc43..d6a124889f52 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c
@@ -125,7 +125,7 @@ fbnic_mdio_write_pcs(struct fbnic_dev *fbd, int addr, int regnum, u16 val)
 		addr, regnum, val);
 
 	/* Allow access to both halves of PCS for 50R2 config */
-	if (addr > 2)
+	if (addr >= 2)
 		return;
 
 	/* Skip write for reserved registers */
-- 
2.43.0


^ permalink raw reply related

* [PATCH net-next 0/2] dpll: rework fractional frequency offset reporting
From: Ivan Vecera @ 2026-04-29 15:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Arkadiusz Kubalewski, David S. Miller, Donald Hunter,
	Eric Dumazet, Jakub Kicinski, Jiri Pirko, Jonathan Corbet,
	Leon Romanovsky, Mark Bloch, Michal Schmidt, Paolo Abeni,
	Pasi Vaananen, Petr Oros, Prathosh Satish, Saeed Mahameed,
	Shuah Khan, Simon Horman, Tariq Toukan, Vadim Fedorenko,
	linux-doc, linux-kernel, linux-rdma

Rework how the fractional frequency offset (FFO) is reported in
the DPLL subsystem.

The fractional-frequency-offset-ppt attribute is moved from the
top-level pin attributes into the pin-parent-device nested attribute
set. This makes it consistent with phase-offset (which is already
per-parent) and clarifies that FFO PPT represents the frequency
difference between a pin and its parent DPLL device.

The two FFO contexts are distinguished in the ffo_get callback:
dpll=NULL for the top-level RX vs TX symbol rate offset and a valid
dpll pointer for the nested pin vs DPLL offset.

Patch 1 restructures the DPLL subsystem netlink handling, updates
the YAML spec and driver-api documentation, and adds NULL guards
to mlx5 and zl3073x drivers.

Patch 2 implements the nested FFO for zl3073x using the
dpll_df_offset_x register with ref_ofst=1, providing 2^-48
resolution. The old per-reference frequency measurement is removed
as it was redundant with measured-frequency.

Ivan Vecera (2):
  dpll: move fractional-frequency-offset-ppt under pin-parent-device
  dpll: zl3073x: report FFO as DPLL vs input reference offset

 Documentation/driver-api/dpll.rst             | 16 +++++++
 Documentation/netlink/specs/dpll.yaml         | 11 +++--
 drivers/dpll/dpll_netlink.c                   | 34 ++++++++++----
 drivers/dpll/dpll_nl.c                        |  1 +
 drivers/dpll/zl3073x/chan.c                   | 31 ++++++++++++-
 drivers/dpll/zl3073x/chan.h                   | 14 ++++++
 drivers/dpll/zl3073x/core.c                   | 45 -------------------
 drivers/dpll/zl3073x/dpll.c                   | 34 +++++++-------
 drivers/dpll/zl3073x/ref.h                    | 14 ------
 drivers/dpll/zl3073x/regs.h                   | 15 +++++++
 .../net/ethernet/mellanox/mlx5/core/dpll.c    |  4 ++
 11 files changed, 126 insertions(+), 93 deletions(-)


-- 
2.53.0


^ permalink raw reply

* [PATCH net-next 1/2] dpll: move fractional-frequency-offset-ppt under pin-parent-device
From: Ivan Vecera @ 2026-04-29 15:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Arkadiusz Kubalewski, David S. Miller, Donald Hunter,
	Eric Dumazet, Jakub Kicinski, Jiri Pirko, Jonathan Corbet,
	Leon Romanovsky, Mark Bloch, Michal Schmidt, Paolo Abeni,
	Pasi Vaananen, Petr Oros, Prathosh Satish, Saeed Mahameed,
	Shuah Khan, Simon Horman, Tariq Toukan, Vadim Fedorenko,
	linux-doc, linux-kernel, linux-rdma
In-Reply-To: <20260429150817.3059763-1-ivecera@redhat.com>

Move the fractional-frequency-offset-ppt attribute from the top-level
pin attributes into the pin-parent-device nested attribute set. This
makes it consistent with phase-offset which is already per-parent and
clarifies that FFO PPT represents the frequency difference between
a pin and its parent DPLL device.

The top-level fractional-frequency-offset attribute (in PPM) remains
unchanged for backward compatibility.

Distinguish the two contexts in the ffo_get callback by passing
dpll=NULL for the top-level (rx vs tx symbol rate) call and a valid
dpll pointer for the nested (pin vs parent DPLL) call. Update mlx5
and zl3073x drivers to return -ENODATA for the nested context they
do not yet support.

Add documentation for both FFO attributes to dpll.rst.

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
 Documentation/driver-api/dpll.rst             | 16 +++++++++
 Documentation/netlink/specs/dpll.yaml         | 11 +++---
 drivers/dpll/dpll_netlink.c                   | 34 ++++++++++++++-----
 drivers/dpll/dpll_nl.c                        |  1 +
 drivers/dpll/zl3073x/dpll.c                   |  4 +++
 .../net/ethernet/mellanox/mlx5/core/dpll.c    |  4 +++
 6 files changed, 56 insertions(+), 14 deletions(-)

diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst
index 93c191b2d0898..007e07ef3a840 100644
--- a/Documentation/driver-api/dpll.rst
+++ b/Documentation/driver-api/dpll.rst
@@ -250,6 +250,22 @@ in the ``DPLL_A_PIN_PHASE_OFFSET`` attribute.
   ``DPLL_A_PHASE_OFFSET_MONITOR`` attr state of a feature
   =============================== ========================
 
+Fractional frequency offset
+===========================
+
+The fractional frequency offset (FFO) represents the frequency difference
+between a pin and its parent DPLL device. It is reported in the
+``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT`` attribute nested under
+the parent device, in parts per trillion (PPT, 10^-12).
+
+This is analogous to ``DPLL_A_PIN_PHASE_OFFSET`` but in the frequency
+domain. It is typically reported only for the currently active input pin.
+
+The top-level ``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET`` attribute (in PPM)
+represents the RX vs TX symbol rate offset on the media associated with
+the pin (e.g. for SyncE ethernet ports) and is independent of the
+per-parent FFO PPT attribute.
+
 Frequency monitor
 =================
 
diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml
index 40465a3d7fc20..bf13c0e27c749 100644
--- a/Documentation/netlink/specs/dpll.yaml
+++ b/Documentation/netlink/specs/dpll.yaml
@@ -471,12 +471,10 @@ attribute-sets:
         name: fractional-frequency-offset-ppt
         type: sint
         doc: |
-          The FFO (Fractional Frequency Offset) of the pin with respect to
-          the nominal frequency.
-          Value = (frequency_measured - frequency_nominal) / frequency_nominal
+          The FFO (Fractional Frequency Offset) between a pin and its
+          parent DPLL device, similar to phase-offset but in frequency
+          domain.
           Value is in PPT (parts per trillion, 10^-12).
-          Note: This attribute provides higher resolution than the standard
-          fractional-frequency-offset (which is in PPM).
       -
         name: measured-frequency
         type: u64
@@ -503,6 +501,8 @@ attribute-sets:
         name: state
       -
         name: phase-offset
+      -
+        name: fractional-frequency-offset-ppt
   -
     name: pin-parent-pin
     subset-of: pin
@@ -672,7 +672,6 @@ operations:
             - phase-adjust-max
             - phase-adjust
             - fractional-frequency-offset
-            - fractional-frequency-offset-ppt
             - esync-frequency
             - esync-frequency-supported
             - esync-pulse
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
index af7ce62ec55ca..89d657df66ee0 100644
--- a/drivers/dpll/dpll_netlink.c
+++ b/drivers/dpll/dpll_netlink.c
@@ -394,6 +394,27 @@ dpll_msg_add_phase_offset(struct sk_buff *msg, struct dpll_pin *pin,
 static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
 			    struct dpll_pin_ref *ref,
 			    struct netlink_ext_ack *extack)
+{
+	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
+	s64 ffo;
+	int ret;
+
+	if (!ops->ffo_get)
+		return 0;
+	ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(ref->dpll, pin),
+			   NULL, NULL, &ffo, extack);
+	if (ret) {
+		if (ret == -ENODATA)
+			return 0;
+		return ret;
+	}
+	return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
+			    div_s64(ffo, 1000000));
+}
+
+static int dpll_msg_add_ffo_ppt(struct sk_buff *msg, struct dpll_pin *pin,
+				struct dpll_pin_ref *ref,
+				struct netlink_ext_ack *extack)
 {
 	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
 	struct dpll_device *dpll = ref->dpll;
@@ -409,14 +430,8 @@ static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
 			return 0;
 		return ret;
 	}
-	/* Put the FFO value in PPM to preserve compatibility with older
-	 * programs.
-	 */
-	ret = nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
-			   div_s64(ffo, 1000000));
-	if (ret)
-		return -EMSGSIZE;
-	return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
+	return nla_put_sint(msg,
+			    DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
 			    ffo);
 }
 
@@ -659,6 +674,9 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
 		if (ret)
 			goto nest_cancel;
 		ret = dpll_msg_add_phase_offset(msg, pin, ref, extack);
+		if (ret)
+			goto nest_cancel;
+		ret = dpll_msg_add_ffo_ppt(msg, pin, ref, extack);
 		if (ret)
 			goto nest_cancel;
 		nla_nest_end(msg, attr);
diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c
index 1e652340a5d73..6e4535bac1580 100644
--- a/drivers/dpll/dpll_nl.c
+++ b/drivers/dpll/dpll_nl.c
@@ -18,6 +18,7 @@ const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_PHASE_OFFSET
 	[DPLL_A_PIN_PRIO] = { .type = NLA_U32, },
 	[DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
 	[DPLL_A_PIN_PHASE_OFFSET] = { .type = NLA_S64, },
+	[DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT] = { .type = NLA_SINT, },
 };
 
 const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1] = {
diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
index c95e93ef3ab04..6e9dfaf7309f7 100644
--- a/drivers/dpll/zl3073x/dpll.c
+++ b/drivers/dpll/zl3073x/dpll.c
@@ -299,6 +299,10 @@ zl3073x_dpll_input_pin_ffo_get(const struct dpll_pin *dpll_pin, void *pin_priv,
 {
 	struct zl3073x_dpll_pin *pin = pin_priv;
 
+	/* Only rx vs tx symbol rate FFO is supported */
+	if (dpll)
+		return -ENODATA;
+
 	*ffo = pin->freq_offset;
 
 	return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
index bce72e8d1bc31..ef2c58c390efa 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
@@ -306,6 +306,10 @@ static int mlx5_dpll_ffo_get(const struct dpll_pin *pin, void *pin_priv,
 	struct mlx5_dpll *mdpll = pin_priv;
 	int err;
 
+	/* Only rx vs tx symbol rate FFO is supported */
+	if (dpll)
+		return -ENODATA;
+
 	err = mlx5_dpll_synce_status_get(mdpll->mdev, &synce_status);
 	if (err)
 		return err;
-- 
2.53.0


^ permalink raw reply related

* [PATCH net-next 2/2] dpll: zl3073x: report FFO as DPLL vs input reference offset
From: Ivan Vecera @ 2026-04-29 15:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Arkadiusz Kubalewski, David S. Miller, Donald Hunter,
	Eric Dumazet, Jakub Kicinski, Jiri Pirko, Jonathan Corbet,
	Leon Romanovsky, Mark Bloch, Michal Schmidt, Paolo Abeni,
	Pasi Vaananen, Petr Oros, Prathosh Satish, Saeed Mahameed,
	Shuah Khan, Simon Horman, Tariq Toukan, Vadim Fedorenko,
	linux-doc, linux-kernel, linux-rdma
In-Reply-To: <20260429150817.3059763-1-ivecera@redhat.com>

Replace the per-reference frequency offset measurement (which was
redundant with measured-frequency) with a direct read of the DPLL's
delta frequency offset vs its tracked input reference.

The new implementation uses the dpll_df_offset_x register with
ref_ofst=1 via the dpll_df_read_x semaphore mechanism. This
provides 2^-48 resolution (~3.5 fE) and reports the actual
frequency difference between the DPLL and its active input.

FFO is now reported only for the active input pin in the nested
(pin vs parent DPLL) context. Top-level FFO returns -ENODATA.

Rewrite ffo_check to compare the cached df_offset converted to PPT
instead of using the old per-reference measurement. Remove the
ref_ffo_update periodic measurement and the ref ffo field since
they are no longer needed.

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
 drivers/dpll/zl3073x/chan.c | 31 +++++++++++++++++++++++--
 drivers/dpll/zl3073x/chan.h | 14 ++++++++++++
 drivers/dpll/zl3073x/core.c | 45 -------------------------------------
 drivers/dpll/zl3073x/dpll.c | 34 ++++++++++++----------------
 drivers/dpll/zl3073x/ref.h  | 14 ------------
 drivers/dpll/zl3073x/regs.h | 15 +++++++++++++
 6 files changed, 72 insertions(+), 81 deletions(-)

diff --git a/drivers/dpll/zl3073x/chan.c b/drivers/dpll/zl3073x/chan.c
index 2f48ca2391494..2fe3c3da84bb5 100644
--- a/drivers/dpll/zl3073x/chan.c
+++ b/drivers/dpll/zl3073x/chan.c
@@ -18,6 +18,7 @@
 int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index)
 {
 	struct zl3073x_chan *chan = &zldev->chan[index];
+	u64 val;
 	int rc;
 
 	rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_MON_STATUS(index),
@@ -25,8 +26,34 @@ int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index)
 	if (rc)
 		return rc;
 
-	return zl3073x_read_u8(zldev, ZL_REG_DPLL_REFSEL_STATUS(index),
-			       &chan->refsel_status);
+	rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_REFSEL_STATUS(index),
+			     &chan->refsel_status);
+	if (rc)
+		return rc;
+
+	/* Read df_offset vs tracked reference */
+	rc = zl3073x_poll_zero_u8(zldev, ZL_REG_DPLL_DF_READ(index),
+				  ZL_DPLL_DF_READ_SEM);
+	if (rc)
+		return rc;
+
+	rc = zl3073x_write_u8(zldev, ZL_REG_DPLL_DF_READ(index),
+			      ZL_DPLL_DF_READ_SEM | ZL_DPLL_DF_READ_REF_OFST);
+	if (rc)
+		return rc;
+
+	rc = zl3073x_poll_zero_u8(zldev, ZL_REG_DPLL_DF_READ(index),
+				  ZL_DPLL_DF_READ_SEM);
+	if (rc)
+		return rc;
+
+	rc = zl3073x_read_u48(zldev, ZL_REG_DPLL_DF_OFFSET(index), &val);
+	if (rc)
+		return rc;
+
+	chan->df_offset = sign_extend64(val, 47);
+
+	return 0;
 }
 
 /**
diff --git a/drivers/dpll/zl3073x/chan.h b/drivers/dpll/zl3073x/chan.h
index 481da2133202b..4353809c69122 100644
--- a/drivers/dpll/zl3073x/chan.h
+++ b/drivers/dpll/zl3073x/chan.h
@@ -17,6 +17,7 @@ struct zl3073x_dev;
  * @ref_prio: reference priority registers (4 bits per ref, P/N packed)
  * @mon_status: monitor status register value
  * @refsel_status: reference selection status register value
+ * @df_offset: frequency offset vs tracked reference in 2^-48 steps
  */
 struct zl3073x_chan {
 	struct_group(cfg,
@@ -26,6 +27,7 @@ struct zl3073x_chan {
 	struct_group(stat,
 		u8	mon_status;
 		u8	refsel_status;
+		s64	df_offset;
 	);
 };
 
@@ -37,6 +39,18 @@ int zl3073x_chan_state_set(struct zl3073x_dev *zldev, u8 index,
 
 int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index);
 
+/**
+ * zl3073x_chan_df_offset_get - get cached df_offset vs tracked reference
+ * @chan: pointer to channel state
+ *
+ * Return: frequency offset in 2^-48 steps
+ */
+static inline s64
+zl3073x_chan_df_offset_get(const struct zl3073x_chan *chan)
+{
+	return chan->df_offset;
+}
+
 /**
  * zl3073x_chan_mode_get - get DPLL channel operating mode
  * @chan: pointer to channel state
diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c
index 5f1e70f3e40a0..b3345060490db 100644
--- a/drivers/dpll/zl3073x/core.c
+++ b/drivers/dpll/zl3073x/core.c
@@ -704,44 +704,6 @@ zl3073x_ref_freq_meas_update(struct zl3073x_dev *zldev)
 	return 0;
 }
 
-/**
- * zl3073x_ref_ffo_update - update reference fractional frequency offsets
- * @zldev: pointer to zl3073x_dev structure
- *
- * The function asks device to latch the latest measured fractional
- * frequency offset values, reads and stores them into the ref state.
- *
- * Return: 0 on success, <0 on error
- */
-static int
-zl3073x_ref_ffo_update(struct zl3073x_dev *zldev)
-{
-	int i, rc;
-
-	rc = zl3073x_ref_freq_meas_latch(zldev,
-					 ZL_REF_FREQ_MEAS_CTRL_REF_FREQ_OFF);
-	if (rc)
-		return rc;
-
-	/* Read DPLL-to-REFx frequency offset measurements */
-	for (i = 0; i < ZL3073X_NUM_REFS; i++) {
-		s32 value;
-
-		/* Read value stored in units of 2^-32 signed */
-		rc = zl3073x_read_u32(zldev, ZL_REG_REF_FREQ(i), &value);
-		if (rc)
-			return rc;
-
-		/* Convert to ppt
-		 * ffo = (10^12 * value) / 2^32
-		 * ffo = ( 5^12 * value) / 2^20
-		 */
-		zldev->ref[i].ffo = mul_s64_u64_shr(value, 244140625, 20);
-	}
-
-	return 0;
-}
-
 static void
 zl3073x_dev_periodic_work(struct kthread_work *work)
 {
@@ -776,13 +738,6 @@ zl3073x_dev_periodic_work(struct kthread_work *work)
 		}
 	}
 
-	/* Update references' fractional frequency offsets */
-	rc = zl3073x_ref_ffo_update(zldev);
-	if (rc)
-		dev_warn(zldev->dev,
-			 "Failed to update fractional frequency offsets: %pe\n",
-			 ERR_PTR(rc));
-
 	list_for_each_entry(zldpll, &zldev->dplls, list)
 		zl3073x_dpll_changes_check(zldpll);
 
diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
index 6e9dfaf7309f7..06dec77b2a516 100644
--- a/drivers/dpll/zl3073x/dpll.c
+++ b/drivers/dpll/zl3073x/dpll.c
@@ -299,8 +299,12 @@ zl3073x_dpll_input_pin_ffo_get(const struct dpll_pin *dpll_pin, void *pin_priv,
 {
 	struct zl3073x_dpll_pin *pin = pin_priv;
 
-	/* Only rx vs tx symbol rate FFO is supported */
-	if (dpll)
+	/* Only nested FFO (pin vs parent DPLL) is supported */
+	if (!dpll)
+		return -ENODATA;
+
+	/* Report FFO only for the active pin */
+	if (pin->operstate != DPLL_PIN_OPERSTATE_ACTIVE)
 		return -ENODATA;
 
 	*ffo = pin->freq_offset;
@@ -1699,37 +1703,27 @@ zl3073x_dpll_pin_phase_offset_check(struct zl3073x_dpll_pin *pin)
 }
 
 /**
- * zl3073x_dpll_pin_ffo_check - check for pin fractional frequency offset change
+ * zl3073x_dpll_pin_ffo_check - check for FFO change on active pin
  * @pin: pin to check
  *
- * Check for the given pin's fractional frequency change.
- *
- * Return: true on fractional frequency offset change, false otherwise
+ * Return: true on change, false otherwise
  */
 static bool
 zl3073x_dpll_pin_ffo_check(struct zl3073x_dpll_pin *pin)
 {
 	struct zl3073x_dpll *zldpll = pin->dpll;
-	struct zl3073x_dev *zldev = zldpll->dev;
-	const struct zl3073x_ref *ref;
-	u8 ref_id;
+	const struct zl3073x_chan *chan;
 	s64 ffo;
 
-	/* Get reference monitor status */
-	ref_id = zl3073x_input_pin_ref_get(pin->id);
-	ref = zl3073x_ref_state_get(zldev, ref_id);
-
-	/* Do not report ffo changes if the reference monitor report errors */
-	if (!zl3073x_ref_is_status_ok(ref))
+	if (pin->operstate != DPLL_PIN_OPERSTATE_ACTIVE)
 		return false;
 
-	/* Compare with previous value */
-	ffo = zl3073x_ref_ffo_get(ref);
+	chan = zl3073x_chan_state_get(zldpll->dev, zldpll->id);
+	ffo = mul_s64_u64_shr(zl3073x_chan_df_offset_get(chan),
+			      244140625, 36);
+
 	if (pin->freq_offset != ffo) {
-		dev_dbg(zldev->dev, "%s freq offset changed: %lld -> %lld\n",
-			pin->label, pin->freq_offset, ffo);
 		pin->freq_offset = ffo;
-
 		return true;
 	}
 
diff --git a/drivers/dpll/zl3073x/ref.h b/drivers/dpll/zl3073x/ref.h
index 55e80e4f08734..e140ca3ea17dc 100644
--- a/drivers/dpll/zl3073x/ref.h
+++ b/drivers/dpll/zl3073x/ref.h
@@ -22,7 +22,6 @@ struct zl3073x_dev;
  * @freq_ratio_n: FEC mode divisor
  * @sync_ctrl: reference sync control
  * @config: reference config
- * @ffo: current fractional frequency offset
  * @meas_freq: measured input frequency in Hz
  * @mon_status: reference monitor status
  */
@@ -40,7 +39,6 @@ struct zl3073x_ref {
 		u8	config;
 	);
 	struct_group(stat, /* Status */
-		s64	ffo;
 		u32	meas_freq;
 		u8	mon_status;
 	);
@@ -58,18 +56,6 @@ int zl3073x_ref_state_update(struct zl3073x_dev *zldev, u8 index);
 
 int zl3073x_ref_freq_factorize(u32 freq, u16 *base, u16 *mult);
 
-/**
- * zl3073x_ref_ffo_get - get current fractional frequency offset
- * @ref: pointer to ref state
- *
- * Return: the latest measured fractional frequency offset
- */
-static inline s64
-zl3073x_ref_ffo_get(const struct zl3073x_ref *ref)
-{
-	return ref->ffo;
-}
-
 /**
  * zl3073x_ref_meas_freq_get - get measured input frequency
  * @ref: pointer to ref state
diff --git a/drivers/dpll/zl3073x/regs.h b/drivers/dpll/zl3073x/regs.h
index d425dc67250fe..b8bbea31748f8 100644
--- a/drivers/dpll/zl3073x/regs.h
+++ b/drivers/dpll/zl3073x/regs.h
@@ -157,6 +157,11 @@
 #define ZL_DPLL_MODE_REFSEL_MODE_NCO		4
 #define ZL_DPLL_MODE_REFSEL_REF			GENMASK(7, 4)
 
+#define ZL_REG_DPLL_DF_READ(_idx)					\
+	ZL_REG_IDX(_idx, 5, 0x28, 1, ZL3073X_MAX_CHANNELS, 1)
+#define ZL_DPLL_DF_READ_SEM			BIT(4)
+#define ZL_DPLL_DF_READ_REF_OFST		BIT(3)
+
 #define ZL_REG_DPLL_MEAS_CTRL			ZL_REG(5, 0x50, 1)
 #define ZL_DPLL_MEAS_CTRL_EN			BIT(0)
 #define ZL_DPLL_MEAS_CTRL_AVG_FACTOR		GENMASK(7, 4)
@@ -169,6 +174,16 @@
 #define ZL_REG_DPLL_PHASE_ERR_DATA(_idx)				\
 	ZL_REG_IDX(_idx, 5, 0x55, 6, ZL3073X_MAX_CHANNELS, 6)
 
+/*******************************
+ * Register Pages 6-7, DPLL Data
+ *******************************/
+
+#define ZL_REG_DPLL_DF_OFFSET_03(_idx)					\
+	ZL_REG_IDX(_idx, 6, 0x00, 6, 4, 0x20)
+#define ZL_REG_DPLL_DF_OFFSET_4		ZL_REG(7, 0x00, 6)
+#define ZL_REG_DPLL_DF_OFFSET(_idx)					\
+	((_idx) < 4 ? ZL_REG_DPLL_DF_OFFSET_03(_idx) : ZL_REG_DPLL_DF_OFFSET_4)
+
 /***********************************
  * Register Page 9, Synth and Output
  ***********************************/
-- 
2.53.0


^ permalink raw reply related

* [PATCH] qed: fix division by zero in qed_init_wfq_param when all vports configured
From: Evgenii Burenchev @ 2026-04-29 15:11 UTC (permalink / raw)
  To: stable, Greg Kroah-Hartman
  Cc: Evgenii Burenchev, andrew+netdev, davem, edumazet, kuba, pabeni,
	kees, horms, darinzon, bhelgaas, netdev, linux-kernel

In qed_init_wfq_param(), variable non_requested_count can become zero
when all vports already have configured flag set. This happens when
num_vports equals the number of configured vports.

The function then calculates left_rate_per_vp = total_left_rate /
non_requested_count, which causes division by zero.

Add a check for non_requested_count == 0 before the division. Return
error when no unconfigured vports exist to distribute bandwidth.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Signed-off-by: Evgenii Burenchev <evg28bur@yandex.ru>
---
 drivers/net/ethernet/qlogic/qed/qed_dev.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index 42c6dcfb1f0f..b287e04c8adc 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -5105,6 +5105,13 @@ static int qed_init_wfq_param(struct qed_hwfn *p_hwfn,
 
 	total_left_rate	= min_pf_rate - total_req_min_rate;
 
+	if (non_requested_count == 0) {
+		DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+			   "All %d vports are already configured for WFQ, no unconfigured vports to distribute remaining bandwidth\n",
+			   num_vports);
+		return -EINVAL;
+	}
+
 	left_rate_per_vp = total_left_rate / non_requested_count;
 	if (left_rate_per_vp <  min_pf_rate / QED_WFQ_UNIT) {
 		DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH net v4 8/8] xsk: fix u64 descriptor address truncation on 32-bit architectures
From: Stanislav Fomichev @ 2026-04-29 15:14 UTC (permalink / raw)
  To: Jason Xing
  Cc: davem, edumazet, kuba, pabeni, bjorn, magnus.karlsson,
	maciej.fijalkowski, jonathan.lemon, sdf, ast, daniel, hawk,
	john.fastabend, aleksander.lobakin, bpf, netdev, Jason Xing
In-Reply-To: <CAL+tcoA0j+tHOPr-DLyW26_EF1JhwqV+no0Lcx335FtKRbwUAw@mail.gmail.com>

On 04/29, Jason Xing wrote:
> On Wed, Apr 29, 2026 at 2:11 AM Stanislav Fomichev <sdf.kernel@gmail.com> wrote:
> >
> > On 04/24, Jason Xing wrote:
> > > From: Jason Xing <kernelxing@tencent.com>
> > >
> > > In copy mode TX, xsk_skb_destructor_set_addr() stores the 64-bit
> > > descriptor address into skb_shinfo(skb)->destructor_arg (void *) via a
> > > uintptr_t cast:
> > >
> > >     skb_shinfo(skb)->destructor_arg = (void *)((uintptr_t)addr | 0x1UL);
> > >
> > > On 32-bit architectures uintptr_t is 32 bits, so the upper 32 bits of
> > > the descriptor address are silently dropped. In unaligned mode the chunk
> > > offset is encoded in bits 48-63 of the descriptor address
> > > (XSK_UNALIGNED_BUF_OFFSET_SHIFT = 48), meaning the offset is lost
> > > entirely. The completion queue then returns a truncated address to
> > > userspace, making buffer recycling impossible.
> > >
> > > Fix this by handling the 32-bit case in the destructor_arg helpers:
> > >
> > > - xsk_skb_destructor_set_addr(): on !CONFIG_64BIT, allocate an
> > >   xsk_addrs struct via kmem_cache_zalloc() to store the full u64
> > >   address. Leave num_descs as 0 (zalloc) so that the subsequent
> > >   xsk_inc_num_desc() brings it to the correct count of 1.
> > >
> > > - xsk_skb_destructor_is_addr(): on !CONFIG_64BIT, return true only
> > >   when destructor_arg is NULL (not yet set), false when it points to
> > >   an xsk_addrs struct.
> > >
> > > - xsk_skb_init_misc(): call xsk_skb_destructor_set_addr() first
> > >   before touching any other skb fields; on failure return early so
> > >   the skb destructor is never changed from sock_wfree.
> > >
> > > The existing xsk_consume_skb() already handles 32-bit correctly after
> > > these changes: xsk_skb_destructor_is_addr() returns false for any
> > > allocated xsk_addrs, so the kmem_cache_free path is always taken.
> > >
> > > The overhead is one extra kmem_cache_zalloc per first descriptor on
> > > 32-bit only; 64-bit builds are completely unchanged.
> > >
> > > Closes: https://lore.kernel.org/all/20260419045824.D9E5EC2BCAF@smtp.kernel.org/
> > > Fixes: 0ebc27a4c67d ("xsk: avoid data corruption on cq descriptor number")
> > > Signed-off-by: Jason Xing <kernelxing@tencent.com>
> > > ---
> > >  net/xdp/xsk.c | 38 +++++++++++++++++++++++++++++++-------
> > >  1 file changed, 31 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> > > index ed96f6ec8ff2..fe88f47741b5 100644
> > > --- a/net/xdp/xsk.c
> > > +++ b/net/xdp/xsk.c
> > > @@ -558,7 +558,10 @@ static int xsk_cq_reserve_locked(struct xsk_buff_pool *pool)
> > >
> > >  static bool xsk_skb_destructor_is_addr(struct sk_buff *skb)
> > >  {
> > > -     return (uintptr_t)skb_shinfo(skb)->destructor_arg & 0x1UL;
> > > +     if (IS_ENABLED(CONFIG_64BIT))
> > > +             return (uintptr_t)skb_shinfo(skb)->destructor_arg & 0x1UL;
> > > +     else
> > > +             return !skb_shinfo(skb)->destructor_arg;
> >
> > Don't understand why we need to special case CONFIG_64BIT here?
> > Shouldn't the same existing condition work on 32bit?
> 
> Because 0x1UL is the particular semantic applied on a 64-bit arch.
> xsk_skb_destructor_set_addr() sets it while
> xsk_skb_destructor_is_addr() recognizes it. They are a pair.
> 
> As you noticed, one liner works but is not that appropriate: on a
> 32-bit arch, this member should be either a NULL point or a valid
> pointer pointing to a memory region. Testing if it's NULL can be
> helpful as to the long term maintenance because of its readability and
> robustness/safety.
> 
> The error path in allocation of skb is really complex, which is why
> I'm so cautious to take care of it :)

Let's cleanup the error path instead of adding more complexity? Similar to what
you do with your "xsk: fix xsk_addrs slab leak on multi-buffer error path",
but maybe add a few NULL checks?

Instead of 32 vs 64, I'd like to reason about whether destructor_arg
is an address or an allocated array (not whether we have 1 or >1
descriptors). And we special case 32 bit by always allocating it.

Haven't checked, but maybe this is all you need (besides your _set_addr
changes)?

diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 6149f6a79897..03f217e85d31 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -589,6 +589,8 @@ static u32 xsk_get_num_desc(struct sk_buff *skb)
 		return 1;
 
 	xsk_addr = (struct xsk_addrs *)skb_shinfo(skb)->destructor_arg;
+	if (!xsk_addr)
+		return 0;
 
 	return xsk_addr->num_descs;
 }

> I've noticed the status has been changed to 'changes requested'. Does
> that mean one way or another I have to post a new version?

That wasn't me :-) From my POW, patches 1-7 are good to go..

> >
> > >  }
> > >
> > >  static u64 xsk_skb_destructor_get_addr(struct sk_buff *skb)
> > > @@ -566,9 +569,21 @@ static u64 xsk_skb_destructor_get_addr(struct sk_buff *skb)
> > >       return (u64)((uintptr_t)skb_shinfo(skb)->destructor_arg & ~0x1UL);
> > >  }
> > >
> > > -static void xsk_skb_destructor_set_addr(struct sk_buff *skb, u64 addr)
> > > +static int xsk_skb_destructor_set_addr(struct sk_buff *skb, u64 addr)
> > >  {
> >
> > [..]
> >
> > > +     if (!IS_ENABLED(CONFIG_64BIT)) {
> > > +             struct xsk_addrs *xsk_addr;
> > > +
> > > +             xsk_addr = kmem_cache_zalloc(xsk_tx_generic_cache, GFP_KERNEL);
> > > +             if (!xsk_addr)
> > > +                     return -ENOMEM;
> > > +             xsk_addr->addrs[0] = addr;
> > > +             skb_shinfo(skb)->destructor_arg = (void *)xsk_addr;
> > > +             return 0;
> > > +     }
> > > +
> > >       skb_shinfo(skb)->destructor_arg = (void *)((uintptr_t)addr | 0x1UL);
> > > +     return 0;
> >
> > I think this is gonna be a 3rd copy paste of the same logic? Let's
> > move to a new helper and replace existing kmem_cache_zalloc places?
> >
> > xsk_skb_destructor_alloc_list(prev_addr) ?

Any comments on this?

^ permalink raw reply related

* Re: [syzbot] [net?] WARNING: ODEBUG bug in lane_ioctl (3)
From: Arjan van de Ven @ 2026-04-29 15:17 UTC (permalink / raw)
  To: netdev
  Cc: syzbot+ca9d5686d06994c6547c, davem, edumazet, horms, kuba,
	linux-kernel, pabeni, syzkaller-bugs, Arjan van de Ven
In-Reply-To: <69f16c26.170a0220.34e5b8.0013.GAE@google.com>

This email is created by automation to help kernel developers deal with
a large volume of bug reports by decoding oopses into more actionable
information.


Decoded Backtrace

1. __debug_object_init -- crash site (lib/debugobjects.c:632)

The WARN fires inside debug_print_object (inlined into
__debug_object_init). The object at 0xffff888077a60f78 (a timer_list) is
in the ACTIVE state when debug_object_init is called on it a second time.

  611 static void debug_print_object(struct debug_obj *obj, char *msg)
  612 {
  613     const struct debug_obj_descr *descr = obj->descr;
  614     static int limit;
  622     if (!debug_objects_enabled)
  623         return;
  625     if (limit < 5 && descr != descr_test) {
  626         void *hint = descr->debug_hint ?
  627             descr->debug_hint(obj->object) : NULL;
  628         limit++;
-> 629         WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) "
  630                 "object: %p object type: %s hint: %pS\n",
  631                 msg, obj_states[obj->state], obj->astate,
  632                 obj->object, descr->name, hint);
  633     }
  634     debug_objects_warnings++;
  635 }

  747 static void
  748 __debug_object_init(void *addr, const struct debug_obj_descr *descr,
  749                     int onstack)
  750 {
  751     struct debug_obj *obj, o;
  752     struct debug_bucket *db;
  753     unsigned long flags;
  755     debug_objects_fill_pool();
  757     db = get_bucket((unsigned long) addr);
  759     raw_spin_lock_irqsave(&db->lock, flags);
  761     obj = lookup_object_or_alloc(addr, db, descr, onstack, false);
  762     if (unlikely(!obj)) {
  763         raw_spin_unlock_irqrestore(&db->lock, flags);
  764         debug_objects_oom();
  765         return;
  766     }
  768     switch (obj->state) {
  769     case ODEBUG_STATE_NONE:
  770     case ODEBUG_STATE_INIT:
  771     case ODEBUG_STATE_INACTIVE:
  772         obj->state = ODEBUG_STATE_INIT;
  773         raw_spin_unlock_irqrestore(&db->lock, flags);
  774         return;
  775     default:
  776         break;
  777     }
  779     o = *obj;
  780     raw_spin_unlock_irqrestore(&db->lock, flags);
-> 780     debug_print_object(&o, "init");
  783     if (o.state == ODEBUG_STATE_ACTIVE)
  784         debug_object_fixup(descr->fixup_init, addr, o.state);
  785 }


2. timer_init_key -- kernel/time/timer.c:880

  786 static inline void debug_timer_init(struct timer_list *timer)
  787 {
-> 788     debug_object_init(timer, &timer_debug_descr);
  789 }

  834 static inline void debug_init(struct timer_list *timer)
  835 {
-> 836     debug_timer_init(timer);
  837     trace_timer_init(timer);
  838 }

  876 void timer_init_key(struct timer_list *timer,
  877         void (*func)(struct timer_list *), unsigned int flags,
  878         const char *name, struct lock_class_key *key)
  879 {
-> 880     debug_init(timer);
  881     do_init_timer(timer, func, flags, name, key);
  882 }


3. lane_ioctl / lecd_attach / lec_arp_init (net/atm/lec.c:1037)

  1264 static void lec_arp_init(struct lec_priv *priv)
  1265 {
  1266     unsigned short i;
  1268     for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
  1269         INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
  1270     INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
  1271     INIT_HLIST_HEAD(&priv->lec_no_forward);
  1272     INIT_HLIST_HEAD(&priv->mcast_fwds);
  1273     spin_lock_init(&priv->lec_arp_lock);
->1274     INIT_DELAYED_WORK(&priv->lec_arp_work, lec_arp_check_expire);
  1275     schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
  1276 }

  748 static int lecd_attach(struct atm_vcc *vcc, int arg)
  749 {
  750     int i;
  751     struct lec_priv *priv;
  753     lockdep_assert_held(&lec_mutex);
  754     if (arg < 0)
  755         arg = 0;
  756     if (arg >= MAX_LEC_ITF)
  757         return -EINVAL;
  758     i = array_index_nospec(arg, MAX_LEC_ITF);
  759     if (!dev_lec[i]) {
  763         dev_lec[i] = alloc_etherdev(size);
  775         priv = netdev_priv(dev_lec[i]);
  776     } else {
  776         priv = netdev_priv(dev_lec[i]);
  777         if (rcu_access_pointer(priv->lecd))
  778             return -EADDRINUSE;
  779     }
->781     lec_arp_init(priv);   // called unconditionally for both new and
                                // existing priv -- no work cancellation

  1018 static int lane_ioctl(struct socket *sock, unsigned int cmd,
  1019                       unsigned long arg)
  1020 {
  1034     mutex_lock(&lec_mutex);
  1035     switch (cmd) {
  1036     case ATMLEC_CTRL:
->1037         err = lecd_attach(vcc, (int)arg);
  1038         if (err >= 0)
  1039             sock->state = SS_CONNECTED;
  1040         break;
  1049     mutex_unlock(&lec_mutex);
  1050     return err;
  1051 }


4. do_vcc_ioctl (net/atm/ioctl.c:159)

  153     error = -ENOIOCTLCMD;
  155     mutex_lock(&ioctl_mutex);
  156     list_for_each(pos, &ioctl_list) {
  157         struct atm_ioctl *ic = list_entry(pos, struct atm_ioctl, list);
  158         if (try_module_get(ic->owner)) {
->159             error = ic->ioctl(sock, cmd, arg);  // dispatches to lane_ioctl
  160             module_put(ic->owner);
  161             if (error != -ENOIOCTLCMD)
  162                 break;
  163         }
  164     }
  165     mutex_unlock(&ioctl_mutex);


Tentative Analysis

The ODEBUG WARNING fires when INIT_DELAYED_WORK() is called on a
timer_list (lec_priv.lec_arp_work) that is already in the ACTIVE state.

lec_arp_init() always calls INIT_DELAYED_WORK(&priv->lec_arp_work, ...)
followed by schedule_delayed_work(). lecd_attach() calls lec_arp_init()
unconditionally -- both for a brand-new device and for an existing one
in the else-branch. The only guard for the existing-device path is that
priv->lecd is NULL (no daemon currently attached).

The race is opened by lec_atm_close(), the ATM VCC close handler:

    Thread A (lec_atm_close):        Thread B (lecd_attach via lane_ioctl):
      rcu_assign_pointer(lecd, NULL)
      synchronize_rcu()                mutex_lock(&lec_mutex)
      [window open]                    sees priv->lecd == NULL -- passes guard
                                       lec_arp_init(priv)
                                         INIT_DELAYED_WORK on active timer
                                         --> ODEBUG WARN
      lec_arp_destroy(priv)            [too late: work already re-initialized]

lec_atm_close() clears priv->lecd to NULL *before* calling
lec_arp_destroy() (which contains cancel_delayed_work_sync). Because
lec_atm_close() does not hold lec_mutex, Thread B can observe
priv->lecd == NULL while lec_arp_work is still active, pass the guard
in lecd_attach(), and call lec_arp_init() on a live timer.

The lec_mutex protecting dev_lec[] was introduced by commit d13a3824bfd2
("net: atm: add lec_mutex"), which serialised lecd_attach() and friends
but did not update lec_atm_close() to also acquire the mutex. The
unconditional lec_arp_init() call for existing devices predates that
commit and has always been present.


Potential Solution

Add cancel_delayed_work_sync(&priv->lec_arp_work) in the else-branch of
lecd_attach(), immediately before the call to lec_arp_init(). This
ensures any in-flight work is drained before the timer is re-initialized,
regardless of whether lec_atm_close() has already cancelled it.
cancel_delayed_work_sync() is safe to call from a lec_mutex-held context
because lec_arp_check_expire() only acquires priv->lec_arp_lock (a
spinlock) and never tries to take lec_mutex.

    } else {
        priv = netdev_priv(dev_lec[i]);
        if (rcu_access_pointer(priv->lecd))
            return -EADDRINUSE;
+       cancel_delayed_work_sync(&priv->lec_arp_work);
    }
    lec_arp_init(priv);


More information

Oops-Analysis: http://oops.fenrus.org/reports/lkml/69f16c26.170a0220.34e5b8.0013.GAE@google.com/
Assisted-by: GitHub-Copilot linux-kernel-oops.

^ permalink raw reply

* [PATCH net 0/2] openvswitch: fix self-deadlock on release of tunnel vports
From: Ilya Maximets @ 2026-04-29 15:16 UTC (permalink / raw)
  To: netdev
  Cc: Aaron Conole, Eelco Chaudron, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Shuah Khan, Yuan Tan,
	Yang Yang, dev, linux-kernel, linux-kselftest, Ilya Maximets

Two patches - the fix for the actual bug and the selftest that reproduces it.

I missed the self-deadlock in the original patch that introduced the issue,
because testing required code modification in the ovs-vswitchd to force it to
use legacy tunnel ports.  I thought I made the change correctly, but apparently
something went wrong and the tests were run with the standard LWT infra instead.
The selftest added in this patch set will at least prevent this kind of mistakes
in the future.

I mentioned, however, that these tunnel vports are legacy and not actually used
by ovs-vswitchd.  RTM_NEWLINK + COLLECT_METADATA is used in conjunction with the
standard OVS_VPORT_TYPE_NETDEV instead since 2017.  The code to use the legacy
tunnels still exists in ovs-vswitchd however, but only as a fallback for older
kernels and we're planning to remove it in the next release.  I'll be sending an
RFC to remove support for these legacy tunnel types from the kernel, as they
serve no real purpose today and only increase the uAPI surface for CVEs, but
we need to fix the known bugs for stable versions.

Ilya Maximets (2):
  openvswitch: vport: fix self-deadlock on release of tunnel ports
  selftests: openvswitch: add tests for tunnel vport refcounting

 net/openvswitch/vport-netdev.c                |  6 ++-
 .../selftests/net/openvswitch/openvswitch.sh  | 37 +++++++++++++++++++
 .../selftests/net/openvswitch/ovs-dpctl.py    | 10 ++---
 3 files changed, 47 insertions(+), 6 deletions(-)

-- 
2.53.0


^ permalink raw reply

* [PATCH net 1/2] openvswitch: vport: fix self-deadlock on release of tunnel ports
From: Ilya Maximets @ 2026-04-29 15:16 UTC (permalink / raw)
  To: netdev
  Cc: Aaron Conole, Eelco Chaudron, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Shuah Khan, Yuan Tan,
	Yang Yang, dev, linux-kernel, linux-kselftest, Ilya Maximets,
	stable
In-Reply-To: <20260429151756.4157670-1-i.maximets@ovn.org>

vports are used concurrently and protected by RCU, so netdev_put()
must happen after the RCU grace period.  So, either in an RCU call or
after the synchronize_net().  The rtnl_delete_link() must happen under
RTNL and so can't be executed in RCU context.  Calling synchronize_net()
while holding RTNL is not a good idea for performance and system
stability under load in general, so calling netdev_put() in RCU call
is the right solution here.

However,
when the device is deleted, rtnl_unlock() will call netdev_run_todo()
and block until all the references are gone.  In the current code this
means that we never reach the call_rcu() and the vport is never freed
and the reference is never released, causing a self-deadlock on device
removal.

Fix that by moving the rcu_call() before the rtnl_unlock(), so the
scheduled RCU callback will be executed when synchronize_net() is
called from the rtnl_unlock()->netdev_run_todo() while the RTNL itself
is already released.

Fixes: 6931d21f87bc ("openvswitch: defer tunnel netdev_put to RCU release")
Cc: stable@vger.kernel.org
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 net/openvswitch/vport-netdev.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
index 12055af832dc0..a1df551e915bc 100644
--- a/net/openvswitch/vport-netdev.c
+++ b/net/openvswitch/vport-netdev.c
@@ -196,9 +196,13 @@ void ovs_netdev_tunnel_destroy(struct vport *vport)
 	 */
 	if (vport->dev->reg_state == NETREG_REGISTERED)
 		rtnl_delete_link(vport->dev, 0, NULL);
-	rtnl_unlock();
 
+	/* We can't put the device reference yet, since it can still be in
+	 * use, but rtnl_unlock()->netdev_run_todo() will block until all
+	 * the references are released, so the RCU call must be before it.
+	 */
 	call_rcu(&vport->rcu, vport_netdev_free);
+	rtnl_unlock();
 }
 EXPORT_SYMBOL_GPL(ovs_netdev_tunnel_destroy);
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH net 2/2] selftests: openvswitch: add tests for tunnel vport refcounting
From: Ilya Maximets @ 2026-04-29 15:16 UTC (permalink / raw)
  To: netdev
  Cc: Aaron Conole, Eelco Chaudron, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Shuah Khan, Yuan Tan,
	Yang Yang, dev, linux-kernel, linux-kselftest, Ilya Maximets
In-Reply-To: <20260429151756.4157670-1-i.maximets@ovn.org>

There were a few issues found with the tunnel vport types around the
vport destruction code.  Add some basic tests, so at least we know that
they can be properly added and removed without obvious issues.

The test creates OVS datapath, adds a non-LWT tunnel port, makes sure
they are created, and then removes the datapath and waits for all the
ports to be gone.

The dpctl script had a few bugs in the none-lwt tunnel creation code,
so fixing them as well to make the testing possible:
- The type of the --lwt option changed in order to properly disable it.
- Removed byte order conversion for the port numbers, as the value
  supposed to be in the host order.
- Added missing 'gre' choice for the tunnel type.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 .../selftests/net/openvswitch/openvswitch.sh  | 37 +++++++++++++++++++
 .../selftests/net/openvswitch/ovs-dpctl.py    | 10 ++---
 2 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh
index b327d3061ed53..3cdd953f68132 100755
--- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
+++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
@@ -26,6 +26,7 @@ tests="
 	netlink_checks				ovsnl: validate netlink attrs and settings
 	upcall_interfaces			ovs: test the upcall interfaces
 	tunnel_metadata				ovs: test extraction of tunnel metadata
+	tunnel_refcount				ovs: test tunnel vport reference cleanup
 	drop_reason				drop: test drop reasons are emitted
 	psample					psample: Sampling packets with psample"
 
@@ -830,6 +831,42 @@ test_tunnel_metadata() {
 	return 0
 }
 
+test_tunnel_refcount() {
+	sbxname="test_tunnel_refcount"
+	sbx_add "${sbxname}" || return 1
+
+	ovs_sbx "${sbxname}" ip netns add trefns || return 1
+	on_exit "ovs_sbx ${sbxname} ip netns del trefns"
+
+	for tun_type in gre vxlan geneve; do
+		info "testing ${tun_type} tunnel vport refcount"
+
+		ovs_sbx "${sbxname}" ip netns exec trefns \
+			python3 $ovs_base/ovs-dpctl.py \
+			add-dp dp-${tun_type} || return 1
+
+		ovs_sbx "${sbxname}" ip netns exec trefns \
+			python3 $ovs_base/ovs-dpctl.py \
+			add-if --no-lwt -t ${tun_type} \
+			dp-${tun_type} ovs-${tun_type}0 || return 1
+
+		ovs_wait ip -netns trefns link show \
+			ovs-${tun_type}0 >/dev/null 2>&1 || return 1
+
+		info "deleting dp - may hang if reference counting is broken"
+		ovs_sbx "${sbxname}" ip netns exec trefns \
+			python3 $ovs_base/ovs-dpctl.py \
+			del-dp dp-${tun_type} &
+
+		dev_removed() {
+			! ip -netns trefns link show "$1" >/dev/null 2>&1
+		}
+		ovs_wait dev_removed dp-${tun_type} || return 1
+		ovs_wait dev_removed ovs-${tun_type}0 || return 1
+	done
+	return 0
+}
+
 run_test() {
 	(
 	tname="$1"
diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 848f61fdcee09..196813f476434 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -2069,7 +2069,7 @@ class OvsVport(GenericNetlinkSocket):
         elif vport_type == "internal":
             return OvsVport.OVS_VPORT_TYPE_INTERNAL
         elif vport_type == "gre":
-            return OvsVport.OVS_VPORT_TYPE_INTERNAL
+            return OvsVport.OVS_VPORT_TYPE_GRE
         elif vport_type == "vxlan":
             return OvsVport.OVS_VPORT_TYPE_VXLAN
         elif vport_type == "geneve":
@@ -2131,7 +2131,7 @@ class OvsVport(GenericNetlinkSocket):
                 if not lwt:
                     vportopt = OvsVport.ovs_vport_msg.vportopts()
                     vportopt["attrs"].append(
-                        ["OVS_TUNNEL_ATTR_DST_PORT", socket.htons(dport)]
+                        ["OVS_TUNNEL_ATTR_DST_PORT", dport]
                     )
                     msg["attrs"].append(
                         ["OVS_VPORT_ATTR_OPTIONS", vportopt]
@@ -2563,7 +2563,7 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()):
             if vpo:
                 dpo = vpo.get_attr("OVS_TUNNEL_ATTR_DST_PORT")
                 if dpo:
-                    opts += " tnl-dport:%s" % socket.ntohs(dpo)
+                    opts += " tnl-dport:%s" % dpo
             print(
                 "  port %d: %s (%s%s)"
                 % (
@@ -2632,7 +2632,7 @@ def main(argv):
         "--ptype",
         type=str,
         default="netdev",
-        choices=["netdev", "internal", "geneve", "vxlan"],
+        choices=["netdev", "internal", "gre", "geneve", "vxlan"],
         help="Interface type (default netdev)",
     )
     addifcmd.add_argument(
@@ -2645,7 +2645,7 @@ def main(argv):
     addifcmd.add_argument(
         "-l",
         "--lwt",
-        type=bool,
+        action=argparse.BooleanOptionalAction,
         default=True,
         help="Use LWT infrastructure instead of vport (default true)."
     )
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH 00/18] Migrate rpcsec_gss_krb5 to the crypto/krb5 library
From: Chuck Lever @ 2026-04-29 15:17 UTC (permalink / raw)
  To: Jeff Layton, Trond Myklebust, Anna Schumaker, Chuck Lever,
	NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: linux-nfs, netdev, linux-kernel, Herbert Xu, David Howells,
	Simo Sorce
In-Reply-To: <dbaa192b70fa67d51ab6a4294c045100efc65980.camel@kernel.org>


On Wed, Apr 29, 2026, at 2:39 AM, Jeff Layton wrote:
> On Mon, 2026-04-27 at 09:50 -0400, Chuck Lever wrote:
>> The rpcsec_gss_krb5 module carries its own Kerberos 5 crypto imple-
>> mentation: key derivation, CBC-CTS encryption, HMAC checksumming,
>> and the encrypt-then-MAC construction from RFC 8009. Keeping
>> cryptographic code inside an RPC module means it receives review
>> only from the SUNRPC maintainers, who lack deep crypto expertise.
>> Vulnerabilities and algorithmic errors can persist unnoticed.
>> 
>> Replacing the private SunRPC Kerberos implementation eliminates
>> this duplicated audit surface. A single implementation of Kerberos
>> 5 key derivation and authenticated encryption is easier to verify
>> than two independent copies. New encryption types and hardware
>> offload added to crypto/krb5 will automatically become available
>> to SunRPC Kerberos consumers.
>> 
>> The crypto/krb5 library handles enctype differences internally, so
>> a single encrypt function and a single decrypt function serve all
>> enctypes, eliminating the per-enctype dispatch table that previously
>> existed in struct gss_krb5_enctype.
>> 
>> RFC 4121 Section 4.2.4 requires MIC checksums to cover the message
>> body followed by the GSS token header. The crypto/krb5 get_mic/
>> verify_mic API hashes optional metadata before the scatterlist
>> data, which is the wrong order for the GSS header. The header is
>> therefore placed at the end of the scatterlist rather than passed
>> as the metadata parameter, and a dedicated gss_krb5_mic_build_sg()
>> helper constructs this three-section layout (checksum area, message
>> body, token header) with proper sg_mark_end() termination.
>> 
>> This implementation was available during the Spring 2026 NFS bake-
>> a-thon, and received testing there.

>
> Love that diffstat. Nice work! 
>
> One comment in general: Do you need to add Assisted-by: tags to any of
> this? You can add this to the set:
>
> Reviewed-by: Jeff Layton <jlayton@kernel.org>

Thanks, applied to nfsd-testing. An Acked-by: from one of the NFS
client maintainers would be great too.


-- 
Chuck Lever

^ permalink raw reply

* Re: [PATCH net-next 00/11] net: devmem: support devmem with netkit devices
From: Bobby Eshleman @ 2026-04-29 15:18 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
	Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
	Joshua Washington, Harshitha Ramamurthy, Saeed Mahameed,
	Tariq Toukan, Mark Bloch, Leon Romanovsky, Alexander Duyck,
	kernel-team, Nikolay Aleksandrov, Shuah Khan, David Wei, netdev,
	linux-doc, linux-kernel, linux-rdma, bpf, linux-kselftest,
	Stanislav Fomichev, Mina Almasry, Bobby Eshleman
In-Reply-To: <f954a636-4d21-47c0-8afa-cc4b24adb0fb@iogearbox.net>

On Wed, Apr 29, 2026 at 02:08:31PM +0200, Daniel Borkmann wrote:
> Hi Bobby,
> 
> On 4/29/26 12:41 AM, Bobby Eshleman wrote:
> > This series enables TCP devmem TX through netkit devices.
> > 
> > Netkit now supports queue leasing. A physical NIC's RX queue can be
> > leased to a netkit guest interface inside a container namespace. This
> > gives the container a devmem-capable data path on the RX side (bind-rx,
> > etc...). On the TX side, the container process binds to its netkit guest
> > interface and sends traffic that netkit redirects (via BPF or ip
> > forwarding) to the physical NIC for DMA.
> [...]
> Thanks for working on this, after the RX queue leasing got merged, I've
> been looking into the same actually. :)
> 
> I think the NETMEM_TX_* enum approach seems reasonable.
> 
> What I have a PoC on is to build out TX queue leasing as first-class
> symmetric infrastructure to complement the RX queue leasing - basically
> I implemented an equivalent to the latter in netdev_nl_queue_create_doit
> et al, so you can have independent RX and TX leases and per-queue
> accountability, such that ynl queue-get op shows the full picture, and
> lastly we could also enable AF_XDP TX-only support through this infra.
> 
> Would you be open to collab on integrating both and migrating the devmem
> code to work off an TX queue object? Next week is LSF/MM/BPF, are you
> there by any chance to catch up in person?
> 

Hey Daniel,

Definitely am open to that. I will unfortunately not be at LSF/MM/BPF,
but maybe we can schedule a meeting offline to sync up?

On the approach, explicit TX queue leasing sounds like a better way to
permit devmem's tx binding than implicitly via RX lease.

Best,
Bobby

^ permalink raw reply

* Re: [PATCH v2 net] sfc: fix error code in efx_devlink_info_running_versions()
From: Edward Cree @ 2026-04-29 15:27 UTC (permalink / raw)
  To: Dan Carpenter, Alejandro Lucero
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Martin Habets, Jiri Pirko, netdev, linux-net-drivers,
	linux-kernel, kernel-janitors
In-Reply-To: <afGpsbLRHL4_H0KS@stanley.mountain>

On 29/04/2026 07:48, Dan Carpenter wrote:
> Return -EIO if efx_mcdi_rpc() doesn't return enough space.
> 
> Fixes: 14743ddd2495 ("sfc: add devlink info support for ef100")
> Signed-off-by: Dan Carpenter <error27@gmail.com>

Reviewed-by: Edward Cree <ecree.xilinx@gmail.com>

^ permalink raw reply

* Re: [PATCH net-next] selftests/net: packetdrill: add tcp_syncookies_ip6_9k
From: Eric Dumazet @ 2026-04-29 15:39 UTC (permalink / raw)
  To: Neal Cardwell
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Kuniyuki Iwashima, netdev, eric.dumazet
In-Reply-To: <CADVnQynDD_6B894PqVuSqqz24hmYhyQKov7zDvnYJoKZU0TXZw@mail.gmail.com>

On Wed, Apr 29, 2026 at 7:15 AM Neal Cardwell <ncardwell@google.com> wrote:
>
> On Wed, Apr 29, 2026 at 4:00 AM Eric Dumazet <edumazet@google.com> wrote:
> >
> > This test checks syncookie mode is able to reconstruct some
> > client options when TCP TS are used:
> >
> > - wscale option.
> > - sackOK.
> > - MSS (in a limited way).
> > - ECN (not tested, because of limited value).
> >
> > Signed-off-by: Eric Dumazet <edumazet@google.com>
> > ---
> >  .../net/packetdrill/tcp_syncookies_ip6_9k.pkt | 30 +++++++++++++++++++
> >  1 file changed, 30 insertions(+)
> >  create mode 100644 tools/testing/selftests/net/packetdrill/tcp_syncookies_ip6_9k.pkt
> >
> > diff --git a/tools/testing/selftests/net/packetdrill/tcp_syncookies_ip6_9k.pkt b/tools/testing/selftests/net/packetdrill/tcp_syncookies_ip6_9k.pkt
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..15d03992a99140ecc4241edae58693dc5098fece
> > --- /dev/null
> > +++ b/tools/testing/selftests/net/packetdrill/tcp_syncookies_ip6_9k.pkt
> > @@ -0,0 +1,30 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// Check syncookies.
> > +//
> > +// Check we are able to rebuild client sack, wscale and mss options.
> > +// IPv6 msstab[4] = { 1280 - 60, 1480 - 60, 1500 - 60, 9000 - 60 }
> > +
> > +--ip_version=ipv6
> > +
> > +`./defaults.sh
> > +sysctl -q net.ipv4.tcp_syncookies=2
> > +ip link set dev tun0 mtu 9000
> > +`
> > +
> > +    0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
> > +   +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> > +   +0 bind(3, ..., ...) = 0
> > +   +0 listen(3, 10) = 0
> > +
> > +   +0 < S 0:0(0) win 32792 <mss 8940,sackOK,TS val 100 ecr 0,nop,wscale 10>
> > +   +0 > S. 0:0(0) ack 1 <mss 8940,sackOK,TS val 4000 ecr 100,nop,wscale 8>
> > + +.01 < . 1:1(0) ack 1 win 1024 <nop,nop,TS val 110 ecr 4000>
> > +
> > +   +0 accept(3, ..., ...) = 4
> > +
> > +// Check we properly infer from the final packet the other peer wanted 8940 mss, wscale 10 and sackOK
> > +   +0 %{ assert tcpi_snd_mss == 8928, tcpi_snd_mss }%
> > +   +0 %{ assert tcpi_snd_wscale = 10, tcpi_snd_wscale }%
> > +   +0 %{ assert (tcpi_options & TCPI_OPT_WSCALE) != 0, tcpi_options }%
>
> The comment mentions checking sackOK but the script does not seem to
> do that? Probably want to check the TCPI_OPT_SACK bit as well? Maybe
> TCPI_OPT_TIMESTAMPS as well, for completeness?


Oh right, last minute typo, I was testing (tcpi_options & 2) != 0,
then wanted to replace with the symbolic version, which should have
been TCPI_OPT_SACK.

^ permalink raw reply

* Re: [PATCH net-next 4/4] r8152: Add firmware upload capability for RTL8157/RTL8159
From: Birger Koblitz @ 2026-04-29 15:58 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, linux-usb, netdev, linux-kernel, Chih Kai Hsu
In-Reply-To: <376f2907-55c0-416b-8904-e61888feb3cd@lunn.ch>

On 29/04/2026 3:01 pm, Andrew Lunn wrote:
> On Wed, Apr 29, 2026 at 06:21:58AM +0200, Birger Koblitz wrote:
>> On 29/04/2026 3:57 am, Andrew Lunn wrote:
>>> On Tue, Apr 28, 2026 at 05:47:24AM +0200, Birger Koblitz wrote:
>>>> The RTL8159 requires firmware for its PHY in order to work at
>>>> connection speeds > 5GBit. Add support for uploading firmware for
>>>> the PHYs using the existing rtl8152_apply_firmware() function
>>>> in r8157_hw_phy_cfg() and set up the correct names for the firmware
>>>> files.
> 
>> No, since the RTL8157 (RTL_VER_16) also works in my experiments as expected
>> without this change, i.e. without any updated firmware, or better the
>> possibility to update the firmware. It is only for the RTL8159 where the
>> firmware is necessary to even get 10GBit performance, at least for the
>> link-partners I use for testing. My understanding of the Realtek "firmware"
>> is that it mainly provides updated calibration constants, possibly better
>> calibration routines for interoperability. Unlike for many other drivers,
>> the firmware is not necessary to make the driver work at all.
> 
> O.K. Please could you expand the commit message. Explain why you are
> adding code for RTL_VER_16 as well as RTL_VER_17.
>I will update the commit message accordingly.

Birger

^ permalink raw reply

* [PATCH net v5] ipv6: Implement limits on extension header parsing
From: Daniel Borkmann @ 2026-04-29 15:46 UTC (permalink / raw)
  To: kuba
  Cc: edumazet, dsahern, tom, willemdebruijn.kernel, idosch, pabeni,
	justin.iurman, netdev

ipv6_{skip_exthdr,find_hdr}() and ip6_{tnl_parse_tlv_enc_lim,
protocol_deliver_rcu}() iterate over IPv6 extension headers until they
find a non-extension-header protocol or run out of packet data. The
loops have no iteration counter, relying solely on the packet length
to bound them. For a crafted packet with 8-byte extension headers
filling a 64KB jumbogram, this means a worst case of up to ~8k
iterations with a skb_header_pointer call each. ipv6_skip_exthdr(),
for example, is used where it parses the inner quoted packet inside
an incoming ICMPv6 error:

  - icmpv6_rcv
    - checksum validation
    - case ICMPV6_DEST_UNREACH
      - icmpv6_notify
        - pskb_may_pull()       <- pull inner IPv6 header
        - ipv6_skip_exthdr()    <- iterates here
        - pskb_may_pull()
        - ipprot->err_handler() <- sk lookup

The per-iteration cost of ipv6_skip_exthdr itself is generally
light, but skb_header_pointer becomes more costly on reassembled
packets: the first ~1232 bytes of the inner packet are in the skb's
linear area, but the remaining ~63KB are in the frag_list where
skb_copy_bits is needed to read data.

Initially, the idea was to add a configurable limit via a new
sysctl knob with default 8, in line with knobs from commit
47d3d7ac656a ("ipv6: Implement limits on Hop-by-Hop and Destination
options"), but two reasons eventually argued against it:

- It adds to UAPI that needs to be maintained forever, and
  upcoming work is restricting extension header ordering anyway,
  leaving little reason for another sysctl knob
- exthdrs_core.c is always built-in even when CONFIG_IPV6=n,
  where struct net has no .ipv6 member, so the read site would
  need an ifdef'd fallback to a constant anyway

Therefore, just use a constant (IP6_MAX_EXT_HDRS_CNT). All four
extension header walking functions are now bound by this limit.

Note that the check in ip6_protocol_deliver_rcu() happens right
before the goto resubmit, such that we don't have to have a test
for ipv6_ext_hdr() in the fast-path.

There's an ongoing IETF draft-iurman-6man-eh-occurrences to enforce
IPv6 extension headers ordering and occurrence. The latter also
discusses security implications. As per RFC8200 section 4.1, the
occurrence rules for extension headers provide a practical upper
bound which is 8. In order to be conservative, let's define
IP6_MAX_EXT_HDRS_CNT as 12 to leave enough room for quirky setups.
In the unlikely event that this is still not enough, then we might
need to reconsider a sysctl.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
---
 v4->v5:
   - Reduce the hard-coded limit from 32 to 12 (Justin)
   - Rest as-is
 v3->v4:
   - Switching to hard-coded define with 32 limit as discussed
     earlier, otherwise fixing the kbuild-bot error becomes
     to ugly.. was worth a try, but given the case of being
     built-in also with CONFIG_IPV6=n define seems better
     (Justin, Victor, kbuild-bot)
 v2->v3:
   - Adding IP6SKB_HOPBYHOP coverage (Justin)
   - I left the limit at 8 w/ sysctl, still feels the better
     option to me if we can keep the worst-case more tightened
 v1->v2:
   - Set the default to 8 (Justin)
   - Update IETF references (Justin)
   - Add core path coverage as well (Justin)

 include/net/dropreason-core.h | 6 ++++++
 include/net/ipv6.h            | 3 +++
 net/ipv6/exthdrs_core.c       | 7 +++++++
 net/ipv6/ip6_input.c          | 5 +++++
 net/ipv6/ip6_tunnel.c         | 4 ++++
 5 files changed, 25 insertions(+)

diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h
index e0ca3904ff8e..2f312d1f67d6 100644
--- a/include/net/dropreason-core.h
+++ b/include/net/dropreason-core.h
@@ -99,6 +99,7 @@
 	FN(FRAG_TOO_FAR)		\
 	FN(TCP_MINTTL)			\
 	FN(IPV6_BAD_EXTHDR)		\
+	FN(IPV6_TOO_MANY_EXTHDRS)	\
 	FN(IPV6_NDISC_FRAG)		\
 	FN(IPV6_NDISC_HOP_LIMIT)	\
 	FN(IPV6_NDISC_BAD_CODE)		\
@@ -494,6 +495,11 @@ enum skb_drop_reason {
 	SKB_DROP_REASON_TCP_MINTTL,
 	/** @SKB_DROP_REASON_IPV6_BAD_EXTHDR: Bad IPv6 extension header. */
 	SKB_DROP_REASON_IPV6_BAD_EXTHDR,
+	/**
+	 * @SKB_DROP_REASON_IPV6_TOO_MANY_EXTHDRS: Number of IPv6 extension
+	 * headers in the packet exceeds IP6_MAX_EXT_HDRS_CNT.
+	 */
+	SKB_DROP_REASON_IPV6_TOO_MANY_EXTHDRS,
 	/** @SKB_DROP_REASON_IPV6_NDISC_FRAG: invalid frag (suppress_frag_ndisc). */
 	SKB_DROP_REASON_IPV6_NDISC_FRAG,
 	/** @SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT: invalid hop limit. */
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index d042afe7a245..1dec81faff28 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -90,6 +90,9 @@ struct ip_tunnel_info;
 #define IP6_DEFAULT_MAX_DST_OPTS_LEN	 INT_MAX /* No limit */
 #define IP6_DEFAULT_MAX_HBH_OPTS_LEN	 INT_MAX /* No limit */
 
+/* Hard limit on traversed IPv6 extension headers */
+#define IP6_MAX_EXT_HDRS_CNT		 12
+
 /*
  *	Addr type
  *	
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index 49e31e4ae7b7..9d06d487e8b1 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -73,6 +73,7 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp,
 		     __be16 *frag_offp)
 {
 	u8 nexthdr = *nexthdrp;
+	int exthdr_cnt = 0;
 
 	*frag_offp = 0;
 
@@ -82,6 +83,8 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp,
 
 		if (nexthdr == NEXTHDR_NONE)
 			return -1;
+		if (unlikely(exthdr_cnt++ >= IP6_MAX_EXT_HDRS_CNT))
+			return -1;
 		hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
 		if (!hp)
 			return -1;
@@ -190,6 +193,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
 {
 	unsigned int start = skb_network_offset(skb) + sizeof(struct ipv6hdr);
 	u8 nexthdr = ipv6_hdr(skb)->nexthdr;
+	int exthdr_cnt = 0;
 	bool found;
 
 	if (fragoff)
@@ -216,6 +220,9 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
 			return -ENOENT;
 		}
 
+		if (unlikely(exthdr_cnt++ >= IP6_MAX_EXT_HDRS_CNT))
+			return -EBADMSG;
+
 		hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
 		if (!hp)
 			return -EBADMSG;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 967b07aeb683..8972863c93ee 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -403,6 +403,7 @@ INDIRECT_CALLABLE_DECLARE(int tcp_v6_rcv(struct sk_buff *));
 void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
 			      bool have_final)
 {
+	int exthdr_cnt = IP6CB(skb)->flags & IP6SKB_HOPBYHOP ? 1 : 0;
 	const struct inet6_protocol *ipprot;
 	struct inet6_dev *idev;
 	unsigned int nhoff;
@@ -487,6 +488,10 @@ void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
 				nexthdr = ret;
 				goto resubmit_final;
 			} else {
+				if (unlikely(exthdr_cnt++ >= IP6_MAX_EXT_HDRS_CNT)) {
+					SKB_DR_SET(reason, IPV6_TOO_MANY_EXTHDRS);
+					goto discard;
+				}
 				goto resubmit;
 			}
 		} else if (ret == 0) {
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index c468c83af0f2..9d1037ac082f 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -399,11 +399,15 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
 	unsigned int nhoff = raw - skb->data;
 	unsigned int off = nhoff + sizeof(*ipv6h);
 	u8 nexthdr = ipv6h->nexthdr;
+	int exthdr_cnt = 0;
 
 	while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) {
 		struct ipv6_opt_hdr *hdr;
 		u16 optlen;
 
+		if (unlikely(exthdr_cnt++ >= IP6_MAX_EXT_HDRS_CNT))
+			break;
+
 		if (!pskb_may_pull(skb, off + sizeof(*hdr)))
 			break;
 
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH net 2/2] selftests: openvswitch: add tests for tunnel vport refcounting
From: Ilya Maximets @ 2026-04-29 16:08 UTC (permalink / raw)
  To: netdev
  Cc: i.maximets, Aaron Conole, Eelco Chaudron, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Shuah Khan, Yuan Tan, Yang Yang, dev, linux-kernel,
	linux-kselftest
In-Reply-To: <20260429151756.4157670-3-i.maximets@ovn.org>

On 4/29/26 5:16 PM, Ilya Maximets wrote:
> There were a few issues found with the tunnel vport types around the
> vport destruction code.  Add some basic tests, so at least we know that
> they can be properly added and removed without obvious issues.
> 
> The test creates OVS datapath, adds a non-LWT tunnel port, makes sure
> they are created, and then removes the datapath and waits for all the
> ports to be gone.
> 
> The dpctl script had a few bugs in the none-lwt tunnel creation code,
> so fixing them as well to make the testing possible:
> - The type of the --lwt option changed in order to properly disable it.
> - Removed byte order conversion for the port numbers, as the value
>   supposed to be in the host order.

Hrm, forgot to remove the import for socket library that is now unused.
Can send a v2 with that once I get some reviews on the set.

Best regards, Ilya Maximets.

^ permalink raw reply

* Re: [PATCH net-next 00/11] net: devmem: support devmem with netkit devices
From: Daniel Borkmann @ 2026-04-29 15:33 UTC (permalink / raw)
  To: Bobby Eshleman
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
	Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
	Joshua Washington, Harshitha Ramamurthy, Saeed Mahameed,
	Tariq Toukan, Mark Bloch, Leon Romanovsky, Alexander Duyck,
	kernel-team, Nikolay Aleksandrov, Shuah Khan, David Wei, netdev,
	linux-doc, linux-kernel, linux-rdma, bpf, linux-kselftest,
	Stanislav Fomichev, Mina Almasry, Bobby Eshleman
In-Reply-To: <afIhP5dtlzCtzn1T@devvm29614.prn0.facebook.com>

On 4/29/26 5:18 PM, Bobby Eshleman wrote:
> On Wed, Apr 29, 2026 at 02:08:31PM +0200, Daniel Borkmann wrote:
>> On 4/29/26 12:41 AM, Bobby Eshleman wrote:
>>> This series enables TCP devmem TX through netkit devices.
>>>
>>> Netkit now supports queue leasing. A physical NIC's RX queue can be
>>> leased to a netkit guest interface inside a container namespace. This
>>> gives the container a devmem-capable data path on the RX side (bind-rx,
>>> etc...). On the TX side, the container process binds to its netkit guest
>>> interface and sends traffic that netkit redirects (via BPF or ip
>>> forwarding) to the physical NIC for DMA.
>> [...]
>> Thanks for working on this, after the RX queue leasing got merged, I've
>> been looking into the same actually. :)
>>
>> I think the NETMEM_TX_* enum approach seems reasonable.
>>
>> What I have a PoC on is to build out TX queue leasing as first-class
>> symmetric infrastructure to complement the RX queue leasing - basically
>> I implemented an equivalent to the latter in netdev_nl_queue_create_doit
>> et al, so you can have independent RX and TX leases and per-queue
>> accountability, such that ynl queue-get op shows the full picture, and
>> lastly we could also enable AF_XDP TX-only support through this infra.
>>
>> Would you be open to collab on integrating both and migrating the devmem
>> code to work off an TX queue object? Next week is LSF/MM/BPF, are you
>> there by any chance to catch up in person?
> 
> Definitely am open to that. I will unfortunately not be at LSF/MM/BPF,
> but maybe we can schedule a meeting offline to sync up?

Ack, absolutely, will reach out offline to find sth after LSF/MM/BPF week.
If anyone else wants to join, just DM me.

Cheers,
Daniel

^ permalink raw reply

* Re: [PATCH 7/9] Bluetooth: hci_sync: Add NVMEM-backed BD address retrieval
From: Loic Poulain @ 2026-04-29 16:22 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Bartosz Golaszewski, Ulf Hansson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Jens Axboe, Johannes Berg, Jeff Johnson, Marcel Holtmann,
	Luiz Augusto von Dentz, Balakrishna Godavarthi, Rocky Liao,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, linux-mmc, devicetree, linux-kernel, linux-arm-msm,
	linux-block, linux-wireless, ath10k, linux-bluetooth, netdev,
	daniel
In-Reply-To: <e0adaf64-10d7-4e28-8403-769e3070ec30@lunn.ch>

Hi Bartosz, Andrew,

On Wed, Apr 29, 2026 at 3:15 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> On Wed, Apr 29, 2026 at 10:53:13AM +0200, Bartosz Golaszewski wrote:
> > On Tue, Apr 28, 2026 at 4:23 PM Loic Poulain
> > <loic.poulain@oss.qualcomm.com> wrote:
> > >
> > > Some devices store the Bluetooth BD address in non-volatile
> > > memory, which can be accessed through the NVMEM framework.
> > > Similar to Ethernet or WiFi MAC addresses, add support for
> > > reading the BD address from a 'local-bd-address' NVMEM cell.
> > >
> > > As with the device-tree provided BD address, add a quirk to
> > > indicate whether a device or platform should attempt to read
> > > the address from NVMEM when no valid in-chip address is present.
> > > Also add a quirk to indicate if the address is stored in
> > > big-endian byte order.
> > >
> > > Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> > > ---
> >
> > Is there any reason why we can't extend the existing
> > of_get_mac_address() with another property name and use it here? It
> > already has support for mac addresses from nvmem.
>
> Does it even need to be a different property name? Is a bluetooth MAC
> address somehow different to an Ethernet MAC address? Isn't it just a
> EUI-48, independent of it being Ethernet, Bluetooth, wifi, fddi, token
> ring, homing pigeon?

In terms of naming, I followed the pattern of the existing DT
properties: for Ethernet/WiFi there is mac-address property, and for
Bluetooth a local-bd-address property. So it seems reasonable to reuse
the same naming for the NVMEM labelling. Also One thing to keep in
mind is that Bluetooth has historically handled addresses in
little-endian format, while Ethernet MAC addresses are typically
stored in big-endian format (as far as I know).

That said, a more generic EUI-48 identifier could also make sense if
we want to go in that direction, with expected property/nvmem-cell
name(s) as parameters?

Regards,
Loic

^ permalink raw reply

* Re: [PATCH net-next] selftests/net: packetdrill: add tcp_syncookies_ip6_9k
From: Jakub Kicinski @ 2026-04-29 16:48 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S . Miller, Paolo Abeni, Simon Horman, Neal Cardwell,
	Kuniyuki Iwashima, netdev, eric.dumazet
In-Reply-To: <20260429080036.1528533-1-edumazet@google.com>

On Wed, 29 Apr 2026 08:00:36 +0000 Eric Dumazet wrote:
> This test checks syncookie mode is able to reconstruct some
> client options when TCP TS are used:
> 
> - wscale option.
> - sackOK.
> - MSS (in a limited way).
> - ECN (not tested, because of limited value).

We're getting:

# TAP version 13
# 1..1
#   File "/tmp/code_oyWax9", line 223
#     assert tcpi_snd_wscale = 10, tcpi_snd_wscale
#                            ^
# SyntaxError: invalid syntax
# tcp_syncookies_ip6_9k.pkt: error executing code: 'python3' returned non-zero status 1

do we need to update packetdrill ?

^ permalink raw reply

* Re: [Intel-wired-lan] [PATCH] i40e: Fix i40e_debug() to use struct i40e_hw argument
From: Mohamed Khalfella @ 2026-04-29 16:52 UTC (permalink / raw)
  To: Paul Menzel
  Cc: Tony Nguyen, Przemek Kitszel, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, intel-wired-lan, netdev,
	linux-kernel
In-Reply-To: <558971b7-caea-471a-8fe2-73ba6cc0790a@molgen.mpg.de>

On Wed 2026-04-29 13:02:00 +0200, Paul Menzel wrote:
> Dear Mohamed,
> 
> 
> Thank you for your patch.
> 
> Am 28.04.26 um 20:14 schrieb Mohamed Khalfella:
> > i40e_debug() macro takes struct i40e_hw *h as first argument. But the
> > macro body uses hw instead of h. This has been working so far because hw
> > happen to be the name of the variable in the context where the marco is
> 
> marco → ma*cr*o

Good catch. Also 'happen' should be 'happens'

> 
> > expanded. Fix the macro to use the passed argument.
> 
> I’d add a Fixes: tag, but the maintainers might have more input.

Yes, I should have added Fixes: tag. I will leave it to the maintainer
to decide if v2 is needed to fix the spelling mistakes and add Fixes
tag.

Fixes: 5dfd37c37a44 ("i40e: Split i40e_osdep.h")

> 
> > Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com>
> > ---
> >   drivers/net/ethernet/intel/i40e/i40e_debug.h | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/intel/i40e/i40e_debug.h b/drivers/net/ethernet/intel/i40e/i40e_debug.h
> > index e9871dfb32bd..01fd70db9086 100644
> > --- a/drivers/net/ethernet/intel/i40e/i40e_debug.h
> > +++ b/drivers/net/ethernet/intel/i40e/i40e_debug.h
> > @@ -42,7 +42,7 @@ struct device *i40e_hw_to_dev(struct i40e_hw *hw);
> >   #define i40e_debug(h, m, s, ...)				\
> >   do {								\
> >   	if (((m) & (h)->debug_mask))				\
> > -		dev_info(i40e_hw_to_dev(hw), s, ##__VA_ARGS__);	\
> > +		dev_info(i40e_hw_to_dev(h), s, ##__VA_ARGS__);	\
> >   } while (0)
> >   
> >   #endif /* _I40E_DEBUG_H_ */
> 
> Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
> 
> 
> Kind regards,
> 
> Paul
> 
> 
> PS: gemini/gemini-3.1-pro-preview embargoed it’s review until the 
> evening [1].
> 
> 
> [1]: 
> https://sashiko.dev/#/patchset/20260428181450.2622899-1-mkhalfella%40purestorage.com

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox