xref: /openwifi/README.md (revision 311b18bf7c5a29112a0ac68c32358ca8512d4269)
1# openwifi
2<img src="./openwifi-arch.jpg" width="900">
3
4**openwifi:** Linux mac80211 compatible full-stack IEEE802.11/Wi-Fi design based on SDR (Software Defined Radio).
5
6This repository includes Linux driver and software. [openwifi-hw](https://github.com/open-sdr/openwifi-hw) repository has the FPGA design. [[Project document](https://github.com/open-sdr/openwifi/tree/master/doc)]
7
8[Demo [video](https://youtu.be/NpjEaszd5u4) and video [download](https://users.ugent.be/~xjiao/openwifi-low-aac.mp4)]   [openwifi [maillist](https://lists.ugent.be/wws/subscribe/openwifi)] [[Cite openwifi project](#Cite-openwifi-project)]
9
10Openwifi code has dual licenses. AGPLv3 is the opensource license. For non-opensource 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).
11
12**Features:**
13
14- 802.11a/g
15- 802.11n MCS 0~7 (Only PHY rx for now. Full system support of 802.11n will come soon)
16- 20MHz bandwidth; 70 MHz to 6 GHz frequency range
17- Mode tested: Ad-hoc; Station; AP, Monitor
18- DCF (CSMA/CA) low MAC layer in FPGA (10us SIFS is achieved)
19- Configurable channel access priority parameters:
20  - duration of RTS/CTS, CTS-to-self
21  - SIFS/DIFS/xIFS/slot-time/CW/etc
22- Time slicing based on MAC address
23- Easy to change bandwidth and frequency:
24  - 2MHz for 802.11ah in sub-GHz
25  - 10MHz for 802.11p/vehicle in 5.9GHz
26- On roadmap: **802.11ax**
27
28**Performance (AP: openwifi at channel 44, client: TL-WDN4200 N900 USB Dongle):**
29- AP --> client: 30.6Mbps(TCP), 38.8Mbps(UDP)
30- client --> AP: 17.0Mbps(TCP), 21.5Mbps(UDP)
31
32**Supported SDR platforms:** (Check [Porting guide](#Porting-guide) for your new board if it isn't in the list)
33
34board_name|board combination|status
35-------|-------|----
36zc706_fmcs2|Xilinx ZC706 dev board + FMCOMMS2/3/4|Done
37zed_fmcs2|Xilinx zed board + FMCOMMS2/3/4|Done
38adrv9364z7020|ADRV9364Z7020 SOM|Done
39adrv9361z7035|ADRV9361Z7035 SOM|Done
40zc702_fmcs2|Xilinx ZC702 dev board + FMCOMMS2/3/4|Done
41zcu102_fmcs2|Xilinx ZCU102 dev board + FMCOMMS2/3/4|Done
42zcu102_9371|Xilinx ZCU102 dev board + ADRV9371|Future
43
44- board_name is used to identify FPGA design in openwifi-hw/boards/
45- 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.
46
47[[Quick start](#Quick-start)]
48[[Basic operations](#Basic-operations)]
49[[Update FPGA](#Update-FPGA)]
50[[Update Driver](#Update-Driver)]
51[[Update sdrctl](#Update-sdrctl)]
52[[Easy Access and etc](#Easy-Access-and-etc)]
53
54[[Build openwifi Linux img from scratch](#Build-openwifi-Linux-img-from-scratch)]
55[[Special note for 11b](#Special-note-for-11b)]
56[[Porting guide](#Porting-guide)]
57[[Cite openwifi project](#Cite-openwifi-project)]
58
59## Quick start
60- Burn [openwifi image](https://users.ugent.be/~xjiao/openwifi-1.1.0-taiyuan-2.img.xz) into a SD card ("Open With Disk Image Writer". Or "dd" command after unzip). The SD card has 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:
61  - Copy files in **openwifi/board_name** to the base directory of BOOT partiton.
62  - Copy **openwifi/zynqmp-common/Image** (zcu102 board) or **openwifi/zynq-common/uImage** (other boards) to the base directory of BOOT partiton
63- 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.
64- Power on. login to the board from your PC (PC Ethernet should have IP 192.168.10.1) with one time password **analog**.
65  ```
66  ssh [email protected]
67  ```
68- Setup routing/NAT **on the PC** for the board -- this is **important** for post installation/config.
69  ```
70  sudo sysctl -w net.ipv4.ip_forward=1
71  sudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE
72  sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX
73  ```
74  **ethX** is the PC NIC name connecting the board. **ethY** is the PC NIC name connecting internet.
75
76  If you want, uncommenting "net.ipv4.ip_forward=1" in /etc/sysctl.conf to make IP forwarding persistent on PC.
77- Run **one time** script on board to complete post installation/config (After this, password becomes **openwifi**)
78  ```
79  cd ~/openwifi && ./post_config.sh
80  ```
81- Run openwifi AP together with the on board webserver
82  ```
83  ~/openwifi/fosdem.sh
84  ```
85- After you see the "openwifi" SSID on your device (Phone/Laptop/etc), connect it. Browser to 192.168.13.1 on your deivce, you should see the webpage hosted by the webserver on board.
86  - Note 1: If your device doesn't support 5GHz (ch44), please change the **hostapd-openwifi.conf** on board and re-run fosdem.sh.
87  - 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)
88
89## Basic operations
90The 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.
91- Bring up the openwifi NIC sdr0:
92  ```
93  cd ~/openwifi && ./wgd.sh
94  ```
95- Use openwifi as client to connect other AP (Change wpa-connect.conf on board firstly):
96  ```
97  route del default gw 192.168.10.1
98  wpa_supplicant -i sdr0 -c wpa-connect.conf &
99  dhclient sdr0
100  ```
101- Use openwifi in ad-hoc mode: Please check **sdr-ad-hoc-up.sh** and **sdr-ad-hoc-join.sh**.
102- Use openwifi in monitor mode: Please check **monitor_ch.sh**.
103- 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.
104- **sdrctl** is a dedicated tool to access openwifi driver/FPGA, please check doc directory for more information.
105
106## Update FPGA
107
108Since the pre-built SD card image might not have the latest bug-fixes/updates, it is recommended to udpate the fpga bitstream on board.
109
110- Install Vivado/SDK 2017.4.1 (If you don't need to generate new FPGA bitstream, WebPack version without license is enough)
111- Setup environment variables (use absolute path):
112  ```
113  export XILINX_DIR=your_Xilinx_directory
114  export OPENWIFI_DIR=your_openwifi_directory
115  export BOARD_NAME=your_board_name
116  ```
117- Get the latest FPGA bitstream from openwifi-hw, generate BOOT.BIN and transfer it on board via ssh channel:
118  ```
119  $OPENWIFI_DIR/user_space/get_fpga.sh $OPENWIFI_DIR
120
121  For Zynq 7000:
122  $OPENWIFI_DIR/user_space/boot_bin_gen.sh $OPENWIFI_DIR $XILINX_DIR $BOARD_NAME
123
124  For Zynq MPSoC (like zcu102 board):
125  $OPENWIFI_DIR/user_space/boot_bin_gen_zynqmp.sh $OPENWIFI_DIR $XILINX_DIR $BOARD_NAME
126
127  scp $OPENWIFI_DIR/kernel_boot/boards/$BOARD_NAME/output_boot_bin/BOOT.BIN [email protected]:
128  ```
129- On board: Put the BOOT.BIN into the BOOT partition.
130  ```
131  mount /dev/mmcblk0p1 /mnt
132  cp ~/BOOT.BIN /mnt
133  umount /mnt
134  ```
135  **Power cycle** the board to load new FPGA bitstream.
136
137## Update Driver
138
139Since the pre-built SD card image might not have the latest bug-fixes/updates, it is recommended to udpate the driver on board.
140- Prepare Analog Devices Linux kernel source code (only need to run once):
141  ```
142  $OPENWIFI_DIR/user_space/prepare_kernel.sh $OPENWIFI_DIR $XILINX_DIR ARCH_BIT
143  (For Zynq 7000, ARCH_BIT should be 32, for Zynq MPSoC, ARCH_BIT should be 64)
144  ```
145- Compile the latest openwifi driver
146  ```
147  $OPENWIFI_DIR/driver/make_all.sh $OPENWIFI_DIR $XILINX_DIR ARCH_BIT
148  (For Zynq 7000, ARCH_BIT should be 32, for Zynq MPSoC, ARCH_BIT should be 64)
149  ```
150- Copy the driver files to the board via ssh channel
151  ```
152  scp `find $OPENWIFI_DIR/driver/ -name \*.ko` [email protected]:openwifi/
153  ```
154  Now you can use **wgd.sh** on board to load the new openwifi driver.
155
156## Update sdrctl
157- Copy the sdrctl source files to the board via ssh channel
158  ```
159  scp `find $OPENWIFI_DIR/user_space/sdrctl_src/ -name \*.*` [email protected]:openwifi/sdrctl_src/
160  ```
161- Compile the sdrctl **on board**:
162  ```
163  cd ~/openwifi/sdrctl_src/ && make && cp sdrctl ../ && cd ..
164  ```
165## Easy Access and etc
166
167- FPGA and driver on board update scripts
168  - Setup [ftp server](https://help.ubuntu.com/lts/serverguide/ftp-server.html) on PC, allow anonymous and change ftp root directory to $OPENWIFI_DIR.
169  - On board:
170  ```
171  ./sdcard_boot_update.sh $BOARD_NAME
172  (Above command downloads uImage, BOOT.BIN and devicetree.dtb, then copy them into boot partition. Remember to power cycle)
173  ./wgd.sh remote
174  (Above command downloads driver files, and brings up sdr0)
175  ```
176- Access the board disk/rootfs like a disk:
177   - On PC: "File manager --> Connect to Server...", input: sftp://[email protected]/root
178   - Input password "openwifi"
179
180## Build openwifi Linux img from scratch
181- Download [2019_R1-2020_02_04.img.xz](swdownloads.analog.com/cse/2019_R1-2020_02_04.img.xz) from [Analog Devices Wiki](https://wiki.analog.com/resources/tools-software/linux-software/zynq_images). Burn it to a SD card.
182- 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):
183  ```
184  export SDCARD_DIR=sdcard_mount_point
185  export XILINX_DIR=your_Xilinx_directory
186  export OPENWIFI_DIR=your_openwifi_directory
187  export BOARD_NAME=your_board_name
188  ```
189- Run script to update SD card:
190  ```
191  $OPENWIFI_DIR/user_space/update_sdcard.sh $OPENWIFI_DIR $XILINX_DIR $BOARD_NAME $SDCARD_DIR
192  ```
193- Now you can start from [Quick start](#Quick-start)
194
195## Special note for 11b
196
197Openwifi 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.
198
199As a solution to this problem, openwifi can be fully controlled only if communicating with APs/clients instantiated using hostapd/wpa_supplicant userspace programs respectively.
200
201For 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.
202
203On 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.
204```
205sudo apt-get install libssl1.0-dev
206$OPENWIFI_DIR/user_space/build_wpa_supplicant_wo11b.sh $OPENWIFI_DIR
207```
208## Porting guide
209
210This section explains the porting work by showing the differences between openwifi and Analog Devices reference design. openwifi is based on f61d9707 (2019 r1) of [HDL Reference Designs](https://github.com/analogdevicesinc/hdl).
211- Open the fmcomms2 + zc706 reference design at hdl/projects/fmcomms2/zc706 (Please read Analog Devices help)
212- Open the openwifi design zc706_fmcs2 at openwifi-hw/boards/zc706_fmcs2 (Please read openwifi-hw repository)
213- "Open Block Design", you will see the differences between openwifi and the reference design. Both in "diagram" and in "Address Editor".
214- 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 deivce (FPGA blocks in our case).
215- 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.
216- 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.
217
218## Cite openwifi project
219
220Any use of openwifi project which results in a publication should include a citation via (bibtex example):
221```
222@electronic{openwifigithub,
223            author = {Xianjun, Jiao and Wei, Liu and Michael, Mehari},
224            title = {open-source IEEE802.11/Wi-Fi baseband chip/FPGA design},
225            url = {https://github.com/open-sdr/openwifi},
226            year = {2019},
227}
228```
229Openwifi was born in [ORCA project](https://www.orca-project.eu/) (EU's Horizon2020 programme under agreement number 732174).
230