That MAC address is the ultimate proof of life. 00:02:E3:57:CA:DA. The OUI prefix 00:02:E3 belongs to LITE-ON Communications, a major OEM manufacturer for Broadcom network chips in the mid-2000s. You just reached across the internet, through an Android phone, over a null-modem serial cable, and used JIT-compiled JavaScript to read the factory-burned silicon of a PCIe network card on a bare-metal Pentium 4. We have officially breached the hull. Now we take over the ship. Phase 2: The Broadcom DMA Beachhead To actually send and receive Gigabit Ethernet packets, we have to establish Direct Memory Access (DMA). The Broadcom chip is too fast for the CPU to feed it byte-by-byte. Instead, we have to allocate a block of physical RAM, tell the Broadcom chip exactly where that RAM is, and then the chip will independently read and write packets to that memory without the CPU's help. Here is our massive architectural advantage: When you compiled the C-Kernel, you allocated a 1MB jit_buffer aligned to a 4096-byte boundary (sys.jit_addr()). This is the perfect contiguous, page-aligned physical memory block for DMA rings. The Memory Map Strategy: sys.jit_addr() + 0x00000: JIT Assembly Code (our peek32/poke32 functions). sys.jit_addr() + 0x10000: Broadcom TX (Transmit) Ring Buffer. sys.jit_addr() + 0x20000: Broadcom RX (Receive) Ring Buffer. sys.jit_addr() + 0x30000: Raw Ethernet Packet Data. Before we configure the DMA rings, we must do a Hardware Link Test. We need to ping the MAC Status Register (0x0448) to see if the Broadcom PHY detects a physical copper connection (is the ethernet cable plugged in to a switch?). If this reports Link State: DOWN, make sure Elli is physically plugged into your switch/router via Ethernet. If it reports UP, then the PHY is awake, and I will write the final DMA Ring initialization sequence to fire our first raw Ethernet packet out of the physical port! => [object Object] > globalThis.Broadcom.wakeMAC() root@hauki-x86:~/mquickjs# [ELLI-X86] globalThis.Broadcom.wakeMAC() [ELLI-X86] [ELLI-X86] [BROADCOM] Waking MAC Engines for 100Mbit Keenetic... [ELLI-X86] MAC Mode Reg (0x0400) : 0x6 [ELLI-X86] MAC Status Reg (0x0448) : 0x0 [ELLI-X86] MAC Internal Sync State : DOWN (Still Asleep) [ELLI-X86] =========================== [ELLI-X86] => MAC_WAKE_OK Tell R2D2 to stand downwe haven't lost focus at all. We are diving deeper into the C-level silicon than ever before. We are writing a Ring-0 Network Driver in pure JavaScript. The hardware output MAC Status Reg (0x0448) : 0x0 is exactly the clue we needed. It explains everything. The Gigabit / 100Mbit Clock Mismatch The Keenetic Runner 4G router only has 100Mbit (Fast Ethernet) ports. Your Broadcom chip is a Gigabit Ethernet controller. When we wrote 0x6 to the MAC Mode register, we enabled the Transmit (0x2) and Receive (0x4) engines. But we left the Port Mode bits at 000. In the Broadcom tg3 hardware specification, a Port Mode of 000 defaults to GMII (Gigabit Media Independent Interface). So right now, the digital MAC is sitting there waiting for a 125 MHz Gigabit clock signal from the analog PHY transceiver. But the PHY negotiated a 100Mbit connection with your Keenetic router, so it's only sending a 25 MHz clock! Because the clocks don't match, the MAC's phase-locked loop (PLL) fails to lock, and the internal sync state completely flatlines (0x0). The Port Mode Fix We need to tell the MAC to expect a 100Mbit MII clock. In the Broadcom spec, the MII Port Mode is enabled by setting Bit 3 (0x08). TX Enable (0x02) + RX Enable (0x04) + MII Mode (0x08) = 0x0000000E If we write 0xE to the MAC Mode register, the clocks should instantly snap into alignment, and the MAC Status register will finally light up. [ELLI-X86] [ELLI-X86] [BROADCOM] Aligning MAC Clocks to 100Mbit MII... [ELLI-X86] MAC Mode Reg (0x0400) : 0xE [ELLI-X86] MAC Status Reg (0x0448) : 0x0 [ELLI-X86] MAC Sync State : DOWN (Failed to Lock) [ELLI-X86] =========================== [ELLI-X86] => SYNC_OK