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.
The short version¶
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. Because those two worlds are developed with completely different tools (Verilog + Vivado vs. C + the kernel build system), they live in separate repositories.
Why more than one repository?¶
There is not one "openwifi repo." There are four, 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/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/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/doc 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.
The board_name thread ties it all together
The same board_name string (for example zed_fmcs2, zcu102_fmcs2) names a board in all the repos: 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 + 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, only the
openwifirepo's artifacts run on the board: the FPGA bitstream (system_top.bit.bin), the kernel driver (sdr.koand friends), and the user-space tools. The bitstream originally came fromopenwifi-hw(or was downloaded fromopenwifi-hw-img). - At build time, the driver must agree with the FPGA on the register map. That contract is expressed in two mirror-image places:
openwifi/driver/hw_def.h(the addresses the driver writes) and each core's*_s_axi.vinopenwifi-hw/ip/(the registers the FPGA implements). A driver file and its FPGA counterpart usually even share a name (xpu.c↔xpu.v). This is why the two repos are versioned together even though they are separate in git. - The submodule chain:
openwifi-hwpulls in two submodules.analogdevicesinc/hdl(the Analog Devices FPGA reference design openwifi is built on top of, pinned to tag2022_R2) sits atadi-hdl/, andopenofdm(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 (August 7, 2026). Bumping it when they move is a welcome contribution.
| Component | Target version | Set / 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 / Z7035 / RFSoC4x2 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 / 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. |
| 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 / 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 / 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/demodulation) or the real-time MAC (CSMA/CA, ACK, TSF)¶
openwifi-hw/ip/: one directory per IP core. xpu/ is the real-time MAC, openofdm_tx/ and openofdm_rx/ are the PHY, tx_intf//rx_intf/ are the RF/DAC/ADC interfaces, side_ch/ is CSI/IQ capture. See FPGA IP Cores.
…CSI / 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/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 / 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 + 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 / 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 for the open-source release, with commercial/advanced-feature licensing available via openwifi.tech. Individual files may be GPL-2.0-or-later or BSD-3-Clause, and 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 / imec (Xianjun Jiao, Wei Liu, Michael Mehari, and contributors), funded by the EU H2020 ORCA project (grant 732174) and NLnet/NGI Zero. See FAQ & Resources for citation info and the publication list.