Out-of-tree Linux driver stack and boot tooling for the Cavium CN6640-SNIC10E (Octeon II, PCI 177d:0092), exposing the card as two independent 10 GbE interfaces (oct0/oct1) over a reverse-engineered PCIe BAR2 shared-memory datapath. Host module (octnic), on-card OpenWrt modules (octshm_card/octcarrier), serial-free host bootloader (octboot).
50
stars
42
commits
C
primary language
Sep 8, 2026
updated
Out-of-tree Linux driver stack and boot tooling for the Cavium CN6640-SNIC10E
(Octeon II CN6640, PCI 177d:0092), exposing the card as two independent 10 GbE
host interfaces (oct0, oct1) over a reverse-engineered PCIe BAR2 shared-memory
datapath. No vendor NDA firmware. Host OS untouched, fully reversible.
Status: working. Both ports link at 10 G on a DAC and pass traffic bidirectionally — TX at line-rate 10 GbE (9.7–9.8 Gb/s, zero-copy datapath) and RX at 8.1–8.8 Gb/s (see PERFORMANCE). Card boots with no serial cable; the host brings both NICs up automatically at boot.
The SNIC10E is an OEM Cavium "SmartNIC": an 8-core Octeon II SoC with two SFP+ ports,
meant to run vendor LiquidIO firmware. The stock liquidio driver cannot drive this OEM
board (its soft-reset + flash-handshake boot model doesn't fit it), and for a long time
the card looked architecturally unusable as a plain host NIC because both PCIe BARs read
back all-0xFF.
That "BAR wall" turned out to be unprogrammed PEM inbound registers, not a hardware
limit. Programming PEMX_P2N_BARx_START / PEMX_BAR1_INDEXx from the card side (plain
u-boot write64, no firmware) opens a full bidirectional host↔card channel over PCIe.
On top of that channel this repo builds a real NIC:
octnic maps that ring and registers oct0 / oct1;Everything is reversible: the card runs entirely from RAM (nothing is flashed for the NIC role), and the host side is out-of-tree modules + scripts.
| Name | Side | Role |
|---|---|---|
octboot | host (bash) | Host bootloader: SBR the card, restore BARs, push the OpenWrt image into card DRAM over BAR2, wait for the NIC heartbeat. No serial. |
octnic (hostmod/octnic.c) | host (kmod) | Registers oct0/oct1 over the card's BAR2 window. Auto-discovers the card (modprobe octnic ports=2). |
octshm_card (cardmod/) | card (kmod) | Card end of the shared-memory datapath: per-port rings, DPI RX, XAUI uplink tap. |
octcarrier (cardmod/) | card (kmod) | Un-gates xaui0/xaui1 TX on the QLogic DAC (cvmx_helper_link_set). |
cavium-up.sh / twocard-up.sh | host | Orchestrate a full bring-up: boot the card, load octnic, wire up both ports. |
Run entirely hands-off by the cavium-nic.service systemd unit (see system/).
One-shot install (builds + installs the host module, drops the configs, enables autostart):
sudo ./install.sh # host side; add --start to also boot the card now
First time only — provision the card's u-boot env over serial (one command, see FLASHING); already-provisioned cards skip this:
sudo ./card-prep-hostboot.sh # serial, once — reads this machine's BARs, saveenv to NAND
Then, every boot, no serial:
sudo systemctl start cavium-nic # boots the card + brings up oct0 and oct1 (no serial)
ip -br addr show oct0 # 10 GbE host interface, port 0
ip -br addr show oct1 # 10 GbE host interface, port 1
Manual equivalent:
sudo ./octboot # boot the card (no serial)
sudo modprobe octnic ports=2 # oct0 + oct1 appear
# assign IPs / bridge / use like any NIC
Full details: FLASHING · USAGE · HARDWARE · ARCHITECTURE · PERFORMANCE.
cardmod/ octshm_card.c, octcarrier.c — card-side kernel modules (cross-built)
hostmod/ octnic.c — host-side kernel module (native build)
install.sh — one-shot host installer (module + configs + service)
octboot — host bootloader (no serial)
cavium-up.sh, twocard-up.sh, cexec.sh — bring-up orchestration (+ serial fallback)
card-temp.sh — card temperature feed
card-prep-hostboot.sh — first-time serial u-boot provisioning (once)
boot-clean.sh, set-hostboot.sh, restore-*.sh — serial fallbacks / legacy / revert
openwrt/ snic10e.config, build-openwrt.sh, files/ — OpenWrt image build + overlay
system/ cavium-nic.service, blacklist-liquidio.conf, 99-octnic-unmanaged.conf
docs/ HARDWARE, FLASHING, USAGE, ARCHITECTURE, PERFORMANCE, DMA-DESIGN
The R&D history (experiments, logs, snapshots, the reverse-engineering reference tree) lives outside the repo and is not published.
snic10e-ethernet
— the OpenWrt port that brings up the SNIC10E and its XAUI Ethernet; this project runs
that image on the card and builds the host datapath on top of it.cvmx_* helpers) and the in-tree liquidio driver, used as
reverse-engineering references for the SLI/DPI/PEM register layout.GPL-2.0 for the kernel modules (see SPDX headers). Scripts and docs under the same repo license unless noted.
Reverse-engineered, unofficial, no warranty. It power-cycles and reprograms an OEM card over PCIe; a wedged card can hang the host under heavy load (see USAGE → troubleshooting). Use on hardware you can afford to reset.
40 commits
2 commits
C
62.7%
Shell
36.9%
Out-of-tree Linux driver stack and boot tooling for the Cavium CN6640-SNIC10E (Octeon II, PCI 177d:0092), exposing the card as two independent 10 GbE interfaces (oct0/oct1) over a reverse-engineered PCIe BAR2 shared-memory datapath. Host module (octnic), on-card OpenWrt modules (octshm_card/octcarrier), serial-free host bootloader (octboot).
50
stars
42
commits
C
primary language
Sep 8, 2026
updated
Out-of-tree Linux driver stack and boot tooling for the Cavium CN6640-SNIC10E
(Octeon II CN6640, PCI 177d:0092), exposing the card as two independent 10 GbE
host interfaces (oct0, oct1) over a reverse-engineered PCIe BAR2 shared-memory
datapath. No vendor NDA firmware. Host OS untouched, fully reversible.
Status: working. Both ports link at 10 G on a DAC and pass traffic bidirectionally — TX at line-rate 10 GbE (9.7–9.8 Gb/s, zero-copy datapath) and RX at 8.1–8.8 Gb/s (see PERFORMANCE). Card boots with no serial cable; the host brings both NICs up automatically at boot.
The SNIC10E is an OEM Cavium "SmartNIC": an 8-core Octeon II SoC with two SFP+ ports,
meant to run vendor LiquidIO firmware. The stock liquidio driver cannot drive this OEM
board (its soft-reset + flash-handshake boot model doesn't fit it), and for a long time
the card looked architecturally unusable as a plain host NIC because both PCIe BARs read
back all-0xFF.
That "BAR wall" turned out to be unprogrammed PEM inbound registers, not a hardware
limit. Programming PEMX_P2N_BARx_START / PEMX_BAR1_INDEXx from the card side (plain
u-boot write64, no firmware) opens a full bidirectional host↔card channel over PCIe.
On top of that channel this repo builds a real NIC:
octnic maps that ring and registers oct0 / oct1;Everything is reversible: the card runs entirely from RAM (nothing is flashed for the NIC role), and the host side is out-of-tree modules + scripts.
| Name | Side | Role |
|---|---|---|
octboot | host (bash) | Host bootloader: SBR the card, restore BARs, push the OpenWrt image into card DRAM over BAR2, wait for the NIC heartbeat. No serial. |
octnic (hostmod/octnic.c) | host (kmod) | Registers oct0/oct1 over the card's BAR2 window. Auto-discovers the card (modprobe octnic ports=2). |
octshm_card (cardmod/) | card (kmod) | Card end of the shared-memory datapath: per-port rings, DPI RX, XAUI uplink tap. |
octcarrier (cardmod/) | card (kmod) | Un-gates xaui0/xaui1 TX on the QLogic DAC (cvmx_helper_link_set). |
cavium-up.sh / twocard-up.sh | host | Orchestrate a full bring-up: boot the card, load octnic, wire up both ports. |
Run entirely hands-off by the cavium-nic.service systemd unit (see system/).
One-shot install (builds + installs the host module, drops the configs, enables autostart):
sudo ./install.sh # host side; add --start to also boot the card now
First time only — provision the card's u-boot env over serial (one command, see FLASHING); already-provisioned cards skip this:
sudo ./card-prep-hostboot.sh # serial, once — reads this machine's BARs, saveenv to NAND
Then, every boot, no serial:
sudo systemctl start cavium-nic # boots the card + brings up oct0 and oct1 (no serial)
ip -br addr show oct0 # 10 GbE host interface, port 0
ip -br addr show oct1 # 10 GbE host interface, port 1
Manual equivalent:
sudo ./octboot # boot the card (no serial)
sudo modprobe octnic ports=2 # oct0 + oct1 appear
# assign IPs / bridge / use like any NIC
Full details: FLASHING · USAGE · HARDWARE · ARCHITECTURE · PERFORMANCE.
cardmod/ octshm_card.c, octcarrier.c — card-side kernel modules (cross-built)
hostmod/ octnic.c — host-side kernel module (native build)
install.sh — one-shot host installer (module + configs + service)
octboot — host bootloader (no serial)
cavium-up.sh, twocard-up.sh, cexec.sh — bring-up orchestration (+ serial fallback)
card-temp.sh — card temperature feed
card-prep-hostboot.sh — first-time serial u-boot provisioning (once)
boot-clean.sh, set-hostboot.sh, restore-*.sh — serial fallbacks / legacy / revert
openwrt/ snic10e.config, build-openwrt.sh, files/ — OpenWrt image build + overlay
system/ cavium-nic.service, blacklist-liquidio.conf, 99-octnic-unmanaged.conf
docs/ HARDWARE, FLASHING, USAGE, ARCHITECTURE, PERFORMANCE, DMA-DESIGN
The R&D history (experiments, logs, snapshots, the reverse-engineering reference tree) lives outside the repo and is not published.
snic10e-ethernet
— the OpenWrt port that brings up the SNIC10E and its XAUI Ethernet; this project runs
that image on the card and builds the host datapath on top of it.cvmx_* helpers) and the in-tree liquidio driver, used as
reverse-engineering references for the SLI/DPI/PEM register layout.GPL-2.0 for the kernel modules (see SPDX headers). Scripts and docs under the same repo license unless noted.
Reverse-engineered, unofficial, no warranty. It power-cycles and reprograms an OEM card over PCIe; a wedged card can hang the host under heavy load (see USAGE → troubleshooting). Use on hardware you can afford to reset.
40 commits
2 commits
C
62.7%
Shell
36.9%