{"id":27867699,"url":"https://github.com/openhd/rtl88x2cu","last_synced_at":"2026-07-10T06:31:32.855Z","repository":{"id":240222628,"uuid":"802022148","full_name":"OpenHD/rtl88x2cu","owner":"OpenHD","description":null,"archived":false,"fork":false,"pushed_at":"2024-06-18T13:16:02.000Z","size":4400,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-01T00:15:47.038Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenHD.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-17T11:16:03.000Z","updated_at":"2025-04-13T15:55:18.000Z","dependencies_parsed_at":"2024-12-26T19:22:20.487Z","dependency_job_id":"948b4df2-1a34-49de-a9b1-14570a08082f","html_url":"https://github.com/OpenHD/rtl88x2cu","commit_stats":{"total_commits":5,"total_committers":1,"mean_commits":5.0,"dds":0.0,"last_synced_commit":"82e041a8b602a244b632e35f60db2e23dae4de0a"},"previous_names":["openhd/rtl88x2cu"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHD%2Frtl88x2cu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHD%2Frtl88x2cu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHD%2Frtl88x2cu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHD%2Frtl88x2cu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenHD","download_url":"https://codeload.github.com/OpenHD/rtl88x2cu/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252411816,"owners_count":21743604,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-04T22:52:27.593Z","updated_at":"2026-07-10T06:31:32.842Z","avatar_url":"https://github.com/OpenHD.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"![realtek_logo](doc/image/realtek_logo.png)\n# rtl88x2cu_ohd\nLinux Driver for WiFi Adapters that are based on the RTL8812CU and RTL8822CU Chipsets, based on driver ```v5.15.0.1-197```\n\nThis branch is mainly focused on FPV and includes the OpenHD-specific naming and configuration overrides.\n\nPRs welcome.\n\n## Hardware \nBL-M8812CU2 or any adaptor based on RTL8812CU/RTL8822CU should be ok.  \n\n## Installation\n### Platform Configuration\nFor arm (32-bit), run: \n```\nsed -i 's/CONFIG_PLATFORM_I386_PC = y/CONFIG_PLATFORM_I386_PC = n/g' Makefile\nsed -i 's/CONFIG_PLATFORM_ARM_RPI = n/CONFIG_PLATFORM_ARM_RPI = y/g' Makefile\n```\nOr, for arm64, run: \n```\nsed -i 's/CONFIG_PLATFORM_I386_PC = y/CONFIG_PLATFORM_I386_PC = n/g' Makefile\nsed -i 's/CONFIG_PLATFORM_ARM64_RPI = n/CONFIG_PLATFORM_ARM64_RPI = y/g' Makefile\n```\n### Build / Install with DKMS\nThis driver can be installed using [DKMS]. This is a system which will automatically recompile and install a kernel module when a new kernel gets installed or updated. To make use of DKMS, install the dkms package, which on Debian (based) systems is done like this:\n```\nsudo apt-get install dkms\n```\n#### Installation of Driver\nIn order to install the driver open a terminal in the directory with the source code and execute the following command:\n```\nsudo ./dkms-install.sh\n```\n#### Removal of Driver\nIn order to remove the driver from your system open a terminal in the directory with the source code and execute the following command:\n```\nsudo ./dkms-remove.sh\n```\n### Build / Install with make\nFor building \u0026 installing the driver with 'make' use\n```\nmake\nsudo make install\n```\n## For setting monitor mode\n### Install tools:\n```\nsudo apt-get install tcpdump wireless-tools net-tools\n```\n### load the driver:\n```\nsudo modprobe cfg80211\nsudo insmod 88x2cu_ohd.ko rtw_tx_pwr_by_rate=0 rtw_tx_pwr_lmt_enable=0\n```\n### Fix problematic interference in monitor mode.\n```\nsudo airmon-ng check kill\n```\n### Set interface down\n```\nsudo ip link set wlan0 down\nor...\nsudo ifconfig wlan0 down\n```\n### Set monitor mode\n```\nsudo airmon-ng start wlan0\nor...\nsudo iw dev wlan0 set type monitor\n```\n### Set interface up\n```\nsudo ip link set wlan0 up\nor...\nsudo ifconfig wlan0 up\n```\n### Set RF channel and bandwidth\n```\niwlist wlan0 channel\n# sudo iw dev wlan0 set channel 165 10MHz\n# sudo iw dev wlan0 set channel 165 5MHz\n# sudo iw dev wlan0 set channel 165 HT40-\n# sudo iw dev wlan0 set channel 165 HT40+\nsudo iw dev wlan0 set channel 165 HT20\n```\n### For setting TX power to a fixed mBm (0=min, 3150=max). \nThe real TX power measured increased accordingly when increasing the mbm value. When mbm increases by 500, the signal strength increases by +5dB, but when mbm is higher than ~2000, the PA starts to saturate and the increase becomes smaller\n```\nsudo iw dev wlan0 set txpower fixed \u003cmBm\u003e\n```\n\n```iw``` will not show the correct value if the TX power has been overridden. To check the current setting, the only table is to:\n```\ncat /proc/net/rtl88x2cu_ohd/wlan0/tx_power_idx\n```\n\nNote: TX power setting for Realtek chips is some internal, dimensionless value, only positively related to the real TX power. One of the goals in \"MP calibration\" is to find the value set of the TX power index, to keep the TX power in every channel at the same level the datasheet gives, then save those values into the crab chip's eFuse. \nThat's the only thing that could match the power index to real dBm without any measurement.\n\n#### ANT0_5825MHz_20M_11n_MCS1_mBm=1700\nRF power 21dBm, offset 4dB for  tx_power_idx, EVM -20dB, Mask Margins 6dB(min). \n![realtek_logo](doc/image/ANT0_5825MHz_20M_11n_MCS1_mBm=1700.jpg)\n\n#### ANT0_5825MHz_20M_11n_MCS1_mBm=1800\nRF power 23dBm, offset 5dB for  tx_power_idx, EVM -15dB, Mask Margins -1dB(min). Tx performance has deteriorated.\n![realtek_logo](doc/image/ANT0_5825MHz_20M_11n_MCS1_mBm=1800.jpg)\n\n#### ANT0_5825MHz_20M_11n_MCS1_mBm=2000\nRF power 24.4dBm, offset 4dB for  tx_power_idx, EVM -13dB, Mask Margins -5dB(min). Tx performance has deteriorated.\n![realtek_logo](doc/image/ANT0_5825MHz_20M_11n_MCS1_mBm=2000.jpg)\n\n#### ANT0_5825MHz_20MHz_11n_MCS7_mBm=1200\nRF power 18dBm, offset 6dB for  tx_power_idx, EVM -29dB, Mask Margins 15dB(min). ```-M 7``` in ```wfb_tx``` to change MCS.\n![realtek_logo](doc/image/ANT0_5825MHz_20MHz_11n_MCS7_mBm=1200.jpg)\n\n### Check RF channel data\nCheck if there is any data on the rf channel.\n```\nsudo tcpdump -i wlan0\n```\n\n## Narrowband Transmission \n### Injection in Different Bandwidth\n#### 10MHz Injection\nTo transmit packets in monitor mode using packet injection:\n - Set  on both air \u0026 ground\n ```\n sudo iw dev wlan0 set channel 165 10MHz\n ```\n - Set the inject packet's radiotap header with any **20MHz bandwidth** modulation (legacy/HT20/VHT20; e.g. ```-B 20``` in ```wfb_tx```) \nThen the packet is actually transmitted in 10MHz bandwidth, which seems like being achieved by simply underclocking the baseband.  \nIt's the same on the receiver side, though in which the radiotap header in received packets still indicates a 20MHz bandwidth. You can check that with any SDR receiver or spectrum analyzer.\n\n###### ANT0_5825MHz_10M_11n_MCS1_mBm=1700\nRF power 20dBm, offset 3dB for tx_power_idx, EVM -22dB, Mask Margins 6dB(min). \n![realtek_logo](doc/image/ANT0_5825MHz_10M_11n_MCS1_mBm=1700.jpg)\n\n##### Notes About \"Devices or Resources Busy\" \nWhen ```iw``` says ```Devices or Resources Busy (-16)```, check ```iw \u003cwlan\u003e info``` if the ```iw``` recognized the adaptor is in monitor mode.   \nIf not, ```iw \u003cwlan\u003e set monitor```, then try setting 10MHz again.  \nThat's because:  \n1. The crab driver supports both WEXT and cfg80211 APIs, but it seems that it's not that robust and there's some conflicts exist\n2. the cfg80211 API checks [here](https://github.com/OpenIPC/linux/blob/eb50a943c26845925ff11ccb1651c40fa02c105e/net/wireless/chan.c#L862) if there's any other interface is not in monitor mode\n3. If the monitor mode is set by ```iwconfig```, the process is done by calling the old WEXT APIs, so the cfg80211-based ```iw``` may not get the latest status and think the interface is still in managed mode\n\n##### 5MHz Injection\nTo transmit packets in monitor mode using packet injection:\n - Set  on both air \u0026 ground\n ```\n sudo iw dev wlan0 set channel 165 5MHz\n ```\n###### ANT0_5825MHz_5M_11n_MCS1_mBm=1700\nRF power 20dBm, offset 3dB for tx_power_idx, EVM -22dB, Mask Margins 3dB(min). \n![realtek_logo](doc/image/ANT0_5825MHz_5M_11n_MCS1_mBm=1700.jpg)\n\n##### Note about Changing TX Power in Narrowband Modes\nChanging TX power by ```iw``` will not work when injecting with 10MHz BW.  \nYou should manually set BW back to 20MHz, set TX power, then set BW back again.  \n\n#### 20/40/80MHz Injection\nUse ```iw``` to set channel \u0026 NOHT/HT20/HT40/80MHz bandwidth, then set the correct bandwidth in the radiotap header (can be done by using ```-B``` in wfb-ng)   \n\n### 10MHz BW AP/STA \nAccording to the module vendor's ambiguous document and the crab's mysterious driver tar with a \"_10MHz\" suffix:  \n1. Enable ```CONFIG_NARROWBAND_SUPPORTING``` in ```include/hal_ic_cfg.h``` (in ```#ifdef CONFIG_RTL8822C``` section if using RTL8812CU), then ```#define CONFIG_NB_VALUE RTW_NB_CONFIG_WIDTH_10``` below\n2. Rename ```hal/rtl8822c/hal8822c_fw_10M.*``` into ```hal/rtl8822c/hal8822c_fw.*``` to replace the original firmware\n3. Now you get the \"\u003ctar_name\u003e_10MHz\" driver. Rebuild the driver\n4. ```iw``` Set the channel to 10MHz bandwidth\n5. If there are any tools complain about the Wi-Fi regularities when setting up a 10MHz AP,  try setting the channel plan manually by ```echo 0x3E \u003e /proc/net/rtl88x2cu_ohd/\u003cwlan\u003e/chan_plan```.\n6. Check the ACK timeout setting below if the range is \u003e\\~3km\n7. Check ```/proc/net/rtl88x2cu_ohd/\u003cwlan\u003e/rate_ctl``` for manually control of the rate if needed. See [@Vito-Swift's tutorial here](https://github.com/Vito-Swift/rtl8814au-ext/blob/main/doc/how_to_do_unicast_rc.md)  \n\n## Set (Unlocked) Channel in procfs  \nThe chip's RF synthesizer can work in a bit wider range than regular 5GHz Wi-Fi. May be 5080MHz ~ 6165MHz. \n\nTo see usage.  \n```\ncat /proc/net/rtl88x2cu_ohd/wlan0/monitor_chan_override\n```\n\nUsage: echo \"\u003cchan\u003e \u003cbw\u003e\" \u003e monitor_chan_override.  \nchan:\t16~253, freq=channel*5+5000.  \nbw:\t10/20/40/80, MHz. Not determing the bandwidth, but should be the same as 'iw'.  \n1. To transmit in 6005MHz with 10MHz BW, you should: \n\t - use 'iw' to set the bandwidth to 10MHz in any channel \n\t - use '-B 20' in 'wfb-ng' or any other tools\n\t - echo \"201 10\" \u003e monitor_chan_override\n\n2. To transmit in 5080MHz with 20MHz BW: \n\t - use 'iw' to set the bandwidth to 20MHz in any channel \n\t - use '-B 20' in 'wfb-ng' or any other tools\n\t - echo \"16 20\" \u003e monitor_chan_override\n\n3. To transmit in 5255MHz with 40MHz BW: \n\t - use 'iw' to set the bandwidth to HT40 in any channel \n\t - use '-B 40' in 'wfb-ng' or any other tools\n\t - echo \"51 40\" \u003e monitor_chan_override\n\nDisclaimer: Some chip may not lock on some frequency. There's no guarantee on performance. The unlocked frequency may damage your hardware. You should obey the law, and use it at your own risk.\n\nI decided to use procfs is that it doesn't need any changes in user-space tools, e.g. iw, hostapd.  \nOf course, you can use this \"procfs API\" to set regular channels like 149 or 36. Might be useful when developing any Wi-Fi-based broadcast FPV system with frequency hopping and automatic bandwidth.  \n\nI recommend using ```iw``` to set the channel first if the channel is usable. Only use the procfs method for irregular.  \nThe channel can only be set to any frequency with a 5MHz step since the channel number was directly written into some register, not some divider of the synthesizer. \n\n### ANT0_5925MHz_10M_11n_MCS1_mBm=1700\nRF power 20dBm, offset 3dB for tx_power_idx, EVM -22dB, Mask Margins 7dB(min). \n![realtek_logo](doc/image/ANT0_5925MHz_10M_11n_MCS1_mBm=1700.jpg)\n\n### ANT0_6000MHz_10M_11n_MCS1_mBm=1700\nRF power 19dBm, offset 2dB for tx_power_idx, EVM -26dB, Mask Margins 10dB(min). \n![realtek_logo](doc/image/ANT0_6000MHz_10M_11n_MCS1_mBm=1700.jpg)\n\n### ANT0_6000MHz_10M_11n_MCS1_mBm=1800\nRF power 22dBm, offset 4dB for tx_power_idx, EVM -17dB, Mask Margins -1dB(min). Tx performance has deteriorated.\n![realtek_logo](doc/image/ANT0_6000MHz_10M_11n_MCS1_mBm=1800.jpg)\n\nDISCLAIMER:  \nSome chips' synthesizer's PLL may not lock on some frequency. There's no guarantee of its performance. (Actually, TX power and distortion seem worse in these channels as it's not calibrated. But less interference - it's an either-or)\n\n## EDCCA\n### Override default EDCCA Threshold  \nTo override dafault EDCCA threshold, check ```cat /proc/net/rtl88x2cu_ohd/wlan0/edcca_threshold_jaguar3_override```.  \n\ne.g. ```echo \"1 -30\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/edcca_threshO1d_jaguar3_Override```   \nThat means: before sending any packet, the adaptor checks if there's any signal with higher than -30dBm (L2H) power exists.\nIf there are any, the adaptor will wait until the energy level in the air is lower than -38dBm (H2L). Then your transmission starts.\n\nNote that there are actually two values, L2H and H2L. The L2H is typically set 8dB higher so it creates a hysteresis.\nThe value you're setting is L2H. The H2L is automatically set 8dB lower.\n\n### Disable CCA (EXPERIMENTAL)\n```echo \"1\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/dis_cca```  \nNeeds test. 10/20MHz BW only.  \n\n## ACK Timeout \nProvided by Realtek.\ne.g. Set ACK timeout to 100us:  \n```echo 100 \u003e /proc/net/rtl88x2cu_ohd/wlan0/ack_timeout```  \n\n## 802.11 DCF hacking   \n### SIFS\nEXPERIMENTAL, may not work.  \n```/proc/net/rtl88x2cu_ohd/wlan0/sifs_override```  \n\n### Slot time \nEXPERIMENTAL, may not work.  \n```/proc/net/rtl88x2cu_ohd/wlan0/slottime_override```  \n\nDISCLAIMER: There's no guarantee of its performance.\n\n## Noise Monitor \nUpdate: The code controlled by ```CONFIG_BACKGROUND_NOISE_MONITOR``` is dedicated to Jaguar(1) series (e.g. 8812au), not for Jaguar3 (8812cu/eu). \nThe code used fix gain (IGI), gated the clock of the baseband \u0026 MAC, read ADC data of the I/Q channel via some debug register, calculated the magnitude (can represent the noise floor), and then resumed the clock. So it's doable in any chipset as long as there's an ADC debug register with the definition known, but unfortunately not for 8812cu now.\n\nIf you know anything more about it, please tell us in the issue.  \n\n## Thermometer  \nThe chip contains a thermometer for calibrating the RF part dynamically. It can be used to estimate the chip temperature.  \ne.g. To read the temperature:  \n```\ncat /proc/net/rtl88x2cu_ohd/wlan0/thermal_state \n```\nNote: This value is not accurate enough. The LSB of its ADC only represents 2.5K and contains a measured value as the offset.   \nHowever, it can be used to estimate the status of the chip, \"cool/warm/hot/smoked/crispy\".  \nThe offset can be tuned by ```echo \"\u003coffset\u003e\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/thermal_state```. By default, it's ```32```, based on my measurement.  \n\n## TX NPATH setting  \nRealtek didn't say anything about the feature, but IMO it should be the Cyclic Shift Diversity (CSD) feature (A 'sine wave' can be seen on top of the OFDM spectrum when enabled).  \nOnly works when 1. injecting legacy rates, or 2. injecting in MCS rates with only 1 spatial stream enabled and STBC disabled.  \nUse ```rtw_tx_npath_enable=1``` when ```insmod``` to enable the feature. You can see a significant input current difference.  \nLike the STBC, it's another transmit diversity technique. Need more tests to tell the difference in the FPV scenario.  \n\n## Generating Single Tone  \nTo generate a single tone at the carrier frequency, \n 1. Set monitor mode \u0026 any channel, e.g. ```iwconfig wlan0 mode monitor channel 52``` (5260 MHz)\n 2. ```echo \"1 4\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/single_tone```, in which ```\u003cEN:0/1\u003e```, ```\u003cRF_PATH:0(A)/1(B)/4(AB)\u003e```\n 3. Remember to set ```EN``` back to ```0``` before any normal operation\n\nUseful when generating any signal without PAPR matters.  \nThe amplitude of the sine wave seems can not be controlled. It's only a test mode for the LO, so the functionality may not be good enough.\n\n### Generating the 5.340 GHz Single Tone \n1. Set the adapter to monitor mode (see nic_quick_test.sh). Any 5 GHz channel is ok for the script argument.\n    ```\n    sudo ./nic_quick_test.sh wlan0 60\n    ```\n2. Set the center frequency to 5.340 GHz (Channel 68). The frequency is usually disabled due to wireless regulation, so use /proc\n    ```\n    echo \"68 20\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/monitor_chan_override   # freq = 5000+68*5 = 5340 MHz\n    ```\n3. Generate single tone. The blue square has two IPEX connector J0 and J1 (see BL-M8812CU2 datasheet)\n    ```\n    echo \"1 0\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/single_tone               # Output at J0 only\n    # echo \"1 1\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/single_tone              # Output at J1 only\n    # echo \"1 4\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/single_tone              # Output at both J0 and J1\n    ```\n4. Change to some other frequency\n    ```\n    echo \"0 0\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/single_tone            # !! ALWAYS DISABLE THE OUTPUT FIRST !!\n    echo \"69 20\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/monitor_chan_override   # 5345 MHz\n    echo \"1 0\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/single_tone               # Output at J0 only\n    ```\n5. Change to some other frequency\n    ```\n    echo \"0 0\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/single_tone            # !! ALWAYS DISABLE THE OUTPUT FIRST !!\n    echo \"67 20\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/monitor_chan_override   # 5335 MHz\n    echo \"1 0\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/single_tone               # Output at J0 only\n    ```\n6. Disable the output\n    ```\n    echo \"0 0\" \u003e /proc/net/rtl88x2cu_ohd/wlan0/single_tone               # !! DISABLE THE OUTPUT !!\n    ```\n\n### ANT0_5340MHz_Single_Tone\nRF power 15dBm. \n![realtek_logo](doc/image/ANT0_5340MHz_Single_Tone.jpg)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenhd%2Frtl88x2cu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenhd%2Frtl88x2cu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenhd%2Frtl88x2cu/lists"}