The openwifi Project and Its Repositories¶
New to openwifi? Start here. This page explains what the project is made of, why it is split across several repositories, and where to look when you need to find something.
Summary¶
openwifi is a full-stack, Linux mac80211-compatible IEEE 802.11 (Wi-Fi) implementation for SDR hardware. The radio PHY and real-time MAC live in FPGA fabric. The driver and everything above it are ordinary Linux. The FPGA uses Verilog and Vivado, while the driver uses C and the kernel build system. The two halves live in separate repositories.
Why more than one repository?¶
The project has four repositories, each with its own job and toolchain.
| Repository | What it holds | When you touch it |
|---|---|---|
| openwifi | The Linux kernel driver, sdrctl and other user-space tools, capture and demo scripts, SD-card boot files (kernel patches, device trees, U-Boot), and all the documentation |
Rebuilding the driver, changing runtime behavior, writing scripts, flashing and booting a board, reading app notes |
| openwifi-hw | The FPGA design: openwifi's custom IP cores (xpu, openofdm_tx, tx_intf, rx_intf, side_ch, and the openofdm_rx submodule) plus a Vivado project per supported board |
Modifying the PHY or real-time MAC, adding a board, rebuilding the bitstream |
| openwifi-hw-img | Prebuilt FPGA bitstreams for each board (.xsa, bitstream, ILA .ltx, init files under boards/<board_name>/sdk/), plus the CLA and documentation PDFs |
You want a working bitstream without installing Vivado or waiting hours for synthesis |
| openofdm | The 802.11 OFDM receiver that openofdm_rx is based on. openwifi's improvements live on the dot11zynq branch (and dot11zynq_hls for the HLS variant). Originally by jhshi |
Deep receiver work (synchronization, channel estimation, Viterbi decode). Usually you let the build script fetch it |
openwifi-hw-img is pulled in by the software build scripts, and openofdm is fetched as a git submodule of openwifi-hw.
One board_name across all repositories
The same board_name string (for example zed_fmcs2, zcu102_fmcs2) names a board in all the repos. It selects openwifi-hw/boards/$BOARD_NAME/ (FPGA project), openwifi-hw-img/boards/$BOARD_NAME/sdk/ (prebuilt bitstream), and openwifi/kernel_boot/boards/$BOARD_NAME/ (boot files and device tree). Set export BOARD_NAME=... once and every build script uses it. See Supported Boards.
How the pieces fit at build and run time¶
- At run time, three things run on the board. These are the FPGA bitstream (
system_top.bit.bin), the kernel driver (sdr.koand related modules), and the user-space tools. The driver and tools come fromopenwifi. The bitstream is built fromopenwifi-hwor downloaded fromopenwifi-hw-img. - At build time, the driver must agree with the FPGA on the register map.
openwifi/driver/hw_def.hholds the addresses the driver writes, while each core's*_s_axi.vinopenwifi-hw/ip/implements the registers in the FPGA. A driver file and its FPGA counterpart usually share a name (xpu.candxpu.v). The two repos are versioned together because those definitions must match. - The submodule chain:
openwifi-hwpulls in two submodules. The Analog Devices FPGA reference design,analogdevicesinc/hdl, sits atadi-hdl/and is pinned to tag2022_R2. openwifi is built on top of it.openofdm(branchdot11zynq) sits atip/openofdm_rx/. A freshopenwifi-hwclone has these as empty directories until you run./prepare_adi_lib.shand./get_ip_openofdm_rx.sh(orgit submodule update --init).
Versions this wiki targets¶
openwifi pins several toolchains and upstream projects, and they intentionally don't all share a version number. A 2022-era FPGA toolchain paired with a current kernel is normal here. If a build script or a repo README states a version different from the table below, trust the repo. Treat this table as a snapshot from the last reconciliation with the repos (September 26, 2026). Bumping it when they move is a welcome contribution.
| Component | Target version | Set or pinned in | Notes |
|---|---|---|---|
| Vivado + Vitis | 2022.2 (needs Vitis, not Vitis_HLS) |
openwifi-hw build scripts | Free tier suffices for Zynq-7020 boards. ZC706, ZCU102, and Z7035 need a license to rebuild the FPGA. See FPGA Development. |
ADI HDL reference design (adi-hdl submodule) |
tag 2022_R2 |
openwifi-hw submodule pin |
The FPGA design is built on top of it (prepare_adi_lib.sh). |
ADI Linux kernel (adi-linux and adi-linux-64) |
branch 2026_R1, Linux 6.12 |
prepare_kernel.sh |
Patched by ad9361_v6_12.patch. See Boot, Kernel & Device Tree. |
openofdm receiver (submodule) |
branch dot11zynq (HLS variant dot11zynq_hls) |
get_ip_openofdm_rx.sh |
Backs the openofdm_rx core. |
| ADI Kuiper base image | 2023-12-13 release (image_2023-12-13-ADI-Kuiper-full.zip, tagged 2022_r2) |
flashed manually | Only the starting rootfs. You build a current kernel on top. See Building SD Images. |
| OpenWrt (alternative to Kuiper) | branch openwrt-openwifi_v25.12.5 = OpenWrt 25.12.5, Linux 6.12, mac80211 6.18 |
openwrt-openwifi repo |
Docker-only build, no Vivado. See Building SD Images. |
| Buildroot (alternative to Kuiper) | Buildroot 2025.02.11, Linux 6.12, U-Boot xlnx_rebase_v2024.01_2024.2 |
buildroot submodule + buildroot-external/ |
Small, fast-booting deployment image for antsdr_e200, antsdr, e310v2. No Vivado, reuses a prebuilt XSA. See Building SD Images. |
| Xilinx Viterbi decoder | evaluation license | Vivado IP catalog | The eval license halts a running receiver after ~2 hours. A paid license removes the limit. |
| Build-host OS | Ubuntu 18, 20, or 22 LTS | not pinned | Ubuntu 24 needs libtinfo5 installed manually (see Environment Setup). |
Driver and FPGA ship as a matched set
openwifi's releases are codenamed (for example v1.5.0 shahecheng, v1.2.0 leuven) and version the driver and the FPGA design together, because the two sides share the register-map contract described above. Run a driver against the bitstream from the same release rather than mixing across versions. The wgd.sh hot-reload flow exists to swap matched driver + FPGA pairs on a running board without rebooting (see Software Development Workflow). There is no formal cross-version compatibility matrix, so when in doubt, match versions. The full release history and notes live on the openwifi releases page.
Where do you look for…?¶
…runtime behavior (rates, power, CCA, ACK, slicing)¶
openwifi/user_space/: dozens of helper scripts wrap sdrctl register writes. Start with the sdrctl & Runtime Control page. The tool itself is openwifi/user_space/sdrctl_src/.
…the driver and how Linux talks to the hardware¶
openwifi/driver/: sdr.c (the mac80211 driver), sdrctl_intf.c (the sdrctl netlink handler), sysfs_intf.c (statistics), hw_def.h (register addresses). See Architecture.
…the PHY (OFDM modulation and demodulation) or the real-time MAC (CSMA/CA, ACK, TSF)¶
openwifi-hw/ip/: one directory per IP core. xpu/ is the real-time MAC, and openofdm_tx/ and openofdm_rx/ are the PHY. tx_intf/ and rx_intf/ are the DAC-side and ADC-side interfaces, and side_ch/ handles CSI and IQ capture. See FPGA IP Cores.
…CSI and IQ capture (the research features)¶
Three places cooperate: openwifi-hw/ip/side_ch/ (the FPGA capture engine), openwifi/driver/side_ch/ (the side_ch.ko kernel module), and openwifi/user_space/side_ch_ctl_src/ (the side_ch_ctl tool plus the Python and MATLAB display scripts). See Research Features.
…how a board boots (kernel, device tree, U-Boot, BOOT.BIN)¶
openwifi/kernel_boot/: per-board boot artifacts under boards/<board_name>/, kernel patches, and the device-tree overlay machinery (construct_device_tree.sh, openwifi_32_ad9361.dtso, and openwifi_64_ad9361.dtso). See Boot, Kernel & Device Tree.
…adding or porting a board¶
Both repos: openwifi-hw/boards/<board_name>/ (Vivado project) and openwifi/kernel_boot/boards/<board_name>/ (device tree and boot files). See FPGA Development → Porting to a new board.
…a prebuilt bitstream (skip synthesis)¶
openwifi-hw-img, boards/<board_name>/sdk/.
…the authoritative docs and app notes¶
openwifi/doc/ and openwifi/doc/app_notes/. The wiki pages reorganize that material thematically. When the wiki and the repo disagree, trust the repo, and please fix the wiki.
Repository directory maps¶
openwifi (driver + software + docs):
openwifi/
├── driver/ # Linux kernel driver (sdr.c, hw_def.h, sdrctl_intf.c, sysfs_intf.c, per-core sub-drivers)
├── user_space/ # sdrctl, side_ch_ctl, inject_80211, ~70 helper scripts, demo configs
│ ├── sdrctl_src/ # the sdrctl CLI
│ ├── side_ch_ctl_src/ # side_ch_ctl + Python/MATLAB CSI/IQ display scripts
│ ├── inject_80211/ # packet injection + analyze_80211
│ └── arbitrary_iq_gen/ # generate arbitrary TX IQ waveforms
├── kernel_boot/ # SD-card boot files: per-board device trees, U-Boot, kernel patches/config
│ └── boards/ # one directory per board_name
├── doc/ # architecture reference, app notes, known issues, publications, videos
│ ├── app_notes/ # CSI, IQ, fuzzer, radar, injection, 802.11n, HLS, etc.
│ ├── img_build_instruction/ # Kuiper and OpenWrt SD-image build guides
│ └── known_issue/ # notter.md: the canonical troubleshooting list
└── README.md
openwifi-hw (FPGA design):
openwifi-hw/
├── ip/ # the custom openwifi IP cores
│ ├── xpu/ # real-time MAC: CSMA/CA, ACK, TSF, TX-queue gating, RSSI/CCA
│ ├── openofdm_tx/ # 802.11 OFDM transmitter (IFFT, FEC, modulation, preambles)
│ ├── openofdm_rx/ # 802.11 OFDM receiver (submodule → openofdm, dot11zynq branch)
│ ├── tx_intf/ # DAC-side interface + TX BRAM + CSI fuzzer
│ ├── rx_intf/ # ADC-side interface + RX DMA
│ └── side_ch/ # CSI / raw-IQ capture side channel
├── boards/ # one Vivado project per board_name (system.bd, .xdc, system_top.v, TCL)
├── adi-hdl/ # submodule → analogdevicesinc/hdl (ADI reference design), tag 2022_R2
├── prepare_adi_lib.sh, prepare_adi_board_ip.sh, get_ip_openofdm_rx.sh
├── gpio_led.md # which FPGA signals are routed to board LEDs / PMOD test points
└── README.md
Licensing and contributing across the repos¶
All openwifi repositories are dual-licensed. AGPLv3 covers the open-source release, and openwifi.tech offers commercial licenses for advanced features. Individual files may be GPL-2.0-or-later or BSD-3-Clause. Vendored third-party components (Analog Devices HDL, the Xilinx Viterbi decoder, openofdm) carry their own terms, so check per-file headers for your use case.
Contributing to any repo requires signing a CLA (Individual or Entity, generated via the Project Harmony framework) and emailing it to Filip.Louagie@UGent.be before your first contribution. See each repo's CONTRIBUTING.md.
The project originated at Ghent University and imec (Xianjun Jiao, Wei Liu, Michael Mehari, and contributors). It was funded by the EU H2020 ORCA project (grant 732174) and by NLnet through NGI Zero. See FAQ & Resources for citation info and the publication list.