Skip to content

The XGS 136

Measured on a Sophos XGS 136. Where a fact is known to generalise across the range it says so; where it is not, assume it does not. This page is the appliance as an object: what it is, what FreeBSD sees of it, how to tell the board from software, the fourteen ports, and the board photographed part by part. The driver it runs is contrib/npuep, and the protocols that driver speaks are the pages under npuep/.

What it is

Two computers in one box, like the rest of the range:

host         AMD Ryzen Embedded R1606G (x86), 4 CPUs, 8 GB, a SATA drive on M.2, OPNsense on it
coprocessor  Marvell CN9131 (AP807 + two CP115, ARM), its own Linux, its own eMMC
link         PCIe 11ab:7080, Gen3 x4: BAR0 1 MB, BAR2 16 MB, BAR4 16 MB; MSI-X 16; 6 VFs
front        fourteen ports: labels 1 to 8 behind an 88E6193X switch, F1 and F2 on the same
             switch, labels 9 to 12 on an AQR412C quad PHY - all behind the coprocessor
assembly     AMDA0201-0003 inside the SMBIOS serial; AMDA0201 in the USB bridge's EEPROM

Where each part is written up

part page
getting the coprocessor out of reset, over the USB-to-SPI bridge npuep/npu-bring-up.md
what the coprocessor publishes into its BARs, and the handshake npuep/facility-protocol.md
mvmgmt0, the management link npuep/mvmgmt.md
the datapath that carries the fourteen ports, and its header npuep/giu.md
the control channel and the forwarding tables npuep/rpc.md
per-port state: link, media, address npuep/netagent.md
the family, and what has run on which board families/armada.md
the three parts and the channels, drawn the-road.md
the photographs images/hardware/xgs136/
measurements none from this appliance yet; measurements/ says so

What FreeBSD sees on the host

Working with no driver work at all:

CPU    AMD Ryzen Embedded R1606G, 4 CPUs (1 package x 2 cores x 2 threads)
RAM    8192 MB
Disk   ahci0 -> ada0, SATA 3.x
USB    xhci0, USB 3.0
SMBus  intsmb0 -> smbus0 (AMD FCH)      the I2C path to the SFP cages and the PoE controller
HID    Microchip MCP2210 USB to SPI Master -> usbhid0 -> hidbus0
serial uart0 0x3f8 (console) and uart2 0x3e8 (the NPU's console, needs a hint)

Not working, and it is the whole reason this repository exists:

pci1: <network, ethernet> at device 0.0 (no driver attached)

There is also no superio, so the NCT6779D hardware monitor - which the BIOS reads perfectly well - is invisible to a stock FreeBSD. That is a separate piece of work.

The way in before the ports: a USB network adapter

Until npuep brings the front ports up, the host has no network of its own: every port belongs to the coprocessor, and pci1 above is the only network device on the bus. So the first network this appliance had under OPNsense was a USB Ethernet adapter - and it stays the one way in that does not depend on the coprocessor at all, which is exactly what a driver under development needs. porting-notes.md says why it is worth reaching for one early.

The one in use here, after several were tried:

The WAVLINK WL-NWU330GCA USB to 2.5G Ethernet adapter Its label: WL-NWU330GCA, Rev.a, the serial number pixelated
maker WAVLINK - the product page
model WL-NWU330GCA, Rev.a
host side USB 3.2 at 5 Gbps, on a hybrid cable: USB-C, with a USB-A adapter tethered to it
network side one RJ45, 10/100/1000 Mbit/s and 2.5 Gbit/s; the light green at 2.5G and amber below it
chip a Realtek RTL8156, by the retailers' listings - RTL8156B on one, RTL8156 on another; the maker's page does not name it
under FreeBSD ure(4), in the stock kernel, which lists the RTL8156, RTL8156B and RTL8156BG at up to 2,500 Mbit/s; the adapter appears as a ue interface with nothing to install

Two identical adapters are one too many. With two of the same model on this appliance - LAN on one, WAN on the other - the two traded names across a warm reboot, and the box served its LAN address on the WAN cable and asked for an address on the LAN one: healthy, and unreachable. It looks exactly like a reboot that hung. Both adapters report the same USB serial number from the factory, so nothing but the root-hub port each sits in tells them apart, and FreeBSD's ue numbering does not follow the port. One adapter has nothing to swap with.

Other adapters whose chip FreeBSD names

Not tested here. Each is listed because its maker's own page names the chip and a FreeBSD driver in the stock kernel lists that chip; the photographs are on the makers' pages.

adapter the chip, as its maker states it speed FreeBSD driver maker's page
Plugable USBC-E2500 Realtek RTL8156B 2.5 Gbit/s ure(4) plugable.com
TP-Link UE300 Realtek RTL8153 1 Gbit/s ure(4) tp-link.com

For a gigabit adapter on an ASIX chip the driver is axge(4), which lists the AX88179, AX88179A and AX88178A; a phone or anything else that presents itself as a standard CDC network device is cdce(4).

The same product name can hide a new chip. Retail listings of Plugable's USB3-E1000 name an ASIX AX88179; the maker's page now names the AX88179B, which axge(4) does not list, and Plugable itself does not recommend that adapter for FreeBSD or pfSense. Check the chip on the maker's page, and once it is plugged in, check what usbconfig and dmesg say attached, before trusting an adapter with a firewall's only way in.

The endpoint

pci0:1:0:0   vendor=0x11ab device=0x7080   class=network/ethernet
  bar[10]  1 MB    64-bit
  bar[18]  16 MB   64-bit
  bar[20]  16 MB   32-bit
  PCIe     x4 @ 8.0 GT/s (Gen3)
  MSI      32 messages;  MSI-X 16 messages, table in BAR0 @0x1000, PBA @0x1800
  SR-IOV   VF device ID 0x7081, 6 VFs supported
  ARI, AER, LTR, TPH Requester, Resizable BAR, L1 PM Substates

The link is Gen3 x4, about 32 Gbit/s. All fourteen front ports together are about 17 Gbit/s at most - eight switch ports and labels 9 and 10 at 1G, labels 11 and 12 at 2.5G, and the two SFP cages at 1G - so the roughly 936 Mbps single-port ceiling reported by other projects on this hardware is not a PCIe bandwidth limit, and neither is an MTU of 1500. Whatever causes them is above the bus.

The SR-IOV capability reports 6 VFs where the vendor's Linux exposes 8 in sysfs. Unresolved, and recorded because it is the sort of discrepancy that wastes a day later.

Identifying the board from software

Two independent sources, and the second is the more useful one.

SMBIOS is awkward. smbios.planar.product is the generic string XGS across the whole range and smbios.planar.version is not the model either. The assembly number is buried inside smbios.planar.serial, in the form:

NEAAMDA0201-00xxxxxxxxxx
   ^^^^^^^^^^^^
   AMDA0201-0003 = Desktop XGS 136

So anything keying a chassis table off SMBIOS has to match on the serial, not on product or version - and the serial also carries the unit's own identity, which is worth remembering before putting it in a log.

The MCP2210's EEPROM is better for this purpose. Bytes 0 and 1 hold the assembly number as (byte0 << 8) | byte1, so 0x00, 0xC9 is 201, which is AMDA0201. It is on the host side, needs no I2C, and answers while the coprocessor is held in reset.

The coprocessor

SoC       Marvell CN9131  (AP807 + two CP115)
storage   its own eMMC, 7.28 GiB, four partitions, root on p3
firmware  U-Boot 2019.10-10.22.03, Linux 4.14.207-10.22.03
model     the kernel reports "Sophos XGS126/136" - one board for both
cmdline   console=ttyS0,115200n8 root=/dev/mmcblk0p3 cpuidle.off=1
          isolcpus=1-3 nohz_full=1-3 rcu_nocbs=1-3

The CN9131's second CP115 is what lets this board drive fourteen ports where the nine-port model in the same family uses a CN9130.

Three cores are isolated from the scheduler and run the dataplane; that is what isolcpus=1-3 is for.

The coprocessor boots from its own storage, not from the host's disk. Replacing the host SSD

  • which is what running OPNsense on one of these means - does not touch its firmware at all, and that is what makes the whole exercise reversible.

The port map

Fourteen ports, all behind the coprocessor. The switch is an 88E6193X LinkStreet; the multi-gig ports are on an AQR412C quad PHY.

labels 1-8   ->  switch ports 1-8      (88E6193X, CPU port is port 0)
label 9      ->  CN9131 COMPHY 2       (AQR412C address 0, 1G)
label 10     ->  CN9131 COMPHY 4       (AQR412C address 1, 1G)
label 11     ->  CN9131 COMPHY 5       (AQR412C address 2, 2.5G + PoE)
label 12     ->  CN9131 COMPHY 3       (AQR412C address 3, 2.5G + PoE)
F1, F2       ->  switch ports 9, 10    (SFP)

Each port takes one offset from the board's base MAC, in that order.

The device tree is not where this map lives, which is worth knowing before going looking for it there. Neither the 9130 nor the 9131 device tree contains a switch node, a DSA node, an AQR412C node or any PHY child: both MDIO controllers per CP are declared empty and handed to userspace. The map comes from a platform text file in the coprocessor's firmware plus the bootloader environment.

The XGS 136's fourteen front ports, end to end

The board, photographed

Photographed on 2026-10-11, the XGS 136 out of its case. Everything above was read over a wire or out of a file; this is the same board, and the pictures put a part under each of those readings. Serial numbers, barcodes and the storage's label are pixelated with tools/blur-labels.py; part markings and reference designators are left, because they describe the design and not this unit. The private-data checker cannot read a photograph, so that tool is the only gate. The photographs of each appliance are in a folder of their own under docs/images/.

The XGS 136 from above, with its parts numbered

1 the host's two SO-DIMMs 9 AQR412C, the PHY behind labels 9 to 12
2 the host's M.2 SATA drive 10 the SFP cages, F1 and F2
3 AMD Ryzen, the host 11 the eight copper ports, labels 1 to 8
4 CN9130, the coprocessor, under its lid 12 labels 9 to 12, two of them with PoE
5 the coprocessor's four DDR4 chips 13 the PoE transformer
6 NCT6779D, the Super I/O 14 the console and USB at the back
7 the coprocessor's heatsink 15 the BIOS flash, under the AMIBIOS sticker
8 88E6193X, the switch behind labels 1 to 8 and the cages

The numbers are placed by eye on the photograph; each part is named from its marking in the close-ups below, and tied to what software sees where the sections above say so.

The XGS 136, part by part

The XGS 136 from above

The same board unmarked. The assembly's label is at the bottom right; AMDA0201 is what the EEPROM says and what the sections above read.

The XGS 136 from below

From below: no active part of note - the two black bars are the DIMM and M.2 retainers' backs - and the assembly barcode at the top left, pixelated.

The assembly label

The label and the silkscreen beside it: XGS 136w VER:C, assembled in Taiwan.

The CN9130 and its memory

The coprocessor: Marvell CN9130-2200, with four SK hynix H5AN8G6NCJ DDR4 chips around it. The kernel on it reports a CN9131, which is a CN9130 with a second CP115 - and that second part is the next photograph.

The second Marvell part

Marked 88F8215-A0, beside an 8-pin Atmel part (U25, an EEPROM by its package and marking). The port map above puts labels 9 to 12 on CN9131 COMPHY lanes that a bare CN9130 does not have; this is the part that has them. Read from the marking and the port map, not from a datasheet.

The AQR412C

Marvell AQrate AQR412C-B0-C: the quad multi-gig PHY behind labels 9 to 12, two of them at 2.5G with PoE. The crystal beside it is U19.

The 88E6193X

Marvell 88E6193X-BXB2, the LinkStreet switch behind labels 1 to 8 and the two SFP cages (ports 9 and 10 on the switch). The same part as the XGS 3300's, reached there over the coprocessor's MDIO - see the OCTEON TX peripherals.

The host CPU

The host: AMD Ryzen Embedded, which FreeBSD reports as an R1606G. Its lot code and matrix are pixelated.

The Nuvoton NCT6779D

Nuvoton NCT6779D, U35: the Super I/O whose hardware monitor the BIOS reads and a stock FreeBSD does not, as the first section says. It is the chip os-fanctl knows a table for and could not find on this board for want of superio(4) - which this photograph settles: it is there.

The BIOS flash and the serial label

BIOS1, an 8-pin SPI flash beside a second footprint BIOS1(1) that is not fitted; the AMIBIOS sticker; the assembly's serial barcode, pixelated; and the host's M.2 socket above with its screw post, its designator cut by the photograph's edge. The heatsink at the right is the coprocessor's.

The RS-232 transceiver

TI TRS213I, U65: the RS-232 transceiver on the host's console. The coprocessor's own console is the host's third UART, at 115200, and needs a hint; see the first section.

The PoE controller

U40, marked PD6910481: by that marking a Microchip PD69104, a four-port PoE controller - the part behind the "2.5G + PoE" of labels 11 and 12, and what the SMBus path to the PoE controller in the first section reaches. Identified from the marking only.

The eMMC

SanDisk SDINBDG4-8G, U53: an 8 GB eMMC. The coprocessor boots from its own storage - 7.28 GiB in four partitions, as above - and this is the part of that size on the board.

DDR4 and JP12

One of the coprocessor's DRAMs, with JP12, a four-pin header, and JP13 and JP14 at the board's edge. Which of them is the coprocessor's console header was not traced; the XGS 3300 has the same question answered on its page.

CN8, JP11 and a flash

CN8, an M.2 socket with nothing in it - corrected on 2026-10-18, from this photograph and the vendor's own material:

  • The white socket is a Mini PCIe socket, not M.2, and it is empty. Its contacts run eight before the key, then from the silkscreen's 17 to its 51: the 52-pin layout of a PCI Express Mini Card, keyed after pin 15. An M.2 socket has 75 positions and its keys elsewhere. Its own designator is cut off at the photograph's left edge - only CN shows.
  • CN8 is the black connector along the bottom of the photograph. Its silkscreen numbers a row B1 to B32, as a PCIe card edge with 32 contacts a side is numbered, and it sits at the edge directly above the expansion bay. By its position it is the bay's connector - the one expansion slot the vendor's datasheet lists, for a 3G/4G or 5G module, an SFP DSL module or, on a w model, a second Wi-Fi radio. Not traced.
  • What the Mini PCIe socket is for. This board's label reads XGS 136w, and the vendor's datasheet gives the w models an integrated Wi-Fi 5 radio, 3x3, with three external antennas - the kind of radio that comes on a Mini PCIe card. Under the vendor's own system on this unit, the host's PCI bus showed nothing but the coprocessor and no radio or modem driver was loaded, so the socket was empty then as well. The vendor's system carries ath10k and mt7915e for its radios, and its modem daemon finds a modem by its USB identity (expansion-modules.md).
  • The datasheet's integrated 64 GB SSD is the host's M.2 SATA drive - 2 on the numbered photograph above. That is the board's one M.2 socket in these photographs.

JP11, a two-by-four header, and U12, an 8-pin SPI flash (Macronix by its marking), sit beside the Mini PCIe socket. Not traced.

J1, J2 and the LEDs

At the front edge: J1, a four-pin header, J2, a four-pad footprint, and the front LEDs LED25 to LED27 with their drivers. Not traced.

The markings, in one table

part marking as photographed designator what it is read from
the assembly XGS 136w VER:C; AMDA0201 on the label - the board, assembled in Taiwan the label; the EEPROM and the SMBIOS serial say the same
the coprocessor Marvell CN9130-2200 - the coprocessor; the kernel on it reports a CN9131 software, confirmed by the marking
the coprocessor's DRAM SK hynix H5AN8G6NCJ, four - DDR4 around the coprocessor marking
the second Marvell part 88F8215-A0 - the second CP115 that makes the CN9131 of a CN9130 the marking and the port map; not a datasheet
an 8-pin Atmel part Atmel U25 an EEPROM package and marking only
the quad PHY Marvell AQrate AQR412C-B0-C - behind labels 9 to 12 the platform file, confirmed by the marking; crystal U19
the switch Marvell 88E6193X-BXB2 - behind labels 1 to 8 and the cages the platform file, confirmed by the marking
the host AMD Ryzen Embedded - the R1606G FreeBSD reports software, confirmed by the marking
the Super I/O Nuvoton NCT6779D U35 the hardware monitor a stock FreeBSD cannot see the BIOS reads it; the marking confirms it is there
the BIOS flash an 8-pin SPI flash, AMIBIOS sticker BIOS1; BIOS1(1) not fitted the host's firmware marking and silkscreen
the console transceiver TI TRS213I U65 RS-232 on the host's console marking
the PoE controller PD6910481 U40 a Microchip PD69104, four ports, behind labels 11 and 12 the marking only
the eMMC SanDisk SDINBDG4-8G U53 8 GB; the coprocessor's root is on it software (7.28 GiB, root on p3), confirmed by the marking
a SPI flash Macronix U12 beside the empty M.2 socket CN8 Mini PCIe socket marking; not traced
the Mini PCIe socket 52 contacts, keyed after pin 15, silkscreen 17 and 51 CN, the digit cut off empty; on a w board, the place of the integrated Wi-Fi 5 radio the datasheet gives the photograph and the datasheet; not traced
the expansion bay's connector a row numbered B1 to B32 CN8 the one expansion slot, by its position above the bay silkscreen and position; not traced
headers JP11 (2x4), JP12 (4 pins), JP13, JP14, J1 (4 pins), J2 (4 pads) - the coprocessor's console header is one of them silkscreen; not traced
the front LEDs LED25 to LED27 - the front indicators and their drivers silkscreen; not traced

What the vendor's own tools tell you

Useful mostly as a map of what is reachable and from where. Roughly half of the xgs-* tools on the host are seven-line shell wrappers that ssh to the coprocessor over the management link - which this repository's driver now brings up, so what limits them is the SFOS userland they expect on the far side, not the link. The rest run on the host.

Two are worth naming:

  • The USB-SPI flash tool is the one this repository's reset path is derived from. It also reads and writes the coprocessor's boot flash from the host, which means a bricked bootloader is recoverable without opening the case.
  • The platform-init tool is not a bring-up tool despite the name. It probes I2C busses 0-7 at address 0x57 for the baseboard VPD EEPROM and builds a key-value database that everything else reads. FreeBSD has smbus0 on this board, so that database can be rebuilt natively - it is where the per-port MAC addresses, PHY labels and transceiver configuration come from.

The XGS 3300, the other appliance here, has its own page: xgs3300.md.

Discussion

The discussion of this page is held in the project's GitHub Discussions. Showing it here loads giscus from giscus.app and GitHub, and writing in it needs a GitHub account - what that means.