How to use ZYNQ SDR in Linux mode

Attention

You are not allowed to download any native file from the zc706 board. The source files are available at openwifi github repository.

Boot Linux

The following steps describe how to run an experiment using the zc706 ZYNQ SDR in Linux mode from JTAG. Please download openwifijtagfiles.zip to continue.

  1. Make a reservation of one zc706zynqSDR and its corresponding host machine, currently 3 zc706zynqSDR available, for details refer to Hardware Info ZYNQ SDR.
  2. Start an experiment with one SDR and its corresponding host, eg apuV4 and zc706zyncSDR2. Do not draw any links between the two nodes. Do not specify any image for the nodes, in this case the default image will be used.
  3. After experiment is started, reboot the zc706 board by right click on the zc706 board in jFed, select reboot and then select reboot OS.
  4. Log into the host and establish serial connection to the zc706 board using minicom, launched as follows. In the Serial port setup, device should be /dev/ttyUSB1 on APU and /dev/ttyUSB0 on server16, Hardware Flow Control should be disabled.
sudo apt-get install minicom
sudo minicom -s
  1. Upload openwifijtagfiles.zip the host node, unzip it, you will get the directory openwifijtagfiles
  2. In the ssh terminal, cd openwifijtagfiles ; source /share/xilinx/Vivado/2017.4/settings64.sh and then execute xsdb
  3. In the xsdb console, execute source dow_fsblonly.tcl, after this step, get ready to interrupt uboot auto start in serial console by hitting any key, when you are ready, execute in xsdb console con.
    • If you don’t have u-boot running and see messages such as Unable to open file BOOT.BIN, please refer to the subject Restore rootfs if SD card is corrupted in Advanced Topics.
    • Please note that the first stage boot loader will use whatever FPGA bitstream that is available on the SD card, refer to Update Bitstream if you would like to run a different FPGA bitstream.
  4. When u-boot autoboot is stopped, execute disconnect in xsdb console, and execute run uenvboot in serial console.
  5. Wait and see… after this command normally linux should be booted. You may now also log into the board via ssh, as explained in Initial configuration of OpenWiFi.

Update Bitstream

If you need to update the bitstream running on the FPGA, you need to regenerate BOOT.BIN file and write it to the SD card, this is explained in the following steps.

  1. Generate files on your local machine:
    • Make sure you have the Xilinx SDK installed, setup the enviornment by running source /Your/Path/To/SDK/2017.4/settings64.sh.
    • Copy the new system.hdf file into openwifijtagfiles directory.
    • Compile new BOOT.BIN, fsbl.elf by ./build_boot_bin.sh system.hdf u-boot.elf, you will find the new files in output_boot_bin directory
  2. Upload the new BOOT.BIN, fsbl.elf from your local machine to the host node, copy them to the openwifijtagfiles directory.
  3. Boot linux on zc706 as explained in the previous section, make sure you have network connection to the board, log into the zc706board, and mount the boot partition by ``mkdir /sdcard ; mount /dev/mmcblk0p1 /sdcard/ ``
  4. Copy files from the host node to zc706
    • scp output_boot_bin/BOOT.BIN root@192.168.10.122:/sdcard
    • copy other files, eg devicetree.dtb, uImage if necessary in the same way.
    • update kernel modules if needed as explained on the openwifi repository.
    • update user space spcripts if needed as explained on the openwifi repository.
    • after copying the files, very important, go to the terminal of zc706 and execute umount /sdcard.
  5. On the host node, make sure your newly generated fsbl.elf is in the same folder as the dow_onlyfsbl.tcl script
  6. Power cycle the zc706 board, first execute shutdown now on the zc706 and then power cycle the board in jFed.
  7. Boot the zc706 as explained in the Boot Linux session to use the new configuration.

Initial configuration of OpenWiFi

Then bring up the correct network interface on the host to connect to the ZYNQ board:

  • Eg, on apuV4 run:
sudo ifconfig eth2 up ; sudo ifconfig eth2 192.168.10.254/24 ; ping 192.168.10.122
  • Login to the zc706 board from the apuV4, the default password is openwifi, however it might be a different one (different image or changed by other users), just set a new password with passwd command in serial console if you cannot log in.
ssh root@192.168.10.122 (password: openwifi)
  • Load openwifi driver:
./wgd.sh
  • Bring up openwifi interface sdr0:
ifconfig sdr0 up
  • Run the following commands to check the interface capabilities:
# iwconfig

sdr0      IEEE 802.11  ESSID:off/any
          Mode:Managed  Access Point: Not-Associated   Tx-Power=20 dBm
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off

Followed by:

# iw list

Experiment 1: openwifi NIC as client and connect to an AP

Read this tutorial first: Access point and client.

1 . Configure wlan0 in apuV4 as AP.
You need to set
hw_mode=a
channel=36

for hostapd, because currently the openwifi NIC sdr0 supports only OFDM. Use hostapd /root/hostapd.conf -dd to see more debug information.

2 . operate openwifi NIC sdr0 in zc706.

Run: iwlist sdr0 scan

You should see AP information like:

Cell 01 - Address: 04:F0:21:11:E5:55
          Channel:36
          Frequency:5.18 GHz (Channel 36)
          Quality=41/70  Signal level=-69 dBm
          Encryption key:off
          ESSID:"iperfAP"
          Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s
                    36 Mb/s; 48 Mb/s; 54 Mb/s
          Mode:Master
          Extra:tsf=00000000019c80dc
          Extra: Last beacon: 10ms ago
          IE: Unknown: 000769706572664150
          IE: Unknown: 01088C129824B048606C
          IE: Unknown: 030124
          IE: Unknown: 7F080000000000000040
          IE: Unknown: AF00

Then:

iwconfig sdr0 mode managed
iwconfig sdr0 essid iperfAP
ifconfig sdr0 192.168.1.10/24 up
ping 192.168.1.1

Experiment 2: openwifi communicate with commercial wifi card in ad-hoc mode

You need a commercial wifi card that support IBSS mode. To check the wifi card capability (mode, rate, etc), you can use iw list command. Please make sure they have Wi-Fi card AR9462 or AR93xx. Please avoid nodes with Wi-Fi card AR928X (ZOTAC) , QCA988x or QCA986x/988x (APU).

1 . Start ad-hoc mode of DSS node, for example dssK5 or dssJ5 :

($xxx means a parameter you should specify. The ad-hoc network SSID will be "ad-hoc-test")
($nic_name, the network interface name when you run ifconfig)
($ch_number, Wi-Fi channel number, such as 1, 6, 11)
($ip_addr, IP address you want)

sudo ip link set $nic_name down
sudo iwconfig $nic_name mode ad-hoc
sudo iwconfig $nic_name essid 'ad-hoc-test'
sudo ip link set $nic_name up
sudo iwconfig $nic_name channel $ch_number
sudo ifconfig $nic_name $ip_addr netmask 255.255.255.0
ifconfig
iwconfig $nic_name

(Now you should see … ESSID “ad-hoc-test” … Cell: xx:yy:zz…)

2 . Start ad-hoc mode of node 2 (openwifi or ZOTAC), and let it to join the “ad-hoc-test” network:

($cell should be xx:yy:zz... you saw in node 1)
sudo ip link set $nic_name down
sudo iwconfig $nic_name mode ad-hoc
sudo iwconfig $nic_name essid 'ad-hoc-test'
sudo ip link set $nic_name up
sudo iwconfig $nic_name channel $ch_number
sudo iwconfig $nic_name ap $cell
sudo ifconfig $nic_name $ip_addr netmask 255.255.255.0
ifconfig
iwconfig $nic_name

Advanced topics

Restore rootfs if SD card is corrupted

Follow instructions below if there is no usable rootfs, or if BOOT.BIN is not found

  1. Download a recent openwifi image file from this link, will refer to it as openwifi-xxxx.img in this tutorial.
  2. The first steps (up till step 6) are the same as the normal procedure explained in the section Boot Linux.
  3. The 7th step is replaced by source xsdb_dow_bs_fsbl.tcl, after this step, execute con, interrupt uboot auto start process, and execute bootm 0x3000000 0x2000000 0x2a00000 in the serial console, this will launch linux from the ramdisk.
  4. After linux is booted, in the serial console, give the eth0 an IP address by executing ifconfig eth0 192.168.10.122/24
  5. Configure your host IP accordingly by executing ifconfig eno2 192.168.10.254/24, eno2 can also be eth2, make sure you can ssh to the zynq board using user name root and password root.
  6. In the host, go to the directory where you store the SD card image and execute the following command, this command will take more than half an hour, so be patient.
dd bs=4M if=openwifi-xxxx.img | ssh root@192.168.10.122 dd of=/dev/mmcblk0
  1. Wait until the command completes, and then execute poweroff in the serial console, after that reboot the zc706 board in jFed and use the normal procedure to launch Linux.

SDR TX time slicing

For SDR TX, there is a hardware/FPGA timer based slicing mechanism.

Example of two time slices (2:98 allocation) for explanation:

  • In FPGA, a timer counts from 0 to 50000us again and again.
  • When timer value is between 1000us~50000us, we do tx for slice0 if there are any packets left in the FPGA slice0 queue. (Linux driver receives packets from Linux upper layer, and put packets in FPGA hardware queue. Depending on the target MAC address and type of the packet, driver knows that the packet should be put into FPGA slice0 queue or slice1 queue).
  • For slice1, same procedure except that timer value has to be between 0~1000us. So 0~1000us means 2% (1000/50000) air time of SDR tx, 1000~50000 means 98% (49000/50000) air time of SDR tx.

We only do above slicing operation for unicast data packet. For 802.11 management/control packet or broadcasting packet, we will send immediately, because they don’t belong to any slice and they are important for the whole Wi-Fi network.

Note that all above numbers (10000us, 50000us, etc) are configurable. The minimum time unit is 1us.

Slice config command:

# set SDR tx slice0 target MAC address (assume it is 6c:fd:b9:4c:b1:c1)
     ./sdrctl dev sdr0 set addr0 b94cb1c1
# set SDR tx slice0 cycle length in us
     ./sdrctl dev sdr0 set slice_total0 49999
     # set SDR tx slice0 start time in us
     ./sdrctl dev sdr0 set slice_start0 1000
     # set SDR tx slice0 end time in us
     ./sdrctl dev sdr0 set slice_end0  49999

To set for slice1, just replace those “0” to “1”.

To get value of above configurations, just replace “set” to “get”