xref: /openwifi/doc/README.md (revision 17f1faaf26e29452bd8144f4b53a69169826bf8f)
1a6085186SLina Ceballos<!--
291398b98SJiao XianjunAuthor: Xianjun jiao, Michael Mehari, Wei Liu
3b9dde989SJiao XianjunSPDX-FileCopyrightText: 2019 UGent
4a6085186SLina CeballosSPDX-License-Identifier: AGPL-3.0-or-later
5a6085186SLina Ceballos-->
6a6085186SLina Ceballos
7a6085186SLina Ceballos
8da2a8350SJiao Xianjun# Openwifi document
92ee67178SXianjun Jiao<img src="./openwifi-detail.jpg" width="1100">
102ee67178SXianjun Jiao
1190a96182SXianjun JiaoAbove figure shows software and hardware/FPGA modules that compose the openwifi design. The module name is equal/similar to the source code file name. Driver module source codes are in openwifi/driver/. FPGA module source codes are in openwifi-hw repository. The user space tool sdrctl source code are in openwifi/user_space/sdrctl_src/. [Sysfs](https://man7.org/linux/man-pages/man5/sysfs.5.html) is another channel that is offered to do userspace-driver communication by mapping driver variables to virtual files. Check [this app note](app_notes/driver_stat.md#Sysfs-explanation) for further explanation.
122ee67178SXianjun Jiao
13da2a8350SJiao Xianjun- [Driver and software overall principle](#Driver-and-software-overall-principle)
1410d539beSJiao Xianjun- [sdrctl command](#sdrctl-command)
15da2a8350SJiao Xianjun- [Rx packet flow and filtering config](#Rx-packet-flow-and-filtering-config)
16da2a8350SJiao Xianjun- [Tx packet flow and config](#Tx-packet-flow-and-config)
17*17f1faafSJiao Xianjun- [Understand the timestamp of WiFi packet](#Understand-the-timestamp-of-WiFi-packet)
18da2a8350SJiao Xianjun- [Regulation and channel config](#Regulation-and-channel-config)
19da2a8350SJiao Xianjun- [Analog and digital frequency design](#Analog-and-digital-frequency-design)
20da2a8350SJiao Xianjun- [Debug methods](#Debug-methods)
2190a96182SXianjun Jiao- [Test mode driver](#Test-mode-driver)
22b49db4c5SXianjun Jiao- [Application notes](app_notes/README.md)
235f436b3cSJiao Xianjun
24da2a8350SJiao Xianjun## Driver and software overall principle
255f436b3cSJiao Xianjun
2690a96182SXianjun Jiao[Linux mac80211 subsystem](https://www.kernel.org/doc/html/v4.16/driver-api/80211/mac80211.html), as a part of [Linux wireless](https://wireless.wiki.kernel.org/en/developers/documentation/mac80211), defines a set of APIs ([ieee80211_ops](https://www.kernel.org/doc/html/v4.9/80211/mac80211.html#c.ieee80211_ops)) to rule the Wi-Fi chip driver behavior. SoftMAC Wi-Fi chip driver implements (subset of) those APIs. That is why Linux can support so many Wi-Fi chips of different chip vendors. Different mode (AP/Client/ad-hoc/mesh) might need different set of APIs
275f436b3cSJiao Xianjun
285f436b3cSJiao Xianjunopenwifi driver (sdr.c) implements following APIs of ieee80211_ops:
295f436b3cSJiao Xianjun-	**tx**. It is called when upper layer has a packet to send
305f436b3cSJiao Xianjun-	**start**. It is called when NIC up. (ifconfig sdr0 up)
315f436b3cSJiao Xianjun-	**stop**. It is called when NIC down. (ifconfig sdr0 down)
325f436b3cSJiao Xianjun-	**add_interface**. It is called when NIC is created
335f436b3cSJiao Xianjun-	**remove_interface**. It is called when NIC is deleted
345f436b3cSJiao Xianjun-	**config**. It is called when upper layer wants to change channel/frequency (like the scan operation)
3590a96182SXianjun Jiao-	**set_antenna**. Set/select the tx/rx antenna
3690a96182SXianjun Jiao-	**get_antenna**. Read the current tx/rx antenna idx/combination
375f436b3cSJiao Xianjun-	**bss_info_changed**. It is called when upper layer believe some BSS parameters need to be changed (BSSID, TX power, beacon interval, etc)
385f436b3cSJiao Xianjun-	**conf_tx**. It is called when upper layer needs to config/change some tx parameters (AIFS, CW_MIN, CW_MAX, TXOP, etc)
396a6fa9b4Sweiliu1011-	**prepare_multicast**. It is called when upper layer needs to prepare multicast, currently only a empty function hook is present.
404ecf49bbSJiao Xianjun-	**configure_filter**. It is called when upper layer wants to config/change the [frame filtering](#Rx-packet-flow-and-filtering-config) rule in FPGA.
415f436b3cSJiao Xianjun-	**rfkill_poll**. It is called when upper layer wants to know the RF status (ON/OFF).
425f436b3cSJiao Xianjun-	**get_tsf**. It is called when upper layer wants to get 64bit FPGA timer value (TSF - Timing synchronization function)
435f436b3cSJiao Xianjun-	**set_tsf**. It is called when upper layer wants to set 64bit FPGA timer value
445f436b3cSJiao Xianjun-	**reset_tsf**. It is called when upper layer wants to reset 64bit FPGA timer value
455f436b3cSJiao Xianjun-	**set_rts_threshold**. It is called when upper layer wants to change the threshold (packet length) for turning on RTS mechanism
4690a96182SXianjun Jiao-	**ampdu_action**. AMPDU (Aggregated Mac PDU) related operations
475f436b3cSJiao Xianjun-	**testmode_cmd**. It is called when upper layer has test command for us. [sdrctl command](#sdrctl-command) message is handled by this function.
485f436b3cSJiao Xianjun
4990a96182SXianjun JiaoAbove APIs are called by upper layer (Linux mac80211 subsystem). When they are called, the driver (sdr.c) will do necessary job via openwifi FPGA implementation. If necessary, the driver will call other component drivers, like tx_intf_api/rx_intf_api/openofdm_tx_api/openofdm_rx_api/xpu_api, for help.
505f436b3cSJiao Xianjun
514f977aa9SJiao XianjunAfter receiving a packet from the air, FPGA will raise interrupt (if the frame filtering rule allows) to Linux, then the function openwifi_rx_interrupt() of openwifi driver (sdr.c) will be triggered. In that function, ieee80211_rx_irqsafe() API is used to give the packet and related information (timestamp, rssi, etc) to upper layer.
5210d539beSJiao Xianjun
5390a96182SXianjun JiaoThe packet sending is initiated by upper layer towards openwifi driver. After the packet is sent by the driver over FPGA to the air, the upper layer will expect a sending report from the driver. Each time FPGA sends a packet, an interrupt will be raised to Linux and trigger openwifi_tx_interrupt(). This function will report the sending result (failed? succeeded? number of retransmissions, etc.) to upper layer via ieee80211_tx_status_irqsafe() API.
545f436b3cSJiao Xianjun
555f436b3cSJiao Xianjun## sdrctl command
562ee67178SXianjun Jiao
5790a96182SXianjun JiaoBesides the Linux native Wi-Fi control programs, such as ifconfig/iw/iwconfig/iwlist/wpa_supplicant/hostapd/etc, openwifi offers a user space tool sdrctl to access openwifi specific functionalities, such as time sharing of the interface between two network slices, arbitrary Tx/Rx frequency, Tx attenuation, etc. you may find more details of the slicing mechanism [here](https://doc.ilabt.imec.be/ilabt/wilab/tutorials/openwifi.html#sdr-tx-time-slicing).
5862591d26Sweiliu1011
5990a96182SXianjun Jiaosdrctl is implemented as nl80211 testmode command and communicates with openwifi driver (function openwifi_testmode_cmd() in sdrctl_intf.c) via Linux nl80211--cfg80211--mac80211 path
602ee67178SXianjun Jiao
61da2a8350SJiao Xianjun### Get and set a parameter
622ee67178SXianjun Jiao```
632ee67178SXianjun Jiaosdrctl dev sdr0 get para_name
642ee67178SXianjun Jiaosdrctl dev sdr0 set para_name value
652ee67178SXianjun Jiao```
6662591d26Sweiliu1011para_name|meaning|comment
672ee67178SXianjun Jiao---------|-------|----
68c8b47d08SXianjun Jiaoslice_idx|the slice that will be set/get|0 to 3. After finishing all slice config, **set slice_idx to 4** to synchronize all slices. Otherwise the start/end of different slices have different actual time
694ecf49bbSJiao Xianjunaddr|target MAC address of tx slice_idx|32bit. for address 6c:fd:b9:4c:b1:c1, you set b94cb1c1
704ecf49bbSJiao Xianjunslice_total|tx slice_idx cycle length in us|for length 50ms, you set 49999
714ecf49bbSJiao Xianjunslice_start|tx slice_idx cycle start time in us|for start at 10ms, you set 10000
724ecf49bbSJiao Xianjunslice_end|  tx slice_idx cycle end   time in us|for end   at 40ms, you set 39999
73e63d1ec3SXianjun Jiaotsf| sets TSF value| it requires two values "high_TSF low_TSF". Decimal
742ee67178SXianjun Jiao
75da2a8350SJiao Xianjun### Get and set a register of a module
762ee67178SXianjun Jiao```
772ee67178SXianjun Jiaosdrctl dev sdr0 get reg module_name reg_idx
782ee67178SXianjun Jiaosdrctl dev sdr0 set reg module_name reg_idx reg_value
792ee67178SXianjun Jiao```
8090a96182SXianjun Jiaomodule_name **drv_rx**/**drv_tx**/**drv_xpu**/**rf** refers to the corresponding driver functionality. Related registers are defined in sdr.h. Search drv_rx_reg_val/drv_tx_reg_val/drv_xpu_reg_val/rf_reg_val to see their functionalities.
812ee67178SXianjun Jiao
8290a96182SXianjun Jiaomodule_name **rx_intf**/**tx_intf**/**rx**/**tx**/**xpu** FPGA modules (rx_intf/tx_intf/openofdm_rx/openofdm_tx/xpu). Related register addresses are defined in hw_def.h and mapped to slv_regX in .v file (X is the register index). Check rx_intf/tx_intf/openofdm_rx/openofdm_tx/xpu.c and .v files to see their functionalities.
832ee67178SXianjun Jiao
8490a96182SXianjun Jiaomodule name **rf** refers to RF (ad9xxx front-end). The agent register rf_reg_val is defined in sdr.h.
8590a96182SXianjun Jiao
8690a96182SXianjun JiaoPlease be aware that some registers are set by driver in real-time (instructed by Linux mac80211), so be careful when set them manually.
87c8b47d08SXianjun Jiao
88c8b47d08SXianjun Jiaomodule_name: **drv_rx** (for full list, search drv_rx_reg_val in sdr.c)
892ee67178SXianjun Jiao
9062591d26Sweiliu1011reg_idx|meaning|comment
912ee67178SXianjun Jiao-------|-------|----
9290a96182SXianjun Jiao0|receiver action threshold|receiver will not react (short preamble search and further) if the signal strength is less than this threshold. N means -NdBm
9390a96182SXianjun Jiao4|rx antenna selection|0:rx1, 1:rx2
9490a96182SXianjun Jiao7|dmesg print control|please check Debug methods section in this page
952ee67178SXianjun Jiao
96404ff4e0SJiao Xianjun(In the **comment** column, you may get a list of **decimalvalue(0xhexvalue):explanation** for a register, only use the **decimalvalue** in the sdrctl command)
97404ff4e0SJiao Xianjun
98b5a0a70cSXianjun Jiaomodule_name: **drv_tx** (for full list, search drv_tx_reg_val in sdr.c)
992ee67178SXianjun Jiao
10062591d26Sweiliu1011reg_idx|meaning|comment
1012ee67178SXianjun Jiao-------|-------|----
10290a96182SXianjun Jiao0|override Linux rate control of non-ht TX unicast data packet|0:auto by Linux, 4:6M, 5:9M, 6:12M, 7:18M, 8:24M, 9:36M, 10:48M, 11:54M
10390a96182SXianjun Jiao1|override Linux rate control of ht TX unicast data packet|0:auto by Linux, 4:6.5M, 5:13M, 6:19.5M,7:26M, 8:39M, 9:52M, 10:58.5M, 11:65M (add 16 to these values for short GI rate)
10490a96182SXianjun Jiao2|override Linux rate control of vht (11ac)|not implemented yet
10590a96182SXianjun Jiao3|override Linux rate control of he (11ax)|not implemented yet
10690a96182SXianjun Jiao4|tx antenna selection|0:tx1, 1:tx2
10790a96182SXianjun Jiao7|dmesg print control|please check Debug methods section in this page
1082ee67178SXianjun Jiao
109c8b47d08SXianjun Jiaomodule_name: **drv_xpu** (for full list, search drv_xpu_reg_val in sdr.c)
1102ee67178SXianjun Jiao
11162591d26Sweiliu1011reg_idx|meaning|comment
1122ee67178SXianjun Jiao-------|-------|----
11390a96182SXianjun Jiao0|LBT/CCA threshold|0: automatic threshold by ad9361_rf_set_channel(). others -- N means -NdBm fixed threshold
11490a96182SXianjun Jiao7|git revision when build the driver|return the git revision in hex format
1152ee67178SXianjun Jiao
116404ff4e0SJiao Xianjunmodule_name: **rf**
1172ee67178SXianjun Jiao
11862591d26Sweiliu1011reg_idx|meaning|comment
1192ee67178SXianjun Jiao-------|-------|----
12090a96182SXianjun Jiao0|TX attenuation in dB\*1000|example: set to 3000 for 3dB attenuation
12190a96182SXianjun Jiao1|TX frequency in MHz|example: set to 5000 for 5GHz -- override Linux channenl tuning/control
12290a96182SXianjun Jiao5|RX frequency in MHz|example: set to 4000 for 4GHz -- override Linux channenl tuning/control
1232ee67178SXianjun Jiao
124c8b47d08SXianjun Jiaomodule_name: **rx_intf** (for full list, check rx_intf.c and **slv_reg** in rx_intf.v)
1252ee67178SXianjun Jiao
12662591d26Sweiliu1011reg_idx|meaning|comment
1272ee67178SXianjun Jiao-------|-------|----
12890a96182SXianjun Jiao0|reset|each bit is connected to rx_intf.v internal sub-module. 1 -- reset; 0 -- normal
129c8b47d08SXianjun Jiao1|trigger for ILA debug|bit4 and bit0. Please check slv_reg1 in rx_intf.v
1302ee67178SXianjun Jiao2|enable/disable rx interrupt|256(0x100):disable, 0:enable
1316035432bSXianjun Jiao3|get loopback I/Q from tx_intf|256(0x100):from tx_intf, 0:from ad9361 ADC
13290a96182SXianjun Jiao4|baseband clock and IQ fifo in/out control|no use anymore -- for old bb rf independent mode
13390a96182SXianjun Jiao5|control/config dma to cpu|check rx_intf.v slv_reg5
13490a96182SXianjun Jiao6|abnormal packet length threshold|bit31-16 to store the threshold. if the packet length is not in the range of 14 to threshold, terminate the dma to cpu
13590a96182SXianjun Jiao7|source selection of rx dma to cpu|check rx_intf.v slv_reg7
13690a96182SXianjun Jiao8|reserved|reserved
13790a96182SXianjun Jiao9|number of dma symbol to cpu|only valid in manual mode (slv_reg5[5]==1). normally the dma is set automatically by the received packet length
13890a96182SXianjun Jiao10|rx adc fifo reading control|check rx_intf.v slv_reg10
139c8b47d08SXianjun Jiao11|rx digital I/Q gain|number of bit shift to left. default 4 in rx_intf.c: rx_intf_api->RX_INTF_REG_BB_GAIN_write(4)
14090a96182SXianjun Jiao12|timeout/reset control of dma to cpu|check rx_intf.v slv_reg12
14190a96182SXianjun Jiao13|delay from RX DMA complete to RX packet interrupt to cpu|unit 0.1us
14290a96182SXianjun Jiao16|rx antenna selection|0:ant0, 1:ant1. default 0
1432ee67178SXianjun Jiao
144c8b47d08SXianjun Jiaomodule_name: **tx_intf** (for full list, check tx_intf.c and **slv_reg** in tx_intf.v)
1452ee67178SXianjun Jiao
14662591d26Sweiliu1011reg_idx|meaning|comment
1472ee67178SXianjun Jiao-------|-------|----
14890a96182SXianjun Jiao0|reset|each bit is connected to tx_intf.v internal sub-module. 1 -- reset; 0 -- normal
14990a96182SXianjun Jiao1|DUC config or tx arbitrary IQ write port|DUC is removed already. Now it is used to write arbitrary IQ to tx_intf for test purpose
15090a96182SXianjun Jiao2|phy tx auto start config|check tx_intf.v slv_reg2
15190a96182SXianjun Jiao4|CTS to Self config|auto set by cts_reg in openwifi_tx of sdr.c. bit31: enable/disable, bit30: rate selection: 1: use traffic rate, 0: manual rate in bit7-4, bit23-8: duration field
15290a96182SXianjun Jiao5|csi fuzzer config|check CSI fuzzer app note
153c8b47d08SXianjun Jiao6|CTS to Self sending delay (for SIFS)|unit 0.1us. bit13-0 for 2.4GHz, bit29-16 for 5GHz
15490a96182SXianjun Jiao7|tx arbitrary IQ config|check tx_intf.v slv_reg7
15590a96182SXianjun Jiao8|tx config per packet|automatically set per packet in openwifi_tx() via tx_intf_api->TX_INTF_REG_TX_CONFIG_write(tx_config)
15690a96182SXianjun Jiao9|reserved|reserved
15790a96182SXianjun Jiao10|dac input and dma control|check tx_intf.v slv_reg10
158c8b47d08SXianjun Jiao11|threshold for FPGA fifo almost full|driver(sdr.c) read 1bit flag in slv_reg21 (4bit in total for 4 queue) to know the FPGA fifo/queue is almost full.
15990a96182SXianjun Jiao12|threshold to pause openofdm_tx|unit: number of sample. back pressure flow control for I/Q generation speed of openofdm_tx
16090a96182SXianjun Jiao13|tx I/Q digital gain before dac|find the optimal value (and test record) in tx_intf.c: tx_intf_api->TX_INTF_REG_BB_GAIN_write
16190a96182SXianjun Jiao14|tx interrupt config|196612(0x30004):disable, 4:enable. check tx_intv.v slv_reg14
16290a96182SXianjun Jiao15|ampdu action config|set automatically in driver (sdr.c) by openwifi_ampdu_action()
16390a96182SXianjun Jiao16|tx antenna selection and cdd control|bit1: 0 or 1 to select ant0 or 1. bit4: 1 to enable simple cdd (two antennas have 1 sample tx delay)
16490a96182SXianjun Jiao17|phy config per packet|aggregation/rate/GI/ht/non-ht/etc. automatically set by driver tx_intf_api->TX_INTF_REG_PHY_HDR_CONFIG_write(phy_hdr_config)
165c8b47d08SXianjun Jiao21|queue almost full flag|4bit for 4 queue. criteria is the threshold in slv_reg11. check by tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read() in sdr.c
16690a96182SXianjun Jiao22|tx status0 per pkt sent|cw,num_slot_random,linux_prio,tx_queue_idx,bd_wr_idx,num_retrans -- per pkt info read by tx interrupt after the pkt sent
16790a96182SXianjun Jiao23|tx status1 per pkt sent|blk_ack_resp_ssn, pkt_cnt -- per pkt info read by tx interrupt after the pkt sent
16890a96182SXianjun Jiao24|tx status2 per pkt sent|blk_ack_bitmap_low -- per pkt info read by tx interrupt after the pkt sent
16990a96182SXianjun Jiao25|tx status3 per pkt sent|blk_ack_bitmap_high -- per pkt info read by tx interrupt after the pkt sent
17090a96182SXianjun Jiao26|FPGA tx queue runtime length|bit6-0: queue0; bit14-8: queue1; bit22-16: queue2; bit30-24: queue3
1712ee67178SXianjun Jiao
172c8b47d08SXianjun Jiaomodule_name: **rx** (for full list, check openofdm_rx.c and **slv_reg** in openofdm_rx.v)
1732ee67178SXianjun Jiao
17462591d26Sweiliu1011reg_idx|meaning|comment
1752ee67178SXianjun Jiao-------|-------|----
17690a96182SXianjun Jiao0|reset|each bit is connected to openofdm_rx.v internal sub-module. 1 -- reset; 0 -- normal
17790a96182SXianjun Jiao1|channel estimation subcarrier smoothing control|bit0: 1--force smoothing; 0--auto by ht header. bit4: 1--disable all smoothing; 0--let bit0 decide
17890a96182SXianjun Jiao2|power trigger and dc detection threshold|bit10-0: signal level below this threshold won't trigger demodulation. the unit is rssi_half_db, check rssi_half_db_to_rssi_dbm()/rssi_dbm_to_rssi_half_db() in sdr.c to see the relation to rssi dBm. bit23-16: threshold to prevent dc (or low frequency interference) triggered demodulation
17990a96182SXianjun Jiao3|minimum plateau used for short preamble detection|initialized by openofdm_rx.c: openofdm_rx_api->OPENOFDM_RX_REG_MIN_PLATEAU_write
18090a96182SXianjun Jiao4|soft decoding flag and abnormal packet length threshold|bit0 for soft decoding: 0 -- hard, 1 -- soft. bit31-16: if the packet length is not in the range of 14 to this threshold, terminate demodulation.
1812ee67178SXianjun Jiao20|history of PHY rx state|read only. If the last digit readback is always 3, it means the Viterbi decoder stops working
18290a96182SXianjun Jiao31|git revision when build the receiver|returned register value means git revision in hex format
1832ee67178SXianjun Jiao
184c8b47d08SXianjun Jiaomodule_name: **tx** (for full list, check openofdm_tx.c and **slv_reg** in openofdm_tx.v)
1852ee67178SXianjun Jiao
18662591d26Sweiliu1011reg_idx|meaning|comment
1872ee67178SXianjun Jiao-------|-------|----
18890a96182SXianjun Jiao0|reset|each bit is connected to openofdm_tx.v internal sub-module. 1 -- reset; 0 -- normal
18990a96182SXianjun Jiao1|pilot scrambler initial state|lowest 7 bits are used. 127(0x7F) by default in openofdm_tx.c
19090a96182SXianjun Jiao2|data  scrambler initial state|lowest 7 bits are used. 127(0x7F) by default in openofdm_tx.c
19190a96182SXianjun Jiao20|reserved|reserved
1922ee67178SXianjun Jiao
193c8b47d08SXianjun Jiaomodule_name: **xpu** (for full list, check xpu.c and **slv_reg** in xpu.v)
1942ee67178SXianjun Jiao
19562591d26Sweiliu1011reg_idx|meaning|comment
1962ee67178SXianjun Jiao-------|-------|----
19790a96182SXianjun Jiao0|reset|each bit is connected to xpu.v internal sub-module. 1 -- reset; 0 -- normal
19890a96182SXianjun Jiao1|rx packet and I/Q config when tx|bit0 0: auto control (auto self-rx-IQ-mute when tx), 1:manual control by bit31 (1 self-IQ-mute; 0 unmute). bit2 0: rx packet filtering is configured by Linux, 1: no rx packet filtering, send all to Linux
199c8b47d08SXianjun Jiao2|TSF timer low  32bit write|only write this register won't trigger the TSF timer reload. should use together with register for high 31bit
20090a96182SXianjun Jiao3|TSF timer high 31bit write|falling edge of register MSB will trigger the TSF timer reload, which means write '1' then '0' to bit31 (bit30-0 for TSF)
20190a96182SXianjun Jiao4|band, channel and ERP short slot setting|for CSMA engine config. set automatically by Linux. manual set could be overrided unless you change sdr.c
20290a96182SXianjun Jiao5|DIFS and backoff advance (us), abnormal pkt length threshold|advance (us) for tx preparation before the end of DIFS/backoff. bit7-0:DIFS advance, bit15-8: backoff advance. bit31-16: if the packet length is not in the range of 14 to this threshold, terminate pkt filtering procedure
20390a96182SXianjun Jiao6|multi purpose CSMA settings|bit7-0: forced channel idle (us) after decoding done to avoid false alarm caused by strong "AGC tail" signal. bit31: NAV disable, bit30: DIFS disable, bit29: EIFS disable, bit28: dynamic CW disable (when disable, CW is taken from bit19-16). (value 1 -- forced disable; 0 -- normal/enable)
20490a96182SXianjun Jiao7|RSSI and ad9361 gpio/gain delay setting (sync with IQ rssi)|bit26-16: offset for rssi report to Linux; bit6-0 delay (number of sample) of ad9361 gpio/gain to sync with IQ sample rssi/amplitude
20590a96182SXianjun Jiao8|RSSI threshold for CCA (channel idle/busy)|set by ad9361_rf_set_channel automatically. the unit is rssi_half_db, check rssi_half_db_to_rssi_dbm()/rssi_dbm_to_rssi_half_db() in sdr.c to see the relation to rssi dBm
20690a96182SXianjun Jiao9|some low MAC time setting|bit31 0:auto, 1:manual. When manual, bit6-0: PHY rx delay, bit13-7: SIFS, bit18-14: slot time, bit23-19: ofdm symbol time, bit30-24: preamble+SIG time. unit us. check xpu.v (search slv_reg9)
20790a96182SXianjun Jiao10|BB RF delay setting|unit 0.1us. bit7-0: BB RF delay, bit14-8: RF end extended time on top of the delay. bit22-16: delay between bb tx start to RF tx on (lo or port control via spi). bit30-24: delay between bb tx end to RF tx off. check xpu.v (search slv_reg10)
20898d83bb1SXianjun Jiao11|ACK control and max num retransmission|bit4: 0:normal ACK tx/reply, 1:disable auto ACK tx/reply in FPGA. bit5: 0:normal ACK rx from peer, 1:not expecting ACK rx from peer. bit3-0: if bit3==0, the number of retransmission is decided by Linux. if bit3==1, the max num retransmission is taken from bit2-0
20990a96182SXianjun Jiao12|AMPDU control|bit0: indicate low MAC start to receive AMPDU. bit4-1: tid. bit31: tid enable (by default, tid is not enabled and we decode AMPDU of all tid)
21090a96182SXianjun Jiao13|spi controller config|1: disable spi control and Tx RF is always on; 0: enable spi control and Tx RF only on (lo/port) when pkt sending
211c8b47d08SXianjun Jiao16|setting when wait for ACK in 2.4GHz|unit 0.1us. bit14-0: OFDM decoding timeout (after detect PHY header), bit30-16: timeout for PHY header detection, bit31: 0: FCS valid is not needed for ACK packet, 1: FCS valid is needed for ACK packet
212c8b47d08SXianjun Jiao17|setting when wait for ACK in 5GHz|unit 0.1us. bit14-0: OFDM decoding timeout (after detect PHY header), bit30-16: timeout for PHY header detection, bit31: 0: FCS valid is not needed for ACK packet, 1: FCS valid is needed for ACK packet
213c8b47d08SXianjun Jiao18|setting for sending ACK|unit 0.1us. bit14-0: ACK sending delay in 2.4GHz, bit30-16: ACK sending delay in 5GHz
21490a96182SXianjun Jiao19|CW min and max setting for 4 FPGA queues|bit3-0: CW min for queue 0, bit7-4: CW max for queue 0, bit11-8: CW min for queue 1, bit15-12: CW max for queue 1, bit19-16: CW min for queue 2, bit23-20: CW max for queue 2, bit27-24: CW min for queue 3, bit31-28: CW max for queue 3. automatically decided by Linux via openwifi_conf_tx of sdr.c
21590a96182SXianjun Jiao20|slice/queue-tx-gate total cycle length|bit21-20: queue selection. bit19-0: total cycle length in us
21690a96182SXianjun Jiao21|slice/queue-tx-gate start time in the cycle|bit21-20: queue selection. bit19-0: start time in us
21790a96182SXianjun Jiao22|slice/queue-tx-gate end time in the cycle|bit21-20: queue selection. bit19-0: end time in us
218c8b47d08SXianjun Jiao26|CTS to RTS setting|bit15-0: extra duration, bit20-16: rate/MCS, bit31: 0:enable CTStoRTS 1:disable CTStoRTS
21990a96182SXianjun Jiao27|FPGA packet filter config|bit13-0 passing/filter config. bit24-16 dropping config. check openwifi_configure_filter in sdr.c. also [mac80211 frame filtering](https://www.kernel.org/doc/html/v4.9/80211/mac80211.html#frame-filtering)
220c8b47d08SXianjun Jiao28|BSSID address low  32bit for BSSID filtering|auto set by xpu_api->XPU_REG_BSSID_FILTER_LOW_write in openwifi_bss_info_changed of sdr.c
22190a96182SXianjun Jiao29|BSSID address high 16bit for BSSID filtering|auto set by xpu_api->XPU_REG_BSSID_FILTER_HIGH_write in openwifi_bss_info_changed of sdr.c
222c8b47d08SXianjun Jiao30|MAC address low  32bit|auto set by XPU_REG_MAC_ADDR_write in sdr.c
22390a96182SXianjun Jiao31|MAC address high 16bit|auto set by XPU_REG_MAC_ADDR_write in sdr.c
2242ee67178SXianjun Jiao58|TSF runtime value low  32bit|read only
2252ee67178SXianjun Jiao59|TSF runtime value high 32bit|read only
226f6dab9cdSThijs Havinga62|addr2 of rx packet read back|bit31-0 are from bit47-16 of addr2 field in the received packet
22790a96182SXianjun Jiao63|git revision when build the FPGA|returned register value means git revision in hex format
2285f436b3cSJiao Xianjun
229da2a8350SJiao Xianjun## Rx packet flow and filtering config
2305f436b3cSJiao Xianjun
231c8b47d08SXianjun JiaoAfter FPGA receives a packet, no matter the FCS/CRC is correct or not it will raise interrupt to Linux if the frame filtering rule allows (See also [mac80211 frame filtering](https://www.kernel.org/doc/html/v4.9/80211/mac80211.html#frame-filtering)). openwifi_rx_interrupt() function in sdr.c serves the interrupt and gives the necessary information to upper layer (Linux mac80211 subsystem) via ieee80211_rx_irqsafe.
2325f436b3cSJiao Xianjun
23310d539beSJiao Xianjun- frame filtering
23410d539beSJiao Xianjun
23590a96182SXianjun JiaoThe FPGA frame filtering configuration is done by function openwifi_configure_filter() in sdr.c. The filter_flag together with **HIGH_PRIORITY_DISCARD_FLAG** finally go to pkt_filter_ctl.v of xpu module in FPGA, and control how FPGA does frame filtering. Openwifi has the capability to capture all received packets even if the CRC is wrong. You just need to set the NIC to monitor mode by iwconfig command (check monitor_ch.sh in user_space directory). In monitor mode, all received packets (including control packet, like ACK) will be given to Linux mac80211.
23610d539beSJiao Xianjun
23710d539beSJiao Xianjun- main rx interrupt operations in openwifi_rx_interrupt()
2384f977aa9SJiao Xianjun  - get raw content from DMA buffer. When Linux receives interrupt from FPGA rx_intf module, the content has been ready in Linux DMA buffer
23910d539beSJiao Xianjun  - parse extra information inserted by FPGA in the DMA buffer
24010d539beSJiao Xianjun    - TSF timer value
2414f977aa9SJiao Xianjun    - raw RSSI value that will be converted to actual RSSI in dBm by different correction in different bands/channels
24210d539beSJiao Xianjun    - packet length and MCS
24310d539beSJiao Xianjun    - FCS is valid or not
24490a96182SXianjun Jiao  - send packet pointer (skb) and necessary extra information to upper layer via ieee80211_rx_irqsafe()
2455f436b3cSJiao Xianjun
246da2a8350SJiao Xianjun## Tx packet flow and config
2475f436b3cSJiao Xianjun
24810d539beSJiao XianjunLinux mac80211 subsystem calls openwifi_tx() to initiate a packet sending.
24910d539beSJiao Xianjun
25010d539beSJiao Xianjun- main operations in openwifi_tx()
251c8b47d08SXianjun Jiao  - get necessary information from the packet header (struct ieee80211_hdr) for future FPGA configuration
25210d539beSJiao Xianjun    - packet length and MCS
2534f977aa9SJiao Xianjun    - unicast or broadcast? does it need ACK? how many retransmissions at most are allowed to be tried by FPGA in case ACK is not received in time?
25490a96182SXianjun Jiao    - which driver-ring/queue (time slice) in FPGA the packet should go?
25510d539beSJiao Xianjun    - should RTS-CTS be used? (Send RTS and wait for CTS before actually send the data packet)
25610d539beSJiao Xianjun    - should CTS-to-self be used? (Send CTS-to-self packet before sending the data packet. You can force this on by force_use_cts_protect = true;)
25790a96182SXianjun Jiao    - should a sequence number be inserted to the packet at the driver/chip level?
25890a96182SXianjun Jiao  - maintain sequence number (ring->bd_wr_idx) for internal use (cross check between FPGA, openwifi_tx and openwifi_tx_interrupt)
25990a96182SXianjun Jiao  - config FPGA register according to the above information to help FPGA do correct actions (generate PHY header, etc) according to the packet specific requirement.
26090a96182SXianjun Jiao  - fire DMA transmission from Linux to one of FPGA tx queues. The packet may not be sent immediately if there are still some packets in FPGA tx queue (FPGA does the queue packet transmission according to channel and low MAC CSMA state)
26110d539beSJiao Xianjun
2624f977aa9SJiao XianjunEach time when FPGA sends a packet, an interrupt will be raised to Linux reporting the packet sending result. This interrupt handler is openwifi_tx_interrupt().
26310d539beSJiao Xianjun
26410d539beSJiao Xianjun- main operations in openwifi_tx_interrupt()
2654f977aa9SJiao Xianjun  - get necessary information/status of the packet just sent by FPGA
26690a96182SXianjun Jiao    - packet length and sequence number to capture abnormal situation (cross checking between FPGA, openwifi_tx and openwifi_tx_interrupt)
267c8b47d08SXianjun Jiao    - packet sending result: packet is sent successfully (FPGA receives ACK for this packet) or not. How many retransmissions have been done (in case FPGA doesn't receive ACK in time, FPGA will do retransmission according to CSMA/CA low MAC state)
26810d539beSJiao Xianjun  - send above information to upper layer (Linux mac80211 subsystem) via ieee80211_tx_status_irqsafe()
2692309afd4SJiao Xianjun
270*17f1faafSJiao Xianjun## Understand the timestamp of WiFi packet
271*17f1faafSJiao Xianjun
272*17f1faafSJiao XianjunThe TSF timestamp shown in the usual wireshark snapshot is reported by openwifi Linux driver towards Linux mac80211 framework.
273*17f1faafSJiao Xianjun![](https://user-images.githubusercontent.com/5212105/270659135-44a048ae-773f-48a7-bf3f-76ffc3ee399a.jpg)
274*17f1faafSJiao Xianjun
275*17f1faafSJiao XianjunThis TSF timestamp is attached to the DMA of the received packet in FPGA by reading the TSF timier (defined by 802.11 standard and implemented in FPGA) value while PHY header is received: [FPGA code snip](https://github.com/open-sdr/openwifi-hw/blob/14b1e840591f470ee945844cd3bb51a95d7da09f/ip/rx_intf/src/rx_intf_pl_to_m_axis.v#L201).
276*17f1faafSJiao Xianjun
277*17f1faafSJiao XianjunThen openwifi driver report this timestamp value (together with the corresponding packet) to Linux via:
278*17f1faafSJiao Xianjunhttps://github.com/open-sdr/openwifi/blob/0ce2e6b86ade2f6164a373b2e98d075eb7eecd9e/driver/sdr.c#L530
279*17f1faafSJiao Xianjun
280*17f1faafSJiao XianjunTo match the openwifi side channel collected data (CSI, IQ sample, etc.) to the TSF timestamp of the packet, please check: https://github.com/open-sdr/openwifi/discussions/344
281*17f1faafSJiao Xianjun
282da2a8350SJiao Xianjun## Regulation and channel config
2830273d862SJiao Xianjun
28490a96182SXianjun JiaoSDR is a powerful tool for research. It is the user's responsibility to align with local spectrum regulation when doing OTA (Over The Air) test, or do the test via cable (conducted test), or in a chamber to avoid any potential interference.
2850273d862SJiao Xianjun
28690a96182SXianjun JiaoThis section explains how openwifi config the frequency/channel range and change it driven by Linux. The frequency overriding method is also offered by openwifi to allow the system working in any frequency in 70MHz-6GHz.
2870273d862SJiao Xianjun
288da2a8350SJiao Xianjun### Frequency range
2890273d862SJiao Xianjun
2900273d862SJiao XianjunWhen openwifi driver is loaded, openwifi_dev_probe() will be executed. Following two lines configure the frequency range:
2910273d862SJiao Xianjun```
2920273d862SJiao Xianjundev->wiphy->regulatory_flags = xxx
2930273d862SJiao Xianjunwiphy_apply_custom_regulatory(dev->wiphy, &sdr_regd);
2940273d862SJiao Xianjun```
2950273d862SJiao Xianjunsdr_regd is the predefined variable in sdr.h. You can search the definition/meaning of its type: struct ieee80211_regdomain.
2960273d862SJiao Xianjun
297da2a8350SJiao Xianjun### Supported channel
2980273d862SJiao Xianjun
2999d96e692SJiao XianjunThe supported channel list is defined in openwifi_2GHz_channels and openwifi_5GHz_channels in sdr.h. If you change the number of supported channels, make sure you also change the frequency range in sdr_regd accordingly and also array size of the following two fields in the struct openwifi_priv:
3000273d862SJiao Xianjun```
3010273d862SJiao Xianjunstruct ieee80211_channel channels_2GHz[14];
30290a96182SXianjun Jiaostruct ieee80211_channel channels_5GHz[53];
3030273d862SJiao Xianjun```
3040273d862SJiao XianjunFinally, the supported channel list is transferred to Linux mac80211 when openwifi driver is loaded by following two lines in openwifi_dev_probe():
3050273d862SJiao Xianjun```
3060273d862SJiao Xianjundev->wiphy->bands[NL80211_BAND_2GHZ] = &(priv->band_2GHz);
3070273d862SJiao Xianjundev->wiphy->bands[NL80211_BAND_5GHZ] = &(priv->band_5GHz);
3080273d862SJiao Xianjun```
3090273d862SJiao Xianjun
31090a96182SXianjun Jiao### Real-time channel setting and restrict the channel
3110273d862SJiao Xianjun
31290a96182SXianjun JiaoLinux mac80211 (struct ieee80211_ops openwifi_ops in sdr.c) uses the "config" API to configure channel frequency and some other parameters in real-time (such as during scanning or channel setting by iwconfig). It is hooked to openwifi_config() in sdr.c, and supports only frequency setting currently. The real execution of frequency setting falls to ad9361_rf_set_channel() via the "set_chan" field of struct openwifi_rf_ops ad9361_rf_ops in sdr.c. Besides tuning RF front-end (AD9361), the ad9361_rf_set_channel() also handles AD9361 calibration (if the tuning step size >= 100MHz), RSSI compensation for different frequencies and FPGA configurations (SIFS, etc) for different bands.
31390a96182SXianjun Jiao
31490a96182SXianjun JiaoIf you don't want openwifi node to change the channel anymore (even the Linux asks to do so), use the script user_space/set_restrict_freq.sh to limit the frequency.
31590a96182SXianjun Jiao```
31690a96182SXianjun Jiao./set_restrict_freq abcd
31790a96182SXianjun Jiao```
31890a96182SXianjun JiaoAbove will limit the frequency to abcdMHz. For instance, after you setup the working system in channel 44 and you don't want the node to tune to other channel (occasionally driven by Linux scanning for example), input 5220 as argument to the script.
31990a96182SXianjun Jiao```
32090a96182SXianjun Jiao./set_restrict_freq 0
32190a96182SXianjun Jiao```
32290a96182SXianjun JiaoAbove will remove the limitation. Linux driven channel tuning will be recovered.
32390a96182SXianjun Jiao
32490a96182SXianjun Jiao### Let openwifi work at arbitrary frequency
32590a96182SXianjun Jiao
32690a96182SXianjun JiaoBefore setting a non-WiFi frequency to the system, a normal working system should be setup in normal WiFi frequency. After this, you can set it to any frequency in 70MHz-6GHz.
32790a96182SXianjun Jiao```
32890a96182SXianjun Jiao./sdrctl dev sdr0 set reg rf 1 3500
32990a96182SXianjun Jiao```
33090a96182SXianjun JiaoAbove will set the Tx frequency to 3.5GHz.
33190a96182SXianjun Jiao
33290a96182SXianjun Jiao```
33390a96182SXianjun Jiao./sdrctl dev sdr0 set reg rf 5 3500
33490a96182SXianjun Jiao```
33590a96182SXianjun JiaoAbove will set the Rx frequency to 3.5GHz.
3360273d862SJiao Xianjun
337da2a8350SJiao Xianjun## Analog and digital frequency design
338da2a8350SJiao Xianjun
33990a96182SXianjun JiaoOpenwifi has adopted a new RF/baseband frequency and sampling design instead of the original "offset tuning" to achieve better EVM, spectrum mask conformance, sensitivity and RSSI measurement accuracy. The AD9361 is set to FDD working mode with the same Tx and Rx frequency. Realtime AD9361 Tx chain control is done via FPGA SPI interface (openwifi-hw/ip/xpu/src/spi.v) to achieve self-interference free (when Rx) and fast Tx/Rx turn around time (0.6us). The AD9361 Tx lo (local oscillator) or RF switch is turned on before the Tx packet and turned off after the Tx packet. so that there isn't any Tx lo noise leakage during Rx period. The IQ sampling rate between AD9361 and FPGA is 40Msps. It is converted to 20Msps via decimation/interpolation inside FPGA to WiFi baseband transceiver.
340da2a8350SJiao Xianjun
341c8b47d08SXianjun JiaoFollowing figure shows the detailed configuration point in AD9361, driver (.c file) and related FPGA modules (.v file).
3420168c125SJiao Xianjun![](./rf-digital-if-chain-config.jpg)
3430168c125SJiao Xianjun
34490a96182SXianjun JiaoThe openwifi FPGA baseband clock is driven by AD9361 clock, so there won't be any clock drifting/slight-mismatching between RF and baseband as shown in the following picture.
34590a96182SXianjun Jiao![](./bb-clk.jpg)
34690a96182SXianjun Jiao
347da2a8350SJiao Xianjun## Debug methods
3482309afd4SJiao Xianjun
3492309afd4SJiao Xianjun### dmesg
3502309afd4SJiao Xianjun
35190a96182SXianjun JiaoTo debug/see the basic driver behaviour via printk in the sdr.c, you could turn on **dmesg** message printing by
3524ecf49bbSJiao Xianjun```
3537cf9ba6eSXianjun Jiao./sdrctl dev sdr0 set reg drv_tx 7 X
3547cf9ba6eSXianjun Jiao./sdrctl dev sdr0 set reg drv_rx 7 X
3557cf9ba6eSXianjun Jiao
3567cf9ba6eSXianjun JiaoThe bit in value X controls what type of information will be printed to the dmesg (0--no print; 1--print).
3577cf9ba6eSXianjun Jiaobit0: error   message
3587cf9ba6eSXianjun Jiaobit1: regular message for unicast packet (openwifi_tx/openwifi_tx_interrupt/openwifi_rx_interrupt)
3597cf9ba6eSXianjun Jiaobit2: regular message for broadcast packet
36090a96182SXianjun Jiaobit3: regular queue stop/wake-up message due to too much traffic
3617cf9ba6eSXianjun Jiao
3627cf9ba6eSXianjun JiaoFor example, regular message for unicast packet and error message
3634ecf49bbSJiao Xianjun./sdrctl dev sdr0 set reg drv_tx 7 3
3644ecf49bbSJiao Xianjun./sdrctl dev sdr0 set reg drv_rx 7 3
3657cf9ba6eSXianjun Jiao
3667cf9ba6eSXianjun JiaoFor example, error message only:
3674ecf49bbSJiao Xianjun./sdrctl dev sdr0 set reg drv_tx 7 1
3684ecf49bbSJiao Xianjun./sdrctl dev sdr0 set reg drv_rx 7 1
3694ecf49bbSJiao Xianjun```
370c8b47d08SXianjun Jiaoand use **dmesg** command in Linux to see those messages. Regular printing includes tx/rx packet information when a packet is sent or received. Error printing has WARNING information if something abnormal happens. You can search "printk" in sdr.c to see all the printing points.
3712309afd4SJiao Xianjun
372c8b47d08SXianjun Jiao### tx printing example
373c8b47d08SXianjun Jiao```
37490a96182SXianjun Jiaosdr,sdr openwifi_tx: 70B RC0 10M FC0040 DI0000 ADDRffffffffffff/6655443322aa/ffffffffffff flag4001201e QoS00 SC20_1 retr1 ack0 prio0 q0 wr19 rd18
375c8b47d08SXianjun Jiao```
376c8b47d08SXianjun Jiao- printing from sdr driver, openwifi_tx function
37790a96182SXianjun Jiao- 70B: packet size (length field in SIGNAL)
37890a96182SXianjun Jiao- RC0: rate of the packet. enum mac80211_rate_control_flags in Linux kernel mac80211.h
37990a96182SXianjun Jiao- 10M: rate 1Mbps. This 802.11b rate will be converted to 6Mbps, because openwifi supports only OFDM rate.
38090a96182SXianjun Jiao- FC0040: Frame Control field. Example: FC0208 means type data, subtype data, to DS 0, from DS 1 (a packet from AP to client)
38190a96182SXianjun Jiao- DI0000: Duration/ID field
38290a96182SXianjun Jiao- ADDR: address fields addr1/2/3. Target MAC address ffffffffffff (broadcast), source MAC address 6655443322aa (openwifi)
38390a96182SXianjun Jiao- flag4001201e: flags field from Linux mac80211 struct ieee80211_tx_info (first fragment? need ACK? need sequence number insertion? etc.)
38490a96182SXianjun Jiao- QoS00: QoS control byte related to the packet (from Linux mac80211)
38590a96182SXianjun Jiao- SC20_1: sequence number 20 is set to the header of the packet. 1 means that it is set by driver (under request of Linux mac80211)
38690a96182SXianjun Jiao- retr1: retr1 means no retransmission is needed. retr6 means the maximum number of transmissions for this packet is 6 (set by Linux mac80211)
38790a96182SXianjun Jiao- ack0: ack0 means the packet doesn't need ACK; ack1 means the packet needs ACK. (set by Linux mac80211)
38890a96182SXianjun Jiao- prio0: priority queue 0 for this packet (0:VO voice, 1:VI video, 2:BE best effort and 3:BK background). check prio in openwifi_tx() of sdr.c (set by Linux mac80211)
38990a96182SXianjun Jiao- q0: the packet goes to FPGA queue 0. (You can change the mapping between Linux priority and FPGA queue in sdr.c)
39090a96182SXianjun Jiao- wr19 rd18: the write/read index of buffer (shared buffer between the active openwifi_tx and background openwifi_tx_interrupt/FPGA)
3912309afd4SJiao Xianjun
392c8b47d08SXianjun Jiao### tx interrupt printing example
3932238b42bSweiliu```
39490a96182SXianjun Jiaosdr,sdr openwifi_tx_interrupt: tx_result [nof_retx 1 pass 1] SC20 prio0 q0 wr20 rd19 num_slot0 cw0 hwq len00000000 no_room_flag0
3952238b42bSweiliu```
396c8b47d08SXianjun Jiao- printing from sdr driver, openwifi_tx_interrupt function
39790a96182SXianjun Jiao- tx_result [nof_retx 1 pass 1]: nof_retx 1 means the total number of transmission is 1. pass 1 indicates ACK is received. (0 means not)
39890a96182SXianjun Jiao- SC20: sequence number 20
39990a96182SXianjun Jiao- prio, q, wr, rd: these fields can be interpreted the same way as the print in openwifi_tx function
40090a96182SXianjun Jiao- num_slot: tells how many slots the CSMA/CA state machine waited until the packet is sent in the last tx attempt
401c8b47d08SXianjun Jiao- cw: the exponent of the Contention Window for this packet. 6 means the CW size 64. If the contention phase is never entered, CW is 0
4026aaa1165SXianjun Jiao- hwq len: the current FPGA queue length (number of pkt left in the queue).8bit per queue. see tx_intf register 26 in the register table section.
4036aaa1165SXianjun Jiao- no_room_flag: the DMA room of FPGA queue is almost run out. 1bit per queue. see tx_intf register 21 in the register table section.
4042238b42bSweiliu
405c8b47d08SXianjun Jiao### rx printing example
406c8b47d08SXianjun Jiao```
40790a96182SXianjun Jiaosdr,sdr openwifi_rx: 270B ht0aggr0/0 sgi0 240M FC0080 DI0000 ADDRffffffffffff/00c88b113f5f/00c88b113f5f SC2133 fcs1 buf_idx10 -78dBm
408c8b47d08SXianjun Jiao```
409c8b47d08SXianjun Jiao- printing from sdr driver, openwifi_rx_interrupt function
41090a96182SXianjun Jiao- 270B: packet size (length field in SIGNAL)
41190a96182SXianjun Jiao- ht0: ht0 means 11a/g (legacy); ht1 means 11n (ht)
41290a96182SXianjun Jiao- aggr0/0: the 1st digit means the packet is from a AMPDU packet (1) or not (0). the 2nd digit means the packet is the last packet of a AMPDU packet (1) or not (0)
41390a96182SXianjun Jiao- sgi0: 0 means normal GI (Guard Interval); 1 means short GI
41490a96182SXianjun Jiao- 240M:  rate 24Mbps
41590a96182SXianjun Jiao- FC0080: Frame Control field. Example: FC0108 means type data, subtype data, to DS 1, from DS 0 (a packet client to openwifi AP)
41690a96182SXianjun Jiao- DI0000: Duration/ID field
41790a96182SXianjun Jiao- ADDR: address fields addr1/2/3. Target MAC address ffffffffffff (broadcast), source MAC address 00c88b113f5f
41890a96182SXianjun Jiao- SC2133: sequence number 2133 from the header of the packet
4194ecf49bbSJiao Xianjun- fcs1: FCS/CRC is OK. (fcs0 means bad CRC)
42090a96182SXianjun Jiao- buf_idx10: the rx packet is from DMA buffer with index 10
42190a96182SXianjun Jiao- -78dBm: signal strength of this received packet (after calibration)
4222309afd4SJiao Xianjun
423da2a8350SJiao Xianjun### Native Linux tools
4242309afd4SJiao Xianjun
425c8b47d08SXianjun JiaoFor analysis/debug, many native Linux tools you still could rely on. Such as tcpdump, tshark, etc.
4262309afd4SJiao Xianjun
42790a96182SXianjun Jiao### Debug FPGA
4282309afd4SJiao Xianjun
42990a96182SXianjun JiaoFor FPGA itself, FPGA developer could use Xilinx ILA tools to analyze FPGA signals (https://github.com/open-sdr/openwifi-hw/issues/39). Spying on those state machines in xpu/tx_intf/rx_intf would be very helpful for understanding/debugging Wi-Fi low level functionalities.
43090a96182SXianjun Jiao
43190a96182SXianjun Jiao## Test mode driver
43290a96182SXianjun Jiao
43390a96182SXianjun JiaoWhile loading the openwifi driver by "insmod sdr.ko", a test_mode argument can be specified (You can also specify the test_mode value to wgd.sh or fosdem.sh). It will enable some experimental feataures (such as AMPDU aggregation):
43490a96182SXianjun Jiao```
43590a96182SXianjun Jiaoinsmod sdr.ko test_mode=value
43690a96182SXianjun Jiao```
43790a96182SXianjun JiaoIt is implemented by the global static variable test_mode in sdr.c.
43890a96182SXianjun Jiao
43990a96182SXianjun JiaoSupported test_mode value definitions:
44090a96182SXianjun Jiao- bit0: AMPDU/aggregation is ON (1) or OFF (0 -- default OFF)
441