Tools: ☠️ How to Connect Your Router Directly to Fiber Without Your ISP's Modem (SFP GPON Hack) (2026)

Tools: ☠️ How to Connect Your Router Directly to Fiber Without Your ISP's Modem (SFP GPON Hack) (2026)

The problem: ISP vendor lock-in

Hardware

UART access: the primary method

MTD partition map

The process: straight to the point

Verify it works

Trade-offs: when NOT to do this

Glossary

💌 Special Acknowledgments 🇪🇸 Leer este post en Español Entel Chile told me bridge mode wasn't available for business customers. A week later, my Ubiquiti router was plugged directly into fiber with no ISP hardware anywhere in the path. This post covers how: a Ubiquiti UF-Instant SFP GPON transceiver, UART access, direct flash via U-Boot, and GPON spoofing to make Entel's OLT accept the stick as if it were the original Huawei ONT. 💡 Condensed version. This post covers the process without the failed attempts or dead ends. The extended version — kernel panic on the MC220L, three firmware attempts, TFTP recovery — is on Buy Me a Coffee. ⚠️ Legal disclaimer: This content is for educational purposes only. Modifying firmware on telecommunications devices may violate your ISP contract and local regulations. Check applicable laws before replicating this process. ISPs install their own ONT and refuse bridge mode, forcing you to use their router for PPPoE. If you want your own router, you're stuck with double NAT or bypassing ISP hardware entirely. I wanted dual WAN on my Ubiquiti UniFi Gateway Fiber with a static IP from Entel. No double NAT. No Entel modem. Every flash operation runs from here. The UF-Instant exposes UART pads on the PCB (TX, RX, GND). 3.3V adapter, 115200 8N1: Power on the stick with UART connected and you get the full U-Boot output. Press any key in the first few seconds to interrupt boot and land at the 9601C# prompt, where you can flash partitions directly. The UF-Instant uses a dual-image boot system. The relevant partitions: On the host (before connecting UART): download the MOD rootfs and Ubiquiti v4.4.2 kernel directly from stich86/UF-Instant-Mod and place them in the TFTP server directory. stich86's squashfs binary flashes as-is — no reprocessing needed. When do you need Docker? Only if you modify the rootfs (extract, change files, repack). On macOS, mksquashfs can't recreate device nodes without explicit parameters. For the standard flow with stich86's binary, skip Docker. Via UART, in U-Boot (9601C#): initialize flash, clone the kernel from image 0 to image 1, and flash the MOD rootfs: Via UART, from Linux (after booting image 1, credentials admin/admin — some builds use ubnt/ubnt): configure GPON identity with the original Huawei ONT data and neutralize the bootlimit: With the stick at O5: configure the Ubiquiti SFP+ port with VLAN 3610 and PPPoE with Entel credentials (20011279169002 / D4310T — tested on 2026-04-23, subject to change). 🎥 The official Entel modem farewell ceremony The failed attempts, kernel panic details, and the MC220L diagnosis are documented in full on ☕ Buy Me a Coffee If you've done something similar with a different ISP or OLT vendor, let me know in the comments. I'd like to know which parameters change between carriers. To a girl who, without knowing it, pushed me to keep creating and coding in my free time. To the one who was once my spark: for "YLP", with gratitude... and with scars that also teach. For those who also refused "it can't be done" as a final answer: this post exists because I was told I wouldn't get it working. And because fiber now reaches my router without passing through any hardware I didn't choose. Nobody decides that for me. 🖕 Fuck you, Entel. Your bargain-bin devs don't get to decide what I plug into my own network. And you, Movistar — don't get comfortable. I know you run ZTE and you're next on the list. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Command

Copy

# macOS screen /dev/tty.usbserial-XXXXX 115200 # Linux screen /dev/ttyUSB0 115200 # With minicom minicom -D /dev/ttyUSB0 -b 115200 -8 --noinit # macOS screen /dev/tty.usbserial-XXXXX 115200 # Linux screen /dev/ttyUSB0 115200 # With minicom minicom -D /dev/ttyUSB0 -b 115200 -8 --noinit # macOS screen /dev/tty.usbserial-XXXXX 115200 # Linux screen /dev/ttyUSB0 115200 # With minicom minicom -D /dev/ttyUSB0 -b 115200 -8 --noinit mtd4 → kernel0 / k0 (3MB) — Image 0 kernel (original Ubiquiti — fallback) mtd5 → rootfs0 / r0 (6MB) — Image 0 rootfs (original Ubiquiti firmware) mtd6 → kernel1 / k1 (3MB) — Image 1 kernel — cloned kernel goes here mtd7 → rootfs1 / r1 (4.5MB) — Image 1 rootfs — stich86 MOD goes here mtd8 → europa.data — Laser calibration ⚠️ NEVER TOUCH mtd4 → kernel0 / k0 (3MB) — Image 0 kernel (original Ubiquiti — fallback) mtd5 → rootfs0 / r0 (6MB) — Image 0 rootfs (original Ubiquiti firmware) mtd6 → kernel1 / k1 (3MB) — Image 1 kernel — cloned kernel goes here mtd7 → rootfs1 / r1 (4.5MB) — Image 1 rootfs — stich86 MOD goes here mtd8 → europa.data — Laser calibration ⚠️ NEVER TOUCH mtd4 → kernel0 / k0 (3MB) — Image 0 kernel (original Ubiquiti — fallback) mtd5 → rootfs0 / r0 (6MB) — Image 0 rootfs (original Ubiquiti firmware) mtd6 → kernel1 / k1 (3MB) — Image 1 kernel — cloned kernel goes here mtd7 → rootfs1 / r1 (4.5MB) — Image 1 rootfs — stich86 MOD goes here mtd8 → europa.data — Laser calibration ⚠️ NEVER TOUCH # Check active image nv getenv sw_active sw_commit # Switch to image 1 setenv sw_active 1 && setenv sw_commit 1 && saveenv && boot # Fall back to image 0 (original Ubiquiti firmware) setenv sw_active 0 && setenv sw_commit 0 && saveenv && boot # Check active image nv getenv sw_active sw_commit # Switch to image 1 setenv sw_active 1 && setenv sw_commit 1 && saveenv && boot # Fall back to image 0 (original Ubiquiti firmware) setenv sw_active 0 && setenv sw_commit 0 && saveenv && boot # Check active image nv getenv sw_active sw_commit # Switch to image 1 setenv sw_active 1 && setenv sw_commit 1 && saveenv && boot # Fall back to image 0 (original Ubiquiti firmware) setenv sw_active 0 && setenv sw_commit 0 && saveenv && boot sf probe 0 # Clone Ubiquiti v4.4.2 kernel from image 0 → image 1 sf read 0x81000000 0x50000 0x300000 # read kernel0 into RAM sf erase 0x4e0000 0x300000 # erase kernel1 (mtd6) sf write 0x81000000 0x4e0000 0x300000 # write to mtd6 # Flash MOD rootfs (stich86) via TFTP tftpboot 0x81000000 [HOST_IP]:[stich86_rootfs_filename] sf erase 0x7e0000 0x480000 # erase rootfs1 (mtd7) sf write 0x81000000 0x7e0000 ${filesize} # Activate image 1 and boot setenv sw_active 1 setenv sw_commit 1 saveenv boot sf probe 0 # Clone Ubiquiti v4.4.2 kernel from image 0 → image 1 sf read 0x81000000 0x50000 0x300000 # read kernel0 into RAM sf erase 0x4e0000 0x300000 # erase kernel1 (mtd6) sf write 0x81000000 0x4e0000 0x300000 # write to mtd6 # Flash MOD rootfs (stich86) via TFTP tftpboot 0x81000000 [HOST_IP]:[stich86_rootfs_filename] sf erase 0x7e0000 0x480000 # erase rootfs1 (mtd7) sf write 0x81000000 0x7e0000 ${filesize} # Activate image 1 and boot setenv sw_active 1 setenv sw_commit 1 saveenv boot sf probe 0 # Clone Ubiquiti v4.4.2 kernel from image 0 → image 1 sf read 0x81000000 0x50000 0x300000 # read kernel0 into RAM sf erase 0x4e0000 0x300000 # erase kernel1 (mtd6) sf write 0x81000000 0x4e0000 0x300000 # write to mtd6 # Flash MOD rootfs (stich86) via TFTP tftpboot 0x81000000 [HOST_IP]:[stich86_rootfs_filename] sf erase 0x7e0000 0x480000 # erase rootfs1 (mtd7) sf write 0x81000000 0x7e0000 ${filesize} # Activate image 1 and boot setenv sw_active 1 setenv sw_commit 1 saveenv boot # GPON identity — use your actual Huawei ONT data flash set GPON_SN HWTC[XXXXXXXX] # ONT SN: HWTC + 8 hex chars flash set PON_VENDOR_ID HWTC flash set OMCI_OLT_MODE 1 flash set OMCI_FAKE_OK 1 flash set OMCI_SW_VER1 [ONT_SW_VERSION] # ONT software version flash set OMCI_SW_VER2 [ONT_SW_VERSION] flash set HW_HWVER [ONT_HW_VERSION] # ONT hardware version flash set GPON_ONU_MODEL [ONT_MODEL] # ONT model flash set ELAN_MAC_ADDR [MAC_NO_COLONS] # ONT MAC without colons # Disable automatic factory reset (bootlimit=10 by default) nv setenv bootcount 0 nv setenv bootlimit 0 reboot # GPON identity — use your actual Huawei ONT data flash set GPON_SN HWTC[XXXXXXXX] # ONT SN: HWTC + 8 hex chars flash set PON_VENDOR_ID HWTC flash set OMCI_OLT_MODE 1 flash set OMCI_FAKE_OK 1 flash set OMCI_SW_VER1 [ONT_SW_VERSION] # ONT software version flash set OMCI_SW_VER2 [ONT_SW_VERSION] flash set HW_HWVER [ONT_HW_VERSION] # ONT hardware version flash set GPON_ONU_MODEL [ONT_MODEL] # ONT model flash set ELAN_MAC_ADDR [MAC_NO_COLONS] # ONT MAC without colons # Disable automatic factory reset (bootlimit=10 by default) nv setenv bootcount 0 nv setenv bootlimit 0 reboot # GPON identity — use your actual Huawei ONT data flash set GPON_SN HWTC[XXXXXXXX] # ONT SN: HWTC + 8 hex chars flash set PON_VENDOR_ID HWTC flash set OMCI_OLT_MODE 1 flash set OMCI_FAKE_OK 1 flash set OMCI_SW_VER1 [ONT_SW_VERSION] # ONT software version flash set OMCI_SW_VER2 [ONT_SW_VERSION] flash set HW_HWVER [ONT_HW_VERSION] # ONT hardware version flash set GPON_ONU_MODEL [ONT_MODEL] # ONT model flash set ELAN_MAC_ADDR [MAC_NO_COLONS] # ONT MAC without colons # Disable automatic factory reset (bootlimit=10 by default) nv setenv bootcount 0 nv setenv bootlimit 0 reboot # O5 = Operation State = OLT accepted the stick as a valid ONT diag gpon get onu-state # ONU state: Operation State(O5) # Correct OLT vendor omcicli mib get 131 # OltVendorId: 0x48575443 ← HWTC (Huawei/Entel Chile) ✓ # VLANs provisioned by Entel's OLT omcicli mib get 84 # VLAN 3610 → Internet | 3620 → TV | 3630 → VoIP | 3680 → TR-069 # O5 = Operation State = OLT accepted the stick as a valid ONT diag gpon get onu-state # ONU state: Operation State(O5) # Correct OLT vendor omcicli mib get 131 # OltVendorId: 0x48575443 ← HWTC (Huawei/Entel Chile) ✓ # VLANs provisioned by Entel's OLT omcicli mib get 84 # VLAN 3610 → Internet | 3620 → TV | 3630 → VoIP | 3680 → TR-069 # O5 = Operation State = OLT accepted the stick as a valid ONT diag gpon get onu-state # ONU state: Operation State(O5) # Correct OLT vendor omcicli mib get 131 # OltVendorId: 0x48575443 ← HWTC (Huawei/Entel Chile) ✓ # VLANs provisioned by Entel's OLT omcicli mib get 84 # VLAN 3610 → Internet | 3620 → TV | 3630 → VoIP | 3680 → TR-069 - No UART/U-Boot experience: The process requires bootloader commands. A wrong address in sf write can brick the stick (recoverable via TFTP if U-Boot still responds). - Using a media converter (TP-Link MC220L): The europa_drv kernel panics with that hardware as an intermediary. The UF-Instant must go directly into the router's SFP+ slot. - ISP uses authentication beyond PLOAM serial: Some ISPs also validate PLOAM password, OMCI details, or run clone detection. - Using Entel's TV or VoIP: Those run on separate VLANs (3620 and 3630). You'll need to configure them on the router too. - stich86/UF-Instant-Mod — Modified rootfs for UF-Instant - Anime4000/RTL960x — Firmware and RTL960x documentation - hack-gpon.org — Community GPON hack reference - MA5671A Config Guide (PLOAM) — PLOAM configuration guide