Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next v3 1/4] net: eth: fbnic: Fix addr validation in pcs write
From: Jakub Kicinski @ 2026-05-07  1:58 UTC (permalink / raw)
  To: Paolo Abeni
  Cc: mike.marciniszyn, Alexander Duyck, kernel-team, Andrew Lunn,
	David S. Miller, Eric Dumazet, Heiner Kallweit, Russell King,
	Jacob Keller, Mohsin Bashir, Simon Horman, Lee Trager,
	Andrew Lunn, netdev, linux-kernel
In-Reply-To: <20260504135815.44226-2-mike.marciniszyn@gmail.com>

On Mon,  4 May 2026 09:58:12 -0400 mike.marciniszyn@gmail.com wrote:
> From: "Mike Marciniszyn (Meta)" <mike.marciniszyn@gmail.com>
> 
> The DW IP has two distinct PCS address ranges cooresponding
> to the C45 PCS registers.
> 
> The shim translates the PCS addr/regno into specific CSR writes
> into one of those two zero-relative.
> 
> This patch fixes a one off in the test that could allow an invalid
> CSR write if an addr == 2 was called.
> 
> This patch contains a fix for addr validation in fbnic_mdio_write_pcs()
> to only return actual CSR reads for addr 0 and 1.
> 
> There are as of yet, no real impact for the bug as no PCS writes are
> not yet present.

Hi Paolo! Was there a reason / do you recall why this was not applied?
(I dropped it from patchwork now. If the omission was accidental it has
to be reposted)

^ permalink raw reply

* [linux-next:master] BUILD REGRESSION 735d2f48cadaa9a87e7c7601667878de70c771c5
From: kernel test robot @ 2026-05-07  1:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Memory Management List, netdev, Thierry Reding

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: 735d2f48cadaa9a87e7c7601667878de70c771c5  Add linux-next specific files for 20260506

Unverified Error/Warning (likely false positive, kindly check if interested):

    ERROR: modpost: "__aarch64_ldadd8_relax" [kernel/trace/preemptirq_delay_test.ko] undefined!
    ERROR: modpost: "__aarch64_ldadd8_relax" [kernel/trace/synth_event_gen_test.ko] undefined!
    ERROR: modpost: "__sync_fetch_and_add_8" [io_uring/mock_file.ko] undefined!

Error/Warning ids grouped by kconfigs:

recent_errors
|-- arm64-randconfig-r121-20260505
|   |-- ERROR:__aarch64_ldadd8_relax-kernel-trace-preemptirq_delay_test.ko-undefined
|   `-- ERROR:__aarch64_ldadd8_relax-kernel-trace-synth_event_gen_test.ko-undefined
|-- hexagon-randconfig-r131-20260506
|   `-- drivers-net-bareudp.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-struct-sock-sk-got-struct-sock-noderef-__rcu-sk
`-- parisc-randconfig-002-20260506
    `-- ERROR:__sync_fetch_and_add_8-io_uring-mock_file.ko-undefined

elapsed time: 725m

configs tested: 270
configs skipped: 7

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
alpha                               defconfig    gcc-15.2.0
arc                              allmodconfig    clang-16
arc                              allmodconfig    gcc-15.2.0
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    gcc-15.2.0
arc                                 defconfig    gcc-15.2.0
arc                   randconfig-001-20260507    gcc-10.5.0
arc                   randconfig-001-20260507    gcc-14.3.0
arc                   randconfig-002-20260507    gcc-14.3.0
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    clang-16
arm                              allyesconfig    gcc-15.2.0
arm                                 defconfig    clang-23
arm                                 defconfig    gcc-15.2.0
arm                   randconfig-001-20260507    clang-23
arm                   randconfig-002-20260507    gcc-10.5.0
arm                   randconfig-002-20260507    gcc-14.3.0
arm                   randconfig-003-20260507    clang-23
arm                   randconfig-004-20260507    gcc-13.4.0
arm                   randconfig-004-20260507    gcc-14.3.0
arm64                            allmodconfig    clang-19
arm64                             allnoconfig    gcc-15.2.0
arm64                               defconfig    gcc-15.2.0
arm64                          randconfig-001    gcc-8.5.0
arm64                 randconfig-001-20260506    gcc-8.5.0
arm64                 randconfig-001-20260507    gcc-15.2.0
arm64                          randconfig-002    gcc-14.3.0
arm64                 randconfig-002-20260506    gcc-8.5.0
arm64                 randconfig-002-20260507    gcc-15.2.0
arm64                          randconfig-003    clang-23
arm64                 randconfig-003-20260506    gcc-11.5.0
arm64                 randconfig-003-20260507    gcc-15.2.0
arm64                          randconfig-004    clang-23
arm64                 randconfig-004-20260506    clang-23
arm64                 randconfig-004-20260507    gcc-15.2.0
csky                             alldefconfig    gcc-15.2.0
csky                             allmodconfig    gcc-15.2.0
csky                              allnoconfig    gcc-15.2.0
csky                                defconfig    gcc-15.2.0
csky                           randconfig-001    gcc-10.5.0
csky                  randconfig-001-20260506    gcc-15.2.0
csky                  randconfig-001-20260507    gcc-15.2.0
csky                           randconfig-002    gcc-10.5.0
csky                  randconfig-002-20260506    gcc-15.2.0
csky                  randconfig-002-20260507    gcc-15.2.0
hexagon                          allmodconfig    clang-17
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-15.2.0
hexagon                             defconfig    clang-23
hexagon                             defconfig    gcc-15.2.0
hexagon               randconfig-001-20260506    clang-23
hexagon               randconfig-002-20260506    clang-23
i386                             allmodconfig    gcc-14
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-15.2.0
i386                             allyesconfig    gcc-14
i386                 buildonly-randconfig-001    clang-20
i386        buildonly-randconfig-001-20260506    gcc-14
i386        buildonly-randconfig-001-20260507    clang-20
i386        buildonly-randconfig-001-20260507    gcc-14
i386                 buildonly-randconfig-002    clang-20
i386        buildonly-randconfig-002-20260506    gcc-14
i386        buildonly-randconfig-002-20260507    clang-20
i386        buildonly-randconfig-002-20260507    gcc-14
i386                 buildonly-randconfig-003    clang-20
i386        buildonly-randconfig-003-20260506    clang-20
i386        buildonly-randconfig-003-20260507    clang-20
i386        buildonly-randconfig-003-20260507    gcc-14
i386                 buildonly-randconfig-004    clang-20
i386        buildonly-randconfig-004-20260506    clang-20
i386        buildonly-randconfig-004-20260507    clang-20
i386        buildonly-randconfig-004-20260507    gcc-14
i386                 buildonly-randconfig-005    clang-20
i386        buildonly-randconfig-005-20260506    clang-20
i386        buildonly-randconfig-005-20260507    clang-20
i386                 buildonly-randconfig-006    clang-20
i386        buildonly-randconfig-006-20260506    gcc-14
i386        buildonly-randconfig-006-20260507    clang-20
i386        buildonly-randconfig-006-20260507    gcc-14
i386                                defconfig    clang-20
i386                                defconfig    gcc-15.2.0
i386                  randconfig-001-20260506    gcc-14
i386                  randconfig-002-20260506    gcc-14
i386                  randconfig-003-20260506    gcc-14
i386                  randconfig-004-20260506    clang-20
i386                  randconfig-005-20260506    gcc-14
i386                  randconfig-006-20260506    gcc-14
i386                  randconfig-007-20260506    clang-20
i386                  randconfig-011-20260507    clang-20
i386                  randconfig-011-20260507    gcc-14
i386                  randconfig-012-20260507    clang-20
i386                  randconfig-013-20260507    clang-20
i386                  randconfig-013-20260507    gcc-14
i386                  randconfig-014-20260507    clang-20
i386                  randconfig-014-20260507    gcc-14
i386                  randconfig-015-20260506    gcc-14
i386                  randconfig-015-20260507    clang-20
i386                  randconfig-016-20260507    clang-20
i386                  randconfig-016-20260507    gcc-14
i386                  randconfig-017-20260507    clang-20
i386                  randconfig-017-20260507    gcc-14
loongarch                        allmodconfig    clang-19
loongarch                         allnoconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-19
loongarch             randconfig-001-20260506    clang-18
loongarch             randconfig-002-20260506    clang-23
m68k                             allmodconfig    gcc-15.2.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    clang-16
m68k                             allyesconfig    gcc-15.2.0
m68k                                defconfig    clang-19
m68k                                defconfig    gcc-15.2.0
m68k                          hp300_defconfig    gcc-15.2.0
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                          defconfig    clang-19
microblaze                          defconfig    gcc-15.2.0
mips                             allmodconfig    gcc-15.2.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
nios2                            allmodconfig    clang-23
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-23
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    clang-19
nios2                               defconfig    gcc-11.5.0
nios2                 randconfig-001-20260506    gcc-8.5.0
nios2                 randconfig-002-20260506    gcc-8.5.0
openrisc                         allmodconfig    clang-23
openrisc                         allmodconfig    gcc-15.2.0
openrisc                          allnoconfig    clang-23
openrisc                          allnoconfig    gcc-15.2.0
openrisc                            defconfig    gcc-15.2.0
parisc                           allmodconfig    gcc-15.2.0
parisc                            allnoconfig    clang-23
parisc                            allnoconfig    gcc-15.2.0
parisc                           allyesconfig    gcc-15.2.0
parisc                              defconfig    gcc-15.2.0
parisc                randconfig-001-20260506    gcc-13.4.0
parisc                randconfig-002-20260506    gcc-10.5.0
parisc64                            defconfig    clang-19
parisc64                            defconfig    gcc-15.2.0
powerpc                          allmodconfig    gcc-15.2.0
powerpc                           allnoconfig    clang-23
powerpc                           allnoconfig    gcc-15.2.0
powerpc               randconfig-001-20260506    gcc-10.5.0
powerpc               randconfig-002-20260506    gcc-8.5.0
powerpc64             randconfig-001-20260506    gcc-8.5.0
powerpc64             randconfig-002-20260506    gcc-13.4.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                             allnoconfig    gcc-15.2.0
riscv                            allyesconfig    clang-16
riscv                               defconfig    clang-23
riscv                               defconfig    gcc-15.2.0
riscv                 randconfig-001-20260507    clang-23
s390                             allmodconfig    clang-18
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-15.2.0
s390                                defconfig    clang-23
s390                                defconfig    gcc-15.2.0
s390                  randconfig-001-20260507    gcc-13.4.0
s390                  randconfig-002-20260507    clang-23
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-23
sh                                allnoconfig    gcc-15.2.0
sh                               allyesconfig    gcc-15.2.0
sh                                  defconfig    gcc-14
sh                                  defconfig    gcc-15.2.0
sh                    randconfig-001-20260507    gcc-10.5.0
sh                    randconfig-002-20260507    gcc-15.2.0
sparc                             allnoconfig    clang-23
sparc                             allnoconfig    gcc-15.2.0
sparc                               defconfig    gcc-15.2.0
sparc                 randconfig-001-20260506    gcc-15.2.0
sparc                 randconfig-002-20260506    gcc-11.5.0
sparc64                          allmodconfig    clang-23
sparc64                             defconfig    clang-20
sparc64                             defconfig    gcc-14
sparc64               randconfig-001-20260506    clang-23
sparc64               randconfig-002-20260506    clang-23
um                               allmodconfig    clang-19
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-14
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    clang-23
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                    randconfig-001-20260506    gcc-14
um                    randconfig-002-20260506    clang-23
um                           x86_64_defconfig    clang-23
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-20
x86_64                            allnoconfig    clang-20
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-20
x86_64      buildonly-randconfig-001-20260506    clang-20
x86_64      buildonly-randconfig-001-20260507    clang-20
x86_64      buildonly-randconfig-002-20260506    gcc-14
x86_64      buildonly-randconfig-002-20260507    clang-20
x86_64      buildonly-randconfig-003-20260506    clang-20
x86_64      buildonly-randconfig-003-20260507    clang-20
x86_64      buildonly-randconfig-004-20260506    clang-20
x86_64      buildonly-randconfig-004-20260507    clang-20
x86_64      buildonly-randconfig-005-20260506    gcc-12
x86_64      buildonly-randconfig-005-20260507    clang-20
x86_64      buildonly-randconfig-006-20260506    clang-20
x86_64      buildonly-randconfig-006-20260507    clang-20
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-20
x86_64                randconfig-001-20260506    gcc-13
x86_64                randconfig-002-20260506    clang-20
x86_64                randconfig-003-20260506    clang-20
x86_64                randconfig-004-20260506    clang-20
x86_64                randconfig-005-20260506    gcc-14
x86_64                randconfig-006-20260506    clang-20
x86_64                         randconfig-011    gcc-14
x86_64                randconfig-011-20260506    clang-20
x86_64                randconfig-011-20260507    gcc-14
x86_64                         randconfig-012    gcc-14
x86_64                randconfig-012-20260506    clang-20
x86_64                randconfig-012-20260507    gcc-14
x86_64                         randconfig-013    clang-20
x86_64                randconfig-013-20260506    clang-20
x86_64                randconfig-013-20260507    gcc-14
x86_64                         randconfig-014    gcc-14
x86_64                randconfig-014-20260506    clang-20
x86_64                randconfig-014-20260507    gcc-14
x86_64                         randconfig-015    gcc-14
x86_64                randconfig-015-20260506    gcc-12
x86_64                randconfig-015-20260507    gcc-14
x86_64                         randconfig-016    clang-20
x86_64                randconfig-016-20260506    gcc-14
x86_64                randconfig-016-20260507    gcc-14
x86_64                         randconfig-071    gcc-14
x86_64                randconfig-071-20260506    gcc-14
x86_64                randconfig-071-20260507    clang-20
x86_64                         randconfig-072    gcc-14
x86_64                randconfig-072-20260506    gcc-14
x86_64                randconfig-072-20260507    clang-20
x86_64                         randconfig-073    clang-20
x86_64                randconfig-073-20260506    gcc-14
x86_64                randconfig-073-20260507    clang-20
x86_64                         randconfig-074    gcc-14
x86_64                randconfig-074-20260506    clang-20
x86_64                randconfig-074-20260507    clang-20
x86_64                         randconfig-075    gcc-13
x86_64                randconfig-075-20260506    gcc-14
x86_64                randconfig-075-20260507    clang-20
x86_64                         randconfig-076    clang-20
x86_64                randconfig-076-20260506    clang-20
x86_64                randconfig-076-20260507    clang-20
x86_64                               rhel-9.4    clang-20
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-20
x86_64                    rhel-9.4-kselftests    clang-20
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-20
xtensa                            allnoconfig    clang-23
xtensa                            allnoconfig    gcc-15.2.0
xtensa                           allyesconfig    clang-23
xtensa                           allyesconfig    gcc-15.2.0
xtensa                randconfig-001-20260506    gcc-15.2.0
xtensa                randconfig-002-20260506    gcc-13.4.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH net v2] net: ethernet: cortina: Drop half-assembled SKB
From: patchwork-bot+netdevbpf @ 2026-05-07  2:00 UTC (permalink / raw)
  To: Linus Walleij
  Cc: ulli.kroll, andrew+netdev, davem, edumazet, kuba, pabeni,
	mirq-linux, lixiasong1, netdev, eitschman
In-Reply-To: <20260505-gemini-ethernet-fix-v2-1-997c31d06079@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue, 05 May 2026 23:52:17 +0200 you wrote:
> From: Andreas Haarmann-Thiemann <eitschman@nebelreich.de>
> 
> In gmac_rx() (drivers/net/ethernet/cortina/gemini.c), when
> gmac_get_queue_page() returns NULL for the second page of a multi-page
> fragment, the driver logs an error and continues — but does not free the
> partially assembled skb that was being assembled via napi_build_skb() /
> napi_get_frags().
> 
> [...]

Here is the summary with links:
  - [net,v2] net: ethernet: cortina: Drop half-assembled SKB
    https://git.kernel.org/netdev/net/c/b266bacba796

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH net-next v4 0/3] r8152: Add support for the RTL8159 10Gbit USB Ethernet chip
From: patchwork-bot+netdevbpf @ 2026-05-07  2:00 UTC (permalink / raw)
  To: Birger Koblitz
  Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux-usb, netdev,
	linux-kernel, hsu.chih.kai, andrew, olek2
In-Reply-To: <20260505-rtl8159_net_next-v4-0-1a648a9c4d8d@birger-koblitz.de>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue, 05 May 2026 17:56:32 +0200 you wrote:
> Add support for the RTL8159, which is a 10GBit USB-Ethernet adapter
> chip in the RTL815x family of chips.
> 
> The RTL8159 re-uses the frame descriptor format and SRAM2 access introduced
> with the RTL8157 as well as most of the setup and PM logic of the RTL8157.
> 
> The module was tested with a Lekuo DR59R11 USB-C 10GbE Ethernet Adapter:
> [ 2502.906947] usb 2-1: new SuperSpeed USB device number 3 using xhci_hcd
> [ 2502.927859] usb 2-1: New USB device found, idVendor=0bda, idProduct=815a, bcdDevice=30.00
> [ 2502.927867] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=7
> [ 2502.927871] usb 2-1: Product: USB 10/100/1G/2.5G/5G/10G LAN
> [ 2502.927873] usb 2-1: Manufacturer: Realtek
> [ 2502.927875] usb 2-1: SerialNumber: 000388C9B3B5XXXX
> [ 2503.063745] r8152-cfgselector 2-1: reset SuperSpeed USB device number 3 using xhci_hcd
> [ 2503.123876] r8152 2-1:1.0: Requesting firmware: rtl_nic/rtl8159-1.fw
> [ 2503.126267] r8152 2-1:1.0: PHY firmware installed 0 to be loaded: 20
> [ 2503.156265] r8152 2-1:1.0: load rtl8159-1 v1 2026/01/01 successfully
> [ 2503.270729] r8152 2-1:1.0 eth0: v1.12.13
> [ 2503.289349] r8152 2-1:1.0 enx88c9b3b5xxxx: renamed from eth0
> [ 2507.777055] r8152 2-1:1.0 enx88c9b3b5xxxx: carrier on
> 
> [...]

Here is the summary with links:
  - [net-next,v4,1/3] r8152: Add support for 10Gbit Link Speeds and EEE
    https://git.kernel.org/netdev/net-next/c/9774acd5fa5d
  - [net-next,v4,2/3] r8152: Add support for the RTL8159 chip
    https://git.kernel.org/netdev/net-next/c/ad2a55b63b41
  - [net-next,v4,3/3] r8152: Add firmware upload capability for RTL8157/RTL8159
    https://git.kernel.org/netdev/net-next/c/a51e171e176c

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* [PATCH net v2 0/3] macsec: use rcu_work to fix crypto cleanup in softirq context
From: alexjlzheng @ 2026-05-07  2:04 UTC (permalink / raw)
  To: sd, andrew+netdev, davem, edumazet, kuba, pabeni, horms, hannes,
	albinwyang, kuniyu, shenyangyang4
  Cc: netdev, linux-kernel, Jinliang Zheng

From: Jinliang Zheng <alexjlzheng@tencent.com>

crypto_free_aead() can internally call vunmap() (e.g. via dma_free_attrs()
in hardware crypto drivers like hisi_sec2), which must not be invoked from
softirq context. Both free_rxsa() and free_txsa() are RCU callbacks that
run in softirq, causing a kernel crash on affected hardware.

This series fixes the issue by deferring the actual cleanup to a workqueue
using rcu_work, which combines the RCU grace period and workqueue dispatch
into a single primitive.

Two design decisions worth noting:

1. rcu_work instead of schedule_work() + synchronize_rcu()

   An alternative would be to call schedule_work() directly from
   macsec_rxsa_put()/macsec_txsa_put(), then call synchronize_rcu() at
   the start of the work handler to replace the grace period previously
   provided by call_rcu(). However, synchronize_rcu() blocks the worker
   thread for the duration of a full RCU grace period. Under high SA
   churn (e.g. tearing down an interface with many SAs), each SA would
   occupy a worker thread while waiting, and multiple concurrent calls
   cannot share the same grace period — leading to unnecessary latency
   and resource waste.

   rcu_work uses call_rcu_hurry() internally, which is fully asynchronous:
   the worker thread is only dispatched after the grace period has elapsed,
   and multiple concurrent queue_rcu_work() calls naturally batch under the
   same grace period via the RCU subsystem's existing coalescing mechanism.

2. Dedicated workqueue instead of system_wq

   Using a dedicated workqueue (macsec_wq) allows macsec_exit() to drain
   exactly the work items belonging to this module — by calling
   destroy_workqueue() after rcu_barrier(). If system_wq were used,
   flush_scheduled_work() would drain all pending work items across the
   entire system, creating unnecessary coupling with unrelated subsystems
   and potentially causing unexpected delays. The dedicated workqueue
   provides a clean, contained teardown path.

Changes in v2:
- Use rcu_work instead of work_struct to avoid the manual RCU callback
  wrapper (suggested by Kuniyuki Iwashima)
- Introduce a dedicated workqueue and drain it properly in macsec_exit()
  to prevent potential crash on module unload (noted by Sabrina Dubroca)
- Extend the fix to TX SAs, which suffer from the same issue
  (noted by Sabrina Dubroca)
- Add Fixes tag (noted by Sabrina Dubroca)
- Split into three patches

Thanks to Kuniyuki Iwashima and Sabrina Dubroca for the review.

Link: https://lore.kernel.org/netdev/20260506100107.388184-1-alexjlzheng@tencent.com/T/#u

Jinliang Zheng (3):
  macsec: introduce dedicated workqueue for SA crypto cleanup
  macsec: use rcu_work to defer RX SA crypto cleanup out of softirq
  macsec: use rcu_work to defer TX SA crypto cleanup out of softirq

 drivers/net/macsec.c | 27 ++++++++++++++++++++-------
 include/net/macsec.h |  5 +++--
 2 files changed, 23 insertions(+), 9 deletions(-)

-- 
2.39.3


^ permalink raw reply

* [PATCH net v2 v2 1/3] macsec: introduce dedicated workqueue for SA crypto cleanup
From: alexjlzheng @ 2026-05-07  2:04 UTC (permalink / raw)
  To: sd, andrew+netdev, davem, edumazet, kuba, pabeni, horms, hannes,
	albinwyang, kuniyu, shenyangyang4
  Cc: netdev, linux-kernel, Jinliang Zheng
In-Reply-To: <20260507020426.1126254-1-alexjlzheng@tencent.com>

From: Jinliang Zheng <alexjlzheng@tencent.com>

Introduce a dedicated ordered workqueue, macsec_wq, which will be used
by subsequent patches to defer SA crypto cleanup (crypto_free_aead and
related teardown) out of softirq context.

Using a dedicated workqueue instead of system_wq allows macsec_exit()
to drain exactly the work items belonging to this module via
destroy_workqueue(), without interfering with unrelated work items on
system_wq or causing unexpected delays elsewhere.

rcu_barrier() in macsec_exit() ensures all in-flight rcu_work callbacks
have enqueued their work items before destroy_workqueue() drains and
destroys the queue, making the two-step teardown correct and complete.

Signed-off-by: Jinliang Zheng <alexjlzheng@tencent.com>
---
 drivers/net/macsec.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index f6cad0746a02..ddb22473e701 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -26,6 +26,8 @@
 
 #include <uapi/linux/if_macsec.h>
 
+static struct workqueue_struct *macsec_wq;
+
 /* SecTAG length = macsec_eth_header without the optional SCI */
 #define MACSEC_TAG_LEN 6
 
@@ -4450,10 +4452,14 @@ static int __init macsec_init(void)
 {
 	int err;
 
+	macsec_wq = alloc_ordered_workqueue("macsec", 0);
+	if (!macsec_wq)
+		return -ENOMEM;
+
 	pr_info("MACsec IEEE 802.1AE\n");
 	err = register_netdevice_notifier(&macsec_notifier);
 	if (err)
-		return err;
+		goto wq;
 
 	err = rtnl_link_register(&macsec_link_ops);
 	if (err)
@@ -4469,6 +4475,8 @@ static int __init macsec_init(void)
 	rtnl_link_unregister(&macsec_link_ops);
 notifier:
 	unregister_netdevice_notifier(&macsec_notifier);
+wq:
+	destroy_workqueue(macsec_wq);
 	return err;
 }
 
@@ -4478,6 +4486,7 @@ static void __exit macsec_exit(void)
 	rtnl_link_unregister(&macsec_link_ops);
 	unregister_netdevice_notifier(&macsec_notifier);
 	rcu_barrier();
+	destroy_workqueue(macsec_wq);
 }
 
 module_init(macsec_init);
-- 
2.39.3


^ permalink raw reply related

* [PATCH net v2 v2 2/3] macsec: use rcu_work to defer RX SA crypto cleanup out of softirq
From: alexjlzheng @ 2026-05-07  2:04 UTC (permalink / raw)
  To: sd, andrew+netdev, davem, edumazet, kuba, pabeni, horms, hannes,
	albinwyang, kuniyu, shenyangyang4
  Cc: netdev, linux-kernel, Jinliang Zheng
In-Reply-To: <20260507020426.1126254-1-alexjlzheng@tencent.com>

From: Jinliang Zheng <alexjlzheng@tencent.com>

crypto_free_aead() can internally invoke vunmap() (e.g. via
dma_free_attrs() in hardware crypto drivers such as hisi_sec2).
vunmap() must not be called from softirq context, but free_rxsa()
is an RCU callback that runs in softirq, leading to a kernel crash:

  vunmap+0x4c/0x70
  __iommu_dma_free+0xd0/0x138
  dma_free_attrs+0xf4/0x100
  sec_aead_exit+0x64/0xb8 [hisi_sec2]
  crypto_destroy_tfm+0x98/0x110
  free_rxsa+0x28/0x50 [macsec]
  rcu_do_batch+0x184/0x460
  rcu_core+0xf4/0x1f8
  handle_softirqs+0x118/0x330

Use rcu_work to defer the cleanup to a workqueue. rcu_work dispatches
the worker asynchronously after the RCU grace period, so no thread
blocks waiting, and concurrent releases of multiple SAs naturally
share the same grace period.

Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
Signed-off-by: Jinliang Zheng <alexjlzheng@tencent.com>
---
 drivers/net/macsec.c | 8 +++++---
 include/net/macsec.h | 3 ++-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index ddb22473e701..e0862ecd23f2 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -176,9 +176,10 @@ static void macsec_rxsc_put(struct macsec_rx_sc *sc)
 		call_rcu(&sc->rcu_head, free_rx_sc_rcu);
 }
 
-static void free_rxsa(struct rcu_head *head)
+static void free_rxsa_work(struct work_struct *work)
 {
-	struct macsec_rx_sa *sa = container_of(head, struct macsec_rx_sa, rcu);
+	struct macsec_rx_sa *sa =
+		container_of(to_rcu_work(work), struct macsec_rx_sa, destroy_work);
 
 	crypto_free_aead(sa->key.tfm);
 	free_percpu(sa->stats);
@@ -188,7 +189,7 @@ static void free_rxsa(struct rcu_head *head)
 static void macsec_rxsa_put(struct macsec_rx_sa *sa)
 {
 	if (refcount_dec_and_test(&sa->refcnt))
-		call_rcu(&sa->rcu, free_rxsa);
+		queue_rcu_work(macsec_wq, &sa->destroy_work);
 }
 
 static struct macsec_tx_sa *macsec_txsa_get(struct macsec_tx_sa __rcu *ptr)
@@ -1409,6 +1410,7 @@ static int init_rx_sa(struct macsec_rx_sa *rx_sa, char *sak, int key_len,
 	rx_sa->next_pn = 1;
 	refcount_set(&rx_sa->refcnt, 1);
 	spin_lock_init(&rx_sa->lock);
+	INIT_RCU_WORK(&rx_sa->destroy_work, free_rxsa_work);
 
 	return 0;
 }
diff --git a/include/net/macsec.h b/include/net/macsec.h
index bc7de5b53e54..d6136debe1c8 100644
--- a/include/net/macsec.h
+++ b/include/net/macsec.h
@@ -9,6 +9,7 @@
 
 #include <linux/u64_stats_sync.h>
 #include <linux/if_vlan.h>
+#include <linux/workqueue.h>
 #include <uapi/linux/if_link.h>
 #include <uapi/linux/if_macsec.h>
 
@@ -136,7 +137,7 @@ struct macsec_rx_sa {
 	bool active;
 	struct macsec_rx_sa_stats __percpu *stats;
 	struct macsec_rx_sc *sc;
-	struct rcu_head rcu;
+	struct rcu_work destroy_work;
 };
 
 struct pcpu_rx_sc_stats {
-- 
2.39.3


^ permalink raw reply related

* [PATCH net v2 v2 3/3] macsec: use rcu_work to defer TX SA crypto cleanup out of softirq
From: alexjlzheng @ 2026-05-07  2:04 UTC (permalink / raw)
  To: sd, andrew+netdev, davem, edumazet, kuba, pabeni, horms, hannes,
	albinwyang, kuniyu, shenyangyang4
  Cc: netdev, linux-kernel, Jinliang Zheng
In-Reply-To: <20260507020426.1126254-1-alexjlzheng@tencent.com>

From: Jinliang Zheng <alexjlzheng@tencent.com>

free_txsa() is an RCU callback running in softirq context, but calls
crypto_free_aead() which can invoke vunmap() internally on hardware
crypto drivers (e.g. hisi_sec2), triggering a kernel crash.

Use rcu_work to defer the cleanup to a workqueue, for the same reasons
as the analogous fix to free_rxsa() in the previous patch.

Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
Signed-off-by: Jinliang Zheng <alexjlzheng@tencent.com>
---
 drivers/net/macsec.c | 8 +++++---
 include/net/macsec.h | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index e0862ecd23f2..c3eefeef9526 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -205,9 +205,10 @@ static struct macsec_tx_sa *macsec_txsa_get(struct macsec_tx_sa __rcu *ptr)
 	return sa;
 }
 
-static void free_txsa(struct rcu_head *head)
+static void free_txsa_work(struct work_struct *work)
 {
-	struct macsec_tx_sa *sa = container_of(head, struct macsec_tx_sa, rcu);
+	struct macsec_tx_sa *sa =
+		container_of(to_rcu_work(work), struct macsec_tx_sa, destroy_work);
 
 	crypto_free_aead(sa->key.tfm);
 	free_percpu(sa->stats);
@@ -217,7 +218,7 @@ static void free_txsa(struct rcu_head *head)
 static void macsec_txsa_put(struct macsec_tx_sa *sa)
 {
 	if (refcount_dec_and_test(&sa->refcnt))
-		call_rcu(&sa->rcu, free_txsa);
+		queue_rcu_work(macsec_wq, &sa->destroy_work);
 }
 
 static struct macsec_cb *macsec_skb_cb(struct sk_buff *skb)
@@ -1510,6 +1511,7 @@ static int init_tx_sa(struct macsec_tx_sa *tx_sa, char *sak, int key_len,
 	tx_sa->active = false;
 	refcount_set(&tx_sa->refcnt, 1);
 	spin_lock_init(&tx_sa->lock);
+	INIT_RCU_WORK(&tx_sa->destroy_work, free_txsa_work);
 
 	return 0;
 }
diff --git a/include/net/macsec.h b/include/net/macsec.h
index d6136debe1c8..cf92f57733df 100644
--- a/include/net/macsec.h
+++ b/include/net/macsec.h
@@ -187,7 +187,7 @@ struct macsec_tx_sa {
 	refcount_t refcnt;
 	bool active;
 	struct macsec_tx_sa_stats __percpu *stats;
-	struct rcu_head rcu;
+	struct rcu_work destroy_work;
 };
 
 /**
-- 
2.39.3


^ permalink raw reply related

* Re: [PATCH net-next v3] net: stmmac: Add support for TX/RX channel interrupt
From: Jakub Kicinski @ 2026-05-07  2:07 UTC (permalink / raw)
  To: muhammad.nazim.amirul.nazle.asmade
  Cc: netdev, davem, pabeni, edumazet, andrew+netdev, linux-kernel
In-Reply-To: <20260506020018.25014-1-muhammad.nazim.amirul.nazle.asmade@altera.com>

On Tue,  5 May 2026 19:00:18 -0700
muhammad.nazim.amirul.nazle.asmade@altera.com wrote:
> - Add net-next tree prefix to subject line.
> - Fix variable declarations to follow Reverse Christmas Tree order.

This patch does not apply to net-next, please rebase and repost.

^ permalink raw reply

* RE: [PATCH v5 net-next 12/15] net: dsa: netc: add FDB, STP, MTU, port setup and host flooding support
From: Wei Fang @ 2026-05-07  2:08 UTC (permalink / raw)
  To: Claudiu Manoil, Vladimir Oltean, Clark Wang,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org, f.fainelli@gmail.com,
	Frank Li, chleroy@kernel.org, horms@kernel.org,
	linux@armlinux.org.uk
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org, imx@lists.linux.dev
In-Reply-To: <20260430024945.3413973-13-wei.fang@nxp.com>

There are some false positives reported by Sashiko, see the comments
from Sashiko and my response inline. Other comments are useful and
I will add improvements in v6.

>  static int netc_setup(struct dsa_switch *ds)
>  {
>  	struct netc_switch *priv = ds->priv;
> @@ -393,6 +627,8 @@ static int netc_setup(struct dsa_switch *ds)
>  	if (err)
>  		return err;
> 
> +	netc_get_switch_capabilities(priv);
> +
>  	err = netc_init_all_ports(priv);

Sashiko says:
Since the DSA subsystem can call setup() and teardown() multiple times
(for example, if the CPU master interface is unbound and rebound), does
calling netc_init_all_ports() here leak memory?

Looking at netc_init_all_ports(), it uses devm_kcalloc() and devm_kzalloc()
for the priv->ports array and port structures. Because devm_ allocations
are tied to the PCI device lifetime, they won't be freed during teardown(),
which could lead to a memory leak on each rebind.

Response: Analysis of the DSA core driver reveals the following call stack
for setup():

netc_switch_probe()
	└──dsa_register_switch()
		 └── dsa_switch_probe()
			   └── dsa_tree_setup()
				     └── dsa_tree_setup_switches()
						   └── dsa_switch_setup()

netc_setup() is only called when the switch driver probes, so it will not
be called multiple times during the lifetime of the DSA switch device.

[...]


> +static int netc_port_fdb_add(struct dsa_switch *ds, int port,
> +			     const unsigned char *addr, u16 vid,
> +			     struct dsa_db db)
> +{
> +	struct netc_port *np = NETC_PORT(ds, port);
> +
> +	/* Currently, only support standalone port mode, so only
> +	 * NETC_STANDALONE_PVID (= 0) is supported here.
> +	 */
> +	if (vid != NETC_STANDALONE_PVID)
> +		return -EOPNOTSUPP;
> +
> +	return netc_port_set_fdb_entry(np, addr, vid);
> +}

Sashiko says:
Does this implementation break network isolation between standalone ports?

The driver sets ds->fdb_isolation = true in netc_switch_probe(), which
means it must isolate FDB entries per standalone port or bridge. However,
the isolation context (struct dsa_db db) is ignored here and all entries
are placed in NETC_STANDALONE_PVID (0).

If the same MAC address is added to multiple standalone ports, such as an
IPv6 multicast group, the single FDB entry in VID 0 is updated to include
all these ports in its port_bitmap. A frame matching this MAC arriving on
one standalone port will then be switched in hardware to the other
standalone ports, instead of keeping the traffic properly isolated.

Response: Currently, the NETC switch only supports single port mode, so
all the FDB entries are only added to the CPU port, they will not be added
to the user ports. So this is a false positive.


^ permalink raw reply

* Re: [PATCH net] net: usb: asix: ax88772: replace usbnet_link_change() with queue_work() and usbnet_unlink_rx_urbs()
From: Jakub Kicinski @ 2026-05-07  2:15 UTC (permalink / raw)
  To: Markus.Baier
  Cc: Jakub Kicinski, o.rempel, andrew+netdev, davem, edumazet, pabeni,
	linux, enelsonmoore, linmq006, linux-usb, linux-kernel, netdev
In-Reply-To: <20260506010344.184636-1-Markus.Baier@soslab.tu-darmstadt.de>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
Subject: net: usb: asix: ax88772: replace usbnet_link_change() with queue_work() and usbnet_unlink_rx_urbs()

This patch replaces the usbnet_link_change() calls in the ax88772
phylink mac_link_up()/mac_link_down() callbacks with direct
queue_work(system_bh_wq, &dev->bh_work) and usbnet_unlink_rx_urbs(),
with the stated rationale that phylink already manages the carrier
state. It is tagged Fixes: 36bdc0e815b4 ("net: usb: asix: ax88772:
re-add usbnet_link_change() in phylink callbacks").

> diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
> index 293ef80c4e30..4230ff611c4b 100644
> --- a/drivers/net/usb/asix_devices.c
> +++ b/drivers/net/usb/asix_devices.c

[ ... mac_link_down hunk snipped, not relevant to the comment below ... ]

> @@ -787,7 +791,11 @@ static void ax88772_mac_link_up(struct phylink_config *config,
>  		m |= AX_MEDIUM_RFC;
>  
>  	asix_write_medium_mode(dev, m, 0);
> -	usbnet_link_change(dev, true, false);
> +
> +	/* Phylink will call netif_carrier_on(), but we need to explicitly
> +	 * kick off RX URB submission in usbnet.
> +	 */
> +	queue_work(system_bh_wq, &dev->bh_work);
>  }

Can this reintroduce the "no RX until first TX" symptom that commit
805206e66fab ("net: asix: fix 'can't send until first packet is send'
issue") and the Fixes: target 36bdc0e815b4 addressed?

Looking at the ordering in phylink_link_up() in drivers/net/phy/phylink.c,
the mac_link_up() callback is invoked before netif_carrier_on():

	pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->act_link_an_mode,
				 pl->cur_interface, speed, duplex,
				 !!(link_state.pause & MLO_PAUSE_TX), rx_pause);

	if (pl->mac_supports_eee && pl->phy_enable_tx_lpi)
		phylink_activate_lpi(pl);

	if (ndev)
		netif_carrier_on(ndev);

So when ax88772_mac_link_up() runs queue_work(system_bh_wq, &dev->bh_work),
the netdev carrier is still off.

system_bh_wq is a WQ_BH workqueue, so queue_work() on it raises
TASKLET_SOFTIRQ, which can be serviced on the next hard-IRQ exit (or by
ksoftirqd) before phylink_link_up() reaches netif_carrier_on().

When bh_work runs, usbnet_bh() in drivers/net/usb/usbnet.c gates RX URB
submission on netif_carrier_ok():

	} else if (netif_running (dev->net) &&
		   netif_device_present (dev->net) &&
		   netif_carrier_ok(dev->net) &&
		   ...
		   !test_bit(EVENT_RX_HALT, &dev->flags)) {
		...
		if (temp < RX_QLEN(dev)) {
			if (rx_alloc_submit(dev, GFP_ATOMIC) == -ENOLINK)
				return;
			...
			if (dev->rxq.qlen < RX_QLEN(dev))
				queue_work(system_bh_wq, &dev->bh_work);
		}

If carrier is still off when usbnet_bh() runs, the rx_alloc_submit()
branch is skipped and bh_work does not reschedule itself. Once phylink
eventually calls netif_carrier_on(), nothing kicks bh_work again: the
in-flight RX URBs were unlinked by the prior ax88772_mac_link_down(),
so there are no URB completions to re-queue work either.

Does the previous usbnet_link_change() path avoid this race because
__handle_link_change() in drivers/net/usb/usbnet.c flips the carrier
before queuing work?

	if (test_and_clear_bit(EVENT_LINK_CARRIER_ON, &dev->flags))
		netif_carrier_on(dev->net);

	if (!netif_carrier_ok(dev->net)) {
		/* kill URBs for reading packets to save bus bandwidth */
		unlink_urbs(dev, &dev->rxq);
		...
	} else {
		/* submitting URBs for reading packets */
		queue_work(system_bh_wq, &dev->bh_work);
	}

Here bh_work only runs after carrier_ok() is already true, so the gate
in usbnet_bh() cannot close on it.

Given the Fixes: tag targets -stable, is there a concern that this
patch partly reintroduces the original "RX silent until first TX or
link bounce" regression?

Would scheduling bh_work from a phylink_resolve() follow-up, or keeping
the usbnet_link_change() path (which sets EVENT_LINK_CARRIER_ON and
lets __handle_link_change() order carrier-on before queue_work), be a
safer sequencing?

As a side note, the comment added by this hunk states "Phylink will
call netif_carrier_on(), but we need to explicitly kick off RX URB
submission in usbnet." Should the comment reflect that phylink calls
netif_carrier_on() after this callback returns, rather than before, so
the ordering assumption is explicit?
-- 
pw-bot: cr

^ permalink raw reply

* RE: [Patch net-next v1 0/7] r8169: add RSS support for RTL8127
From: Javen @ 2026-05-07  2:19 UTC (permalink / raw)
  To: Heiner Kallweit, nic_swsd@realtek.com, andrew+netdev@lunn.ch,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, horms@kernel.org
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <bf301c5e-f6a3-459f-8eaa-a4032aaa3aa3@gmail.com>

>On 06.05.2026 10:13, javen wrote:
>> From: Javen Xu <javen_xu@realsil.com.cn>
>>
>> This patch series adds RSS (Receive Side Scaling) support for the
>> r8169 ethernet driver, specifically for RTL8127 (RTL_GIGA_MAC_VER_80).
>
>Series adds RSS support for RTL8127 only. Is this generic enough to retrofit RSS
>support for other chip versions like RTL8126 w/o bigger refactoring?
>
Yes. The current implementation is generic enough. Almost all the registers are shared and can be reused. If we want to enable rss for 8125/8126 later, the only necessary change would be setting tp->init_rx_desc_type to a new value. And add a new struct rx_desc for 8125 or 8126. For example, this is a desc type for 8125.
struct RxDescV3 {
        union {
                struct {
                        u32 rsv1;
                        u32 rsv2;
                } RxDescDDWord1;
        };
        union {
                struct {
                        u32 RSSResult;
                        u16 HeaderBufferLen;
                        u16 HeaderInfo;
                } RxDescNormalDDWord2;

                struct {
                        u32 rsv5;
                        u32 rsv6;
                } RxDescDDWord2;
        };
        union {
                u64   addr;

                struct {
                        u32 TimeStampLow;
                        u32 TimeStampHigh;
                } RxDescTimeStamp;

                struct {
                        u32 rsv8;
                        u32 rsv9;
                } RxDescDDWord3;
        };
        union {
                struct {
                        u32 opts2;
                        u32 opts1;
                } RxDescNormalDDWord4;

                struct {
                        u16 TimeStampHHigh;
                        u16 rsv11;
                        u32 opts1;
                } RxDescPTPDDWord4;
        };
};
This is complex because it reserves some words for PTP.

Thanks,
BRs,
Javen

>>
>> RSS enables packet distribution across multiple receive queues, which
>> can significantly improve network throughput on multi-core systems by
>> allowing parallel processing of incoming packets.
>>
>> Key features:
>> - Multi-queue RX support (up to 8 queues)
>> - MSI-X interrupt with vector mapping
>> - Dynamic queue configuration via ethtool (-L)
>> - RSS hash computation for flow classification
>>
>> Experiments:
>> Platform: AMD Ryzen Embedded R2514 with Radeon Graphics(4 Cores/8
>> Threads)
>> Arch: x86_64
>> Test command:
>>   Server: iperf3 -s
>>   Client: iperf3 -c 192.168.2.1 -P 20 -t 3600
>> Monitor: mpstat -P ALL 1
>>
>> Before this patch (Without RSS):
>>   Throughput: Unstable, fluctuating between 3.76 Gbits/sec and
>>   8.2 Gbits/sec.
>>   CPU Usage: A single CPU core is fully occupied with softirq reaching
>>   up to 96%.
>>
>> After this patch (With RSS enabled):
>>   Throughput: Stable at 9.42 Gbits/sec.
>>   CPU Usage: The traffic load is evenly distributed across multiple CPU
>>   cores. The maximum softirq on a single core dropped to 63%.
>>
>> Other Experiments:
>> Link:
>> https://lore.kernel.org/netdev/0A5279953D81BB9C+f50c9b49-3e5d-467f-
>b69
>> a-7e49ed223383@radxa.com/
>>
>> Javen Xu (7):
>>   r8169: add support for multi irqs
>>   r8169: add support for multi rx queues
>>   r8169: add support for new interrupt mapping
>>   r8169: enable new interrupt mapping
>>   r8169: add support and enable rss
>>   r8169: move struct ethtool_ops
>>   r8169: add support for ethtool
>>
>>  drivers/net/ethernet/realtek/r8169_main.c | 1202
>> ++++++++++++++++++---
>>  1 file changed, 1080 insertions(+), 122 deletions(-)
>>


^ permalink raw reply

* Re: [PATCH net-next V3 0/7] net/mlx5: Improve representor lifecycle and late IB representor loading
From: patchwork-bot+netdevbpf @ 2026-05-07  2:20 UTC (permalink / raw)
  To: Tariq Toukan
  Cc: edumazet, kuba, pabeni, andrew+netdev, davem, leon, jgg, saeedm,
	mbloch, shayd, ohartoov, edwards, horms, msanalla, parav, phaddad,
	kees, gbayer, moshe, cjubran, cratiu, linux-rdma, linux-kernel,
	netdev, gal, dtatulea
In-Reply-To: <20260503202726.266415-1-tariqt@nvidia.com>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Sun, 3 May 2026 23:27:19 +0300 you wrote:
> Hi,
> 
> Find detailed description by Mark below.
> 
> Regards,
> Tariq
> 
> [...]

Here is the summary with links:
  - [net-next,V3,1/7] net/mlx5: Lag: refactor representor reload handling
    https://git.kernel.org/netdev/net-next/c/b501400fa66d
  - [net-next,V3,2/7] net/mlx5: E-Switch, let esw work callers choose GFP flags
    https://git.kernel.org/netdev/net-next/c/386ef557f6df
  - [net-next,V3,3/7] net/mlx5: E-Switch, add representor lifecycle lock
    https://git.kernel.org/netdev/net-next/c/9b8468f001e4
  - [net-next,V3,4/7] net/mlx5: Lag, avoid LAG and representor lock cycles
    https://git.kernel.org/netdev/net-next/c/63ec6c69e613
  - [net-next,V3,5/7] net/mlx5: E-Switch, serialize representor lifecycle
    https://git.kernel.org/netdev/net-next/c/32a72840ee30
  - [net-next,V3,6/7] net/mlx5: E-Switch, unwind only newly loaded representor types
    https://git.kernel.org/netdev/net-next/c/8a6712925d38
  - [net-next,V3,7/7] net/mlx5: E-Switch, load reps via work queue after registration
    https://git.kernel.org/netdev/net-next/c/25933aca1012

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* RE: [PATCH v5 net-next 13/15] net: dsa: netc: initialize buffer pool table and implement flow-control
From: Wei Fang @ 2026-05-07  2:27 UTC (permalink / raw)
  To: Claudiu Manoil, Vladimir Oltean, Clark Wang,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org, f.fainelli@gmail.com,
	Frank Li, chleroy@kernel.org, horms@kernel.org,
	linux@armlinux.org.uk
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org, imx@lists.linux.dev
In-Reply-To: <20260430024945.3413973-14-wei.fang@nxp.com>

> +static void netc_ipv_to_buffer_pool_mapping(struct netc_switch *priv)
> +{
> +	int bp_per_port = priv->num_bp / priv->info->num_ports;
> +	int q = NETC_IPV_NUM / bp_per_port;
> +	int r = NETC_IPV_NUM % bp_per_port;
> +	int num = q + r;
> +
> +	/* IPV-to–buffer-pool mapping per port:
> +	 * Each port is allocated 'bp_per_port' buffer pools and supports 8
> +	 * IPVs, where a higher IPV indicates a higher frame priority. Each
> +	 * IPV can be mapped to only one buffer pool.
> +	 *
> +	 * The mapping rule is as follows:
> +	 * - The first 'num' IPVs share the port's first buffer pool (index
> +	 * 'base_id').
> +	 * - After that, every 'q' IPVs share one buffer pool, with pool
> +	 * indices increasing sequentially.
> +	 */
> +	for (int i = 0; i < priv->info->num_ports; i++) {
> +		u32 base_id = i * bp_per_port;
> +		u32 bp_id = base_id;
> +		u64 mapping = 0;
> +
> +		for (int ipv = 0; ipv < NETC_IPV_NUM; ipv++) {
> +			/* Update the buffer pool index */
> +			if (ipv >= num)
> +				bp_id = base_id + ((ipv - num) / q) + 1;
> +
> +			mapping |= (u64)bp_id << (ipv * 8);

Sashiko says:

If hardware ever provides more than 8 buffer pools per port (for example,
bp_per_port = 10), will this logic fail to utilize the extra pools?

With bp_per_port > 8, q evaluates to 0, r evaluates to 8, and num becomes 8.
The condition if (ipv >= num) then evaluates to if (ipv >= 8), which
is never met since the loop terminates at ipv < 8.

This would leave bp_id at base_id for all priorities, mapping them all to a
single buffer pool and leaving the rest unused. Should bp_per_port be capped
to NETC_IPV_NUM before calculating q to prevent this silent fallback?

From hardware perspective, each port has 8 IPVs, each IPV can only be
mapped to one buffer pool, it is impossible that the hardware provides
more than 8 buffer pools per port. So this is a false positive.


^ permalink raw reply

* Re: [PATCH net-next v2 1/6] net: add netmem_tx modes that indicate dma capability
From: Jakub Kicinski @ 2026-05-07  2:30 UTC (permalink / raw)
  To: Bobby Eshleman
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, 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, Daniel Borkmann,
	Nikolay Aleksandrov, Shuah Khan, netdev, linux-doc, linux-kernel,
	linux-rdma, bpf, linux-kselftest, Stanislav Fomichev,
	Mina Almasry, Bobby Eshleman
In-Reply-To: <20260504-tcp-dm-netkit-v2-1-56d52ac72fd4@meta.com>

On Mon, 04 May 2026 17:27:48 -0700 Bobby Eshleman wrote:
> --- a/drivers/net/netkit.c
> +++ b/drivers/net/netkit.c
> @@ -466,6 +466,7 @@ static void netkit_setup(struct net_device *dev)
>  	dev->priv_flags |= IFF_NO_QUEUE;
>  	dev->priv_flags |= IFF_DISABLE_NETPOLL;
>  	dev->lltx = true;
> +	dev->netmem_tx = NETMEM_TX_NO_DMA;
>  
>  	dev->netdev_ops     = &netkit_netdev_ops;
>  	dev->ethtool_ops    = &netkit_ethtool_ops;
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 0e1e581efc5a..11d68e75eb4f 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1788,6 +1788,12 @@ enum netdev_stat_type {
>  	NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */
>  };
>  
> +enum netmem_tx_mode {
> +	NETMEM_TX_NONE,		/* no netmem TX support */
> +	NETMEM_TX_DMA,		/* DMA-capable netmem TX (real HW) */
> +	NETMEM_TX_NO_DMA,	/* no DMA, e.g. passthrough for virtual devs */

Now there's a little too much here, let's move the NO_DMA changes to
another patch. Just convert the netmem_tx to an enum and change the
existing drivers in patch 1.

Next patch has:

> @@ -1164,16 +1197,30 @@ int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info)
>  		goto err_unlock_netdev;
>  	}
>  
> -	if (!netdev->netmem_tx) {
> +	if (netdev->netmem_tx == NETMEM_TX_NONE) {
>  		err = -EOPNOTSUPP;
>  		NL_SET_ERR_MSG(info->extack,
>  			       "Driver does not support netmem TX");
>  		goto err_unlock_netdev;
>  	}

which also should have been in patch 1.

^ permalink raw reply

* Re: [PATCH net-next v2 2/6] net: devmem: support TX over NETMEM_TX_NO_DMA devices
From: Jakub Kicinski @ 2026-05-07  2:34 UTC (permalink / raw)
  To: Bobby Eshleman
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, 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, Daniel Borkmann,
	Nikolay Aleksandrov, Shuah Khan, netdev, linux-doc, linux-kernel,
	linux-rdma, bpf, linux-kselftest, Stanislav Fomichev,
	Mina Almasry, Bobby Eshleman
In-Reply-To: <20260504-tcp-dm-netkit-v2-2-56d52ac72fd4@meta.com>

On Mon, 04 May 2026 17:27:49 -0700 Bobby Eshleman wrote:
> +	if (bind_dev != netdev)
> +		netdev_lock(bind_dev);
> +	dma_dev = netdev_queue_get_dma_dev(bind_dev, 0, NETDEV_QUEUE_TYPE_TX);
> +	if (bind_dev != netdev)
> +		netdev_unlock(bind_dev);
> +	binding = net_devmem_bind_dmabuf(bind_dev,
> +					 bind_dev != netdev ? netdev : NULL,
> +					 dma_dev, DMA_TO_DEVICE, dmabuf_fd,
> +					 priv, info->extack);

Not sure if it matters but are we intentionally releasing the bind_dev
lock before calling net_devmem_bind_dmabuf() ? Previously more code here
was covered by the physical netdev's lock.

^ permalink raw reply

* Re: [PATCH 1/3] [net-next] w5100: remove MMIO support
From: patchwork-bot+netdevbpf @ 2026-05-07  2:40 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: netdev, robh, linusw, brgl, arnd
In-Reply-To: <20260505180459.1247690-1-arnd@kernel.org>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue,  5 May 2026 20:04:57 +0200 you wrote:
> From: Arnd Bergmann <arnd@arndb.de>
> 
> This driver supports both SPI and MMIO based register access, but only
> the former has devicetree support. While MMIO mode would have worked
> with old-style board files, those have never defined such a device
> upstream.
> 
> [...]

Here is the summary with links:
  - [1/3,net-next] w5100: remove MMIO support
    https://git.kernel.org/netdev/net-next/c/5e138e0ec32b
  - [2/3,net-next] : w5300: remove unused driver
    https://git.kernel.org/netdev/net-next/c/68edebbd0e7d
  - [3/3,net-next,v5] w5100: remove unused gpio link detection
    https://git.kernel.org/netdev/net-next/c/dacf281771a9

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* RE: [PATCH v5 net-next 14/15] net: dsa: netc: add support for the standardized counters
From: Wei Fang @ 2026-05-07  2:41 UTC (permalink / raw)
  To: Claudiu Manoil, Vladimir Oltean, Clark Wang,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org, f.fainelli@gmail.com,
	Frank Li, chleroy@kernel.org, horms@kernel.org,
	linux@armlinux.org.uk
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org, imx@lists.linux.dev
In-Reply-To: <20260430024945.3413973-15-wei.fang@nxp.com>

> diff --git a/include/linux/fsl/netc_global.h b/include/linux/fsl/netc_global.h
> index fdecca8c90f0..5b8ff528d369 100644
> --- a/include/linux/fsl/netc_global.h
> +++ b/include/linux/fsl/netc_global.h
> @@ -5,6 +5,7 @@
>  #define __NETC_GLOBAL_H
> 
>  #include <linux/io.h>
> +#include <linux/io-64-nonatomic-lo-hi.h>
> 
>  static inline u32 netc_read(void __iomem *reg)
>  {
> @@ -16,4 +17,9 @@ static inline void netc_write(void __iomem *reg, u32 val)
>  	iowrite32(val, reg);
>  }
> 
> +static inline u64 netc_read64(void __iomem *reg)
> +{
> +	return ioread64(reg);
> +}
> +

Sashiko says:

Will this cause a build failure on 32-bit architectures? I noticed
ioread64() is used here, but it is strictly gated behind #ifdef CONFIG_64BIT
in include/asm-generic/io.h. Even though linux/io-64-nonatomic-lo-hi.h is
included above, ioread64() isn't provided by that header.

If this is updated to use readq() to fix the 32-bit build, could it lead to
torn reads? On 32-bit systems, readq() falls back to lo_hi_readq(), which
reads the lower 32 bits and then the upper 32 bits sequentially. 

Since these are live, continuously incrementing hardware counters, a wrap of
the lower 32 bits between reads could result in a spurious counter spike of
~4.29 billion. Would it be safer to use a read-high, read-low, read-high
retry loop to ensure atomicity on 32-bit architectures?

First, if CONFIG_64BIT is not selected, then ioread64() is provided by
linux/io-64-nonatomic-lo-hi.h. Sashiko mistakenly believed that
linux/io-64-nonatomic-lo-hi.h did not provide ioread64().

i.MX9x and S32N7 and subsequent SoCs are all arm64 architectures,
netc_read64() is used to read 64-bit registers of NETC.

So this is a false positive.


^ permalink raw reply

* Re: [net-next PATCH v2 7/8] net: dsa: realtek: rtl8365mb: add FDB support
From: Luiz Angelo Daros de Luca @ 2026-05-07  2:50 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, Linus Walleij, Alvin Šipraga,
	Yury Norov, Rasmus Villemoes, Russell King, netdev, linux-kernel
In-Reply-To: <20260505182712.2aa4fb3c@kernel.org>

> Warning: ../drivers/net/dsa/realtek/rtl8365mb_l2.c:243 function parameter 'entry' not described in 'rtl8365mb_l2_get_next_uc'
> Warning: ../drivers/net/dsa/realtek/rtl8365mb_l2.c:243 function parameter 'entry' not described in 'rtl8365mb_l2_get_next_uc'

Thanks Jakub, sorry for that. I missed the kernel-doc check before submitting.

Regards,

Luiz

^ permalink raw reply

* Re: [net-next PATCH v2 4/8] net: dsa: realtek: rtl8365mb: add table lookup interface
From: Luiz Angelo Daros de Luca @ 2026-05-07  2:51 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, Linus Walleij, Alvin Šipraga,
	Yury Norov, Rasmus Villemoes, Russell King, netdev, linux-kernel
In-Reply-To: <20260505182638.6b543f5b@kernel.org>

> Defensive checks are discouraged in the kernel. AI will make short work
> of finding such trivial violations.

Sure. I removed this and other cases. I hope it is fine now. I'll soon
send v3 with the fixes.

Regards,

Luiz

^ permalink raw reply

* [net-next PATCH v3 0/8] net: dsa: realtek: rtl8365mb: bridge offloading and VLAN support
From: Luiz Angelo Daros de Luca @ 2026-05-07  2:58 UTC (permalink / raw)
  To: Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Linus Walleij,
	Alvin Šipraga, Yury Norov, Rasmus Villemoes, Russell King
  Cc: netdev, linux-kernel, Luiz Angelo Daros de Luca,
	Abdulkader Alrezej, Yury Norov

This series introduces bridge offloading, FDB management, and VLAN support
for the Realtek rtl8365mb DSA switch driver. The primary goal is to
enable hardware frame forwarding between bridge ports, reducing CPU
overhead and providing advanced features like VLAN and FDB isolation.

Some of these patches are based on original work by Alvin Šipraga,
subsequently adapted and updated for the current net-next state.

---
I attempted to reach Alvin for review of the final version but was
unable to establish contact. Any regressions in this version are my
responsibility.

Changes in v3:
- Fixed kernel-doc warnings
- Removed unnecessary defensive checks
- Link to v2: https://patch.msgid.link/20260503-realtek_forward-v2-0-d064e220b391@gmail.com

Changes in v2:
- added patch to use ERR_PTR()
- dropped bitfield patch. Use FIELD_PREP instead. Suggested by Yury
  Norov
- tag_rtl8_4 patches were submitted on its own series (already accepted)
- dropped rtl8365mb_vlan_mc_port_{add,del}(). rtl8365mb_vlan_mc_port_set
  is now called directly from PVID methods.
- reordered methods in rtl8365mb_vlan.c
- use dsa_switch_for_each_user_port() instead of simple for in bridge
  port join/leave
- PVID check now uses dsa_switch_for_each_available_port instead of
  dsa_switch_for_each_port
- set EFID of user ports to 0 at setup(), although it is the expected
  state after reset
- STP patch was dropped and replaced by a more extensive one that
  disables all ports (including unused ones) before setting CPU and user
  ports. It also extended the CPU port isolation to include all user
  ports.
- refactored bridge, FDB, and MDB port operations into the common
  rtl83xx module, introducing new realtek_ops callbacks to abstract the
  hardware access
- Collected Reviewed-by and Suggested-by tags
- Link to v1:
  https://patch.msgid.link/20260331-realtek_forward-v1-0-44fb63033b7e@gmail.com

To: Linus Walleij <linusw@kernel.org>
To: Alvin Šipraga <alsi@bang-olufsen.dk>
To: Andrew Lunn <andrew@lunn.ch>
To: Vladimir Oltean <olteanv@gmail.com>
To: "David S. Miller" <davem@davemloft.net>
To: Eric Dumazet <edumazet@google.com>
To: Jakub Kicinski <kuba@kernel.org>
To: Paolo Abeni <pabeni@redhat.com>
To: Russell King <linux@armlinux.org.uk>
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---
Alvin Šipraga (6):
      net: dsa: realtek: rtl8365mb: prepare for multiple source files
      net: dsa: realtek: rtl8365mb: add table lookup interface
      net: dsa: realtek: rtl8365mb: add VLAN support
      net: dsa: realtek: rtl8365mb: add port_bridge_{join,leave}
      net: dsa: realtek: rtl8365mb: add FDB support
      net: dsa: realtek: rtl8365mb: add bridge port flags

Luiz Angelo Daros de Luca (2):
      net: dsa: realtek: rtl8365mb: use ERR_PTR
      net: dsa: realtek: rtl8365mb: use dsa helpers for port iteration

 drivers/net/dsa/realtek/Makefile                   |   4 +
 drivers/net/dsa/realtek/realtek.h                  |  42 ++
 drivers/net/dsa/realtek/rtl8365mb_l2.c             | 493 +++++++++++++
 drivers/net/dsa/realtek/rtl8365mb_l2.h             |  32 +
 .../dsa/realtek/{rtl8365mb.c => rtl8365mb_main.c}  | 548 ++++++++++++--
 drivers/net/dsa/realtek/rtl8365mb_table.c          | 214 ++++++
 drivers/net/dsa/realtek/rtl8365mb_table.h          | 131 ++++
 drivers/net/dsa/realtek/rtl8365mb_vlan.c           | 797 +++++++++++++++++++++
 drivers/net/dsa/realtek/rtl8365mb_vlan.h           |  25 +
 drivers/net/dsa/realtek/rtl83xx.c                  | 482 +++++++++++++
 drivers/net/dsa/realtek/rtl83xx.h                  |  27 +
 11 files changed, 2727 insertions(+), 68 deletions(-)
---
base-commit: edf4bee4215a173c0534d1851d7523d827149f9e
change-id: 20260323-realtek_forward-1bac3a77c664

Best regards,
--  
Luiz Angelo Daros de Luca <luizluca@gmail.com>


^ permalink raw reply

* [net-next PATCH v3 1/8] net: dsa: realtek: rtl8365mb: use ERR_PTR
From: Luiz Angelo Daros de Luca @ 2026-05-07  2:58 UTC (permalink / raw)
  To: Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Linus Walleij,
	Alvin Šipraga, Yury Norov, Rasmus Villemoes, Russell King
  Cc: netdev, linux-kernel, Luiz Angelo Daros de Luca
In-Reply-To: <20260506-realtek_forward-v3-0-1d87c5f85a3b@gmail.com>

Convert numeric error codes into human-readable strings by
using %pe together with ERR_PTR() in dev_err() messages.

Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/net/dsa/realtek/rtl8365mb.c | 40 ++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index c35cef01ec26..edbc16345d0d 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -789,8 +789,8 @@ static int rtl8365mb_phy_read(struct realtek_priv *priv, int phy, int regnum)
 	ret = rtl8365mb_phy_ocp_read(priv, phy, ocp_addr, &val);
 	if (ret) {
 		dev_err(priv->dev,
-			"failed to read PHY%d reg %02x @ %04x, ret %d\n", phy,
-			regnum, ocp_addr, ret);
+			"failed to read PHY%d reg %02x @ %04x, ret %pe\n", phy,
+			regnum, ocp_addr, ERR_PTR(ret));
 		return ret;
 	}
 
@@ -817,8 +817,8 @@ static int rtl8365mb_phy_write(struct realtek_priv *priv, int phy, int regnum,
 	ret = rtl8365mb_phy_ocp_write(priv, phy, ocp_addr, val);
 	if (ret) {
 		dev_err(priv->dev,
-			"failed to write PHY%d reg %02x @ %04x, ret %d\n", phy,
-			regnum, ocp_addr, ret);
+			"failed to write PHY%d reg %02x @ %04x, ret %pe\n", phy,
+			regnum, ocp_addr, ERR_PTR(ret));
 		return ret;
 	}
 
@@ -1068,8 +1068,8 @@ static void rtl8365mb_phylink_mac_config(struct phylink_config *config,
 		ret = rtl8365mb_ext_config_rgmii(priv, port, state->interface);
 		if (ret)
 			dev_err(priv->dev,
-				"failed to configure RGMII mode on port %d: %d\n",
-				port, ret);
+				"failed to configure RGMII mode on port %d: %pe\n",
+				port, ERR_PTR(ret));
 		return;
 	}
 
@@ -1098,8 +1098,8 @@ static void rtl8365mb_phylink_mac_link_down(struct phylink_config *config,
 						     false, false);
 		if (ret)
 			dev_err(priv->dev,
-				"failed to reset forced mode on port %d: %d\n",
-				port, ret);
+				"failed to reset forced mode on port %d: %pe\n",
+				port, ERR_PTR(ret));
 
 		return;
 	}
@@ -1129,8 +1129,8 @@ static void rtl8365mb_phylink_mac_link_up(struct phylink_config *config,
 						     rx_pause);
 		if (ret)
 			dev_err(priv->dev,
-				"failed to force mode on port %d: %d\n", port,
-				ret);
+				"failed to force mode on port %d: %pe\n", port,
+				ERR_PTR(ret));
 
 		return;
 	}
@@ -1285,8 +1285,8 @@ static void rtl8365mb_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *da
 						 mib->length, &data[i]);
 		if (ret) {
 			dev_err(priv->dev,
-				"failed to read port %d counters: %d\n", port,
-				ret);
+				"failed to read port %d counters: %pe\n", port,
+				ERR_PTR(ret));
 			break;
 		}
 	}
@@ -1638,7 +1638,8 @@ static irqreturn_t rtl8365mb_irq(int irq, void *data)
 	return IRQ_HANDLED;
 
 out_error:
-	dev_err(priv->dev, "failed to read interrupt status: %d\n", ret);
+	dev_err(priv->dev, "failed to read interrupt status: %pe\n",
+		ERR_PTR(ret));
 
 out_none:
 	return IRQ_NONE;
@@ -1776,7 +1777,8 @@ static int rtl8365mb_irq_setup(struct realtek_priv *priv)
 	ret = request_threaded_irq(irq, NULL, rtl8365mb_irq, IRQF_ONESHOT,
 				   "rtl8365mb", priv);
 	if (ret) {
-		dev_err(priv->dev, "failed to request irq: %d\n", ret);
+		dev_err(priv->dev, "failed to request irq: %pe\n",
+			ERR_PTR(ret));
 		goto out_remove_irqdomain;
 	}
 
@@ -1952,14 +1954,16 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
 
 	ret = rtl8365mb_reset_chip(priv);
 	if (ret) {
-		dev_err(priv->dev, "failed to reset chip: %d\n", ret);
+		dev_err(priv->dev, "failed to reset chip: %pe\n",
+			ERR_PTR(ret));
 		goto out_error;
 	}
 
 	/* Configure switch to vendor-defined initial state */
 	ret = rtl8365mb_switch_init(priv);
 	if (ret) {
-		dev_err(priv->dev, "failed to initialize switch: %d\n", ret);
+		dev_err(priv->dev, "failed to initialize switch: %pe\n",
+			ERR_PTR(ret));
 		goto out_error;
 	}
 
@@ -2077,8 +2081,8 @@ static int rtl8365mb_detect(struct realtek_priv *priv)
 
 	ret = rtl8365mb_get_chip_id_and_ver(priv->map, &chip_id, &chip_ver);
 	if (ret) {
-		dev_err(priv->dev, "failed to read chip id and version: %d\n",
-			ret);
+		dev_err(priv->dev, "failed to read chip id and version: %pe\n",
+			ERR_PTR(ret));
 		return ret;
 	}
 

-- 
2.54.0


^ permalink raw reply related

* [net-next PATCH v3 2/8] net: dsa: realtek: rtl8365mb: use dsa helpers for port iteration
From: Luiz Angelo Daros de Luca @ 2026-05-07  2:58 UTC (permalink / raw)
  To: Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Linus Walleij,
	Alvin Šipraga, Yury Norov, Rasmus Villemoes, Russell King
  Cc: netdev, linux-kernel, Abdulkader Alrezej,
	Luiz Angelo Daros de Luca
In-Reply-To: <20260506-realtek_forward-v3-0-1d87c5f85a3b@gmail.com>

Use dsa_switch_for_each_*() whenever possible.

For port setup(), a new blocking setup phase was added for all ports,
including unused ones, before the user and CPU port setup.

CPU isolation now includes all user ports as traffic was being blocked in
some scenarios (suggested by Abdulkader Alrezej).

Suggested-by: Abdulkader Alrezej <abdulkader.alrezej@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/net/dsa/realtek/rtl8365mb.c | 115 +++++++++++++++++++++---------------
 1 file changed, 66 insertions(+), 49 deletions(-)

diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index edbc16345d0d..7ddb82fcd026 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -1540,18 +1540,15 @@ static void rtl8365mb_stats_setup(struct realtek_priv *priv)
 {
 	struct rtl8365mb *mb = priv->chip_data;
 	struct dsa_switch *ds = &priv->ds;
-	int i;
+	struct dsa_port *dp;
 
 	/* Per-chip global mutex to protect MIB counter access, since doing
 	 * so requires accessing a series of registers in a particular order.
 	 */
 	mutex_init(&mb->mib_lock);
 
-	for (i = 0; i < priv->num_ports; i++) {
-		struct rtl8365mb_port *p = &mb->ports[i];
-
-		if (dsa_is_unused_port(ds, i))
-			continue;
+	dsa_switch_for_each_available_port(dp, ds) {
+		struct rtl8365mb_port *p = &mb->ports[dp->index];
 
 		/* Per-port spinlock to protect the stats64 data */
 		spin_lock_init(&p->stats_lock);
@@ -1567,13 +1564,10 @@ static void rtl8365mb_stats_teardown(struct realtek_priv *priv)
 {
 	struct rtl8365mb *mb = priv->chip_data;
 	struct dsa_switch *ds = &priv->ds;
-	int i;
-
-	for (i = 0; i < priv->num_ports; i++) {
-		struct rtl8365mb_port *p = &mb->ports[i];
+	struct dsa_port *dp;
 
-		if (dsa_is_unused_port(ds, i))
-			continue;
+	dsa_switch_for_each_available_port(dp, ds) {
+		struct rtl8365mb_port *p = &mb->ports[dp->index];
 
 		cancel_delayed_work_sync(&p->mib_work);
 	}
@@ -1632,6 +1626,9 @@ static irqreturn_t rtl8365mb_irq(int irq, void *data)
 	for_each_set_bit(line, &line_changes, priv->num_ports) {
 		int child_irq = irq_find_mapping(priv->irqdomain, line);
 
+		if (!child_irq)
+			continue;
+
 		handle_nested_irq(child_irq);
 	}
 
@@ -1695,13 +1692,14 @@ static int rtl8365mb_irq_disable(struct realtek_priv *priv)
 static int rtl8365mb_irq_setup(struct realtek_priv *priv)
 {
 	struct rtl8365mb *mb = priv->chip_data;
+	struct dsa_switch *ds = &priv->ds;
 	struct device_node *intc;
+	struct dsa_port *dp;
 	u32 irq_trig;
 	int virq;
 	int irq;
 	u32 val;
 	int ret;
-	int i;
 
 	intc = of_get_child_by_name(priv->dev->of_node, "interrupt-controller");
 	if (!intc) {
@@ -1727,8 +1725,8 @@ static int rtl8365mb_irq_setup(struct realtek_priv *priv)
 		goto out_put_node;
 	}
 
-	for (i = 0; i < priv->num_ports; i++) {
-		virq = irq_create_mapping(priv->irqdomain, i);
+	dsa_switch_for_each_available_port(dp, ds) {
+		virq = irq_create_mapping(priv->irqdomain, dp->index);
 		if (!virq) {
 			dev_err(priv->dev,
 				"failed to create irq domain mapping\n");
@@ -1798,9 +1796,11 @@ static int rtl8365mb_irq_setup(struct realtek_priv *priv)
 	mb->irq = 0;
 
 out_remove_irqdomain:
-	for (i = 0; i < priv->num_ports; i++) {
-		virq = irq_find_mapping(priv->irqdomain, i);
-		irq_dispose_mapping(virq);
+	dsa_switch_for_each_available_port(dp, ds) {
+		virq = irq_find_mapping(priv->irqdomain, dp->index);
+
+		if (virq)
+			irq_dispose_mapping(virq);
 	}
 
 	irq_domain_remove(priv->irqdomain);
@@ -1815,8 +1815,9 @@ static int rtl8365mb_irq_setup(struct realtek_priv *priv)
 static void rtl8365mb_irq_teardown(struct realtek_priv *priv)
 {
 	struct rtl8365mb *mb = priv->chip_data;
+	struct dsa_switch *ds = &priv->ds;
+	struct dsa_port *dp;
 	int virq;
-	int i;
 
 	if (mb->irq) {
 		free_irq(mb->irq, priv);
@@ -1824,9 +1825,11 @@ static void rtl8365mb_irq_teardown(struct realtek_priv *priv)
 	}
 
 	if (priv->irqdomain) {
-		for (i = 0; i < priv->num_ports; i++) {
-			virq = irq_find_mapping(priv->irqdomain, i);
-			irq_dispose_mapping(virq);
+		dsa_switch_for_each_available_port(dp, ds) {
+			virq = irq_find_mapping(priv->irqdomain, dp->index);
+
+			if (virq)
+				irq_dispose_mapping(virq);
 		}
 
 		irq_domain_remove(priv->irqdomain);
@@ -1943,11 +1946,11 @@ static int rtl8365mb_reset_chip(struct realtek_priv *priv)
 static int rtl8365mb_setup(struct dsa_switch *ds)
 {
 	struct realtek_priv *priv = ds->priv;
+	struct dsa_port *cpu_dp, *dp;
 	struct rtl8365mb_cpu *cpu;
-	struct dsa_port *cpu_dp;
 	struct rtl8365mb *mb;
+	u32 userports_mask;
 	int ret;
-	int i;
 
 	mb = priv->chip_data;
 	cpu = &mb->cpu;
@@ -1974,44 +1977,58 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
 	else if (ret)
 		dev_info(priv->dev, "no interrupt support\n");
 
+	/* Start with all ports blocked, including unused ports */
+	dsa_switch_for_each_port(dp, ds) {
+		struct rtl8365mb_port *p = &mb->ports[dp->index];
+
+		/* Set the initial STP state of all ports to DISABLED, otherwise
+		 * ports will still forward frames to the CPU despite being
+		 * administratively down by default.
+		 */
+		rtl8365mb_port_stp_state_set(ds, dp->index, BR_STATE_DISABLED);
+
+		/* Start with all port completely isolated */
+		ret = rtl8365mb_port_set_isolation(priv, dp->index, 0);
+		if (ret)
+			goto out_teardown_irq;
+
+		/* Disable learning */
+		ret = rtl8365mb_port_set_learning(priv, dp->index, false);
+		if (ret)
+			goto out_teardown_irq;
+
+		/* Set up per-port private data */
+		p->priv = priv;
+		p->index = dp->index;
+	}
+
+	userports_mask = dsa_user_ports(ds);
+
 	/* Configure CPU tagging */
 	dsa_switch_for_each_cpu_port(cpu_dp, ds) {
-		cpu->mask |= BIT(cpu_dp->index);
-
+		/* Use the first CPU port as trap_port */
 		if (cpu->trap_port == RTL8365MB_MAX_NUM_PORTS)
 			cpu->trap_port = cpu_dp->index;
+
+		/* Forward to all user ports */
+		ret = rtl8365mb_port_set_isolation(priv, cpu_dp->index,
+						   userports_mask);
+		if (ret)
+			goto out_teardown_irq;
 	}
+
+	cpu->mask = dsa_cpu_ports(ds);
 	cpu->enable = cpu->mask > 0;
 	ret = rtl8365mb_cpu_config(priv);
 	if (ret)
 		goto out_teardown_irq;
 
-	/* Configure ports */
-	for (i = 0; i < priv->num_ports; i++) {
-		struct rtl8365mb_port *p = &mb->ports[i];
-
-		if (dsa_is_unused_port(ds, i))
-			continue;
-
+	/* Configure user ports */
+	dsa_switch_for_each_user_port(dp, ds) {
 		/* Forward only to the CPU */
-		ret = rtl8365mb_port_set_isolation(priv, i, cpu->mask);
+		ret = rtl8365mb_port_set_isolation(priv, dp->index, cpu->mask);
 		if (ret)
 			goto out_teardown_irq;
-
-		/* Disable learning */
-		ret = rtl8365mb_port_set_learning(priv, i, false);
-		if (ret)
-			goto out_teardown_irq;
-
-		/* Set the initial STP state of all ports to DISABLED, otherwise
-		 * ports will still forward frames to the CPU despite being
-		 * administratively down by default.
-		 */
-		rtl8365mb_port_stp_state_set(ds, i, BR_STATE_DISABLED);
-
-		/* Set up per-port private data */
-		p->priv = priv;
-		p->index = i;
 	}
 
 	ret = rtl8365mb_port_change_mtu(ds, cpu->trap_port, ETH_DATA_LEN);

-- 
2.54.0


^ permalink raw reply related

* [net-next PATCH v3 3/8] net: dsa: realtek: rtl8365mb: prepare for multiple source files
From: Luiz Angelo Daros de Luca @ 2026-05-07  2:58 UTC (permalink / raw)
  To: Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Linus Walleij,
	Alvin Šipraga, Yury Norov, Rasmus Villemoes, Russell King
  Cc: netdev, linux-kernel, Luiz Angelo Daros de Luca
In-Reply-To: <20260506-realtek_forward-v3-0-1d87c5f85a3b@gmail.com>

From: Alvin Šipraga <alsi@bang-olufsen.dk>

Rename rtl8365mb.c to rtl8365mb_main.c in preparation for subsequent
commits which add additional source files to the driver.

The trailing backslash in the Makefile is deliberate. It allows for new
files to be added without clobbering git history.

Co-developed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/net/dsa/realtek/Makefile                          | 1 +
 drivers/net/dsa/realtek/{rtl8365mb.c => rtl8365mb_main.c} | 0
 2 files changed, 1 insertion(+)

diff --git a/drivers/net/dsa/realtek/Makefile b/drivers/net/dsa/realtek/Makefile
index 17367bcba496..3f986e04912f 100644
--- a/drivers/net/dsa/realtek/Makefile
+++ b/drivers/net/dsa/realtek/Makefile
@@ -16,3 +16,4 @@ ifdef CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS
 rtl8366-objs 				+= rtl8366rb-leds.o
 endif
 obj-$(CONFIG_NET_DSA_REALTEK_RTL8365MB) += rtl8365mb.o
+rtl8365mb-objs := rtl8365mb_main.o \
diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb_main.c
similarity index 100%
rename from drivers/net/dsa/realtek/rtl8365mb.c
rename to drivers/net/dsa/realtek/rtl8365mb_main.c

-- 
2.54.0


^ permalink raw reply related

* [net-next PATCH v3 4/8] net: dsa: realtek: rtl8365mb: add table lookup interface
From: Luiz Angelo Daros de Luca @ 2026-05-07  2:58 UTC (permalink / raw)
  To: Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Linus Walleij,
	Alvin Šipraga, Yury Norov, Rasmus Villemoes, Russell King
  Cc: netdev, linux-kernel, Luiz Angelo Daros de Luca
In-Reply-To: <20260506-realtek_forward-v3-0-1d87c5f85a3b@gmail.com>

From: Alvin Šipraga <alsi@bang-olufsen.dk>

Add a generic table lookup interface to centralize access to
the RTL8365MB internal tables.

This interface abstracts the low-level table access logic and
will be used by subsequent commits to implement FDB and VLAN
operations.

Co-developed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/net/dsa/realtek/Makefile          |   1 +
 drivers/net/dsa/realtek/rtl8365mb_table.c | 214 ++++++++++++++++++++++++++++++
 drivers/net/dsa/realtek/rtl8365mb_table.h | 131 ++++++++++++++++++
 3 files changed, 346 insertions(+)

diff --git a/drivers/net/dsa/realtek/Makefile b/drivers/net/dsa/realtek/Makefile
index 3f986e04912f..99654c4c5a3d 100644
--- a/drivers/net/dsa/realtek/Makefile
+++ b/drivers/net/dsa/realtek/Makefile
@@ -17,3 +17,4 @@ rtl8366-objs 				+= rtl8366rb-leds.o
 endif
 obj-$(CONFIG_NET_DSA_REALTEK_RTL8365MB) += rtl8365mb.o
 rtl8365mb-objs := rtl8365mb_main.o \
+		  rtl8365mb_table.o \
diff --git a/drivers/net/dsa/realtek/rtl8365mb_table.c b/drivers/net/dsa/realtek/rtl8365mb_table.c
new file mode 100644
index 000000000000..df312769b0be
--- /dev/null
+++ b/drivers/net/dsa/realtek/rtl8365mb_table.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Look-up table query interface for the rtl8365mb switch family
+ *
+ * Copyright (C) 2022 Alvin Šipraga <alsi@bang-olufsen.dk>
+ */
+
+#include "rtl8365mb_table.h"
+#include <linux/regmap.h>
+
+/* Table access control register */
+#define RTL8365MB_TABLE_CTRL_REG		0x0500
+/* Should be one of rtl8365mb_table enum members */
+#define   RTL8365MB_TABLE_CTRL_TABLE_MASK	GENMASK(2, 0)
+/* Should be one of rtl8365mb_table_op enum members */
+#define   RTL8365MB_TABLE_CTRL_OP_MASK		GENMASK(3, 3)
+/* Should be one of rtl8365mb_table_l2_method enum members */
+#define   RTL8365MB_TABLE_CTRL_METHOD_MASK	GENMASK(7, 4)
+/* NOTE: PORT_MASK is only 4 bit, which suggests that port-based
+ * look-up of the L2 table only works for physical port addresses
+ * 0~4. It could be that the Realtek driver is out-of-date and
+ * actually the mask is something like 0xFF00, but this is
+ * unconfirmed.
+ */
+#define   RTL8365MB_TABLE_CTRL_PORT_MASK	GENMASK(11, 8)
+
+/* Table access address register */
+#define RTL8365MB_TABLE_ACCESS_ADDR_REG		0x0501
+#define   RTL8365MB_TABLE_ADDR_MASK		GENMASK(13, 0)
+
+/* Table status register */
+#define RTL8365MB_TABLE_STATUS_REG			0x0502
+#define   RTL8365MB_TABLE_STATUS_ADDRESS_MASK		GENMASK(10, 0)
+/* set for L3, unset for L2  */
+#define   RTL8365MB_TABLE_STATUS_ADDR_TYPE_MASK		GENMASK(11, 11)
+#define   RTL8365MB_TABLE_STATUS_HIT_STATUS_MASK	GENMASK(12, 12)
+#define   RTL8365MB_TABLE_STATUS_BUSY_FLAG_MASK		GENMASK(13, 13)
+#define   RTL8365MB_TABLE_STATUS_ADDRESS_EXT_MASK	GENMASK(14, 14)
+
+/* Table read/write registers */
+#define RTL8365MB_TABLE_WRITE_BASE			0x0510
+#define RTL8365MB_TABLE_WRITE_REG(_x) \
+		(RTL8365MB_TABLE_WRITE_BASE + (_x))
+#define RTL8365MB_TABLE_READ_BASE			0x0520
+#define RTL8365MB_TABLE_READ_REG(_x) \
+		(RTL8365MB_TABLE_READ_BASE + (_x))
+#define RTL8365MB_TABLE_ENTRY_MAX_SIZE			10
+#define RTL8365MB_TABLE_10TH_DATA_MASK			GENMASK(3, 0)
+#define RTL8365MB_TABLE_WRITE_10TH_REG \
+		RTL8365MB_TABLE_WRITE_REG(RTL8365MB_TABLE_ENTRY_MAX_SIZE - 1)
+
+static int rtl8365mb_table_poll_busy(struct realtek_priv *priv)
+{
+	u32 val;
+
+	return regmap_read_poll_timeout(priv->map_nolock,
+			RTL8365MB_TABLE_STATUS_REG, val,
+			!FIELD_GET(RTL8365MB_TABLE_STATUS_BUSY_FLAG_MASK, val),
+			10, 100);
+}
+
+int rtl8365mb_table_query(struct realtek_priv *priv,
+			  enum rtl8365mb_table table,
+			  enum rtl8365mb_table_op op, u16 *addr,
+			  enum rtl8365mb_table_l2_method method,
+			  u16 port, u16 *data, size_t size)
+{
+	bool addr_as_input = true;
+	bool write_data = false;
+	int ret = 0;
+	u32 cmd;
+	u32 val;
+	u32 hit;
+
+	/* Prepare target table and operation (read or write) */
+	cmd = 0;
+	cmd |= FIELD_PREP(RTL8365MB_TABLE_CTRL_TABLE_MASK, table);
+	cmd |= FIELD_PREP(RTL8365MB_TABLE_CTRL_OP_MASK, op);
+	if (op == RTL8365MB_TABLE_OP_READ && table == RTL8365MB_TABLE_L2) {
+		cmd |= FIELD_PREP(RTL8365MB_TABLE_CTRL_METHOD_MASK, method);
+		switch (method) {
+		case RTL8365MB_TABLE_L2_METHOD_MAC:
+			/*
+			 * Method MAC requires as input the same L2 table format
+			 * you'll get as result. However, it might only use mac
+			 * address and FID/VID fields.
+			 */
+			write_data = true;
+
+			/* METHOD_MAC does not use addr as input, but may return
+			 * the matched index.
+			 */
+			addr_as_input = false;
+
+			break;
+		case RTL8365MB_TABLE_L2_METHOD_ADDR:
+		case RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT:
+		case RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC:
+		case RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_MC:
+			break;
+		case RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC_PORT:
+			cmd |= FIELD_PREP(RTL8365MB_TABLE_CTRL_PORT_MASK, port);
+			break;
+		default:
+			return -EINVAL;
+		}
+	} else if (op == RTL8365MB_TABLE_OP_WRITE) {
+		write_data = true;
+
+		/* Writing to L2 does not use addr as input, as the table index
+		 * is derived from key fields.
+		 */
+		if (table == RTL8365MB_TABLE_L2)
+			addr_as_input = false;
+	}
+
+	/* To prevent concurrent access to the look-up tables, take the regmap
+	 * lock manually and access via the map_nolock regmap.
+	 */
+	mutex_lock(&priv->map_lock);
+
+	/* Write entry data if writing to the table (or L2_METHOD_MAC) */
+	if (write_data) {
+		/* bulk write data up to 9th byte */
+		ret = regmap_bulk_write(priv->map_nolock,
+					RTL8365MB_TABLE_WRITE_BASE,
+					data,
+					min_t(size_t, size,
+					      RTL8365MB_TABLE_ENTRY_MAX_SIZE -
+						      1));
+		if (ret)
+			goto out;
+
+		/* 10th register uses only 4 less significant bits */
+		if (size == RTL8365MB_TABLE_ENTRY_MAX_SIZE) {
+			val = FIELD_PREP(RTL8365MB_TABLE_10TH_DATA_MASK,
+					 data[size - 1]);
+			ret = regmap_update_bits(priv->map_nolock,
+						 RTL8365MB_TABLE_WRITE_10TH_REG,
+						 RTL8365MB_TABLE_10TH_DATA_MASK,
+						 val);
+		}
+
+		if (ret)
+			goto out;
+	}
+
+	/* Write address (if needed) */
+	if (addr_as_input) {
+		ret = regmap_write(priv->map_nolock,
+				   RTL8365MB_TABLE_ACCESS_ADDR_REG,
+				   FIELD_PREP(RTL8365MB_TABLE_ADDR_MASK,
+					      *addr));
+		if (ret)
+			goto out;
+	}
+
+	/* Execute */
+	ret = regmap_write(priv->map_nolock, RTL8365MB_TABLE_CTRL_REG, cmd);
+	if (ret)
+		goto out;
+
+	/* Poll for completion */
+	ret = rtl8365mb_table_poll_busy(priv);
+	if (ret)
+		goto out;
+
+	/* For both reads and writes to the L2 table, check status */
+	if (table == RTL8365MB_TABLE_L2) {
+		ret = regmap_read(priv->map_nolock, RTL8365MB_TABLE_STATUS_REG,
+				  &val);
+		if (ret)
+			goto out;
+
+		/* Did the query find an entry? */
+		hit = FIELD_GET(RTL8365MB_TABLE_STATUS_HIT_STATUS_MASK, val);
+		if (!hit) {
+			ret = -ENOENT;
+			goto out;
+		}
+
+		/* If so, extract the address */
+		*addr = 0;
+		*addr |= FIELD_GET(RTL8365MB_TABLE_STATUS_ADDRESS_MASK, val);
+		*addr |= FIELD_GET(RTL8365MB_TABLE_STATUS_ADDRESS_EXT_MASK, val)
+			 << 11;
+		/* only set if it is a L3 address */
+		*addr |= FIELD_GET(RTL8365MB_TABLE_STATUS_ADDR_TYPE_MASK, val)
+			 << 12;
+	}
+
+	/* Finally, get the table entry if we were reading */
+	if (op == RTL8365MB_TABLE_OP_READ) {
+		ret = regmap_bulk_read(priv->map_nolock,
+				       RTL8365MB_TABLE_READ_BASE,
+				       data, size);
+
+		/* For the biggest table entries, the uppermost table
+		 * entry register has space for only one nibble. Mask
+		 * out the remainder bits. Empirically I saw nothing
+		 * wrong with omitting this mask, but it may prevent
+		 * unwanted behaviour. FYI.
+		 */
+		if (size == RTL8365MB_TABLE_ENTRY_MAX_SIZE) {
+			val = FIELD_GET(RTL8365MB_TABLE_10TH_DATA_MASK,
+					data[size - 1]);
+			data[size - 1] = val;
+		}
+	}
+
+out:
+	mutex_unlock(&priv->map_lock);
+
+	return ret;
+}
diff --git a/drivers/net/dsa/realtek/rtl8365mb_table.h b/drivers/net/dsa/realtek/rtl8365mb_table.h
new file mode 100644
index 000000000000..413af4f9759c
--- /dev/null
+++ b/drivers/net/dsa/realtek/rtl8365mb_table.h
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Look-up table query interface for the rtl8365mb switch family
+ *
+ * Copyright (C) 2022 Alvin Šipraga <alsi@bang-olufsen.dk>
+ */
+
+#ifndef _REALTEK_RTL8365MB_TABLE_H
+#define _REALTEK_RTL8365MB_TABLE_H
+
+#include <linux/if_ether.h>
+#include <linux/types.h>
+
+#include "realtek.h"
+
+/**
+ * enum rtl8365mb_table - available switch tables
+ * @RTL8365MB_TABLE_ACL_RULE: ACL rules
+ * @RTL8365MB_TABLE_ACL_ACTION: ACL actions
+ * @RTL8365MB_TABLE_CVLAN: VLAN4k configurations
+ * @RTL8365MB_TABLE_L2: filtering database (2K hash table)
+ * @RTL8365MB_TABLE_IGMP_GROUP: IGMP group database (readonly)
+ *
+ * NOTE: Don't change the enum values. They must concur with the field
+ * described by @RTL8365MB_TABLE_CTRL_TABLE_MASK.
+ */
+enum rtl8365mb_table {
+	RTL8365MB_TABLE_ACL_RULE = 1,
+	RTL8365MB_TABLE_ACL_ACTION = 2,
+	RTL8365MB_TABLE_CVLAN = 3,
+	RTL8365MB_TABLE_L2 = 4,
+	RTL8365MB_TABLE_IGMP_GROUP = 5,
+};
+
+/**
+ * enum rtl8365mb_table_op - table query operation
+ * @RTL8365MB_TABLE_OP_READ: read an entry from the target table
+ * @RTL8365MB_TABLE_OP_WRITE: write an entry to the target table
+ *
+ * NOTE: Don't change the enum values. They must concur with the field
+ * described by @RTL8365MB_TABLE_CTRL_OP_MASK.
+ */
+enum rtl8365mb_table_op {
+	RTL8365MB_TABLE_OP_READ = 0,
+	RTL8365MB_TABLE_OP_WRITE = 1,
+};
+
+/**
+ * enum rtl8365mb_table_l2_method - look-up method for read queries of L2 table
+ * @RTL8365MB_TABLE_L2_METHOD_MAC: look-up by source MAC address and FID (or
+ *   VID)
+ * @RTL8365MB_TABLE_L2_METHOD_ADDR: look-up by entry address
+ * @RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT: look-up next entry starting from the
+ *   supplied address
+ * @RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC: same as ADDR_NEXT but search only
+ *   unicast addresses
+ * @RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_MC: same as ADDR_NEXT but search only
+ *   multicast addresses
+ * @RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC_PORT: same as ADDR_NEXT_UC but
+ *   search only entries with matching source port
+ *
+ * NOTE: Don't change the enum values. They must concur with the field
+ * described by @RTL8365MB_TABLE_CTRL_METHOD_MASK
+ */
+enum rtl8365mb_table_l2_method {
+	RTL8365MB_TABLE_L2_METHOD_MAC = 0,
+	RTL8365MB_TABLE_L2_METHOD_ADDR = 1,
+	RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT = 2,
+	RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC = 3,
+	RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_MC = 4,
+	/*
+	 * RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_MC_L3 = 5,
+	 * RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_MC_L2L3 = 6,
+	 */
+	RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC_PORT = 7,
+};
+
+/**
+ * rtl8365mb_table_query() - read from or write to a switch table
+ * @priv: driver context
+ * @table: target table, see &enum rtl8365mb_table
+ * @op: read or write operation, see &enum rtl8365mb_table_op
+ * @addr: table address. For indexed tables, this selects the entry to access.
+ *        For L2 read queries, it is ignored as input for MAC-based lookup
+ *        methods and used as input for address-based lookup methods. On
+ *        successful L2 queries, it is updated with the matched entry address.
+ * @method: L2 table lookup method, see &enum rtl8365mb_table_l2_method.
+ *	    Ignored for non-L2 tables.
+ * @port: for L2 read queries using method
+ *        %RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC_PORT, restrict the search
+ *        to entries associated with this source port. Ignored otherwise.
+ * @data: data buffer used to read from or write to the table. For L2 MAC
+ *        lookups, this buffer provides the lookup key and receives the
+ *        matched entry contents on success.
+ * @size: size of @data in 16-bit words
+ *
+ * This function provides unified access to the internal tables of the switch.
+ * All tables except the L2 table are simple indexed tables, where @addr
+ * selects the entry and @op determines whether the access is a read or a
+ * write operation.
+ *
+ * The L2 table is a hash table and supports multiple lookup methods. For
+ * %RTL8365MB_TABLE_L2_METHOD_MAC, an entry is searched based on the MAC
+ * address and FID/VID fields provided in @data, using the same format as
+ * an L2 table entry. Address-based methods either read a specific entry
+ * (%RTL8365MB_TABLE_L2_METHOD_ADDR) or iterate over valid entries starting
+ * from @addr (%RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT and variants). When using
+ * %RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC_PORT, only entries associated with
+ * the specified @port are considered.
+ *
+ * On successful L2 lookups, @addr is updated with the matched table address
+ * and @data contains the corresponding table entry. If no matching entry
+ * is found, -ENOENT is returned.
+ *
+ * The contents of @data are used as input when writing to tables or when
+ * specifying the lookup key for L2 MAC searches, and as output for all
+ * successful read operations. If an error occurs, the contents of @addr
+ * and @data are undefined.
+ *
+ * @size must match the size of the target table entry, expressed in 16-bit
+ * words. This function only validates that it is non-zero and fits in the
+ * available register space.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int rtl8365mb_table_query(struct realtek_priv *priv,
+			  enum rtl8365mb_table table,
+			  enum rtl8365mb_table_op op, u16 *addr,
+			  enum rtl8365mb_table_l2_method method,
+			  u16 port, u16 *data, size_t size);
+
+#endif /* _REALTEK_RTL8365MB_TABLE_H */

-- 
2.54.0


^ permalink raw reply related


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