xref: /openwifi/README.md (revision efa47b29f6d5d373a45064351dbcfb7ff5720ddb)
1<!--
2Author: Xianjun jiao, Michael Mehari, Wei Liu
3SPDX-FileCopyrightText: 2019 UGent
4SPDX-License-Identifier: AGPL-3.0-or-later
5-->
6
7# openwifi
8<img src="./openwifi-arch.jpg" width="900">
9
10**openwifi:** Linux mac80211 compatible full-stack IEEE802.11/Wi-Fi design based on SDR (Software Defined Radio).
11
12This repository includes Linux driver and software. **openwifi-hw** repository has the FPGA design. It is **YOUR RESPONSIBILITY** to follow your **LOCAL SPECTRUM REGULATION** or use **CABLE** to avoid potential interference over the air.
13
14[[Quick start](#Quick-start)]
15[[Project document](doc/README.md)]
16[[Application notes](doc/app_notes/README.md)]
17[[Videos](doc/videos.md)]
18[[Publications and How to Cite](doc/publications.md)]
19[[maillist](https://lists.ugent.be/wws/subscribe/openwifi)]
20
21Openwifi code has dual licenses. [AGPLv3](https://github.com/open-sdr/openwifi/blob/master/LICENSE) is the opensource license. For non-opensource and advanced feature license, please contact [email protected]. Openwifi project also leverages some 3rd party modules. It is user's duty to check and follow licenses of those modules according to the purpose/usage. You can find [an example explanation from Analog Devices](https://github.com/analogdevicesinc/hdl/blob/master/LICENSE) for this compound license conditions. [[How to contribute]](https://github.com/open-sdr/openwifi/blob/master/CONTRIBUTING.md).
22
23**Features:**
24
25- 802.11a/g/n [[IEEE 802.11n (Wi-Fi 4)](doc/app_notes/ieee80211n.md)]
26- 20MHz bandwidth; [70 MHz to 6 GHz frequency range](doc/README.md#let-openwifi-work-at-arbitrary-frequency)
27- Mode tested: [Ad-hoc](doc/app_notes/ad-hoc-two-sdr.md); [Station; AP](doc/app_notes/ap-client-two-sdr.md), Monitor
28- [DCF (CSMA/CA) low MAC layer in FPGA (10us SIFS is achieved)](doc/app_notes/frequent_trick.md)
29- [802.11 packet injection and fuzzing](doc/app_notes/inject_80211.md)
30- [CSI](doc/app_notes/csi.md): Channel State Information, freq offset, equalizer to computer
31- [CSI fuzzer](doc/app_notes/csi_fuzzer.md): Create artificial channel response in WiFi transmitter
32- [CSI radar](doc/app_notes/radar-self-csi.md): Moving detection. Joint radar and communication
33- [[IQ capture](doc/app_notes/iq.md)]: real-time AGC, RSSI, IQ sample to computer. [[Dual antenna version](doc/app_notes/iq_2ant.md)]
34- [Configurable channel access priority parameters](doc/app_notes/frequent_trick.md):
35  - CCA threshold, receiver sensitivity, etc
36  - duration of RTS/CTS, CTS-to-self
37  - SIFS/DIFS/xIFS/slot-time/CW/etc
38- [Time slicing based on MAC address (time gated/scheduled FPGA queues)](https://doc.ilabt.imec.be/ilabt/wilab/tutorials/openwifi.html#sdr-tx-time-slicing)
39- Easy to change bandwidth and [frequency](doc/README.md#let-openwifi-work-at-arbitrary-frequency):
40  - 2MHz for 802.11ah in sub-GHz
41  - 10MHz for 802.11p/vehicle in 5.9GHz
42- **802.11ax** under development
43
44**Performance (best case: aggregation/AMPDU on):**
45- iperf: TCP 40~50Mbps; UDP 50Mbps
46- EVM -38dB; MCS0 sensitivity -87dBm; MCS7 -72dBm. (FMCOMMS2 2.4GHz; cable and OTA test)
47
48**Supported SDR platforms:** (Check [Porting guide](#Porting-guide) for your new board if it isn't in the list)
49
50board_name|board combination|status|SD card img|Vivado license
51-------|-------|----|----|-----
52zc706_fmcs2|[Xilinx ZC706 board](https://www.xilinx.com/products/boards-and-kits/ek-z7-zc706-g.html) + [FMCOMMS2/3/4](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-ad-fmcomms2.html)|Done|[32bit img](https://users.ugent.be/~xjiao/openwifi-1.3.1-wilsele-1-32bit.img.xz)|Need
53zed_fmcs2|[Xilinx zed board](https://www.xilinx.com/products/boards-and-kits/1-8dyf-11.html) + [FMCOMMS2/3/4](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-ad-fmcomms2.html)|Done|[32bit img](https://users.ugent.be/~xjiao/openwifi-1.3.1-wilsele-1-32bit.img.xz)|**NO** need
54adrv9364z7020|[ADRV9364-Z7020 + ADRV1CRR-BOB](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/adrv9364-z7020.html)|Done|[32bit img](https://users.ugent.be/~xjiao/openwifi-1.3.1-wilsele-1-32bit.img.xz)|**NO** need
55adrv9361z7035|[ADRV9361-Z7035 + ADRV1CRR-BOB/FMC](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/ADRV9361-Z7035.html)|Done|[32bit img](https://users.ugent.be/~xjiao/openwifi-1.3.1-wilsele-1-32bit.img.xz)|Need
56zc702_fmcs2|[Xilinx ZC702 board](https://www.xilinx.com/products/boards-and-kits/ek-z7-zc702-g.html) + [FMCOMMS2/3/4](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-ad-fmcomms2.html)|Done|[32bit img](https://users.ugent.be/~xjiao/openwifi-1.3.1-wilsele-1-32bit.img.xz)|**NO** need
57antsdr|[MicroPhase](https://github.com/MicroPhase/) enhanced ADALM-PLUTO [Notes](kernel_boot/boards/antsdr/notes.md)|Done|[32bit img](https://users.ugent.be/~xjiao/openwifi-1.3.1-wilsele-1-32bit.img.xz)|**NO** need
58antsdr_e200|[MicroPhase](https://github.com/MicroPhase/) enhanced ADALM-PLUTO [Notes](kernel_boot/boards/antsdr_e200/README.md)|Done|[32bit img](https://users.ugent.be/~xjiao/openwifi-1.3.1-wilsele-1-32bit.img.xz)|**NO** need
59sdrpi|[HexSDR](https://github.com/HexSDR/) Powerful SDR in Raspberry Pi size [Notes](kernel_boot/boards/sdrpi/notes.md)|Done|[32bit img](https://users.ugent.be/~xjiao/openwifi-1.3.1-wilsele-1-32bit.img.xz)|**NO** need
60zcu102_fmcs2|[Xilinx ZCU102 board](https://www.xilinx.com/products/boards-and-kits/ek-u1-zcu102-g.html) + [FMCOMMS2/3/4](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-ad-fmcomms2.html)|Done|[64bit img](https://users.ugent.be/~xjiao/openwifi-1.3.1-wilsele-64bit.img.xz)|Need
61zcu102_9371|[Xilinx ZCU102 board](https://www.xilinx.com/products/boards-and-kits/ek-u1-zcu102-g.html) + [ADRV9371](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-adrv9371.html)|Future|Future|Need
62
63- board_name is used to identify FPGA design in openwifi-hw/boards/
64- Don't have any boards? Or you like JTAG boot instead of SD card? Check our test bed [w-iLab.t](https://doc.ilabt.imec.be/ilabt/wilab/tutorials/openwifi.html) tutorial.
65
66[[Quick start](#Quick-start)]
67[[Basic operations](#Basic-operations)]
68[[Update FPGA](#Update-FPGA)]
69[[Update Driver](#Update-Driver)]
70[[Update sdrctl](#Update-sdrctl)]
71[[Easy Access and etc](#Easy-Access-and-etc)]
72
73[[Build openwifi Linux img from scratch](#Build-openwifi-Linux-img-from-scratch)]
74[[Special note for 11b](#Special-note-for-11b)]
75[[Porting guide](#Porting-guide)]
76[[Project document](doc/README.md)]
77[[Application notes](doc/app_notes/README.md)]
78
79## Quick start
80- Restore openwifi board specific img file (from the table) into a SD card. To do this, program "Disks" in Ubuntu can be used (Install: "sudo apt install gnome-disk-utility"). After restoring, the SD card should have two partitions: BOOT and rootfs. You need to config the **correct files in the BOOT partition** according to the **board you have** by operation on your computer:
81  - Copy files in **openwifi/board_name** to the base directory of BOOT partition.
82  - Copy **openwifi/zynqmp-common/Image** (zcu102 board) or **openwifi/zynq-common/uImage** (other boards) to the base directory of BOOT partition
83- Connect two antennas to RXA/TXA ports. Config the board to SD card boot mode (check the board manual). Insert the SD card to the board. Power on.
84- Login to the board from your PC (PC Ethernet should have IP 192.168.10.1) with password **openwifi**.
85  ```
86  ssh [email protected]
87  ```
88- Then, run openwifi AP and the on board webserver
89  ```
90  cd openwifi
91  ./wgd.sh
92  ./fosdem.sh
93  (Use "./wgd.sh 1" to enable experimental AMPDU aggregation on top of 11n)
94  (Use "./fosdem-11ag.sh" to force 11a/g mode)
95  ```
96  **NOTE** adrv9361z7035 has ultra low TX power in 5GHz. Move **CLOSER** when you use that board in 5GHz!!!
97- After you see the "openwifi" SSID on your device (Phone/Laptop/etc), connect it. Browser to 192.168.13.1 on your device, you should see the webpage hosted by the webserver on board.
98  - Note 1: If your device doesn't support 5GHz (ch44), please change the **hostapd-openwifi.conf** on board and re-run fosdem.sh.
99  - Note 2: After ~2 hours, the Viterbi decoder will halt (Xilinx Evaluation License). Just power cycle the board if it happens. (If output of "./sdrctl dev sdr0 get reg rx 20" is always the same, it means the decoder halts)
100- To give the Wi-Fi client internet access, configure routing/NAT **on the PC**:
101  ```
102  sudo sysctl -w net.ipv4.ip_forward=1
103  sudo iptables -t nat -A POSTROUTING -o NICY -j MASQUERADE
104  sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX
105  ```
106  **ethX** is the PC NIC name connecting the board ethernet. **NICY** is the PC NIC name connecting internet (WiFi or another ethernet).
107
108  If you want, uncommenting "net.ipv4.ip_forward=1" in /etc/sysctl.conf to make IP forwarding persistent on PC.
109- To monitor **real-time CSI (Chip State Information)**, such as timestamp, frequency offset, channel state, equalizer, please refer to [[CSI notes](doc/app_notes/csi.md)].
110
111## Basic operations
112The board actually is an Linux/Ubuntu computer which is running **hostapd** to offer Wi-Fi AP functionality over the Wi-Fi Network Interface (NIC). The NIC is implemented by openwifi-hw FPGA design. We use the term **"On board"** to indicate that the commands should be executed after ssh login to the board. **"On PC"** means the commands should run on PC.
113- Bring up the openwifi NIC sdr0:
114  ```
115  cd ~/openwifi && ./wgd.sh
116  (Use "./wgd.sh 1" to enable experimental AMPDU aggregation)
117  ```
118- Use openwifi as client to connect other AP (Change wpa-connect.conf on board firstly):
119  ```
120  route del default gw 192.168.10.1
121  wpa_supplicant -i sdr0 -c wpa-connect.conf &
122  dhclient sdr0
123  ```
124- Use openwifi in ad-hoc mode: Please check **sdr-ad-hoc-up.sh**, **sdr-ad-hoc-join.sh** and [this app note](./doc/app_notes/ad-hoc-two-sdr.md).
125- Use openwifi in monitor mode: Please check **monitor_ch.sh** and [this app note](./doc/app_notes/inject_80211.md).
126- The Linux native Wi-Fi tools/Apps (iwconfig/ifconfig/iwlist/iw/hostapd/wpa_supplicant/etc) can run over openwifi NIC in the same way as commercial Wi-Fi chip.
127- **sdrctl** is a dedicated tool to access openwifi driver/FPGA, please check [project document](./doc/README.md) for more information.
128
129## Update FPGA
130
131(Check [Driver and FPGA dynamic reloading app note](./doc/app_notes/drv_fpga_dynamic_loading.md) for more convenient way of updating FPGA and driver files)
132
133Since the pre-built SD card image might not have the latest bug-fixes/updates, it is recommended to always copy the latest files in the [user_space](./user_space) directory on to the board. Then update the fpga bitstream and driver (see next section) on to the board.
134
135- Install Vivado/SDK 2018.3 (Vivado Design Suite - HLx Editions - 2018.3 Full Product Installation. If you don't need to generate new FPGA bitstream, WebPack version without license is enough)
136- Setup environment variables (use absolute path):
137  ```
138  export XILINX_DIR=your_Xilinx_install_directory
139  (Example: export XILINX_DIR=/opt/Xilinx. The Xilinx directory should include sth like: Downloads, SDK, Vivado, xic)
140  export OPENWIFI_HW_DIR=your_openwifi-hw_directory
141  (The directory where you store the open-sdr/openwifi-hw repo via git clone)
142  export BOARD_NAME=your_board_name
143  ```
144- Pick the FPGA bitstream from openwifi-hw, and generate BOOT.BIN and transfer it on board via ssh channel:
145  ```
146  For Zynq 7000:
147
148  cd openwifi/user_space; ./boot_bin_gen.sh $OPENWIFI_HW_DIR $XILINX_DIR $BOARD_NAME
149
150  For Zynq MPSoC (like zcu102 board):
151  cd openwifi/user_space; ./boot_bin_gen_zynqmp.sh $OPENWIFI_HW_DIR $XILINX_DIR $BOARD_NAME
152
153  cd openwifi/kernel_boot/boards/$BOARD_NAME/output_boot_bin; scp ./BOOT.BIN [email protected]:
154  ```
155- On board: Put the BOOT.BIN into the BOOT partition.
156  ```
157  mount /dev/mmcblk0p1 /mnt
158  cp ~/BOOT.BIN /mnt
159  cd /mnt
160  sync
161  cd ~
162  umount /mnt
163  ```
164  **Power cycle** the board to load new FPGA bitstream.
165
166  To load FPGA dynamically without rebooting/power-cycle, check [Driver and FPGA dynamic reloading app note](./doc/app_notes/drv_fpga_dynamic_loading.md).
167
168## Update Driver
169
170(Check [Driver and FPGA dynamic reloading app note](./doc/app_notes/drv_fpga_dynamic_loading.md) for more convenient way of updating FPGA and driver files)
171
172Since the pre-built SD card image might not have the latest bug-fixes/updates, it is recommended to always copy the latest files in the [user_space](./user_space) directory on to the board. Then update the fpga bitstream (see previous section) and driver on to the board.
173
174- Prepare Analog Devices Linux kernel source code (only need to run once):
175  ```
176  cd openwifi/user_space; ./prepare_kernel.sh $XILINX_DIR ARCH_BIT build
177  (For Zynq 7000, ARCH_BIT should be 32, for Zynq MPSoC, ARCH_BIT should be 64)
178  ```
179  **Note**: In Ubuntu, gcc-10 might have issue ('yylloc' error), so use gcc-9 if you encounter error.
180- Compile the latest openwifi driver
181  ```
182  cd openwifi/driver; ./make_all.sh $XILINX_DIR ARCH_BIT
183  (For Zynq 7000, ARCH_BIT should be 32, for Zynq MPSoC, ARCH_BIT should be 64)
184  (More arguments (max 5) beyond above two will be converted to "#define argument" in pre_def.h for conditional compiling)
185  ```
186- Copy the driver files to the board via ssh channel
187  ```
188  cd openwifi/driver; scp `find ./ -name \*.ko` [email protected]:openwifi/
189  ```
190  Now you can use **wgd.sh** on board to load the new openwifi driver. **wgd.sh** also tries to reload FPGA img if system_top.bit.bin presents in the same directory.
191  Find more information in [Driver and FPGA dynamic reloading app note](./doc/app_notes/drv_fpga_dynamic_loading.md).
192
193  **Note**: If you have symbol or version error while loadng the driver, it could be because the kernel in the SD card image is too old. In this case, you need to follow [[Build openwifi Linux img from scratch](#Build-openwifi-Linux-img-from-scratch)] to generate your new SD card image.
194
195## Update sdrctl
196- Copy the sdrctl source files to the board via ssh channel
197  ```
198  cd openwifi/user_space/sdrctl_src; scp `find ./ -name \*` [email protected]:openwifi/sdrctl_src/
199  ```
200- Compile the sdrctl **on board**:
201  ```
202  cd ~/openwifi/sdrctl_src/ && make && cp sdrctl ../ && cd ..
203  ```
204## Easy Access and etc
205
206- Check [Driver and FPGA dynamic reloading app note](./doc/app_notes/drv_fpga_dynamic_loading.md) for more convenient way of updating FPGA and driver files.
207- FPGA and driver on board update scripts
208  - Setup [ftp server](https://ubuntu.com/server/docs/service-ftp) on PC, allow anonymous and change ftp root directory to the openwifi directory.
209  - On board:
210  ```
211  ./sdcard_boot_update.sh $BOARD_NAME
212  (Above command downloads uImage, BOOT.BIN and devicetree.dtb, then copy them into boot partition. Remember to power cycle)
213  ./wgd.sh remote
214  (Above command downloads driver files, and brings up sdr0)
215  ```
216- Access the board disk/rootfs like a disk:
217   - On PC: "File manager --> Connect to Server...", input: sftp://[email protected]/root
218   - Input password "openwifi"
219
220## Build openwifi Linux img from scratch
221- Install the devicetree compiler -- dtc. (For Ubuntu: sudo apt install device-tree-compiler)
222- Install the mkimage tool. (For Ubuntu: sudo apt install u-boot-tools)
223- Download [2019_R1-2020_06_22.img.xz](http://swdownloads.analog.com/cse/2019_R1-2020_06_22.img.xz) from [Analog Devices Wiki](https://wiki.analog.com/resources/tools-software/linux-software/zynq_images). Burn it to a SD card.
224- Insert the SD card to your Linux PC. Find out the mount point (that has two sub directories BOOT and rootfs), and setup environment variables (use absolute path):
225  ```
226  export SDCARD_DIR=sdcard_mount_point
227  export XILINX_DIR=your_Xilinx_install_directory
228  export OPENWIFI_HW_DIR=your_openwifi-hw_directory
229  export BOARD_NAME=your_board_name
230  ```
231- Run script to update SD card:
232  ```
233  cd openwifi/user_space; ./update_sdcard.sh $OPENWIFI_HW_DIR $XILINX_DIR $BOARD_NAME $SDCARD_DIR
234  ```
235- Config your board to SD card boot mode (check the board manual). Insert the SD card to the board. Power on.
236- Login to the board from your PC (PC Ethernet should have IP 192.168.10.1) with one time password **analog**.
237  ```
238  ssh [email protected]
239  ```
240- Setup routing/NAT **on the PC** for your board -- this internet connection is **important** for post installation/config.
241  ```
242  sudo sysctl -w net.ipv4.ip_forward=1
243  sudo iptables -t nat -A POSTROUTING -o NICY -j MASQUERADE
244  sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX
245  ```
246  **ethX** is the PC NIC name connecting the board ethernet. **NICY** is the PC NIC name connecting internet (WiFi or another ethernet).
247
248  If you want, uncommenting "net.ipv4.ip_forward=1" in /etc/sysctl.conf to make IP forwarding persistent on PC.
249- Test the connectivity. Run on board (in the ssh session):
250  ```
251  route add default gw 192.168.10.1
252  ping IP_YOU_KNOW_ON_YOUR_NETWORK
253  ```
254  If there is issue with the connectivity (ping can not reach the target), it needs to be solved before going to the next step.
255- Run **one time** script on board to complete post installation/config (After this, password becomes **openwifi**)
256  ```
257  cd ~/openwifi && ./post_config.sh
258  ```
259- Now you can start from [Quick start](#Quick-start) (Skip the image download and burn step)
260
261## Special note for 11b
262
263Openwifi only applies OFDM as its modulation scheme and as a result, it is not backward compatible with 802.11b clients or modes of operation. This is usually the case during beacon transmission, connection establishment, and robust communication.
264
265As a solution to this problem, openwifi can be fully controlled only if communicating with APs/clients instantiated using hostapd/wpa_supplicant userspace programs respectively.
266
267For hostapd program, 802.11b rates can be suppressed using configuration commands (i.e. supported_rates, basic_rates) and an example configuration file is provided (i.e. hostapd-openwifi.conf). One small caveat to this one comes from fullMAC Wi-Fi cards as they must implement the *NL80211_TXRATE_LEGACY* NetLink handler at the device driver level.
268
269On the other hand, the wpa_supplicant program on the client side (commercial Wi-Fi dongle/board) cannot suppress 802.11b rates out of the box in 2.4GHz band, so there will be an issue when connecting openwifi (OFDM only). A patched wpa_supplicant should be used at the client side.
270```
271sudo apt-get install libssl1.0-dev
272cd openwifi/user_space; ./build_wpa_supplicant_wo11b.sh
273```
274## Porting guide
275
276This section explains the porting work by showing the differences between openwifi and Analog Devices reference design. openwifi is based on 2019_R1 of [HDL Reference Designs](https://github.com/analogdevicesinc/hdl).
277- Open the fmcomms2 + zc706 reference design at hdl/projects/fmcomms2/zc706 (Please read Analog Devices help)
278- Open the openwifi design zc706_fmcs2 at openwifi-hw/boards/zc706_fmcs2 (Please read openwifi-hw repository)
279- "Open Block Design", you will see the differences between openwifi and the reference design. Both in "diagram" and in "Address Editor".
280- The address/interrupts of FPGA blocks hooked to the ARM bus should be put/aligned to the devicetree file openwifi/kernel_boot/boards/zc706_fmcs2/devicetree.dts. Linux will parse the devicetree.dtb when booting to know information of attached device (FPGA blocks in our case).
281- We use dtc command to get devicetree.dts converted from devicetree.dtb in [Analog Devices Linux image](https://wiki.analog.com/resources/tools-software/linux-software/zynq_images), then do modification according to what we have added/modified to the reference design.
282- Please learn the script in [[Build openwifi Linux img from scratch](#Build-openwifi-Linux-img-from-scratch)] to understand how we generate devicetree.dtb, BOOT.BIN and Linux kernel uImage and put them together to build the full SD card image.
283
284## License
285
286This project is available as open source under the terms of the AGPL 3.0 Or later. However, some elements are being licensed under GPL 2-0 or later and BSD 3 license . For accurate information, please check individual files.
287