DAP-1620 A2 - MT7620 DSA test (#24493): external port 5 and RGMII delays

Att: @dormancygrace, @mietekn and anyone else for that matter!

I've now got the DAP-1620 A2 working with MT7620 DSA (#24493), and I'd appreciate some review before I try to turn this into a proper OpenWrt PR.

In short, the main thing needed to get DSA working on the DAP-1620 A2 was support for the external MAC connection on MT7620 switch port 5, which is connected via RGMII to the RTL8211E PHY. This was needed because the existing MT7620 DSA driver from #24493 only handles ports 0–4 plus CPU port 6.

This patch adds:

  • phylink support/configuration for external port 5
  • RGMII/MII/RMII support for port 5
  • CPU forwarding based on the actual DSA user ports
  • 20 ms MIB polling for active external switch port 5
  • conversion of the DAP-1620 DTS/network setup from swconfig to DSA

The part I'd especially like some feedback on is the RGMII delay handling.

1. In the first working solution I tested, the RGMII delays were split between the PHY and MAC:

RTL8211E: RX delay
MT7620: TX delay

That worked, but meant that responsibility for the RGMII delays was split between the PHY and MAC. It also made the configuration less clearly tied to the standardized phy-mode description in Device Tree.

2. I then tested what might be considered a "cleaner" solution, using phy-mode = "rgmii-id" and letting the PHY handle both RGMII delays:

RTL8211E: TX + RX delay
MT7620: TX + RX delay disabled

This also works without any problems, and after a cold boot, the expected configuration was applied automatically:

RTL8211E delay register: 0xbd75
MT7620 GPC1:             0x00ec0004

So the patch lets the PHY provide the requested RGMII delays for the RGMII *ID modes and explicitly disables both delays on the MT7620 MAC side. This should reduce the risk of applying the same delay twice and makes it clearer that the phylink/Device Tree configuration describes the intended RGMII delay semantics between the MAC and PHY, rather than relying on the older MT7620-specific delay handling.

I'd really appreciate some feedback on whether this is the right approach for the MT7620 DSA driver, or if it would be better to preserve more of the old MT7620 legacy delay handling, or handle it in some other way.

Any other comments are welcome too!

Links:

  1. The review branch is pushed here: https://github.com/Boilerplate4u/openwrt/tree/dap1620-dsa-review-v1

  2. This compare view might be easier for forum review since it only shows the two DSA commits: https://github.com/Boilerplate4u/openwrt/compare/416bc133b5f5e74c9ed7ead8b7dfb1c0b8ef8ac...dap1620-dsa-review-v1

  3. PR #24493: https://github.com/openwrt/openwrt/pull/24493
    __

I have flashed the DSA version as the default image based on this patch on my DAP-1620 A2.

Boot log: openwrt-dap1620-a1-dsa-a46721f-squashfs-sysupgrade.bin
Please choose the operation:
   1: Load system code to SDRAM via TFTP.
   2: Load system code then write to Flash via TFTP.
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial.
   9: Load Boot Loader code then write to Flash via TFTP.                                              0

3: System Boot system code via Flash.
## Booting image at bc050000 ...
raspi_read: from:50000 len:40
   Image Name:   MIPS OpenWrt Linux-6.18.44
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    2921012 Bytes =  2.8 MB
   Load Address: 80000000
   Entry Point:  80000000
raspi_read: from:50040 len:2c9234
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
No initrd
## Transferring control to Linux (at address 80000000) ...
## Giving linux memsize in MB, 64

Starting kernel ...

[    0.000000] Linux version 6.18.44 (builder@openwrt-dev) (mipsel-openwrt-linux-musl-gcc (OpenWrt GCC 14.4.0 r36008+1-a46721f04d) 14.4.0, GNU ld (GNU Binutils) 2.46.1) #0 Wed Sep  2 09:56:27 2026
[    0.000000] Board has DDR2
[    0.000000] Analog PMU set to hw control
[    0.000000] Digital PMU set to hw control
[    0.000000] SoC Type: MediaTek MT7620A ver:2 eco:6
[    0.000000] printk: legacy bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 00019650 (MIPS 24KEc)
[    0.000000] MIPS: machine is D-Link DAP-1620 A2
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
[    0.000000] Primary data cache 32kB, 4-way, PIPT, no aliases, linesize 32 bytes
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] OF: reserved mem: Reserved memory: No reserved-memory node in the DT
[    0.000000] Kernel command line: console=ttyS0,57600 rootfstype=squashfs,jffs2
[    0.000000] printk: log buffer data + meta data: 131072 + 409600 = 540672 bytes
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[    0.000000] Writing ErrCtl register=00034400
[    0.000000] Readback ErrCtl register=00034400
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16384
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=1.
[    0.000000] NR_IRQS: 256
[    0.000000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.000000] CPU Clock: 580MHz
[    0.000000] clocksource: systick: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 583261500 ns
[    0.000000] systick: running - mult: 214748, shift: 32
[    0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 6590553264 ns
[    0.000002] sched_clock: 32 bits at 290MHz, resolution 3ns, wraps every 7405115902ns
[    0.015599] Calibrating delay loop... 385.84 BogoMIPS (lpj=1929216)
[    0.087823] pid_max: default: 32768 minimum: 301
[    0.110045] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.124483] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.166690] Memory: 53472K/65536K available (7116K kernel code, 604K rwdata, 1620K rodata, 1212K init, 234K bss, 11532K reserved, 0K cma-reserved)
[    0.200111] posixtimers hash table entries: 512 (order: 0, 2048 bytes, linear)
[    0.214470] futex hash table entries: 256 (4096 bytes on 1 NUMA nodes, total 4 KiB, linear).
[    0.240605] pinctrl core: initialized pinctrl subsystem
[    0.255392] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.271710] /pinctrl: Fixed dependency cycle(s) with /pinctrl/pinctrl0
[    2.107725] PCI host bridge to bus 0000:00
[    2.115822] pci_bus 0000:00: root bus resource [mem 0x20000000-0x2fffffff]
[    2.129422] pci_bus 0000:00: root bus resource [io  0x10160000-0x1016ffff]
[    2.143110] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    2.158921] pci 0000:00:00.0: [1814:0801] type 01 class 0x060400 PCIe Root Port
[    2.173411] pci 0000:00:00.0: BAR 0 [mem 0x00000000-0x7fffffff]
[    2.185158] pci 0000:00:00.0: BAR 1 [mem 0x20200000-0x2020ffff]
[    2.196933] pci 0000:00:00.0: PCI bridge to [bus 01]
[    2.206777] pci 0000:00:00.0:   bridge window [io  0x0000-0x0fff]
[    2.218907] pci 0000:00:00.0:   bridge window [mem 0x20000000-0x200fffff]
[    2.232406] pci 0000:00:00.0:   bridge window [mem 0x20100000-0x201fffff pref]
[    2.246854] pci 0000:00:00.0: supports D1
[    2.254714] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
[    2.268972] pci 0000:01:00.0: [14c3:7662] type 00 class 0x028000 PCIe Endpoint
[    2.283373] pci 0000:01:00.0: BAR 0 [mem 0x00000000-0x000fffff 64bit]
[    2.296076] pci 0000:01:00.0: ROM [mem 0x00000000-0x0000ffff pref]
[    2.308512] pci 0000:01:00.0: PME# supported from D0 D3hot D3cold
[    2.321008] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    2.334114] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01
[    2.347244] pci 0000:00:00.0: BAR 0 [mem size 0x80000000]: can't assign; no space
[    2.362102] pci 0000:00:00.0: BAR 0 [mem size 0x80000000]: failed to assign
[    2.375967] pci 0000:00:00.0: bridge window [mem 0x20000000-0x200fffff]: assigned
[    2.390838] pci 0000:00:00.0: bridge window [mem 0x20100000-0x201fffff pref]: assigned
[    2.406586] pci 0000:00:00.0: BAR 1 [mem 0x20200000-0x2020ffff]: assigned
[    2.420090] pci 0000:00:00.0: bridge window [mem 0x20000000-0x200fffff]: releasing
[    2.435144] pci 0000:00:00.0: bridge window [mem 0x20100000-0x201fffff pref]: releasing
[    2.451060] pci 0000:00:00.0: BAR 1 [mem 0x20200000-0x2020ffff]: releasing
[    2.464735] pci 0000:00:00.0: BAR 0 [mem size 0x80000000]: can't assign; no space
[    2.479618] pci 0000:00:00.0: BAR 0 [mem size 0x80000000]: failed to assign
[    2.493473] pci 0000:00:00.0: bridge window [mem 0x20000000-0x200fffff]: assigned
[    2.508356] pci 0000:00:00.0: bridge window [mem 0x20100000-0x201fffff pref]: assigned
[    2.524104] pci 0000:00:00.0: BAR 1 [mem 0x20200000-0x2020ffff]: assigned
[    2.537610] pci 0000:01:00.0: BAR 0 [mem 0x20000000-0x200fffff 64bit]: assigned
[    2.552170] pci 0000:01:00.0: ROM [mem 0x20100000-0x2010ffff pref]: assigned
[    2.566164] pci 0000:00:00.0: PCI bridge to [bus 01]
[    2.576006] pci 0000:00:00.0:   bridge window [mem 0x20000000-0x200fffff]
[    2.589523] pci 0000:00:00.0:   bridge window [mem 0x20100000-0x201fffff pref]
[    2.606039] clocksource: Switched to clocksource MIPS
[    2.630557] NET: Registered PF_INET protocol family
[    2.640544] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    2.655944] tcp_listen_portaddr_hash hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    2.672723] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[    2.689372] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    2.704529] TCP bind hash table entries: 1024 (order: 1, 8192 bytes, linear)
[    2.718549] TCP: Hash tables configured (established 1024 bind 1024)
[    2.731835] MPTCP token hash table entries: 512 (order: 1, 6144 bytes, linear)
[    2.746520] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[    2.759483] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[    2.774358] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    2.785710] PCI: CLS 0 bytes, default 32
[    2.793695] rt-timer 10000100.timer: maximum frequency is 1220Hz
[    2.810585] workingset: timestamp_bits=14 max_order=14 bucket_order=0
[    2.825430] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    2.836982] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    2.867840] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[    2.882266] printk: legacy console [ttyS0] disabled
[    2.892738] 10000c00.serial: ttyS0 at MMIO 0x10000c00 (irq = 20, base_baud = 2500000) is a Palmchip BK-3103
[    2.912160] printk: legacy console [ttyS0] enabled
[    2.912160] printk: legacy console [ttyS0] enabled
[    2.931122] printk: legacy bootconsole [early0] disabled
[    2.931122] printk: legacy bootconsole [early0] disabled
[    2.968004] spi spi0.0: force spi mode3
[    2.976215] spi-nor spi0.0: supply vcc not found, using dummy regulator
[    2.990106] 4 fixed-partitions partitions found on MTD device spi0.0
[    3.003257] Creating 4 MTD partitions on "spi0.0":
[    3.012882] 0x000000000000-0x000000030000 : "u-boot"
[    3.026687] 0x000000030000-0x000000040000 : "nvram"
[    3.038474] 0x000000040000-0x000000050000 : "factory"
[    3.051272] 0x000000050000-0x000000800000 : "firmware"
[    3.063868] 2 uimage-fw partitions found on MTD device firmware
[    3.075787] Creating 2 MTD partitions on "firmware":
[    3.085697] 0x000000000000-0x0000002c9274 : "kernel"
[    3.095621] mtd: partition "kernel" doesn't end on an erase/write block -- force read-only
[    3.114266] 0x0000002c9274-0x0000007b0000 : "rootfs"
[    3.124281] mtd: partition "rootfs" doesn't start on an erase/write block boundary -- force read-only
[    3.144563] mtd: setting mtd5 (rootfs) as root device
[    3.154832] 1 squashfs-split partitions found on MTD device rootfs
[    3.167208] 0x0000006f0000-0x0000007b0000 : "rootfs_data"
[    3.204540] gsw: ephy base address: 12
[    3.213441] gsw: setting port4 to ephy mode
[    3.225732] mtk_soc_eth 10100000.ethernet eth0: mediatek frame engine at 0xb0100000, irq 5
[    3.243104] rt2880_wdt 10000120.watchdog: Initialized
[    3.255959] NET: Registered PF_INET6 protocol family
[    3.273556] Segment Routing with IPv6
[    3.281113] In-situ OAM (IOAM) with IPv6
[    3.289216] NET: Registered PF_PACKET protocol family
[    3.299404] 8021q: 802.1Q VLAN Support v1.8
[    3.347711] clk: Disabling unused clocks
[    3.355856] check access for rdinit=/init failed: -2, ignoring
[    3.376363] VFS: Mounted root (squashfs filesystem) readonly on device 31:5.
[    3.397158] Freeing unused kernel image (initmem) memory: 1212K
[    3.408999] This architecture does not have kernel memory protection.
[    3.421865] Run /sbin/init as init process
[    4.647640] init: Console is alive
[    4.654940] init: - watchdog -
[    6.328297] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[    6.455823] gpio_button_hotplug: loading out-of-tree module taints kernel.
[    6.482345] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[    6.507630] init: - preinit -
[   10.606095] random: crng init done
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
[   15.615492] mount_root: jffs2 not ready yet, using temporary tmpfs overlay
[   15.634684] urandom-seed: Seed file not found (/etc/urandom.seed)
- generating board file -
[   16.632458] procd: - early -
[   16.638740] procd: - watchdog -
[   17.364768] procd: - watchdog -
[   17.373347] procd: - ubus -
[   17.522164] procd: - init -
Please press Enter to activate this console.
[   21.051910] kmodloader: loading kernel modules from /etc/modules.d/*
[   22.975970] urngd: v1.0.2 started.
[   23.102160] i2c_dev: i2c /dev entries driver
[   23.174183] Loading modules backported from Linux version v7.2-0-g8d3ae59288f1
[   23.188699] Backport generated by backports.git v5.15.58-1-198-g2580fa90cb79
[   23.504403] mt7620-dsa mt7620-dsa.0.auto: configuring for fixed/rgmii link mode
[   23.519877] mt7620-dsa mt7620-dsa.0.auto lan (uninitialized): PHY [mdio-bus:01] driver [RTL8211E Gigabit Ethernet] (irq=POLL)
[   23.544122] mtk_soc_eth 10100000.ethernet eth0: entered promiscuous mode
[   23.557732] DSA: tree 0 setup
[   23.563972] mt7620-dsa mt7620-dsa.0.auto: Link is Up - 1Gbps/Full - flow control rx/tx
[   24.711826] mt76x2e 0000:01:00.0: card - bus=0x1, slot = 0x0 irq=4
[   24.756308] mt76x2e 0000:01:00.0: ASIC revision: 76120044
[   25.447305] mt76x2e 0000:01:00.0: ROM patch build: 20141115060606a
[   25.816361] mt76x2e 0000:01:00.0: Firmware Version: 0.0.00
[   25.827382] mt76x2e 0000:01:00.0: Build: 1
[   25.835544] mt76x2e 0000:01:00.0: Build Time: 201607111443____
[   25.916059] mt76x2e 0000:01:00.0: Firmware running!
[   25.926096] mt76x2e 0000:01:00.0: registering led 'mt76-phy0'
[   26.340540] PPP generic driver version 2.4.2
[   26.377525] NET: Registered PF_PPPOX protocol family
[   26.532716] ieee80211 phy1: rt2x00_set_rt: Info - RT chipset 6352, rev 0500 detected
[   26.548728] ieee80211 phy1: rt2x00_set_rf: Info - RF chipset 7620 detected
[   26.606644] kmodloader: done loading kernel modules from /etc/modules.d/*
[   55.885976] 8021q: adding VLAN 0 to HW filter on device eth0
[   55.929339] mt7620-dsa mt7620-dsa.0.auto lan: configuring for phy/rgmii-id link mode
[   55.946086] mt7620-dsa mt7620-dsa.0.auto lan: Link is Up - 1Gbps/Full - flow control rx/tx
[   55.990735] br-lan: port 1(lan) entered blocking state
[   56.001097] br-lan: port 1(lan) entered disabled state
[   56.011445] mt7620-dsa mt7620-dsa.0.auto lan: entered allmulticast mode
[   56.024698] mtk_soc_eth 10100000.ethernet eth0: entered allmulticast mode
[   56.038792] mt7620-dsa mt7620-dsa.0.auto lan: entered promiscuous mode
[   56.182217] br-lan: port 1(lan) entered blocking state
[   56.192577] br-lan: port 1(lan) entered forwarding state
[   63.082776] jffs2_scan_eraseblock(): End of filesystem marker found at 0x0
[   63.156239] jffs2_build_filesystem(): unlocking the mtd device...
[   63.156275] done.
[   63.172496] jffs2_build_filesystem(): erasing all blocks after the end marker...
[   69.001529] done.
[   69.020437] jffs2: notice: (2195) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
[   69.274995] overlayfs: upper fs does not support tmpfile.



BusyBox v1.38.0 (2026-05-13 02:19:59 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt SNAPSHOT, r36012-73ceb51325
 -----------------------------------------------------

 === WARNING! =====================================
 There is no root password defined on this device!
 Use the "passwd" command to set up a new password
 in order to prevent unauthorized SSH logins.
 --------------------------------------------------

root@OpenWrt:~# 

This patch addresses several issues identified in the MT7620 GSW DSA driver:

  1. Eliminate the magic number "5" for the external RGMII1 port by
    introducing MT7620_GSW_EXTERNAL_PORT in the shared header and
    using it consistently across gsw_mt7620.c and gsw_mt7620_dsa.c.

  2. Rename mt7620_gsw_config_external_port() to mt7620_gsw_config_rgmii1()
    and drop the redundant "port" parameter. The function only ever
    handles port 5 (RGMII1); the caller already filters on that port.

  3. Fix RGMII delay settings for RGMII_RXID and RGMII_TXID modes.
    Previously all three *ID variants disabled both MAC-side delays,
    which is wrong when the PHY only provides one of the two delays.

    • RGMII_ID: disable both (unchanged, correct).
    • RGMII_RXID: PHY provides RX delay -> MAC must provide TX delay.
    • RGMII_TXID: PHY provides TX delay -> MAC must provide RX delay.
      NOTE: this assumes TX delay is active-high and RX delay is
      active-low, which matches MT7620 documentation.
  4. Make the fast MIB polling path depend on the actual negotiated
    link speed rather than on the port being enabled. A new field
    mib_gige_ports is set/cleared in mac_link_up() and mac_link_down()
    so that only ports currently running at 1 Gbps are polled every
    20 ms; slower links fall back to the 200 ms full scan.

  5. Reset mib_port_intervals when the last user port is disabled so
    that re-enabling ports restores the full 200 ms cadence.

--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.h
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.h
@@ -103,6 +103,8 @@ enum {
 	GSW_ATTR_PORT_UNTAG,
 };

+#define MT7620_GSW_EXTERNAL_PORT	5
+
 struct mt7620_gsw_vlan {
 	u16 vid;
 	u8 members;
@@ -127,6 +129,7 @@ struct mt7620_gsw {
 	struct mt7620_gsw_vlan	vlans[GSW_NUM_VLANS];
 	struct delayed_work	mib_work;
 	unsigned long		mib_active_ports;
+	unsigned long		mib_gige_ports;
 	u8			mib_port_intervals;
 	/* Protects the software-extended MIB counter state. */
 	spinlock_t		mib_lock;
@@ -138,8 +141,7 @@ struct mt7620_gsw {

 void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg);
 u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg);
-int mt7620_gsw_config_external_port(struct mt7620_gsw *gsw, int port,
-				    phy_interface_t interface);
+int mt7620_gsw_config_rgmii1(struct mt7620_gsw *gsw, phy_interface_t interface);
 int mtk_gsw_init(struct fe_priv *priv);
 #if IS_ENABLED(CONFIG_NET_DSA_MT7620)
 int mt7620_gsw_dsa_device_register(struct mt7620_gsw *gsw,

--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
@@ -35,16 +35,12 @@ u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg)
 }
 EXPORT_SYMBOL_GPL(mtk_switch_r32);

-int mt7620_gsw_config_external_port(struct mt7620_gsw *gsw, int port,
-				    phy_interface_t interface)
+int mt7620_gsw_config_rgmii1(struct mt7620_gsw *gsw, phy_interface_t interface)
 {
 	u32 mode, val;
 	u32 delay_mask = GSW_REG_GPCx_TXDELAY | GSW_REG_GPCx_RXDELAY;
 	u32 delay_val = 0;

-	/* Port 5 is the external MAC exposed through RGMII1 on MT7620. */
-	if (port != 5)
-		return -EINVAL;

 	switch (interface) {
 	case PHY_INTERFACE_MODE_RGMII:
@@ -55,15 +51,26 @@ int mt7620_gsw_config_external_port(struct mt7620_gsw *gsw, int port,
 		delay_mask = 0;
 		break;
 	case PHY_INTERFACE_MODE_RGMII_ID:
-	case PHY_INTERFACE_MODE_RGMII_RXID:
-	case PHY_INTERFACE_MODE_RGMII_TXID:
 		mode = 0;
 		/*
-		 * For RGMII *ID modes the PHY provides the requested internal
-		 * delay. Disable both MT7620 MAC-side delays to avoid doubling
-		 * the delay. The RX delay control is active-low on MT7620.
+		 * PHY provides both delays; disable both MAC-side delays.
+		 * RX delay control is active-low on MT7620.
 		 */
 		delay_val = GSW_REG_GPCx_RXDELAY;
 		break;
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		mode = 0;
+		/*
+		 * PHY provides RX delay; MAC must provide TX delay.
+		 * RX delay is active-low (1 = disabled).
+		 */
+		delay_val = GSW_REG_GPCx_TXDELAY | GSW_REG_GPCx_RXDELAY;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		mode = 0;
+		/*
+		 * PHY provides TX delay; MAC must provide RX delay.
+		 * RX delay is active-low (0 = enabled).
+		 */
+		delay_val = 0;
+		break;
 	case PHY_INTERFACE_MODE_MII:
 		mode = 1;
 		break;
@@ -96,7 +103,7 @@ int mt7620_gsw_config_external_port(struct mt7620_gsw *gsw, int port,

 	return 0;
 }
-EXPORT_SYMBOL_GPL(mt7620_gsw_config_external_port);
+EXPORT_SYMBOL_GPL(mt7620_gsw_config_rgmii1);

 static irqreturn_t gsw_interrupt_mt7620(int irq, void *_priv)
 {

--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620_dsa.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620_dsa.c
@@ -23,7 +23,7 @@

 #define MT7620_DSA_NUM_PORTS		7
 #define MT7620_DSA_CPU_PORT		6
-#define MT7620_DSA_EXTERNAL_PORT		5
+#define MT7620_DSA_EXTERNAL_PORT		MT7620_GSW_EXTERNAL_PORT
 #define MT7620_DSA_INTERNAL_PORTS	GENMASK(4, 0)
 #define MT7620_DSA_ALL_PORTS		GENMASK(6, 0)

@@ -177,7 +177,7 @@ static void mt7620_gsw_mib_work(struct work_struct *work)
 	struct mt7620_gsw *gsw =
 		container_of(to_delayed_work(work), struct mt7620_gsw, mib_work);
 	unsigned long ports = BIT(MT7620_DSA_CPU_PORT) |
-			      (READ_ONCE(gsw->mib_active_ports) &
+			      (READ_ONCE(gsw->mib_gige_ports) &
 			       BIT(MT7620_DSA_EXTERNAL_PORT));

 	if (++gsw->mib_port_intervals == MT7620_MIB_PORT_INTERVALS) {
@@ -575,6 +575,7 @@ static int mt7620_gsw_setup(struct dsa_switch *ds)
 	memset(gsw->mib_stats, 0, sizeof(gsw->mib_stats));
 	gsw->mib_initialized = false;
 	gsw->mib_active_ports = 0;
+	gsw->mib_gige_ports = 0;
 	gsw->mib_port_intervals = 0;
 	mt7620_gsw_mib_update(gsw, MT7620_DSA_ALL_PORTS);

@@ -596,10 +597,12 @@ static int mt7620_gsw_port_enable(struct dsa_switch *ds, int port,
 		mt7620_gsw_set_port_matrix(gsw, port,
 					   BIT(MT7620_DSA_CPU_PORT));
 		start_mib = !READ_ONCE(gsw->mib_active_ports);
 		set_bit(port, &gsw->mib_active_ports);
-		if (start_mib)
+		if (start_mib) {
+			gsw->mib_port_intervals = 0;
 			schedule_delayed_work(&gsw->mib_work,
 					      MT7620_MIB_CPU_INTERVAL);
+		}
 	}

 	return 0;
@@ -611,9 +614,11 @@ static void mt7620_gsw_port_disable(struct dsa_switch *ds, int port)

 	if (dsa_is_user_port(ds, port)) {
 		mt7620_gsw_set_port_matrix(gsw, port, 0);
 		clear_bit(port, &gsw->mib_active_ports);
+		clear_bit(port, &gsw->mib_gige_ports);
 		if (!READ_ONCE(gsw->mib_active_ports)) {
 			cancel_delayed_work_sync(&gsw->mib_work);
 			mt7620_gsw_mib_update(gsw, MT7620_DSA_ALL_PORTS);
+			gsw->mib_port_intervals = 0;
 		}
 	}
 }
@@ -932,6 +937,11 @@ static void mt7620_gsw_mac_link_up(struct phylink_config *config,
 	hw_speed = mt7620_gsw_pmcr_speed(speed);
 	if (hw_speed < 0)
 		return;

+	if (speed == SPEED_1000)
+		set_bit(dp->index, &gsw->mib_gige_ports);
+	else
+		clear_bit(dp->index, &gsw->mib_gige_ports);
+
 	val = PMCR_IPG | PMCR_MAC_MODE | PMCR_FORCE | PMCR_TX_EN |
 	      PMCR_RX_EN | PMCR_BACKOFF | PMCR_BACKPRES | PMCR_LINK |
 	      PMCR_SPEED(hw_speed);
@@ -954,6 +964,8 @@ static void mt7620_gsw_mac_link_down(struct phylink_config *config,
 	if (dsa_is_cpu_port(dp->ds, dp->index))
 		return;

+	clear_bit(dp->index, &gsw->mib_gige_ports);
+
 	mt7620_gsw_rmw(gsw, GSW_REG_PORT_PMCR(dp->index),
 		       PMCR_FORCE | PMCR_LINK, PMCR_FORCE);
 }
@@ -982,7 +994,7 @@ static void mt7620_gsw_mac_config(struct phylink_config *config,
 	if (dp->index != MT7620_DSA_EXTERNAL_PORT)
 		return;

-	ret = mt7620_gsw_config_external_port(gsw, dp->index, state->interface);
+	ret = mt7620_gsw_config_rgmii1(gsw, state->interface);
 	if (ret)
 		dev_err(gsw->dev, "port %d: unsupported PHY interface %d\n",
 			dp->index, state->interface);

Many thanks for the quick review and for taking the time to put together the patch! :folded_hands: :slightly_smiling_face:

All the changes look very sensible to me, but with one exception that I think might be worth discussing: point 3.

For RGMII_ID I completely agree, and that's also the mode used by the DAP-1620. The RTL8211E provides both TX and RX delays and the MT7620 MAC-side delays are disabled, which is the configuration I've tested on the hardware.

I'm a bit less sure about RGMII_RXID and RGMII_TXID though (but I might be missing something here).

The current Linux PHY documentation defines the RGMII modes from the PHY's perspective:

  • RGMII_RXID means that the PHY provides the RX delay
  • RGMII_TXID means that the PHY provides the TX delay
  • RGMII_ID means that the PHY provides both

The current DT binding also treats phy-mode as describing which delays are already provided by the PCB, rather than as an instruction for the MAC to automatically provide the opposite delay.

So I'm not completely sure about having the MT7620 MAC automatically provide the "missing" opposite delay for RXID/TXID. If the MAC itself provides one of the delays, Linux now has phy_fix_phy_mode_for_mac_delays() to adjust the mode passed on to the PHY accordingly.

Electrically the resulting delay combinations make sense, but I think it would be good to clarify which model we want the MT7620 driver to follow before changing the generic behaviour.

This doesn't really affect the DAP-1620 A2 itself, since it uses RGMII_ID and your patch leaves this unchanged.

All the other changes look like very good generic MT7620 DSA improvements.

I'm also wondering if it might make sense to split this into two separate PRs like this:

  1. A generic MT7620 DSA PR adding support for external RGMII1/port 5, including these generic cleanups/improvements.

  2. A separate DAP-1620 A2 PR converting the device to DSA on top of that support.

That would keep the device-specific part quite small while making the external port/RGMII1 support reusable for other MT7620 devices. What do you think?

Thanks for the review. You're absolutely right about the RGMII delay semantics β€” phy-mode describes what the PHY/PCB provides, not an instruction for the MAC to automatically compensate. I've dropped the RXID/TXID delay changes from this patch and left the original behaviour (all *ID modes disable both MAC-side delays) untouched.

The remaining changes are:

  • Remove the magic number 5 by adding MT7620_GSW_EXTERNAL_PORT to the shared header.
  • Rename mt7620_gsw_config_external_port() β†’ mt7620_gsw_config_rgmii1() and drop the redundant port parameter.
  • Introduce mib_gige_ports so the fast MIB poll (20 ms) only covers ports actually running at 1 Gbps, not merely enabled ones.
  • Reset mib_port_intervals on port disable/enable to keep the cadence consistent.
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.h
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.h
@@ -103,6 +103,8 @@ enum {
 	GSW_ATTR_PORT_UNTAG,
 };

+#define MT7620_GSW_EXTERNAL_PORT	5
+
 struct mt7620_gsw_vlan {
 	u16 vid;
 	u8 members;
@@ -127,6 +129,7 @@ struct mt7620_gsw {
 	struct mt7620_gsw_vlan	vlans[GSW_NUM_VLANS];
 	struct delayed_work	mib_work;
 	unsigned long		mib_active_ports;
+	unsigned long		mib_gige_ports;
 	u8			mib_port_intervals;
 	/* Protects the software-extended MIB counter state. */
 	spinlock_t		mib_lock;
@@ -138,8 +141,7 @@ struct mt7620_gsw {

 void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg);
 u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg);
-int mt7620_gsw_config_external_port(struct mt7620_gsw *gsw, int port,
-				    phy_interface_t interface);
+int mt7620_gsw_config_rgmii1(struct mt7620_gsw *gsw, phy_interface_t interface);
 int mtk_gsw_init(struct fe_priv *priv);
 #if IS_ENABLED(CONFIG_NET_DSA_MT7620)
 int mt7620_gsw_dsa_device_register(struct mt7620_gsw *gsw,

--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
@@ -35,16 +35,12 @@ u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg)
 }
 EXPORT_SYMBOL_GPL(mtk_switch_r32);

-int mt7620_gsw_config_external_port(struct mt7620_gsw *gsw, int port,
-				    phy_interface_t interface)
+int mt7620_gsw_config_rgmii1(struct mt7620_gsw *gsw, phy_interface_t interface)
 {
 	u32 mode, val;
 	u32 delay_mask = GSW_REG_GPCx_TXDELAY | GSW_REG_GPCx_RXDELAY;
 	u32 delay_val = 0;

-	/* Port 5 is the external MAC exposed through RGMII1 on MT7620. */
-	if (port != 5)
-		return -EINVAL;

 	switch (interface) {
 	case PHY_INTERFACE_MODE_RGMII:
@@ -96,7 +92,7 @@ int mt7620_gsw_config_external_port(struct mt7620_gsw *gsw, int port,

 	return 0;
 }
-EXPORT_SYMBOL_GPL(mt7620_gsw_config_external_port);
+EXPORT_SYMBOL_GPL(mt7620_gsw_config_rgmii1);

 static irqreturn_t gsw_interrupt_mt7620(int irq, void *_priv)
 {

--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620_dsa.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620_dsa.c
@@ -23,7 +23,7 @@

 #define MT7620_DSA_NUM_PORTS		7
 #define MT7620_DSA_CPU_PORT		6
-#define MT7620_DSA_EXTERNAL_PORT		5
+#define MT7620_DSA_EXTERNAL_PORT		MT7620_GSW_EXTERNAL_PORT
 #define MT7620_DSA_INTERNAL_PORTS	GENMASK(4, 0)
 #define MT7620_DSA_ALL_PORTS		GENMASK(6, 0)

@@ -177,7 +177,7 @@ static void mt7620_gsw_mib_work(struct work_struct *work)
 	struct mt7620_gsw *gsw =
 		container_of(to_delayed_work(work), struct mt7620_gsw, mib_work);
 	unsigned long ports = BIT(MT7620_DSA_CPU_PORT) |
-			      (READ_ONCE(gsw->mib_active_ports) &
+			      (READ_ONCE(gsw->mib_gige_ports) &
 			       BIT(MT7620_DSA_EXTERNAL_PORT));

 	if (++gsw->mib_port_intervals == MT7620_MIB_PORT_INTERVALS) {
@@ -575,6 +575,7 @@ static int mt7620_gsw_setup(struct dsa_switch *ds)
 	memset(gsw->mib_stats, 0, sizeof(gsw->mib_stats));
 	gsw->mib_initialized = false;
 	gsw->mib_active_ports = 0;
+	gsw->mib_gige_ports = 0;
 	gsw->mib_port_intervals = 0;
 	mt7620_gsw_mib_update(gsw, MT7620_DSA_ALL_PORTS);

@@ -596,10 +597,12 @@ static int mt7620_gsw_port_enable(struct dsa_switch *ds, int port,
 		mt7620_gsw_set_port_matrix(gsw, port,
 					   BIT(MT7620_DSA_CPU_PORT));
 		start_mib = !READ_ONCE(gsw->mib_active_ports);
 		set_bit(port, &gsw->mib_active_ports);
-		if (start_mib)
+		if (start_mib) {
+			gsw->mib_port_intervals = 0;
 			schedule_delayed_work(&gsw->mib_work,
 					      MT7620_MIB_CPU_INTERVAL);
+		}
 	}

 	return 0;
@@ -611,9 +614,11 @@ static void mt7620_gsw_port_disable(struct dsa_switch *ds, int port)

 	if (dsa_is_user_port(ds, port)) {
 		mt7620_gsw_set_port_matrix(gsw, port, 0);
 		clear_bit(port, &gsw->mib_active_ports);
+		clear_bit(port, &gsw->mib_gige_ports);
 		if (!READ_ONCE(gsw->mib_active_ports)) {
 			cancel_delayed_work_sync(&gsw->mib_work);
 			mt7620_gsw_mib_update(gsw, MT7620_DSA_ALL_PORTS);
+			gsw->mib_port_intervals = 0;
 		}
 	}
 }
@@ -932,6 +937,11 @@ static void mt7620_gsw_mac_link_up(struct phylink_config *config,
 	hw_speed = mt7620_gsw_pmcr_speed(speed);
 	if (hw_speed < 0)
 		return;

+	if (speed == SPEED_1000)
+		set_bit(dp->index, &gsw->mib_gige_ports);
+	else
+		clear_bit(dp->index, &gsw->mib_gige_ports);
+
 	val = PMCR_IPG | PMCR_MAC_MODE | PMCR_FORCE | PMCR_TX_EN |
 	      PMCR_RX_EN | PMCR_BACKOFF | PMCR_BACKPRES | PMCR_LINK |
 	      PMCR_SPEED(hw_speed);
@@ -954,6 +964,8 @@ static void mt7620_gsw_mac_link_down(struct phylink_config *config,
 	if (dsa_is_cpu_port(dp->ds, dp->index))
 		return;

+	clear_bit(dp->index, &gsw->mib_gige_ports);
+
 	mt7620_gsw_rmw(gsw, GSW_REG_PORT_PMCR(dp->index),
 		       PMCR_FORCE | PMCR_LINK, PMCR_FORCE);
 }
@@ -982,7 +994,7 @@ static void mt7620_gsw_mac_config(struct phylink_config *config,
 	if (dp->index != MT7620_DSA_EXTERNAL_PORT)
 		return;

-	ret = mt7620_gsw_config_external_port(gsw, dp->index, state->interface);
+	ret = mt7620_gsw_config_rgmii1(gsw, state->interface);
 	if (ret)
 		dev_err(gsw->dev, "port %d: unsupported PHY interface %d\n",
 			dp->index, state->interface);

I don't think splitting is worth the overhead here. The external port support and the DAP-1620 A2 conversion are tightly coupled β€” the device conversion is the only in-tree user of the new RGMII1 code right now, and the total diff is small enough to review in one go. Keeping it together also avoids the chicken-and-egg problem of merging a generic PR with no immediate consumer.

I've now applied the four remaining changes from your patch and tested them on the DAP-1620 A2. Everything looks good here.

I put the changes into a separate fixup commit on top of the existing external port 5 commit, so the history hasn't been rewritten yet. The fixup contains:

  • MT7620_GSW_EXTERNAL_PORT in the shared header
  • mt7620_gsw_config_rgmii1() rename and removal of the redundant port argument
  • mib_gige_ports for the fast 1 Gbps MIB polling path
  • mib_port_intervals reset on disable/enable

I also verified that the RGMII delay handling itself is unchanged.

The updated initramfs was tested on the actual hardware using TFTP. Port 5 comes up at 1 Gbps/full duplex, traffic works normally, and I also tested a link down/up cycle. The link came back up cleanly at 1 Gbps and traffic resumed without issues.

The fixup commit is pushed to the same review branch as before, so you can see the changes there directly.

I also agree with your point about keeping this in one PR. Since the DAP-1620 is currently the only in-tree user of the new RGMII1/port 5 support, keeping the generic support and the device conversion together seems more reasonable.

Just to make it easy, here are the same links again:

  1. The review branch
    https://github.com/Boilerplate4u/openwrt/tree/dap1620-dsa-review-v1

  2. Compare view:
    https://github.com/Boilerplate4u/openwrt/compare/416bc133b5f5e74c9ed7ead8b7dfb1c0b8ef8ac...dap1620-dsa-review-v1

Boot log and some test results
U-Boot 1.1.3 (Mar 21 2016 - 16:55:00)

Board: Ralink APSoC DRAM:  64 MB
relocate_code Pointer at: 83fb0000
enable ephy clock...done. rf reg 29 = 5
SSC disabled.
******************************
Software System Reset Occurred
******************************
spi_wait_nsec: 29
spi device id: c2 20 17 c2 20 (2017c220)
find flash: MX25L6405D
raspi_read: from:30000 len:1000
raspi_read: from:30000 len:1000
============================================
Ralink UBoot Version: 4.1.1.0
--------------------------------------------
ASIC 7620_MP (Port5<->Phy)
DRAM component: 512 Mbits DDR, width 16
DRAM bus: 16 bit
Total memory: 64 MBytes
Flash component: SPI Flash
Date:Mar 21 2016  Time:16:55:00
Cameo Version: v1.00 Build:02
Module Name: D-Link DAP-1620A1
============================================
icache: sets:512, ways:4, linesz:32 ,total:65536
dcache: sets:256, ways:4, linesz:32 ,total:32768

 ##### The CPU freq = 580 MHZ ####
 estimate memory size =64 Mbytes
raspi_read: from:50000 len:40
raspi_read: from:4f0000 len:40

=================================================
Check image validation:
Image1 Header Magic Number --> OK
Image2 Header Magic Number --> Failed
Image1 Header Checksum --> OK
Image1 Data Checksum --> raspi_read: from:50040 len:2c9234
OK

=================================================

Please choose the operation:
   1: Load system code to SDRAM via TFTP.
   2: Load system code then write to Flash via TFTP.
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial.
   9: Load Boot Loader code then write to Flash via TFTP.                                              1
You choosed 4
                                                                                                       0
raspi_read: from:40028 len:6


4: System Enter Boot Command Line Interface.

U-Boot 1.1.3 (Mar 21 2016 - 16:55:00)
MT7620 # tftpboot 0x81000000 dap1620-dsa-mietekn-post5-initramfs.bin

 netboot_common, argc= 3

 NetTxPacket = 0x83FE70C0

 KSEG1ADDR(NetTxPacket) = 0xA3FE70C0

 NetLoop,call eth_halt !

 NetLoop,call eth_init !
Trying Eth0 (10/100-M)

 Waitting for RX_DMA_BUSY status Start... done


 ETH_STATE_ACTIVE!!
Using Eth0 (10/100-M) device
TFTP from server 192.168.100.230; our IP address is 192.168.100.119
Filename 'dap1620-dsa-mietekn-post5-initramfs.bin'.

 TIMEOUT_COUNT=10,Load address: 0x81000000
Loading: Got ARP REPLY, set server/gtwy eth addr (fe:5e:59:a3:91:64)
done
Bytes transferred = 7041260 (6b70ec hex)
NetBootFileXferSize= 006b70ec
MT7620 # bootm 0x81000000
## Booting image at 81000000 ...
   Image Name:   MIPS OpenWrt Linux-6.18.44
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    7041196 Bytes =  6.7 MB
   Load Address: 80000000
   Entry Point:  80000000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
No initrd
## Transferring control to Linux (at address 80000000) ...
## Giving linux memsize in MB, 64

Starting kernel ...

[    0.000000] Linux version 6.18.44 (builder@openwrt-dev) (mipsel-openwrt-linux-musl-gcc (OpenWrt GCC 14.4.0 r36008+1-a46721f04d) 14.4.0, GNU ld (GNU Binutils) 2.46.1) #0 Wed Sep  2 18:44:49 2026
[    0.000000] Board has DDR2
[    0.000000] Analog PMU set to hw control
[    0.000000] Digital PMU set to hw control
[    0.000000] SoC Type: MediaTek MT7620A ver:2 eco:6
[    0.000000] printk: legacy bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 00019650 (MIPS 24KEc)
[    0.000000] MIPS: machine is D-Link DAP-1620 A2
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
[    0.000000] Primary data cache 32kB, 4-way, PIPT, no aliases, linesize 32 bytes
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] OF: reserved mem: Reserved memory: No reserved-memory node in the DT
[    0.000000] Kernel command line: console=ttyS0,57600 rootfstype=squashfs,jffs2
[    0.000000] printk: log buffer data + meta data: 131072 + 409600 = 540672 bytes
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[    0.000000] Writing ErrCtl register=00034410
[    0.000000] Readback ErrCtl register=00034410
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16384
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=1.
[    0.000000] NR_IRQS: 256
[    0.000000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.000000] CPU Clock: 580MHz
[    0.000000] clocksource: systick: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 583261500 ns
[    0.000000] systick: running - mult: 214748, shift: 32
[    0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 6590553264 ns
[    0.000002] sched_clock: 32 bits at 290MHz, resolution 3ns, wraps every 7405115902ns
[    0.015600] Calibrating delay loop... 385.84 BogoMIPS (lpj=1929216)
[    0.087824] pid_max: default: 32768 minimum: 301
[    0.110059] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.124495] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.166733] Memory: 49504K/65536K available (7116K kernel code, 604K rwdata, 1620K rodata, 5180K init, 234K bss, 15500K reserved, 0K cma-reserved)
[    0.200166] posixtimers hash table entries: 512 (order: 0, 2048 bytes, linear)
[    0.214525] futex hash table entries: 256 (4096 bytes on 1 NUMA nodes, total 4 KiB, linear).
[    0.240655] pinctrl core: initialized pinctrl subsystem
[    0.255454] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.271803] /pinctrl: Fixed dependency cycle(s) with /pinctrl/pinctrl0
[    2.107831] PCI host bridge to bus 0000:00
[    2.115928] pci_bus 0000:00: root bus resource [mem 0x20000000-0x2fffffff]
[    2.129528] pci_bus 0000:00: root bus resource [io  0x10160000-0x1016ffff]
[    2.143216] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    2.159027] pci 0000:00:00.0: [1814:0801] type 01 class 0x060400 PCIe Root Port
[    2.173517] pci 0000:00:00.0: BAR 0 [mem 0x00000000-0x7fffffff]
[    2.185264] pci 0000:00:00.0: BAR 1 [mem 0x20200000-0x2020ffff]
[    2.197040] pci 0000:00:00.0: PCI bridge to [bus 01]
[    2.206882] pci 0000:00:00.0:   bridge window [io  0x0000-0x0fff]
[    2.219012] pci 0000:00:00.0:   bridge window [mem 0x20000000-0x200fffff]
[    2.232512] pci 0000:00:00.0:   bridge window [mem 0x20100000-0x201fffff pref]
[    2.246959] pci 0000:00:00.0: supports D1
[    2.254820] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
[    2.269080] pci 0000:01:00.0: [14c3:7662] type 00 class 0x028000 PCIe Endpoint
[    2.283480] pci 0000:01:00.0: BAR 0 [mem 0x00000000-0x000fffff 64bit]
[    2.296182] pci 0000:01:00.0: ROM [mem 0x00000000-0x0000ffff pref]
[    2.308617] pci 0000:01:00.0: PME# supported from D0 D3hot D3cold
[    2.321119] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    2.334221] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01
[    2.347353] pci 0000:00:00.0: BAR 0 [mem size 0x80000000]: can't assign; no space
[    2.362210] pci 0000:00:00.0: BAR 0 [mem size 0x80000000]: failed to assign
[    2.376076] pci 0000:00:00.0: bridge window [mem 0x20000000-0x200fffff]: assigned
[    2.390946] pci 0000:00:00.0: bridge window [mem 0x20100000-0x201fffff pref]: assigned
[    2.406694] pci 0000:00:00.0: BAR 1 [mem 0x20200000-0x2020ffff]: assigned
[    2.420198] pci 0000:00:00.0: bridge window [mem 0x20000000-0x200fffff]: releasing
[    2.435252] pci 0000:00:00.0: bridge window [mem 0x20100000-0x201fffff pref]: releasing
[    2.451168] pci 0000:00:00.0: BAR 1 [mem 0x20200000-0x2020ffff]: releasing
[    2.464843] pci 0000:00:00.0: BAR 0 [mem size 0x80000000]: can't assign; no space
[    2.479726] pci 0000:00:00.0: BAR 0 [mem size 0x80000000]: failed to assign
[    2.493580] pci 0000:00:00.0: bridge window [mem 0x20000000-0x200fffff]: assigned
[    2.508464] pci 0000:00:00.0: bridge window [mem 0x20100000-0x201fffff pref]: assigned
[    2.524212] pci 0000:00:00.0: BAR 1 [mem 0x20200000-0x2020ffff]: assigned
[    2.537719] pci 0000:01:00.0: BAR 0 [mem 0x20000000-0x200fffff 64bit]: assigned
[    2.552278] pci 0000:01:00.0: ROM [mem 0x20100000-0x2010ffff pref]: assigned
[    2.566271] pci 0000:00:00.0: PCI bridge to [bus 01]
[    2.576114] pci 0000:00:00.0:   bridge window [mem 0x20000000-0x200fffff]
[    2.589631] pci 0000:00:00.0:   bridge window [mem 0x20100000-0x201fffff pref]
[    2.606164] clocksource: Switched to clocksource MIPS
[    2.630686] NET: Registered PF_INET protocol family
[    2.640680] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    2.656078] tcp_listen_portaddr_hash hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    2.672858] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[    2.689509] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    2.704669] TCP bind hash table entries: 1024 (order: 1, 8192 bytes, linear)
[    2.718689] TCP: Hash tables configured (established 1024 bind 1024)
[    2.731973] MPTCP token hash table entries: 512 (order: 1, 6144 bytes, linear)
[    2.746655] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[    2.759617] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[    2.774499] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    2.785852] PCI: CLS 0 bytes, default 32
[    2.793835] rt-timer 10000100.timer: maximum frequency is 1220Hz
[    3.684063] workingset: timestamp_bits=14 max_order=14 bucket_order=0
[    3.698980] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    3.710554] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    3.742117] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[    3.756692] printk: legacy console [ttyS0] disabled
[    3.767104] 10000c00.serial: ttyS0 at MMIO 0x10000c00 (irq = 20, base_baud = 2500000) is a Palmchip BK-3103
[    3.786531] printk: legacy console [ttyS0] enabled
[    3.786531] printk: legacy console [ttyS0] enabled
[    3.805481] printk: legacy bootconsole [early0] disabled
[    3.805481] printk: legacy bootconsole [early0] disabled
[    3.866728] spi spi0.0: force spi mode3
[    3.874840] spi-nor spi0.0: supply vcc not found, using dummy regulator
[    3.888759] 4 fixed-partitions partitions found on MTD device spi0.0
[    3.901907] Creating 4 MTD partitions on "spi0.0":
[    3.911532] 0x000000000000-0x000000030000 : "u-boot"
[    4.674295] 0x000000030000-0x000000040000 : "nvram"
[    4.685039] 0x000000040000-0x000000050000 : "factory"
[    4.696603] 0x000000050000-0x000000800000 : "firmware"
[    4.707888] 2 uimage-fw partitions found on MTD device firmware
[    4.719814] Creating 2 MTD partitions on "firmware":
[    4.729732] 0x000000000000-0x0000002c9274 : "kernel"
[    4.739656] mtd: partition "kernel" doesn't end on an erase/write block -- force read-only
[    4.757217] 0x0000002c9274-0x0000007b0000 : "rootfs"
[    4.767230] mtd: partition "rootfs" doesn't start on an erase/write block boundary -- force read-only
[    4.786490] mtd: setting mtd5 (rootfs) as root device
[    4.796748] 1 squashfs-split partitions found on MTD device rootfs
[    4.809113] 0x0000006f0000-0x0000007b0000 : "rootfs_data"
[    4.841971] gsw: ephy base address: 12
[    4.850887] gsw: setting port4 to ephy mode
[   11.766825] mtk_soc_eth 10100000.ethernet eth0: mediatek frame engine at 0xb0100000, irq 5
[   11.784147] rt2880_wdt 10000120.watchdog: Initialized
[   11.797087] NET: Registered PF_INET6 protocol family
[   11.814490] Segment Routing with IPv6
[   11.822044] In-situ OAM (IOAM) with IPv6
[   11.830144] NET: Registered PF_PACKET protocol family
[   11.840325] 8021q: 802.1Q VLAN Support v1.8
[   11.888275] clk: Disabling unused clocks
[   11.925123] Freeing unused kernel image (initmem) memory: 5180K
[   11.937000] This architecture does not have kernel memory protection.
[   11.949857] Run /init as init process
[   12.634318] init: Console is alive
[   12.641831] init: - watchdog -
[   12.672130] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[   12.717143] gpio_button_hotplug: loading out-of-tree module taints kernel.
[   12.743470] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[   12.768754] init: - preinit -
[   15.666217] random: crng init done
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
- generating board file -
[   21.042460] procd: - early -
[   21.048735] procd: - watchdog -
[   21.668223] procd: - watchdog -
[   21.675873] procd: - ubus -
[   21.742497] procd: - init -
Please press Enter to activate this console.
[   23.001303] kmodloader: loading kernel modules from /etc/modules.d/*
[   24.661300] i2c_dev: i2c /dev entries driver
[   24.692834] Loading modules backported from Linux version v7.2-0-g8d3ae59288f1
[   24.707350] Backport generated by backports.git v5.15.58-1-198-g2580fa90cb79
[   24.888363] mt7620-dsa mt7620-dsa.0.auto: configuring for fixed/rgmii link mode
[   24.903838] mt7620-dsa mt7620-dsa.0.auto lan (uninitialized): PHY [mdio-bus:01] driver [RTL8211E Gigabit Ethernet] (irq=POLL)
[   24.928054] mtk_soc_eth 10100000.ethernet eth0: entered promiscuous mode
[   24.941644] DSA: tree 0 setup
[   24.947949] mt7620-dsa mt7620-dsa.0.auto: Link is Up - 1Gbps/Full - flow control rx/tx
[   25.331177] mt76x2e 0000:01:00.0: card - bus=0x1, slot = 0x0 irq=4
[   25.356445] mt76x2e 0000:01:00.0: ASIC revision: 76120044
[   26.056632] mt76x2e 0000:01:00.0: ROM patch build: 20141115060606a
[   26.096961] mt76x2e 0000:01:00.0: Firmware Version: 0.0.00
[   26.108041] mt76x2e 0000:01:00.0: Build: 1
[   26.116229] mt76x2e 0000:01:00.0: Build Time: 201607111443____
[   26.132432] urngd: v1.0.2 started.
[   26.176230] mt76x2e 0000:01:00.0: Firmware running!
[   26.186270] mt76x2e 0000:01:00.0: registering led 'mt76-phy0'
[   26.543194] PPP generic driver version 2.4.2
[   26.589561] NET: Registered PF_PPPOX protocol family
[   26.778965] ieee80211 phy1: rt2x00_set_rt: Info - RT chipset 6352, rev 0500 detected
[   26.794974] ieee80211 phy1: rt2x00_set_rf: Info - RF chipset 7620 detected
[   26.916689] kmodloader: done loading kernel modules from /etc/modules.d/*
[   48.604419] 8021q: adding VLAN 0 to HW filter on device eth0
[   48.659111] mt7620-dsa mt7620-dsa.0.auto lan: configuring for phy/rgmii-id link mode
[   48.713521] br-lan: port 1(lan) entered blocking state
[   48.723890] br-lan: port 1(lan) entered disabled state
[   48.734242] mt7620-dsa mt7620-dsa.0.auto lan: entered allmulticast mode
[   48.747496] mtk_soc_eth 10100000.ethernet eth0: entered allmulticast mode
[   48.761586] mt7620-dsa mt7620-dsa.0.auto lan: entered promiscuous mode
[   52.809517] mt7620-dsa mt7620-dsa.0.auto lan: Link is Up - 1Gbps/Full - flow control rx/tx
[   52.826225] br-lan: port 1(lan) entered blocking state
[   52.836524] br-lan: port 1(lan) entered forwarding state

BusyBox v1.38.0 (2026-05-13 02:19:59 UTC) built-in shell (ash)
  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt SNAPSHOT, r36012+1-73ceb51325
 -----------------------------------------------------

 === WARNING! =====================================
 There is no root password defined on this device!
 Use the "passwd" command to set up a new password
 in order to prevent unauthorized SSH logins.
 --------------------------------------------------

root@OpenWrt:~# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN qlen 1000
    link/ether 40:9b:cd:e7:66:76 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::429b:cdff:fee7:6676/64 scope link
       valid_lft forever preferred_lft forever
3: lan@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP qlen 1000
    link/ether 40:9b:cd:e7:66:76 brd ff:ff:ff:ff:ff:ff
4: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 40:9b:cd:e7:66:76 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global br-lan
       valid_lft forever preferred_lft forever
    inet6 fd0b:81f8:4413::1/60 scope global noprefixroute
       valid_lft forever preferred_lft forever
    inet6 fe80::429b:cdff:fee7:6676/64 scope link
       valid_lft forever preferred_lft forever
root@OpenWrt:~# ping 192.168.1.50
PING 192.168.1.50 (192.168.1.50): 56 data bytes
64 bytes from 192.168.1.50: seq=0 ttl=128 time=2.096 ms
64 bytes from 192.168.1.50: seq=1 ttl=128 time=0.800 ms
64 bytes from 192.168.1.50: seq=2 ttl=128 time=0.706 ms
64 bytes from 192.168.1.50: seq=3 ttl=128 time=0.886 ms
^C
--- 192.168.1.50 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.706/1.122/2.096 ms
root@OpenWrt:~#
root@OpenWrt:~# ip link set lan down
sleep 2
ip link set lan [  347.337756] mt7620-dsa mt7620-dsa.0.auto lan: Link is Down
up[  347.351827] ttyS ttyS0: 1 input overrun(s)

sleep 3
[  347.361142] br-lan: port 1(lan) entered disabled state
ping -c 5 192.1root@OpenWrt:~# sleep 2
root@OpenWrt:~# ip link set lan up
[  349.393880] mt7620-dsa mt7620-dsa.0.auto lan: configuring for phy/rgmii-id link mode
root@OpenWrt:~# sleep 3

root@OpenWrt:~# [  352.566615] mt7620-dsa mt7620-dsa.0.auto lan: Link is Up - 1Gbps/Full - flow control rx/tx
[  352.583241] br-lan: port 1(lan) entered blocking state
[  352.593550] br-lan: port 1(lan) entered forwarding state

root@OpenWrt:~# ping 192.168.1.50
PING 192.168.1.50 (192.168.1.50): 56 data bytes
64 bytes from 192.168.1.50: seq=0 ttl=128 time=1.923 ms
64 bytes from 192.168.1.50: seq=1 ttl=128 time=0.952 ms
^C
--- 192.168.1.50 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.952/1.437/1.923 ms
root@OpenWrt:~#

Prepare a complete commit "ramips: mt7620: add DSA support for rgmii1" and create a PR in the main repository. We'll see what Claude AI tells us.

@mietekn, @dormancygrace - Review and feedback appreciated.

Test it first: