Support for TP-Link VX830v (MT7986)

Hi everyone, I'm working on a TP-Link VX830v (from Italian ISP) based on MediaTek MT7986. I can boot an initramfs image via TFTP, but I'm struggling to get a correct NAND dump. I need help to define the correct Device Tree and understand the memory layout to safely backup the original firmware.

  • SoC: MediaTek MT7986A (Filogic 830)
  • RAM: 512 MiB DDR3
  • Flash: 256 MiB SPI-NAND
  • Ethernet: 2x 2.5G , 2x 1G
  • USB: 1x USB 3.0

It has also another Serial port for EN7516 chip. If needed I could also post logs from that, still not tested.

This is the boot Log from U-Boot at the start

F0: 102B 0000
FA: 1040 0000
FA: 1040 0000 [0200]
F9: 0000 0000
V0: 0000 0000 [0001]
00: 0000 0000
BP: 2400 0041 [0000]
G0: 1190 0000
EC: 0000 0000 [1000]
T0: 0000 014B [010F]
Jump to BL

NOTICE:  BL2: v2.6(release):e6124de0e-dirty
NOTICE:  BL2: Built : 09:33:38, Feb  5 2024
NOTICE:  WDT: disabled
NOTICE:  EMI: Using DDR3 settings
NOTICE:  EMI: Detected DRAM size: 512MB
NOTICE:  EMI: complex R/W mem test passed
NOTICE:  SPI_NAND parses attributes from parameter page.
NOTICE:  SPI_NAND Detected ID 0x2c
NOTICE:  Page size 2048, Block size 131072, size 268435456
NOTICE:  Initializing NMBM ...
NOTICE:  Signature found at block 2047 [0x0ffe0000]
NOTICE:  First info table with writecount 2 found in block 1920
NOTICE:  Second info table with writecount 2 found in block 1923
NOTICE:  NMBM has been successfully attached in read-only mode
NOTICE:  BL2: Booting BL31
NOTICE:  BL31: v2.6(release):e6124de0e-dirty
NOTICE:  BL31: Built : 09:33:49, Feb  5 2024


U-Boot 2022.07-rc1 (Feb 05 2024 - 09:31:30 +0800)

CPU:   MediaTek MT7986
Model: mt7986-rfb
DRAM:  512 MiB
Core:  46 devices, 18 uclasses, devicetree: embed

Initializing NMBM ...
spi-nand: spi_nand spi_nand@1: Micron SPI NAND was found.
spi-nand: spi_nand spi_nand@1: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
Could not find a valid device for nmbm0
Signature found at block 2047 [0x0ffe0000]
First info table with writecount 2 found in block 1920
Second info table with writecount 2 found in block 1923
NMBM has been successfully attached

MMC:   mmc@11230000: 0
Loading Environment from MTD... OK
In:    serial@11002000
Out:   serial@11002000
Err:   serial@11002000
Net:
Warning: ethernet@15100000 (eth0) using random MAC address - 0e:5f:ec:00:7e:98
eth0: ethernet@15100000
press ctrl-c or t to go to uboot cmdline                                      0 new bootarg:ubi.mtd=ubi0 console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000
ubi0: attaching mtd6
ubi0: scanning is finished
ubi0: attached mtd6 (name "ubi0", size 40 MiB)
ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
ubi0: good PEBs: 320, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 3, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 213537884
ubi0: available PEBs: 81, total reserved PEBs: 239, PEBs reserved for bad PEB handling: 38
Reading from volume 'uboot' to 0x41dfffc0, size 0x0 ... OK
Reading from volume 'rootfs' to 0x4a000000, size 0x0 ... OK
Reading from volume 'kernel' to 0x46000000, size 0x0 ... OK
## Booting kernel from Legacy Image at 41dfffc0 ...
   Image Name:   seconduboot
   Image Type:   ARM Linux Standalone Program (uncompressed)
   Data Size:    669080 Bytes = 653.4 KiB
   Load Address: 00000000
   Entry Point:  41e00000
   Verifying Checksum ... OK
   Loading Standalone Program


U-Boot 2022.07-rc1 (Jul 03 2025 - 13:50:03 +0800)

CPU:   MediaTek MT7986
Model: mt7986-rfb
DRAM:  512 MiB
Core:  43 devices, 16 uclasses, devicetree: embed

Initializing NMBM ...
spi-nand: spi_nand spi_nand@1: Micron SPI NAND was found.
spi-nand: spi_nand spi_nand@1: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
Could not find a valid device for nmbm0
Signature found at block 2047 [0x0ffe0000]
First info table with writecount 2 found in block 1920
Second info table with writecount 2 found in block 1923
NMBM has been successfully attached

Loading Environment from MTD... OK
In:    serial@11002000
Out:   serial@11002000
Err:   serial@11002000
Net:
Warning: ethernet@15100000 (eth0) using random MAC address - 02:75:45:65:24:55
eth0: ethernet@15100000
new bootarg:ubi.mtd=ubi0 console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000
second uboot to boot kernel @46000000
## Loading kernel from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Trying 'kernel-1' kernel subimage
     Description:  ARM64 OpenWrt Linux-5.4.211
     Type:         Kernel Image
     Compression:  lzma compressed
     Data Start:   0x460000e8
     Data Size:    4093742 Bytes = 3.9 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x48080000
     Entry Point:  0x48080000
     Hash algo:    crc32
     Hash value:   79317af1
     Hash algo:    sha1
     Hash value:   464e92a11d77b47cbde56c72e33494923fb94635
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading fdt from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Trying 'fdt-1' fdt subimage
     Description:  ARM64 OpenWrt VX830v device tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x463e7950
     Data Size:    24229 Bytes = 23.7 KiB
     Architecture: AArch64
     Hash algo:    crc32
     Hash value:   16ad80d5
     Hash algo:    sha1
     Hash value:   ca8dfe15291e343d26df733c0cf3c68e353edce9
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0x463e7950
   Uncompressing Kernel Image
   Loading Device Tree to 000000005f7f1000, end 000000005f7f9ea4 ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 5.4.211 (root@7086da4efda9) (gcc version 8.4.0 (OpenWrt GCC 8.4.0 r16649-bcaabe6d05)) #1 SMP Thu Jul 3 13:52:57 CST 2025
[    0.000000] Machine model: MediaTek MT7986a RFB
[    0.000000] earlycon: uart8250 at MMIO32 0x0000000011002000 (options '')
[    0.000000] printk: bootconsole [uart8250] enabled
[    0.000000] On node 0 totalpages: 130064
[    0.000000]   DMA32 zone: 2048 pages used for memmap
[    0.000000]   DMA32 zone: 0 pages reserved
[    0.000000]   DMA32 zone: 130064 pages, LIFO batch:31
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] psci: SMC Calling Convention v1.0
[    0.000000] percpu: Embedded 20 pages/cpu s44440 r8192 d29288 u81920
[    0.000000] pcpu-alloc: s44440 r8192 d29288 u81920 alloc=20*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: detected: ARM erratum 845719
[    0.000000] CPU features: detected: GIC system register CPU interface
[    0.000000] CPU features: kernel page table isolation disabled by kernel configuration
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 128016
[    0.000000] Kernel command line: ubi.mtd=ubi0 console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000
[    0.000000] Dentry cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.000000] Inode-cache hash table entries: 32768 (order: 6, 262144 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 489416K/520256K available (8254K kernel code, 610K rwdata, 2408K rodata, 512K init, 306K bss, 30840K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     CONFIG_RCU_FANOUT set to non-default value of 32.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GICv3: GIC: Using split EOI/Deactivate mode
[    0.000000] GICv3: 640 SPIs implemented
[    0.000000] GICv3: 0 Extended SPIs implemented
[    0.000000] GICv3: Distributor has no Range Selector support
[    0.000000] GICv3: 16 PPIs implemented
[    0.000000] GICv3: no VLPI support, no direct LPI support
[    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x000000000c080000
[    0.000000] arch_timer: cp15 timer(s) running at 13.00MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x2ff89eacb, max_idle_ns: 440795202429 ns
[    0.000002] sched_clock: 56 bits at 13MHz, resolution 76ns, wraps every 4398046511101ns
[    0.008184] Calibrating delay loop (skipped), value calculated using timer frequency.. 26.00 BogoMIPS (lpj=130000)
[    0.018586] pid_max: default: 32768 minimum: 301
[    0.023279] Mount-cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
[    0.030625] Mountpoint-cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
[    0.039127] ASID allocator initialised with 65536 entries
[    0.044597] rcu: Hierarchical SRCU implementation.
[    0.049669] smp: Bringing up secondary CPUs ...
[    0.054435] Detected VIPT I-cache on CPU1
[    0.054450] GICv3: CPU1: found redistributor 1 region 0:0x000000000c0a0000
[    0.054466] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[    0.054728] Detected VIPT I-cache on CPU2
[    0.054737] GICv3: CPU2: found redistributor 2 region 0:0x000000000c0c0000
[    0.054745] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[    0.054956] Detected VIPT I-cache on CPU3
[    0.054964] GICv3: CPU3: found redistributor 3 region 0:0x000000000c0e0000
[    0.054971] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[    0.054998] smp: Brought up 1 node, 4 CPUs
[    0.111534] SMP: Total of 4 processors activated.
[    0.116253] CPU features: detected: 32-bit EL0 Support
[    0.121409] CPU features: detected: CRC32 instructions
[    0.126649] CPU: All CPU(s) started at EL2
[    0.130763] alternatives: patching kernel code
[    0.135627] devtmpfs: initialized
[    0.140753] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.150649] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
[    0.157626] pinctrl core: initialized pinctrl subsystem
[    0.163473] NET: Registered protocol family 16
[    0.168098] DMA: preallocated 256 KiB pool for atomic allocations
[    0.174604] cpuidle: using governor ladder
[    0.178736] cpuidle: using governor menu
[    0.190687] cryptd: max_cpu_qlen set to 1000
[    0.196117] SCSI subsystem initialized
[    0.199998] libata version 3.00 loaded.
[    0.203993] usbcore: registered new interface driver usbfs
[    0.209523] usbcore: registered new interface driver hub
[    0.214870] usbcore: registered new device driver usb
[    0.220300] Advanced Linux Sound Architecture Driver Initialized.
[    0.227395] rbus 18000000.wbsys: PCI host bridge to bus 0000:00
[    0.233350] pci_bus 0000:00: root bus resource [mem 0x18000000-0x18ffffff]
[    0.240254] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.245763] pci_bus 0000:00: scanning bus
[    0.249794] pci 0000:00:00.0: [14c3:7986] type 00 class 0x000280
[    0.255834] pci 0000:00:00.0: reg 0x10: [mem 0x18000000-0x1800000f 64bit]
[    0.262650] pci 0000:00:00.0: reg 0x18: [mem 0x00000000-0x0000000f]
[    0.268945] pci 0000:00:00.0: reg 0x1c: [mem 0x00000000-0x0000000f]
[    0.275237] pci 0000:00:00.0: reg 0x20: [mem 0x00000000-0x0000000f]
[    0.281531] pci 0000:00:00.0: reg 0x24: [mem 0x00000000-0x0000000f]
[    0.288598] pci_bus 0000:00: fixups for bus
[    0.292798] pci_bus 0000:00: bus scan returning with max=00
[    0.298652] clocksource: Switched to clocksource arch_sys_counter
[    0.305393] thermal_sys: Registered thermal governor 'fair_share'
[    0.305395] thermal_sys: Registered thermal governor 'bang_bang'
[    0.311550] thermal_sys: Registered thermal governor 'step_wise'
[    0.317579] thermal_sys: Registered thermal governor 'user_space'
[    0.323612] thermal_sys: Registered thermal governor 'power_allocator'
[    0.329940] NET: Registered protocol family 2
[    0.340939] IP idents hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.348479] tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.356895] TCP established hash table entries: 4096 (order: 3, 32768 bytes, linear)
[    0.364691] TCP bind hash table entries: 4096 (order: 4, 65536 bytes, linear)
[    0.371893] TCP: Hash tables configured (established 4096 bind 4096)
[    0.378323] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[    0.384887] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[    0.391950] NET: Registered protocol family 1
[    0.396336] PCI: CLS 0 bytes, default 64
[    0.400889] workingset: timestamp_bits=46 max_order=17 bucket_order=0
[    0.409820] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.415820] ntfs: driver 2.1.32 [Flags: R/O].
[    0.420282] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.430242] fuse: init (API version 7.31)
[    0.442649] mt7986-pinctrl 1001f000.pinctrl: invalid group "pcie_wake" for function "pcie"
[    0.451001] mtk-pcie 11280000.pcie: host bridge /pcie@11280000 ranges:
[    0.457558] mtk-pcie 11280000.pcie: Parsing ranges property...
[    0.463421] mtk-pcie 11280000.pcie:   MEM 0x20000000..0x2fffffff -> 0x20000000
[    0.470695] phy phy-pcie-phy@11c00000.0: try to get sw efuse
[    0.476376] phy phy-pcie-phy@11c00000.0: try to get sw efuse+
[    0.482159] phy phy-pcie-phy@11c00000.0: u3 auto load valid efuse: ENABLE with value: 1
[    0.490217] phy phy-pcie-phy@11c00000.0: u3 efuse - intr 2b, rx_imp 10, tx_imp f
[    0.497649] phy phy-pcie-phy@11c00000.0: pcie auto load valid efuse: ENABLE with value: 1
[    0.505882] phy phy-pcie-phy@11c00000.0: u3 lane1 efuse - intr 2b, rx_imp 10, tx_imp f
[    0.728658] mtk-pcie 11280000.pcie: PCIe link down, ltssm reg val: 0x0
[    0.735259] mtk-pcie: probe of 11280000.pcie failed with error -110
[    0.748920] Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
[    0.755849] printk: console [ttyS0] disabled
[    0.780250] 11002000.serial: ttyS0 at MMIO 0x11002000 (irq = 12, base_baud = 2500000) is a ST16650V2
[    0.789453] printk: console [ttyS0] enabled
[    0.797799] printk: bootconsole [uart8250] disabled

MTD structure

List of MTD devices:
* spi-nand0
  - device: spi_nand@1
  - parent: spi@1100a000
  - driver: spi_nand
  - path: /spi@1100a000/spi_nand@1
  - type: NAND flash
  - block size: 0x20000 bytes
  - min I/O: 0x800 bytes
  - OOB size: 128 bytes
  - OOB available: 62 bytes
  - 0x000000000000-0x000010000000 : "spi-nand0"
* nmbm0
  - type: Unknown
  - block size: 0x20000 bytes
  - min I/O: 0x800 bytes
  - OOB size: 128 bytes
  - OOB available: 62 bytes
  - 0x000000000000-0x00000f000000 : "nmbm0"
          - 0x000000000000-0x000000200000 : "boot"
          - 0x000000200000-0x000000300000 : "u-boot-env"
          - 0x000000300000-0x000000900000 : "misc_ro"
          - 0x000000900000-0x000000f00000 : "misc_rw"
          - 0x000000f00000-0x000003700000 : "ubi0"
          - 0x000003700000-0x000005f00000 : "ubi1"

UBI output

----- ubi0 --------
Volume information dump:
        vol_id          0
        reserved_pebs   6
        alignment       1
        data_pad        0
        vol_type        4
        name_len        5
        usable_leb_size 126976
        used_ebs        6
        used_bytes      669144
        last_eb_bytes   34264
        corrupted       0
        upd_marker      0
        skip_check      0
        name            uboot
Volume information dump:
        vol_id          1
        reserved_pebs   33
        alignment       1
        data_pad        0
        vol_type        4
        name_len        6
        usable_leb_size 126976
        used_ebs        33
        used_bytes      4119852
        last_eb_bytes   56620
        corrupted       0
        upd_marker      0
        skip_check      0
        name            kernel
Volume information dump:
        vol_id          2
        reserved_pebs   158
        alignment       1
        data_pad        0
        vol_type        4
        name_len        6
        usable_leb_size 126976
        used_ebs        158
        used_bytes      19955712
        last_eb_bytes   20480
        corrupted       0
        upd_marker      0
        skip_check      0
        name            rootfs
Volume information dump:
        vol_id          2147479551
        reserved_pebs   2
        alignment       1
        data_pad        0
        vol_type        3
        name_len        13
        usable_leb_size 126976
        used_ebs        2
        used_bytes      253952
        last_eb_bytes   2
        corrupted       0
        upd_marker      0
        skip_check      0
        name            layout volume

----- ubi1 ---------
Volume information dump:
        vol_id          0
        reserved_pebs   6
        alignment       1
        data_pad        0
        vol_type        4
        name_len        5
        usable_leb_size 126976
        used_ebs        6
        used_bytes      669144
        last_eb_bytes   34264
        corrupted       0
        upd_marker      0
        skip_check      0
        name            uboot
Volume information dump:
        vol_id          1
        reserved_pebs   33
        alignment       1
        data_pad        0
        vol_type        4
        name_len        6
        usable_leb_size 126976
        used_ebs        33
        used_bytes      4120588
        last_eb_bytes   57356
        corrupted       0
        upd_marker      0
        skip_check      0
        name            kernel
Volume information dump:
        vol_id          2
        reserved_pebs   167
        alignment       1
        data_pad        0
        vol_type        4
        name_len        6
        usable_leb_size 126976
        used_ebs        167
        used_bytes      21110784
        last_eb_bytes   32768
        corrupted       0
        upd_marker      0
        skip_check      0
        name            rootfs
Volume information dump:
        vol_id          2147479551
        reserved_pebs   2
        alignment       1
        data_pad        0
        vol_type        3
        name_len        13
        usable_leb_size 126976
        used_ebs        2
        used_bytes      253952
        last_eb_bytes   2
        corrupted       0
        upd_marker      0
        skip_check      0
        name            layout volume

Environment


MT7986> printenv
baudrate=115200
bootargs=ubi.mtd=ubi0 console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000
bootcmd=bootp; setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; bootm
bootdelay=5
ethaddr=76:1b:0f:42:8f:c8
fdtcontroladdr=5ffc53b0
ipaddr=192.168.1.1
loadaddr=0x46000000
mtdids=nmbm0=nmbm0
mtdparts=nmbm0:2M(boot),1M(u-boot-env),6M(misc_ro),6M(misc_rw),40M(ubi0),40M(ubi1)
netmask=255.255.255.0
serverip=192.168.1.2
stderr=serial@11002000
stdin=serial@11002000
stdout=serial@11002000

Environment size: 573/131068 bytes

nmbm logs

MT7986> nmbm list
Index   NMBM device         Lower device
========================================
0       nmbm0               spi-nand0
MT7986> nmbm nmbm0 info
nmbm0:
Total blocks:                  2048
Data blocks:                   1920
Management start block:        1920
Info table size:               0x3000
Main info table start block:   1920
Backup info table start block: 1923
Signature block:               2047
Mapping blocks top address:    2045
Mapping blocks limit address:  1924
MT7986> nmbm nmbm0 mapping
Logical Block       Physical Block
==================================
1919                2046

My goal is to contribute to a proper porting for this device, ensuring the Device Tree accurately reflects the partition layout and NMBM mapping. I want to make sure I have a reliable way to backup and restore the stock firmware before moving forwards.

Any insights on the NMBM logic or the specific SPI-NAND configuration would be greatly appreciated.

Back up OEM partitions from uboot or oem linux and try to binwarlk towards dtc-ing dtb into dts. Maybe it is similar to a retail device.
Then try to netboot that similar retail device kernel (provided help in uboot shows tftpboot and bootm at least)
DSL and DECT and phone sockets will not be supportable, you still get a normal router though

Any progress on porting OpenWrt to this device? I plan to buy one soon and would like to continue the porting work. Is someone still working on it? Did the porting effort stall because of specific technical blockers I should be aware of, or for other reasons?

Hi, we're working on it in a telegram group. Thanks to Alessandro we got everything except SFP, DSL and FXS working.
It used it for 10 days, it looks stable and wifi performs great.

Two guys are trying to study on DSL and FXS.

Hello, I recently acquired two units of this model that will arrive next week; I plan to use them for testing and would like to participate.

Hi,
a friend of mine using GPL sources initially provided bringup for Openwrt.
He had some custom patches and a DTS mainly based on the VENDOR one and I've taken up his work to properly bring up a clean Openwrt to be accepted by the community.

The hardware consist of:

SoC: MediaTek MT7986A (Filogic 830)
RAM: 512 MiB DDR3
Flash (Storage): 256 MiB SPI-NAND (UBI Layout)
WLAN 2.4 GHz: MediaTek MT7975 (I haven't opened the EMI cages to verify)
WLAN 5 GHz: MediaTek MT7975 (I haven't opened the EMI cages to verify)
Secondary SoC: EcoNet EN7516 (Dedicated xDSL / Coprocessor)
VoIP SoC/Slic: SI3228 (Interface handled via secondary coprocessor / 2x FXS ports)

Switch/PHY: Built-in MediaTek MT7531
Port Configuration: 
* 1x 2.5 Gbps Ethernet WAN (PHY: EN8811H via MAC1)
* 1x 2.5 Gbps Ethernet LAN  (PHY: EN8811H via Switch Port5)
* 2x 1.0 Gbps Ethernet LAN
* 1x SFP Port (Integrated cage, max 2.5G, XOR via SGMII MUX between the case and WAN phy)
* 1x RJ11 DSL Port (terminated via EN7516)

USB: 1x USB 3.0 Type-A SuperSpeed
Serial (UART): 2x Header Locations on PCB
* UART0: Main CPU (MediaTek MT7986A) - 115200n1, 3.3V
* UART1: Secondary DSL CPU (EcoNet EN7516)

From this, and other people reports, it should be all working fine, but building on top of snapshot using his provided patches and using Openwrt built in logic and scripting I'm facing two issues:

  • The phy on the 2.5 LAN is correctly loading the firmware but the switch driver fails the phy capabilities/verification match throwing an error.
  • I cannot find a way to properly load the EEPROM data for the WIFI.

Lets tackle each issue by starting from the PHY.
This is the dmesg in question:

[    2.490355] mt7530-mdio mdio-bus:1f: configuring for fixed/2500base-x link mode
[    2.499155] mt7530-mdio mdio-bus:1f: Link is Up - 2.5Gbps/Full - flow control rx/tx
[    2.509117] mt7530-mdio mdio-bus:1f lan0 (uninitialized): PHY [mt7530-0:00] driver [MediaTek MT7531 PHY] (irq=124)
[    2.534642] mt7530-mdio mdio-bus:1f lan2 (uninitialized): PHY [mt7530-0:01] driver [MediaTek MT7531 PHY] (irq=125)
[    2.559858] mt7530-mdio mdio-bus:1f lan1 (uninitialized): PHY [mt7530-0:02] driver [MediaTek MT7531 PHY] (irq=126)
[    2.576078] mt7530-mdio mdio-bus:1f lan3 (uninitialized): validation of 2500base-x with support 0000000,00000000,00000000,000062e8 and advertisement 0000000,00000000,00000000,000062c0 failed: -EINVAL
[    2.606424] mt7530-mdio mdio-bus:1f lan3 (uninitialized): failed to connect to PHY: -EINVAL
[    2.614766] mt7530-mdio mdio-bus:1f lan3 (uninitialized): error -22 setting up PHY for tree 0, switch 0, port 5
[    2.625167] mtk_soc_eth 15100000.ethernet eth0: entered promiscuous mode
[    2.631882] DSA: tree 0 setup
...
[    8.686743] Airoha EN8811H mdio-bus:0e: MD32 firmware version: 25062302
[   10.851327] Airoha EN8811H mdio-bus:0f: MD32 firmware version: 25062302

From what I understand supported c advertised so this should not be an issue.
But digging deeper I get that the C45 are somehow different and not matching so the init is halted.

Now, this message is printed here:

And the error is a EINVAL, no additional output is printed. so I suppose that the failure can then in two places:

I need to find a way to make the kernel verbose on initramfs boot. For what I've seen uboot is overriding the bootargs.

I've read somewhere that the EN8011H have a missing bit for the 2500 on the C45 response. I tried to hardcode the ETHTOOL_LINK_MODE_2500baseT_Full_BIT. No results.

At this point any suggestion is welcome as I have no idea on what is causing this issue as the same layout is used on the EX5601 I helped bringing Openwrt up without any such issue.

The relevant DTS:

&mdio {
	phy_lan25g: ethernet-phy@e {
		compatible = "ethernet-phy-id03a2.a411";
		reg = <0xe>;

		reset-gpios = <&pio 11 GPIO_ACTIVE_LOW>;
		reset-assert-us = <10000>;
		reset-deassert-us = <10000>;

		phy-mode = "2500base-x";
		full-duplex;
		pause;
	};

	phy_wan: ethernet-phy@f {
		compatible = "ethernet-phy-id03a2.a411";
		reg = <0xf>;

		reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>;
		reset-assert-us = <10000>;
		reset-deassert-us = <10000>;

		phy-mode = "2500base-x";
		full-duplex;
		pause;
	};

	switch: switch@1f {
		compatible = "mediatek,mt7531";
		reg = <31>;

		reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;

		interrupt-controller;
		#interrupt-cells = <1>;
		interrupt-parent = <&pio>;
		interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;

		mediatek,p5-sgmii;
	};
};

&switch {
	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		port@0 {
			reg = <0>;
			label = "lan0";
		};

		port@1 {
			reg = <1>;
			label = "lan2";
		};

		port@2 {
			reg = <2>;
			label = "lan1";
		};

		port@5 {
			reg = <5>;
			label = "lan3";
			phy-mode = "2500base-x";
			phy-handle = <&phy_lan25g>;
		};

		port@6 {
			reg = <6>;
			ethernet = <&gmac0>;
			phy-mode = "2500base-x";

			fixed-link {
				speed = <2500>;
				full-duplex;
				pause;
			};
		};
	};
};

Now lets step back to the WIFI problem.
Iḿ welcome with a firmware load error:

[   17.406308] mt798x-wmac 18000000.wifi: HW/SW Version: 0x8a108a10, Build Time: 20260515120518a
[   17.422756] mt798x-wmac 18000000.wifi: WM Firmware Version: ____000000, Build Time: 20260515120536
[   17.460735] mt798x-wmac 18000000.wifi: WA Firmware Version: DEV_000000, Build Time: 20260515120626
[   17.607070] mt798x-wmac 18000000.wifi: eeprom load fail, use default bin
[   17.613815] mt798x-wmac 18000000.wifi: Direct firmware load for mediatek/mt7986_eeprom_mt7975_dual.bin failed with error -2
[   17.624925] mt798x-wmac 18000000.wifi: Falling back to sysfs fallback for: mediatek/mt7986_eeprom_mt7975_dual.bin
[   17.655861] mt798x-wmac 18000000.wifi: probe with driver mt798x-wmac failed with error -12

Now we have to discuss a bit on where this data is. It is in a UBI volume inside the misc_ro MTD partition.
The UBI volume is not raw data, but instead contains some binary files like the EEPROM data and the MAC address. (Don't let the file names mess you up, yes they are named like memory addresses)

[    1.986090] 9 fixed-partitions partitions found on MTD device spi0.1
[    1.992445] Creating 9 MTD partitions on "spi0.1":
[    1.997239] 0x000000000000-0x000000200000 : "boot"
[    2.003915] 0x000000200000-0x000000300000 : "u-boot-env"
[    2.010152] 0x000000300000-0x000000900000 : "misc_ro"
[    2.019879] 0x000000900000-0x000000f00000 : "misc_rw"
[    2.029840] 0x000000f00000-0x000003700000 : "ubi0"
[    2.064567] 0x000003700000-0x000005f00000 : "ubi1"
[    2.099415] 0x000005f00000-0x000006500000 : "misc_rw_bak"
[    2.109637] 0x000006500000-0x000006b00000 : "bflag"
[    2.119211] 0x000006b00000-0x000007100000 : "misc_isp"

This partition is loaded using the preinit scripts.
And on caldata script it is linking the correct file:

And then the firmware is loaded via:

Now please note the dd in there, this was my last attempt to see if it was due to the file being too bit to be loaded on the reserved memory. But even by directly linking the file the error was the same.

What I wasn't expecting was the same failure even with built-in eeprom firmware from the Openwrt packages. I was expecting low performance, not working wireless but not a firmware load error.

Full device tree:

Full bootlog:

Edit: I probably had a brain-fart with the EEPROM. The only issue I keep having is the PHY.

While working on the VX830V port, I've hit a limitation with the current OpenWrt mainline implementation regarding the onboard 2.5 GbE LAN interface.

At the moment, achieving a functional 2.5 GbE LAN port with upstream OpenWrt and the default build configuration (i.e., without any device-specific customizations) appears to be impossible.

The root cause seems to be that DSA does not support deferred loading of PHY drivers. The Airoha EN8811H PHY must have its MCU firmware running before it can correctly respond to Clause 45 (C45) MDIO queries. Since the MT7530 switch is initialized before the PHY firmware is loaded, device probing fails.

The current options being evaluated are summarized below:

Option Description Pros Cons
A Embed the EN8811H PHY driver and firmware directly into the kernel image. Keeps the current initialization order intact and works reliably. Requires a custom kernel configuration for the VX830V and prevents shipping fully functional images through Image Builder or Attended Sysupgrade.
B Build mt7530 as a kernel module (=m), package it as kmod-mt7530, and load it after the PHY driver during boot. Allows the PHY firmware to be initialized before DSA probes the switch. Affects all devices in the Filogic target by changing the switch driver from built-in to modular.

Option A

Build the PHY driver into the kernel and embed the required firmware:

CONFIG_AIR_EN8811H_PHY=y
CONFIG_EXTRA_FIRMWARE="airoha/EthMD32.dm.bin airoha/EthMD32.DSP.bin"
CONFIG_EXTRA_FIRMWARE_DIR="$(TOPDIR)/firmware"

This approach works, but it introduces a device-specific kernel configuration. As a result, a fully working image cannot be generated using Image Builder or distributed through Attended Sysupgrade without additional customization.

Option B

Convert the mt7530 driver from built-in to a module:

CONFIG_NET_DSA_MT7530=m

The idea would be to:

  1. Remove mt7530 from the kernel binary.
  2. Create a dedicated kmod-mt7530 package.
  3. Ensure the EN8811H PHY driver and firmware are loaded first.
  4. modprobe the MT7530 module later in the boot sequence.

This would allow the EN8811H MCU firmware to be running before DSA attempts to enumerate the switch and issue C45 queries.

However, this solution impacts every device in the Filogic target, as all of them would inherit the change from a built-in switch driver to a modular one.

At this point, neither option is ideal:

  • Option A introduces a VX830V-specific kernel configuration and breaks the standard OpenWrt image generation workflow.
  • Option B provides a cleaner runtime sequence but has broader implications for the entire Filogic platform.

Unless DSA gains support for deferred PHY probing/loading, or the EN8811H driver can initialize its firmware earlier in the boot process, the VX830V's 2.5 GbE LAN support will likely remain dependent on one of these workarounds.

Feedback and alternative approaches are welcome, especially from anyone familiar with DSA initialization ordering or prior EN8811H integrations.

While working on the port of the EX8601 @daniel was the PHY guy so he might have some ideas.