├── .github └── workflows │ └── cmake-multi-platform.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── demo └── main.cpp ├── hal ├── Hal8812PhyReg.h ├── Hal8812PwrSeq.c ├── Hal8812PwrSeq.h ├── HalPwrSeqCmd.h ├── HalVerDef.h ├── basic_types.h ├── drv_types.h ├── hal8812a_fw.c ├── hal8812a_fw.h ├── hal_com.h ├── hal_com_reg.h ├── phydm_pre_define.h ├── rtl8812a_hal.h ├── rtl8812a_recv.h ├── rtl8812a_spec.h └── rtw_efuse.h ├── src ├── EepromManager.cpp ├── EepromManager.h ├── Firmware.h ├── FirmwareManager.cpp ├── FirmwareManager.h ├── FrameParser.cpp ├── FrameParser.h ├── HalModule.cpp ├── HalModule.h ├── ParsedRadioPacket.cpp ├── RadioManagementModule.cpp ├── RadioManagementModule.h ├── Radiotap.c ├── RfPath.h ├── Rtl8812aDevice.cpp ├── Rtl8812aDevice.h ├── RtlUsbAdapter.cpp ├── RtlUsbAdapter.h ├── SelectedChannel.h ├── WiFiDriver.cpp ├── WiFiDriver.h ├── ieee80211_radiotap.h ├── logger.h └── registry_priv.h └── txdemo └── main.cpp /.github/workflows/cmake-multi-platform.yml: -------------------------------------------------------------------------------- 1 | # This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform. 2 | # See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml 3 | name: CMake on multiple platforms 4 | 5 | on: 6 | push: 7 | branches: [ "master" ] 8 | pull_request: 9 | branches: [ "master" ] 10 | workflow_dispatch: 11 | 12 | jobs: 13 | build: 14 | runs-on: ${{ matrix.os }} 15 | 16 | strategy: 17 | # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. 18 | fail-fast: false 19 | 20 | # Set up a matrix to run the following 3 configurations: 21 | # 1. 22 | # 2. 23 | # 3. 24 | # 25 | # To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list. 26 | matrix: 27 | os: [ubuntu-latest, windows-latest] 28 | build_type: [Release] 29 | c_compiler: [gcc, clang, cl] 30 | include: 31 | - os: windows-latest 32 | c_compiler: cl 33 | cpp_compiler: cl 34 | - os: ubuntu-latest 35 | c_compiler: gcc 36 | cpp_compiler: g++ 37 | - os: ubuntu-latest 38 | c_compiler: clang 39 | cpp_compiler: clang++ 40 | exclude: 41 | - os: windows-latest 42 | c_compiler: gcc 43 | - os: windows-latest 44 | c_compiler: clang 45 | - os: ubuntu-latest 46 | c_compiler: cl 47 | 48 | steps: 49 | - uses: actions/checkout@v4 50 | 51 | - name: Set reusable strings 52 | # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. 53 | id: strings 54 | shell: bash 55 | run: | 56 | echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" 57 | 58 | - name: Install dependency libraries (Windows) 59 | id: vars 60 | if: runner.os == 'Windows' 61 | run: | 62 | git clone https://github.com/Microsoft/vcpkg.git 63 | cd vcpkg 64 | .\bootstrap-vcpkg.bat 65 | .\vcpkg integrate install 66 | .\vcpkg install libusb 67 | echo ("VCPKG_ROOT=" + "$PWD") >> $env:GITHUB_ENV 68 | 69 | - name: Install dependency libraries (Linux) 70 | if: runner.os == 'Linux' 71 | run: 72 | sudo apt-get install libusb-1.0-0-dev 73 | 74 | - name: Configure CMake (Windows) 75 | if: runner.os == 'Windows' 76 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 77 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 78 | run: > 79 | cmake -B ${{ steps.strings.outputs.build-output-dir }} 80 | -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} 81 | -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} 82 | -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} 83 | -S ${{ github.workspace }} 84 | 85 | - name: Configure CMake (Linux) 86 | if: runner.os == 'Linux' 87 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 88 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 89 | run: > 90 | cmake -B ${{ steps.strings.outputs.build-output-dir }} 91 | -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} 92 | -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} 93 | -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} 94 | -S ${{ github.workspace }} 95 | 96 | - name: Build 97 | # Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). 98 | run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} 99 | 100 | - name: Test 101 | working-directory: ${{ steps.strings.outputs.build-output-dir }} 102 | # Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). 103 | # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail 104 | run: ctest --build-config ${{ matrix.build_type }} 105 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | compile_commands.json 2 | build 3 | .cache 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | 3 | # Set the toolchain file for vcpkg on Windows. 4 | if(WIN32) 5 | set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake") 6 | endif() 7 | 8 | project(Rtl8812auNet) 9 | 10 | # Find pkg-config and then use it to locate libusb. 11 | find_package(PkgConfig REQUIRED) 12 | pkg_check_modules(libusb REQUIRED IMPORTED_TARGET libusb-1.0) 13 | 14 | add_library(WiFiDriver 15 | src/logger.h 16 | 17 | hal/Hal8812PhyReg.h 18 | hal/Hal8812PwrSeq.c 19 | hal/Hal8812PwrSeq.h 20 | hal/basic_types.h 21 | hal/hal8812a_fw.c 22 | hal/hal8812a_fw.h 23 | hal/hal_com_reg.h 24 | hal/rtl8812a_hal.h 25 | hal/rtl8812a_recv.h 26 | hal/rtl8812a_spec.h 27 | 28 | src/ieee80211_radiotap.h 29 | src/EepromManager.cpp 30 | src/EepromManager.h 31 | src/Firmware.h 32 | src/FirmwareManager.cpp 33 | src/FirmwareManager.h 34 | src/FrameParser.cpp 35 | src/FrameParser.h 36 | src/HalModule.cpp 37 | src/HalModule.h 38 | src/ParsedRadioPacket.cpp 39 | src/RadioManagementModule.cpp 40 | src/RadioManagementModule.h 41 | src/Radiotap.c 42 | src/Rtl8812aDevice.cpp 43 | src/Rtl8812aDevice.h 44 | src/RtlUsbAdapter.cpp 45 | src/RtlUsbAdapter.h 46 | src/SelectedChannel.h 47 | src/WiFiDriver.cpp 48 | src/WiFiDriver.h 49 | src/registry_priv.h 50 | ) 51 | 52 | target_compile_features(WiFiDriver PUBLIC cxx_std_20) 53 | 54 | # Link WiFiDriver with libusb as found via pkg-config. 55 | target_link_libraries(WiFiDriver PUBLIC PkgConfig::libusb) 56 | 57 | target_include_directories(WiFiDriver PUBLIC hal) 58 | target_include_directories(WiFiDriver PUBLIC src) 59 | 60 | add_executable(WiFiDriverDemo 61 | demo/main.cpp 62 | ) 63 | target_link_libraries(WiFiDriverDemo PUBLIC WiFiDriver) 64 | 65 | add_executable(WiFiDriverTxDemo 66 | txdemo/main.cpp 67 | ) 68 | target_link_libraries(WiFiDriverTxDemo PUBLIC WiFiDriver PRIVATE PkgConfig::libusb) 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # devourer 2 | The RTL8812AU driver that simply devours its competitors 3 | 4 | ## Installing 5 | 6 | ### Windows 7 | 8 | You can download and install libraries using the vcpkg dependency manager: 9 | 10 | ``` 11 | git clone https://github.com/Microsoft/vcpkg.git 12 | cd vcpkg 13 | .\bootstrap-vcpkg.bat 14 | .\vcpkg integrate install 15 | .\vcpkg install libusb spdlog 16 | ``` 17 | -------------------------------------------------------------------------------- /demo/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "FrameParser.h" 7 | #include "RtlUsbAdapter.h" 8 | #include "WiFiDriver.h" 9 | 10 | #define USB_VENDOR_ID 0x0bda 11 | #define USB_PRODUCT_ID 0x8812 12 | 13 | static void packetProcessor(const Packet &packet) {} 14 | 15 | int main() { 16 | libusb_context *ctx; 17 | int rc; 18 | 19 | auto logger = std::make_shared(); 20 | 21 | rc = libusb_init(&ctx); 22 | if (rc < 0) { 23 | return rc; 24 | } 25 | 26 | libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG); 27 | 28 | libusb_device_handle *dev_handle = 29 | libusb_open_device_with_vid_pid(ctx, USB_VENDOR_ID, USB_PRODUCT_ID); 30 | if (dev_handle == NULL) { 31 | logger->error("Cannot find device {:04x}:{:04x}", USB_VENDOR_ID, 32 | USB_PRODUCT_ID); 33 | libusb_exit(ctx); 34 | return 1; 35 | } 36 | 37 | // Check if the kernel driver attached 38 | if (libusb_kernel_driver_active(dev_handle, 0)) { 39 | rc = libusb_detach_kernel_driver(dev_handle, 0); // detach driver 40 | } 41 | 42 | rc = libusb_claim_interface(dev_handle, 0); 43 | assert(rc == 0); 44 | 45 | WiFiDriver wifi_driver(logger); 46 | auto rtlDevice = wifi_driver.CreateRtlDevice(dev_handle); 47 | rtlDevice->Init(packetProcessor, SelectedChannel{ 48 | .Channel = 36, 49 | .ChannelOffset = 0, 50 | .ChannelWidth = CHANNEL_WIDTH_20, 51 | }); 52 | 53 | rc = libusb_release_interface(dev_handle, 0); 54 | assert(rc == 0); 55 | 56 | libusb_close(dev_handle); 57 | 58 | libusb_exit(ctx); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /hal/Hal8812PwrSeq.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright(c) 2007 - 2017 Realtek Corporation. 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of version 2 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | *****************************************************************************/ 15 | 16 | #include "Hal8812PwrSeq.h" 17 | #include 18 | 19 | /* 20 | drivers should parse below arrays and do the corresponding actions 21 | */ 22 | /* 3 Power on Array */ 23 | WLAN_PWR_CFG rtl8812_power_on_flow[RTL8812_TRANS_CARDEMU_TO_ACT_STEPS + RTL8812_TRANS_END_STEPS] = { 24 | RTL8812_TRANS_CARDEMU_TO_ACT 25 | RTL8812_TRANS_END 26 | }; 27 | 28 | /* 3Radio off GPIO Array */ 29 | WLAN_PWR_CFG rtl8812_radio_off_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_END_STEPS] = { 30 | RTL8812_TRANS_ACT_TO_CARDEMU 31 | RTL8812_TRANS_END 32 | }; 33 | 34 | /* 3Card Disable Array */ 35 | WLAN_PWR_CFG rtl8812_card_disable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + RTL8812_TRANS_END_STEPS] = { 36 | RTL8812_TRANS_ACT_TO_CARDEMU 37 | RTL8812_TRANS_CARDEMU_TO_CARDDIS 38 | RTL8812_TRANS_END 39 | }; 40 | 41 | /* 3 Card Enable Array */ 42 | WLAN_PWR_CFG rtl8812_card_enable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + RTL8812_TRANS_END_STEPS] = { 43 | RTL8812_TRANS_CARDDIS_TO_CARDEMU 44 | RTL8812_TRANS_CARDEMU_TO_ACT 45 | RTL8812_TRANS_END 46 | }; 47 | 48 | /* 3Suspend Array */ 49 | WLAN_PWR_CFG rtl8812_suspend_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_SUS_STEPS + RTL8812_TRANS_END_STEPS] = { 50 | RTL8812_TRANS_ACT_TO_CARDEMU 51 | RTL8812_TRANS_CARDEMU_TO_SUS 52 | RTL8812_TRANS_END 53 | }; 54 | 55 | /* 3 Resume Array */ 56 | WLAN_PWR_CFG rtl8812_resume_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_SUS_STEPS + RTL8812_TRANS_END_STEPS] = { 57 | RTL8812_TRANS_SUS_TO_CARDEMU 58 | RTL8812_TRANS_CARDEMU_TO_ACT 59 | RTL8812_TRANS_END 60 | }; 61 | 62 | 63 | 64 | /* 3HWPDN Array */ 65 | WLAN_PWR_CFG rtl8812_hwpdn_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + RTL8812_TRANS_END_STEPS] = { 66 | RTL8812_TRANS_ACT_TO_CARDEMU 67 | RTL8812_TRANS_CARDEMU_TO_PDN 68 | RTL8812_TRANS_END 69 | }; 70 | 71 | /* 3 Enter LPS */ 72 | WLAN_PWR_CFG rtl8812_enter_lps_flow[RTL8812_TRANS_ACT_TO_LPS_STEPS + RTL8812_TRANS_END_STEPS] = { 73 | /* FW behavior */ 74 | RTL8812_TRANS_ACT_TO_LPS 75 | RTL8812_TRANS_END 76 | }; 77 | 78 | /* 3 Leave LPS */ 79 | WLAN_PWR_CFG rtl8812_leave_lps_flow[RTL8812_TRANS_LPS_TO_ACT_STEPS + RTL8812_TRANS_END_STEPS] = { 80 | /* FW behavior */ 81 | RTL8812_TRANS_LPS_TO_ACT 82 | RTL8812_TRANS_END 83 | }; 84 | -------------------------------------------------------------------------------- /hal/Hal8812PwrSeq.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright(c) 2007 - 2017 Realtek Corporation. 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of version 2 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | *****************************************************************************/ 15 | 16 | 17 | #ifndef __HAL8812PWRSEQ_H__ 18 | #define __HAL8812PWRSEQ_H__ 19 | 20 | #include "HalPwrSeqCmd.h" 21 | 22 | /* 23 | Check document WB-110628-DZ-RTL8195 (Jaguar) Power Architecture-R04.pdf 24 | There are 6 HW Power States: 25 | 0: POFF--Power Off 26 | 1: PDN--Power Down 27 | 2: CARDEMU--Card Emulation 28 | 3: ACT--Active Mode 29 | 4: LPS--Low Power State 30 | 5: SUS--Suspend 31 | 32 | The transision from different states are defined below 33 | TRANS_CARDEMU_TO_ACT 34 | TRANS_ACT_TO_CARDEMU 35 | TRANS_CARDEMU_TO_SUS 36 | TRANS_SUS_TO_CARDEMU 37 | TRANS_CARDEMU_TO_PDN 38 | TRANS_ACT_TO_LPS 39 | TRANS_LPS_TO_ACT 40 | 41 | TRANS_END 42 | */ 43 | #define RTL8812_TRANS_CARDEMU_TO_ACT_STEPS 15 44 | #define RTL8812_TRANS_ACT_TO_CARDEMU_STEPS 15 45 | #define RTL8812_TRANS_CARDEMU_TO_SUS_STEPS 15 46 | #define RTL8812_TRANS_SUS_TO_CARDEMU_STEPS 15 47 | #define RTL8812_TRANS_CARDEMU_TO_PDN_STEPS 15 48 | #define RTL8812_TRANS_PDN_TO_CARDEMU_STEPS 15 49 | #define RTL8812_TRANS_ACT_TO_LPS_STEPS 15 50 | #define RTL8812_TRANS_LPS_TO_ACT_STEPS 15 51 | #define RTL8812_TRANS_END_STEPS 1 52 | 53 | 54 | #define RTL8812_TRANS_CARDEMU_TO_ACT \ 55 | /* format */ \ 56 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 57 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT2, 0},/* disable SW LPS 0x04[10]=0*/ \ 58 | {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ 59 | /*{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, 0}, disable HWPDN 0x04[15]=0*/ \ 60 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, 0},/* disable WL suspend*/ \ 61 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/ \ 62 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT0, 0},/**/ \ 63 | {0x0024, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* 0x24[1] Choose the type of buffer after xosc: nand*/ \ 64 | {0x0028, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0}, /* 0x28[33] Choose the type of buffer after xosc: nand*/ 65 | 66 | #define RTL8812_TRANS_ACT_TO_CARDEMU \ 67 | /* format */ \ 68 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 69 | {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xc00[7:0] = 4 turn off 3-wire */ \ 70 | {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xe00[7:0] = 4 turn off 3-wire */ \ 71 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0}, /* 0x2[0] = 0 RESET BB, CLOSE RF */ \ 72 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ 73 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0}, /* Whole BB is reset*/ \ 74 | /*{0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},//0x1F[7:0] = 0 turn off RF*/ \ 75 | /*{0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, 0},//0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */ \ 76 | {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x2A}, /* 0x07[7:0] = 0x28 sps pwm mode 0x2a for BT coex*/ \ 77 | {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x02, 0},/*0x8[1] = 0 ANA clk = 500k */ \ 78 | /*{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0 | BIT1, 0}, // 0x02[1:0] = 0 reset BB */ \ 79 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ 80 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ 81 | 82 | #define RTL8812_TRANS_CARDEMU_TO_SUS \ 83 | /* format */ \ 84 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 85 | {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xcc},\ 86 | {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xEC},\ 87 | {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x07},/* gpio11 input mode, gpio10~8 output mode */ \ 88 | {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00},/* gpio 0~7 output same value as input ?? */ \ 89 | {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xff},/* gpio0~7 output mode */ \ 90 | {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/* 0x47[7:0] = 00 gpio mode */ \ 91 | {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/* suspend option all off */ \ 92 | {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x80, BIT7},/*0x14[7] = 1 turn on ZCD */ \ 93 | {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, BIT0},/* 0x15[0] =1 trun on ZCD */ \ 94 | {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x10, BIT4},/*0x23[4] = 1 hpon LDO sleep mode */ \ 95 | {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x02, 0},/*0x8[1] = 0 ANA clk = 500k */ \ 96 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, BIT3}, /*0x04[11] = 2b'11 enable WL suspend for PCIe*/ 97 | 98 | #define RTL8812_TRANS_SUS_TO_CARDEMU \ 99 | /* format */ \ 100 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 101 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, 0}, /*0x04[11] = 2b'01enable WL suspend*/ \ 102 | {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x10, 0},/*0x23[4] = 0 hpon LDO sleep mode leave */ \ 103 | {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, 0},/* 0x15[0] =0 trun off ZCD */ \ 104 | {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x80, 0},/*0x14[7] = 0 turn off ZCD */ \ 105 | {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00},/* gpio0~7 input mode */ \ 106 | {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00},/* gpio11 input mode, gpio10~8 input mode */ 107 | 108 | #define RTL8812_TRANS_CARDEMU_TO_CARDDIS \ 109 | /* format */ \ 110 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 111 | /**{0x0194, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0}, //0x194[0]=0 , disable 32K clock*/ \ 112 | /**{0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x94}, //0x93 = 0x94 , 90[30] =0 enable 500k ANA clock .switch clock from 12M to 500K , 90 [26] =0 disable EEprom loader clock*/ \ 113 | {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT2, 0}, /*0x03[2] = 0, reset 8051*/ \ 114 | {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x05}, /*0x80 = 05h if reload fw, fill the default value of host_CPU handshake field*/ \ 115 | {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xcc},\ 116 | {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xEC},\ 117 | {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x07},/* gpio11 input mode, gpio10~8 output mode */ \ 118 | {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00},/* gpio 0~7 output same value as input ?? */ \ 119 | {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xff},/* gpio0~7 output mode */ \ 120 | {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/* 0x47[7:0] = 00 gpio mode */ \ 121 | {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x80, BIT7},/*0x14[7] = 1 turn on ZCD */ \ 122 | {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, BIT0},/* 0x15[0] =1 trun on ZCD */ \ 123 | {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, 0},/*0x12[0] = 0 force PFM mode */ \ 124 | {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x10, BIT4},/*0x23[4] = 1 hpon LDO sleep mode */ \ 125 | {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x02, 0},/*0x8[1] = 0 ANA clk = 500k */ \ 126 | {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07 = 0x20 , SOP option to disable BG/MB*/ \ 127 | {0x001f, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0}, /*0x01f[1]=0 , disable RFC_0 control REG_RF_CTRL_8812 */ \ 128 | {0x0076, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0}, /*0x076[1]=0 , disable RFC_1 control REG_OPT_CTRL_8812 +2 */ \ 129 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, BIT3}, /*0x04[11] = 2b'01 enable WL suspend*/ 130 | 131 | #define RTL8812_TRANS_CARDDIS_TO_CARDEMU \ 132 | /* format */ \ 133 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 134 | {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0},/*0x12[0] = 1 force PWM mode */ \ 135 | {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x80, 0},/*0x14[7] = 0 turn off ZCD */ \ 136 | {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, 0},/* 0x15[0] =0 trun off ZCD */ \ 137 | {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x10, 0},/*0x23[4] = 0 hpon LDO leave sleep mode */ \ 138 | {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00},/* gpio0~7 input mode */ \ 139 | {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00},/* gpio11 input mode, gpio10~8 input mode */ \ 140 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT2, 0}, /*0x04[10] = 0, enable SW LPS PCIE only*/ \ 141 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, 0}, /*0x04[11] = 2b'01enable WL suspend*/ \ 142 | {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT2, BIT2}, /*0x03[2] = 1, enable 8051*/ \ 143 | {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/ \ 144 | {0x0024, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /* 0x24[1] Choose the type of buffer after xosc: schmitt trigger*/ \ 145 | {0x0028, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3}, /* 0x28[33] Choose the type of buffer after xosc: schmitt trigger*/ 146 | 147 | 148 | #define RTL8812_TRANS_CARDEMU_TO_PDN \ 149 | /* format */ \ 150 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 151 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ 152 | 153 | #define RTL8812_TRANS_PDN_TO_CARDEMU \ 154 | /* format */ \ 155 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 156 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ 157 | 158 | #define RTL8812_TRANS_ACT_TO_LPS \ 159 | /* format */ \ 160 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 161 | {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ 162 | {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F},/*Tx Pause*/ \ 163 | {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ 164 | {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ 165 | {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ 166 | {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ 167 | {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xc00[7:0] = 4 turn off 3-wire */ \ 168 | {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xe00[7:0] = 4 turn off 3-wire */ \ 169 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled, and clock are gated, and RF closed*/ \ 170 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ 171 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0}, /* Whole BB is reset*/ \ 172 | {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ 173 | {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ 174 | {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ 175 | 176 | 177 | #define RTL8812_TRANS_LPS_TO_ACT \ 178 | /* format */ \ 179 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 180 | {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/ \ 181 | {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/ \ 182 | {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/ \ 183 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/ \ 184 | {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/ \ 185 | {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/ \ 186 | {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT6 | BIT7, 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/ \ 187 | {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/ \ 188 | {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/ \ 189 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1 | BIT0, BIT1 | BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/ \ 190 | {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ 191 | 192 | #define RTL8812_TRANS_END \ 193 | /* format */ \ 194 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ 195 | {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, 0, PWR_CMD_END, 0, 0}, 196 | 197 | 198 | extern WLAN_PWR_CFG rtl8812_power_on_flow[RTL8812_TRANS_CARDEMU_TO_ACT_STEPS + RTL8812_TRANS_END_STEPS]; 199 | extern WLAN_PWR_CFG rtl8812_radio_off_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_END_STEPS]; 200 | extern WLAN_PWR_CFG rtl8812_card_disable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + RTL8812_TRANS_END_STEPS]; 201 | extern WLAN_PWR_CFG rtl8812_card_enable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + RTL8812_TRANS_END_STEPS]; 202 | extern WLAN_PWR_CFG rtl8812_suspend_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_SUS_STEPS + RTL8812_TRANS_END_STEPS]; 203 | extern WLAN_PWR_CFG rtl8812_resume_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_SUS_STEPS + RTL8812_TRANS_END_STEPS]; 204 | extern WLAN_PWR_CFG rtl8812_hwpdn_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + RTL8812_TRANS_END_STEPS]; 205 | extern WLAN_PWR_CFG rtl8812_enter_lps_flow[RTL8812_TRANS_ACT_TO_LPS_STEPS + RTL8812_TRANS_END_STEPS]; 206 | extern WLAN_PWR_CFG rtl8812_leave_lps_flow[RTL8812_TRANS_LPS_TO_ACT_STEPS + RTL8812_TRANS_END_STEPS]; 207 | 208 | #endif /* __HAL8812PWRSEQ_H__ */ 209 | -------------------------------------------------------------------------------- /hal/HalPwrSeqCmd.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright(c) 2007 - 2017 Realtek Corporation. 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of version 2 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | *****************************************************************************/ 15 | #ifndef __HALPWRSEQCMD_H__ 16 | #define __HALPWRSEQCMD_H__ 17 | 18 | #include 19 | 20 | /*---------------------------------------------*/ 21 | /* 3 The value of cmd: 4 bits 22 | *---------------------------------------------*/ 23 | #define PWR_CMD_READ 0x00 24 | /* offset: the read register offset 25 | * msk: the mask of the read value 26 | * value: N/A, left by 0 27 | * note: dirver shall implement this function by read & msk */ 28 | 29 | #define PWR_CMD_WRITE 0x01 30 | /* offset: the read register offset 31 | * msk: the mask of the write bits 32 | * value: write value 33 | * note: driver shall implement this cmd by read & msk after write */ 34 | 35 | #define PWR_CMD_POLLING 0x02 36 | /* offset: the read register offset 37 | * msk: the mask of the polled value 38 | * value: the value to be polled, masked by the msd field. 39 | * note: driver shall implement this cmd by 40 | * do { 41 | * if( (Read(offset) & msk) == (value & msk) ) 42 | * break; 43 | * } while(not timeout); */ 44 | 45 | #define PWR_CMD_DELAY 0x03 46 | /* offset: the value to delay 47 | * msk: N/A 48 | * value: the unit of delay, 0: us, 1: ms */ 49 | 50 | #define PWR_CMD_END 0x04 51 | /* offset: N/A 52 | * msk: N/A 53 | * value: N/A */ 54 | 55 | /*---------------------------------------------*/ 56 | /* 3 The value of base: 4 bits 57 | *--------------------------------------------- 58 | * define the base address of each block */ 59 | #define PWR_BASEADDR_MAC 0x00 60 | #define PWR_BASEADDR_USB 0x01 61 | #define PWR_BASEADDR_PCIE 0x02 62 | #define PWR_BASEADDR_SDIO 0x03 63 | 64 | /*---------------------------------------------*/ 65 | /* 3 The value of interface_msk: 4 bits 66 | *---------------------------------------------*/ 67 | #define PWR_INTF_SDIO_MSK BIT(0) 68 | #define PWR_INTF_USB_MSK BIT(1) 69 | #define PWR_INTF_PCI_MSK BIT(2) 70 | #define PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) 71 | 72 | /*---------------------------------------------*/ 73 | /* 3 The value of fab_msk: 4 bits 74 | *---------------------------------------------*/ 75 | #define PWR_FAB_TSMC_MSK BIT(0) 76 | #define PWR_FAB_UMC_MSK BIT(1) 77 | #define PWR_FAB_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) 78 | 79 | /*---------------------------------------------*/ 80 | /* 3 The value of cut_msk: 8 bits 81 | *---------------------------------------------*/ 82 | #define PWR_CUT_TESTCHIP_MSK BIT(0) 83 | #define PWR_CUT_A_MSK BIT(1) 84 | #define PWR_CUT_B_MSK BIT(2) 85 | #define PWR_CUT_C_MSK BIT(3) 86 | #define PWR_CUT_D_MSK BIT(4) 87 | #define PWR_CUT_E_MSK BIT(5) 88 | #define PWR_CUT_F_MSK BIT(6) 89 | #define PWR_CUT_G_MSK BIT(7) 90 | #define PWR_CUT_ALL_MSK 0xFF 91 | 92 | 93 | typedef enum _PWRSEQ_CMD_DELAY_UNIT_ { 94 | PWRSEQ_DELAY_US, 95 | PWRSEQ_DELAY_MS, 96 | } PWRSEQ_DELAY_UNIT; 97 | 98 | typedef struct _WL_PWR_CFG_ { 99 | u16 offset; 100 | u8 cut_msk; 101 | u8 fab_msk:4; 102 | u8 interface_msk:4; 103 | u8 base:4; 104 | u8 cmd:4; 105 | u8 msk; 106 | u8 value; 107 | } WLAN_PWR_CFG, *PWLAN_PWR_CFG; 108 | 109 | 110 | #define GET_PWR_CFG_OFFSET(__PWR_CMD) ((__PWR_CMD).offset) 111 | #define GET_PWR_CFG_CUT_MASK(__PWR_CMD) ((__PWR_CMD).cut_msk) 112 | #define GET_PWR_CFG_FAB_MASK(__PWR_CMD) ((__PWR_CMD).fab_msk) 113 | #define GET_PWR_CFG_INTF_MASK(__PWR_CMD) ((__PWR_CMD).interface_msk) 114 | #define GET_PWR_CFG_BASE(__PWR_CMD) ((__PWR_CMD).base) 115 | #define GET_PWR_CFG_CMD(__PWR_CMD) ((__PWR_CMD).cmd) 116 | #define GET_PWR_CFG_MASK(__PWR_CMD) ((__PWR_CMD).msk) 117 | #define GET_PWR_CFG_VALUE(__PWR_CMD) ((__PWR_CMD).value) 118 | 119 | 120 | /* ******************************************************************************** 121 | * Prototype of protected function. 122 | * ******************************************************************************** */ 123 | u8 HalPwrSeqCmdParsing( 124 | PADAPTER padapter, 125 | u8 CutVersion, 126 | u8 FabVersion, 127 | u8 InterfaceType, 128 | WLAN_PWR_CFG PwrCfgCmd[]); 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /hal/HalVerDef.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright(c) 2007 - 2017 Realtek Corporation. 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of version 2 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | *****************************************************************************/ 15 | #ifndef __HAL_VERSION_DEF_H__ 16 | #define __HAL_VERSION_DEF_H__ 17 | 18 | #undef TRUE 19 | #undef FALSE 20 | 21 | #include "basic_types.h" 22 | #include "drv_types.h" 23 | 24 | #define TRUE _TRUE 25 | #define FALSE _FALSE 26 | 27 | /* HAL_IC_TYPE_E */ 28 | typedef enum tag_HAL_IC_Type_Definition { 29 | CHIP_8192S = 0, 30 | CHIP_8188C = 1, 31 | CHIP_8192C = 2, 32 | CHIP_8192D = 3, 33 | CHIP_8723A = 4, 34 | CHIP_8188E = 5, 35 | CHIP_8812 = 6, 36 | CHIP_8821 = 7, 37 | CHIP_8723B = 8, 38 | CHIP_8192E = 9, 39 | CHIP_8814A = 10, 40 | CHIP_8703B = 11, 41 | CHIP_8188F = 12, 42 | CHIP_8822B = 13, 43 | CHIP_8723D = 14, 44 | CHIP_8821C = 15 45 | } HAL_IC_TYPE_E; 46 | 47 | /* HAL_CHIP_TYPE_E */ 48 | typedef enum tag_HAL_CHIP_Type_Definition { 49 | TEST_CHIP = 0, 50 | NORMAL_CHIP = 1, 51 | FPGA = 2, 52 | } HAL_CHIP_TYPE_E; 53 | 54 | /* HAL_CUT_VERSION_E */ 55 | typedef enum tag_HAL_Cut_Version_Definition { 56 | A_CUT_VERSION = 0, 57 | B_CUT_VERSION = 1, 58 | C_CUT_VERSION = 2, 59 | D_CUT_VERSION = 3, 60 | E_CUT_VERSION = 4, 61 | F_CUT_VERSION = 5, 62 | G_CUT_VERSION = 6, 63 | H_CUT_VERSION = 7, 64 | I_CUT_VERSION = 8, 65 | J_CUT_VERSION = 9, 66 | K_CUT_VERSION = 10, 67 | } HAL_CUT_VERSION_E; 68 | 69 | /* HAL_Manufacturer */ 70 | typedef enum tag_HAL_Manufacturer_Version_Definition { 71 | CHIP_VENDOR_TSMC = 0, 72 | CHIP_VENDOR_UMC = 1, 73 | CHIP_VENDOR_SMIC = 2, 74 | } HAL_VENDOR_E; 75 | 76 | typedef enum tag_HAL_RF_Type_Definition { 77 | RF_TYPE_1T1R = 0, 78 | RF_TYPE_1T2R = 1, 79 | RF_TYPE_2T2R = 2, 80 | RF_TYPE_2T3R = 3, 81 | RF_TYPE_2T4R = 4, 82 | RF_TYPE_3T3R = 5, 83 | RF_TYPE_3T4R = 6, 84 | RF_TYPE_4T4R = 7, 85 | RF_TYPE_MAX = 0x0F, 86 | } HAL_RF_TYPE_E; 87 | 88 | typedef struct tag_HAL_VERSION { 89 | HAL_IC_TYPE_E ICType; 90 | HAL_CHIP_TYPE_E ChipType; 91 | HAL_CUT_VERSION_E CUTVersion; 92 | HAL_VENDOR_E VendorType; 93 | HAL_RF_TYPE_E RFType; 94 | u8 ROMVer; 95 | } HAL_VERSION, *PHAL_VERSION; 96 | 97 | /* VERSION_8192C VersionID; 98 | * HAL_VERSION VersionID; */ 99 | 100 | /* Get element */ 101 | #define GET_CVID_IC_TYPE(version) ((HAL_IC_TYPE_E)(((HAL_VERSION)version).ICType)) 102 | #define GET_CVID_CHIP_TYPE(version) ((HAL_CHIP_TYPE_E)(((HAL_VERSION)version).ChipType)) 103 | #define GET_CVID_RF_TYPE(version) ((HAL_RF_TYPE_E)(((HAL_VERSION)version).RFType)) 104 | #define GET_CVID_MANUFACTUER(version) ((HAL_VENDOR_E)(((HAL_VERSION)version).VendorType)) 105 | #define GET_CVID_CUT_VERSION(version) ((HAL_CUT_VERSION_E)(((HAL_VERSION)version).CUTVersion)) 106 | #define GET_CVID_ROM_VERSION(version) ((((HAL_VERSION)version).ROMVer) & ROM_VERSION_MASK) 107 | 108 | /* ---------------------------------------------------------------------------- 109 | * Common Macro. -- 110 | * ---------------------------------------------------------------------------- 111 | * HAL_VERSION VersionID */ 112 | 113 | /* HAL_IC_TYPE_E */ 114 | #if 0 115 | #define IS_81XXC(version) (((GET_CVID_IC_TYPE(version) == CHIP_8192C) || (GET_CVID_IC_TYPE(version) == CHIP_8188C)) ? TRUE : FALSE) 116 | #define IS_8723_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723A) ? TRUE : FALSE) 117 | #define IS_92D(version) ((GET_CVID_IC_TYPE(version) == CHIP_8192D) ? TRUE : FALSE) 118 | #endif 119 | 120 | #define IS_8188E(version) ((GET_CVID_IC_TYPE(version) == CHIP_8188E) ? TRUE : FALSE) 121 | #define IS_8188F(version) ((GET_CVID_IC_TYPE(version) == CHIP_8188F) ? TRUE : FALSE) 122 | #define IS_8192E(version) ((GET_CVID_IC_TYPE(version) == CHIP_8192E) ? TRUE : FALSE) 123 | #define IS_8812_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8812) ? TRUE : FALSE) 124 | #define IS_8821_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8821) ? TRUE : FALSE) 125 | #define IS_8814A_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8814A) ? TRUE : FALSE) 126 | #define IS_8723B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723B) ? TRUE : FALSE) 127 | #define IS_8703B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8703B) ? TRUE : FALSE) 128 | #define IS_8822B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8822B) ? TRUE : FALSE) 129 | #define IS_8821C_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8821C) ? TRUE : FALSE) 130 | #define IS_8723D_SERIES(version)\ 131 | ((GET_CVID_IC_TYPE(version) == CHIP_8723D) ? TRUE : FALSE) 132 | /* HAL_CHIP_TYPE_E */ 133 | #define IS_TEST_CHIP(version) ((GET_CVID_CHIP_TYPE(version) == TEST_CHIP) ? TRUE : FALSE) 134 | #define IS_NORMAL_CHIP(version) ((GET_CVID_CHIP_TYPE(version) == NORMAL_CHIP) ? TRUE : FALSE) 135 | 136 | /* HAL_CUT_VERSION_E */ 137 | #define IS_A_CUT(version) ((GET_CVID_CUT_VERSION(version) == A_CUT_VERSION) ? TRUE : FALSE) 138 | #define IS_B_CUT(version) ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? TRUE : FALSE) 139 | #define IS_C_CUT(version) ((GET_CVID_CUT_VERSION(version) == C_CUT_VERSION) ? TRUE : FALSE) 140 | #define IS_D_CUT(version) ((GET_CVID_CUT_VERSION(version) == D_CUT_VERSION) ? TRUE : FALSE) 141 | #define IS_E_CUT(version) ((GET_CVID_CUT_VERSION(version) == E_CUT_VERSION) ? TRUE : FALSE) 142 | #define IS_F_CUT(version) ((GET_CVID_CUT_VERSION(version) == F_CUT_VERSION) ? TRUE : FALSE) 143 | #define IS_I_CUT(version) ((GET_CVID_CUT_VERSION(version) == I_CUT_VERSION) ? TRUE : FALSE) 144 | #define IS_J_CUT(version) ((GET_CVID_CUT_VERSION(version) == J_CUT_VERSION) ? TRUE : FALSE) 145 | #define IS_K_CUT(version) ((GET_CVID_CUT_VERSION(version) == K_CUT_VERSION) ? TRUE : FALSE) 146 | 147 | /* HAL_VENDOR_E */ 148 | #define IS_CHIP_VENDOR_TSMC(version) ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_TSMC) ? TRUE : FALSE) 149 | #define IS_CHIP_VENDOR_UMC(version) ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_UMC) ? TRUE : FALSE) 150 | #define IS_CHIP_VENDOR_SMIC(version) ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_SMIC) ? TRUE : FALSE) 151 | 152 | /* HAL_RF_TYPE_E */ 153 | #define IS_1T1R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T1R) ? TRUE : FALSE) 154 | #define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R) ? TRUE : FALSE) 155 | #define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R) ? TRUE : FALSE) 156 | #define IS_3T3R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_3T3R) ? TRUE : FALSE) 157 | #define IS_3T4R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_3T4R) ? TRUE : FALSE) 158 | #define IS_4T4R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_4T4R) ? TRUE : FALSE) 159 | 160 | 161 | 162 | /* ---------------------------------------------------------------------------- 163 | * Chip version Macro. -- 164 | * ---------------------------------------------------------------------------- */ 165 | #if 0 166 | #define IS_81XXC_TEST_CHIP(version) ((IS_81XXC(version) && (!IS_NORMAL_CHIP(version))) ? TRUE : FALSE) 167 | 168 | #define IS_92C_SERIAL(version) ((IS_81XXC(version) && IS_2T2R(version)) ? TRUE : FALSE) 169 | #define IS_81xxC_VENDOR_UMC_A_CUT(version) (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? (IS_A_CUT(version) ? TRUE : FALSE) : FALSE) : FALSE) 170 | #define IS_81xxC_VENDOR_UMC_B_CUT(version) (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? (IS_B_CUT(version) ? TRUE : FALSE) : FALSE) : FALSE) 171 | #define IS_81xxC_VENDOR_UMC_C_CUT(version) (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? (IS_C_CUT(version) ? TRUE : FALSE) : FALSE) : FALSE) 172 | 173 | #define IS_NORMAL_CHIP92D(version) ((IS_92D(version)) ? ((GET_CVID_CHIP_TYPE(version) == NORMAL_CHIP) ? TRUE : FALSE) : FALSE) 174 | 175 | #define IS_92D_SINGLEPHY(version) ((IS_92D(version)) ? (IS_2T2R(version) ? TRUE : FALSE) : FALSE) 176 | #define IS_92D_C_CUT(version) ((IS_92D(version)) ? (IS_C_CUT(version) ? TRUE : FALSE) : FALSE) 177 | #define IS_92D_D_CUT(version) ((IS_92D(version)) ? (IS_D_CUT(version) ? TRUE : FALSE) : FALSE) 178 | #define IS_92D_E_CUT(version) ((IS_92D(version)) ? (IS_E_CUT(version) ? TRUE : FALSE) : FALSE) 179 | 180 | #define IS_8723A_A_CUT(version) ((IS_8723_SERIES(version)) ? (IS_A_CUT(version) ? TRUE : FALSE) : FALSE) 181 | #define IS_8723A_B_CUT(version) ((IS_8723_SERIES(version)) ? (IS_B_CUT(version) ? TRUE : FALSE) : FALSE) 182 | #endif 183 | #define IS_VENDOR_8188E_I_CUT_SERIES(_Adapter) ((IS_8188E(GET_HAL_DATA(_Adapter)->version_id)) ? ((GET_CVID_CUT_VERSION(GET_HAL_DATA(_Adapter)->version_id) >= I_CUT_VERSION) ? TRUE : FALSE) : FALSE) 184 | #define IS_VENDOR_8812A_TEST_CHIP(_Adapter) ((IS_8812_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? FALSE : TRUE) : FALSE) 185 | #define IS_VENDOR_8812A_MP_CHIP(_Adapter) ((IS_8812_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? TRUE : FALSE) : FALSE) 186 | #define IS_VENDOR_8812A_C_CUT(_Adapter) ((IS_8812_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((GET_CVID_CUT_VERSION(GET_HAL_DATA(_Adapter)->version_id) == C_CUT_VERSION) ? TRUE : FALSE) : FALSE) 187 | 188 | #define IS_VENDOR_8821A_TEST_CHIP(_Adapter) ((IS_8821_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? FALSE : TRUE) : FALSE) 189 | #define IS_VENDOR_8821A_MP_CHIP(_Adapter) ((IS_8821_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? TRUE : FALSE) : FALSE) 190 | 191 | #define IS_VENDOR_8192E_B_CUT(_Adapter) ((GET_CVID_CUT_VERSION(GET_HAL_DATA(_Adapter)->version_id) == B_CUT_VERSION) ? TRUE : FALSE) 192 | 193 | #define IS_VENDOR_8723B_TEST_CHIP(_Adapter) ((IS_8723B_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? FALSE : TRUE) : FALSE) 194 | #define IS_VENDOR_8723B_MP_CHIP(_Adapter) ((IS_8723B_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? TRUE : FALSE) : FALSE) 195 | 196 | #define IS_VENDOR_8703B_TEST_CHIP(_Adapter) ((IS_8703B_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? FALSE : TRUE) : FALSE) 197 | #define IS_VENDOR_8703B_MP_CHIP(_Adapter) ((IS_8703B_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? TRUE : FALSE) : FALSE) 198 | #define IS_VENDOR_8814A_TEST_CHIP(_Adapter) ((IS_8814A_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? FALSE : TRUE) : FALSE) 199 | #define IS_VENDOR_8814A_MP_CHIP(_Adapter) ((IS_8814A_SERIES(GET_HAL_DATA(_Adapter)->version_id)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->version_id)) ? TRUE : FALSE) : FALSE) 200 | 201 | #endif 202 | -------------------------------------------------------------------------------- /hal/basic_types.h: -------------------------------------------------------------------------------- 1 | #ifndef BASIC_TYPES_H 2 | #define BASIC_TYPES_H 3 | 4 | #include "drv_types.h" 5 | 6 | #define SUCCESS 0 7 | #define FAIL (-1) 8 | 9 | #ifndef TRUE 10 | #define _TRUE 1 11 | #else 12 | #define _TRUE TRUE 13 | #endif 14 | 15 | #ifndef FALSE 16 | #define _FALSE 0 17 | #else 18 | #define _FALSE FALSE 19 | #endif 20 | 21 | #define cpu_to_le32(x) ((__u32)(x)) 22 | #define le32_to_cpu(x) ((__u32)(x)) 23 | #define cpu_to_le16(x) ((__u16)(x)) 24 | #define le16_to_cpu(x) ((__u16)(x)) 25 | 26 | 27 | #define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ 28 | ((LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset)) & \ 29 | BIT_LEN_MASK_32(__BitLen)) 30 | #define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (le32_to_cpu(*((u32 *)(__pStart)))) 31 | #define BIT_LEN_MASK_32(__BitLen) ((u32)(0xFFFFFFFF >> (32 - (__BitLen)))) 32 | 33 | #define ReadLE2Byte(_ptr) le16_to_cpu(*((u16 *)(_ptr))) 34 | 35 | #endif /* BASIC_TYPES_H */ 36 | -------------------------------------------------------------------------------- /hal/drv_types.h: -------------------------------------------------------------------------------- 1 | #ifndef DRV_TYPES_H 2 | #define DRV_TYPES_H 3 | 4 | #define BIT(nr) (1UL << (nr)) 5 | #define BIT0 BIT(0) 6 | #define BIT1 BIT(1) 7 | #define BIT2 BIT(2) 8 | #define BIT3 BIT(3) 9 | #define BIT4 BIT(4) 10 | #define BIT5 BIT(5) 11 | #define BIT6 BIT(6) 12 | #define BIT7 BIT(7) 13 | #define BIT8 BIT(8) 14 | #define BIT9 BIT(9) 15 | #define BIT10 BIT(10) 16 | #define BIT11 BIT(11) 17 | #define BIT12 BIT(12) 18 | #define BIT13 BIT(13) 19 | #define BIT14 BIT(14) 20 | #define BIT15 BIT(15) 21 | #define BIT16 BIT(16) 22 | #define BIT17 BIT(17) 23 | #define BIT18 BIT(18) 24 | #define BIT19 BIT(19) 25 | #define BIT20 BIT(20) 26 | #define BIT21 BIT(21) 27 | #define BIT22 BIT(22) 28 | #define BIT23 BIT(23) 29 | #define BIT24 BIT(24) 30 | #define BIT25 BIT(25) 31 | #define BIT26 BIT(26) 32 | #define BIT27 BIT(27) 33 | #define BIT28 BIT(28) 34 | #define BIT29 BIT(29) 35 | #define BIT30 BIT(30) 36 | #define BIT31 BIT(31) 37 | 38 | #include 39 | #include 40 | 41 | typedef uint8_t u8; 42 | typedef uint16_t u16; 43 | typedef uint32_t u32; 44 | typedef void *PADAPTER; 45 | #ifndef WIN32 46 | typedef bool BOOLEAN; 47 | typedef void VOID; 48 | #endif 49 | 50 | 51 | static uint32_t PHY_CalculateBitShift(uint32_t BitMask) { 52 | int i; 53 | 54 | for (i = 0; i <= 31; i++) { 55 | if (((BitMask >> i) & 0x1) == 1) 56 | break; 57 | } 58 | 59 | return i; 60 | } 61 | 62 | #endif /* DRV_TYPES_H */ 63 | -------------------------------------------------------------------------------- /hal/hal8812a_fw.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of version 2 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 17 | * 18 | * 19 | ******************************************************************************/ 20 | 21 | #ifdef CONFIG_RTL8812A 22 | 23 | #ifndef _FW_HEADER_8812A_H 24 | #define _FW_HEADER_8812A_H 25 | 26 | #ifdef LOAD_FW_HEADER_FROM_DRIVER 27 | #if (defined(CONFIG_AP_WOWLAN) || (DM_ODM_SUPPORT_TYPE & (ODM_AP))) 28 | extern u8 array_mp_8812a_fw_ap[24130]; 29 | extern u32 array_length_mp_8812a_fw_ap; 30 | #endif 31 | 32 | #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) || (DM_ODM_SUPPORT_TYPE & (ODM_CE)) 33 | extern u8 array_mp_8812a_fw_nic[27054]; 34 | extern u32 array_length_mp_8812a_fw_nic; 35 | extern u8 array_mp_8812a_fw_nic_bt[29918]; 36 | extern u32 array_length_mp_8812a_fw_nic_bt; 37 | extern u8 array_mp_8812a_fw_nic_mcc[29452]; 38 | extern u32 array_length_mp_8812a_fw_nic_mcc; 39 | extern u8 array_mp_8812a_fw_wowlan[32450]; 40 | extern u32 array_length_mp_8812a_fw_wowlan; 41 | #endif 42 | #endif /* end of LOAD_FW_HEADER_FROM_DRIVER */ 43 | 44 | #endif 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /hal/rtl8812a_hal.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright(c) 2007 - 2017 Realtek Corporation. 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of version 2 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | *****************************************************************************/ 15 | #ifndef __RTL8812A_HAL_H__ 16 | #define __RTL8812A_HAL_H__ 17 | 18 | /* #include "hal_com.h" */ 19 | #if 0 20 | #include "hal_data.h" 21 | #endif 22 | 23 | #include "basic_types.h" 24 | 25 | /* include HAL Related header after HAL Related compiling flags */ 26 | #include "rtl8812a_spec.h" 27 | #if 0 28 | #include "rtl8812a_rf.h" 29 | #include "rtl8812a_dm.h" 30 | #include "rtl8812a_recv.h" 31 | #include "rtl8812a_xmit.h" 32 | #include "rtl8812a_cmd.h" 33 | #include "rtl8812a_led.h" 34 | #include "Hal8812PwrSeq.h" 35 | #include "Hal8821APwrSeq.h" /* for 8821A/8811A */ 36 | #include "Hal8812PhyReg.h" 37 | #include "Hal8812PhyCfg.h" 38 | #ifdef DBG_CONFIG_ERROR_DETECT 39 | #include "rtl8812a_sreset.h" 40 | #endif 41 | #endif 42 | 43 | /* --------------------------------------------------------------------- 44 | * RTL8812 Power Configuration CMDs for PCIe interface 45 | * --------------------------------------------------------------------- */ 46 | #define Rtl8812_NIC_PWR_ON_FLOW rtl8812_power_on_flow 47 | #define Rtl8812_NIC_RF_OFF_FLOW rtl8812_radio_off_flow 48 | #define Rtl8812_NIC_DISABLE_FLOW rtl8812_card_disable_flow 49 | #define Rtl8812_NIC_ENABLE_FLOW rtl8812_card_enable_flow 50 | #define Rtl8812_NIC_SUSPEND_FLOW rtl8812_suspend_flow 51 | #define Rtl8812_NIC_RESUME_FLOW rtl8812_resume_flow 52 | #define Rtl8812_NIC_PDN_FLOW rtl8812_hwpdn_flow 53 | #define Rtl8812_NIC_LPS_ENTER_FLOW rtl8812_enter_lps_flow 54 | #define Rtl8812_NIC_LPS_LEAVE_FLOW rtl8812_leave_lps_flow 55 | 56 | /* --------------------------------------------------------------------- 57 | * RTL8821 Power Configuration CMDs for PCIe interface 58 | * --------------------------------------------------------------------- */ 59 | #define Rtl8821A_NIC_PWR_ON_FLOW rtl8821A_power_on_flow 60 | #define Rtl8821A_NIC_RF_OFF_FLOW rtl8821A_radio_off_flow 61 | #define Rtl8821A_NIC_DISABLE_FLOW rtl8821A_card_disable_flow 62 | #define Rtl8821A_NIC_ENABLE_FLOW rtl8821A_card_enable_flow 63 | #define Rtl8821A_NIC_SUSPEND_FLOW rtl8821A_suspend_flow 64 | #define Rtl8821A_NIC_RESUME_FLOW rtl8821A_resume_flow 65 | #define Rtl8821A_NIC_PDN_FLOW rtl8821A_hwpdn_flow 66 | #define Rtl8821A_NIC_LPS_ENTER_FLOW rtl8821A_enter_lps_flow 67 | #define Rtl8821A_NIC_LPS_LEAVE_FLOW rtl8821A_leave_lps_flow 68 | 69 | 70 | #if 1 /* download firmware related data structure */ 71 | #define FW_SIZE_8812 0x8000 /* Compatible with RTL8723 Maximal RAM code size 24K. modified to 32k, TO compatible with 92d maximal fw size 32k */ 72 | #define FW_START_ADDRESS 0x1000 73 | #define FW_END_ADDRESS 0x5FFF 74 | 75 | 76 | #if 0 77 | typedef struct _RT_FIRMWARE_8812 { 78 | FIRMWARE_SOURCE eFWSource; 79 | #ifdef CONFIG_EMBEDDED_FWIMG 80 | u8 *szFwBuffer; 81 | #else 82 | u8 szFwBuffer[FW_SIZE_8812]; 83 | #endif 84 | u32 ulFwLength; 85 | } RT_FIRMWARE_8812, *PRT_FIRMWARE_8812; 86 | #endif 87 | 88 | /* 89 | * This structure must be cared byte-ordering 90 | * 91 | * Added by tynli. 2009.12.04. */ 92 | #define IS_FW_HEADER_EXIST_8812(_pFwHdr) ((GET_FIRMWARE_HDR_SIGNATURE_8812(_pFwHdr) & 0xFFF0) == 0x9500) 93 | 94 | #define IS_FW_HEADER_EXIST_8821(_pFwHdr) ((GET_FIRMWARE_HDR_SIGNATURE_8812(_pFwHdr) & 0xFFF0) == 0x2100) 95 | /* ***************************************************** 96 | * Firmware Header(8-byte alinment required) 97 | * ***************************************************** 98 | * --- LONG WORD 0 ---- */ 99 | #define GET_FIRMWARE_HDR_SIGNATURE_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 0, 16) /* 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut */ 100 | #define GET_FIRMWARE_HDR_CATEGORY_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 16, 8) /* AP/NIC and USB/PCI */ 101 | #define GET_FIRMWARE_HDR_FUNCTION_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 24, 8) /* Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions */ 102 | #define GET_FIRMWARE_HDR_VERSION_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 0, 16)/* FW Version */ 103 | #define GET_FIRMWARE_HDR_SUB_VER_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 16, 8) /* FW Subversion, default 0x00 */ 104 | #define GET_FIRMWARE_HDR_RSVD1_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 24, 8) 105 | 106 | /* --- LONG WORD 1 ---- */ 107 | #define GET_FIRMWARE_HDR_MONTH_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 0, 8) /* Release time Month field */ 108 | #define GET_FIRMWARE_HDR_DATE_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 8, 8) /* Release time Date field */ 109 | #define GET_FIRMWARE_HDR_HOUR_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 16, 8)/* Release time Hour field */ 110 | #define GET_FIRMWARE_HDR_MINUTE_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 24, 8)/* Release time Minute field */ 111 | #define GET_FIRMWARE_HDR_ROMCODE_SIZE_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+12, 0, 16)/* The size of RAM code */ 112 | #define GET_FIRMWARE_HDR_RSVD2_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+12, 16, 16) 113 | 114 | /* --- LONG WORD 2 ---- */ 115 | #define GET_FIRMWARE_HDR_SVN_IDX_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+16, 0, 32)/* The SVN entry index */ 116 | #define GET_FIRMWARE_HDR_RSVD3_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+20, 0, 32) 117 | 118 | /* --- LONG WORD 3 ---- */ 119 | #define GET_FIRMWARE_HDR_RSVD4_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 0, 32) 120 | #define GET_FIRMWARE_HDR_RSVD5_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+28, 0, 32) 121 | 122 | #endif /* download firmware related data structure */ 123 | 124 | 125 | #define DRIVER_EARLY_INT_TIME_8812 0x05 126 | #define BCN_DMA_ATIME_INT_TIME_8812 0x02 127 | 128 | /* for 8812 129 | * TX 128K, RX 16K, Page size 512B for TX, 128B for RX */ 130 | #define MAX_RX_DMA_BUFFER_SIZE_8812 0x3E80 /* RX 16K */ 131 | 132 | #ifdef CONFIG_WOWLAN 133 | #define RESV_FMWF (WKFMCAM_SIZE * MAX_WKFM_CAM_NUM) /* 16 entries, for each is 24 bytes*/ 134 | #else 135 | #define RESV_FMWF 0 136 | #endif 137 | 138 | #ifdef CONFIG_FW_C2H_DEBUG 139 | #define RX_DMA_RESERVED_SIZE_8812 0x100 /* 256B, reserved for c2h debug message */ 140 | #else 141 | #define RX_DMA_RESERVED_SIZE_8812 0x0 /* 0B */ 142 | #endif 143 | #define RX_DMA_BOUNDARY_8812 (MAX_RX_DMA_BUFFER_SIZE_8812 - RX_DMA_RESERVED_SIZE_8812 - 1) 144 | 145 | #define BCNQ_PAGE_NUM_8812 0x07 146 | 147 | /* For WoWLan , more reserved page 148 | * ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:1,GTK EXT MEM:1, AOAC rpt: 1,PNO: 6 149 | * NS offload: 1 NDP info: 1 150 | */ 151 | #ifdef CONFIG_WOWLAN 152 | #define WOWLAN_PAGE_NUM_8812 0x08 153 | #else 154 | #define WOWLAN_PAGE_NUM_8812 0x00 155 | #endif 156 | 157 | 158 | #ifdef CONFIG_BEAMFORMER_FW_NDPA 159 | #define FW_NDPA_PAGE_NUM 0x02 160 | #else 161 | #define FW_NDPA_PAGE_NUM 0x00 162 | #endif 163 | 164 | #define TX_TOTAL_PAGE_NUMBER_8812 (0xFF - BCNQ_PAGE_NUM_8812 - WOWLAN_PAGE_NUM_8812-FW_NDPA_PAGE_NUM) 165 | #define TX_PAGE_BOUNDARY_8812 (TX_TOTAL_PAGE_NUMBER_8812 + 1) 166 | 167 | #define TX_PAGE_BOUNDARY_WOWLAN_8812 (0xFF - BCNQ_PAGE_NUM_8812 - WOWLAN_PAGE_NUM_8812 + 1) 168 | 169 | #define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8812 TX_TOTAL_PAGE_NUMBER_8812 170 | #define WMM_NORMAL_TX_PAGE_BOUNDARY_8812 (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8812 + 1) 171 | 172 | /* For Normal Chip Setting 173 | * (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER_8812 */ 174 | #define NORMAL_PAGE_NUM_LPQ_8812 0x10 175 | #define NORMAL_PAGE_NUM_HPQ_8812 0x10 176 | #define NORMAL_PAGE_NUM_NPQ_8812 0x00 177 | 178 | #define WMM_NORMAL_PAGE_NUM_HPQ_8812 0x30 179 | #define WMM_NORMAL_PAGE_NUM_LPQ_8812 0x20 180 | #define WMM_NORMAL_PAGE_NUM_NPQ_8812 0x20 181 | 182 | 183 | /* for 8821A 184 | * TX 64K, RX 16K, Page size 256B for TX, 128B for RX */ 185 | #define PAGE_SIZE_TX_8821A 256 186 | #define PAGE_SIZE_RX_8821A 128 187 | 188 | #define MAX_RX_DMA_BUFFER_SIZE_8821 0x3E80 /* RX 16K */ 189 | 190 | #ifdef CONFIG_FW_C2H_DEBUG 191 | #define RX_DMA_RESERVED_SIZE_8821 0x100 /* 256B, reserved for c2h debug message */ 192 | #else 193 | #define RX_DMA_RESERVED_SIZE_8821 0x0 /* 0B */ 194 | #endif 195 | #define RX_DMA_BOUNDARY_8821 (MAX_RX_DMA_BUFFER_SIZE_8821 - RX_DMA_RESERVED_SIZE_8821 - 1) 196 | 197 | #define BCNQ_PAGE_NUM_8821 0x08 198 | #ifdef CONFIG_CONCURRENT_MODE 199 | #define BCNQ1_PAGE_NUM_8821 0x04 200 | #else 201 | #define BCNQ1_PAGE_NUM_8821 0x00 202 | #endif 203 | 204 | /* For WoWLan , more reserved page 205 | * ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:1,GTK EXT MEM:1, PNO: 6 */ 206 | #ifdef CONFIG_WOWLAN 207 | #define WOWLAN_PAGE_NUM_8821 0x06 208 | #else 209 | #define WOWLAN_PAGE_NUM_8821 0x00 210 | #endif 211 | 212 | #define TX_TOTAL_PAGE_NUMBER_8821 (0xFF - BCNQ_PAGE_NUM_8821 - BCNQ1_PAGE_NUM_8821 - WOWLAN_PAGE_NUM_8821) 213 | #define TX_PAGE_BOUNDARY_8821 (TX_TOTAL_PAGE_NUMBER_8821 + 1) 214 | /* #define TX_PAGE_BOUNDARY_WOWLAN_8821 0xE0 */ 215 | 216 | #define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8821 TX_TOTAL_PAGE_NUMBER_8821 217 | #define WMM_NORMAL_TX_PAGE_BOUNDARY_8821 (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8821 + 1) 218 | 219 | 220 | /* (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER */ 221 | #define NORMAL_PAGE_NUM_LPQ_8821 0x08/* 0x10 */ 222 | #define NORMAL_PAGE_NUM_HPQ_8821 0x08/* 0x10 */ 223 | #define NORMAL_PAGE_NUM_NPQ_8821 0x00 224 | #define NORMAL_PAGE_NUM_EPQ_8821 0x04 225 | 226 | #define WMM_NORMAL_PAGE_NUM_HPQ_8821 0x30 227 | #define WMM_NORMAL_PAGE_NUM_LPQ_8821 0x20 228 | #define WMM_NORMAL_PAGE_NUM_NPQ_8821 0x20 229 | #define WMM_NORMAL_PAGE_NUM_EPQ_8821 0x00 230 | 231 | #define MCC_NORMAL_PAGE_NUM_HPQ_8821 0x10 232 | #define MCC_NORMAL_PAGE_NUM_LPQ_8821 0x10 233 | #define MCC_NORMAL_PAGE_NUM_NPQ_8821 0x10 234 | 235 | #define EFUSE_HIDDEN_812AU 0 236 | #define EFUSE_HIDDEN_812AU_VS 1 237 | #define EFUSE_HIDDEN_812AU_VL 2 238 | #define EFUSE_HIDDEN_812AU_VN 3 239 | 240 | #if 0 241 | #define EFUSE_REAL_CONTENT_LEN_JAGUAR 1024 242 | #define HWSET_MAX_SIZE_JAGUAR 1024 243 | #else 244 | #define EFUSE_REAL_CONTENT_LEN_JAGUAR 512 245 | #define HWSET_MAX_SIZE_JAGUAR 512 246 | #endif 247 | 248 | #define EFUSE_MAX_BANK_8812A 2 249 | #define EFUSE_MAP_LEN_JAGUAR 512 250 | #define EFUSE_MAX_SECTION_JAGUAR 64 251 | #define EFUSE_MAX_WORD_UNIT_JAGUAR 4 252 | #define EFUSE_IC_ID_OFFSET_JAGUAR 506 /* For some inferiority IC purpose. added by Roger, 2009.09.02. */ 253 | #define AVAILABLE_EFUSE_ADDR_8812(addr) (addr < EFUSE_REAL_CONTENT_LEN_JAGUAR) 254 | /* To prevent out of boundary programming case, leave 1byte and program full section 255 | * 9bytes + 1byt + 5bytes and pre 1byte. 256 | * For worst case: 257 | * | 2byte|----8bytes----|1byte|--7bytes--| */ /* 92D */ 258 | #define EFUSE_OOB_PROTECT_BYTES_JAGUAR 18 /* PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte. */ 259 | #define EFUSE_PROTECT_BYTES_BANK_JAGUAR 16 260 | 261 | #define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) 262 | #define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) 263 | 264 | /* #define IS_MULTI_FUNC_CHIP(_Adapter) (((((PHAL_DATA_TYPE)(_Adapter->HalData))->MultiFunc) & (RT_MULTI_FUNC_BT|RT_MULTI_FUNC_GPS)) ? _TRUE : _FALSE) */ 265 | 266 | /* #define RT_IS_FUNC_DISABLED(__pAdapter, __FuncBits) ( (__pAdapter)->DisabledFunctions & (__FuncBits) ) */ 267 | #define HAL_EFUSE_MEMORY 268 | 269 | /* ******************************************************** 270 | * EFUSE for BT definition 271 | * ******************************************************** */ 272 | #define BANK_NUM 2 273 | #define EFUSE_BT_REAL_BANK_CONTENT_LEN 512 274 | #define EFUSE_BT_REAL_CONTENT_LEN \ 275 | (EFUSE_BT_REAL_BANK_CONTENT_LEN * BANK_NUM) 276 | #define EFUSE_BT_MAP_LEN 1024 /* 1k bytes */ 277 | #define EFUSE_BT_MAX_SECTION (EFUSE_BT_MAP_LEN / 8) 278 | #define EFUSE_PROTECT_BYTES_BANK 16 279 | 280 | #define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_BT_REAL_CONTENT_LEN) 281 | 282 | #ifdef CONFIG_FILE_FWIMG 283 | extern char *rtw_fw_file_path; 284 | #ifdef CONFIG_WOWLAN 285 | extern char *rtw_fw_wow_file_path; 286 | #endif 287 | #ifdef CONFIG_MP_INCLUDED 288 | extern char *rtw_fw_mp_bt_file_path; 289 | #endif 290 | #endif 291 | 292 | #if 0 293 | /* rtl8812_hal_init.c */ 294 | void _8051Reset8812(PADAPTER padapter); 295 | s32 FirmwareDownload8812(PADAPTER Adapter, BOOLEAN bUsedWoWLANFw); 296 | void InitializeFirmwareVars8812(PADAPTER padapter); 297 | 298 | s32 _LLTWrite_8812A(PADAPTER Adapter, u32 address, u32 data); 299 | s32 InitLLTTable8812A(PADAPTER padapter, u8 txpktbuf_bndy); 300 | void InitRDGSetting8812A(PADAPTER padapter); 301 | 302 | void CheckAutoloadState8812A(PADAPTER padapter); 303 | 304 | /* EFuse */ 305 | u8 GetEEPROMSize8812A(PADAPTER padapter); 306 | void InitPGData8812A(PADAPTER padapter); 307 | void Hal_EfuseParseIDCode8812A(PADAPTER padapter, u8 *hwinfo); 308 | void Hal_ReadPROMVersion8812A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); 309 | void Hal_ReadTxPowerInfo8812A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); 310 | void Hal_ReadBoardType8812A(PADAPTER pAdapter, u8 *hwinfo, BOOLEAN AutoLoadFail); 311 | void Hal_ReadThermalMeter_8812A(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); 312 | void Hal_ReadChannelPlan8812A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); 313 | void Hal_EfuseParseXtal_8812A(PADAPTER pAdapter, u8 *hwinfo, BOOLEAN AutoLoadFail); 314 | void Hal_ReadAntennaDiversity8812A(PADAPTER pAdapter, u8 *PROMContent, BOOLEAN AutoLoadFail); 315 | void Hal_ReadAmplifierType_8812A(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); 316 | void Hal_ReadPAType_8821A(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); 317 | void Hal_ReadRFEType_8812A(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); 318 | void Hal_EfuseParseBTCoexistInfo8812A(PADAPTER Adapter, u8 *hwinfo, BOOLEAN AutoLoadFail); 319 | void hal_ReadUsbType_8812AU(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); 320 | #ifdef CONFIG_MP_INCLUDED 321 | int FirmwareDownloadBT(PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware); 322 | #endif 323 | void Hal_ReadRemoteWakeup_8812A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); 324 | 325 | BOOLEAN HalDetectPwrDownMode8812(PADAPTER Adapter); 326 | void Hal_EfuseParseKFreeData_8821A(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); 327 | 328 | #ifdef CONFIG_WOWLAN 329 | void Hal_DetectWoWMode(PADAPTER pAdapter); 330 | #endif /* CONFIG_WOWLAN */ 331 | 332 | void _InitBeaconParameters_8812A(PADAPTER padapter); 333 | void SetBeaconRelatedRegisters8812A(PADAPTER padapter); 334 | 335 | void ReadRFType8812A(PADAPTER padapter); 336 | void InitDefaultValue8821A(PADAPTER padapter); 337 | 338 | u8 SetHwReg8812A(PADAPTER padapter, u8 variable, u8 *pval); 339 | void GetHwReg8812A(PADAPTER padapter, u8 variable, u8 *pval); 340 | u8 SetHalDefVar8812A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); 341 | u8 GetHalDefVar8812A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); 342 | void rtl8812_set_hal_ops(struct hal_ops *pHalFunc); 343 | void init_hal_spec_8812a(_adapter *adapter); 344 | void init_hal_spec_8821a(_adapter *adapter); 345 | 346 | u32 upload_txpktbuf_8812au(_adapter *adapter, u8 *buf, u32 buflen); 347 | 348 | /* register */ 349 | void SetBcnCtrlReg(PADAPTER padapter, u8 SetBits, u8 ClearBits); 350 | 351 | void rtl8812_start_thread(PADAPTER padapter); 352 | void rtl8812_stop_thread(PADAPTER padapter); 353 | 354 | #ifdef CONFIG_PCI_HCI 355 | BOOLEAN InterruptRecognized8812AE(PADAPTER Adapter); 356 | VOID UpdateInterruptMask8812AE(PADAPTER Adapter, u32 AddMSR, u32 AddMSR1, u32 RemoveMSR, u32 RemoveMSR1); 357 | VOID InitTRXDescHwAddress8812AE(PADAPTER Adapter); 358 | #endif 359 | 360 | #ifdef CONFIG_BT_COEXIST 361 | void rtl8812a_combo_card_WifiOnlyHwInit(PADAPTER Adapter); 362 | #endif 363 | 364 | VOID 365 | Hal_PatchwithJaguar_8812( 366 | IN PADAPTER Adapter, 367 | IN RT_MEDIA_STATUS MediaStatus 368 | ); 369 | #endif 370 | 371 | #endif /* __RTL8188E_HAL_H__ */ 372 | -------------------------------------------------------------------------------- /hal/rtl8812a_recv.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright(c) 2007 - 2017 Realtek Corporation. 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of version 2 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | *****************************************************************************/ 15 | #ifndef __RTL8812A_RECV_H__ 16 | #define __RTL8812A_RECV_H__ 17 | 18 | #if defined(CONFIG_USB_HCI) 19 | 20 | #ifndef MAX_RECVBUF_SZ 21 | #ifdef PLATFORM_OS_CE 22 | #define MAX_RECVBUF_SZ (8192+1024) /* 8K+1k */ 23 | #else 24 | #ifndef CONFIG_MINIMAL_MEMORY_USAGE 25 | #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER 26 | #define MAX_RECVBUF_SZ (rtw_rtkm_get_buff_size()) /*depend rtkm*/ 27 | #else 28 | #define MAX_RECVBUF_SZ (32768) /*32k*/ 29 | #endif 30 | /* #define MAX_RECVBUF_SZ (24576) */ /* 24k */ 31 | /* #define MAX_RECVBUF_SZ (20480) */ /* 20K */ 32 | /* #define MAX_RECVBUF_SZ (10240) */ /* 10K */ 33 | /* #define MAX_RECVBUF_SZ (15360) */ /* 15k < 16k */ 34 | /* #define MAX_RECVBUF_SZ (8192+1024) */ /* 8K+1k */ 35 | #ifdef CONFIG_PLATFORM_NOVATEK_NT72668 36 | #undef MAX_RECVBUF_SZ 37 | #define MAX_RECVBUF_SZ (15360) /* 15k < 16k */ 38 | #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */ 39 | #else 40 | #define MAX_RECVBUF_SZ (4000) /* about 4K */ 41 | #endif 42 | #endif 43 | #endif /* !MAX_RECVBUF_SZ */ 44 | 45 | #elif defined(CONFIG_PCI_HCI) 46 | /* #ifndef CONFIG_MINIMAL_MEMORY_USAGE */ 47 | /* #define MAX_RECVBUF_SZ (9100) */ 48 | /* #else */ 49 | #define MAX_RECVBUF_SZ (4000) /* about 4K 50 | * #endif */ 51 | 52 | 53 | #elif defined(CONFIG_SDIO_HCI) 54 | 55 | #define MAX_RECVBUF_SZ (RX_DMA_BOUNDARY_8821 + 1) 56 | 57 | #endif 58 | 59 | 60 | /* Rx smooth factor */ 61 | #define Rx_Smooth_Factor (20) 62 | 63 | /* DWORD 0 */ 64 | #define SET_RX_STATUS_DESC_PKT_LEN_8812(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxStatusDesc, 0, 14, __Value) 65 | #define SET_RX_STATUS_DESC_EOR_8812(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxStatusDesc, 30, 1, __Value) 66 | #define SET_RX_STATUS_DESC_OWN_8812(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxStatusDesc, 31, 1, __Value) 67 | 68 | #define GET_RX_STATUS_DESC_PKT_LEN_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 0, 14) 69 | #define GET_RX_STATUS_DESC_CRC32_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 14, 1) 70 | #define GET_RX_STATUS_DESC_ICV_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 15, 1) 71 | #define GET_RX_STATUS_DESC_DRVINFO_SIZE_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 16, 4) 72 | #define GET_RX_STATUS_DESC_SECURITY_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 20, 3) 73 | #define GET_RX_STATUS_DESC_QOS_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 23, 1) 74 | #define GET_RX_STATUS_DESC_SHIFT_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 24, 2) 75 | #define GET_RX_STATUS_DESC_PHY_STATUS_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 26, 1) 76 | #define GET_RX_STATUS_DESC_SWDEC_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 27, 1) 77 | #define GET_RX_STATUS_DESC_LAST_SEG_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 28, 1) 78 | #define GET_RX_STATUS_DESC_FIRST_SEG_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 29, 1) 79 | #define GET_RX_STATUS_DESC_EOR_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 30, 1) 80 | #define GET_RX_STATUS_DESC_OWN_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 31, 1) 81 | 82 | /* DWORD 1 */ 83 | #define GET_RX_STATUS_DESC_MACID_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 0, 7) 84 | #define GET_RX_STATUS_DESC_TID_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 8, 4) 85 | #define GET_RX_STATUS_DESC_AMSDU_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 13, 1) 86 | #define GET_RX_STATUS_DESC_RXID_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 14, 1) 87 | #define GET_RX_STATUS_DESC_PAGGR_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 15, 1) 88 | #define GET_RX_STATUS_DESC_A1_FIT_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 16, 4) 89 | #define GET_RX_STATUS_DESC_CHKERR_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 20, 1) 90 | #define GET_RX_STATUS_DESC_IPVER_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 21, 1) 91 | #define GET_RX_STATUS_DESC_IS_TCPUDP__8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 22, 1) 92 | #define GET_RX_STATUS_DESC_CHK_VLD_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 23, 1) 93 | #define GET_RX_STATUS_DESC_PAM_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 24, 1) 94 | #define GET_RX_STATUS_DESC_PWR_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 25, 1) 95 | #define GET_RX_STATUS_DESC_MORE_DATA_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 26, 1) 96 | #define GET_RX_STATUS_DESC_MORE_FRAG_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 27, 1) 97 | #define GET_RX_STATUS_DESC_TYPE_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 28, 2) 98 | #define GET_RX_STATUS_DESC_MC_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 30, 1) 99 | #define GET_RX_STATUS_DESC_BC_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 31, 1) 100 | 101 | /* DWORD 2 */ 102 | #define GET_RX_STATUS_DESC_SEQ_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+8, 0, 12) 103 | #define GET_RX_STATUS_DESC_FRAG_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+8, 12, 4) 104 | #define GET_RX_STATUS_DESC_RX_IS_QOS_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+8, 16, 1) 105 | #define GET_RX_STATUS_DESC_WLANHD_IV_LEN_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+8, 18, 6) 106 | #define GET_RX_STATUS_DESC_RPT_SEL_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+8, 28, 1) 107 | 108 | /* DWORD 3 */ 109 | #define GET_RX_STATUS_DESC_RX_RATE_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+12, 0, 7) 110 | #define GET_RX_STATUS_DESC_HTC_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+12, 10, 1) 111 | #define GET_RX_STATUS_DESC_EOSP_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+12, 11, 1) 112 | #define GET_RX_STATUS_DESC_BSSID_FIT_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+12, 12, 2) 113 | #ifdef CONFIG_USB_RX_AGGREGATION 114 | #define GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+12, 16, 8) 115 | #endif 116 | #define GET_RX_STATUS_DESC_PATTERN_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+12, 29, 1) 117 | #define GET_RX_STATUS_DESC_UNICAST_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+12, 30, 1) 118 | #define GET_RX_STATUS_DESC_MAGIC_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+12, 31, 1) 119 | 120 | /* DWORD 6 */ 121 | #define GET_RX_STATUS_DESC_SPLCP_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+16, 0, 1) 122 | #define GET_RX_STATUS_DESC_LDPC_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+16, 1, 1) 123 | #define GET_RX_STATUS_DESC_STBC_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+16, 2, 1) 124 | #define GET_RX_STATUS_DESC_BW_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+16, 4, 2) 125 | 126 | /* DWORD 5 */ 127 | #define GET_RX_STATUS_DESC_TSFL_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+20, 0, 32) 128 | 129 | #define GET_RX_STATUS_DESC_BUFF_ADDR_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+24, 0, 32) 130 | #define GET_RX_STATUS_DESC_BUFF_ADDR64_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+28, 0, 32) 131 | 132 | #define SET_RX_STATUS_DESC_BUFF_ADDR_8812(__pRxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxDesc+24, 0, 32, __Value) 133 | 134 | 135 | #ifdef CONFIG_SDIO_HCI 136 | s32 InitRecvPriv8821AS(PADAPTER padapter); 137 | void FreeRecvPriv8821AS(PADAPTER padapter); 138 | #endif /* CONFIG_SDIO_HCI */ 139 | 140 | #ifdef CONFIG_USB_HCI 141 | void rtl8812au_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); 142 | s32 rtl8812au_init_recv_priv(PADAPTER padapter); 143 | void rtl8812au_free_recv_priv(PADAPTER padapter); 144 | #endif 145 | 146 | #ifdef CONFIG_PCI_HCI 147 | s32 rtl8812ae_init_recv_priv(PADAPTER padapter); 148 | void rtl8812ae_free_recv_priv(PADAPTER padapter); 149 | #endif 150 | 151 | void rtl8812_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc); 152 | 153 | #endif /* __RTL8812A_RECV_H__ */ 154 | -------------------------------------------------------------------------------- /hal/rtl8812a_spec.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright(c) 2007 - 2017 Realtek Corporation. 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of version 2 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | *****************************************************************************/ 15 | #ifndef __RTL8812A_SPEC_H__ 16 | #define __RTL8812A_SPEC_H__ 17 | 18 | //#include 19 | 20 | 21 | /* ************************************************************ 22 | * 8812 Regsiter offset definition 23 | * ************************************************************ */ 24 | 25 | /* ************************************************************ 26 | * 27 | * ************************************************************ */ 28 | 29 | /* ----------------------------------------------------- 30 | * 31 | * 0x0000h ~ 0x00FFh System Configuration 32 | * 33 | * ----------------------------------------------------- */ 34 | #define REG_SYS_CLKR_8812A 0x0008 35 | #define REG_AFE_PLL_CTRL_8812A 0x0028 36 | #define REG_HSIMR_8812 0x0058 37 | #define REG_HSISR_8812 0x005c 38 | #define REG_GPIO_EXT_CTRL 0x0060 39 | #define REG_GPIO_STATUS_8812 0x006C 40 | #define REG_SDIO_CTRL_8812 0x0070 41 | #define REG_OPT_CTRL_8812 0x0074 42 | #define REG_RF_B_CTRL_8812 0x0076 43 | #define REG_FW_DRV_MSG_8812 0x0088 44 | #define REG_HMEBOX_E2_E3_8812 0x008C 45 | #define REG_HIMR0_8812 0x00B0 46 | #define REG_HISR0_8812 0x00B4 47 | #define REG_HIMR1_8812 0x00B8 48 | #define REG_HISR1_8812 0x00BC 49 | #define REG_EFUSE_BURN_GNT_8812 0x00CF 50 | #define REG_SYS_CFG1_8812 0x00FC 51 | 52 | /* ----------------------------------------------------- 53 | * 54 | * 0x0100h ~ 0x01FFh MACTOP General Configuration 55 | * 56 | * ----------------------------------------------------- */ 57 | #define REG_CR_8812A 0x100 58 | #define REG_PKTBUF_DBG_ADDR (REG_PKTBUF_DBG_CTRL) 59 | #define REG_RXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+2) 60 | #define REG_TXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+3) 61 | #define REG_WOWLAN_WAKE_REASON REG_MCUTST_WOWLAN 62 | 63 | #define REG_RSVD3_8812 0x0168 64 | #define REG_C2HEVT_CMD_SEQ_88XX 0x01A1 65 | #define REG_C2hEVT_CMD_CONTENT_88XX 0x01A2 66 | #define REG_C2HEVT_CMD_LEN_88XX 0x01AE 67 | 68 | #define REG_HMEBOX_EXT0_8812 0x01F0 69 | #define REG_HMEBOX_EXT1_8812 0x01F4 70 | #define REG_HMEBOX_EXT2_8812 0x01F8 71 | #define REG_HMEBOX_EXT3_8812 0x01FC 72 | 73 | /* ----------------------------------------------------- 74 | * 75 | * 0x0200h ~ 0x027Fh TXDMA Configuration 76 | * 77 | * ----------------------------------------------------- */ 78 | #define REG_DWBCN0_CTRL_8812 REG_TDECTRL 79 | #define REG_DWBCN1_CTRL_8812 0x0228 80 | 81 | /* ----------------------------------------------------- 82 | * 83 | * 0x0280h ~ 0x02FFh RXDMA Configuration 84 | * 85 | * ----------------------------------------------------- */ 86 | #define REG_TDECTRL_8812A 0x0208 87 | #define REG_RXDMA_CONTROL_8812A 0x0286 /*Control the RX DMA.*/ 88 | #define REG_RXDMA_PRO_8812 0x0290 89 | #define REG_EARLY_MODE_CONTROL_8812 0x02BC 90 | #define REG_RSVD5_8812 0x02F0 91 | #define REG_RSVD6_8812 0x02F4 92 | #define REG_RSVD7_8812 0x02F8 93 | #define REG_RSVD8_8812 0x02FC 94 | 95 | 96 | /* ----------------------------------------------------- 97 | * 98 | * 0x0300h ~ 0x03FFh PCIe 99 | * 100 | * ----------------------------------------------------- */ 101 | #define REG_PCIE_CTRL_REG_8812A 0x0300 102 | #define REG_DBI_WDATA_8812 0x0348 /* DBI Write Data */ 103 | #define REG_DBI_RDATA_8812 0x034C /* DBI Read Data */ 104 | #define REG_DBI_ADDR_8812 0x0350 /* DBI Address */ 105 | #define REG_DBI_FLAG_8812 0x0352 /* DBI Read/Write Flag */ 106 | #define REG_MDIO_WDATA_8812 0x0354 /* MDIO for Write PCIE PHY */ 107 | #define REG_MDIO_RDATA_8812 0x0356 /* MDIO for Reads PCIE PHY */ 108 | #define REG_MDIO_CTL_8812 0x0358 /* MDIO for Control */ 109 | #define REG_PCIE_HRPWM_8812A 0x0361 /* PCIe RPWM */ 110 | #define REG_PCIE_HCPWM_8812A 0x0363 /* PCIe CPWM */ 111 | 112 | #define REG_PCIE_MULTIFET_CTRL_8812 0x036A /* PCIE Multi-Fethc Control */ 113 | 114 | /* ----------------------------------------------------- 115 | * 116 | * 0x0400h ~ 0x047Fh Protocol Configuration 117 | * 118 | * ----------------------------------------------------- */ 119 | #define REG_TXPKT_EMPTY_8812A 0x041A 120 | #define REG_FWHW_TXQ_CTRL_8812A 0x0420 121 | #define REG_TXBF_CTRL_8812A 0x042C 122 | #define REG_ARFR0_8812 0x0444 123 | #define REG_ARFR1_8812 0x044C 124 | #define REG_CCK_CHECK_8812 0x0454 125 | #define REG_AMPDU_MAX_TIME_8812 0x0456 126 | #define REG_TXPKTBUF_BCNQ_BDNY1_8812 0x0457 127 | 128 | #define REG_AMPDU_MAX_LENGTH_8812 0x0458 129 | #define REG_TXPKTBUF_WMAC_LBK_BF_HD_8812 0x045D 130 | #define REG_NDPA_OPT_CTRL_8812A 0x045F 131 | #define REG_DATA_SC_8812 0x0483 132 | #ifdef CONFIG_WOWLAN 133 | #define REG_TXPKTBUF_IV_LOW 0x0484 134 | #define REG_TXPKTBUF_IV_HIGH 0x0488 135 | #endif 136 | #define REG_ARFR2_8812 0x048C 137 | #define REG_ARFR3_8812 0x0494 138 | #define REG_TXRPT_START_OFFSET 0x04AC 139 | #define REG_AMPDU_BURST_MODE_8812 0x04BC 140 | #define REG_HT_SINGLE_AMPDU_8812 0x04C7 141 | #define REG_MACID_PKT_DROP0_8812 0x04D0 142 | 143 | /* ----------------------------------------------------- 144 | * 145 | * 0x0500h ~ 0x05FFh EDCA Configuration 146 | * 147 | * ----------------------------------------------------- */ 148 | #define REG_TXPAUSE_8812A 0x0522 149 | #define REG_CTWND_8812 0x0572 150 | #define REG_SECONDARY_CCA_CTRL_8812 0x0577 151 | #define REG_SCH_TXCMD_8812A 0x05F8 152 | 153 | /* ----------------------------------------------------- 154 | * 155 | * 0x0600h ~ 0x07FFh WMAC Configuration 156 | * 157 | * ----------------------------------------------------- */ 158 | #define REG_MAC_CR_8812 0x0600 159 | 160 | #define REG_MAC_TX_SM_STATE_8812 0x06B4 161 | 162 | /* Power */ 163 | #define REG_BFMER0_INFO_8812A 0x06E4 164 | #define REG_BFMER1_INFO_8812A 0x06EC 165 | #define REG_CSI_RPT_PARAM_BW20_8812A 0x06F4 166 | #define REG_CSI_RPT_PARAM_BW40_8812A 0x06F8 167 | #define REG_CSI_RPT_PARAM_BW80_8812A 0x06FC 168 | 169 | /* Hardware Port 2 */ 170 | #define REG_BFMEE_SEL_8812A 0x0714 171 | #define REG_SND_PTCL_CTRL_8812A 0x0718 172 | 173 | 174 | /* ----------------------------------------------------- 175 | * 176 | * Redifine register definition for compatibility 177 | * 178 | * ----------------------------------------------------- */ 179 | 180 | /* TODO: use these definition when using REG_xxx naming rule. 181 | * NOTE: DO NOT Remove these definition. Use later. */ 182 | #define ISR_8812 REG_HISR0_8812 183 | 184 | /* ---------------------------------------------------------------------------- 185 | * 8195 IMR/ISR bits (offset 0xB0, 8bits) 186 | * ---------------------------------------------------------------------------- */ 187 | #define IMR_DISABLED_8812 0 188 | /* IMR DW0(0x00B0-00B3) Bit 0-31 */ 189 | #define IMR_TIMER2_8812 BIT31 /* Timeout interrupt 2 */ 190 | #define IMR_TIMER1_8812 BIT30 /* Timeout interrupt 1 */ 191 | #define IMR_PSTIMEOUT_8812 BIT29 /* Power Save Time Out Interrupt */ 192 | #define IMR_GTINT4_8812 BIT28 /* When GTIMER4 expires, this bit is set to 1 */ 193 | #define IMR_GTINT3_8812 BIT27 /* When GTIMER3 expires, this bit is set to 1 */ 194 | #define IMR_TXBCN0ERR_8812 BIT26 /* Transmit Beacon0 Error */ 195 | #define IMR_TXBCN0OK_8812 BIT25 /* Transmit Beacon0 OK */ 196 | #define IMR_TSF_BIT32_TOGGLE_8812 BIT24 /* TSF Timer BIT32 toggle indication interrupt */ 197 | #define IMR_BCNDMAINT0_8812 BIT20 /* Beacon DMA Interrupt 0 */ 198 | #define IMR_BCNDERR0_8812 BIT16 /* Beacon Queue DMA OK0 */ 199 | #define IMR_HSISR_IND_ON_INT_8812 BIT15 /* HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) */ 200 | #define IMR_BCNDMAINT_E_8812 BIT14 /* Beacon DMA Interrupt Extension for Win7 */ 201 | #define IMR_ATIMEND_8812 BIT12 /* CTWidnow End or ATIM Window End */ 202 | #define IMR_C2HCMD_8812 BIT10 /* CPU to Host Command INT Status, Write 1 clear */ 203 | #define IMR_CPWM2_8812 BIT9 /* CPU power Mode exchange INT Status, Write 1 clear */ 204 | #define IMR_CPWM_8812 BIT8 /* CPU power Mode exchange INT Status, Write 1 clear */ 205 | #define IMR_HIGHDOK_8812 BIT7 /* High Queue DMA OK */ 206 | #define IMR_MGNTDOK_8812 BIT6 /* Management Queue DMA OK */ 207 | #define IMR_BKDOK_8812 BIT5 /* AC_BK DMA OK */ 208 | #define IMR_BEDOK_8812 BIT4 /* AC_BE DMA OK */ 209 | #define IMR_VIDOK_8812 BIT3 /* AC_VI DMA OK */ 210 | #define IMR_VODOK_8812 BIT2 /* AC_VO DMA OK */ 211 | #define IMR_RDU_8812 BIT1 /* Rx Descriptor Unavailable */ 212 | #define IMR_ROK_8812 BIT0 /* Receive DMA OK */ 213 | 214 | /* IMR DW1(0x00B4-00B7) Bit 0-31 */ 215 | #define IMR_BCNDMAINT7_8812 BIT27 /* Beacon DMA Interrupt 7 */ 216 | #define IMR_BCNDMAINT6_8812 BIT26 /* Beacon DMA Interrupt 6 */ 217 | #define IMR_BCNDMAINT5_8812 BIT25 /* Beacon DMA Interrupt 5 */ 218 | #define IMR_BCNDMAINT4_8812 BIT24 /* Beacon DMA Interrupt 4 */ 219 | #define IMR_BCNDMAINT3_8812 BIT23 /* Beacon DMA Interrupt 3 */ 220 | #define IMR_BCNDMAINT2_8812 BIT22 /* Beacon DMA Interrupt 2 */ 221 | #define IMR_BCNDMAINT1_8812 BIT21 /* Beacon DMA Interrupt 1 */ 222 | #define IMR_BCNDOK7_8812 BIT20 /* Beacon Queue DMA OK Interrup 7 */ 223 | #define IMR_BCNDOK6_8812 BIT19 /* Beacon Queue DMA OK Interrup 6 */ 224 | #define IMR_BCNDOK5_8812 BIT18 /* Beacon Queue DMA OK Interrup 5 */ 225 | #define IMR_BCNDOK4_8812 BIT17 /* Beacon Queue DMA OK Interrup 4 */ 226 | #define IMR_BCNDOK3_8812 BIT16 /* Beacon Queue DMA OK Interrup 3 */ 227 | #define IMR_BCNDOK2_8812 BIT15 /* Beacon Queue DMA OK Interrup 2 */ 228 | #define IMR_BCNDOK1_8812 BIT14 /* Beacon Queue DMA OK Interrup 1 */ 229 | #define IMR_ATIMEND_E_8812 BIT13 /* ATIM Window End Extension for Win7 */ 230 | #define IMR_TXERR_8812 BIT11 /* Tx Error Flag Interrupt Status, write 1 clear. */ 231 | #define IMR_RXERR_8812 BIT10 /* Rx Error Flag INT Status, Write 1 clear */ 232 | #define IMR_TXFOVW_8812 BIT9 /* Transmit FIFO Overflow */ 233 | #define IMR_RXFOVW_8812 BIT8 /* Receive FIFO Overflow */ 234 | 235 | 236 | #ifdef CONFIG_PCI_HCI 237 | /* #define IMR_RX_MASK (IMR_ROK_8812|IMR_RDU_8812|IMR_RXFOVW_8812) */ 238 | #define IMR_TX_MASK (IMR_VODOK_8812 | IMR_VIDOK_8812 | IMR_BEDOK_8812 | IMR_BKDOK_8812 | IMR_MGNTDOK_8812 | IMR_HIGHDOK_8812) 239 | 240 | #define RT_BCN_INT_MASKS (IMR_BCNDMAINT0_8812 | IMR_TXBCN0OK_8812 | IMR_TXBCN0ERR_8812 | IMR_BCNDERR0_8812) 241 | 242 | #define RT_AC_INT_MASKS (IMR_VIDOK_8812 | IMR_VODOK_8812 | IMR_BEDOK_8812 | IMR_BKDOK_8812) 243 | #endif 244 | 245 | 246 | /* **************************************************************************** 247 | * Regsiter Bit and Content definition 248 | * **************************************************************************** */ 249 | 250 | /* 2 ACMHWCTRL 0x05C0 */ 251 | #define AcmHw_HwEn_8812 BIT(0) 252 | #define AcmHw_VoqEn_8812 BIT(1) 253 | #define AcmHw_ViqEn_8812 BIT(2) 254 | #define AcmHw_BeqEn_8812 BIT(3) 255 | #define AcmHw_VoqStatus_8812 BIT(5) 256 | #define AcmHw_ViqStatus_8812 BIT(6) 257 | #define AcmHw_BeqStatus_8812 BIT(7) 258 | 259 | #endif /* __RTL8812A_SPEC_H__ */ 260 | 261 | #ifdef CONFIG_RTL8821A 262 | #include "rtl8821a_spec.h" 263 | #endif /* CONFIG_RTL8821A */ 264 | -------------------------------------------------------------------------------- /hal/rtw_efuse.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright(c) 2007 - 2017 Realtek Corporation. 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of version 2 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | *****************************************************************************/ 15 | #ifndef __RTW_EFUSE_H__ 16 | #define __RTW_EFUSE_H__ 17 | 18 | #include "drv_types.h" 19 | 20 | #define EFUSE_ERROE_HANDLE 1 21 | 22 | #define PG_STATE_HEADER 0x01 23 | #define PG_STATE_WORD_0 0x02 24 | #define PG_STATE_WORD_1 0x04 25 | #define PG_STATE_WORD_2 0x08 26 | #define PG_STATE_WORD_3 0x10 27 | #define PG_STATE_DATA 0x20 28 | 29 | #define PG_SWBYTE_H 0x01 30 | #define PG_SWBYTE_L 0x02 31 | 32 | #define PGPKT_DATA_SIZE 8 33 | 34 | #define EFUSE_WIFI 0 35 | #define EFUSE_BT 1 36 | 37 | enum _EFUSE_DEF_TYPE { 38 | TYPE_EFUSE_MAX_SECTION = 0, 39 | TYPE_EFUSE_REAL_CONTENT_LEN = 1, 40 | TYPE_AVAILABLE_EFUSE_BYTES_BANK = 2, 41 | TYPE_AVAILABLE_EFUSE_BYTES_TOTAL = 3, 42 | TYPE_EFUSE_MAP_LEN = 4, 43 | TYPE_EFUSE_PROTECT_BYTES_BANK = 5, 44 | TYPE_EFUSE_CONTENT_LEN_BANK = 6, 45 | }; 46 | 47 | #define EFUSE_MAX_MAP_LEN 1024 48 | 49 | #define EFUSE_MAX_HW_SIZE 1024 50 | #define EFUSE_MAX_SECTION_BASE 16 51 | #define EFUSE_MAX_SECTION_NUM 128 52 | #define EFUSE_MAX_BANK_SIZE 512 53 | 54 | /*RTL8822B 8821C BT EFUSE Define 1 BANK 128 size logical map 1024*/ 55 | #ifdef RTW_HALMAC 56 | #define BANK_NUM 1 57 | #define EFUSE_BT_REAL_BANK_CONTENT_LEN 128 58 | #define EFUSE_BT_REAL_CONTENT_LEN (EFUSE_BT_REAL_BANK_CONTENT_LEN * BANK_NUM) 59 | #define EFUSE_BT_MAP_LEN 1024 /* 1k bytes */ 60 | #define EFUSE_BT_MAX_SECTION (EFUSE_BT_MAP_LEN / 8) 61 | #define EFUSE_PROTECT_BYTES_BANK 16 62 | #define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_BT_REAL_CONTENT_LEN) 63 | #endif 64 | 65 | #define EXT_HEADER(header) ((header & 0x1F) == 0x0F) 66 | #define ALL_WORDS_DISABLED(wde) ((wde & 0x0F) == 0x0F) 67 | #define GET_HDR_OFFSET_2_0(header) ((header & 0xE0) >> 5) 68 | 69 | #define EFUSE_REPEAT_THRESHOLD_ 3 70 | 71 | #define IS_MASKED_MP(ic, txt, offset) (EFUSE_IsAddressMasked_MP_##ic##txt(offset)) 72 | #define IS_MASKED_TC(ic, txt, offset) (EFUSE_IsAddressMasked_TC_##ic##txt(offset)) 73 | #define GET_MASK_ARRAY_LEN_MP(ic, txt) (EFUSE_GetArrayLen_MP_##ic##txt()) 74 | #define GET_MASK_ARRAY_LEN_TC(ic, txt) (EFUSE_GetArrayLen_TC_##ic##txt()) 75 | #define GET_MASK_ARRAY_MP(ic, txt, offset) (EFUSE_GetMaskArray_MP_##ic##txt(offset)) 76 | #define GET_MASK_ARRAY_TC(ic, txt, offset) (EFUSE_GetMaskArray_TC_##ic##txt(offset)) 77 | 78 | 79 | #define IS_MASKED(ic, txt, offset) (IS_MASKED_MP(ic, txt, offset)) 80 | #define GET_MASK_ARRAY_LEN(ic, txt) (GET_MASK_ARRAY_LEN_MP(ic, txt)) 81 | #define GET_MASK_ARRAY(ic, txt, out) do { GET_MASK_ARRAY_MP(ic, txt, out); } while (0) 82 | 83 | /* ********************************************* 84 | * The following is for BT Efuse definition 85 | * ********************************************* */ 86 | #define EFUSE_BT_MAX_MAP_LEN 1024 87 | #define EFUSE_MAX_BANK 4 88 | #define EFUSE_MAX_BT_BANK (EFUSE_MAX_BANK-1) 89 | /* ********************************************* 90 | *--------------------------Define Parameters-------------------------------*/ 91 | #define EFUSE_MAX_WORD_UNIT 4 92 | 93 | /*------------------------------Define structure----------------------------*/ 94 | typedef struct PG_PKT_STRUCT_A { 95 | u8 offset; 96 | u8 word_en; 97 | u8 data[8]; 98 | u8 word_cnts; 99 | } PGPKT_STRUCT, *PPGPKT_STRUCT; 100 | 101 | typedef enum { 102 | ERR_SUCCESS = 0, 103 | ERR_DRIVER_FAILURE, 104 | ERR_IO_FAILURE, 105 | ERR_WI_TIMEOUT, 106 | ERR_WI_BUSY, 107 | ERR_BAD_FORMAT, 108 | ERR_INVALID_DATA, 109 | ERR_NOT_ENOUGH_SPACE, 110 | ERR_WRITE_PROTECT, 111 | ERR_READ_BACK_FAIL, 112 | ERR_OUT_OF_RANGE 113 | } ERROR_CODE; 114 | 115 | /*------------------------------Define structure----------------------------*/ 116 | typedef struct _EFUSE_HAL { 117 | u8 fakeEfuseBank; 118 | u32 fakeEfuseUsedBytes; 119 | u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE]; 120 | u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN]; 121 | u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN]; 122 | u32 EfuseUsedBytes; 123 | u8 EfuseUsedPercentage; 124 | 125 | u16 BTEfuseUsedBytes; 126 | u8 BTEfuseUsedPercentage; 127 | u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; 128 | u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; 129 | u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; 130 | 131 | u16 fakeBTEfuseUsedBytes; 132 | u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; 133 | u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; 134 | u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; 135 | 136 | /* EFUSE Configuration, initialized in HAL_CmnInitPGData(). */ 137 | const u16 MaxSecNum_WiFi; 138 | const u16 MaxSecNum_BT; 139 | const u16 WordUnit; 140 | const u16 PhysicalLen_WiFi; 141 | const u16 PhysicalLen_BT; 142 | const u16 LogicalLen_WiFi; 143 | const u16 LogicalLen_BT; 144 | const u16 BankSize; 145 | const u16 TotalBankNum; 146 | const u16 BankNum_WiFi; 147 | const u16 BankNum_BT; 148 | const u16 OOBProtectBytes; 149 | const u16 ProtectBytes; 150 | const u16 BankAvailBytes; 151 | const u16 TotalAvailBytes_WiFi; 152 | const u16 TotalAvailBytes_BT; 153 | const u16 HeaderRetry; 154 | const u16 DataRetry; 155 | 156 | ERROR_CODE Status; 157 | 158 | } EFUSE_HAL, *PEFUSE_HAL; 159 | 160 | extern u8 maskfileBuffer[64]; 161 | 162 | /*------------------------Export global variable----------------------------*/ 163 | extern u8 fakeEfuseBank; 164 | extern u32 fakeEfuseUsedBytes; 165 | extern u8 fakeEfuseContent[]; 166 | extern u8 fakeEfuseInitMap[]; 167 | extern u8 fakeEfuseModifiedMap[]; 168 | 169 | extern u32 BTEfuseUsedBytes; 170 | extern u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; 171 | extern u8 BTEfuseInitMap[]; 172 | extern u8 BTEfuseModifiedMap[]; 173 | 174 | extern u32 fakeBTEfuseUsedBytes; 175 | extern u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; 176 | extern u8 fakeBTEfuseInitMap[]; 177 | extern u8 fakeBTEfuseModifiedMap[]; 178 | /*------------------------Export global variable----------------------------*/ 179 | #define MAX_SEGMENT_SIZE 200 180 | #define MAX_SEGMENT_NUM 200 181 | #define MAX_BUF_SIZE (MAX_SEGMENT_SIZE*MAX_SEGMENT_NUM) 182 | #define TMP_BUF_SIZE 100 183 | 184 | static u8 dcmd_Return_Buffer[MAX_BUF_SIZE] = {0}; 185 | static u32 dcmd_Buf_Idx = 0; 186 | static u32 dcmd_Finifh_Flag = 0; 187 | 188 | static char dcmd_Buf[TMP_BUF_SIZE]; 189 | 190 | #define rtprintf dcmd_Store_Return_Buf 191 | 192 | u8 efuse_bt_GetCurrentSize(PADAPTER padapter, u16 *size); 193 | u16 efuse_bt_GetMaxSize(PADAPTER padapter); 194 | u16 efuse_GetavailableSize(PADAPTER adapter); 195 | 196 | u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size); 197 | u16 efuse_GetMaxSize(PADAPTER padapter); 198 | u8 rtw_efuse_access(PADAPTER padapter, u8 bRead, u16 start_addr, u16 cnts, u8 *data); 199 | u8 rtw_efuse_bt_access(PADAPTER adapter, u8 write, u16 addr, u16 cnts, u8 *data); 200 | 201 | u8 rtw_efuse_mask_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); 202 | u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); 203 | u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); 204 | u8 rtw_BT_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); 205 | u8 rtw_BT_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); 206 | 207 | u16 Efuse_GetCurrentSize(PADAPTER pAdapter, u8 efuseType, BOOLEAN bPseudoTest); 208 | u8 Efuse_CalculateWordCnts(u8 word_en); 209 | void ReadEFuseByte(PADAPTER Adapter, u16 _offset, u8 *pbuf, BOOLEAN bPseudoTest) ; 210 | void EFUSE_GetEfuseDefinition(PADAPTER pAdapter, u8 efuseType, u8 type, void *pOut, BOOLEAN bPseudoTest); 211 | u8 efuse_OneByteRead(PADAPTER pAdapter, u16 addr, u8 *data, BOOLEAN bPseudoTest); 212 | #define efuse_onebyte_read(adapter, addr, data, pseudo_test) efuse_OneByteRead((adapter), (addr), (data), (pseudo_test)) 213 | 214 | u8 efuse_OneByteWrite(PADAPTER pAdapter, u16 addr, u8 data, BOOLEAN bPseudoTest); 215 | 216 | void BTEfuse_PowerSwitch(PADAPTER pAdapter, u8 bWrite, u8 PwrState); 217 | void Efuse_PowerSwitch(PADAPTER pAdapter, u8 bWrite, u8 PwrState); 218 | int Efuse_PgPacketRead(PADAPTER pAdapter, u8 offset, u8 *data, BOOLEAN bPseudoTest); 219 | int Efuse_PgPacketWrite(PADAPTER pAdapter, u8 offset, u8 word_en, u8 *data, BOOLEAN bPseudoTest); 220 | void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata); 221 | u8 Efuse_WordEnableDataWrite(PADAPTER pAdapter, u16 efuse_addr, u8 word_en, u8 *data, BOOLEAN bPseudoTest); 222 | void EFUSE_ShadowMapUpdate(PADAPTER pAdapter, u8 efuseType, BOOLEAN bPseudoTest); 223 | void EFUSE_ShadowRead(PADAPTER pAdapter, u8 Type, u16 Offset, u32 *Value); 224 | #define efuse_logical_map_read(adapter, type, offset, value) EFUSE_ShadowRead((adapter), (type), (offset), (value)) 225 | 226 | VOID hal_ReadEFuse_BT_logic_map( 227 | PADAPTER padapter, 228 | u16 _offset, 229 | u16 _size_byte, 230 | u8 *pbuf 231 | ); 232 | u8 EfusePgPacketWrite_BT( 233 | PADAPTER pAdapter, 234 | u8 offset, 235 | u8 word_en, 236 | u8 *pData, 237 | u8 bPseudoTest); 238 | u16 rtw_get_efuse_mask_arraylen(PADAPTER pAdapter); 239 | void rtw_efuse_mask_array(PADAPTER pAdapter, u8 *pArray); 240 | void rtw_efuse_analyze(PADAPTER padapter, u8 Type, u8 Fake); 241 | 242 | #define MAC_HIDDEN_MAX_BW_NUM 8 243 | extern const u8 _mac_hidden_max_bw_to_hal_bw_cap[]; 244 | #define mac_hidden_max_bw_to_hal_bw_cap(max_bw) (((max_bw) >= MAC_HIDDEN_MAX_BW_NUM) ? 0 : _mac_hidden_max_bw_to_hal_bw_cap[(max_bw)]) 245 | 246 | #define MAC_HIDDEN_PROTOCOL_NUM 4 247 | extern const u8 _mac_hidden_proto_to_hal_proto_cap[]; 248 | #define mac_hidden_proto_to_hal_proto_cap(proto) (((proto) >= MAC_HIDDEN_PROTOCOL_NUM) ? 0 : _mac_hidden_proto_to_hal_proto_cap[(proto)]) 249 | 250 | u8 mac_hidden_wl_func_to_hal_wl_func(u8 func); 251 | 252 | #ifdef PLATFORM_LINUX 253 | u8 rtw_efuse_file_read(PADAPTER padapter, u8 *filepatch, u8 *buf, u32 len); 254 | #ifdef CONFIG_EFUSE_CONFIG_FILE 255 | u32 rtw_read_efuse_from_file(const char *path, u8 *buf, int map_size); 256 | u32 rtw_read_macaddr_from_file(const char *path, u8 *buf); 257 | #endif /* CONFIG_EFUSE_CONFIG_FILE */ 258 | #endif /* PLATFORM_LINUX */ 259 | 260 | #endif 261 | -------------------------------------------------------------------------------- /src/EepromManager.h: -------------------------------------------------------------------------------- 1 | #ifndef EEPROMMANAGER_H 2 | #define EEPROMMANAGER_H 3 | 4 | #include "RtlUsbAdapter.h" 5 | #include "logger.h" 6 | 7 | #include "HalVerDef.h" 8 | #include "phydm_pre_define.h" 9 | #include "rtl8812a_hal.h" 10 | 11 | typedef unsigned short ushort; 12 | 13 | class EepromManager { 14 | RtlUsbAdapter _device; 15 | Logger_t _logger; 16 | 17 | uint8_t efuse_eeprom_data[EFUSE_MAP_LEN_JAGUAR]; /*92C:256bytes, 88E:512bytes, 18 | we use union set (512bytes)*/ 19 | uint8_t EEPROMVersion; 20 | uint8_t EEPROMRegulatory; 21 | bool EEPROMBluetoothCoexist; 22 | uint8_t eeprom_thermal_meter; 23 | uint8_t PAType_2G; 24 | uint8_t PAType_5G; 25 | uint8_t LNAType_2G; 26 | uint8_t LNAType_5G; 27 | uint8_t external_pa_5g; 28 | uint8_t external_lna_5g; 29 | 30 | public: 31 | EepromManager(RtlUsbAdapter device, Logger_t logger); 32 | uint8_t GetBoardType(); 33 | void efuse_ShadowRead1Byte(uint16_t Offset, uint8_t *Value); 34 | 35 | HAL_VERSION version_id; 36 | odm_cut_version_e cut_version; 37 | uint8_t crystal_cap; 38 | uint16_t TypeGPA; 39 | uint16_t TypeAPA; 40 | uint16_t TypeGLNA; 41 | uint16_t TypeALNA; 42 | uint8_t numTotalRfPath; 43 | bool ExternalLNA_2G; 44 | bool ExternalPA_2G; 45 | HAL_RF_TYPE_E rf_type; 46 | uint16_t rfe_type; 47 | 48 | private: 49 | void read_chip_version_8812a(RtlUsbAdapter device); 50 | void dump_chip_info(HAL_VERSION ChipVersion); 51 | void rtw_hal_config_rftype(); 52 | void hal_InitPGData_8812A(); 53 | void EFUSE_ShadowMapUpdate(uint8_t efuseType); 54 | void Efuse_ReadAllMap(uint8_t efuseType, uint8_t *Efuse); 55 | void EfusePowerSwitch8812A(bool bWrite, bool pwrState); 56 | bool IsEfuseTxPowerInfoValid(uint8_t *efuseEepromData); 57 | void efuse_ReadEFuse(uint8_t efuseType, uint16_t _offset, uint16_t _size_byte, 58 | uint8_t *pbuf); 59 | void Hal_EfuseReadEFuse8812A(uint16_t _offset, uint16_t _size_byte, 60 | uint8_t *pbuf); 61 | void rtw_dump_cur_efuse(); 62 | void Hal_EfuseParseIDCode8812A(); 63 | uint8_t Hal_ReadPROMVersion8812A(RtlUsbAdapter device, 64 | uint8_t *efuse_eeprom_data); 65 | uint8_t Hal_ReadTxPowerInfo8812A(RtlUsbAdapter device, 66 | uint8_t *efuse_eeprom_data); 67 | void Hal_EfuseParseBTCoexistInfo8812A(); 68 | void Hal_EfuseParseXtal_8812A(); 69 | void Hal_ReadThermalMeter_8812A(); 70 | void Hal_ReadAmplifierType_8812A(); 71 | void hal_ReadPAType_8812A(); 72 | void Hal_ReadRFEType_8812A(); 73 | void hal_ReadUsbType_8812AU(); 74 | }; 75 | 76 | #endif /* EEPROMMANAGER_H */ 77 | -------------------------------------------------------------------------------- /src/Firmware.h: -------------------------------------------------------------------------------- 1 | #ifndef FIRMWARE_H 2 | #define FIRMWARE_H 3 | 4 | #define CONFIG_RTL8812A 5 | #define LOAD_FW_HEADER_FROM_DRIVER 6 | #define ODM_WIN 1 7 | #define DM_ODM_SUPPORT_TYPE ODM_WIN 8 | typedef uint8_t u8; 9 | typedef uint32_t u32; 10 | extern "C"{ 11 | #include "hal8812a_fw.h" 12 | } 13 | 14 | struct Firmware { 15 | constexpr static u8 *pFirmwareBuf = array_mp_8812a_fw_nic; 16 | constexpr static size_t FirmwareLen = sizeof(array_mp_8812a_fw_nic); 17 | }; 18 | 19 | #endif /* FIRMWARE_H */ 20 | -------------------------------------------------------------------------------- /src/FirmwareManager.cpp: -------------------------------------------------------------------------------- 1 | #include "FirmwareManager.h" 2 | 3 | #include "Firmware.h" 4 | #include "rtl8812a_hal.h" 5 | 6 | #include 7 | 8 | template 11 | auto since(std::chrono::time_point const &start) { 12 | return std::chrono::duration_cast(clock_t::now() - start); 13 | } 14 | 15 | FirmwareManager::FirmwareManager(RtlUsbAdapter device, Logger_t logger) 16 | : _device{device}, _logger{logger} {} 17 | 18 | void FirmwareManager::FirmwareDownload8812() { 19 | bool rtStatus = true; 20 | uint8_t write_fw = 0; 21 | 22 | auto pFirmwareBuf = Firmware::pFirmwareBuf; 23 | auto FirmwareLen = Firmware::FirmwareLen; 24 | 25 | auto firmwareVersion = (uint16_t)GET_FIRMWARE_HDR_VERSION_8812(pFirmwareBuf); 26 | auto firmwareSubVersion = 27 | (uint16_t)GET_FIRMWARE_HDR_SUB_VER_8812(pFirmwareBuf); 28 | auto firmwareSignature = 29 | (uint16_t)GET_FIRMWARE_HDR_SIGNATURE_8812(pFirmwareBuf); 30 | 31 | _logger->info("FirmwareDownload8812: fw_ver={} " 32 | "fw_subver={} sig=0x{:X}", 33 | firmwareVersion, firmwareSubVersion, firmwareSignature); 34 | 35 | if (IS_FW_HEADER_EXIST_8812(pFirmwareBuf)) { 36 | /* Shift 32 bytes for FW header */ 37 | pFirmwareBuf = pFirmwareBuf + 32; 38 | FirmwareLen -= 32; 39 | } 40 | 41 | /* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw 42 | * to reset by itself, */ 43 | /* or it will cause download Fw fail. 2010.02.01. by tynli. */ 44 | if ((_device.rtw_read8(REG_MCUFWDL) & BIT7) != 0) { 45 | /* 8051 RAM code */ 46 | _device.rtw_write8(REG_MCUFWDL, 0x00); 47 | _device._8051Reset8812(); 48 | } 49 | 50 | _FWDownloadEnable_8812(true); 51 | 52 | auto fwdl_start_time = std::chrono::steady_clock::now(); 53 | while ((write_fw++ < 3 || (since(fwdl_start_time).count()) < 500)) { 54 | /* reset FWDL chksum */ 55 | _device.rtw_write8(REG_MCUFWDL, (uint8_t)(_device.rtw_read8(REG_MCUFWDL) | 56 | FWDL_ChkSum_rpt)); 57 | 58 | rtStatus = WriteFW8812(pFirmwareBuf, FirmwareLen); 59 | if (rtStatus != true) { 60 | continue; 61 | } 62 | 63 | rtStatus = polling_fwdl_chksum(5, 50); 64 | if (rtStatus == true) { 65 | break; 66 | } 67 | } 68 | 69 | _FWDownloadEnable_8812(false); 70 | if (true != rtStatus) { 71 | return; 72 | } 73 | 74 | rtStatus = _FWFreeToGo8812(10, 200); 75 | if (true != rtStatus) { 76 | return; 77 | } 78 | 79 | InitializeFirmwareVars8812(); 80 | } 81 | 82 | // TODO: now does nothing 83 | static void yield() {} 84 | 85 | void FirmwareManager::_FWDownloadEnable_8812(bool enable) { 86 | u8 tmp; 87 | 88 | if (enable) { 89 | /* MCU firmware download enable. */ 90 | tmp = _device.rtw_read8(REG_MCUFWDL); 91 | _device.rtw_write8(REG_MCUFWDL, tmp | 0x01); 92 | 93 | /* 8051 reset */ 94 | tmp = _device.rtw_read8(REG_MCUFWDL + 2); 95 | _device.rtw_write8(REG_MCUFWDL + 2, tmp & 0xf7); 96 | } else { 97 | 98 | /* MCU firmware download disable. */ 99 | tmp = _device.rtw_read8(REG_MCUFWDL); 100 | _device.rtw_write8(REG_MCUFWDL, tmp & 0xfe); 101 | } 102 | } 103 | 104 | bool FirmwareManager::WriteFW8812(uint8_t *buffer, uint32_t size) { 105 | const int MAX_DLFW_PAGE_SIZE = 4096; /* @ page : 4k bytes */ 106 | 107 | /* Since we need dynamic decide method of dwonload fw, so we call this 108 | * function to get chip version. */ 109 | bool ret = true; 110 | int32_t pageNums, remainSize; 111 | int32_t page; 112 | int offset; 113 | auto bufferPtr = buffer; 114 | 115 | pageNums = (int)(size / MAX_DLFW_PAGE_SIZE); 116 | /* RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n")); 117 | */ 118 | remainSize = (int)(size % MAX_DLFW_PAGE_SIZE); 119 | 120 | for (page = 0; page < pageNums; page++) { 121 | offset = page * MAX_DLFW_PAGE_SIZE; 122 | ret = _PageWrite_8812(page, bufferPtr + offset, MAX_DLFW_PAGE_SIZE); 123 | 124 | if (ret == false) { 125 | goto exit; 126 | } 127 | } 128 | 129 | if (remainSize != 0) { 130 | offset = pageNums * MAX_DLFW_PAGE_SIZE; 131 | page = pageNums; 132 | ret = _PageWrite_8812(page, bufferPtr + offset, remainSize); 133 | 134 | if (ret == false) { 135 | goto exit; 136 | } 137 | } 138 | 139 | exit: 140 | return ret; 141 | } 142 | 143 | int FirmwareManager::_PageWrite_8812(uint32_t page, uint8_t *buffer, 144 | uint32_t size) { 145 | u8 value8; 146 | u8 u8Page = (u8)(page & 0x07); 147 | 148 | value8 = (_device.rtw_read8(REG_MCUFWDL + 2) & 0xF8) | u8Page; 149 | _device.rtw_write8(REG_MCUFWDL + 2, value8); 150 | 151 | return BlockWrite(buffer, size); 152 | } 153 | 154 | bool FirmwareManager::BlockWrite(uint8_t *buffer, int buffSize) { 155 | const int MAX_REG_BOLCK_SIZE = 196; 156 | 157 | bool ret = true; 158 | 159 | uint32_t blockSize_p1 = 160 | 4; /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */ 161 | uint32_t blockSize_p2 = 162 | 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */ 163 | uint32_t blockSize_p3 = 164 | 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */ 165 | uint32_t blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0; 166 | uint32_t remainSize_p1 = 0, remainSize_p2 = 0; 167 | // byte *bufferPtr = (byte *)buffer; 168 | uint32_t i = 0, offset = 0; 169 | 170 | blockSize_p1 = MAX_REG_BOLCK_SIZE; 171 | 172 | /* 3 Phase #1 */ 173 | blockCount_p1 = (uint32_t)(buffSize / blockSize_p1); 174 | remainSize_p1 = (uint32_t)(buffSize % blockSize_p1); 175 | 176 | for (i = 0; i < blockCount_p1; i++) { 177 | _device.WriteBytes((ushort)(FW_START_ADDRESS + i * blockSize_p1), 178 | buffer + i * blockSize_p1, (int)blockSize_p1); 179 | } 180 | 181 | /* 3 Phase #2 */ 182 | if (remainSize_p1 != 0) { 183 | offset = blockCount_p1 * blockSize_p1; 184 | 185 | blockCount_p2 = remainSize_p1 / blockSize_p2; 186 | remainSize_p2 = remainSize_p1 % blockSize_p2; 187 | 188 | for (i = 0; i < blockCount_p2; i++) { 189 | _device.WriteBytes((ushort)(FW_START_ADDRESS + offset + i * blockSize_p2), 190 | buffer + offset + i * blockSize_p2, (int)blockSize_p2); 191 | } 192 | } 193 | 194 | /* 3 Phase #3 */ 195 | if (remainSize_p2 != 0) { 196 | offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2); 197 | 198 | blockCount_p3 = remainSize_p2 / blockSize_p3; 199 | 200 | for (i = 0; i < blockCount_p3; i++) { 201 | _device.rtw_write8((ushort)(FW_START_ADDRESS + offset + i), 202 | buffer[(int)(offset + i)]); 203 | } 204 | } 205 | 206 | return ret; 207 | } 208 | 209 | void FirmwareManager::InitializeFirmwareVars8812() { 210 | /* Init H2C cmd. */ 211 | _device.rtw_write8(REG_HMETFR, 0x0f); 212 | } 213 | 214 | bool FirmwareManager::polling_fwdl_chksum(uint32_t min_cnt, uint32_t timeout_ms) { 215 | bool ret = false; 216 | u32 value32; 217 | auto start = std::chrono::steady_clock::now(); 218 | u32 cnt = 0; 219 | 220 | /* polling CheckSum report */ 221 | do { 222 | cnt++; 223 | value32 = _device.rtw_read32(REG_MCUFWDL); 224 | if (value32 & FWDL_ChkSum_rpt) 225 | break; 226 | yield(); 227 | } while (since(start).count() < timeout_ms || cnt < min_cnt); 228 | 229 | if (!(value32 & FWDL_ChkSum_rpt)) 230 | goto exit; 231 | 232 | ret = true; 233 | 234 | exit: 235 | _logger->info("{}: Checksum report {}! ({}, {}ms), REG_MCUFWDL:{:08x}", 236 | __FUNCTION__, ret == true ? "OK" : "Fail", cnt, 237 | since(start).count(), value32); 238 | 239 | return ret; 240 | } 241 | 242 | bool FirmwareManager::_FWFreeToGo8812(uint32_t min_cnt, uint32_t timeout_ms) { 243 | bool ret = false; 244 | uint32_t value32; 245 | uint32_t cnt = 0; 246 | 247 | value32 = _device.rtw_read32(REG_MCUFWDL); 248 | value32 |= MCUFWDL_RDY; 249 | value32 = (uint32_t)(value32 & ~WINTINI_RDY); 250 | _device.rtw_write32(REG_MCUFWDL, value32); 251 | 252 | _device._8051Reset8812(); 253 | 254 | auto start = std::chrono::steady_clock::now(); 255 | /* polling for FW ready */ 256 | do { 257 | cnt++; 258 | value32 = _device.rtw_read32(REG_MCUFWDL); 259 | if ((value32 & WINTINI_RDY) != 0) { 260 | break; 261 | } 262 | yield(); 263 | } while (since(start).count() < timeout_ms || cnt < min_cnt); 264 | 265 | if (!((value32 & WINTINI_RDY) != 0)) { 266 | goto exit; 267 | } 268 | 269 | // if (rtw_fwdl_test_trigger_wintint_rdy_fail()) 270 | //{ 271 | // goto exit; 272 | // } 273 | 274 | ret = true; 275 | 276 | exit: 277 | _logger->info("{}: Polling FW ready {}! ({}, {}ms), REG_MCUFWDL:0x{:08x}", 278 | __FUNCTION__, ret == true ? "OK" : "Fail", cnt, 279 | since(start).count(), value32); 280 | 281 | return ret; 282 | } 283 | -------------------------------------------------------------------------------- /src/FirmwareManager.h: -------------------------------------------------------------------------------- 1 | #ifndef FIRMWAREMANAGER_H 2 | #define FIRMWAREMANAGER_H 3 | 4 | #include "RtlUsbAdapter.h" 5 | #include "logger.h" 6 | 7 | class FirmwareManager { 8 | RtlUsbAdapter _device; 9 | Logger_t _logger; 10 | 11 | public: 12 | FirmwareManager(RtlUsbAdapter device, Logger_t logger); 13 | void FirmwareDownload8812(); 14 | 15 | private: 16 | void _FWDownloadEnable_8812(bool enable); 17 | bool WriteFW8812(uint8_t *buffer, uint32_t size); 18 | int _PageWrite_8812(uint32_t page, uint8_t *buffer, uint32_t size); 19 | bool BlockWrite(uint8_t *buffer, int buffSize); 20 | void InitializeFirmwareVars8812(); 21 | bool polling_fwdl_chksum(uint32_t min_cnt, uint32_t timeout_ms); 22 | bool _FWFreeToGo8812(uint32_t min_cnt, uint32_t timeout_ms); 23 | 24 | }; 25 | 26 | #endif /* FIRMWAREMANAGER_H */ 27 | -------------------------------------------------------------------------------- /src/FrameParser.cpp: -------------------------------------------------------------------------------- 1 | #include "FrameParser.h" 2 | 3 | #define CONFIG_USB_RX_AGGREGATION 1 4 | 5 | #define RXDESC_SIZE 24 6 | 7 | #include "basic_types.h" 8 | #include "rtl8812a_recv.h" 9 | 10 | #include 11 | #include 12 | 13 | struct _phy_status_rpt_8812 { 14 | /* DWORD 0*/ 15 | u8 gain_trsw[2]; /*path-A and path-B {TRSW, gain[6:0] }*/ 16 | u8 chl_num_LSB; /*channel number[7:0]*/ 17 | u8 chl_num_MSB : 2; /*channel number[9:8]*/ 18 | u8 sub_chnl : 4; /*sub-channel location[3:0]*/ 19 | u8 r_RFMOD : 2; /*RF mode[1:0]*/ 20 | 21 | /* DWORD 1*/ 22 | u8 pwdb_all; /*CCK signal quality / OFDM pwdb all*/ 23 | s8 cfosho[2]; /*DW1 byte 1 DW1 byte2 CCK AGC report and CCK_BB_Power / 24 | OFDM path-A and path-B short CFO*/ 25 | /*this should be checked again because the definition of 8812 and 8814 26 | * is different*/ 27 | /* u8 r_cck_rx_enable_pathc:2; cck rx enable pathc[1:0]*/ 28 | /* u8 cck_rx_path:4; cck rx path[3:0]*/ 29 | u8 resvd_0 : 6; 30 | u8 bt_RF_ch_MSB : 2; /*8812A:2'b0 8814A: bt rf channel keep[7:6]*/ 31 | u8 ant_div_sw_a : 1; /*8812A: ant_div_sw_a 8814A: 1'b0*/ 32 | u8 ant_div_sw_b : 1; /*8812A: ant_div_sw_b 8814A: 1'b0*/ 33 | u8 bt_RF_ch_LSB : 6; /*8812A: 6'b0 8814A: bt rf 34 | channel keep[5:0]*/ 35 | s8 cfotail[2]; /*DW2 byte 1 DW2 byte 2 path-A and path-B CFO tail*/ 36 | u8 PCTS_MSK_RPT_0; /*PCTS mask report[7:0]*/ 37 | u8 PCTS_MSK_RPT_1; /*PCTS mask report[15:8]*/ 38 | 39 | /* DWORD 3*/ 40 | s8 rxevm[2]; /*DW3 byte 1 DW3 byte 2 stream 1 and stream 2 RX EVM*/ 41 | s8 rxsnr[2]; /*DW3 byte 3 DW4 byte 0 path-A and path-B RX SNR*/ 42 | 43 | /* DWORD 4*/ 44 | u8 PCTS_MSK_RPT_2; /*PCTS mask report[23:16]*/ 45 | u8 PCTS_MSK_RPT_3 : 6; /*PCTS mask report[29:24]*/ 46 | u8 pcts_rpt_valid : 1; /*pcts_rpt_valid*/ 47 | u8 resvd_1 : 1; /*1'b0*/ 48 | s8 rxevm_cd[2]; /*DW 4 byte 3 DW5 byte 0 8812A: 16'b0 8814A: stream 3 49 | and stream 4 RX EVM*/ 50 | 51 | /* DWORD 5*/ 52 | u8 csi_current[2]; /*DW5 byte 1 DW5 byte 2 8812A: stream 1 and 2 CSI 53 | 8814A: path-C and path-D RX SNR*/ 54 | u8 gain_trsw_cd[2]; /*DW5 byte 3 DW6 byte 0 path-C and path-D {TRSW, 55 | gain[6:0] }*/ 56 | 57 | /* DWORD 6*/ 58 | s8 sigevm; /*signal field EVM*/ 59 | u8 antidx_antc : 3; /*8812A: 3'b0 8814A: antidx_antc[2:0]*/ 60 | u8 antidx_antd : 3; /*8812A: 3'b0 8814A: antidx_antd[2:0]*/ 61 | u8 dpdt_ctrl_keep : 1; /*8812A: 1'b0 8814A: dpdt_ctrl_keep*/ 62 | u8 GNT_BT_keep : 1; /*8812A: 1'b0 8814A: GNT_BT_keep*/ 63 | u8 antidx_anta : 3; /*antidx_anta[2:0]*/ 64 | u8 antidx_antb : 3; /*antidx_antb[2:0]*/ 65 | u8 hw_antsw_occur : 2; /*1'b0*/ 66 | }; 67 | 68 | FrameParser::FrameParser(Logger_t logger) : _logger{logger} {} 69 | 70 | static rx_pkt_attrib rtl8812_query_rx_desc_status(uint8_t *pdesc) { 71 | auto pattrib = rx_pkt_attrib{}; 72 | 73 | /* Offset 0 */ 74 | pattrib.pkt_len = GET_RX_STATUS_DESC_PKT_LEN_8812(pdesc); 75 | pattrib.crc_err = GET_RX_STATUS_DESC_CRC32_8812(pdesc); 76 | pattrib.icv_err = GET_RX_STATUS_DESC_ICV_8812(pdesc); 77 | pattrib.drvinfo_sz = 78 | (uint8_t)(GET_RX_STATUS_DESC_DRVINFO_SIZE_8812(pdesc) * 8); 79 | pattrib.encrypt = GET_RX_STATUS_DESC_SECURITY_8812(pdesc); 80 | pattrib.qos = GET_RX_STATUS_DESC_QOS_8812(pdesc); 81 | /* Qos data, wireless 82 | lan header length is 83 | 26 */ 84 | pattrib.shift_sz = GET_RX_STATUS_DESC_SHIFT_8812( 85 | pdesc); /* ((le32_to_cpu(pdesc.rxdw0) >> 24) & 0x3); */ 86 | pattrib.physt = GET_RX_STATUS_DESC_PHY_STATUS_8812( 87 | pdesc); /* ((le32_to_cpu(pdesc.rxdw0) >> 26) & 0x1); */ 88 | pattrib.bdecrypted = !GET_RX_STATUS_DESC_SWDEC_8812( 89 | pdesc); /* (le32_to_cpu(pdesc.rxdw0) & BIT(27))? 0:1; */ 90 | 91 | /* Offset 4 */ 92 | pattrib.priority = GET_RX_STATUS_DESC_TID_8812(pdesc); 93 | pattrib.mdata = GET_RX_STATUS_DESC_MORE_DATA_8812(pdesc); 94 | pattrib.mfrag = GET_RX_STATUS_DESC_MORE_FRAG_8812(pdesc); 95 | /* more fragment bit */ 96 | 97 | /* Offset 8 */ 98 | pattrib.seq_num = GET_RX_STATUS_DESC_SEQ_8812(pdesc); 99 | pattrib.frag_num = GET_RX_STATUS_DESC_FRAG_8812(pdesc); 100 | /* fragmentation number */ 101 | 102 | if (GET_RX_STATUS_DESC_RPT_SEL_8812(pdesc)) { 103 | pattrib.pkt_rpt_type = RX_PACKET_TYPE::C2H_PACKET; 104 | } else { 105 | pattrib.pkt_rpt_type = RX_PACKET_TYPE::NORMAL_RX; 106 | } 107 | 108 | /* Offset 12 */ 109 | pattrib.data_rate = GET_RX_STATUS_DESC_RX_RATE_8812(pdesc); 110 | /* Offset 16 */ 111 | pattrib.sgi = GET_RX_STATUS_DESC_SPLCP_8812(pdesc); 112 | pattrib.ldpc = GET_RX_STATUS_DESC_LDPC_8812(pdesc); 113 | pattrib.stbc = GET_RX_STATUS_DESC_STBC_8812(pdesc); 114 | pattrib.bw = GET_RX_STATUS_DESC_BW_8812(pdesc); 115 | 116 | /* Offset 20 */ 117 | /* pattrib.tsfl=(byte)GET_RX_STATUS_DESC_TSFL_8812(pdesc); */ 118 | 119 | return pattrib; 120 | } 121 | 122 | __inline static u32 _RND8(u32 sz) { 123 | u32 val; 124 | 125 | val = ((sz >> 3) + ((sz & 7) ? 1 : 0)) << 3; 126 | 127 | return val; 128 | } 129 | 130 | std::vector FrameParser::recvbuf2recvframe(std::span ptr) { 131 | auto pbuf = ptr; 132 | auto pkt_cnt = GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8812(pbuf.data()); 133 | //_logger->info("pkt_cnt == {}", pkt_cnt); 134 | 135 | auto ret = std::vector{}; 136 | 137 | do { 138 | auto pattrib = rtl8812_query_rx_desc_status(pbuf.data()); 139 | 140 | if ((pattrib.crc_err) || (pattrib.icv_err)) { 141 | _logger->info("RX Warning! crc_err={} " 142 | "icv_err={}, skip!", 143 | pattrib.crc_err, pattrib.icv_err); 144 | break; 145 | } 146 | 147 | auto pkt_offset = RXDESC_SIZE + pattrib.drvinfo_sz + pattrib.shift_sz + 148 | pattrib.pkt_len; // this is offset for next package 149 | 150 | if ((pattrib.pkt_len <= 0) || (pkt_offset > pbuf.size())) { 151 | _logger->warn( 152 | "RX Warning!,pkt_len <= 0 or pkt_offset > transfer_len; pkt_len: " 153 | "{}, pkt_offset: {}, transfer_len: {}", 154 | pattrib.pkt_len, pkt_offset, pbuf.size()); 155 | break; 156 | } 157 | 158 | if (pattrib.mfrag) { 159 | // !!! We skips this packages because ohd not use fragmentation 160 | _logger->warn("mfrag scipping"); 161 | 162 | // if (rtw_os_alloc_recvframe(precvframe, pbuf.Slice(pattrib.shift_sz + 163 | // pattrib.drvinfo_sz + RXDESC_SIZE), pskb) == false) 164 | //{ 165 | // return false; 166 | // } 167 | } 168 | 169 | // recvframe_put(precvframe, pattrib.pkt_len); 170 | /* recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE); */ 171 | 172 | if (pattrib.pkt_rpt_type == 173 | RX_PACKET_TYPE::NORMAL_RX) /* Normal rx packet */ 174 | { 175 | ret.push_back({pattrib, pbuf.subspan(pattrib.shift_sz + 176 | pattrib.drvinfo_sz + RXDESC_SIZE, 177 | pattrib.pkt_len)}); 178 | 179 | struct _phy_status_rpt_8812 driver_data; 180 | memcpy(static_cast(&driver_data), pbuf.data() + RXDESC_SIZE, sizeof(driver_data)); 181 | ret.back().RxAtrib.rssi[0] = driver_data.gain_trsw[0]; 182 | ret.back().RxAtrib.rssi[1] = driver_data.gain_trsw[1]; 183 | ret.back().RxAtrib.snr[0] = driver_data.rxsnr[0]; 184 | ret.back().RxAtrib.snr[1] = driver_data.rxsnr[1]; 185 | } else { 186 | /* pkt_rpt_type == TX_REPORT1-CCX, TX_REPORT2-TX RTP,HIS_REPORT-USB HISR 187 | * RTP */ 188 | if (pattrib.pkt_rpt_type == RX_PACKET_TYPE::C2H_PACKET) { 189 | _logger->info("RX USB C2H_PACKET"); 190 | // rtw_hal_c2h_pkt_pre_hdl(padapter, precvframe.u.hdr.rx_data, 191 | // pattrib.pkt_len); 192 | } else if (pattrib.pkt_rpt_type == RX_PACKET_TYPE::HIS_REPORT) { 193 | _logger->info("RX USB HIS_REPORT"); 194 | } 195 | } 196 | 197 | /* jaguar 8-byte alignment */ 198 | pkt_offset = (uint16_t)_RND8(pkt_offset); 199 | // pkt_cnt--; 200 | 201 | if (pkt_offset >= pbuf.size()) { 202 | break; 203 | } 204 | pbuf = pbuf.subspan(pkt_offset, pbuf.size() - pkt_offset); 205 | } while (pbuf.size() > 0); 206 | 207 | if (pkt_cnt != 0) { 208 | _logger->info("Unprocessed packets: {}", pkt_cnt); 209 | } 210 | //_logger->info("{} received in frame", ret.size()); 211 | 212 | return ret; 213 | } 214 | 215 | void rtl8812a_cal_txdesc_chksum(uint8_t *ptxdesc) { 216 | u16 *usPtr; 217 | u32 count; 218 | u32 index; 219 | u16 checksum = 0; 220 | 221 | usPtr = (u16 *)ptxdesc; 222 | 223 | /* checksum is always calculated by first 32 bytes, */ 224 | /* and it doesn't depend on TX DESC length. */ 225 | /* Thomas,Lucas@SD4,20130515 */ 226 | count = 16; 227 | 228 | /* Clear first */ 229 | SET_TX_DESC_TX_DESC_CHECKSUM_8812(ptxdesc, 0); 230 | 231 | for (index = 0; index < count; index++) 232 | checksum = checksum ^ le16_to_cpu(*(usPtr + index)); 233 | 234 | SET_TX_DESC_TX_DESC_CHECKSUM_8812(ptxdesc, checksum); 235 | } 236 | 237 | int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, 238 | u8 *action) { 239 | /*const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); 240 | u16 fc; 241 | u8 c; 242 | u8 a = ACT_PUBLIC_MAX; 243 | 244 | fc = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)frame)->frame_ctl); 245 | 246 | if ((fc & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE)) 247 | != (RTW_IEEE80211_FTYPE_MGMT | RTW_IEEE80211_STYPE_ACTION) 248 | ) 249 | return _FALSE; 250 | 251 | c = frame_body[0]; 252 | 253 | switch (c) { 254 | case RTW_WLAN_CATEGORY_P2P: // vendor-specific 255 | break; 256 | default: 257 | a = frame_body[1]; 258 | } 259 | 260 | if (category) 261 | *category = c; 262 | if (action) 263 | *action = a; 264 | */ 265 | return _TRUE; 266 | } 267 | -------------------------------------------------------------------------------- /src/HalModule.h: -------------------------------------------------------------------------------- 1 | #ifndef HALMODULE_H 2 | #define HALMODULE_H 3 | 4 | #include "EepromManager.h" 5 | extern "C"{ 6 | #include "Hal8812PwrSeq.h" 7 | } 8 | #include "RadioManagementModule.h" 9 | #include "RtlUsbAdapter.h" 10 | #include "SelectedChannel.h" 11 | #include "logger.h" 12 | 13 | typedef enum _RX_AGG_MODE { 14 | RX_AGG_DISABLE, 15 | RX_AGG_DMA, 16 | RX_AGG_USB, 17 | RX_AGG_MIX 18 | } RX_AGG_MODE; 19 | 20 | enum odm_bb_config_type { 21 | CONFIG_BB_PHY_REG, 22 | CONFIG_BB_AGC_TAB, 23 | CONFIG_BB_AGC_TAB_2G, 24 | CONFIG_BB_AGC_TAB_5G, 25 | CONFIG_BB_PHY_REG_PG, 26 | CONFIG_BB_PHY_REG_MP, 27 | CONFIG_BB_AGC_TAB_DIFF, 28 | CONFIG_BB_RF_CAL_INIT, 29 | }; 30 | 31 | enum odm_rf_config_type { 32 | CONFIG_RF_RADIO, 33 | CONFIG_RF_TXPWR_LMT, 34 | CONFIG_RF_SYN_RADIO, 35 | }; 36 | 37 | class HalModule { 38 | RtlUsbAdapter _device; 39 | std::shared_ptr _eepromManager; 40 | std::shared_ptr _radioManagementModule; 41 | Logger_t _logger; 42 | bool _macPwrCtrlOn = false; 43 | uint32_t _intrMask[3] = {0}; 44 | bool _usbTxAggMode = false; 45 | uint8_t _usbTxAggDescNum = 46 | 0x01; // adjust value for OQT Overflow issue 0x3; only 4 bits 47 | RX_AGG_MODE _rxAggMode = RX_AGG_USB; 48 | uint8_t _rxAggDmaTimeout = 0x6; /* 6, absolute time = 34ms/(2^6) */ 49 | uint8_t _rxAggDmaSize = 50 | 16; /* uint: 128b, 0x0A = 10 = 51 | MAX_RX_DMA_BUFFER_SIZE/2/pHalData.UsbBulkOutSize */ 52 | 53 | public: 54 | HalModule(RtlUsbAdapter device, std::shared_ptr eepromManager, 55 | std::shared_ptr _radioManagementModule, 56 | Logger_t logger); 57 | bool rtw_hal_init(SelectedChannel selectedChannel); 58 | 59 | private: 60 | bool rtl8812au_hal_init(); 61 | bool InitPowerOn(); 62 | bool InitLLTTable8812A(uint8_t txpktbuf_bndy); 63 | bool _LLTWrite_8812A(uint32_t address, uint32_t data); 64 | void _InitHardwareDropIncorrectBulkOut_8812A(); 65 | bool HalPwrSeqCmdParsing(WLAN_PWR_CFG *PwrSeqCmd); 66 | void PHY_MACConfig8812(); 67 | void odm_read_and_config_mp_8812a_mac_reg(); 68 | void odm_write_1byte(uint16_t reg_addr, uint8_t data); 69 | bool check_positive(int32_t condition1, int32_t condition2, 70 | int32_t condition4); 71 | void _InitQueueReservedPage_8812AUsb(); 72 | void _InitTxBufferBoundary_8812AUsb(); 73 | void _InitQueuePriority_8812AUsb(); 74 | void _InitNormalChipTwoOutEpPriority_8812AUsb(); 75 | void _InitNormalChipRegPriority_8812AUsb(uint16_t beQ, uint16_t bkQ, 76 | uint16_t viQ, uint16_t voQ, 77 | uint16_t mgtQ, uint16_t hiQ); 78 | void _InitNormalChipThreeOutEpPriority_8812AUsb(); 79 | void _InitNormalChipFourOutEpPriority_8812AUsb(); 80 | void init_hi_queue_config_8812a_usb(); 81 | void _InitPageBoundary_8812AUsb(); 82 | void _InitTransferPageSize_8812AUsb(); 83 | void _InitDriverInfoSize_8812A(uint8_t drvInfoSize); 84 | void _InitInterrupt_8812AU(); 85 | void _InitNetworkType_8812A(); 86 | void _InitWMACSetting_8812A(); 87 | void _InitAdaptiveCtrl_8812AUsb(); 88 | void _InitEDCA_8812AUsb(); 89 | void _InitRetryFunction_8812A(); 90 | 91 | void init_UsbAggregationSetting_8812A(); 92 | void usb_AggSettingRxUpdate_8812A(); 93 | void usb_AggSettingTxUpdate_8812A(); 94 | void _InitBeaconParameters_8812A(); 95 | void _InitBeaconMaxError_8812A(); 96 | void _InitBurstPktLen(); 97 | 98 | bool PHY_BBConfig8812(); 99 | bool phy_BB8812_Config_ParaFile(); 100 | void hal_set_crystal_cap(uint8_t crystal_cap); 101 | bool odm_config_bb_with_header_file(odm_bb_config_type config_type); 102 | void odm_read_and_config_mp_8812a_phy_reg(); 103 | void odm_read_and_config_mp_8812a_phy_reg_mp(); 104 | void odm_read_and_config_mp_8812a_agc_tab(); 105 | 106 | void odm_config_bb_phy_8812a(uint32_t addr, uint32_t bitmask, uint32_t data); 107 | void odm_set_bb_reg(uint32_t reg_addr, uint32_t bit_mask, uint32_t data); 108 | void odm_config_bb_agc_8812a(uint32_t addr, uint32_t bitmask, uint32_t data); 109 | 110 | void PHY_RF6052_Config_8812(); 111 | void phy_RF6052_Config_ParaFile_8812(); 112 | void odm_config_rf_with_header_file(odm_rf_config_type config_type, 113 | RfPath e_rf_path); 114 | void odm_read_and_config_mp_8812a_radioa(); 115 | void odm_read_and_config_mp_8812a_radiob(); 116 | void odm_config_rf_radio_a_8812a(uint32_t addr, uint32_t data); 117 | void odm_config_rf_reg_8812a(uint32_t addr, uint32_t data, RfPath RF_PATH, 118 | uint16_t reg_addr); 119 | void odm_set_rf_reg(RfPath e_rf_path, uint16_t reg_addr, uint32_t bit_mask, 120 | uint32_t data); 121 | void odm_config_rf_radio_b_8812a(uint32_t addr, uint32_t data); 122 | void PHY_BB8812_Config_1T(); 123 | 124 | }; 125 | 126 | #endif /* HALMODULE_H */ 127 | -------------------------------------------------------------------------------- /src/ParsedRadioPacket.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/devourer/a2a676ed79274f4befc2ca8191ed236410ec8e89/src/ParsedRadioPacket.cpp -------------------------------------------------------------------------------- /src/RadioManagementModule.h: -------------------------------------------------------------------------------- 1 | #ifndef RADIOMANAGEMENTMODULE_H 2 | #define RADIOMANAGEMENTMODULE_H 3 | 4 | #include 5 | #include 6 | 7 | #include "EepromManager.h" 8 | #include "RfPath.h" 9 | #include "RtlUsbAdapter.h" 10 | #include "SelectedChannel.h" 11 | #include "logger.h" 12 | 13 | #define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 14 | #define HAL_PRIME_CHNL_OFFSET_LOWER 1 15 | #define HAL_PRIME_CHNL_OFFSET_UPPER 2 16 | 17 | enum class HwPort { HW_PORT0, HW_PORT1 }; 18 | 19 | enum class BandType { 20 | BAND_ON_2_4G = 0, 21 | BAND_ON_5G = 1, 22 | BAND_ON_BOTH = 2, 23 | BAND_MAX = 3, 24 | }; 25 | 26 | enum RATE_SECTION { 27 | CCK = 0, 28 | OFDM = 1, 29 | HT_MCS0_MCS7 = 2, 30 | HT_MCS8_MCS15 = 3, 31 | HT_MCS16_MCS23 = 4, 32 | HT_MCS24_MCS31 = 5, 33 | HT_1SS = HT_MCS0_MCS7, 34 | HT_2SS = HT_MCS8_MCS15, 35 | HT_3SS = HT_MCS16_MCS23, 36 | HT_4SS = HT_MCS24_MCS31, 37 | VHT_1SSMCS0_1SSMCS9 = 6, 38 | VHT_2SSMCS0_2SSMCS9 = 7, 39 | VHT_3SSMCS0_3SSMCS9 = 8, 40 | VHT_4SSMCS0_4SSMCS9 = 9, 41 | VHT_1SS = VHT_1SSMCS0_1SSMCS9, 42 | VHT_2SS = VHT_2SSMCS0_2SSMCS9, 43 | VHT_3SS = VHT_3SSMCS0_3SSMCS9, 44 | VHT_4SS = VHT_4SSMCS0_4SSMCS9, 45 | RATE_SECTION_NUM, 46 | }; 47 | 48 | enum MGN_RATE { 49 | MGN_1M = 0x02, 50 | MGN_2M = 0x04, 51 | MGN_5_5M = 0x0B, 52 | MGN_6M = 0x0C, 53 | MGN_9M = 0x12, 54 | MGN_11M = 0x16, 55 | MGN_12M = 0x18, 56 | MGN_18M = 0x24, 57 | MGN_24M = 0x30, 58 | MGN_36M = 0x48, 59 | MGN_48M = 0x60, 60 | MGN_54M = 0x6C, 61 | MGN_MCS32 = 0x7F, 62 | MGN_MCS0, 63 | MGN_MCS1, 64 | MGN_MCS2, 65 | MGN_MCS3, 66 | MGN_MCS4, 67 | MGN_MCS5, 68 | MGN_MCS6, 69 | MGN_MCS7, 70 | MGN_MCS8, 71 | MGN_MCS9, 72 | MGN_MCS10, 73 | MGN_MCS11, 74 | MGN_MCS12, 75 | MGN_MCS13, 76 | MGN_MCS14, 77 | MGN_MCS15, 78 | MGN_MCS16, 79 | MGN_MCS17, 80 | MGN_MCS18, 81 | MGN_MCS19, 82 | MGN_MCS20, 83 | MGN_MCS21, 84 | MGN_MCS22, 85 | MGN_MCS23, 86 | MGN_MCS24, 87 | MGN_MCS25, 88 | MGN_MCS26, 89 | MGN_MCS27, 90 | MGN_MCS28, 91 | MGN_MCS29, 92 | MGN_MCS30, 93 | MGN_MCS31, 94 | MGN_VHT1SS_MCS0, 95 | MGN_VHT1SS_MCS1, 96 | MGN_VHT1SS_MCS2, 97 | MGN_VHT1SS_MCS3, 98 | MGN_VHT1SS_MCS4, 99 | MGN_VHT1SS_MCS5, 100 | MGN_VHT1SS_MCS6, 101 | MGN_VHT1SS_MCS7, 102 | MGN_VHT1SS_MCS8, 103 | MGN_VHT1SS_MCS9, 104 | MGN_VHT2SS_MCS0, 105 | MGN_VHT2SS_MCS1, 106 | MGN_VHT2SS_MCS2, 107 | MGN_VHT2SS_MCS3, 108 | MGN_VHT2SS_MCS4, 109 | MGN_VHT2SS_MCS5, 110 | MGN_VHT2SS_MCS6, 111 | MGN_VHT2SS_MCS7, 112 | MGN_VHT2SS_MCS8, 113 | MGN_VHT2SS_MCS9, 114 | MGN_VHT3SS_MCS0, 115 | MGN_VHT3SS_MCS1, 116 | MGN_VHT3SS_MCS2, 117 | MGN_VHT3SS_MCS3, 118 | MGN_VHT3SS_MCS4, 119 | MGN_VHT3SS_MCS5, 120 | MGN_VHT3SS_MCS6, 121 | MGN_VHT3SS_MCS7, 122 | MGN_VHT3SS_MCS8, 123 | MGN_VHT3SS_MCS9, 124 | MGN_VHT4SS_MCS0, 125 | MGN_VHT4SS_MCS1, 126 | MGN_VHT4SS_MCS2, 127 | MGN_VHT4SS_MCS3, 128 | MGN_VHT4SS_MCS4, 129 | MGN_VHT4SS_MCS5, 130 | MGN_VHT4SS_MCS6, 131 | MGN_VHT4SS_MCS7, 132 | MGN_VHT4SS_MCS8, 133 | MGN_VHT4SS_MCS9, 134 | MGN_UNKNOWN 135 | }; 136 | 137 | class RadioManagementModule { 138 | RtlUsbAdapter _device; 139 | std::shared_ptr _eepromManager; 140 | Logger_t _logger; 141 | HwPort _hwPort = HwPort::HW_PORT0; 142 | bool _needIQK = false; 143 | ChannelWidth_t _currentChannelBw; 144 | uint8_t _currentChannel; 145 | BandType current_band_type; 146 | bool _swChannel = false; 147 | bool _channelBwInitialized = false; 148 | bool _setChannelBw = false; 149 | uint8_t _cur40MhzPrimeSc; 150 | uint8_t _cur80MhzPrimeSc; 151 | uint8_t _currentCenterFrequencyIndex; 152 | uint8_t power = 16; 153 | 154 | public: 155 | RadioManagementModule(RtlUsbAdapter device, 156 | std::shared_ptr eepromManager, 157 | Logger_t logger); 158 | void hw_var_rcr_config(uint32_t rcr); 159 | void SetMonitorMode(); 160 | void set_channel_bwmode(uint8_t channel, uint8_t channel_offset, 161 | ChannelWidth_t bwmode); 162 | void phy_set_rf_reg(RfPath eRFPath, uint16_t RegAddr, uint32_t BitMask, 163 | uint32_t Data); 164 | void init_hw_mlme_ext(SelectedChannel pmlmeext); 165 | void rtw_hal_set_chnl_bw(uint8_t channel, ChannelWidth_t Bandwidth, 166 | uint8_t Offset40, uint8_t Offset80); 167 | void PHY_SwitchWirelessBand8812(BandType Band); 168 | void SetTxPower(uint8_t p); 169 | 170 | private: 171 | void rtw_hal_set_msr(uint8_t net_type); 172 | void hw_var_set_monitor(); 173 | void PHY_SetSwChnlBWMode8812(uint8_t channel, ChannelWidth_t Bandwidth, 174 | uint8_t Offset40, uint8_t Offset80); 175 | void PHY_HandleSwChnlAndSetBW8812(bool bSwitchChannel, bool bSetBandWidth, 176 | uint8_t ChannelNum, 177 | ChannelWidth_t ChnlWidth, 178 | uint8_t ChnlOffsetOf40MHz, 179 | uint8_t ChnlOffsetOf80MHz, 180 | uint8_t CenterFrequencyIndex1); 181 | void phy_SwChnlAndSetBwMode8812(); 182 | uint32_t phy_RFSerialRead(RfPath eRFPath, uint32_t Offset); 183 | void phy_RFSerialWrite(RfPath eRFPath, uint32_t Offset, uint32_t Data); 184 | void phy_SetRFEReg8812(BandType Band); 185 | void phy_SetBBSwingByBand_8812A(BandType Band); 186 | uint32_t phy_get_tx_bb_swing_8812a(BandType Band, RfPath RFPath); 187 | void Set_HW_VAR_ENABLE_RX_BAR(bool val); 188 | void phy_SwChnl8812(); 189 | bool phy_SwBand8812(uint8_t channelToSW); 190 | void phy_FixSpur_8812A(ChannelWidth_t Bandwidth, uint8_t Channel); 191 | void phy_PostSetBwMode8812(); 192 | void phy_SetRegBW_8812(ChannelWidth_t CurrentBW); 193 | void PHY_RF6052SetBandwidth8812(ChannelWidth_t Bandwidth); 194 | uint8_t phy_GetSecondaryChnl_8812(); 195 | void PHY_SetTxPowerLevel8812(uint8_t Channel); 196 | void phy_set_tx_power_level_by_path(uint8_t channel, RfPath path); 197 | void phy_set_tx_power_index_by_rate_section(RfPath rfPath, uint8_t channel, 198 | RATE_SECTION rateSection); 199 | void PHY_TxPowerTrainingByPath_8812(RfPath rfPath); 200 | void PHY_SetTxPowerIndexByRateArray(RfPath rfPath, 201 | const std::vector &rates); 202 | void PHY_SetTxPowerIndex_8812A(uint32_t powerIndex, RfPath rfPath, 203 | MGN_RATE rate); 204 | uint32_t phy_query_bb_reg(uint16_t regAddr, uint32_t bitMask); 205 | uint32_t PHY_QueryBBReg8812(uint16_t regAddr, uint32_t bitMask); 206 | }; 207 | 208 | #endif /* RADIOMANAGEMENTMODULE_H */ 209 | -------------------------------------------------------------------------------- /src/RfPath.h: -------------------------------------------------------------------------------- 1 | #ifndef RFPATH_H 2 | #define RFPATH_H 3 | 4 | #include 5 | 6 | enum RfPath : uint8_t { 7 | RF_PATH_A = 0, 8 | RF_PATH_B = 1, 9 | }; 10 | 11 | #endif /* RFPATH_H */ 12 | -------------------------------------------------------------------------------- /src/Rtl8812aDevice.cpp: -------------------------------------------------------------------------------- 1 | #include "Rtl8812aDevice.h" 2 | #include "EepromManager.h" 3 | #include "RadioManagementModule.h" 4 | 5 | Rtl8812aDevice::Rtl8812aDevice(RtlUsbAdapter device, Logger_t logger) 6 | : _device{device}, 7 | _eepromManager{std::make_shared(device, logger)}, 8 | _radioManagement{std::make_shared( 9 | device, _eepromManager, logger)}, 10 | _halModule{device, _eepromManager, _radioManagement, logger}, 11 | _logger{logger} {} 12 | 13 | void Rtl8812aDevice::InitWrite(SelectedChannel channel) { 14 | StartWithMonitorMode(channel); 15 | SetMonitorChannel(channel); 16 | _logger->info("In Monitor Mode"); 17 | } 18 | 19 | bool Rtl8812aDevice::send_packet(const uint8_t *packet, size_t length) { 20 | struct tx_desc *ptxdesc; 21 | bool resp; 22 | uint8_t *usb_frame; 23 | int real_packet_length, usb_frame_length, radiotap_length; 24 | 25 | bool vht = false; 26 | int ret = 0; 27 | int qos_len = 0; 28 | u8 fixed_rate = MGN_1M, sgi = 0, bwidth = 0, ldpc = 0, stbc = 0; 29 | u16 txflags = 0; 30 | int rate_id = 0; 31 | radiotap_length = int(packet[2]); 32 | real_packet_length = length - radiotap_length; 33 | 34 | if (radiotap_length != 0x0d) 35 | vht = true; 36 | 37 | usb_frame_length = real_packet_length + TXDESC_SIZE; 38 | 39 | _logger->info("radiotap length is {}, 80211 length is {}, usb_frame length " 40 | "should be {}", 41 | radiotap_length, real_packet_length, usb_frame_length); 42 | 43 | struct ieee80211_radiotap_header *rtap_hdr; 44 | rtap_hdr = (struct ieee80211_radiotap_header *)packet; 45 | struct ieee80211_radiotap_iterator iterator; 46 | ret = ieee80211_radiotap_iterator_init(&iterator, rtap_hdr, radiotap_length, 47 | NULL); 48 | while (!ret) { 49 | ret = ieee80211_radiotap_iterator_next(&iterator); 50 | 51 | if (ret) 52 | continue; 53 | 54 | /* see if this argument is something we can use */ 55 | switch (iterator.this_arg_index) { 56 | 57 | case IEEE80211_RADIOTAP_RATE: 58 | fixed_rate = *iterator.this_arg; 59 | break; 60 | 61 | case IEEE80211_RADIOTAP_TX_FLAGS: 62 | txflags = get_unaligned_le16(iterator.this_arg); 63 | break; 64 | 65 | case IEEE80211_RADIOTAP_MCS: { 66 | u8 mcs_flags = iterator.this_arg[1]; 67 | 68 | uint8_t mcs_bw_field = mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK; 69 | if (mcs_bw_field == IEEE80211_RADIOTAP_MCS_BW_40) { 70 | bwidth = CHANNEL_WIDTH_40; 71 | } else if (mcs_bw_field == IEEE80211_RADIOTAP_MCS_BW_20 || 72 | mcs_bw_field == IEEE80211_RADIOTAP_MCS_BW_20L || 73 | mcs_bw_field == IEEE80211_RADIOTAP_MCS_BW_20U) { 74 | bwidth = CHANNEL_WIDTH_20; 75 | } 76 | 77 | if (mcs_flags & 0x04) { 78 | sgi = 1; 79 | } else { 80 | sgi = 0; 81 | } 82 | } break; 83 | 84 | case IEEE80211_RADIOTAP_VHT: { 85 | u8 known = iterator.this_arg[0]; 86 | u8 flags = iterator.this_arg[2]; 87 | unsigned int mcs, nss; 88 | if ((known & 4) && (flags & 4)) 89 | sgi = 1; 90 | if ((known & 1) && (flags & 1)) 91 | stbc = 1; 92 | if (known & 0x40) { 93 | auto bw = iterator.this_arg[3] & 0x1f; 94 | if (bw >= 1 && bw <= 3) 95 | bwidth = 40; 96 | else if (bw >= 4 && bw <= 10) 97 | bwidth = 80; 98 | else 99 | bwidth = 20; 100 | } 101 | 102 | if (iterator.this_arg[8] & 1) 103 | ldpc = 1; 104 | mcs = (iterator.this_arg[4] >> 4) & 0x0f; 105 | nss = iterator.this_arg[4] & 0x0f; 106 | if (nss > 0) { 107 | if (nss > 4) 108 | nss = 4; 109 | if (mcs > 9) 110 | mcs = 9; 111 | fixed_rate = MGN_VHT1SS_MCS0 + ((nss - 1) * 10 + mcs); 112 | } 113 | } break; 114 | 115 | default: 116 | break; 117 | } 118 | } 119 | 120 | usb_frame = new uint8_t[usb_frame_length](); 121 | 122 | ptxdesc = (struct tx_desc *)usb_frame; 123 | 124 | _logger->info("fixed rate:{}, sgi:{}, radiotap_bwidth:{}, ldpc:{}, stbc:{}", 125 | (int)fixed_rate, (int)sgi, (int)bwidth, (int)ldpc, (int)stbc); 126 | 127 | uint8_t BWSettingOfDesc; 128 | if (bwidth == CHANNEL_WIDTH_40) { 129 | BWSettingOfDesc = 1; 130 | } else if (bwidth == CHANNEL_WIDTH_80) { 131 | BWSettingOfDesc = 2; 132 | } else { 133 | BWSettingOfDesc = 0; 134 | } 135 | _logger->info("TX DESC BW decision: _channel.ChannelWidth(RX)={}, radiotap_bwidth(TX)={}, BWSettingOfDesc(TX_DESC)={}", 136 | (int)_channel.ChannelWidth, (int)bwidth, (int)BWSettingOfDesc); 137 | 138 | SET_TX_DESC_DATA_BW_8812(usb_frame, BWSettingOfDesc); 139 | 140 | SET_TX_DESC_FIRST_SEG_8812(usb_frame, 1); 141 | SET_TX_DESC_LAST_SEG_8812(usb_frame, 1); 142 | SET_TX_DESC_OWN_8812(usb_frame, 1); 143 | 144 | SET_TX_DESC_PKT_SIZE_8812(usb_frame, 145 | static_cast(real_packet_length)); 146 | 147 | SET_TX_DESC_OFFSET_8812(usb_frame, 148 | static_cast(TXDESC_SIZE + OFFSET_SZ)); 149 | 150 | SET_TX_DESC_MACID_8812(usb_frame, static_cast(0x01)); 151 | 152 | if (!vht) { 153 | rate_id = 7; 154 | } else { 155 | rate_id = 9; 156 | } 157 | 158 | SET_TX_DESC_BMC_8812(usb_frame, 1); 159 | SET_TX_DESC_RATE_ID_8812( 160 | usb_frame, 161 | static_cast(rate_id)); 162 | 163 | SET_TX_DESC_QUEUE_SEL_8812(usb_frame, 0x12); 164 | SET_TX_DESC_HWSEQ_EN_8812( 165 | usb_frame, static_cast(0)); 166 | SET_TX_DESC_SEQ_8812( 167 | usb_frame, 168 | GetSequence(packet + 169 | radiotap_length)); 170 | SET_TX_DESC_RETRY_LIMIT_ENABLE_8812(usb_frame, static_cast(1)); 171 | 172 | SET_TX_DESC_DATA_RETRY_LIMIT_8812(usb_frame, static_cast(0)); 173 | if (sgi) { 174 | _logger->info("short gi enabled,set sgi"); 175 | SET_TX_DESC_DATA_SHORT_8812(usb_frame, 1); 176 | } 177 | SET_TX_DESC_DISABLE_FB_8812(usb_frame, 1); 178 | SET_TX_DESC_USE_RATE_8812(usb_frame, 1); 179 | SET_TX_DESC_TX_RATE_8812(usb_frame, 180 | static_cast(MRateToHwRate( 181 | fixed_rate))); 182 | 183 | if (ldpc) { 184 | SET_TX_DESC_DATA_LDPC_8812(usb_frame, ldpc); 185 | } 186 | 187 | SET_TX_DESC_DATA_STBC_8812(usb_frame, stbc & 3); 188 | 189 | rtl8812a_cal_txdesc_chksum(usb_frame); 190 | _logger->info("tx desc formed"); 191 | #ifdef DEBUG 192 | for (size_t i = 0; i < usb_frame_length; ++i) { 193 | std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') 194 | << static_cast(usb_frame[i]); 195 | 196 | if (i < usb_frame_length - 1) { 197 | std::cout << ","; 198 | } 199 | } 200 | std::cout << std::dec << std::endl; 201 | #endif 202 | uint8_t *addr = usb_frame + TXDESC_SIZE; 203 | memcpy(addr, packet + radiotap_length, real_packet_length); 204 | _logger->info("packet formed"); 205 | #ifdef DEBUG 206 | for (size_t i = 0; i < usb_frame_length; ++i) { 207 | std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') 208 | << static_cast(usb_frame[i]); 209 | 210 | if (i < usb_frame_length - 1) { 211 | std::cout << ","; 212 | } 213 | } 214 | std::cout << std::dec << std::endl; 215 | #endif 216 | resp = _device.send_packet(usb_frame, usb_frame_length); 217 | delete[] usb_frame; 218 | 219 | return resp; 220 | } 221 | 222 | void Rtl8812aDevice::Init(Action_ParsedRadioPacket packetProcessor, 223 | SelectedChannel channel) { 224 | _packetProcessor = packetProcessor; 225 | 226 | StartWithMonitorMode(channel); 227 | SetMonitorChannel(channel); 228 | 229 | _logger->info("Listening air..."); 230 | while (!should_stop) { 231 | auto packets = _device.infinite_read(); 232 | for (auto &p : packets) { 233 | _packetProcessor(p); 234 | } 235 | } 236 | 237 | #if 0 238 | _device.UsbDevice.SetBulkDataHandler(BulkDataHandler); 239 | _readTask = Task.Run(() = > _device.UsbDevice.InfinityRead()); 240 | #endif 241 | } 242 | 243 | void Rtl8812aDevice::SetMonitorChannel(SelectedChannel channel) { 244 | _radioManagement->set_channel_bwmode(channel.Channel, channel.ChannelOffset, 245 | channel.ChannelWidth); 246 | } 247 | 248 | void Rtl8812aDevice::StartWithMonitorMode(SelectedChannel selectedChannel) { 249 | if (NetDevOpen(selectedChannel) == false) { 250 | throw std::ios_base::failure("StartWithMonitorMode failed NetDevOpen"); 251 | } 252 | 253 | _radioManagement->SetMonitorMode(); 254 | } 255 | 256 | void Rtl8812aDevice::SetTxPower(uint8_t power) { 257 | _radioManagement->SetTxPower(power); 258 | } 259 | 260 | bool Rtl8812aDevice::NetDevOpen(SelectedChannel selectedChannel) { 261 | auto status = _halModule.rtw_hal_init(selectedChannel); 262 | if (status == false) { 263 | return false; 264 | } 265 | 266 | return true; 267 | } 268 | -------------------------------------------------------------------------------- /src/Rtl8812aDevice.h: -------------------------------------------------------------------------------- 1 | #ifndef RTL8812ADEVICE_H 2 | #define RTL8812ADEVICE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "logger.h" 9 | #include "HalModule.h" 10 | #include "SelectedChannel.h" 11 | #include "EepromManager.h" 12 | #include "RadioManagementModule.h" 13 | #include "FrameParser.h" 14 | 15 | extern "C" 16 | { 17 | #include "ieee80211_radiotap.h" 18 | } 19 | 20 | using Action_ParsedRadioPacket = std::function; 21 | 22 | class Rtl8812aDevice { 23 | std::shared_ptr _eepromManager; 24 | std::shared_ptr _radioManagement; 25 | SelectedChannel _channel; 26 | RtlUsbAdapter _device; 27 | HalModule _halModule; 28 | Logger_t _logger; 29 | uint8_t debug; 30 | Action_ParsedRadioPacket _packetProcessor = nullptr; 31 | 32 | public: 33 | Rtl8812aDevice(RtlUsbAdapter device, Logger_t logger); 34 | void Init(Action_ParsedRadioPacket packetProcessor, SelectedChannel channel); 35 | void SetMonitorChannel(SelectedChannel channel); 36 | void InitWrite(SelectedChannel channel); 37 | void SetTxPower(uint8_t power); 38 | bool send_packet(const uint8_t* packet, size_t length); 39 | SelectedChannel GetSelectedChannel(); 40 | bool should_stop = false; 41 | 42 | private: 43 | void StartWithMonitorMode(SelectedChannel selectedChannel); 44 | bool NetDevOpen(SelectedChannel selectedChannel); 45 | }; 46 | 47 | #endif /* RTL8812ADEVICE_H */ 48 | -------------------------------------------------------------------------------- /src/RtlUsbAdapter.cpp: -------------------------------------------------------------------------------- 1 | #include "RtlUsbAdapter.h" 2 | 3 | #include 4 | #if defined(__ANDROID__) || defined(_MSC_VER) 5 | #include 6 | #else 7 | #include 8 | #endif 9 | #include "FrameParser.h" 10 | #include "Hal8812PhyReg.h" 11 | #include "logger.h" 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std::chrono_literals; 17 | 18 | RtlUsbAdapter::RtlUsbAdapter(libusb_device_handle *dev_handle, Logger_t logger) 19 | : _dev_handle{dev_handle}, _logger{logger} { 20 | InitDvObj(); 21 | 22 | if (usbSpeed > LIBUSB_SPEED_HIGH) // USB 3.0 23 | { 24 | rxagg_usb_size = 0x7; 25 | rxagg_usb_timeout = 0x1a; 26 | } else { 27 | /* the setting to reduce RX FIFO overflow on USB2.0 and increase rx 28 | * throughput */ 29 | rxagg_usb_size = 0x5; 30 | rxagg_usb_timeout = 0x20; 31 | } 32 | 33 | GetChipOutEP8812(); 34 | 35 | uint8_t eeValue = rtw_read8(REG_9346CR); 36 | EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) != 0; 37 | AutoloadFailFlag = (eeValue & EEPROM_EN) == 0; 38 | 39 | _logger->info("Boot from {}, Autoload {} !", 40 | EepromOrEfuse ? "EEPROM" : "EFUSE", 41 | (AutoloadFailFlag ? "Fail" : "OK")); 42 | } 43 | 44 | /* 45 | $ lsusb -v -d 0bda:8812 46 | Endpoint Descriptor: 47 | bLength 7 48 | bDescriptorType 5 49 | bEndpointAddress 0x81 EP 1 IN 50 | bmAttributes 2 51 | Transfer Type Bulk 52 | Synch Type None 53 | Usage Type Data 54 | wMaxPacketSize 0x0200 1x 512 bytes 55 | bInterval 0 56 | */ 57 | 58 | std::vector RtlUsbAdapter::infinite_read() { 59 | uint8_t buffer[65000] = {0}; 60 | int actual_length = 0; 61 | int rc; 62 | 63 | rc = libusb_bulk_transfer(_dev_handle, 0x81, buffer, sizeof(buffer), 64 | &actual_length, USB_TIMEOUT * 10); 65 | 66 | if (rc < 0) { 67 | _logger->error("libusb_bulk_transfer failed with error: {}", rc); 68 | } 69 | 70 | std::vector packets; 71 | FrameParser fp{_logger}; 72 | packets = 73 | fp.recvbuf2recvframe(std::span{buffer, (size_t)actual_length}); 74 | return packets; 75 | } 76 | 77 | bool RtlUsbAdapter::WriteBytes(uint16_t reg_num, uint8_t *ptr, size_t size) { 78 | if (libusb_control_transfer(_dev_handle, REALTEK_USB_VENQT_WRITE, 5, reg_num, 79 | 0, ptr, size, USB_TIMEOUT) == size) { 80 | return true; 81 | } 82 | return false; 83 | } 84 | 85 | void RtlUsbAdapter::rtl8812au_hw_reset() { 86 | uint32_t reg_val = 0; 87 | 88 | if ((rtw_read8(REG_MCUFWDL) & BIT7) != 0) { 89 | _8051Reset8812(); 90 | rtw_write8(REG_MCUFWDL, 0x00); 91 | 92 | /* before BB reset should do clock gated */ 93 | rtw_write32(rFPGA0_XCD_RFPara, rtw_read32(rFPGA0_XCD_RFPara) | (BIT6)); 94 | 95 | /* reset BB */ 96 | reg_val = rtw_read8(REG_SYS_FUNC_EN); 97 | reg_val = (uint8_t)(reg_val & ~(BIT0 | BIT1)); 98 | rtw_write8(REG_SYS_FUNC_EN, (uint8_t)reg_val); 99 | 100 | /* reset RF */ 101 | rtw_write8(REG_RF_CTRL, 0); 102 | 103 | /* reset TRX path */ 104 | rtw_write16(REG_CR, 0); 105 | 106 | /* reset MAC */ 107 | reg_val = rtw_read8(REG_APS_FSMCO + 1); 108 | reg_val |= BIT1; 109 | rtw_write8(REG_APS_FSMCO + 1, 110 | (uint8_t)reg_val); /* reg0x5[1] ,auto FSM off */ 111 | 112 | reg_val = rtw_read8(REG_APS_FSMCO + 1); 113 | 114 | /* check if reg0x5[1] auto cleared */ 115 | while ((reg_val & BIT1) != 0) { 116 | std::this_thread::sleep_for(1ms); 117 | reg_val = rtw_read8(REG_APS_FSMCO + 1); 118 | } 119 | 120 | reg_val |= BIT0; 121 | rtw_write8(REG_APS_FSMCO + 1, 122 | (uint8_t)reg_val); /* reg0x5[0] ,auto FSM on */ 123 | 124 | reg_val = rtw_read8(REG_SYS_FUNC_EN + 1); 125 | reg_val = (uint8_t)(reg_val & ~(BIT4 | BIT7)); 126 | rtw_write8(REG_SYS_FUNC_EN + 1, (uint8_t)reg_val); 127 | reg_val = rtw_read8(REG_SYS_FUNC_EN + 1); 128 | reg_val = (uint8_t)(reg_val | BIT4 | BIT7); 129 | rtw_write8(REG_SYS_FUNC_EN + 1, (uint8_t)reg_val); 130 | } 131 | } 132 | 133 | void RtlUsbAdapter::_8051Reset8812() { 134 | uint8_t u1bTmp, u1bTmp2; 135 | 136 | /* Reset MCU IO Wrapper- sugggest by SD1-Gimmy */ 137 | u1bTmp2 = rtw_read8(REG_RSV_CTRL); 138 | rtw_write8(REG_RSV_CTRL, (uint8_t)(u1bTmp2 & (~BIT1))); 139 | u1bTmp2 = rtw_read8(REG_RSV_CTRL + 1); 140 | rtw_write8(REG_RSV_CTRL + 1, (uint8_t)(u1bTmp2 & (~BIT3))); 141 | 142 | u1bTmp = rtw_read8(REG_SYS_FUNC_EN + 1); 143 | rtw_write8(REG_SYS_FUNC_EN + 1, (uint8_t)(u1bTmp & (~BIT2))); 144 | 145 | /* Enable MCU IO Wrapper */ 146 | u1bTmp2 = rtw_read8(REG_RSV_CTRL); 147 | rtw_write8(REG_RSV_CTRL, (uint8_t)(u1bTmp2 & (~BIT1))); 148 | u1bTmp2 = rtw_read8(REG_RSV_CTRL + 1); 149 | rtw_write8(REG_RSV_CTRL + 1, (uint8_t)(u1bTmp2 | (BIT3))); 150 | 151 | rtw_write8(REG_SYS_FUNC_EN + 1, (uint8_t)(u1bTmp | (BIT2))); 152 | 153 | _logger->info("=====> _8051Reset8812(): 8051 reset success ."); 154 | } 155 | 156 | /* 11/16/2008 MH Read one byte from real Efuse. */ 157 | uint8_t RtlUsbAdapter::efuse_OneByteRead(uint16_t addr, uint8_t *data) { 158 | u32 tmpidx = 0; 159 | u8 bResult; 160 | u8 readbyte; 161 | 162 | /* -----------------e-fuse reg ctrl --------------------------------- */ 163 | /* address */ 164 | rtw_write8(EFUSE_CTRL + 1, (u8)(addr & 0xff)); 165 | rtw_write8(EFUSE_CTRL + 2, 166 | ((u8)((addr >> 8) & 0x03)) | (rtw_read8(EFUSE_CTRL + 2) & 0xFC)); 167 | 168 | /* rtw_write8(pAdapter, EFUSE_CTRL+3, 0x72); */ /* read cmd */ 169 | /* Write bit 32 0 */ 170 | readbyte = rtw_read8(EFUSE_CTRL + 3); 171 | rtw_write8(EFUSE_CTRL + 3, (readbyte & 0x7f)); 172 | 173 | while (!(0x80 & rtw_read8(EFUSE_CTRL + 3)) && (tmpidx < 1000)) { 174 | std::this_thread::sleep_for(1ms); 175 | tmpidx++; 176 | } 177 | if (tmpidx < 100) { 178 | *data = rtw_read8(EFUSE_CTRL); 179 | bResult = true; 180 | } else { 181 | *data = 0xff; 182 | bResult = false; 183 | _logger->error("addr=0x{:x} bResult={} time out 1s !!!", addr, bResult); 184 | _logger->error("EFUSE_CTRL =0x{:08x} !!!", rtw_read32(EFUSE_CTRL)); 185 | } 186 | 187 | return bResult; 188 | } 189 | 190 | void RtlUsbAdapter::ReadEFuseByte(uint16_t _offset, uint8_t *pbuf) { 191 | uint32_t value32; 192 | uint8_t readbyte; 193 | uint16_t retry; 194 | 195 | /* Write Address */ 196 | rtw_write8(EFUSE_CTRL + 1, (uint8_t)(_offset & 0xff)); 197 | readbyte = rtw_read8(EFUSE_CTRL + 2); 198 | rtw_write8(EFUSE_CTRL + 2, 199 | (uint8_t)(((_offset >> 8) & 0x03) | (readbyte & 0xfc))); 200 | 201 | /* Write bit 32 0 */ 202 | readbyte = rtw_read8(EFUSE_CTRL + 3); 203 | rtw_write8(EFUSE_CTRL + 3, (uint8_t)(readbyte & 0x7f)); 204 | 205 | /* Check bit 32 read-ready */ 206 | retry = 0; 207 | value32 = rtw_read32(EFUSE_CTRL); 208 | /* while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) */ 209 | while ((((value32 >> 24) & 0xff) & 0x80) == 0 && (retry < 10000)) { 210 | value32 = rtw_read32(EFUSE_CTRL); 211 | retry++; 212 | } 213 | 214 | /* 20100205 Joseph: Add delay suggested by SD1 Victor. */ 215 | /* This fix the problem that Efuse read error in high temperature condition. 216 | */ 217 | /* Designer says that there shall be some delay after ready bit is set, or the 218 | */ 219 | /* result will always stay on last data we read. */ 220 | 221 | // TODO: decide to we really need it? 222 | // std::this_thread::sleep_for(50ms); 223 | value32 = rtw_read32(EFUSE_CTRL); 224 | 225 | pbuf[0] = (uint8_t)(value32 & 0xff); 226 | } 227 | 228 | const char *RtlUsbAdapter::strUsbSpeed() { 229 | switch (usbSpeed) { 230 | case LIBUSB_SPEED_UNKNOWN: 231 | return "UNKNOWN"; 232 | case LIBUSB_SPEED_LOW: 233 | return "1.5MBit/s"; 234 | case LIBUSB_SPEED_FULL: 235 | return "12MBit/s"; 236 | case LIBUSB_SPEED_HIGH: 237 | return "480MBit/s"; 238 | case LIBUSB_SPEED_SUPER: 239 | return "5000MBit/s"; 240 | case LIBUSB_SPEED_SUPER_PLUS: 241 | return "10000MBit/s"; 242 | default: 243 | return NULL; 244 | } 245 | } 246 | 247 | void RtlUsbAdapter::InitDvObj() { 248 | libusb_device *dev = libusb_get_device(_dev_handle); 249 | usbSpeed = (enum libusb_speed)libusb_get_device_speed(dev); 250 | _logger->info("Running USB bus at {}", strUsbSpeed()); 251 | 252 | libusb_device_descriptor desc; 253 | int ret = libusb_get_device_descriptor(dev, &desc); 254 | if (ret < 0) { 255 | return; 256 | } 257 | 258 | for (uint8_t k = 0; k < desc.bNumConfigurations; k++) { 259 | libusb_config_descriptor *config; 260 | ret = libusb_get_config_descriptor(dev, k, &config); 261 | if (LIBUSB_SUCCESS != ret) { 262 | continue; 263 | } 264 | 265 | if (!config->bNumInterfaces) { 266 | continue; 267 | } 268 | const libusb_interface *interface = &config->interface[0]; 269 | 270 | if (!interface->altsetting) { 271 | continue; 272 | } 273 | const libusb_interface_descriptor *interface_desc = 274 | &interface->altsetting[0]; 275 | 276 | for (uint8_t j = 0; j < interface_desc->bNumEndpoints; j++) { 277 | const libusb_endpoint_descriptor *endpoint = &interface_desc->endpoint[j]; 278 | uint8_t endPointAddr = endpoint->bEndpointAddress; 279 | 280 | if ((!(endPointAddr & LIBUSB_ENDPOINT_IN)) && 281 | ((endpoint->bmAttributes & 0b11) == 282 | LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK)) { 283 | numOutPipes++; 284 | } 285 | } 286 | 287 | libusb_free_config_descriptor(config); 288 | break; 289 | } 290 | } 291 | 292 | void RtlUsbAdapter::GetChipOutEP8812() { 293 | OutEpQueueSel = 0; 294 | OutEpNumber = 0; 295 | 296 | switch (numOutPipes) { 297 | case 4: 298 | OutEpQueueSel = TxSele::TX_SELE_HQ | TxSele::TX_SELE_LQ | 299 | TxSele::TX_SELE_NQ | TxSele::TX_SELE_EQ; 300 | OutEpNumber = 4; 301 | break; 302 | case 3: 303 | OutEpQueueSel = 304 | TxSele::TX_SELE_HQ | TxSele::TX_SELE_LQ | TxSele::TX_SELE_NQ; 305 | OutEpNumber = 3; 306 | break; 307 | case 2: 308 | OutEpQueueSel = TxSele::TX_SELE_HQ | TxSele::TX_SELE_NQ; 309 | OutEpNumber = 2; 310 | break; 311 | case 1: 312 | OutEpQueueSel = TxSele::TX_SELE_HQ; 313 | OutEpNumber = 1; 314 | break; 315 | default: 316 | break; 317 | } 318 | 319 | _logger->info("OutEpQueueSel({}), OutEpNumber({})", OutEpQueueSel, 320 | OutEpNumber); 321 | } 322 | 323 | void transfer_callback(struct libusb_transfer *transfer) { 324 | Logger *_logger = (Logger *)(transfer->user_data); 325 | if (transfer->status == LIBUSB_TRANSFER_COMPLETED && 326 | transfer->actual_length == transfer->length) { 327 | _logger->debug("Packet {} sent successfully, length: {}", _logger, 328 | transfer->length); 329 | } else { 330 | _logger->error("Failed to send packet {}, status: {}, actual length: {}", 331 | _logger, transfer->status, transfer->actual_length); 332 | } 333 | libusb_free_transfer(transfer); 334 | } 335 | 336 | bool RtlUsbAdapter::send_packet(uint8_t *packet, size_t length) { 337 | 338 | libusb_transfer *transfer = libusb_alloc_transfer(0); 339 | if (!transfer) { 340 | _logger->error("Failed to allocate transfer"); 341 | return false; 342 | } 343 | 344 | libusb_fill_bulk_transfer(transfer, _dev_handle, 0x02, packet, length, 345 | transfer_callback, (void *)(_logger.get()), 346 | USB_TIMEOUT); 347 | auto start = std::chrono::high_resolution_clock::now(); 348 | int rc = rc = libusb_submit_transfer(transfer); 349 | auto end = std::chrono::high_resolution_clock::now(); 350 | std::chrono::duration elapsed = end - start; 351 | if (rc == LIBUSB_SUCCESS) { 352 | _logger->debug("Packet sent successfully, length: {},used time {}ms", length, 353 | elapsed.count()); 354 | return true; 355 | } else { 356 | _logger->error("Failed to send packet, error code: {}", rc); 357 | libusb_free_transfer(transfer); 358 | return false; 359 | } 360 | } 361 | 362 | void RtlUsbAdapter::phy_set_bb_reg(uint16_t regAddr, uint32_t bitMask, 363 | uint32_t data) { 364 | PHY_SetBBReg8812(regAddr, bitMask, data); 365 | } 366 | 367 | void RtlUsbAdapter::PHY_SetBBReg8812(uint16_t regAddr, uint32_t bitMask, 368 | uint32_t dataOriginal) { 369 | uint32_t data = dataOriginal; 370 | if (bitMask != bMaskDWord) { 371 | /* if not "double word" write */ 372 | auto OriginalValue = rtw_read32(regAddr); 373 | auto BitShift = PHY_CalculateBitShift(bitMask); 374 | data = ((OriginalValue) & (~bitMask)) | 375 | (((dataOriginal << (int)BitShift)) & bitMask); 376 | } 377 | 378 | rtw_write32(regAddr, data); 379 | 380 | /* RTW_INFO("BBW MASK=0x%x Addr[0x%x]=0x%x\n", BitMask, RegAddr, Data); */ 381 | } 382 | -------------------------------------------------------------------------------- /src/RtlUsbAdapter.h: -------------------------------------------------------------------------------- 1 | #ifndef RTLUSBADAPTER_H 2 | #define RTLUSBADAPTER_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "FrameParser.h" 10 | #include "drv_types.h" 11 | #include "hal_com_reg.h" 12 | #include "logger.h" 13 | 14 | #define rtw_read8 rtw_read 15 | #define rtw_read16 rtw_read 16 | #define rtw_read32 rtw_read 17 | 18 | #define rtw_write8 rtw_write 19 | #define rtw_write16 rtw_write 20 | #define rtw_write32 rtw_write 21 | 22 | #define REALTEK_USB_VENQT_READ 0xC0 23 | #define REALTEK_USB_VENQT_WRITE 0x40 24 | #define USB_TIMEOUT 500 25 | 26 | enum TxSele { 27 | TX_SELE_HQ = 1 << (0), /* High Queue */ 28 | TX_SELE_LQ = 1 << (1), /* Low Queue */ 29 | TX_SELE_NQ = 1 << (2), /* Normal Queue */ 30 | TX_SELE_EQ = 1 << (3), /* Extern Queue */ 31 | }; 32 | 33 | class RtlUsbAdapter { 34 | libusb_device_handle *_dev_handle; 35 | Logger_t _logger; 36 | 37 | enum libusb_speed usbSpeed; 38 | uint8_t numOutPipes = 0; 39 | 40 | public: 41 | RtlUsbAdapter(libusb_device_handle *dev_handle, Logger_t logger); 42 | 43 | bool AutoloadFailFlag = false; 44 | bool EepromOrEfuse = false; 45 | uint8_t OutEpQueueSel; 46 | uint8_t OutEpNumber; 47 | uint8_t rxagg_usb_size; 48 | uint8_t rxagg_usb_timeout; 49 | bool send_packet(uint8_t* packet, size_t length); 50 | std::vector infinite_read(); 51 | uint8_t efuse_OneByteRead(uint16_t addr, uint8_t *data); 52 | void phy_set_bb_reg(uint16_t regAddr, uint32_t bitMask, uint32_t data); 53 | 54 | template T rtw_read(uint16_t reg_num) { 55 | T data = 0; 56 | if (libusb_control_transfer(_dev_handle, REALTEK_USB_VENQT_READ, 5, reg_num, 57 | 0, (uint8_t *)&data, sizeof(T), 58 | USB_TIMEOUT) == sizeof(T)) { 59 | return data; 60 | } 61 | 62 | _logger->error("rtw_read({:04x}), sizeof(T) = {}", reg_num, sizeof(T)); 63 | throw std::ios_base::failure("rtw_read"); 64 | return 0; 65 | } 66 | 67 | template bool rtw_write(uint16_t reg_num, T value) { 68 | if (libusb_control_transfer(_dev_handle, REALTEK_USB_VENQT_WRITE, 5, 69 | reg_num, 0, (uint8_t *)&value, sizeof(T), 70 | USB_TIMEOUT) == sizeof(T)) { 71 | return true; 72 | } 73 | return false; 74 | } 75 | 76 | bool WriteBytes(uint16_t reg_num, uint8_t *ptr, size_t size); 77 | 78 | void rtl8812au_hw_reset(); 79 | void _8051Reset8812(); 80 | void ReadEFuseByte(uint16_t _offset, uint8_t *pbuf); 81 | 82 | private: 83 | void InitDvObj(); 84 | const char *strUsbSpeed(); 85 | void GetChipOutEP8812(); 86 | void PHY_SetBBReg8812(uint16_t regAddr, uint32_t bitMask, 87 | uint32_t dataOriginal); 88 | }; 89 | 90 | #endif /* RTLUSBADAPTER_H */ 91 | -------------------------------------------------------------------------------- /src/SelectedChannel.h: -------------------------------------------------------------------------------- 1 | #ifndef SELECTEDCHANNEL_H 2 | #define SELECTEDCHANNEL_H 3 | 4 | #include 5 | 6 | enum ChannelWidth_t { 7 | CHANNEL_WIDTH_20 = 0, 8 | CHANNEL_WIDTH_40 = 1, 9 | CHANNEL_WIDTH_80 = 2, 10 | CHANNEL_WIDTH_160 = 3, 11 | CHANNEL_WIDTH_80_80 = 4, 12 | CHANNEL_WIDTH_5 = 5, 13 | CHANNEL_WIDTH_10 = 6, 14 | CHANNEL_WIDTH_MAX = 7, 15 | }; 16 | 17 | struct SelectedChannel { 18 | uint8_t Channel; 19 | uint8_t ChannelOffset; 20 | ChannelWidth_t ChannelWidth; 21 | }; 22 | 23 | #endif /* SELECTEDCHANNEL_H */ 24 | -------------------------------------------------------------------------------- /src/WiFiDriver.cpp: -------------------------------------------------------------------------------- 1 | #include "WiFiDriver.h" 2 | 3 | #include 4 | #include "Rtl8812aDevice.h" 5 | 6 | WiFiDriver::WiFiDriver(Logger_t logger) 7 | : _logger{std::move(logger)} {} 8 | 9 | std::unique_ptr 10 | WiFiDriver::CreateRtlDevice(libusb_device_handle *dev_handle) { 11 | _logger->info("Creating Rtl8812aDevice from LibUSB"); 12 | 13 | return std::make_unique(RtlUsbAdapter(dev_handle, _logger), _logger); 14 | } 15 | -------------------------------------------------------------------------------- /src/WiFiDriver.h: -------------------------------------------------------------------------------- 1 | #ifndef WIFI_DRIVER_H 2 | #define WIFI_DRIVER_H 3 | 4 | #include 5 | 6 | #include "Rtl8812aDevice.h" 7 | #include "logger.h" 8 | 9 | class WiFiDriver { 10 | Logger_t _logger; 11 | 12 | public: 13 | explicit WiFiDriver(Logger_t logger); 14 | 15 | std::unique_ptr 16 | CreateRtlDevice(libusb_device_handle *dev_handle); 17 | }; 18 | 19 | #endif /* WIFI_DRIVER_H */ 20 | -------------------------------------------------------------------------------- /src/ieee80211_radiotap.h: -------------------------------------------------------------------------------- 1 | #ifndef IEEE80211_RADIOTAP_H 2 | #define IEEE80211_RADIOTAP_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | typedef unsigned int u32; 11 | typedef unsigned short u16; 12 | typedef unsigned char u8; 13 | #ifdef _MSC_VER 14 | typedef uint16_t __le16; 15 | typedef uint32_t __le32; 16 | #else 17 | typedef u16 __le16; 18 | typedef u32 __le32; 19 | #endif 20 | 21 | #ifndef le16_to_cpu 22 | #define le16_to_cpu(x) (x) 23 | #endif 24 | 25 | #ifndef le32_to_cpu 26 | #define le32_to_cpu(x) (x) 27 | #endif 28 | 29 | #define unlikely(x) (x) 30 | 31 | /* Are two types/vars the same type (ignoring qualifiers)? */ 32 | #ifndef __same_type 33 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) 34 | #endif 35 | 36 | #ifndef BUILD_BUG_ON 37 | /* Force a compilation error if condition is true */ 38 | #define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition)) 39 | /* Force a compilation error if condition is true, but also produce a 40 | result (of value 0 and type size_t), so the expression can be used 41 | e.g. in a structure initializer (or where-ever else comma expressions 42 | aren't permitted). */ 43 | #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int : -!!(e); })) 44 | #define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int : -!!(e); })) 45 | #endif 46 | 47 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) 48 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) 49 | 50 | /* Channel flags. */ 51 | #define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */ 52 | #define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */ 53 | #define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */ 54 | #define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */ 55 | #define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */ 56 | #define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */ 57 | #define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */ 58 | #define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */ 59 | #define IEEE80211_CHAN_GSM 0x1000 /* GSM (900 MHz) */ 60 | #define IEEE80211_CHAN_STURBO 0x2000 /* Static Turbo */ 61 | #define IEEE80211_CHAN_HALF 0x4000 /* Half channel (10 MHz wide) */ 62 | #define IEEE80211_CHAN_QUARTER 0x8000 /* Quarter channel (5 MHz wide) */ 63 | 64 | /* For IEEE80211_RADIOTAP_FLAGS */ 65 | #define IEEE80211_RADIOTAP_F_CFP \ 66 | 0x01 /* sent/received \ 67 | * during CFP \ 68 | */ 69 | #define IEEE80211_RADIOTAP_F_SHORTPRE \ 70 | 0x02 /* sent/received \ 71 | * with short \ 72 | * preamble \ 73 | */ 74 | #define IEEE80211_RADIOTAP_F_WEP \ 75 | 0x04 /* sent/received \ 76 | * with WEP encryption \ 77 | */ 78 | #define IEEE80211_RADIOTAP_F_FRAG \ 79 | 0x08 /* sent/received \ 80 | * with fragmentation \ 81 | */ 82 | #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ 83 | #define IEEE80211_RADIOTAP_F_DATAPAD \ 84 | 0x20 /* frame has padding between \ 85 | * 802.11 header and payload \ 86 | * (to 32-bit boundary) \ 87 | */ 88 | #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* bad FCS */ 89 | 90 | /* For IEEE80211_RADIOTAP_RX_FLAGS */ 91 | #define IEEE80211_RADIOTAP_F_RX_BADPLCP 0x0002 /* frame has bad PLCP */ 92 | 93 | /* For IEEE80211_RADIOTAP_TX_FLAGS */ 94 | #define IEEE80211_RADIOTAP_F_TX_FAIL \ 95 | 0x0001 /* failed due to excessive \ 96 | * retries */ 97 | #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ 98 | #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ 99 | #define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* don't expect an ack */ 100 | 101 | /* For IEEE80211_RADIOTAP_MCS */ 102 | #define IEEE80211_RADIOTAP_MCS_HAVE_BW 0x01 103 | #define IEEE80211_RADIOTAP_MCS_HAVE_MCS 0x02 104 | #define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04 105 | #define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08 106 | #define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10 107 | #define IEEE80211_RADIOTAP_MCS_HAVE_STBC 0x20 108 | 109 | #define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03 110 | #define IEEE80211_RADIOTAP_MCS_BW_20 0 111 | #define IEEE80211_RADIOTAP_MCS_BW_40 1 112 | #define IEEE80211_RADIOTAP_MCS_BW_20L 2 113 | #define IEEE80211_RADIOTAP_MCS_BW_20U 3 114 | #define IEEE80211_RADIOTAP_MCS_SGI 0x04 115 | #define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08 116 | #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 117 | #define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 118 | #define IEEE80211_RADIOTAP_MCS_STBC_1 1 119 | #define IEEE80211_RADIOTAP_MCS_STBC_2 2 120 | #define IEEE80211_RADIOTAP_MCS_STBC_3 3 121 | 122 | #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 123 | 124 | /* For IEEE80211_RADIOTAP_AMPDU_STATUS */ 125 | #define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 126 | #define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002 127 | #define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004 128 | #define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 129 | #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 130 | #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 131 | 132 | /* For IEEE80211_RADIOTAP_VHT */ 133 | #define IEEE80211_RADIOTAP_VHT_KNOWN_STBC 0x0001 134 | #define IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA 0x0002 135 | #define IEEE80211_RADIOTAP_VHT_KNOWN_GI 0x0004 136 | #define IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS 0x0008 137 | #define IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM 0x0010 138 | #define IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED 0x0020 139 | #define IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH 0x0040 140 | #define IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID 0x0080 141 | #define IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID 0x0100 142 | 143 | #define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01 144 | #define IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA 0x02 145 | #define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04 146 | #define IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 0x08 147 | #define IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM 0x10 148 | #define IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED 0x20 149 | 150 | #define IEEE80211_RADIOTAP_CODING_LDPC_USER0 0x01 151 | #define IEEE80211_RADIOTAP_CODING_LDPC_USER1 0x02 152 | #define IEEE80211_RADIOTAP_CODING_LDPC_USER2 0x04 153 | #define IEEE80211_RADIOTAP_CODING_LDPC_USER3 0x08 154 | 155 | /*------------------------------ Tx Desc definition Macro 156 | * ------------------------*/ 157 | /* #pragma mark -- Tx Desc related definition. -- */ 158 | /* ---------------------------------------------------------------------------- 159 | * ----------------------------------------------------------- 160 | * Rate 161 | * ----------------------------------------------------------- 162 | * CCK Rates, TxHT = 0 */ 163 | #define DESC_RATE1M 0x00 164 | #define DESC_RATE2M 0x01 165 | #define DESC_RATE5_5M 0x02 166 | #define DESC_RATE11M 0x03 167 | 168 | /* OFDM Rates, TxHT = 0 */ 169 | #define DESC_RATE6M 0x04 170 | #define DESC_RATE9M 0x05 171 | #define DESC_RATE12M 0x06 172 | #define DESC_RATE18M 0x07 173 | #define DESC_RATE24M 0x08 174 | #define DESC_RATE36M 0x09 175 | #define DESC_RATE48M 0x0a 176 | #define DESC_RATE54M 0x0b 177 | 178 | /* MCS Rates, TxHT = 1 */ 179 | #define DESC_RATEMCS0 0x0c 180 | #define DESC_RATEMCS1 0x0d 181 | #define DESC_RATEMCS2 0x0e 182 | #define DESC_RATEMCS3 0x0f 183 | #define DESC_RATEMCS4 0x10 184 | #define DESC_RATEMCS5 0x11 185 | #define DESC_RATEMCS6 0x12 186 | #define DESC_RATEMCS7 0x13 187 | #define DESC_RATEMCS8 0x14 188 | #define DESC_RATEMCS9 0x15 189 | #define DESC_RATEMCS10 0x16 190 | #define DESC_RATEMCS11 0x17 191 | #define DESC_RATEMCS12 0x18 192 | #define DESC_RATEMCS13 0x19 193 | #define DESC_RATEMCS14 0x1a 194 | #define DESC_RATEMCS15 0x1b 195 | #define DESC_RATEMCS16 0x1C 196 | #define DESC_RATEMCS17 0x1D 197 | #define DESC_RATEMCS18 0x1E 198 | #define DESC_RATEMCS19 0x1F 199 | #define DESC_RATEMCS20 0x20 200 | #define DESC_RATEMCS21 0x21 201 | #define DESC_RATEMCS22 0x22 202 | #define DESC_RATEMCS23 0x23 203 | #define DESC_RATEMCS24 0x24 204 | #define DESC_RATEMCS25 0x25 205 | #define DESC_RATEMCS26 0x26 206 | #define DESC_RATEMCS27 0x27 207 | #define DESC_RATEMCS28 0x28 208 | #define DESC_RATEMCS29 0x29 209 | #define DESC_RATEMCS30 0x2A 210 | #define DESC_RATEMCS31 0x2B 211 | #define DESC_RATEVHTSS1MCS0 0x2C 212 | #define DESC_RATEVHTSS1MCS1 0x2D 213 | #define DESC_RATEVHTSS1MCS2 0x2E 214 | #define DESC_RATEVHTSS1MCS3 0x2F 215 | #define DESC_RATEVHTSS1MCS4 0x30 216 | #define DESC_RATEVHTSS1MCS5 0x31 217 | #define DESC_RATEVHTSS1MCS6 0x32 218 | #define DESC_RATEVHTSS1MCS7 0x33 219 | #define DESC_RATEVHTSS1MCS8 0x34 220 | #define DESC_RATEVHTSS1MCS9 0x35 221 | #define DESC_RATEVHTSS2MCS0 0x36 222 | #define DESC_RATEVHTSS2MCS1 0x37 223 | #define DESC_RATEVHTSS2MCS2 0x38 224 | #define DESC_RATEVHTSS2MCS3 0x39 225 | #define DESC_RATEVHTSS2MCS4 0x3A 226 | #define DESC_RATEVHTSS2MCS5 0x3B 227 | #define DESC_RATEVHTSS2MCS6 0x3C 228 | #define DESC_RATEVHTSS2MCS7 0x3D 229 | #define DESC_RATEVHTSS2MCS8 0x3E 230 | #define DESC_RATEVHTSS2MCS9 0x3F 231 | #define DESC_RATEVHTSS3MCS0 0x40 232 | #define DESC_RATEVHTSS3MCS1 0x41 233 | #define DESC_RATEVHTSS3MCS2 0x42 234 | #define DESC_RATEVHTSS3MCS3 0x43 235 | #define DESC_RATEVHTSS3MCS4 0x44 236 | #define DESC_RATEVHTSS3MCS5 0x45 237 | #define DESC_RATEVHTSS3MCS6 0x46 238 | #define DESC_RATEVHTSS3MCS7 0x47 239 | #define DESC_RATEVHTSS3MCS8 0x48 240 | #define DESC_RATEVHTSS3MCS9 0x49 241 | #define DESC_RATEVHTSS4MCS0 0x4A 242 | #define DESC_RATEVHTSS4MCS1 0x4B 243 | #define DESC_RATEVHTSS4MCS2 0x4C 244 | #define DESC_RATEVHTSS4MCS3 0x4D 245 | #define DESC_RATEVHTSS4MCS4 0x4E 246 | #define DESC_RATEVHTSS4MCS5 0x4F 247 | #define DESC_RATEVHTSS4MCS6 0x50 248 | #define DESC_RATEVHTSS4MCS7 0x51 249 | #define DESC_RATEVHTSS4MCS8 0x52 250 | #define DESC_RATEVHTSS4MCS9 0x53 251 | 252 | /* Base version of the radiotap packet header data */ 253 | #define PKTHDR_RADIOTAP_VERSION 0 254 | 255 | static inline u16 __get_unaligned_memmove16(const void *p) { 256 | u16 tmp; 257 | memmove(&tmp, p, 2); 258 | return tmp; 259 | } 260 | 261 | static inline u32 __get_unaligned_memmove32(const void *p) { 262 | u32 tmp; 263 | memmove(&tmp, p, 4); 264 | return tmp; 265 | } 266 | 267 | static inline u16 get_unaligned_le16(const void *p) { 268 | u16 tmp = __get_unaligned_memmove16((const u8 *)p); 269 | return le16_to_cpu(tmp); 270 | } 271 | 272 | static inline u32 get_unaligned_le32(const void *p) { 273 | u32 tmp = __get_unaligned_memmove32((const u8 *)p); 274 | return le32_to_cpu(tmp); 275 | } 276 | 277 | /* A generic radio capture format is desirable. There is one for 278 | * Linux, but it is neither rigidly defined (there were not even 279 | * units given for some fields) nor easily extensible. 280 | * 281 | * I suggest the following extensible radio capture format. It is 282 | * based on a bitmap indicating which fields are present. 283 | * 284 | * I am trying to describe precisely what the application programmer 285 | * should expect in the following, and for that reason I tell the 286 | * units and origin of each measurement (where it applies), or else I 287 | * use sufficiently weaselly language ("is a monotonically nondecreasing 288 | * function of...") that I cannot set false expectations for lawyerly 289 | * readers. 290 | */ 291 | 292 | /* 293 | * The radio capture header precedes the 802.11 header. 294 | * All data in the header is little endian on all platforms. 295 | */ 296 | #ifdef _MSC_VER 297 | #pragma pack(push, 1) 298 | #endif 299 | struct ieee80211_radiotap_header { 300 | u8 it_version; /* Version 0. Only increases 301 | * for drastic changes, 302 | * introduction of compatible 303 | * new fields does not count. 304 | */ 305 | u8 it_pad; 306 | __le16 it_len; /* length of the whole 307 | * header in bytes, including 308 | * it_version, it_pad, 309 | * it_len, and data fields. 310 | */ 311 | __le32 it_present; /* A bitmap telling which 312 | * fields are present. Set bit 31 313 | * (0x80000000) to extend the 314 | * bitmap by another 32 bits. 315 | * Additional extensions are made 316 | * by setting bit 31. 317 | */ 318 | } 319 | #ifdef _MSC_VER 320 | ; 321 | #pragma pack(pop) 322 | #else 323 | __attribute__((packed)); 324 | #endif 325 | 326 | /* Name Data type Units 327 | * ---- --------- ----- 328 | * 329 | * IEEE80211_RADIOTAP_TSFT __le64 microseconds 330 | * 331 | * Value in microseconds of the MAC's 64-bit 802.11 Time 332 | * Synchronization Function timer when the first bit of the 333 | * MPDU arrived at the MAC. For received frames, only. 334 | * 335 | * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap 336 | * 337 | * Tx/Rx frequency in MHz, followed by flags (see below). 338 | * 339 | * IEEE80211_RADIOTAP_FHSS __le16 see below 340 | * 341 | * For frequency-hopping radios, the hop set (first byte) 342 | * and pattern (second byte). 343 | * 344 | * IEEE80211_RADIOTAP_RATE u8 500kb/s 345 | * 346 | * Tx/Rx data rate 347 | * 348 | * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from 349 | * one milliwatt (dBm) 350 | * 351 | * RF signal power at the antenna, decibel difference from 352 | * one milliwatt. 353 | * 354 | * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from 355 | * one milliwatt (dBm) 356 | * 357 | * RF noise power at the antenna, decibel difference from one 358 | * milliwatt. 359 | * 360 | * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB) 361 | * 362 | * RF signal power at the antenna, decibel difference from an 363 | * arbitrary, fixed reference. 364 | * 365 | * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB) 366 | * 367 | * RF noise power at the antenna, decibel difference from an 368 | * arbitrary, fixed reference point. 369 | * 370 | * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless 371 | * 372 | * Quality of Barker code lock. Unitless. Monotonically 373 | * nondecreasing with "better" lock strength. Called "Signal 374 | * Quality" in datasheets. (Is there a standard way to measure 375 | * this?) 376 | * 377 | * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless 378 | * 379 | * Transmit power expressed as unitless distance from max 380 | * power set at factory calibration. 0 is max power. 381 | * Monotonically nondecreasing with lower power levels. 382 | * 383 | * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB) 384 | * 385 | * Transmit power expressed as decibel distance from max power 386 | * set at factory calibration. 0 is max power. Monotonically 387 | * nondecreasing with lower power levels. 388 | * 389 | * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from 390 | * one milliwatt (dBm) 391 | * 392 | * Transmit power expressed as dBm (decibels from a 1 milliwatt 393 | * reference). This is the absolute power level measured at 394 | * the antenna port. 395 | * 396 | * IEEE80211_RADIOTAP_FLAGS u8 bitmap 397 | * 398 | * Properties of transmitted and received frames. See flags 399 | * defined below. 400 | * 401 | * IEEE80211_RADIOTAP_ANTENNA u8 antenna index 402 | * 403 | * Unitless indication of the Rx/Tx antenna for this packet. 404 | * The first antenna is antenna 0. 405 | * 406 | * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap 407 | * 408 | * Properties of received frames. See flags defined below. 409 | * 410 | * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap 411 | * 412 | * Properties of transmitted frames. See flags defined below. 413 | * 414 | * IEEE80211_RADIOTAP_RTS_RETRIES u8 data 415 | * 416 | * Number of rts retries a transmitted frame used. 417 | * 418 | * IEEE80211_RADIOTAP_DATA_RETRIES u8 data 419 | * 420 | * Number of unicast retries a transmitted frame used. 421 | * 422 | * IEEE80211_RADIOTAP_MCS u8, u8, u8 unitless 423 | * 424 | * Contains a bitmap of known fields/flags, the flags, and 425 | * the MCS index. 426 | * 427 | * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless 428 | * 429 | * Contains the AMPDU information for the subframe. 430 | * 431 | * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 432 | * 433 | * Contains VHT information about this frame. 434 | */ 435 | enum ieee80211_radiotap_type { 436 | IEEE80211_RADIOTAP_TSFT = 0, 437 | IEEE80211_RADIOTAP_FLAGS = 1, 438 | IEEE80211_RADIOTAP_RATE = 2, 439 | IEEE80211_RADIOTAP_CHANNEL = 3, 440 | IEEE80211_RADIOTAP_FHSS = 4, 441 | IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, 442 | IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, 443 | IEEE80211_RADIOTAP_LOCK_QUALITY = 7, 444 | IEEE80211_RADIOTAP_TX_ATTENUATION = 8, 445 | IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, 446 | IEEE80211_RADIOTAP_DBM_TX_POWER = 10, 447 | IEEE80211_RADIOTAP_ANTENNA = 11, 448 | IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, 449 | IEEE80211_RADIOTAP_DB_ANTNOISE = 13, 450 | IEEE80211_RADIOTAP_RX_FLAGS = 14, 451 | IEEE80211_RADIOTAP_TX_FLAGS = 15, 452 | IEEE80211_RADIOTAP_RTS_RETRIES = 16, 453 | IEEE80211_RADIOTAP_DATA_RETRIES = 17, 454 | 455 | IEEE80211_RADIOTAP_MCS = 19, 456 | IEEE80211_RADIOTAP_AMPDU_STATUS = 20, 457 | IEEE80211_RADIOTAP_VHT = 21, 458 | IEEE80211_RADIOTAP_TIMESTAMP = 22, 459 | 460 | /* valid in every it_present bitmap, even vendor namespaces */ 461 | IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, 462 | IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, 463 | IEEE80211_RADIOTAP_EXT = 31 464 | }; 465 | 466 | struct radiotap_align_size { 467 | uint8_t align : 4, size : 4; 468 | }; 469 | 470 | struct ieee80211_radiotap_namespace { 471 | const struct radiotap_align_size *align_size; 472 | int n_bits; 473 | uint32_t oui; 474 | uint8_t subns; 475 | }; 476 | 477 | struct ieee80211_radiotap_vendor_namespaces { 478 | const struct ieee80211_radiotap_namespace *ns; 479 | int n_ns; 480 | }; 481 | 482 | /* helpers */ 483 | static inline int ieee80211_get_radiotap_len(unsigned char *data) { 484 | struct ieee80211_radiotap_header *hdr = 485 | (struct ieee80211_radiotap_header *)data; 486 | 487 | return get_unaligned_le16(&hdr->it_len); 488 | } 489 | 490 | /** 491 | * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args 492 | * @this_arg_index: index of current arg, valid after each successful call 493 | * to ieee80211_radiotap_iterator_next() 494 | * @this_arg: pointer to current radiotap arg; it is valid after each 495 | * call to ieee80211_radiotap_iterator_next() but also after 496 | * ieee80211_radiotap_iterator_init() where it will point to 497 | * the beginning of the actual data portion 498 | * @this_arg_size: length of the current arg, for convenience 499 | * @current_namespace: pointer to the current namespace definition 500 | * (or internally %NULL if the current namespace is unknown) 501 | * @is_radiotap_ns: indicates whether the current namespace is the default 502 | * radiotap namespace or not 503 | * 504 | * @_rtheader: pointer to the radiotap header we are walking through 505 | * @_max_length: length of radiotap header in cpu byte ordering 506 | * @_arg_index: next argument index 507 | * @_arg: next argument pointer 508 | * @_next_bitmap: internal pointer to next present u32 509 | * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present 510 | * @_vns: vendor namespace definitions 511 | * @_next_ns_data: beginning of the next namespace's data 512 | * @_reset_on_ext: internal; reset the arg index to 0 when going to the 513 | * next bitmap word 514 | * 515 | * Describes the radiotap parser state. Fields prefixed with an underscore 516 | * must not be used by users of the parser, only by the parser internally. 517 | */ 518 | 519 | struct ieee80211_radiotap_iterator { 520 | struct ieee80211_radiotap_header *_rtheader; 521 | const struct ieee80211_radiotap_vendor_namespaces *_vns; 522 | const struct ieee80211_radiotap_namespace *current_namespace; 523 | 524 | unsigned char *_arg, *_next_ns_data; 525 | __le32 *_next_bitmap; 526 | 527 | unsigned char *this_arg; 528 | int this_arg_index; 529 | int this_arg_size; 530 | 531 | int is_radiotap_ns; 532 | 533 | int _max_length; 534 | int _arg_index; 535 | uint32_t _bitmap_shifter; 536 | int _reset_on_ext; 537 | }; 538 | 539 | int ieee80211_radiotap_iterator_init( 540 | struct ieee80211_radiotap_iterator *iterator, 541 | struct ieee80211_radiotap_header *radiotap_header, int max_length, 542 | const struct ieee80211_radiotap_vendor_namespaces *vns); 543 | 544 | int ieee80211_radiotap_iterator_next( 545 | struct ieee80211_radiotap_iterator *iterator); 546 | 547 | u16 GetSequence(const u8 *packet); 548 | u8 MRateToHwRate(u8 rate); 549 | 550 | #endif 551 | -------------------------------------------------------------------------------- /src/logger.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGGER_H 2 | #define LOGGER_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define ushort uint16_t 14 | #define DEVOURER_LOG_TAG "devourer" 15 | 16 | #ifdef __ANDROID__ 17 | #include 18 | 19 | #define DEVOURER_LOGV(...) __android_log_write(ANDROID_LOG_VERBOSE, DEVOURER_LOG_TAG, __VA_ARGS__) 20 | #define DEVOURER_LOGD(...) __android_log_write(ANDROID_LOG_DEBUG, DEVOURER_LOG_TAG, __VA_ARGS__) 21 | #define DEVOURER_LOGI(...) __android_log_write(ANDROID_LOG_INFO, DEVOURER_LOG_TAG, __VA_ARGS__) 22 | #define DEVOURER_LOGW(...) __android_log_write(ANDROID_LOG_WARN, DEVOURER_LOG_TAG, __VA_ARGS__) 23 | #define DEVOURER_LOGE(...) __android_log_write(ANDROID_LOG_ERROR, DEVOURER_LOG_TAG, __VA_ARGS__) 24 | #else 25 | #include 26 | 27 | #define DEVOURER_LOGV(...) \ 28 | printf("<%s>", DEVOURER_LOG_TAG); \ 29 | printf(__VA_ARGS__); \ 30 | printf("\n") 31 | #define DEVOURER_LOGD(...) \ 32 | printf("<%s>", DEVOURER_LOG_TAG); \ 33 | printf(__VA_ARGS__); \ 34 | printf("\n") 35 | #define DEVOURER_LOGI(...) \ 36 | printf("<%s>", DEVOURER_LOG_TAG); \ 37 | printf(__VA_ARGS__); \ 38 | printf("\n") 39 | #define DEVOURER_LOGW(...) \ 40 | printf("<%s>", DEVOURER_LOG_TAG); \ 41 | printf(__VA_ARGS__); \ 42 | printf("\n") 43 | #define DEVOURER_LOGE(...) \ 44 | printf("<%s>", DEVOURER_LOG_TAG); \ 45 | printf(__VA_ARGS__); \ 46 | printf("\n") 47 | #endif 48 | 49 | template 50 | void format_helper(std::ostringstream& oss, 51 | std::string_view& str, const T& value) 52 | { 53 | std::size_t openBracket = str.find('{'); 54 | if (openBracket == std::string::npos) { return; } 55 | std::size_t closeBracket = str.find('}', openBracket + 1); 56 | if (closeBracket == std::string::npos) { return; } 57 | oss << str.substr(0, openBracket) << value; 58 | str = str.substr(closeBracket + 1); 59 | } 60 | 61 | template 62 | std::string format(std::string_view str, Targs...args) 63 | { 64 | std::ostringstream oss; 65 | (format_helper(oss, str, args),...); 66 | oss << str; 67 | return oss.str(); 68 | } 69 | 70 | template 71 | using format_string_t = std::string_view; 72 | 73 | class Logger { 74 | public: 75 | template 76 | void debug(format_string_t fmt, Args &&...args) { 77 | #if !defined(NDEBUG) 78 | std::string txt = format(fmt, args...); 79 | DEVOURER_LOGD(txt.c_str()); 80 | #endif 81 | } 82 | 83 | template 84 | void info(format_string_t fmt, Args &&...args) { 85 | std::string txt = format(fmt, args...); 86 | DEVOURER_LOGI(txt.c_str()); 87 | } 88 | 89 | template 90 | void warn(format_string_t fmt, Args &&...args) { 91 | std::string txt = format(fmt, args...); 92 | DEVOURER_LOGW(txt.c_str()); 93 | } 94 | 95 | template 96 | void error(format_string_t fmt, Args &&...args) { 97 | std::string txt = format(fmt, args...); 98 | DEVOURER_LOGE(txt.c_str()); 99 | } 100 | }; 101 | 102 | using Logger_t = std::shared_ptr; 103 | 104 | #endif /* LOGGER_H */ 105 | -------------------------------------------------------------------------------- /src/registry_priv.h: -------------------------------------------------------------------------------- 1 | #ifndef REGISTRY_PRIV_H 2 | #define REGISTRY_PRIV_H 3 | 4 | #include "HalVerDef.h" 5 | #include 6 | 7 | struct registry_priv { 8 | constexpr static uint8_t channel = 36; /* ad-hoc support requirement */ 9 | constexpr static HAL_RF_TYPE_E rf_config = RF_TYPE_MAX; 10 | constexpr static bool wifi_spec = false; /* !turbo_mode */ 11 | constexpr static uint8_t special_rf_path = 12 | 0; /* 0: 2T2R ,1: only turn on path A 1T1R */ 13 | constexpr static int8_t TxBBSwing_2G = -1; 14 | constexpr static int8_t TxBBSwing_5G = -1; 15 | constexpr static uint8_t AmplifierType_2G = 0; 16 | constexpr static uint8_t AmplifierType_5G = 0; 17 | constexpr static uint8_t RFE_Type = 64; 18 | }; 19 | 20 | #endif /* REGISTRY_PRIV_H */ 21 | -------------------------------------------------------------------------------- /txdemo/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #if defined(_MSC_VER) 7 | #include 8 | #include 9 | typedef int pid_t; 10 | #define fork() (0) 11 | #define sleep(seconds) Sleep((seconds)*1000) 12 | #elif defined(__ANDROID__) 13 | // On Android, include the libusb header as required. 14 | #include 15 | #else 16 | #include 17 | #endif 18 | 19 | #include "FrameParser.h" 20 | #include "RtlUsbAdapter.h" 21 | #include "WiFiDriver.h" 22 | #include "logger.h" 23 | 24 | #include 25 | 26 | 27 | // #define USB_VENDOR_ID 0x0bda 28 | // #define USB_PRODUCT_ID 0x8812 29 | 30 | void printHexArray(const uint8_t *array, size_t length) { 31 | for (size_t i = 0; i < length; ++i) { 32 | // Print each byte as a two-digit hexadecimal number 33 | std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') 34 | << static_cast(array[i]); 35 | 36 | // Print a space between bytes, but not after the last byte 37 | if (i < length - 1) { 38 | std::cout << " "; 39 | } 40 | } 41 | std::cout << std::dec << std::endl; // Reset to decimal formatting 42 | } 43 | 44 | static void packetProcessor(const Packet &packet) {} 45 | 46 | void usb_event_loop(Logger_t _logger,libusb_context* ctx){ 47 | while (true) { 48 | int r = libusb_handle_events(ctx); 49 | if (r < 0) { 50 | _logger->error("Error handling events: {}", r); 51 | break; 52 | } 53 | } 54 | } 55 | 56 | int main(int argc, char **argv) { 57 | libusb_context *context; 58 | libusb_device_handle *handle; 59 | libusb_device *device; 60 | struct libusb_device_descriptor desc; 61 | uint8_t usb_frame[10000]; 62 | unsigned char buffer[256]; 63 | struct tx_desc *ptxdesc; 64 | int fd; 65 | 66 | auto logger = std::make_shared(); 67 | 68 | // fd from argv is provided by termux on Android 69 | // https://wiki.termux.com/wiki/Termux-usb 70 | fd = atoi(argv[1]); 71 | logger->info("got fd {}", fd); 72 | 73 | // libusb_set_option(context, LIBUSB_OPTION_LOG_LEVEL, 74 | // LIBUSB_LOG_LEVEL_DEBUG); 75 | libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY); 76 | libusb_set_option(NULL, LIBUSB_OPTION_WEAK_AUTHORITY); 77 | 78 | int rc = libusb_init(&context); 79 | 80 | rc = libusb_wrap_sys_device(context, (intptr_t)fd, &handle); 81 | 82 | device = libusb_get_device(handle); 83 | 84 | rc = libusb_get_device_descriptor(device, &desc); 85 | 86 | logger->info("Vendor/Product ID:{:04x}:{:04x}", desc.idVendor, 87 | desc.idProduct); 88 | if (libusb_kernel_driver_active(handle, 0)) { 89 | rc = libusb_detach_kernel_driver(handle, 0); // detach driver 90 | logger->error("libusb_detach_kernel_driver: {}", rc); 91 | } 92 | rc = libusb_claim_interface(handle, 0); 93 | 94 | WiFiDriver wifi_driver{logger}; 95 | auto rtlDevice = wifi_driver.CreateRtlDevice(handle); 96 | pid_t fpid; 97 | fpid = fork(); 98 | rtlDevice->SetTxPower(40); 99 | if (fpid == 0) { 100 | 101 | rtlDevice->Init(packetProcessor, SelectedChannel{ 102 | .Channel = static_cast(161), 103 | .ChannelOffset = 0, 104 | .ChannelWidth = CHANNEL_WIDTH_20, 105 | 106 | }); 107 | 108 | return 1; 109 | } 110 | // Loop for sending packets 111 | 112 | 113 | rtlDevice->InitWrite(SelectedChannel{ 114 | .Channel = static_cast(161), 115 | .ChannelOffset = 0, 116 | .ChannelWidth = CHANNEL_WIDTH_20}); 117 | 118 | 119 | sleep(5); 120 | 121 | // A new thread starts the libusb event loop 122 | std::thread usb_thread(usb_event_loop,logger,context); 123 | uint8_t beacon_frame[] = { 124 | 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80, 0x08, 0x00, 0x08, 0x00, 0x37, 125 | 0x00, 0x01, // radiotap header 126 | 0x08, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x57, 127 | 0x42, 0x75, 0x05, 0xd6, 0x00, 0x57, 0x42, 0x75, 0x05, 0xd6, 0x00, 128 | 0x80, 0x00, // 80211 header 129 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x24, 0x4f, 130 | 0xa0, 0xc5, 0x4a, 0xbb, 0x6a, 0x55, 0x03, 0x72, 0xf8, 0x4d, 0xc4, 131 | 0x9d, 0x1a, 0x51, 0xb7, 0x3f, 0x98, 0xf1, 0xe7, 0x46, 0x4d, 0x1c, 132 | 0x21, 0x86, 0x15, 0x21, 0x02, 0xf4, 0x88, 0x63, 0xff, 0x51, 0x66, 133 | 0x34, 0xf2, 0x16, 0x71, 0xf5, 0x76, 0x0b, 0x35, 0xc0, 0xe1, 0x44, 134 | 0xcd, 0xce, 0x4e, 0x35, 0xd9, 0x85, 0x9a, 0xcf, 0x4d, 0x48, 0x4c, 135 | 0x8f, 0x28, 0x6f, 0x10, 0xb0, 0xa9, 0x5d, 0xbf, 0xcb, 0x6f}; 136 | 137 | int actual_length = 0; 138 | 139 | while (true) { 140 | rc = rtlDevice->send_packet(beacon_frame, sizeof(beacon_frame)); 141 | } 142 | rc = libusb_release_interface(handle, 0); 143 | assert(rc == 0); 144 | 145 | libusb_close(handle); 146 | 147 | libusb_exit(context); 148 | return 0; 149 | } 150 | --------------------------------------------------------------------------------