xref: /openwifi/doc/app_notes/frequent_trick.md (revision 6faed2c4d02cede7eeb145bd7c7cc57517327459)
117cfeb0bSXianjun JiaoSome usual/frequent control trick over the openwifi FPGA. You need to do these controls on board in the openwifi directory.
217cfeb0bSXianjun Jiao
317cfeb0bSXianjun Jiao[[CCA LBT threshold and disable](#CCA-LBT-threshold-and-disable)]
498d83bb1SXianjun Jiao[[Retransmission and ACK control](#Retransmission-and-ACK-control)]
517cfeb0bSXianjun Jiao[[NAV DIFS EIFS CW disable and enable](#NAV-DIFS-EIFS-CW-disable-and-enable)]
617cfeb0bSXianjun Jiao[[CW max and min config](#CW-max-and-min-config)]
717cfeb0bSXianjun Jiao
817cfeb0bSXianjun Jiao[[Rx gain config](#Rx-gain-config)]
917cfeb0bSXianjun Jiao[[Tx power config](#Tx-power-config)]
1017cfeb0bSXianjun Jiao[[Tx Lo and port config](#Tx-Lo-and-port-config)]
1117cfeb0bSXianjun Jiao[[Antenna selection](#Antenna-selection)]
1217cfeb0bSXianjun Jiao[[Restrict the frequency](#Restrict-the-frequency)]
1390a96182SXianjun Jiao[[Receiver sensitivity control](#Receiver-sensitivity-control)]
1417cfeb0bSXianjun Jiao
1517cfeb0bSXianjun Jiao[[Tx rate config](#Tx-rate-config)]
1690a96182SXianjun Jiao[[Arbitrary Tx IQ sample](#Arbitrary-Tx-IQ-sample)]
1717cfeb0bSXianjun Jiao
1817cfeb0bSXianjun Jiao## CCA LBT threshold and disable
1917cfeb0bSXianjun Jiao
2017cfeb0bSXianjun JiaoIn normal operation, different threshold is set to FPGA according to the different calibration of different frequency/channel by driver automatically. Show the current LBT threshold in FPGA:
2117cfeb0bSXianjun Jiao```
2217cfeb0bSXianjun Jiao./set_lbt_th.sh
23*6faed2c4SXianjun Jiaodmesg
2417cfeb0bSXianjun Jiao```
25*6faed2c4SXianjun JiaoIt shows: "sdr,sdr FPGA LBT threshold 166(-62dBm). The last_auto_fpga_lbt_th 166(-62dBm). rssi corr 145". Check rssi_half_db_to_rssi_dbm()/rssi_dbm_to_rssi_half_db() in sdr.c to see the relation to rssi dBm.
2617cfeb0bSXianjun Jiao
2790a96182SXianjun JiaoOverride a new threshold -NNdBm to FPGA, for example -70dBm:
2817cfeb0bSXianjun Jiao```
2990a96182SXianjun Jiao./set_lbt_th.sh 70
30*6faed2c4SXianjun Jiaodmesg
3117cfeb0bSXianjun Jiao```
3217cfeb0bSXianjun JiaoAbove will disable the automatic CCA threshold setting from the openwifi driver.
3317cfeb0bSXianjun Jiao
3417cfeb0bSXianjun JiaoRecover the driver automatic control on the threshold:
3517cfeb0bSXianjun Jiao```
3617cfeb0bSXianjun Jiao./set_lbt_th.sh 0
37*6faed2c4SXianjun Jiaodmesg
3817cfeb0bSXianjun Jiao```
3990a96182SXianjun JiaoDisable the CCA by setting a very strong level as threshold, for example -1dBm:
4017cfeb0bSXianjun Jiao```
4190a96182SXianjun Jiao./set_lbt_th.sh 1
42*6faed2c4SXianjun Jiaodmesg
4317cfeb0bSXianjun Jiao```
4490a96182SXianjun JiaoAfter above command, the CCA engine will always believe the channel is idle, because the rx signal strength not likely could exceed -1dBm.
4517cfeb0bSXianjun Jiao
4698d83bb1SXianjun Jiao## Retransmission and ACK control
4717cfeb0bSXianjun Jiao
4817cfeb0bSXianjun JiaoThe best way of override the maximum number of re-transmission for a Tx packet is doing it in the driver openwifi_tx() function.
4917cfeb0bSXianjun Jiao```
5017cfeb0bSXianjun Jiaoretry_limit_hw_value = ( retry_limit_raw==0?0:((retry_limit_raw - 1)&0xF) );
5117cfeb0bSXianjun Jiao```
5217cfeb0bSXianjun JiaoOverride retry_limit_hw_value to 0 to disable re-transmission. Override it to 1 means that let FPGA do maximum 1 time re-transmission.
5317cfeb0bSXianjun Jiao
5417cfeb0bSXianjun JiaoThe FPGA also has a register to override the re-transmission and ACK behavior. Check the current register value.
5517cfeb0bSXianjun Jiao```
5617cfeb0bSXianjun Jiao./sdrctl dev sdr0 get reg xpu 11
5717cfeb0bSXianjun Jiao```
586aaa1165SXianjun JiaoWhen operate this register, make sure you only change the relevant bits and leave other bits untouched, because other bits have other purposes. Also check the xpu register 11 in the [project document](../README.md)
5917cfeb0bSXianjun Jiao
6017cfeb0bSXianjun JiaoTo override the maximum number of re-transmission, set bit3 to 1, and set the value (0 ~ 7) to bit2 ~ 0. Example, override the maximum number of re-transmission to 1
6117cfeb0bSXianjun Jiao```
6217cfeb0bSXianjun Jiao./sdrctl dev sdr0 set reg xpu 11 9
6317cfeb0bSXianjun Jiao```
6417cfeb0bSXianjun Jiao
6517cfeb0bSXianjun Jiao9 in binary form is 01001.
6617cfeb0bSXianjun Jiao
6798d83bb1SXianjun JiaoTo disable the ACK TX after receiving a packet, set bit4 to 1. (Assume we want to preserve the above re-transmission overriding setting)
6817cfeb0bSXianjun Jiao```
6917cfeb0bSXianjun Jiao./sdrctl dev sdr0 set reg xpu 11 25
7017cfeb0bSXianjun Jiao```
7117cfeb0bSXianjun Jiao
7217cfeb0bSXianjun Jiao25 in binary form is 11001. the 1001 of bit3 to 1 is untouched.
7317cfeb0bSXianjun Jiao
7417cfeb0bSXianjun JiaoDisabling ACK TX might be useful for monitor mode and packet injection.
7517cfeb0bSXianjun Jiao
7698d83bb1SXianjun JiaoTo disable the ACK RX after sending a packet, set bit5 to 1.
7798d83bb1SXianjun Jiao
7817cfeb0bSXianjun Jiao## NAV DIFS EIFS CW disable and enable
7917cfeb0bSXianjun Jiao
8017cfeb0bSXianjun JiaoTo check the current NAV/DIFS/EIFS/CW disable status, just run
8117cfeb0bSXianjun Jiao```
8217cfeb0bSXianjun Jiao./nav_disable.sh
8317cfeb0bSXianjun Jiao./difs_disable.sh
8417cfeb0bSXianjun Jiao./eifs_disable.sh
8517cfeb0bSXianjun Jiao./cw_disable.sh
8617cfeb0bSXianjun Jiao```
8717cfeb0bSXianjun JiaoIf NAV is disabled, the openwifi will always assume the NAV (Network Allocation Vector) is already counting down to 0. If DIFS/EIFS is disabled, when the CSMA engine needs to wait for DIFS/EIFS, it won't wait anymore. If CW is disabled, the contention window is fixed to 0, and there won't be any number of slots for random backoff procedure. To disable them, just input 1 as the script argument.
8817cfeb0bSXianjun Jiao```
8917cfeb0bSXianjun Jiao./nav_disable.sh 1
9017cfeb0bSXianjun Jiao./difs_disable.sh 1
9117cfeb0bSXianjun Jiao./eifs_disable.sh 1
9217cfeb0bSXianjun Jiao./cw_disable.sh 1
9317cfeb0bSXianjun Jiao```
9417cfeb0bSXianjun JiaoTo enable them, just input 0 as the script argument.
9517cfeb0bSXianjun Jiao```
9617cfeb0bSXianjun Jiao./nav_disable.sh 0
9717cfeb0bSXianjun Jiao./difs_disable.sh 0
9817cfeb0bSXianjun Jiao./eifs_disable.sh 0
9917cfeb0bSXianjun Jiao./cw_disable.sh 0
10017cfeb0bSXianjun Jiao```
10117cfeb0bSXianjun Jiao
10217cfeb0bSXianjun Jiao## CW max and min config
10317cfeb0bSXianjun Jiao
10417cfeb0bSXianjun JiaoWhen the openwifi NIC bring up (as AP/Client/ad-hoc/etc), Linux will configure the CW (Contention Window) max and min value for FPGA queue 3 ~ 0 via openwifi_conf_tx() in the openwifi driver. You can check the current CW configuration in FPGA (set by Linux).
10517cfeb0bSXianjun Jiao```
10617cfeb0bSXianjun Jiao./cw_max_min_cfg.sh
10717cfeb0bSXianjun Jiao```
10817cfeb0bSXianjun JiaoIt will show sth like
10917cfeb0bSXianjun Jiao```
11017cfeb0bSXianjun JiaoFPGA  cw max min for q3 to q0: 1023 15; 63 15; 15 7; 7 3
11117cfeb0bSXianjun JiaoFPGA  cw max min for q3 to q0: a4644332
11217cfeb0bSXianjun Jiao```
11317cfeb0bSXianjun JiaoThe CW max and min for q3 ~ 0  are a4, 64, 43, 32 (in hex). Example explanation for q3: in hex the configuration is a4, which means 10 and 4 in the logarithmic domain, (2^10)-1=1023 and (2^4)-1=15 in the linear domain.
11417cfeb0bSXianjun Jiao
11517cfeb0bSXianjun JiaoTo override the CW max and min for queue 3 ~ 0, for example 2047 31; 63 31; 15 7; 7 3, just map it to a hex string b5654332 for queue 3 ~ 0 and give it as the script argument:
11617cfeb0bSXianjun Jiao```
11717cfeb0bSXianjun Jiao./cw_max_min_cfg.sh b5654332
11817cfeb0bSXianjun Jiao```
11917cfeb0bSXianjun JiaoIt will show sth like
12017cfeb0bSXianjun Jiao```
12117cfeb0bSXianjun JiaoFPGA  cw max min for q3 to q0: 2047 31; 63 31; 15 7; 7 3
12217cfeb0bSXianjun JiaoFPGA  cw max min for q3 to q0: b5654332
12317cfeb0bSXianjun JiaoSYSFS cw max min for q3 to q0: 2047 31; 63 31; 15 7; 7 3
12417cfeb0bSXianjun JiaoSYSFS cw max min for q3 to q0: b5654332
12517cfeb0bSXianjun Jiao```
12617cfeb0bSXianjun JiaoTo give the control back to Linux
12717cfeb0bSXianjun Jiao```
12817cfeb0bSXianjun Jiao./cw_max_min_cfg.sh 0
12917cfeb0bSXianjun Jiao```
13017cfeb0bSXianjun JiaoBe careful that above command won't bring the Linux CW max min setting back to FPGA automatically, because Linux normally only call the setting function openwifi_conf_tx() for 1 time when the NIC is started. So either you write down the Linux setting by checking it at the beginning, and set it back via cw_max_min_cfg.sh before giving it argument 0, or re-load the NIC/driver to trigger the Linux setting action for the NIC.
13117cfeb0bSXianjun Jiao
13217cfeb0bSXianjun Jiao## Rx gain config
13317cfeb0bSXianjun Jiao
13417cfeb0bSXianjun JiaoIn normal operation, you don't need to do Rx gain control manually, because it is controled by the AD9361 AGC function. For optimization/experiment purpose, you might want to use the manual rx gain control, you can run
13517cfeb0bSXianjun Jiao```
13617cfeb0bSXianjun Jiao./set_rx_gain_manual.sh 30
13717cfeb0bSXianjun Jiao```
13817cfeb0bSXianjun JiaoAbove command will turn the automatic gain control mode to manual gain control mode, and set 30dB to the Rx gain module.
13917cfeb0bSXianjun Jiao
14017cfeb0bSXianjun JiaoBring it back to the automatic gain control mode
14117cfeb0bSXianjun Jiao```
14217cfeb0bSXianjun Jiao./set_rx_gain_auto.sh
14317cfeb0bSXianjun Jiao```
14417cfeb0bSXianjun JiaoTo find out a good reference about a manual Rx gain setting for the current link/peer, you can set it to automatic mode and then run
14517cfeb0bSXianjun Jiao```
14617cfeb0bSXianjun Jiaorx_gain_show.sh
14717cfeb0bSXianjun Jiao```
14817cfeb0bSXianjun Jiaofor multiple times to check the actual AGC gain vlaue for received packet as explained in this [Access counter/statistics in driver](driver_stat.md). Then you can set the AGC gain value as argument to the **set_rx_gain_manual.sh** with the corret **offset**! For example, if **rx_gain_show.sh** reports a AGC gain value 34 for many successfully received data packets, and you want to use it as a manual gain setting, you need to set
14917cfeb0bSXianjun Jiao```
15017cfeb0bSXianjun Jiao./set_rx_gain_manual.sh 20
15117cfeb0bSXianjun Jiao```
15217cfeb0bSXianjun Jiaoif the current working channel is 5220MHz (34 - 14dB offset = 20). You need to set
15317cfeb0bSXianjun Jiao```
15417cfeb0bSXianjun Jiao./set_rx_gain_manual.sh 29
15517cfeb0bSXianjun Jiao```
15617cfeb0bSXianjun Jiaoif the current working channel is in 2.4GHz  (34 - 5dB offset = 29).
15717cfeb0bSXianjun Jiao
15817cfeb0bSXianjun Jiao## Tx power config
15917cfeb0bSXianjun Jiao```
16017cfeb0bSXianjun Jiao./sdrctl dev sdr0 set reg rf 0 20000
16117cfeb0bSXianjun Jiao```
16217cfeb0bSXianjun JiaoAbove command will set Tx power attenuation to 20dB (20*1000). By default it is 0dB.
16317cfeb0bSXianjun Jiao
16417cfeb0bSXianjun JiaoIf you want an initial attenuation 20dB while loading and bringing up the openwifi NIC, please use the **init_tx_att** argument for the sdr.ko.
16517cfeb0bSXianjun Jiao```
16617cfeb0bSXianjun Jiaoinsmod sdr.ko init_tx_att=20000
16717cfeb0bSXianjun Jiao```
16817cfeb0bSXianjun JiaoYou can change above driver loading action at the end of **wgd.sh**.
16917cfeb0bSXianjun Jiao
17017cfeb0bSXianjun JiaoThe initial Tx attenuation might be useful when you connect two SDR boards directly by cable. Even though, you shouldn't not connect them during the setup phase (bring up the AP or client), because the initialization/tuning of AD9361 might generate big Tx power and kill the other AD9361's Rx. Only connect two SDR boards by cable after both sides have been setup and the attenuation setting takes effect.
17117cfeb0bSXianjun Jiao
1725d6b78c9SJiao XianjunTo increase the Tx power, you can consider add external PA like [this](https://github.com/open-sdr/openwifi/issues/53#issuecomment-767621478). Or increase the value of register 13 of tx_intf (check [README](../README.md)).
1735d6b78c9SJiao Xianjun
1745d6b78c9SJiao XianjunRead the register value:
1755d6b78c9SJiao Xianjun```
1765d6b78c9SJiao Xianjun./sdrctl dev sdr0 get reg tx_intf 13
1775d6b78c9SJiao Xianjun```
1785d6b78c9SJiao Xianjun
1795d6b78c9SJiao XianjunSet the register value to N (a number larger than the value read back above):
1805d6b78c9SJiao Xianjun```
1815d6b78c9SJiao Xianjun./sdrctl dev sdr0 set reg tx_intf 13 N
1825d6b78c9SJiao Xianjun```
1835d6b78c9SJiao XianjunBigger value in that register could hurt the Tx EVM and long packet signal. You need to fine tune it for your case.
1845d6b78c9SJiao Xianjun
18517cfeb0bSXianjun Jiao## Tx Lo and port config
18617cfeb0bSXianjun Jiao
18717cfeb0bSXianjun JiaoIn normal operation, the Tx Lo and RF port are controled by FPGA automatically during signal Tx. To check the current Tx Lo and RF port switch status
18817cfeb0bSXianjun Jiao```
18917cfeb0bSXianjun Jiao./set_tx_port.sh
19017cfeb0bSXianjun Jiao./set_tx_lo.sh
19117cfeb0bSXianjun Jiao```
19217cfeb0bSXianjun JiaoGive argument **1** to above scripts to turn them **ON**, **0** for **OFF**.
19317cfeb0bSXianjun Jiao
19417cfeb0bSXianjun Jiao## Antenna selection
19517cfeb0bSXianjun Jiao
19617cfeb0bSXianjun JiaoBy default, the 1st Tx and Rx antennas are used (tx0 and rx0). You can change the tx antenna to tx1 by
19717cfeb0bSXianjun Jiao```
19817cfeb0bSXianjun Jiao./sdrctl dev sdr0 set reg drv_tx 4 1
19917cfeb0bSXianjun Jiao```
20017cfeb0bSXianjun JiaoChange the tx antenna back to tx0 by
20117cfeb0bSXianjun Jiao```
20217cfeb0bSXianjun Jiao./sdrctl dev sdr0 set reg drv_tx 4 0
20317cfeb0bSXianjun Jiao```
20417cfeb0bSXianjun JiaoChange the rx antenna to rx1 and rx0 by
20517cfeb0bSXianjun Jiao```
20617cfeb0bSXianjun Jiao./sdrctl dev sdr0 set reg drv_rx 4 1
20717cfeb0bSXianjun Jiao./sdrctl dev sdr0 set reg drv_rx 4 0
20817cfeb0bSXianjun Jiao```
20917cfeb0bSXianjun Jiao
21017cfeb0bSXianjun Jiao## Restrict the frequency
21117cfeb0bSXianjun Jiao
21217cfeb0bSXianjun JiaoSince the AD9361 frequency tuning could generate big unwanted Tx noise, and it could damage the other AD9361 Rx during the test via cable, a restricted frequency can be set to avoid the possible frequency tuning (such as the background scan of Wifi). For example, you want the AD9361 works only in 5220Mhz:
21317cfeb0bSXianjun Jiao```
21417cfeb0bSXianjun Jiao./set_restrict_freq.sh 5220
21517cfeb0bSXianjun Jiao```
21617cfeb0bSXianjun JiaoAbove command will fix the AD9361 in 5220MHz and let driver ignore frequency tuning request other than 5220MHz. The restriction can be removed by:
21717cfeb0bSXianjun Jiao```
21817cfeb0bSXianjun Jiao./set_restrict_freq.sh 0
21917cfeb0bSXianjun Jiao```
2201477da16SJiao XianjunTo let openwifi work at arbitrary frequency, please check [Let openwifi work at arbitrary frequency](../README.md#let-openwifi-work-at-arbitrary-frequency)
22190a96182SXianjun Jiao
22290a96182SXianjun Jiao## Receiver sensitivity control
22390a96182SXianjun Jiao
22490a96182SXianjun JiaoSometimes too good sensitivity could be a bad thing. WiFi receiver could be "attracted" by many weak signal/packet in the background, and has less "attention" to its real communication target (client/AP). Openwifi has offered a way to make the receiver less sensitive by setting a threshold. When the received signal is lower than this threshold, the receiver will not try to search the WiFi short preamble, i.e. ignore it. For example, if you want to set -70dBm as the threshold, use:
22590a96182SXianjun Jiao```
22690a96182SXianjun Jiao./sdrctl dev sdr0 set reg drv_rx 0 70
22790a96182SXianjun Jiao```
22890a96182SXianjun Jiao
22917cfeb0bSXianjun Jiao## Tx rate config
23017cfeb0bSXianjun Jiao
23117cfeb0bSXianjun JiaoBy default, the Linux rate adaptation algorithm **minstrel_ht** set the packet rate/MCS automatically via openwifi_tx() function.
23217cfeb0bSXianjun Jiao```
23317cfeb0bSXianjun Jiaorate_hw_value = ieee80211_get_tx_rate(dev, info)->hw_value;
23417cfeb0bSXianjun Jiao```
23517cfeb0bSXianjun JiaoTo override the Linux automatic control for non-ht packet
23617cfeb0bSXianjun Jiao```
23717cfeb0bSXianjun Jiao./sdrctl dev sdr0 set reg drv_tx 0 N
23817cfeb0bSXianjun Jiao```
23917cfeb0bSXianjun JiaoValue N: 0 for Linux auto control; 4 ~ 11 for 6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M.
24017cfeb0bSXianjun Jiao
24117cfeb0bSXianjun JiaoTo override the Linux automatic control for ht packet
24217cfeb0bSXianjun Jiao```
24317cfeb0bSXianjun Jiao./sdrctl dev sdr0 set reg drv_tx 1 N
24417cfeb0bSXianjun Jiao```
24517cfeb0bSXianjun JiaoValue N: 0 for Linux auto control; 4 ~ 11 for 6.5M, 13M, 19.5M, 26M, 39M, 52M, 58.5M, 65M. By default, the normal GI is used. To use the short GI, you need to add 16 to the target value N.
24617cfeb0bSXianjun Jiao
24790a96182SXianjun Jiao## Arbitrary Tx IQ sample
24817cfeb0bSXianjun Jiao
24990a96182SXianjun JiaoArbitrary IQ sample (maximum 512 samples) can be written to tx_intf and sent for test purpose.
250