xref: /openwifi/README.md (revision b73660ad79a69a37f3fe788f4f09f51e1255bab5)
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 + ADRV1CRR-BOB carrier board|Done
39adrv9361z7035|ADRV9361Z7035 SOM + ADRV1CRR-BOB carrier board|Done
40adrv9361z7035_fmc|ADRV9361Z7035 SOM + ADRV1CRR-FMC carrier board|Done
41zc702_fmcs2|Xilinx ZC702 dev board + FMCOMMS2/3/4|Done
42zcu102_fmcs2|Xilinx ZCU102 dev board + FMCOMMS2/3/4|Future
43zcu102_9371|Xilinx ZCU102 dev board + ADRV9371|Future
44
45- board_name is used to identify FPGA design in openwifi-hw/boards/
46- 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.
47
48[[Quick start](#Quick-start)]
49[[Basic operations](#Basic-operations)]
50[[Update FPGA](#Update-FPGA)]
51[[Update Driver](#Update-Driver)]
52[[Update sdrctl](#Update-sdrctl)]
53[[Easy Access and etc](#Easy-Access-and-etc)]
54
55[[Build openwifi Linux img from scratch](#Build-openwifi-Linux-img-from-scratch)]
56[[Special note for 11b](#Special-note-for-11b)]
57[[Porting guide](#Porting-guide)]
58[[Cite openwifi project](#Cite-openwifi-project)]
59
60## Quick start
61- Burn [openwifi image](https://users.ugent.be/~xjiao/openwifi-1.1.0-taiyuan.img.xz) into a SD card (Double clikc in Ubuntu or "Open With Disk Image Writer"). You can see two partitions (BOOT and rootfs) when you insert the SD card to your PC. You need to use **correct files in the BOOT partition** according to the **platform you have**. Just **overwrite** the files in the base directory with the files in **board_name** directory of BOOT partiton.
62- Connect two antennas to RXA/TXA ports. Config the board to SD card boot mode (check your board manual). Insert the SD card to the board.
63- Power on. login to the board from your PC (PC Ethernet should have IP 192.168.10.1) with one time password **analog**.
64  ```
65  ssh [email protected]
66  ```
67- Setup routing/NAT **on the PC** for the board -- this is **important** for post installation/config.
68  ```
69  sudo sysctl -w net.ipv4.ip_forward=1
70  sudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE
71  sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX
72  ```
73  **ethX** is the PC NIC name connecting the board. **ethY** is the PC NIC name connecting internet.
74
75  If you want, uncommenting "net.ipv4.ip_forward=1" in /etc/sysctl.conf to make IP forwarding persistent on PC.
76- Run **one time** script on board to complete post installation/config (After this, password becomes **openwifi**)
77  ```
78  cd ~/openwifi && ./post_config.sh
79  ```
80- Run openwifi AP together with the on board webserver
81  ```
82  ~/openwifi/fosdem.sh
83  ```
84- 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.
85  - Note 1: If your device doesn't support 5GHz (ch44), please change the **hostapd-openwifi.conf** on board and re-run fosdem.sh.
86  - Note 2: After ~2 hours, the Viterbi decoder will halt (Xilinx Evaluation License). Just power cycle the board if it happens.
87
88## Basic operations
89The 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.
90- Bring up the openwifi NIC sdr0:
91  ```
92  cd ~/openwifi && ./wgd.sh
93  ```
94- Use openwifi as client to connect other AP (Change wpa-connect.conf on board firstly):
95  ```
96  route del default gw 192.168.10.1
97  wpa_supplicant -i sdr0 -c wpa-connect.conf &
98  dhclient sdr0
99  ```
100- Use openwifi in ad-hoc mode: Please check **sdr-ad-hoc-up.sh** and **sdr-ad-hoc-join.sh**.
101- Use openwifi in monitor mode: Please check **monitor_ch.sh**.
102- 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.
103- **sdrctl** is a dedicated tool to access openwifi driver/FPGA, please check doc directory for more information.
104
105## Update FPGA
106
107Since the pre-built SD card image might not have the latest bug-fixes/updates, it is recommended to udpate the fpga bitstream on board.
108
109- Install Vivado/SDK 2017.4.1 (If you don't need to generate new FPGA bitstream, WebPack version without license is enough)
110- Setup environment variables (use absolute path):
111  ```
112  export XILINX_DIR=your_Xilinx_directory
113  export OPENWIFI_DIR=your_openwifi_directory
114  export BOARD_NAME=your_board_name
115  ```
116- Get the latest FPGA bitstream from openwifi-hw, generate BOOT.BIN and transfer it on board via ssh channel:
117  ```
118  $OPENWIFI_DIR/user_space/get_fpga.sh $OPENWIFI_DIR
119  $OPENWIFI_DIR/user_space/boot_bin_gen.sh $OPENWIFI_DIR $XILINX_DIR $BOARD_NAME
120  scp $OPENWIFI_DIR/kernel_boot/boards/$BOARD_NAME/output_boot_bin/BOOT.BIN [email protected]:
121  ```
122- On board: Put the BOOT.BIN into the BOOT partition.
123  ```
124  mount /dev/mmcblk0p1 /mnt
125  cp ~/BOOT.BIN /mnt
126  umount /mnt
127  ```
128  **Power cycle** the board to load new FPGA bitstream.
129
130## Update Driver
131
132Since the pre-built SD card image might not have the latest bug-fixes/updates, it is recommended to udpate the driver on board.
133- Prepare Analog Devices Linux kernel source code (only need to run once):
134  ```
135  $OPENWIFI_DIR/user_space/prepare_kernel_src.sh $OPENWIFI_DIR $XILINX_DIR
136  ```
137- Compile the latest openwifi driver
138  ```
139  $OPENWIFI_DIR/driver/make_all.sh $OPENWIFI_DIR $XILINX_DIR
140  ```
141- Copy the driver files to the board via ssh channel
142  ```
143  scp `find $OPENWIFI_DIR/driver/ -name \*.ko` [email protected]:openwifi/
144  ```
145  Now you can use **wgd.sh** on board to load the new openwifi driver.
146
147## Update sdrctl
148- Copy the sdrctl source files to the board via ssh channel
149  ```
150  scp `find $OPENWIFI_DIR/user_space/sdrctl_src/ -name \*.*` [email protected]:openwifi/sdrctl_src/
151  ```
152- Compile the sdrctl **on board**:
153  ```
154  cd ~/openwifi/sdrctl_src/ && make && cp sdrctl ../ && cd ..
155  ```
156## Easy Access and etc
157
158- FPGA and driver on board update scripts
159  - Setup [ftp server](https://help.ubuntu.com/lts/serverguide/ftp-server.html) on PC, allow anonymous and change ftp root directory to $OPENWIFI_DIR.
160  - On board:
161  ```
162  ./sdcard_boot_update.sh $BOARD_NAME
163  (Above command downloads uImage, BOOT.BIN and devicetree.dtb, then copy them into boot partition. Remember to power cycle)
164  ./wgd.sh remote
165  (Above command downloads driver files, and brings up sdr0)
166  ```
167- Access the board disk/rootfs like a disk:
168   - On PC: "File manager --> Connect to Server...", input: sftp://[email protected]/root
169   - Input password "openwifi"
170
171## Build openwifi Linux img from scratch
172- Download [2017_R1-2018_01_29.img.xz](http://swdownloads.analog.com/cse/2017_R1-2018_01_29.img.xz) from [Analog Devices Wiki](https://wiki.analog.com/resources/tools-software/linux-software/zynq_images). Burn it to a SD card.
173- 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):
174  ```
175  export SDCARD_DIR=sdcard_mount_point
176  export XILINX_DIR=your_Xilinx_directory
177  export OPENWIFI_DIR=your_openwifi_directory
178  export BOARD_NAME=your_board_name
179  ```
180- Run script to update SD card:
181  ```
182  $OPENWIFI_DIR/user_space/update_sdcard.sh $OPENWIFI_DIR $XILINX_DIR $BOARD_NAME $SDCARD_DIR
183  ```
184- Now you can start from [Quick start](#Quick-start)
185
186## Special note for 11b
187
188Openwifi 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.
189
190As a solution to this problem, openwifi can be fully controlled only if communicating with APs/clients instantiated using hostapd/wpa_supplicant userspace programs respectively.
191
192For 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.
193
194On 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.
195```
196$OPENWIFI_DIR/user_space/build_wpa_supplicant_wo11b.sh $OPENWIFI_DIR
197```
198## Porting guide
199
200This section explains the porting work by showing the differences between openwifi and Analog Devices reference design. We use **2018_r1** of [HDL Reference Designs](https://github.com/analogdevicesinc/hdl).
201- Open the fmcomms2 + zc706 reference design at hdl/projects/fmcomms2/zc706 (Please read Analog Devices help)
202- Open the openwifi design zc706_fmcs2 at openwifi-hw/boards/zc706_fmcs2 (Please read openwifi-hw repository)
203- "Open Block Design", you will see the differences between openwifi and the reference design. Both in "diagram" and in "Address Editor".
204- 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).
205- 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.
206- 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.
207
208## Cite openwifi project
209
210Any use of openwifi project which results in a publication should include a citation via (bibtex example):
211```
212@electronic{openwifigithub,
213            author = {Xianjun, Jiao and Wei, Liu and Michael, Mehari},
214            title = {open-source IEEE802.11/Wi-Fi baseband chip/FPGA design},
215            url = {https://github.com/open-sdr/openwifi},
216            year = {2019},
217}
218```
219Openwifi was born in [ORCA project](https://www.orca-project.eu/) (EU's Horizon2020 programme under agreement number 732174).
220