This commit is contained in:
Milan Meduna 2019-11-08 18:09:53 +01:00
parent fc8d500add
commit 4c9c5c3ab8
612 changed files with 436152 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
*.o
*.cmd
*.ko
*.cm
Module.symvers
modules.order
*.mod.c
.tmp_versions
.cache.mk

129
.travis.yml Normal file
View File

@ -0,0 +1,129 @@
language: c
compiler: gcc
sudo: required
dist: xenial
before_install:
- sudo apt-get clean
- sudo apt-get update
- sudo apt-get install dpkg
- export ALL_DEB=$(wget --quiet -O - ${KERNEL_URL}v${KVER}/ | grep -o 'href=".*"' | grep -m1 all | cut -d '"' -f 2)
- export KVER_BUILD=$(echo $ALL_DEB | cut -d '_' -f 1 | cut -c15-)
- wget ${KERNEL_URL}v${KVER}/$(wget --quiet -O - ${KERNEL_URL}v${KVER}/ | grep -o 'href=".*"' | grep headers | grep generic | grep -m1 amd64 | cut -d '"' -f 2)
- wget ${KERNEL_URL}v${KVER}/$ALL_DEB
- sudo dpkg -i *.deb
script:
- make CC=$COMPILER KVER=$KVER_BUILD-generic
env:
global:
- KERNEL_URL=http://kernel.ubuntu.com/~kernel-ppa/mainline/
matrix:
include:
- compiler: gcc
addons:
apt:
sources:
- sourceline: 'ppa:ondrej/nginx-mainline'
packages:
- libssl1.1
env: COMPILER=gcc-5 KVER=5.2-rc1
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:ondrej/nginx-mainline'
packages:
- gcc-6
- libssl1.1
env: COMPILER=gcc-6 KVER=5.2-rc1
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:ondrej/nginx-mainline'
packages:
- gcc-7
- libssl1.1
env: COMPILER=gcc-7 KVER=5.2-rc1
- compiler: gcc
addons:
apt:
sources:
- sourceline: 'ppa:ondrej/nginx-mainline'
packages:
- gcc-5
- libelf-dev
- libssl1.1
env: COMPILER=gcc-5 KVER=4.19.45
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:ondrej/nginx-mainline'
packages:
- gcc-6
- libelf-dev
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-7
- libelf-dev
- libssl1.1
env: COMPILER=gcc-6 KVER=4.19.45
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:ondrej/nginx-mainline'
packages:
- gcc-5
- libelf-dev
env: COMPILER=gcc-5 KVER=4.14.16
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-6
- libelf-dev
env: COMPILER=gcc-6 KVER=4.14.16
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-7
- libelf-dev
env: COMPILER=gcc-7 KVER=4.14.16
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-6
env: COMPILER=gcc-6 KVER=4.9.51
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.9
env: COMPILER=gcc-4.9 KVER=3.16.48
- gcc-7
- libssl1.1
env: COMPILER=gcc-7 KVER=4.19.45
- compiler: gcc
env: COMPILER=gcc-5 KVER=3.14.79

6
Kconfig Normal file
View File

@ -0,0 +1,6 @@
config RTL8812AU
tristate "Realtek 8812A USB WiFi"
depends on USB
---help---
Help message of RTL8812AU

339
LICENSE Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

2412
Makefile Executable file

File diff suppressed because it is too large Load Diff

248
REALTEK_README.txt Normal file
View File

@ -0,0 +1,248 @@
===============================================================================
Software Package - Component
===============================================================================
1. ReleaseNotes.pdf
2. document/
2.1 Quick_Start_Guide_for_Driver_Compilation_and_Installation.pdf
2.2 Quick_Start_Guide_for_Station_Mode.pdf
2.3 Quick_Start_Guide_for_SoftAP.pdf
2.4 Quick_Start_Guide_for_Bridge.pdf
2.5 Quick_Start_Guide_for_WOW.pdf
2.6 Quick_Start_Guide_for_Adaptivity_and_Carrier_Sensing_Test.pdf
2.7 HowTo_support_more_VidPids.pdf
2.8 HowTo_support_WIFI_certification_test.pdf
2.9 HowTo_enable_the_power_saving_functionality.pdf
2.10 HowTo_enable_driver_to_support_80211d.pdf
2.11 HowTo_enable_and_verify_TDLS_function_in_Wi-Fi_driver.pdf
2.12 How_to_set_driver_debug_log_level.pdf
2.13 How_to_append_vendor_specific_ie_to_driver_management_frames.pdf
2.14 wpa_cli_with_wpa_supplicant.pdf
2.15 Wireless_tools_porting_guide.pdf
2.16 SoftAP_Mode_features.pdf
2.17 linux_dhcp_server_notes.txt
2.18 RTK_P2P_WFD_Programming_guide.pdf
2.19 Realtek_WiFi_concurrent_mode_Introduction.pdf
2.20 Miracast_for_Realtek_WiFi.pdf
2.21 Driver_Configuration_for_RF_Regulatory_Certification.pdf
3. driver/
3.1 rtl8812AU_linux_v5.6.4_33522.20190509.tar.gz
Naming rule: rtlCHIPS_linux_vM.N.P[.H]_sssss.yyyymmdd[_COEX_VER][_beta].tar.gz
where:
CHIPS: supported chips
M: Major version
N: miNor version
P: Patch number
H: Hotfix number
s: SVN number
y: package year
m: package month
d: package day
COEX_VER: Coext version
_beta: beta driver
4. wpa_supplicant_hostapd/
4.1 wpa_supplicant_hostapd-0.8_rtw_r24647.20171025.tar.gz
4.1.1 wpa_supplicant
The tool help the wlan network to communicate under the
protection of WPAPSK mechanism (WPA/WPA2) and add WPS patch
4.1.2 hostapd
4.2 wpa_0_8.conf
Configure file sample for wpa_supplicant-0.8
4.3 rtl_hostapd_2G.conf
4.4 rtl_hostapd_5G.conf
Configure files for Soft-AP mode 2.4G/5G
4.5 p2p_hostapd.conf
Configure file for hostapd for Wi-Fi Direct (P2P)
4.6 wpa_supplicant_8_jb_4.2_rtw_r25670.20171213.tar.gz
wpa_supplicant_8 from Android 4.2 SDK and patched by Realtek
could be used for pure-linux and Android 4.2. Support only cfg80211/nl80211.
4.7 wpa_supplicant_8_kk_4.4_rtw_r25669.20171213.tar.gz
wpa_supplicant_8 from Android 4.4 SDK and patched by Realtek
could be used for pure-linux and Android 4.4. Support only cfg80211/nl80211.
4.8 wpa_supplicant_8_L_5.x_rtw_r24600.20171025.tar.gz
wpa_supplicant_8 from Android 5.x SDK and patched by Realtek
could be used for pure-linux and Android 5.x Support only cfg80211/nl80211.
4.9 wpa_supplicant_8_M_6.x_rtw_r24570.20171025.tar.gz
wpa_supplicant_8 from Android 6.x SDK and patched by Realtek
could be used for pure-linux and Android 6.x. Support only cfg80211/nl80211.
4.10 wpa_supplicant_8_N_7.x_rtw_r24577.20171025.tar.gz
wpa_supplicant_8 from Android 7.x SDK and patched by Realtek
could be used for pure-linux and Android 7.x. Support only cfg80211/nl80211.
4.11 wpa_supplicant_8_O_8.x_rtw_r31832.20190226.tar.gz
wpa_supplicant_8 from Android 8.x SDK and patched by Realtek
could be used for pure-linux and Android 8.x. Support only cfg80211/nl80211.
4.12 wpa_supplicant_8_P_9.x_rtw_r29226.20180827.tar.gz
wpa_supplicant_8 from Android 8.x SDK and patched by Realtek
could be used for pure-linux and Android 9.x. Support only cfg80211/nl80211.
5. wireless_tools/
5.1 wireless_tools.30.rtl.tar.gz
6. WiFi_Direct_User_Interface/
6.1 p2p_api_test_linux.c
6.2 p2p_ui_test_linux.c
6.3 p2p_test.h
6.4 Start_Guide_P2P_User_Interface_Linux.pdf
7. android_ref_codes_JB_4.2
7.1 linux-3.0.42_STATION_INFO_ASSOC_REQ_IES.diff
Kernel patch file for cfg80211's STATION_INFO_ASSOC_REQ_IES event for kernel 3.0.
7.2 realtek_wifi_SDK_for_android_JB_4.2_20130208.tar.gz
This tar ball includes our android wifi reference codes for Android 4.2
7.3 Realtek_Wi-Fi_SDK_for_Android_JB_4.2.pdf
Guide for porting Realtek wifi onto your Android 4.2 system
8. android_ref_codes_KK_4.4
8.1 linux-3.0.42_STATION_INFO_ASSOC_REQ_IES.diff
Kernel patch file for cfg80211's STATION_INFO_ASSOC_REQ_IES event for kernel 3.0.
8.2 realtek_wifi_SDK_for_android_KK_4.4_20140117.tar.gz
This tar ball includes our android wifi reference codes for Android 4.4
8.3 Realtek_Wi-Fi_SDK_for_Android_KK_4.4.pdf
Guide for porting Realtek wifi onto your Android 4.4 system
9. android_ref_codes_L_5.x
9.1 linux-3.0.42_STATION_INFO_ASSOC_REQ_IES.diff
Kernel patch file for cfg80211's STATION_INFO_ASSOC_REQ_IES event for kernel 3.0.
9.2 realtek_wifi_SDK_for_android_L_5.x_20150811.tgz
This tar ball includes our android wifi reference codes for Android 5.x
9.3 Realtek_Wi-Fi_SDK_for_Android_L_5.x.pdf
Guide for porting Realtek wifi onto your Android 5.x system
10. android_ref_codes_M_6.x
10.1 linux-3.0.42_STATION_INFO_ASSOC_REQ_IES.diff
Kernel patch file for cfg80211's STATION_INFO_ASSOC_REQ_IES event for kernel 3.0.
10.2 realtek_wifi_SDK_for_android_L_6.x_20151116.tgz
This tar ball includes our android wifi reference codes for Android 6.x
10.3 Realtek_Wi-Fi_SDK_for_Android_M_6.x.pdf
Guide for porting Realtek wifi onto your Android 6.x system
11. android_ref_codes_M_7.0
11.1 linux-3.0.42_STATION_INFO_ASSOC_REQ_IES.diff
Kernel patch file for cfg80211's STATION_INFO_ASSOC_REQ_IES event for kernel 3.0.
11.2 realtek_wifi_SDK_for_android_N_7.0_20161024.zip
This tar ball includes our android wifi reference codes for Android 7.0
11.3 Realtek_Wi-Fi_SDK_for_Android_N_7.0.pdf
Guide for porting Realtek wifi onto your Android 7.0 system
12. android_ref_codes_O_8.0
12.1 linux-3.0.42_STATION_INFO_ASSOC_REQ_IES.diff
Kernel patch file for cfg80211's STATION_INFO_ASSOC_REQ_IES event for kernel 3.0.
12.2 realtek_wifi_SDK_for_android_O_8.0_20181001.tar.gz
This tar ball includes our android wifi reference codes for Android 8.0
12.3 Realtek_Wi-Fi_SDK_for_Android_O_8.0.pdf
Guide for porting Realtek wifi onto your Android 8.0 system
13. android_ref_codes_P_9.x
13.1 linux-3.0.42_STATION_INFO_ASSOC_REQ_IES.diff
Kernel patch file for cfg80211's STATION_INFO_ASSOC_REQ_IES event for kernel 3.0.
13.2 realtek_wifi_SDK_for_android_P_9.x_20180813.tar.gz
This tar ball includes our android wifi reference codes for Android 9.x
13.3 Realtek_Wi-Fi_SDK_for_Android_P_9.x.pdf
Guide for porting Realtek wifi onto your Android 9.x system
13. install.sh
Script to compile and install WiFi driver easily in PC-Linux
==================================================================================================================
User Guide for Driver compilation and installation
==================================================================================================================
(*) Please refer to document/Quick_Start_Guide_for_Driver_Compilation_and_Installation.pdf
==================================================================================================================
User Guide for Station mode
==================================================================================================================
(*) Please refer to document/Quick_Start_Guide_for_Station_Mode.pdf
==================================================================================================================
User Guide for Soft-AP mode
==================================================================================================================
(*) Please refer to document/Quick_Start_Guide_for_SoftAP.pdf
(*) Please use wpa_supplicant_hostapd-0.8_rtw_r24647.20171025.tar.gz
(*) Please refer to document/linux_dhcp_server_notes.txt
==================================================================================================================
User Guide for Wi-Fi Direct
==================================================================================================================
Realtek Legacy Wi-Fi Direct:
(*) Please refer to document/RTK_P2P_WFD_Programming_guide.pdf
(*) Please use wpa_supplicant_hostapd-0.8_rtw_r24647.20171025.tar.gz
(*) Please refer to document/linux_dhcp_server_notes.txt
(*) Please refer to WiFi_Direct_User_Interface/
Wi-Fi Direct with nl80211
(*) Please use:
or
wpa_supplicant_8_jb_4.2_rtw_r25670.20171213.tar.gz
or
wpa_supplicant_8_kk_4.4_rtw_r25669.20171213.tar.gz
or
wpa_supplicant_8_L_5.x_rtw_r24600.20171025.tar.gz
or
wpa_supplicant_8_M_6.x_rtw_r24570.20171025.tar.gz
or
wpa_supplicant_8_N_7.x_rtw_r24577.20171025.tar.gz
or
wpa_supplicant_8_O_8.x_rtw_r33457.20190507.tar.gz
or
wpa_supplicant_8_P_9.x_rtw_r29226.20180827.tar.gz
(*) For P2P instruction/command, please refer to:
README-P2P inside the wpa_supplicant folder of the wpa_supplicant_8 you choose
(*) For DHCP server, please refer to:
document/linux_dhcp_server_notes.txt
==================================================================================================================
User Guide for WPS2.0
==================================================================================================================
(*) Please use:
wpa_supplicant_hostapd-0.8_rtw_r24647.20171025.tar.gz
or
wpa_supplicant_8_jb_4.2_rtw_r25670.20171213.tar.gz
or
wpa_supplicant_8_kk_4.4_rtw_r25669.20171213.tar.gz
or
wpa_supplicant_8_L_5.x_rtw_r24600.20171025.tar.gz
or
wpa_supplicant_8_M_6.x_rtw_r24570.20171025.tar.gz
or
wpa_supplicant_8_N_7.x_rtw_r24577.20171025.tar.gz
or
wpa_supplicant_8_O_8.x_rtw_r33457.20190507.tar.gz
or
wpa_supplicant_8_P_9.x_rtw_r29226.20180827.tar.gz
(*) For WPS instruction/command, please refert to:
README-WPS inside the wpa_supplicant folder of the wpa_supplicant_8 you choose
==================================================================================================================
User Guide for Power Saving Mode
==================================================================================================================
(*) Please refer to document/HowTo_enable_the_power_saving_functionality.pdf
==================================================================================================================
User Guide for Applying Wi-Fi solution onto Andriod System
==================================================================================================================
(*) For Android 1.6 ~ 2.3, 4.0, 4.1, 4.3, please contact us for further information
(*) For Android 4.2, please refer to android_ref_codes_JB_4.2/Realtek_Wi-Fi_SDK_for_Android_JB_4.2.pdf
(*) For Android 4.4, please refer to android_ref_codes_KK_4.4/Realtek_Wi-Fi_SDK_for_Android_KK_4.4.pdf
(*) For Android 5.X, please refer to android_ref_codes_L_5.x/Realtek_Wi-Fi_SDK_for_Android_L_5.x.pdf
(*) For Android 6.X, please refer to android_ref_codes_M_6.x/Realtek_Wi-Fi_SDK_for_Android_M_6.x.pdf
(*) For Android 7.X, please refer to android_ref_codes_N_7.0/Realtek_Wi-Fi_SDK_for_Android_N_7.0.pdf
(*) For Android 8.X, please refer to android_ref_codes_O_8.0/Realtek_Wi-Fi_SDK_for_Android_O_8.0.pdf
(*) For Android 9.X, please refer to android_ref_codes_P_9.x/Realtek_Wi-Fi_SDK_for_Android_P_9.x.pdf

BIN
ReleaseNotes.pdf Normal file

Binary file not shown.

View File

@ -0,0 +1,11 @@
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES += p2p_api_test_linux.c p2p_ui_test_linux.c
LOCAL_SHARED_LIBRARIES := libc libcutils
LOCAL_MODULE = P2P_UI
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
endif

View File

@ -0,0 +1,101 @@
wpa_supplicant_hostapd=`ls -1 ../wpa_supplicant_hostapd/wpa_supplicant_hostapd-0.8_*`
echo $wpa_supplicant_hostapd
if [ -e $wpa_supplicant_hostapd ]; then
echo "Checking wpa_supplicant_hostatpd"
else
echo "wpa_supplicant_hostapd doesn'tt exist in corresponding folder"
exit
fi
if [ -e ../wpa_supplicant_hostapd/p2p_hostapd.conf ]; then
echo "Checking p2p_hostapd.conf"
else
echo "p2p_hostapd.conf doesn't exist in corresponding folder"
exit
fi
if [ -e ../wpa_supplicant_hostapd/wpa_0_8.conf ]; then
echo "Checking wpa_0_8.conf"
else
echo "wpa_0_8.conf doesn't exist in corresponding folder"
exit
fi
#cp ../wpa_supplicant_hostapd/wpa_supplicant_hostapd-0.8_rtw_20111118.zip ./
cp $wpa_supplicant_hostapd ./
wpa_supplicant_hostapd=`ls -1 ./wpa_supplicant_hostapd-0.8_*`
echo " "$wpa_supplicant_hostapd
unzip $wpa_supplicant_hostapd
cd wpa_supplicant_hostapd-0.8
cd wpa_supplicant
make clean all
cd ..
cd hostapd
make clean all
cd ..
cd ..
cp ../wpa_supplicant_hostapd/p2p_hostapd.conf ./
cp ../wpa_supplicant_hostapd/wpa_0_8.conf ./
cp ./wpa_supplicant_hostapd-0.8/hostapd/hostapd ./
cp ./wpa_supplicant_hostapd-0.8/hostapd/hostapd_cli ./
cp ./wpa_supplicant_hostapd-0.8/wpa_supplicant/wpa_supplicant ./
cp ./wpa_supplicant_hostapd-0.8/wpa_supplicant/wpa_cli ./
rm -rf wpa_supplicant_hostapd-0.8
rm -rf $wpa_supplicant_hostapd
gcc -o P2P_UI ./p2p_api_test_linux.c ./p2p_ui_test_linux.c -lpthread
if [ ! -e ./p2p_hostapd.conf ]; then
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "Doesn't have p2p_hostapd.conf"
result="fail"
fi
if [ ! -e ./wpa_0_8.conf ]; then
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "Doesn't have wpa_0_8.conf"
result="fail"
fi
if [ ! -e ./hostapd ]; then
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "Doesn't have hostapd"
result="fail"
fi
if [ ! -e ./wpa_supplicant ]; then
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "Doesn't have hostapd_cli"
result="fail"
fi
if [ ! -e ./wpa_cli ]; then
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "Doesn't have p2p_hostapd.conf"
result="fail"
fi
if [ ! -e ./P2P_UI ]; then
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "Doesn't have P2P_UI"
result="fail"
fi
if [ "$result" == "fail" ]; then
echo "WiFi_Direct_User_Interface install unsuccessful"
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
exit
fi
echo "##################################################"
echo "WiFi_Direct_User_Interface install complete!!!!!!!"
echo "##################################################"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,167 @@
#ifndef _P2P_UI_TEST_H_
#define _P2P_UI_TEST_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define P2P_AUTO 1
//#define DHCP 1
#define CMD_SZ 100
#define SSID_SZ 32
#define SEC 1000000
#define SCAN_POOL_NO 8
#define NEGO_RETRY_INTERVAL 10 * SEC
#define NEGO_QUERY_INTERVAL 0.5 * SEC
#define PRE_NEGO_INTERVAL 0.5 * SEC
#define MAX_PROV_RETRY 15
#define PROV_RETRY_INTERVAL 5
#define PROV_WAIT_TIME 1 * SEC
#define MAX_NEGO_RETRY 60
#define NEGO_WAIT_TIME 0.5 * SEC
#define WPS_RETRY 120
#define SUPPLICANT_INIT_TIME 1 * SEC
#define HOSTAPD_INIT_TIME 1 * SEC
#define SUPPLICANT_INTERVAL 1 * SEC
#define HOSTAPD_INTERVAL 1 * SEC
#define POLLING_INTERVAL 1 * SEC
#define _TRUE 1
#define _FALSE 0
#define WPS_CONFIG_METHOD_LABEL 0x0004
#define WPS_CONFIG_METHOD_DISPLAY 0x0008
#define WPS_CONFIG_METHOD_E_NFC 0x0010
#define WPS_CONFIG_METHOD_I_NFC 0x0020
#define WPS_CONFIG_METHOD_NFC 0x0040
#define WPS_CONFIG_METHOD_PBC 0x0080
#define WPS_CONFIG_METHOD_KEYPAD 0x0100
#define WPS_CONFIG_METHOD_VPBC 0x0280
#define WPS_CONFIG_METHOD_PPBC 0x0480
#define WPS_CONFIG_METHOD_VDISPLAY 0x2008
#define WPS_CONFIG_METHOD_PDISPLAY 0x4008
enum thread_trigger{
THREAD_NONE = 0,
THREAD_DEVICE = 1,
THREAD_GO = 2,
};
enum P2P_ROLE {
P2P_ROLE_DISABLE = 0,
P2P_ROLE_DEVICE = 1,
P2P_ROLE_CLIENT = 2,
P2P_ROLE_GO = 3
};
enum P2P_STATE {
P2P_STATE_NONE = 0, // P2P disable
P2P_STATE_IDLE = 1, // P2P had enabled and do nothing
P2P_STATE_LISTEN = 2, // In pure listen state
P2P_STATE_SCAN = 3, // In scan phase
P2P_STATE_FIND_PHASE_LISTEN = 4, // In the listen state of find phase
P2P_STATE_FIND_PHASE_SEARCH = 5, // In the search state of find phase
P2P_STATE_TX_PROVISION_DIS_REQ = 6, // In P2P provisioning discovery
P2P_STATE_RX_PROVISION_DIS_RSP = 7,
P2P_STATE_RX_PROVISION_DIS_REQ = 8,
P2P_STATE_GONEGO_ING = 9, // Doing the group owner negoitation handshake
P2P_STATE_GONEGO_OK = 10, // finish the group negoitation handshake with success
P2P_STATE_GONEGO_FAIL = 11, // finish the group negoitation handshake with failure
P2P_STATE_RECV_INVITE_REQ = 12, // receiving the P2P Inviation request
P2P_STATE_PROVISIONING_ING = 13, // Doing the P2P WPS
P2P_STATE_PROVISIONING_DONE = 14, // Finish the P2P WPS
};
enum P2P_WPSINFO {
P2P_NO_WPSINFO = 0,
P2P_GOT_WPSINFO_PEER_DISPLAY_PIN = 1,
P2P_GOT_WPSINFO_SELF_DISPLAY_PIN = 2,
P2P_GOT_WPSINFO_PBC = 3,
};
struct scan{
char addr[18];
int go;
};
struct p2p{
char ifname[10];
int enable;
int status;
char dev_name[33];
int intent;
int listen_ch;
int wps_info;
int wpsing;
unsigned int pin;
int role;
char peer_devaddr[18];
int p2p_get; //p2p_get==1 : print messages from ioctl p2p_get
char print_line[CMD_SZ];
int have_p2p_dev; //have_p2p_dev==1 : after scanning p2p device
int show_scan_result;
int count_line;
char peer_ifaddr[18];
char cmd[CMD_SZ];
char parse[CMD_SZ];
char apd_ssid[SSID_SZ];
int op_ch; //operation channel
int wpa_open;
int ap_open;
char ap_conf[CMD_SZ];
char ap_path[CMD_SZ];
char apcli_path[CMD_SZ];
char wpa_conf[CMD_SZ];
char wpa_path[CMD_SZ];
char wpacli_path[CMD_SZ];
char ok_msg[CMD_SZ];
char redo_msg[CMD_SZ];
char fail_msg[CMD_SZ];
char nego_msg[CMD_SZ];
char scan_msg[CMD_SZ];
int thread_trigger;
pthread_t pthread;
pthread_t pthread_go;
int res; //check if thread is created; 1: disabled, 0: enabled
int res_go; //created if p2p device becomes GO
struct scan scan_pool[SCAN_POOL_NO];
int connect_go;
int no_sta_connected;
};
void ui_screen(struct p2p *p);
char *naming_wpsinfo(int wps_info);
char *naming_role(int role);
char *naming_status(int status);
unsigned int wps_pin_checksum(unsigned int pin);
void p2p_enable(struct p2p *p);
void p2p_scan(struct p2p *p);
void scan_result(struct p2p *p);
void p2p_intent(struct p2p *p);
void p2p_pincode(struct p2p *p, char *ins_no, char *ins_no_again);
void p2p_devaddr(struct p2p *p);
void p2p_role(struct p2p *p, int flag);
void p2p_status(struct p2p *p, int flag);
void p2p_prov_disc_no_addr(struct p2p *p, char *msg);
void p2p_prov_disc(struct p2p *p, char *msg, char *dis_msg, char *label_msg);
void p2p_set_nego(struct p2p *p);
void p2p_ifaddr(struct p2p *p);
void p2p_client_mode(struct p2p *p);
void p2p_go_mode(struct p2p *p);
void p2p_get_hostapd_conf(struct p2p *p);
void p2p_set_opch(struct p2p *p, char *msg, int print);
void p2p_softap_ssid(struct p2p *p, char *msg, int print);
void p2p_listen_ch(struct p2p *p, char *msg);
void p2p_peer_devaddr(struct p2p *p, char *peer_devaddr);
void p2p_peer_req_cm(struct p2p *p, char *peer_req_cm);
void p2p_peer_info(struct p2p *p, char *peer_devaddr, char *peer_req_cm);
void p2p_wps_cm(struct p2p *p, char *scan_addr, char *cms);
void p2p_device_name(struct p2p *p, char *scan_addr, char *dns);
void p2p_setDN(struct p2p *p);
void *polling_status(void *arg);
void *polling_client(void *arg);
void *print_status(void *arg);
#endif //_P2P_UI_TEST_H_

View File

@ -0,0 +1,536 @@
#include "p2p_test.h"
char *naming_wpsinfo(int wps_info)
{
switch(wps_info)
{
case P2P_NO_WPSINFO: return ("P2P_NO_WPSINFO");
case P2P_GOT_WPSINFO_PEER_DISPLAY_PIN: return ("P2P_GOT_WPSINFO_PEER_DISPLAY_PIN");
case P2P_GOT_WPSINFO_SELF_DISPLAY_PIN: return ("P2P_GOT_WPSINFO_SELF_DISPLAY_PIN");
case P2P_GOT_WPSINFO_PBC: return ("P2P_GOT_WPSINFO_PBC");
default: return ("UI unknown failed");
}
}
char *naming_role(int role)
{
switch(role)
{
case P2P_ROLE_DISABLE: return ("P2P_ROLE_DISABLE");
case P2P_ROLE_DEVICE: return ("P2P_ROLE_DEVICE");
case P2P_ROLE_CLIENT: return ("P2P_ROLE_CLIENT");
case P2P_ROLE_GO: return ("P2P_ROLE_GO");
default: return ("UI unknown failed");
}
}
char *naming_status(int status)
{
switch(status)
{
case P2P_STATE_NONE: return ("P2P_STATE_NONE");
case P2P_STATE_IDLE: return ("P2P_STATE_IDLE");
case P2P_STATE_LISTEN: return ("P2P_STATE_LISTEN");
case P2P_STATE_SCAN: return ("P2P_STATE_SCAN");
case P2P_STATE_FIND_PHASE_LISTEN: return ("P2P_STATE_FIND_PHASE_LISTEN");
case P2P_STATE_FIND_PHASE_SEARCH: return ("P2P_STATE_FIND_PHASE_SEARCH");
case P2P_STATE_TX_PROVISION_DIS_REQ: return ("P2P_STATE_TX_PROVISION_DIS_REQ");
case P2P_STATE_RX_PROVISION_DIS_RSP: return ("P2P_STATE_RX_PROVISION_DIS_RSP");
case P2P_STATE_RX_PROVISION_DIS_REQ: return ("P2P_STATE_RX_PROVISION_DIS_REQ");
case P2P_STATE_GONEGO_ING: return ("P2P_STATE_GONEGO_ING");
case P2P_STATE_GONEGO_OK: return ("P2P_STATE_GONEGO_OK");
case P2P_STATE_GONEGO_FAIL: return ("P2P_STATE_GONEGO_FAIL");
case P2P_STATE_RECV_INVITE_REQ: return ("P2P_STATE_RECV_INVITE_REQ");
case P2P_STATE_PROVISIONING_ING: return ("P2P_STATE_PROVISIONING_ING");
case P2P_STATE_PROVISIONING_DONE: return ("P2P_STATE_PROVISIONING_DONE");
default: return ("UI unknown failed");
}
}
char* naming_enable(int enable)
{
switch(enable)
{
case P2P_ROLE_DISABLE: return ("[Disabled]");
case P2P_ROLE_DEVICE: return ("[Enable/Device]");
case P2P_ROLE_CLIENT: return ("[Enable/Client]");
case P2P_ROLE_GO: return ("[Enable/GO]");
default: return ("UI unknown failed");
}
}
void ui_screen(struct p2p *p)
{
system("clear");
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("****************************************************************************************************\n");
printf("* P2P UI TEST v0.5 *\n");
printf("****************************************************************************************************\n");
printf("* Enable: %-89s*\n", naming_enable(p->enable));
printf("* Intent: %2d *\n", p->intent);
printf("* Status: %-89s*\n", naming_status(p->status));
printf("* Role: %-91s*\n", naming_role(p->role));
printf("* WPS method: %-85s*\n", naming_wpsinfo(p->wps_info));
printf("* PIN code: %08d *\n", p->pin);
printf("* Device name: %-84s*\n", p->dev_name);
printf("* Peer device address: %-76s*\n", p->peer_devaddr);
printf("* Peer interface address: %-73s*\n", p->peer_ifaddr);
printf("* *\n");
printf("* e) Wi-Fi Direct Enable/Disable *\n");
printf("* i) Intent ( The degree to be Group Owner/SoftAP ) *\n");
printf("* a) Scan Wi-Fi Direct devices *\n");
printf("* m) Peer device address you want to test *\n");
printf("* p) Provision discovery *\n");
printf("* c) Input PIN codes *\n");
printf("* w) WPS method *\n");
printf("* n) Group owner negotiation *\n");
printf("* x) Start wpa_supplicant/hostapd *\n");
printf("* h) Set operation channel | t) Set SoftAP ssid *\n");
printf("* r) Get Current P2P Role | s) Get Current P2P Status *\n");
printf("* d) Set device name | l) Set Listen channel *\n");
printf("* f) Reflash Current State | q) Quit *\n");
printf("****************************************************************************************************\n");
if(p->p2p_get==0)
{
printf("* *\n");
}
else if(p->p2p_get==1)
{
printf("*%-98s*\n", p->print_line);
}
printf("****************************************************************************************************\n");
if( ( p->show_scan_result == 1 ) && ( p->have_p2p_dev == 1 ) )
//if( (p->have_p2p_dev == 1) && (p->enable >= P2P_ROLE_DEVICE) && ( p->wpsing == 0 ) && (p->status >= P2P_STATE_LISTEN && p->status <= P2P_STATE_FIND_PHASE_SEARCH) )
{
scan_result(p);
}
else
{
int i=0;
for(i = 0; i < SCAN_POOL_NO + 1; i++ )
printf("* *\n");
}
printf("****************************************************************************************************\n");
p->show_scan_result = 0;
}
void init_p2p(struct p2p *p)
{
strcpy( p->ifname, "wlan0" );
p->enable = P2P_ROLE_DISABLE;
p->res = 1;
p->res_go = 1;
p->status = P2P_STATE_NONE;
p->intent = 1;
p->wps_info = 0;
p->wpsing = 0;
p->pin = 12345670;
p->role = P2P_ROLE_DISABLE;
p->listen_ch = 11;
strcpy( p->peer_devaddr, "00:00:00:00:00:00" );
p->p2p_get = 0;
memset( p->print_line, 0x00, CMD_SZ);
p->have_p2p_dev = 0;
p->count_line = 0;
strcpy( p->peer_ifaddr, "00:00:00:00:00:00" );
memset( p->cmd, 0x00, CMD_SZ);
p->wpa_open=0;
p->ap_open=0;
strcpy(p->ok_msg, "WiFi Direct handshake done" );
strcpy(p->redo_msg, "Re-do GO handshake" );
strcpy(p->fail_msg, "GO handshake unsuccessful" );
strcpy(p->nego_msg, "Start P2P negotiation" );
strcpy(p->wpa_conf, "./wpa_0_8.conf" );
strcpy(p->wpa_path, "./wpa_supplicant" );
strcpy(p->wpacli_path, "./wpa_cli" );
strcpy(p->ap_conf, "./p2p_hostapd.conf" );
strcpy(p->ap_path, "./hostapd" );
strcpy(p->apcli_path, "./hostapd_cli" );
strcpy(p->scan_msg, "Device haven't enable p2p functionalities" );
}
void rename_intf(struct p2p *p)
{
FILE *pfin = NULL;
FILE *pfout = NULL;
pfin = fopen( p->ap_conf, "r" );
pfout = fopen( "./p2p_hostapd_temp.conf", "w" );
if ( pfin )
{
while( !feof( pfin ) ){
memset(p->parse, 0x00, CMD_SZ);
fgets(p->parse, CMD_SZ, pfin);
if(strncmp(p->parse, "interface=", 10) == 0)
{
memset(p->parse, 0x00, CMD_SZ);
sprintf( p->parse, "interface=%s\n", p->ifname );
fputs( p->parse, pfout );
}
else
fputs(p->parse, pfout);
}
}
fclose( pfout );
system( "rm -rf ./p2p_hostapd.conf" );
system( "mv ./p2p_hostapd_temp.conf ./p2p_hostapd.conf" );
return;
}
//int main()
int main(int argc, char **argv)
{
char peerifa[40] = { 0x00 };
char scan[CMD_SZ];
struct p2p p2pstruct;
struct p2p *p=NULL;
p = &p2pstruct;
if( p != NULL)
{
memset(p, 0x00, sizeof(struct p2p));
init_p2p(p);
}
strcpy(p->ifname, argv[1] );
/* Disable P2P functionalities at first*/
p->enable=P2P_ROLE_DISABLE;
p2p_enable(p);
p2p_get_hostapd_conf(p);
usleep(50000);
rename_intf(p);
do
{
ui_screen(p);
printf("*insert cmd:");
memset( scan, 0x00, CMD_SZ );
scanf("%s", scan);
if( p->thread_trigger == THREAD_NONE ) //Active mode for user interface
{
if( strncmp(scan, "e", 1) == 0 ) //Enable
{
p->show_scan_result = 1;
ui_screen(p);
printf("Please insert enable mode;[0]Disable, [1]Device, [2]Client, [3]GO:");
scanf("%d",&p->enable);
p2p_enable(p);
p->show_scan_result = 1;
}
else if( strncmp(scan, "a", 1) == 0 ) // Scan P2P device
{
p2p_scan(p);
p->show_scan_result = 1;
}
else if( strncmp(scan, "d", 1) == 0 ) // Set device name
{
p->p2p_get = 0;
printf("Please insert device name :");
scanf("\n%[^\n]", p->dev_name);
p2p_setDN(p);
p->show_scan_result = 1;
}
else if( strncmp(scan, "i", 1) == 0 ) // Intent
{
p->show_scan_result = 1;
ui_screen(p);
printf("Please insert intent from [0~15(must be softap)] :");
scanf("%d",&p->intent);
p2p_intent(p);
p->show_scan_result = 1;
}
else if( strncmp(scan, "w", 1) == 0 ) // WPS_info
{
p->show_scan_result = 1;
ui_screen(p);
printf("Please insert WPS method\n");
printf("[0]None, [1]Peer Display PIN, [2]Self Display Pin, [3]PBC :");
scanf("%d",&p->wps_info);
p2p_wpsinfo(p);
p->show_scan_result = 1;
}
else if( strncmp(scan, "c", 1) == 0 ) // PIN_code
{
char ins_no[CMD_SZ], ins_no_again[CMD_SZ];
memset(ins_no, 0x00, CMD_SZ);
strcpy(ins_no, "Please insert 8-digit number, eg:12345670 :" );
memset(ins_no_again, 0x00, CMD_SZ);
strcpy(ins_no_again, "Invalid number, insert again, eg:12345670 :" );
p2p_pincode(p, ins_no, ins_no_again);
p->show_scan_result = 1;
}
else if( strncmp(scan, "m", 1) == 0 ) // Set peer device address
{
p->show_scan_result = 1;
ui_screen(p);
printf("Please insert number in scan list:");
p2p_devaddr(p);
p->show_scan_result = 1;
}
else if( strncmp(scan, "r", 1) == 0 ) // Get role
{
p2p_role(p,1);
p->show_scan_result = 1;
}
else if( strncmp(scan, "s", 1) == 0 ) // Get status
{
p2p_status(p, 1);
p->show_scan_result = 1;
}
else if( strncmp(scan, "p", 1) == 0 ) // Provision discovery
{
char msg[CMD_SZ];
memset( msg, 0x00, CMD_SZ );
char dis_msg[CMD_SZ];
memset( dis_msg, 0x00, CMD_SZ );
char label_msg[CMD_SZ];
memset( label_msg, 0x00, CMD_SZ );
if(strncmp(p->peer_devaddr, "00:00:00:00:00:00", 17) == 0)
{
strcpy( msg, "Please insert peer P2P device at first" );
p2p_prov_disc_no_addr(p, msg);
p->show_scan_result = 1;
}
else
{
strcpy( msg, "Please insert WPS configuration method ;[0]display, [1]keypad, [2]pbc, [3]label:\n" );
strcpy( dis_msg, "Please insert PIN code displays on peer device screen:" );
strcpy( label_msg, "Please insert PIN code displays on peer label:" );
p2p_prov_disc(p, msg, dis_msg, label_msg);
}
}
else if( strncmp(scan, "n", 1) == 0 ) // Set negotiation
{
p2p_set_nego(p);
}
else if( strncmp(scan, "f", 1) == 0 ) // Reflash current state
{
p->show_scan_result = 1;
p2p_status(p, 0);
p2p_role(p, 0);
p2p_ifaddr(p);
if( p->status == P2P_STATE_RX_PROVISION_DIS_REQ )
{
char peer_devaddr[18];
char peer_req_cm[4];
memset( peer_devaddr, 0x00, 18);
memset( peer_req_cm, 0x00, 4);
p2p_peer_devaddr(p, peer_devaddr);
p2p_peer_req_cm(p, peer_req_cm);
p2p_peer_info(p, p->peer_devaddr, peer_req_cm);
}
#ifndef P2P_AUTO
else
{
if( p->role == P2P_ROLE_CLIENT )
{
p2p_client_mode(p);
}
else if( p->role == P2P_ROLE_GO )
{
p2p_go_mode(p);
}
}
#endif //P2P_AUTO
}
else if( strncmp(scan, "x", 1) == 0 ) // Start wpa_supplicant/hostapd
{
if( p->role == P2P_ROLE_CLIENT )
{
p2p_client_mode(p);
}
else if( p->role == P2P_ROLE_GO )
{
p2p_go_mode(p);
}
}
else if( strncmp(scan, "h", 1) == 0 ) // Set operation channel
{
char msg[CMD_SZ];
memset( msg, 0x00, CMD_SZ );
strcpy( msg, "Please insert desired operation channel:" );
p2p_set_opch(p, msg, 1);
p->show_scan_result = 1;
}
else if( strncmp(scan, "t", 1) == 0 ) // Set SoftAP ssid
{
char msg[CMD_SZ];
memset( msg, 0x00, CMD_SZ );
strcpy( msg, "Please insert desired SoftAP ssid:" );
p2p_softap_ssid(p, msg, 1);
p->show_scan_result = 1;
}
else if( strncmp(scan, "l", 1) == 0 ) // Set Listen channel
{
char msg[CMD_SZ];
memset( msg, 0x00, CMD_SZ );
strcpy( msg, "Please insert desired Listen channel, only ch.1.6.11 are available:" );
p2p_listen_ch(p, msg);
p->show_scan_result = 1;
}
else if( strncmp(scan, "q", 1) == 0 ) // Quit
{
if( p->res == 0 )
p->res = 1;
if( p->res_go == 0 )
p->res_go = 1;
break;
}
else // Insert wrong commamd
{
p->p2p_get=1;
p->show_scan_result = 1;
memset( p->print_line, 0x00, CMD_SZ );
sprintf( p->print_line, " BAD argument");
}
}
else if( p->thread_trigger == THREAD_DEVICE ) //Passive mode for user interface
{
p->thread_trigger = THREAD_NONE ;
if( strncmp(scan, "b", 1) == 0 )
{
p->wps_info=3;
p2p_wpsinfo(p);
p2p_status(p, 0);
if(p->status != P2P_STATE_GONEGO_OK)
{
p2p_set_nego(p);
}
else
{
p2p_role(p,0);
if( p->role == P2P_ROLE_CLIENT )
{
p2p_client_mode(p);
}
else if( p->role == P2P_ROLE_GO )
{
p2p_go_mode(p);
}
}
}
else if( strncmp(scan, "c", 1) == 0 )
{
p->wps_info=2;
p2p_wpsinfo(p);
p2p_status(p, 0);
if(p->status != P2P_STATE_GONEGO_OK)
{
p2p_set_nego(p);
}
else
{
p2p_role(p,0);
p2p_ifaddr(p);
if( p->role == P2P_ROLE_CLIENT )
{
p2p_client_mode(p);
}
else if( p->role == P2P_ROLE_GO )
{
p2p_go_mode(p);
}
}
}
else if( ('0' <= *scan ) && ( *scan <= '9') )
{
printf("In passive pin code\n");
p->pin = atoi(scan);
p->wps_info=1;
p2p_wpsinfo(p);
p2p_set_nego(p);
}
}
else if( p->thread_trigger == THREAD_GO ) //Passive mode for user interface
{
p->thread_trigger = THREAD_NONE ;
if( strncmp(scan, "b", 1) == 0 )
{
p->wps_info=3;
p2p_wpsinfo(p);
}
else if( strncmp(scan, "c", 1) == 0 )
{
p->wps_info=2;
p2p_wpsinfo(p);
}
else if( ('0' <= *scan ) && ( *scan <= '9') )
{
printf("In passive pin code\n");
p->pin = atoi(scan);
p->wps_info=1;
p2p_wpsinfo(p);
}
p2p_go_mode(p);
}
}
while( 1 );
/* Disable P2P functionalities when exits*/
p->enable= -1 ;
p2p_enable(p);
system( "rm -f ./supp_status.txt" );
system( "rm -f ./temp.txt" );
system( "rm -f ./scan.txt" );
system( "rm -f ./peer.txt" );
system( "rm -f ./status.txt" );
system( "rm -f ./cm.txt" );
return 0;
}

View File

@ -0,0 +1,57 @@
diff -urN linux-3.0.42/include/net/cfg80211.h linux-3.0.42-patch/include/net/cfg80211.h
--- linux-3.0.42/include/net/cfg80211.h 2012-09-05 21:02:06.960467827 +0800
+++ linux-3.0.42-patch/include/net/cfg80211.h 2012-09-05 21:00:09.775049000 +0800
@@ -426,6 +426,7 @@
* @STATION_INFO_RX_BITRATE: @rxrate fields are filled
* @STATION_INFO_BSS_PARAM: @bss_param filled
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
+ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -444,7 +445,8 @@
STATION_INFO_SIGNAL_AVG = 1<<13,
STATION_INFO_RX_BITRATE = 1<<14,
STATION_INFO_BSS_PARAM = 1<<15,
- STATION_INFO_CONNECTED_TIME = 1<<16
+ STATION_INFO_CONNECTED_TIME = 1<<16,
+ STATION_INFO_ASSOC_REQ_IES = 1<<17
};
/**
@@ -536,6 +538,11 @@
* This number should increase every time the list of stations
* changes, i.e. when a station is added or removed, so that
* userspace can tell whether it got a consistent snapshot.
+ * @assoc_req_ies: IEs from (Re)Association Request.
+ * This is used only when in AP mode with drivers that do not use
+ * user space MLME/SME implementation. The information is provided for
+ * the cfg80211_new_sta() calls to notify user space of the IEs.
+ * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
*/
struct station_info {
u32 filled;
@@ -558,6 +565,9 @@
struct sta_bss_parameters bss_param;
int generation;
+
+ const u8 *assoc_req_ies;
+ size_t assoc_req_ies_len;
};
/**
diff -urN linux-3.0.42/net/wireless/nl80211.c linux-3.0.42-patch/net/wireless/nl80211.c
--- linux-3.0.42/net/wireless/nl80211.c 2012-09-05 21:03:25.528853240 +0800
+++ linux-3.0.42-patch/net/wireless/nl80211.c 2012-09-05 20:47:08.472824000 +0800
@@ -2213,6 +2213,10 @@
}
nla_nest_end(msg, sinfoattr);
+ if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
+ NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+ sinfo->assoc_req_ies);
+
return genlmsg_end(msg, hdr);
nla_put_failure:

View File

@ -0,0 +1,57 @@
diff -urN linux-3.0.42/include/net/cfg80211.h linux-3.0.42-patch/include/net/cfg80211.h
--- linux-3.0.42/include/net/cfg80211.h 2012-09-05 21:02:06.960467827 +0800
+++ linux-3.0.42-patch/include/net/cfg80211.h 2012-09-05 21:00:09.775049000 +0800
@@ -426,6 +426,7 @@
* @STATION_INFO_RX_BITRATE: @rxrate fields are filled
* @STATION_INFO_BSS_PARAM: @bss_param filled
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
+ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -444,7 +445,8 @@
STATION_INFO_SIGNAL_AVG = 1<<13,
STATION_INFO_RX_BITRATE = 1<<14,
STATION_INFO_BSS_PARAM = 1<<15,
- STATION_INFO_CONNECTED_TIME = 1<<16
+ STATION_INFO_CONNECTED_TIME = 1<<16,
+ STATION_INFO_ASSOC_REQ_IES = 1<<17
};
/**
@@ -536,6 +538,11 @@
* This number should increase every time the list of stations
* changes, i.e. when a station is added or removed, so that
* userspace can tell whether it got a consistent snapshot.
+ * @assoc_req_ies: IEs from (Re)Association Request.
+ * This is used only when in AP mode with drivers that do not use
+ * user space MLME/SME implementation. The information is provided for
+ * the cfg80211_new_sta() calls to notify user space of the IEs.
+ * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
*/
struct station_info {
u32 filled;
@@ -558,6 +565,9 @@
struct sta_bss_parameters bss_param;
int generation;
+
+ const u8 *assoc_req_ies;
+ size_t assoc_req_ies_len;
};
/**
diff -urN linux-3.0.42/net/wireless/nl80211.c linux-3.0.42-patch/net/wireless/nl80211.c
--- linux-3.0.42/net/wireless/nl80211.c 2012-09-05 21:03:25.528853240 +0800
+++ linux-3.0.42-patch/net/wireless/nl80211.c 2012-09-05 20:47:08.472824000 +0800
@@ -2213,6 +2213,10 @@
}
nla_nest_end(msg, sinfoattr);
+ if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
+ NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+ sinfo->assoc_req_ies);
+
return genlmsg_end(msg, hdr);
nla_put_failure:

View File

@ -0,0 +1,57 @@
diff -urN linux-3.0.42/include/net/cfg80211.h linux-3.0.42-patch/include/net/cfg80211.h
--- linux-3.0.42/include/net/cfg80211.h 2012-09-05 21:02:06.960467827 +0800
+++ linux-3.0.42-patch/include/net/cfg80211.h 2012-09-05 21:00:09.775049000 +0800
@@ -426,6 +426,7 @@
* @STATION_INFO_RX_BITRATE: @rxrate fields are filled
* @STATION_INFO_BSS_PARAM: @bss_param filled
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
+ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -444,7 +445,8 @@
STATION_INFO_SIGNAL_AVG = 1<<13,
STATION_INFO_RX_BITRATE = 1<<14,
STATION_INFO_BSS_PARAM = 1<<15,
- STATION_INFO_CONNECTED_TIME = 1<<16
+ STATION_INFO_CONNECTED_TIME = 1<<16,
+ STATION_INFO_ASSOC_REQ_IES = 1<<17
};
/**
@@ -536,6 +538,11 @@
* This number should increase every time the list of stations
* changes, i.e. when a station is added or removed, so that
* userspace can tell whether it got a consistent snapshot.
+ * @assoc_req_ies: IEs from (Re)Association Request.
+ * This is used only when in AP mode with drivers that do not use
+ * user space MLME/SME implementation. The information is provided for
+ * the cfg80211_new_sta() calls to notify user space of the IEs.
+ * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
*/
struct station_info {
u32 filled;
@@ -558,6 +565,9 @@
struct sta_bss_parameters bss_param;
int generation;
+
+ const u8 *assoc_req_ies;
+ size_t assoc_req_ies_len;
};
/**
diff -urN linux-3.0.42/net/wireless/nl80211.c linux-3.0.42-patch/net/wireless/nl80211.c
--- linux-3.0.42/net/wireless/nl80211.c 2012-09-05 21:03:25.528853240 +0800
+++ linux-3.0.42-patch/net/wireless/nl80211.c 2012-09-05 20:47:08.472824000 +0800
@@ -2213,6 +2213,10 @@
}
nla_nest_end(msg, sinfoattr);
+ if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
+ NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+ sinfo->assoc_req_ies);
+
return genlmsg_end(msg, hdr);
nla_put_failure:

View File

@ -0,0 +1,57 @@
diff -urN linux-3.0.42/include/net/cfg80211.h linux-3.0.42-patch/include/net/cfg80211.h
--- linux-3.0.42/include/net/cfg80211.h 2012-09-05 21:02:06.960467827 +0800
+++ linux-3.0.42-patch/include/net/cfg80211.h 2012-09-05 21:00:09.775049000 +0800
@@ -426,6 +426,7 @@
* @STATION_INFO_RX_BITRATE: @rxrate fields are filled
* @STATION_INFO_BSS_PARAM: @bss_param filled
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
+ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -444,7 +445,8 @@
STATION_INFO_SIGNAL_AVG = 1<<13,
STATION_INFO_RX_BITRATE = 1<<14,
STATION_INFO_BSS_PARAM = 1<<15,
- STATION_INFO_CONNECTED_TIME = 1<<16
+ STATION_INFO_CONNECTED_TIME = 1<<16,
+ STATION_INFO_ASSOC_REQ_IES = 1<<17
};
/**
@@ -536,6 +538,11 @@
* This number should increase every time the list of stations
* changes, i.e. when a station is added or removed, so that
* userspace can tell whether it got a consistent snapshot.
+ * @assoc_req_ies: IEs from (Re)Association Request.
+ * This is used only when in AP mode with drivers that do not use
+ * user space MLME/SME implementation. The information is provided for
+ * the cfg80211_new_sta() calls to notify user space of the IEs.
+ * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
*/
struct station_info {
u32 filled;
@@ -558,6 +565,9 @@
struct sta_bss_parameters bss_param;
int generation;
+
+ const u8 *assoc_req_ies;
+ size_t assoc_req_ies_len;
};
/**
diff -urN linux-3.0.42/net/wireless/nl80211.c linux-3.0.42-patch/net/wireless/nl80211.c
--- linux-3.0.42/net/wireless/nl80211.c 2012-09-05 21:03:25.528853240 +0800
+++ linux-3.0.42-patch/net/wireless/nl80211.c 2012-09-05 20:47:08.472824000 +0800
@@ -2213,6 +2213,10 @@
}
nla_nest_end(msg, sinfoattr);
+ if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
+ NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+ sinfo->assoc_req_ies);
+
return genlmsg_end(msg, hdr);
nla_put_failure:

View File

@ -0,0 +1,57 @@
diff -urN linux-3.0.42/include/net/cfg80211.h linux-3.0.42-patch/include/net/cfg80211.h
--- linux-3.0.42/include/net/cfg80211.h 2012-09-05 21:02:06.960467827 +0800
+++ linux-3.0.42-patch/include/net/cfg80211.h 2012-09-05 21:00:09.775049000 +0800
@@ -426,6 +426,7 @@
* @STATION_INFO_RX_BITRATE: @rxrate fields are filled
* @STATION_INFO_BSS_PARAM: @bss_param filled
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
+ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -444,7 +445,8 @@
STATION_INFO_SIGNAL_AVG = 1<<13,
STATION_INFO_RX_BITRATE = 1<<14,
STATION_INFO_BSS_PARAM = 1<<15,
- STATION_INFO_CONNECTED_TIME = 1<<16
+ STATION_INFO_CONNECTED_TIME = 1<<16,
+ STATION_INFO_ASSOC_REQ_IES = 1<<17
};
/**
@@ -536,6 +538,11 @@
* This number should increase every time the list of stations
* changes, i.e. when a station is added or removed, so that
* userspace can tell whether it got a consistent snapshot.
+ * @assoc_req_ies: IEs from (Re)Association Request.
+ * This is used only when in AP mode with drivers that do not use
+ * user space MLME/SME implementation. The information is provided for
+ * the cfg80211_new_sta() calls to notify user space of the IEs.
+ * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
*/
struct station_info {
u32 filled;
@@ -558,6 +565,9 @@
struct sta_bss_parameters bss_param;
int generation;
+
+ const u8 *assoc_req_ies;
+ size_t assoc_req_ies_len;
};
/**
diff -urN linux-3.0.42/net/wireless/nl80211.c linux-3.0.42-patch/net/wireless/nl80211.c
--- linux-3.0.42/net/wireless/nl80211.c 2012-09-05 21:03:25.528853240 +0800
+++ linux-3.0.42-patch/net/wireless/nl80211.c 2012-09-05 20:47:08.472824000 +0800
@@ -2213,6 +2213,10 @@
}
nla_nest_end(msg, sinfoattr);
+ if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
+ NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+ sinfo->assoc_req_ies);
+
return genlmsg_end(msg, hdr);
nla_put_failure:

View File

@ -0,0 +1,57 @@
diff -urN linux-3.0.42/include/net/cfg80211.h linux-3.0.42-patch/include/net/cfg80211.h
--- linux-3.0.42/include/net/cfg80211.h 2012-09-05 21:02:06.960467827 +0800
+++ linux-3.0.42-patch/include/net/cfg80211.h 2012-09-05 21:00:09.775049000 +0800
@@ -426,6 +426,7 @@
* @STATION_INFO_RX_BITRATE: @rxrate fields are filled
* @STATION_INFO_BSS_PARAM: @bss_param filled
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
+ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -444,7 +445,8 @@
STATION_INFO_SIGNAL_AVG = 1<<13,
STATION_INFO_RX_BITRATE = 1<<14,
STATION_INFO_BSS_PARAM = 1<<15,
- STATION_INFO_CONNECTED_TIME = 1<<16
+ STATION_INFO_CONNECTED_TIME = 1<<16,
+ STATION_INFO_ASSOC_REQ_IES = 1<<17
};
/**
@@ -536,6 +538,11 @@
* This number should increase every time the list of stations
* changes, i.e. when a station is added or removed, so that
* userspace can tell whether it got a consistent snapshot.
+ * @assoc_req_ies: IEs from (Re)Association Request.
+ * This is used only when in AP mode with drivers that do not use
+ * user space MLME/SME implementation. The information is provided for
+ * the cfg80211_new_sta() calls to notify user space of the IEs.
+ * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
*/
struct station_info {
u32 filled;
@@ -558,6 +565,9 @@
struct sta_bss_parameters bss_param;
int generation;
+
+ const u8 *assoc_req_ies;
+ size_t assoc_req_ies_len;
};
/**
diff -urN linux-3.0.42/net/wireless/nl80211.c linux-3.0.42-patch/net/wireless/nl80211.c
--- linux-3.0.42/net/wireless/nl80211.c 2012-09-05 21:03:25.528853240 +0800
+++ linux-3.0.42-patch/net/wireless/nl80211.c 2012-09-05 20:47:08.472824000 +0800
@@ -2213,6 +2213,10 @@
}
nla_nest_end(msg, sinfoattr);
+ if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
+ NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+ sinfo->assoc_req_ies);
+
return genlmsg_end(msg, hdr);
nla_put_failure:

View File

@ -0,0 +1,57 @@
diff -urN linux-3.0.42/include/net/cfg80211.h linux-3.0.42-patch/include/net/cfg80211.h
--- linux-3.0.42/include/net/cfg80211.h 2012-09-05 21:02:06.960467827 +0800
+++ linux-3.0.42-patch/include/net/cfg80211.h 2012-09-05 21:00:09.775049000 +0800
@@ -426,6 +426,7 @@
* @STATION_INFO_RX_BITRATE: @rxrate fields are filled
* @STATION_INFO_BSS_PARAM: @bss_param filled
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
+ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -444,7 +445,8 @@
STATION_INFO_SIGNAL_AVG = 1<<13,
STATION_INFO_RX_BITRATE = 1<<14,
STATION_INFO_BSS_PARAM = 1<<15,
- STATION_INFO_CONNECTED_TIME = 1<<16
+ STATION_INFO_CONNECTED_TIME = 1<<16,
+ STATION_INFO_ASSOC_REQ_IES = 1<<17
};
/**
@@ -536,6 +538,11 @@
* This number should increase every time the list of stations
* changes, i.e. when a station is added or removed, so that
* userspace can tell whether it got a consistent snapshot.
+ * @assoc_req_ies: IEs from (Re)Association Request.
+ * This is used only when in AP mode with drivers that do not use
+ * user space MLME/SME implementation. The information is provided for
+ * the cfg80211_new_sta() calls to notify user space of the IEs.
+ * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
*/
struct station_info {
u32 filled;
@@ -558,6 +565,9 @@
struct sta_bss_parameters bss_param;
int generation;
+
+ const u8 *assoc_req_ies;
+ size_t assoc_req_ies_len;
};
/**
diff -urN linux-3.0.42/net/wireless/nl80211.c linux-3.0.42-patch/net/wireless/nl80211.c
--- linux-3.0.42/net/wireless/nl80211.c 2012-09-05 21:03:25.528853240 +0800
+++ linux-3.0.42-patch/net/wireless/nl80211.c 2012-09-05 20:47:08.472824000 +0800
@@ -2213,6 +2213,10 @@
}
nla_nest_end(msg, sinfoattr);
+ if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
+ NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+ sinfo->assoc_req_ies);
+
return genlmsg_end(msg, hdr);
nla_put_failure:

View File

@ -0,0 +1,79 @@
##### hostapd configuration file ##############################################
interface=wlan0
ctrl_interface=/var/run/hostapd
ssid=DIRECT-RT
channel=6
wpa=2
wpa_passphrase=12345678
##### Wi-Fi Protected Setup (WPS) #############################################
eap_server=1
# WPS state
# 0 = WPS disabled (default)
# 1 = WPS enabled, not configured
# 2 = WPS enabled, configured
wps_state=2
uuid=12345678-9abc-def0-1234-56789abcdef0
# Device Name
# User-friendly description of device; up to 32 octets encoded in UTF-8
device_name=RTL8192CU
# Manufacturer
# The manufacturer of the device (up to 64 ASCII characters)
manufacturer=Realtek
# Model Name
# Model of the device (up to 32 ASCII characters)
model_name=RTW_SOFTAP
# Model Number
# Additional device description (up to 32 ASCII characters)
model_number=WLAN_CU
# Serial Number
# Serial number of the device (up to 32 characters)
serial_number=12345
# Primary Device Type
# Used format: <categ>-<OUI>-<subcateg>
# categ = Category as an integer value
# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
# default WPS OUI
# subcateg = OUI-specific Sub Category as an integer value
# Examples:
# 1-0050F204-1 (Computer / PC)
# 1-0050F204-2 (Computer / Server)
# 5-0050F204-1 (Storage / NAS)
# 6-0050F204-1 (Network Infrastructure / AP)
device_type=6-0050F204-1
# OS Version
# 4-octet operating system version number (hex string)
os_version=01020300
# Config Methods
# List of the supported configuration methods
config_methods=label display push_button keypad
##### default configuration #######################################
driver=rtl871xdrv
beacon_int=100
hw_mode=g
ieee80211n=1
wme_enabled=1
ht_capab=[SHORT-GI-20][SHORT-GI-40][HT40+]
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
max_num_sta=8
wpa_group_rekey=86400
supported_rates=60 90 120 180 240 360 480 540
basic_rates=60 120 240

View File

@ -0,0 +1,79 @@
##### hostapd configuration file ##############################################
interface=wlan0
ctrl_interface=/var/run/hostapd
ssid=rtwap
channel=6
wpa=2
wpa_passphrase=87654321
#bridge=br0
##### Wi-Fi Protected Setup (WPS) #############################################
eap_server=1
# WPS state
# 0 = WPS disabled (default)
# 1 = WPS enabled, not configured
# 2 = WPS enabled, configured
wps_state=2
uuid=12345678-9abc-def0-1234-56789abcdef0
# Device Name
# User-friendly description of device; up to 32 octets encoded in UTF-8
device_name=RTL8192CU
# Manufacturer
# The manufacturer of the device (up to 64 ASCII characters)
manufacturer=Realtek
# Model Name
# Model of the device (up to 32 ASCII characters)
model_name=RTW_SOFTAP
# Model Number
# Additional device description (up to 32 ASCII characters)
model_number=WLAN_CU
# Serial Number
# Serial number of the device (up to 32 characters)
serial_number=12345
# Primary Device Type
# Used format: <categ>-<OUI>-<subcateg>
# categ = Category as an integer value
# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
# default WPS OUI
# subcateg = OUI-specific Sub Category as an integer value
# Examples:
# 1-0050F204-1 (Computer / PC)
# 1-0050F204-2 (Computer / Server)
# 5-0050F204-1 (Storage / NAS)
# 6-0050F204-1 (Network Infrastructure / AP)
device_type=6-0050F204-1
# OS Version
# 4-octet operating system version number (hex string)
os_version=01020300
# Config Methods
# List of the supported configuration methods
config_methods=label display push_button keypad
##### default configuration #######################################
driver=rtl871xdrv
beacon_int=100
hw_mode=g
ieee80211n=1
wme_enabled=1
ht_capab=[SHORT-GI-20][SHORT-GI-40][HT40+]
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
max_num_sta=8
wpa_group_rekey=86400

View File

@ -0,0 +1,78 @@
##### hostapd configuration file ##############################################
interface=wlan0
ctrl_interface=/var/run/hostapd
ssid=rtwap
channel=36
wpa=2
wpa_passphrase=87654321
#bridge=br0
##### Wi-Fi Protected Setup (WPS) #############################################
eap_server=1
# WPS state
# 0 = WPS disabled (default)
# 1 = WPS enabled, not configured
# 2 = WPS enabled, configured
wps_state=2
uuid=12345678-9abc-def0-1234-56789abcdef0
# Device Name
# User-friendly description of device; up to 32 octets encoded in UTF-8
device_name=RTL8192CU
# Manufacturer
# The manufacturer of the device (up to 64 ASCII characters)
manufacturer=Realtek
# Model Name
# Model of the device (up to 32 ASCII characters)
model_name=RTW_SOFTAP
# Model Number
# Additional device description (up to 32 ASCII characters)
model_number=WLAN_CU
# Serial Number
# Serial number of the device (up to 32 characters)
serial_number=12345
# Primary Device Type
# Used format: <categ>-<OUI>-<subcateg>
# categ = Category as an integer value
# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
# default WPS OUI
# subcateg = OUI-specific Sub Category as an integer value
# Examples:
# 1-0050F204-1 (Computer / PC)
# 1-0050F204-2 (Computer / Server)
# 5-0050F204-1 (Storage / NAS)
# 6-0050F204-1 (Network Infrastructure / AP)
device_type=6-0050F204-1
# OS Version
# 4-octet operating system version number (hex string)
os_version=01020300
# Config Methods
# List of the supported configuration methods
config_methods=label display push_button keypad
##### default configuration #######################################
driver=rtl871xdrv
beacon_int=100
hw_mode=a
ieee80211n=1
wme_enabled=1
ht_capab=[SHORT-GI-20][SHORT-GI-40][HT40+]
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
max_num_sta=8
wpa_group_rekey=86400

View File

@ -0,0 +1,51 @@
ctrl_interface=/var/run/wpa_supplicant
update_config=1
# Wi-Fi Protected Setup (WPS) parameters
# Device Name
# User-friendly description of device; up to 32 octets encoded in UTF-8
device_name=RTL8192CU
# Manufacturer
# The manufacturer of the device (up to 64 ASCII characters)
manufacturer=Realtek
# Model Name
# Model of the device (up to 32 ASCII characters)
model_name=RTW_STA
# Model Number
# Additional device description (up to 32 ASCII characters)
model_number=WLAN_CU
# Serial Number
# Serial number of the device (up to 32 characters)
serial_number=12345
# Primary Device Type
# Used format: <categ>-<OUI>-<subcateg>
# categ = Category as an integer value
# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
# default WPS OUI
# subcateg = OUI-specific Sub Category as an integer value
# Examples:
# 1-0050F204-1 (Computer / PC)
# 1-0050F204-2 (Computer / Server)
# 5-0050F204-1 (Storage / NAS)
# 6-0050F204-1 (Network Infrastructure / AP)
device_type=1-0050F204-1
# OS Version
# 4-octet operating system version number (hex string)
os_version=01020300
# Config Methods
# List of the supported configuration methods
# Available methods: usba ethernet label display ext_nfc_token int_nfc_token
# nfc_interface push_button keypad virtual_display physical_display
# virtual_push_button physical_push_button
# For WSC 1.0:
#config_methods=display push_button keypad
# For WSC 2.0:
config_methods=virtual_display virtual_push_button keypad

3278
core/efuse/rtw_efuse.c Normal file

File diff suppressed because it is too large Load Diff

4080
core/mesh/rtw_mesh.c Normal file

File diff suppressed because it is too large Load Diff

534
core/mesh/rtw_mesh.h Normal file
View File

@ -0,0 +1,534 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __RTW_MESH_H_
#define __RTW_MESH_H_
#ifndef CONFIG_AP_MODE
#error "CONFIG_RTW_MESH can't be enabled when CONFIG_AP_MODE is not defined\n"
#endif
#define RTW_MESH_TTL 31
#define RTW_MESH_PERR_MIN_INT 100
#define RTW_MESH_DEFAULT_ELEMENT_TTL 31
#define RTW_MESH_RANN_INTERVAL 5000
#define RTW_MESH_PATH_TO_ROOT_TIMEOUT 6000
#define RTW_MESH_DIAM_TRAVERSAL_TIME 50
#define RTW_MESH_PATH_TIMEOUT 5000
#define RTW_MESH_PREQ_MIN_INT 10
#define RTW_MESH_MAX_PREQ_RETRIES 4
#define RTW_MESH_MIN_DISCOVERY_TIMEOUT (2 * RTW_MESH_DIAM_TRAVERSAL_TIME)
#define RTW_MESH_ROOT_CONFIRMATION_INTERVAL 2000
#define RTW_MESH_PATH_REFRESH_TIME 1000
#define RTW_MESH_ROOT_INTERVAL 5000
#define RTW_MESH_SANE_METRIC_DELTA 100
#define RTW_MESH_MAX_ROOT_ADD_CHK_CNT 2
#define RTW_MESH_PLINK_UNKNOWN 0
#define RTW_MESH_PLINK_LISTEN 1
#define RTW_MESH_PLINK_OPN_SNT 2
#define RTW_MESH_PLINK_OPN_RCVD 3
#define RTW_MESH_PLINK_CNF_RCVD 4
#define RTW_MESH_PLINK_ESTAB 5
#define RTW_MESH_PLINK_HOLDING 6
#define RTW_MESH_PLINK_BLOCKED 7
extern const char *_rtw_mesh_plink_str[];
#define rtw_mesh_plink_str(s) ((s <= RTW_MESH_PLINK_BLOCKED) ? _rtw_mesh_plink_str[s] : _rtw_mesh_plink_str[RTW_MESH_PLINK_UNKNOWN])
#define RTW_MESH_PS_UNKNOWN 0
#define RTW_MESH_PS_ACTIVE 1
#define RTW_MESH_PS_LSLEEP 2
#define RTW_MESH_PS_DSLEEP 3
extern const char *_rtw_mesh_ps_str[];
#define rtw_mesh_ps_str(mps) ((mps <= RTW_MESH_PS_DSLEEP) ? _rtw_mesh_ps_str[mps] : _rtw_mesh_ps_str[RTW_MESH_PS_UNKNOWN])
#define GET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 0, 0, 8)
#define GET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 1, 0, 8)
#define GET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 2, 0, 8)
#define GET_MESH_CONF_ELE_SYNC_METHOD_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 3, 0, 8)
#define GET_MESH_CONF_ELE_AUTH_PROTO_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 4, 0, 8)
#define GET_MESH_CONF_ELE_MESH_FORMATION(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 5, 0, 8)
#define GET_MESH_CONF_ELE_CTO_MGATE(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 5, 0, 1)
#define GET_MESH_CONF_ELE_NUM_OF_PEERINGS(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 5, 1, 6)
#define GET_MESH_CONF_ELE_CTO_AS(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 5, 7, 1)
#define GET_MESH_CONF_ELE_MESH_CAP(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 0, 8)
#define GET_MESH_CONF_ELE_ACCEPT_PEERINGS(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 0, 1)
#define GET_MESH_CONF_ELE_MCCA_SUP(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 1, 1)
#define GET_MESH_CONF_ELE_MCCA_EN(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 2, 1)
#define GET_MESH_CONF_ELE_FORWARDING(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 3, 1)
#define GET_MESH_CONF_ELE_MBCA_EN(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 4, 1)
#define GET_MESH_CONF_ELE_TBTT_ADJ(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 5, 1)
#define GET_MESH_CONF_ELE_PS_LEVEL(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 6, 1)
#define SET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 0, 0, 8, _val)
#define SET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 1, 0, 8, _val)
#define SET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 2, 0, 8, _val)
#define SET_MESH_CONF_ELE_SYNC_METHOD_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 3, 0, 8, _val)
#define SET_MESH_CONF_ELE_AUTH_PROTO_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 4, 0, 8, _val)
#define SET_MESH_CONF_ELE_CTO_MGATE(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 5, 0, 1, _val)
#define SET_MESH_CONF_ELE_NUM_OF_PEERINGS(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 5, 1, 6, _val)
#define SET_MESH_CONF_ELE_CTO_AS(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 5, 7, 1, _val)
#define SET_MESH_CONF_ELE_ACCEPT_PEERINGS(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 0, 1, _val)
#define SET_MESH_CONF_ELE_MCCA_SUP(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 1, 1, _val)
#define SET_MESH_CONF_ELE_MCCA_EN(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 2, 1, _val)
#define SET_MESH_CONF_ELE_FORWARDING(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 3, 1, _val)
#define SET_MESH_CONF_ELE_MBCA_EN(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 4, 1, _val)
#define SET_MESH_CONF_ELE_TBTT_ADJ(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 5, 1, _val)
#define SET_MESH_CONF_ELE_PS_LEVEL(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 6, 1, _val)
/* Mesh flags */
#define MESH_FLAGS_AE 0x3 /* mask */
#define MESH_FLAGS_AE_A4 0x1
#define MESH_FLAGS_AE_A5_A6 0x2
/* Max number of paths */
#define RTW_MESH_MAX_PATHS 1024
#define RTW_PREQ_Q_F_START 0x1
#define RTW_PREQ_Q_F_REFRESH 0x2
#define RTW_PREQ_Q_F_CHK 0x4
#define RTW_PREQ_Q_F_PEER_AKA 0x8
struct rtw_mesh_preq_queue {
_list list;
u8 dst[ETH_ALEN];
u8 flags;
};
extern const u8 ae_to_mesh_ctrl_len[];
enum mesh_frame_type {
MESH_UCAST_DATA = 0x0,
MESH_BMCAST_DATA = 0x1,
MESH_UCAST_PX_DATA = 0x2,
MESH_BMCAST_PX_DATA = 0x3,
MESH_MHOP_UCAST_ACT = 0x4,
MESH_MHOP_BMCAST_ACT = 0x5,
};
enum mpath_sel_frame_type {
MPATH_PREQ = 0,
MPATH_PREP,
MPATH_PERR,
MPATH_RANN
};
/**
* enum rtw_mesh_deferred_task_flags - mesh deferred tasks
*
*
*
* @RTW_MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks
* @RTW_MESH_WORK_ROOT: the mesh root station needs to send a frame
* @RTW_MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other
* mesh nodes
* @RTW_MESH_WORK_MBSS_CHANGED: rebuild beacon and notify driver of BSS changes
*/
enum rtw_mesh_deferred_task_flags {
RTW_MESH_WORK_HOUSEKEEPING,
RTW_MESH_WORK_ROOT,
RTW_MESH_WORK_DRIFT_ADJUST,
RTW_MESH_WORK_MBSS_CHANGED,
};
#define RTW_MESH_MAX_PEER_CANDIDATES 15 /* aid consideration */
#define RTW_MESH_MAX_PEER_LINKS 8
#define RTW_MESH_PEER_LINK_TIMEOUT 20
#define RTW_MESH_PEER_CONF_DISABLED 0 /* special time value means no confirmation ongoing */
#if CONFIG_RTW_MESH_PEER_BLACKLIST
#define IS_PEER_CONF_DISABLED(plink) ((plink)->peer_conf_end_time == RTW_MESH_PEER_CONF_DISABLED)
#define IS_PEER_CONF_TIMEOUT(plink)(!IS_PEER_CONF_DISABLED(plink) && rtw_time_after(rtw_get_current_time(), (plink)->peer_conf_end_time))
#define SET_PEER_CONF_DISABLED(plink) (plink)->peer_conf_end_time = RTW_MESH_PEER_CONF_DISABLED
#define SET_PEER_CONF_END_TIME(plink, timeout_ms) \
do { \
(plink)->peer_conf_end_time = rtw_get_current_time() + rtw_ms_to_systime(timeout_ms); \
if ((plink)->peer_conf_end_time == RTW_MESH_PEER_CONF_DISABLED) \
(plink)->peer_conf_end_time++; \
} while (0)
#else
#define IS_PEER_CONF_DISABLED(plink) 1
#define IS_PEER_CONF_TIMEOUT(plink) 0
#define SET_PEER_CONF_DISABLED(plink) do {} while (0)
#define SET_PEER_CONF_END_TIME(plink, timeout_ms) do {} while (0)
#endif /* CONFIG_RTW_MESH_PEER_BLACKLIST */
#define RTW_MESH_CTO_MGATE_CONF_DISABLED 0 /* special time value means no confirmation ongoing */
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
#define IS_CTO_MGATE_CONF_DISABLED(plink) ((plink)->cto_mgate_conf_end_time == RTW_MESH_CTO_MGATE_CONF_DISABLED)
#define IS_CTO_MGATE_CONF_TIMEOUT(plink)(!IS_CTO_MGATE_CONF_DISABLED(plink) && rtw_time_after(rtw_get_current_time(), (plink)->cto_mgate_conf_end_time))
#define SET_CTO_MGATE_CONF_DISABLED(plink) (plink)->cto_mgate_conf_end_time = RTW_MESH_CTO_MGATE_CONF_DISABLED
#define SET_CTO_MGATE_CONF_END_TIME(plink, timeout_ms) \
do { \
(plink)->cto_mgate_conf_end_time = rtw_get_current_time() + rtw_ms_to_systime(timeout_ms); \
if ((plink)->cto_mgate_conf_end_time == RTW_MESH_CTO_MGATE_CONF_DISABLED) \
(plink)->cto_mgate_conf_end_time++; \
} while (0)
#else
#define IS_CTO_MGATE_CONF_DISABLED(plink) 1
#define IS_CTO_MGATE_CONF_TIMEOUT(plink) 0
#define SET_CTO_MGATE_CONF_DISABLED(plink) do {} while (0)
#define SET_CTO_MGATE_CONF_END_TIME(plink, timeout_ms) do {} while (0)
#endif /* CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST */
struct mesh_plink_ent {
u8 valid;
u8 addr[ETH_ALEN];
u8 plink_state;
#ifdef CONFIG_RTW_MESH_AEK
u8 aek_valid;
u8 aek[32];
#endif
u16 llid;
u16 plid;
#ifndef CONFIG_RTW_MESH_DRIVER_AID
u16 aid; /* aid assigned from upper layer */
#endif
u16 peer_aid; /* aid assigned from peer */
u8 chosen_pmk[16];
#ifdef CONFIG_RTW_MESH_AEK
u8 sel_pcs[4];
u8 l_nonce[32];
u8 p_nonce[32];
#endif
#ifdef CONFIG_RTW_MESH_DRIVER_AID
u8 *tx_conf_ies;
u16 tx_conf_ies_len;
#endif
u8 *rx_conf_ies;
u16 rx_conf_ies_len;
struct wlan_network *scanned;
#if CONFIG_RTW_MESH_PEER_BLACKLIST
systime peer_conf_end_time;
#endif
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
systime cto_mgate_conf_end_time;
#endif
};
#ifdef CONFIG_RTW_MESH_AEK
#define MESH_PLINK_AEK_VALID(ent) ent->aek_valid
#else
#define MESH_PLINK_AEK_VALID(ent) 0
#endif
struct mesh_plink_pool {
_lock lock;
u8 num; /* current ent being used */
struct mesh_plink_ent ent[RTW_MESH_MAX_PEER_CANDIDATES];
#if CONFIG_RTW_MESH_ACNODE_PREVENT
u8 acnode_rsvd;
#endif
#if CONFIG_RTW_MESH_PEER_BLACKLIST
_queue peer_blacklist;
#endif
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
_queue cto_mgate_blacklist;
#endif
};
struct mesh_peer_sel_policy {
u32 scanr_exp_ms;
#if CONFIG_RTW_MESH_ACNODE_PREVENT
u8 acnode_prevent;
u32 acnode_conf_timeout_ms;
u32 acnode_notify_timeout_ms;
#endif
#if CONFIG_RTW_MESH_OFFCH_CAND
u8 offch_cand;
u32 offch_find_int_ms; /* 0 means no offch find triggerred by driver self*/
#endif
#if CONFIG_RTW_MESH_PEER_BLACKLIST
u32 peer_conf_timeout_ms;
u32 peer_blacklist_timeout_ms;
#endif
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
u8 cto_mgate_require;
u32 cto_mgate_conf_timeout_ms;
u32 cto_mgate_blacklist_timeout_ms;
#endif
};
/* b2u flags */
#define RTW_MESH_B2U_ALL BIT0
#define RTW_MESH_B2U_GA_UCAST BIT1 /* Group addressed unicast frame, forward only */
#define RTW_MESH_B2U_BCAST BIT2
#define RTW_MESH_B2U_IP_MCAST BIT3
#define rtw_msrc_b2u_policy_chk(flags, mda) ( \
(flags & RTW_MESH_B2U_ALL) \
|| ((flags & RTW_MESH_B2U_BCAST) && is_broadcast_mac_addr(mda)) \
|| ((flags & RTW_MESH_B2U_IP_MCAST) && (IP_MCAST_MAC(mda) || ICMPV6_MCAST_MAC(mda))) \
)
#define rtw_mfwd_b2u_policy_chk(flags, mda, ucst) ( \
(flags & RTW_MESH_B2U_ALL) \
|| ((flags & RTW_MESH_B2U_GA_UCAST) && ucst) \
|| ((flags & RTW_MESH_B2U_BCAST) && is_broadcast_mac_addr(mda)) \
|| ((flags & RTW_MESH_B2U_IP_MCAST) && (IP_MCAST_MAC(mda) || ICMPV6_MCAST_MAC(mda))) \
)
/**
* @sane_metric_delta: Controlling if trigger additional path check mechanism
* @max_root_add_chk_cnt: The retry cnt to send additional root confirmation
* PREQ through old(last) path
*/
struct rtw_mesh_cfg {
u8 max_peer_links; /* peering limit */
u32 plink_timeout; /* seconds */
u8 dot11MeshTTL;
u8 element_ttl;
u32 path_refresh_time;
u16 dot11MeshHWMPpreqMinInterval;
u16 dot11MeshHWMPnetDiameterTraversalTime;
u32 dot11MeshHWMPactivePathTimeout;
u8 dot11MeshHWMPmaxPREQretries;
u16 min_discovery_timeout;
u16 dot11MeshHWMPconfirmationInterval;
u16 dot11MeshHWMPperrMinInterval;
u8 dot11MeshHWMPRootMode;
BOOLEAN dot11MeshForwarding;
s32 rssi_threshold; /* in dBm, 0: no specified */
u16 dot11MeshHWMPRannInterval;
BOOLEAN dot11MeshGateAnnouncementProtocol;
u32 dot11MeshHWMPactivePathToRootTimeout;
u16 dot11MeshHWMProotInterval;
u8 path_gate_timeout_factor;
#ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
u16 sane_metric_delta;
u8 max_root_add_chk_cnt;
#endif
struct mesh_peer_sel_policy peer_sel_policy;
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
u8 b2u_flags_msrc;
u8 b2u_flags_mfwd;
#endif
};
struct rtw_mesh_stats {
u32 fwded_mcast; /* Mesh forwarded multicast frames */
u32 fwded_unicast; /* Mesh forwarded unicast frames */
u32 fwded_frames; /* Mesh total forwarded frames */
u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/
u32 dropped_frames_no_route; /* Not transmitted, no route found */
u32 dropped_frames_congestion;/* Not forwarded due to congestion */
u32 dropped_frames_duplicate;
u32 mrc_del_qlen; /* MRC entry deleted cause by queue length limit */
};
struct rtw_mrc;
struct rtw_mesh_info {
u8 mesh_id[NDIS_802_11_LENGTH_SSID];
size_t mesh_id_len;
/* Active Path Selection Protocol Identifier */
u8 mesh_pp_id;
/* Active Path Selection Metric Identifier */
u8 mesh_pm_id;
/* Congestion Control Mode Identifier */
u8 mesh_cc_id;
/* Synchronization Protocol Identifier */
u8 mesh_sp_id;
/* Authentication Protocol Identifier */
u8 mesh_auth_id;
struct mesh_plink_pool plink_ctl;
u32 mesh_seqnum;
/* MSTA's own hwmp sequence number */
u32 sn;
systime last_preq;
systime last_sn_update;
systime next_perr;
/* Last used Path Discovery ID */
u32 preq_id;
ATOMIC_T mpaths;
struct rtw_mesh_table *mesh_paths;
struct rtw_mesh_table *mpp_paths;
int mesh_paths_generation;
int mpp_paths_generation;
int num_gates;
struct rtw_mesh_path *max_addr_gate;
bool max_addr_gate_is_larger_than_self;
struct rtw_mesh_stats mshstats;
_queue mpath_tx_queue;
u32 mpath_tx_queue_len;
struct tasklet_struct mpath_tx_tasklet;
struct rtw_mrc *mrc;
_lock mesh_preq_queue_lock;
struct rtw_mesh_preq_queue preq_queue;
int preq_queue_len;
};
extern const char *_action_self_protected_str[];
#define action_self_protected_str(action) ((action < RTW_ACT_SELF_PROTECTED_NUM) ? _action_self_protected_str[action] : _action_self_protected_str[0])
u8 *rtw_set_ie_mesh_id(u8 *buf, u32 *buf_len, const char *mesh_id, u8 id_len);
u8 *rtw_set_ie_mesh_config(u8 *buf, u32 *buf_len
, u8 path_sel_proto, u8 path_sel_metric, u8 congest_ctl_mode, u8 sync_method, u8 auth_proto
, u8 num_of_peerings, bool cto_mgate, bool cto_as
, bool accept_peerings, bool mcca_sup, bool mcca_en, bool forwarding
, bool mbca_en, bool tbtt_adj, bool ps_level);
int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b);
int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u8 ch, u8 add_peer);
void rtw_chk_candidate_peer_notify(_adapter *adapter, struct wlan_network *scanned);
void rtw_mesh_peer_status_chk(_adapter *adapter);
#if CONFIG_RTW_MESH_ACNODE_PREVENT
void rtw_mesh_update_scanned_acnode_status(_adapter *adapter, struct wlan_network *scanned);
bool rtw_mesh_scanned_is_acnode_confirmed(_adapter *adapter, struct wlan_network *scanned);
bool rtw_mesh_acnode_prevent_allow_sacrifice(_adapter *adapter);
struct sta_info *rtw_mesh_acnode_prevent_pick_sacrifice(_adapter *adapter);
void dump_mesh_acnode_prevent_settings(void *sel, _adapter *adapter);
#endif
#if CONFIG_RTW_MESH_OFFCH_CAND
u8 rtw_mesh_offch_candidate_accepted(_adapter *adapter);
u8 rtw_mesh_select_operating_ch(_adapter *adapter);
void dump_mesh_offch_cand_settings(void *sel, _adapter *adapter);
#endif
#if CONFIG_RTW_MESH_PEER_BLACKLIST
int rtw_mesh_peer_blacklist_add(_adapter *adapter, const u8 *addr);
int rtw_mesh_peer_blacklist_del(_adapter *adapter, const u8 *addr);
int rtw_mesh_peer_blacklist_search(_adapter *adapter, const u8 *addr);
void rtw_mesh_peer_blacklist_flush(_adapter *adapter);
void dump_mesh_peer_blacklist(void *sel, _adapter *adapter);
void dump_mesh_peer_blacklist_settings(void *sel, _adapter *adapter);
#endif
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
u8 rtw_mesh_cto_mgate_required(_adapter *adapter);
u8 rtw_mesh_cto_mgate_network_filter(_adapter *adapter, struct wlan_network *scanned);
int rtw_mesh_cto_mgate_blacklist_add(_adapter *adapter, const u8 *addr);
int rtw_mesh_cto_mgate_blacklist_del(_adapter *adapter, const u8 *addr);
int rtw_mesh_cto_mgate_blacklist_search(_adapter *adapter, const u8 *addr);
void rtw_mesh_cto_mgate_blacklist_flush(_adapter *adapter);
void dump_mesh_cto_mgate_blacklist(void *sel, _adapter *adapter);
void dump_mesh_cto_mgate_blacklist_settings(void *sel, _adapter *adapter);
#endif
void dump_mesh_peer_sel_policy(void *sel, _adapter *adapter);
void dump_mesh_networks(void *sel, _adapter *adapter);
void rtw_mesh_adjust_chbw(u8 req_ch, u8 *req_bw, u8 *req_offset);
void rtw_mesh_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx, u16 alg, u16 seq, u16 status);
int rtw_mesh_check_frames_tx(_adapter *adapter, const u8 **buf, size_t *len);
int rtw_mesh_check_frames_rx(_adapter *adapter, const u8 *buf, size_t len);
int rtw_mesh_on_auth(_adapter *adapter, union recv_frame *rframe);
unsigned int on_action_self_protected(_adapter *adapter, union recv_frame *rframe);
bool rtw_mesh_update_bss_peering_status(_adapter *adapter, WLAN_BSSID_EX *bss);
bool rtw_mesh_update_bss_formation_info(_adapter *adapter, WLAN_BSSID_EX *bss);
bool rtw_mesh_update_bss_forwarding_state(_adapter *adapter, WLAN_BSSID_EX *bss);
struct mesh_plink_ent *_rtw_mesh_plink_get(_adapter *adapter, const u8 *hwaddr);
struct mesh_plink_ent *rtw_mesh_plink_get(_adapter *adapter, const u8 *hwaddr);
struct mesh_plink_ent *rtw_mesh_plink_get_no_estab_by_idx(_adapter *adapter, u8 idx);
int _rtw_mesh_plink_add(_adapter *adapter, const u8 *hwaddr);
int rtw_mesh_plink_add(_adapter *adapter, const u8 *hwaddr);
int rtw_mesh_plink_set_state(_adapter *adapter, const u8 *hwaddr, u8 state);
#ifdef CONFIG_RTW_MESH_AEK
int rtw_mesh_plink_set_aek(_adapter *adapter, const u8 *hwaddr, const u8 *aek);
#endif
#if CONFIG_RTW_MESH_PEER_BLACKLIST
int rtw_mesh_plink_set_peer_conf_timeout(_adapter *adapter, const u8 *hwaddr);
#endif
void _rtw_mesh_plink_del_ent(_adapter *adapter, struct mesh_plink_ent *ent);
int rtw_mesh_plink_del(_adapter *adapter, const u8 *hwaddr);
void rtw_mesh_plink_ctl_init(_adapter *adapter);
void rtw_mesh_plink_ctl_deinit(_adapter *adapter);
void dump_mesh_plink_ctl(void *sel, _adapter *adapter);
int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta);
void _rtw_mesh_expire_peer_ent(_adapter *adapter, struct mesh_plink_ent *plink);
void rtw_mesh_expire_peer(_adapter *adapter, const u8 *peer_addr);
u8 rtw_mesh_ps_annc(_adapter *adapter, u8 ps);
unsigned int on_action_mesh(_adapter *adapter, union recv_frame *rframe);
void rtw_mesh_cfg_init(_adapter *adapter);
void rtw_mesh_cfg_init_max_peer_links(_adapter *adapter, u8 stack_conf);
void rtw_mesh_cfg_init_plink_timeout(_adapter *adapter, u32 stack_conf);
void rtw_mesh_init_mesh_info(_adapter *adapter);
void rtw_mesh_deinit_mesh_info(_adapter *adapter);
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
void dump_mesh_b2u_flags(void *sel, _adapter *adapter);
#endif
int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list);
s8 rtw_mesh_tx_set_whdr_mctrl_len(u8 mesh_frame_mode, struct pkt_attrib *attrib);
void rtw_mesh_tx_build_mctrl(_adapter *adapter, struct pkt_attrib *attrib, u8 *buf);
u8 rtw_mesh_tx_build_whdr(_adapter *adapter, struct pkt_attrib *attrib
, u16 *fctrl, struct rtw_ieee80211_hdr *whdr);
int rtw_mesh_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta);
int rtw_mesh_rx_data_validate_mctrl(_adapter *adapter, union recv_frame *rframe
, const struct rtw_ieee80211s_hdr *mctrl, const u8 *mda, const u8 *msa
, u8 *mctrl_len, const u8 **da, const u8 **sa);
int rtw_mesh_rx_validate_mctrl_non_amsdu(_adapter *adapter, union recv_frame *rframe);
int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe
, const u8 *mda, const u8 *msa
, const u8 *da, const u8 *sa
, struct rtw_ieee80211s_hdr *mctrl
, struct xmit_frame **fwd_frame, _list *b2u_list);
void dump_mesh_stats(void *sel, _adapter *adapter);
#if defined(PLATFORM_LINUX) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
#define rtw_lockdep_assert_held(l) lockdep_assert_held(l)
#define rtw_lockdep_is_held(l) lockdep_is_held(l)
#else
#error "TBD\n"
#endif
#include "rtw_mesh_pathtbl.h"
#include "rtw_mesh_hwmp.h"
#endif /* __RTW_MESH_H_ */

1665
core/mesh/rtw_mesh_hwmp.c Normal file

File diff suppressed because it is too large Load Diff

60
core/mesh/rtw_mesh_hwmp.h Normal file
View File

@ -0,0 +1,60 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __RTW_MESH_HWMP_H_
#define __RTW_MESH_HWMP_H_
#ifndef DBG_RTW_HWMP
#define DBG_RTW_HWMP 0
#endif
#if DBG_RTW_HWMP
#define RTW_HWMP_DBG(fmt, arg...) RTW_PRINT(fmt, ##arg)
#else
#define RTW_HWMP_DBG(fmt, arg...) RTW_DBG(fmt, ##arg)
#endif
#ifndef INFO_RTW_HWMP
#define INFO_RTW_HWMP 0
#endif
#if INFO_RTW_HWMP
#define RTW_HWMP_INFO(fmt, arg...) RTW_PRINT(fmt, ##arg)
#else
#define RTW_HWMP_INFO(fmt, arg...) RTW_INFO(fmt, ##arg)
#endif
void rtw_ewma_err_rate_init(struct rtw_ewma_err_rate *e);
unsigned long rtw_ewma_err_rate_read(struct rtw_ewma_err_rate *e);
void rtw_ewma_err_rate_add(struct rtw_ewma_err_rate *e, unsigned long val);
int rtw_mesh_path_error_tx(_adapter *adapter,
u8 ttl, const u8 *target, u32 target_sn,
u16 target_rcode, const u8 *ra);
void rtw_ieee80211s_update_metric(_adapter *adapter, u8 mac_id,
u8 per, u8 rate,
u8 bw, u8 total_pkt);
void rtw_mesh_rx_path_sel_frame(_adapter *adapter, union recv_frame *rframe);
void rtw_mesh_queue_preq(struct rtw_mesh_path *mpath, u8 flags);
void rtw_mesh_path_start_discovery(_adapter *adapter);
void rtw_mesh_path_timer(void *ctx);
void rtw_mesh_path_tx_root_frame(_adapter *adapter);
void rtw_mesh_work_hdl(_workitem *work);
void rtw_ieee80211_mesh_path_timer(void *ctx);
void rtw_ieee80211_mesh_path_root_timer(void *ctx);
BOOLEAN rtw_ieee80211_mesh_root_setup(_adapter *adapter);
void rtw_mesh_work(_workitem *work);
void rtw_mesh_atlm_param_req_timer(void *ctx);
#endif /* __RTW_MESH_HWMP_H_ */

1237
core/mesh/rtw_mesh_pathtbl.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,208 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __RTW_MESH_PATHTBL_H_
#define __RTW_MESH_PATHTBL_H_
#ifndef DBG_RTW_MPATH
#define DBG_RTW_MPATH 1
#endif
#if DBG_RTW_MPATH
#define RTW_MPATH_DBG(fmt, arg...) RTW_PRINT(fmt, ##arg)
#else
#define RTW_MPATH_DBG(fmt, arg...) do {} while (0)
#endif
/**
* enum rtw_mesh_path_flags - mesh path flags
*
* @RTW_MESH_PATH_ACTIVE: the mesh path can be used for forwarding
* @RTW_MESH_PATH_RESOLVING: the discovery process is running for this mesh path
* @RTW_MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence
* number
* @RTW_MESH_PATH_FIXED: the mesh path has been manually set and should not be
* modified
* @RTW_MESH_PATH_RESOLVED: the mesh path can has been resolved
* @RTW_MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination
* already queued up, waiting for the discovery process to start.
* @RTW_MESH_PATH_DELETED: the mesh path has been deleted and should no longer
* be used
* @RTW_MESH_PATH_ROOT_ADD_CHK: root additional check in root mode.
* With this flag, It will try the last used rann_snd_addr
* @RTW_MESH_PATH_PEER_AKA: only used toward a peer, only used in active keep
* alive mechanism. PREQ's da = path dst
*
* RTW_MESH_PATH_RESOLVED is used by the mesh path timer to
* decide when to stop or cancel the mesh path discovery.
*/
enum rtw_mesh_path_flags {
RTW_MESH_PATH_ACTIVE = BIT(0),
RTW_MESH_PATH_RESOLVING = BIT(1),
RTW_MESH_PATH_SN_VALID = BIT(2),
RTW_MESH_PATH_FIXED = BIT(3),
RTW_MESH_PATH_RESOLVED = BIT(4),
RTW_MESH_PATH_REQ_QUEUED = BIT(5),
RTW_MESH_PATH_DELETED = BIT(6),
RTW_MESH_PATH_ROOT_ADD_CHK = BIT(7),
RTW_MESH_PATH_PEER_AKA = BIT(8),
};
/**
* struct rtw_mesh_path - mesh path structure
*
* @dst: mesh path destination mac address
* @mpp: mesh proxy mac address
* @rhash: rhashtable list pointer
* @gate_list: list pointer for known gates list
* @sdata: mesh subif
* @next_hop: mesh neighbor to which frames for this destination will be
* forwarded
* @timer: mesh path discovery timer
* @frame_queue: pending queue for frames sent to this destination while the
* path is unresolved
* @rcu: rcu head for freeing mesh path
* @sn: target sequence number
* @metric: current metric to this destination
* @hop_count: hops to destination
* @exp_time: in jiffies, when the path will expire or when it expired
* @discovery_timeout: timeout (lapse in jiffies) used for the last discovery
* retry
* @discovery_retries: number of discovery retries
* @flags: mesh path flags, as specified on &enum rtw_mesh_path_flags
* @state_lock: mesh path state lock used to protect changes to the
* mpath itself. No need to take this lock when adding or removing
* an mpath to a hash bucket on a path table.
* @rann_snd_addr: the RANN sender address
* @rann_metric: the aggregated path metric towards the root node
* @last_preq_to_root: Timestamp of last PREQ sent to root
* @is_root: the destination station of this path is a root node
* @is_gate: the destination station of this path is a mesh gate
*
*
* The dst address is unique in the mesh path table. Since the mesh_path is
* protected by RCU, deleting the next_hop STA must remove / substitute the
* mesh_path structure and wait until that is no longer reachable before
* destroying the STA completely.
*/
struct rtw_mesh_path {
u8 dst[ETH_ALEN];
u8 mpp[ETH_ALEN]; /* used for MPP or MAP */
rtw_rhash_head rhash;
rtw_hlist_node gate_list;
_adapter *adapter;
struct sta_info __rcu *next_hop;
_timer timer;
_queue frame_queue;
u32 frame_queue_len;
rtw_rcu_head rcu;
u32 sn;
u32 metric;
u8 hop_count;
systime exp_time;
systime discovery_timeout;
systime gate_timeout;
u32 gate_ann_int; /* gate announce interval */
u8 discovery_retries;
enum rtw_mesh_path_flags flags;
_lock state_lock;
u8 rann_snd_addr[ETH_ALEN];
#ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
u8 add_chk_rann_snd_addr[ETH_ALEN];
#endif
u32 rann_metric;
unsigned long last_preq_to_root;
bool is_root;
bool is_gate;
bool gate_asked;
};
/**
* struct rtw_mesh_table
*
* @known_gates: list of known mesh gates and their mpaths by the station. The
* gate's mpath may or may not be resolved and active.
* @gates_lock: protects updates to known_gates
* @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr
* @entries: number of entries in the table
*/
struct rtw_mesh_table {
rtw_hlist_head known_gates;
_lock gates_lock;
rtw_rhashtable rhead;
ATOMIC_T entries;
};
#define RTW_MESH_PATH_EXPIRE (600 * HZ)
/* Maximum number of paths per interface */
#define RTW_MESH_MAX_MPATHS 1024
/* Number of frames buffered per destination for unresolved destinations */
#define RTW_MESH_FRAME_QUEUE_LEN 10
int rtw_mesh_nexthop_lookup(_adapter *adapter,
const u8 *mda, const u8 *msa, u8 *ra);
int rtw_mesh_nexthop_resolve(_adapter *adapter,
struct xmit_frame *xframe);
struct rtw_mesh_path *rtw_mesh_path_lookup(_adapter *adapter,
const u8 *dst);
struct rtw_mesh_path *rtw_mpp_path_lookup(_adapter *adapter,
const u8 *dst);
int rtw_mpp_path_add(_adapter *adapter,
const u8 *dst, const u8 *mpp);
void dump_mpp(void *sel, _adapter *adapter);
struct rtw_mesh_path *
rtw_mesh_path_lookup_by_idx(_adapter *adapter, int idx);
void dump_mpath(void *sel, _adapter *adapter);
struct rtw_mesh_path *
rtw_mpp_path_lookup_by_idx(_adapter *adapter, int idx);
void rtw_mesh_path_fix_nexthop(struct rtw_mesh_path *mpath, struct sta_info *next_hop);
void rtw_mesh_path_expire(_adapter *adapter);
struct rtw_mesh_path *
rtw_mesh_path_add(_adapter *adapter, const u8 *dst);
int rtw_mesh_path_add_gate(struct rtw_mesh_path *mpath);
void rtw_mesh_gate_del(struct rtw_mesh_table *tbl, struct rtw_mesh_path *mpath);
bool rtw_mesh_gate_search(struct rtw_mesh_table *tbl, const u8 *addr);
int rtw_mesh_path_send_to_gates(struct rtw_mesh_path *mpath);
int rtw_mesh_gate_num(_adapter *adapter);
bool rtw_mesh_is_primary_gate(_adapter *adapter);
void dump_known_gates(void *sel, _adapter *adapter);
void rtw_mesh_plink_broken(struct sta_info *sta);
void rtw_mesh_path_assign_nexthop(struct rtw_mesh_path *mpath, struct sta_info *sta);
void rtw_mesh_path_flush_pending(struct rtw_mesh_path *mpath);
void rtw_mesh_path_tx_pending(struct rtw_mesh_path *mpath);
int rtw_mesh_pathtbl_init(_adapter *adapter);
void rtw_mesh_pathtbl_unregister(_adapter *adapter);
int rtw_mesh_path_del(_adapter *adapter, const u8 *addr);
void rtw_mesh_path_flush_by_nexthop(struct sta_info *sta);
void rtw_mesh_path_discard_frame(_adapter *adapter,
struct xmit_frame *xframe);
static inline void rtw_mesh_path_activate(struct rtw_mesh_path *mpath)
{
mpath->flags |= RTW_MESH_PATH_ACTIVE | RTW_MESH_PATH_RESOLVED;
}
void rtw_mesh_path_flush_by_iface(_adapter *adapter);
#endif /* __RTW_MESH_PATHTBL_H_ */

5472
core/rtw_ap.c Normal file

File diff suppressed because it is too large Load Diff

3155
core/rtw_beamforming.c Normal file

File diff suppressed because it is too large Load Diff

1581
core/rtw_br_ext.c Normal file

File diff suppressed because it is too large Load Diff

1575
core/rtw_bt_mp.c Normal file

File diff suppressed because it is too large Load Diff

1762
core/rtw_btcoex.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
/******************************************************************************
*
* Copyright(c) 2013 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <hal_btcoex_wifionly.h>
#include <hal_data.h>
void rtw_btcoex_wifionly_switchband_notify(PADAPTER padapter)
{
hal_btcoex_wifionly_switchband_notify(padapter);
}
void rtw_btcoex_wifionly_scan_notify(PADAPTER padapter)
{
hal_btcoex_wifionly_scan_notify(padapter);
}
void rtw_btcoex_wifionly_connect_notify(PADAPTER padapter)
{
hal_btcoex_wifionly_connect_notify(padapter);
}
void rtw_btcoex_wifionly_hw_config(PADAPTER padapter)
{
hal_btcoex_wifionly_hw_config(padapter);
}
void rtw_btcoex_wifionly_initialize(PADAPTER padapter)
{
hal_btcoex_wifionly_initlizevariables(padapter);
}
void rtw_btcoex_wifionly_AntInfoSetting(PADAPTER padapter)
{
hal_btcoex_wifionly_AntInfoSetting(padapter);
}

1193
core/rtw_chplan.c Normal file

File diff suppressed because it is too large Load Diff

181
core/rtw_chplan.h Normal file
View File

@ -0,0 +1,181 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2018 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __RTW_CHPLAN_H__
#define __RTW_CHPLAN_H__
enum rtw_chplan_id {
/* ===== 0x00 ~ 0x1F, legacy channel plan ===== */
RTW_CHPLAN_FCC = 0x00,
RTW_CHPLAN_IC = 0x01,
RTW_CHPLAN_ETSI = 0x02,
RTW_CHPLAN_SPAIN = 0x03,
RTW_CHPLAN_FRANCE = 0x04,
RTW_CHPLAN_MKK = 0x05,
RTW_CHPLAN_MKK1 = 0x06,
RTW_CHPLAN_ISRAEL = 0x07,
RTW_CHPLAN_TELEC = 0x08,
RTW_CHPLAN_GLOBAL_DOAMIN = 0x09,
RTW_CHPLAN_WORLD_WIDE_13 = 0x0A,
RTW_CHPLAN_TAIWAN = 0x0B,
RTW_CHPLAN_CHINA = 0x0C,
RTW_CHPLAN_SINGAPORE_INDIA_MEXICO = 0x0D,
RTW_CHPLAN_KOREA = 0x0E,
RTW_CHPLAN_TURKEY = 0x0F,
RTW_CHPLAN_JAPAN = 0x10,
RTW_CHPLAN_FCC_NO_DFS = 0x11,
RTW_CHPLAN_JAPAN_NO_DFS = 0x12,
RTW_CHPLAN_WORLD_WIDE_5G = 0x13,
RTW_CHPLAN_TAIWAN_NO_DFS = 0x14,
/* ===== 0x20 ~ 0x7F, new channel plan ===== */
RTW_CHPLAN_WORLD_NULL = 0x20,
RTW_CHPLAN_ETSI1_NULL = 0x21,
RTW_CHPLAN_FCC1_NULL = 0x22,
RTW_CHPLAN_MKK1_NULL = 0x23,
RTW_CHPLAN_ETSI2_NULL = 0x24,
RTW_CHPLAN_FCC1_FCC1 = 0x25,
RTW_CHPLAN_WORLD_ETSI1 = 0x26,
RTW_CHPLAN_MKK1_MKK1 = 0x27,
RTW_CHPLAN_WORLD_KCC1 = 0x28,
RTW_CHPLAN_WORLD_FCC2 = 0x29,
RTW_CHPLAN_FCC2_NULL = 0x2A,
RTW_CHPLAN_IC1_IC2 = 0x2B,
RTW_CHPLAN_MKK2_NULL = 0x2C,
RTW_CHPLAN_WORLD_CHILE1= 0x2D,
RTW_CHPLAN_WORLD1_WORLD1 = 0x2E,
RTW_CHPLAN_WORLD_CHILE2 = 0x2F,
RTW_CHPLAN_WORLD_FCC3 = 0x30,
RTW_CHPLAN_WORLD_FCC4 = 0x31,
RTW_CHPLAN_WORLD_FCC5 = 0x32,
RTW_CHPLAN_WORLD_FCC6 = 0x33,
RTW_CHPLAN_FCC1_FCC7 = 0x34,
RTW_CHPLAN_WORLD_ETSI2 = 0x35,
RTW_CHPLAN_WORLD_ETSI3 = 0x36,
RTW_CHPLAN_MKK1_MKK2 = 0x37,
RTW_CHPLAN_MKK1_MKK3 = 0x38,
RTW_CHPLAN_FCC1_NCC1 = 0x39,
RTW_CHPLAN_ETSI1_ETSI1 = 0x3A,
RTW_CHPLAN_ETSI1_ACMA1 = 0x3B,
RTW_CHPLAN_ETSI1_ETSI6 = 0x3C,
RTW_CHPLAN_ETSI1_ETSI12 = 0x3D,
RTW_CHPLAN_KCC1_KCC2 = 0x3E,
RTW_CHPLAN_FCC1_FCC11 = 0x3F,
RTW_CHPLAN_FCC1_NCC2 = 0x40,
RTW_CHPLAN_GLOBAL_NULL = 0x41,
RTW_CHPLAN_ETSI1_ETSI4 = 0x42,
RTW_CHPLAN_FCC1_FCC2 = 0x43,
RTW_CHPLAN_FCC1_NCC3 = 0x44,
RTW_CHPLAN_WORLD_ACMA1 = 0x45,
RTW_CHPLAN_FCC1_FCC8 = 0x46,
RTW_CHPLAN_WORLD_ETSI6 = 0x47,
RTW_CHPLAN_WORLD_ETSI7 = 0x48,
RTW_CHPLAN_WORLD_ETSI8 = 0x49,
RTW_CHPLAN_IC2_IC2 = 0x4A,
RTW_CHPLAN_WORLD_ETSI9 = 0x50,
RTW_CHPLAN_WORLD_ETSI10 = 0x51,
RTW_CHPLAN_WORLD_ETSI11 = 0x52,
RTW_CHPLAN_FCC1_NCC4 = 0x53,
RTW_CHPLAN_WORLD_ETSI12 = 0x54,
RTW_CHPLAN_FCC1_FCC9 = 0x55,
RTW_CHPLAN_WORLD_ETSI13 = 0x56,
RTW_CHPLAN_FCC1_FCC10 = 0x57,
RTW_CHPLAN_MKK2_MKK4 = 0x58,
RTW_CHPLAN_WORLD_ETSI14 = 0x59,
RTW_CHPLAN_FCC1_FCC5 = 0x60,
RTW_CHPLAN_FCC2_FCC7 = 0x61,
RTW_CHPLAN_FCC2_FCC1 = 0x62,
RTW_CHPLAN_WORLD_ETSI15 = 0x63,
RTW_CHPLAN_MKK2_MKK5 = 0x64,
RTW_CHPLAN_ETSI1_ETSI16 = 0x65,
RTW_CHPLAN_FCC1_FCC14 = 0x66,
RTW_CHPLAN_FCC1_FCC12 = 0x67,
RTW_CHPLAN_FCC2_FCC14 = 0x68,
RTW_CHPLAN_FCC2_FCC12 = 0x69,
RTW_CHPLAN_ETSI1_ETSI17 = 0x6A,
RTW_CHPLAN_WORLD_FCC16 = 0x6B,
RTW_CHPLAN_WORLD_FCC13 = 0x6C,
RTW_CHPLAN_FCC2_FCC15 = 0x6D,
RTW_CHPLAN_WORLD_FCC12 = 0x6E,
RTW_CHPLAN_NULL_ETSI8 = 0x6F,
RTW_CHPLAN_NULL_ETSI18 = 0x70,
RTW_CHPLAN_NULL_ETSI17 = 0x71,
RTW_CHPLAN_NULL_ETSI19 = 0x72,
RTW_CHPLAN_WORLD_FCC7 = 0x73,
RTW_CHPLAN_FCC2_FCC17 = 0x74,
RTW_CHPLAN_WORLD_ETSI20 = 0x75,
RTW_CHPLAN_FCC2_FCC11 = 0x76,
RTW_CHPLAN_WORLD_ETSI21 = 0x77,
RTW_CHPLAN_FCC1_FCC18 = 0x78,
RTW_CHPLAN_MKK2_MKK1 = 0x79,
RTW_CHPLAN_MAX,
RTW_CHPLAN_REALTEK_DEFINE = 0x7F,
RTW_CHPLAN_UNSPECIFIED = 0xFF,
};
u8 rtw_chplan_get_default_regd(u8 id);
bool rtw_chplan_is_empty(u8 id);
#define rtw_is_channel_plan_valid(chplan) (((chplan) < RTW_CHPLAN_MAX || (chplan) == RTW_CHPLAN_REALTEK_DEFINE) && !rtw_chplan_is_empty(chplan))
#define rtw_is_legacy_channel_plan(chplan) ((chplan) < 0x20)
struct _RT_CHANNEL_INFO;
u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, struct _RT_CHANNEL_INFO *channel_set);
#define IS_ALPHA2_NO_SPECIFIED(_alpha2) ((*((u16 *)(_alpha2))) == 0xFFFF)
#define RTW_MODULE_RTL8821AE_HMC_M2 BIT0 /* RTL8821AE(HMC + M.2) */
#define RTW_MODULE_RTL8821AU BIT1 /* RTL8821AU */
#define RTW_MODULE_RTL8812AENF_NGFF BIT2 /* RTL8812AENF(8812AE+8761)_NGFF */
#define RTW_MODULE_RTL8812AEBT_HMC BIT3 /* RTL8812AEBT(8812AE+8761)_HMC */
#define RTW_MODULE_RTL8188EE_HMC_M2 BIT4 /* RTL8188EE(HMC + M.2) */
#define RTW_MODULE_RTL8723BE_HMC_M2 BIT5 /* RTL8723BE(HMC + M.2) */
#define RTW_MODULE_RTL8723BS_NGFF1216 BIT6 /* RTL8723BS(NGFF1216) */
#define RTW_MODULE_RTL8192EEBT_HMC_M2 BIT7 /* RTL8192EEBT(8192EE+8761AU)_(HMC + M.2) */
#define RTW_MODULE_RTL8723DE_NGFF1630 BIT8 /* RTL8723DE(NGFF1630) */
#define RTW_MODULE_RTL8822BE BIT9 /* RTL8822BE */
#define RTW_MODULE_RTL8821CE BIT10 /* RTL8821CE */
struct country_chplan {
char alpha2[2];
u8 chplan;
#ifdef CONFIG_80211AC_VHT
u8 en_11ac;
#endif
#if RTW_DEF_MODULE_REGULATORY_CERT
u16 def_module_flags; /* RTW_MODULE_RTLXXX */
#endif
};
#ifdef CONFIG_80211AC_VHT
#define COUNTRY_CHPLAN_EN_11AC(_ent) ((_ent)->en_11ac)
#else
#define COUNTRY_CHPLAN_EN_11AC(_ent) 0
#endif
#if RTW_DEF_MODULE_REGULATORY_CERT
#define COUNTRY_CHPLAN_DEF_MODULE_FALGS(_ent) ((_ent)->def_module_flags)
#else
#define COUNTRY_CHPLAN_DEF_MODULE_FALGS(_ent) 0
#endif
const struct country_chplan *rtw_get_chplan_from_country(const char *country_code);
void dump_country_chplan(void *sel, const struct country_chplan *ent);
void dump_country_chplan_map(void *sel);
void dump_chplan_id_list(void *sel);
void dump_chplan_test(void *sel);
void dump_chplan_ver(void *sel);
#endif /* __RTW_CHPLAN_H__ */

5808
core/rtw_cmd.c Normal file

File diff suppressed because it is too large Load Diff

7032
core/rtw_debug.c Normal file

File diff suppressed because it is too large Load Diff

369
core/rtw_eeprom.c Normal file
View File

@ -0,0 +1,369 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_EEPROM_C_
#include <drv_conf.h>
#include <osdep_service.h>
#include <drv_types.h>
void up_clk(_adapter *padapter, u16 *x)
{
*x = *x | _EESK;
rtw_write8(padapter, EE_9346CR, (u8)*x);
rtw_udelay_os(CLOCK_RATE);
}
void down_clk(_adapter *padapter, u16 *x)
{
*x = *x & ~_EESK;
rtw_write8(padapter, EE_9346CR, (u8)*x);
rtw_udelay_os(CLOCK_RATE);
}
void shift_out_bits(_adapter *padapter, u16 data, u16 count)
{
u16 x, mask;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
mask = 0x01 << (count - 1);
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDO | _EEDI);
do {
x &= ~_EEDI;
if (data & mask)
x |= _EEDI;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
rtw_write8(padapter, EE_9346CR, (u8)x);
rtw_udelay_os(CLOCK_RATE);
up_clk(padapter, &x);
down_clk(padapter, &x);
mask = mask >> 1;
} while (mask);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x &= ~_EEDI;
rtw_write8(padapter, EE_9346CR, (u8)x);
out:
return;
}
u16 shift_in_bits(_adapter *padapter)
{
u16 x, d = 0, i;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDO | _EEDI);
d = 0;
for (i = 0; i < 16; i++) {
d = d << 1;
up_clk(padapter, &x);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDI);
if (x & _EEDO)
d |= 1;
down_clk(padapter, &x);
}
out:
return d;
}
void standby(_adapter *padapter)
{
u8 x;
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EECS | _EESK);
rtw_write8(padapter, EE_9346CR, x);
rtw_udelay_os(CLOCK_RATE);
x |= _EECS;
rtw_write8(padapter, EE_9346CR, x);
rtw_udelay_os(CLOCK_RATE);
}
u16 wait_eeprom_cmd_done(_adapter *padapter)
{
u8 x;
u16 i, res = _FALSE;
standby(padapter);
for (i = 0; i < 200; i++) {
x = rtw_read8(padapter, EE_9346CR);
if (x & _EEDO) {
res = _TRUE;
goto exit;
}
rtw_udelay_os(CLOCK_RATE);
}
exit:
return res;
}
void eeprom_clean(_adapter *padapter)
{
u16 x;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x &= ~(_EECS | _EEDI);
rtw_write8(padapter, EE_9346CR, (u8)x);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
up_clk(padapter, &x);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
down_clk(padapter, &x);
out:
return;
}
void eeprom_write16(_adapter *padapter, u16 reg, u16 data)
{
u8 x;
#ifdef CONFIG_RTL8712
u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new;
tmp8_ori = rtw_read8(padapter, 0x102502f1);
tmp8_new = tmp8_ori & 0xf7;
if (tmp8_ori != tmp8_new) {
rtw_write8(padapter, 0x102502f1, tmp8_new);
}
tmp8_clk_ori = rtw_read8(padapter, 0x10250003);
tmp8_clk_new = tmp8_clk_ori | 0x20;
if (tmp8_clk_new != tmp8_clk_ori) {
rtw_write8(padapter, 0x10250003, tmp8_clk_new);
}
#endif
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, x);
shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5);
if (padapter->EepromAddressSize == 8) /* CF+ and SDIO */
shift_out_bits(padapter, 0, 6);
else /* USB */
shift_out_bits(padapter, 0, 4);
standby(padapter);
/* Commented out by rcnjko, 2004.0
* Erase this particular word. Write the erase opcode and register
* number in that order. The opcode is 3bits in length; reg is 6 bits long. */
/* shift_out_bits(Adapter, EEPROM_ERASE_OPCODE, 3);
* shift_out_bits(Adapter, reg, Adapter->EepromAddressSize);
*
* if (wait_eeprom_cmd_done(Adapter ) == FALSE)
* {
* return;
* } */
standby(padapter);
/* write the new word to the EEPROM */
/* send the write opcode the EEPORM */
shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3);
/* select which word in the EEPROM that we are writing to. */
shift_out_bits(padapter, reg, padapter->EepromAddressSize);
/* write the data to the selected EEPROM word. */
shift_out_bits(padapter, data, 16);
if (wait_eeprom_cmd_done(padapter) == _FALSE)
goto exit;
standby(padapter);
shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5);
shift_out_bits(padapter, reg, 4);
eeprom_clean(padapter);
exit:
#ifdef CONFIG_RTL8712
if (tmp8_clk_new != tmp8_clk_ori)
rtw_write8(padapter, 0x10250003, tmp8_clk_ori);
if (tmp8_new != tmp8_ori)
rtw_write8(padapter, 0x102502f1, tmp8_ori);
#endif
return;
}
u16 eeprom_read16(_adapter *padapter, u16 reg) /* ReadEEprom */
{
u16 x;
u16 data = 0;
#ifdef CONFIG_RTL8712
u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new;
tmp8_ori = rtw_read8(padapter, 0x102502f1);
tmp8_new = tmp8_ori & 0xf7;
if (tmp8_ori != tmp8_new) {
rtw_write8(padapter, 0x102502f1, tmp8_new);
}
tmp8_clk_ori = rtw_read8(padapter, 0x10250003);
tmp8_clk_new = tmp8_clk_ori | 0x20;
if (tmp8_clk_new != tmp8_clk_ori) {
rtw_write8(padapter, 0x10250003, tmp8_clk_new);
}
#endif
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
/* select EEPROM, reset bits, set _EECS */
x = rtw_read8(padapter, EE_9346CR);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, (unsigned char)x);
/* write the read opcode and register number in that order */
/* The opcode is 3bits in length, reg is 6 bits long */
shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
shift_out_bits(padapter, reg, padapter->EepromAddressSize);
/* Now read the data (16 bits) in from the selected EEPROM word */
data = shift_in_bits(padapter);
eeprom_clean(padapter);
out:
#ifdef CONFIG_RTL8712
if (tmp8_clk_new != tmp8_clk_ori)
rtw_write8(padapter, 0x10250003, tmp8_clk_ori);
if (tmp8_new != tmp8_ori)
rtw_write8(padapter, 0x102502f1, tmp8_ori);
#endif
return data;
}
/* From even offset */
void eeprom_read_sz(_adapter *padapter, u16 reg, u8 *data, u32 sz)
{
u16 x, data16;
u32 i;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
/* select EEPROM, reset bits, set _EECS */
x = rtw_read8(padapter, EE_9346CR);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, (unsigned char)x);
/* write the read opcode and register number in that order */
/* The opcode is 3bits in length, reg is 6 bits long */
shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
shift_out_bits(padapter, reg, padapter->EepromAddressSize);
for (i = 0; i < sz; i += 2) {
data16 = shift_in_bits(padapter);
data[i] = data16 & 0xff;
data[i + 1] = data16 >> 8;
}
eeprom_clean(padapter);
out:
return;
}
/* addr_off : address offset of the entry in eeprom (not the tuple number of eeprom (reg); that is addr_off !=reg) */
u8 eeprom_read(_adapter *padapter, u32 addr_off, u8 sz, u8 *rbuf)
{
u8 quotient, remainder, addr_2align_odd;
u16 reg, stmp , i = 0, idx = 0;
reg = (u16)(addr_off >> 1);
addr_2align_odd = (u8)(addr_off & 0x1);
if (addr_2align_odd) { /* read that start at high part: e.g 1,3,5,7,9,... */
stmp = eeprom_read16(padapter, reg);
rbuf[idx++] = (u8)((stmp >> 8) & 0xff); /* return hogh-part of the short */
reg++;
sz--;
}
quotient = sz >> 1;
remainder = sz & 0x1;
for (i = 0 ; i < quotient; i++) {
stmp = eeprom_read16(padapter, reg + i);
rbuf[idx++] = (u8)(stmp & 0xff);
rbuf[idx++] = (u8)((stmp >> 8) & 0xff);
}
reg = reg + i;
if (remainder) { /* end of read at lower part of short : 0,2,4,6,... */
stmp = eeprom_read16(padapter, reg);
rbuf[idx] = (u8)(stmp & 0xff);
}
return _TRUE;
}
VOID read_eeprom_content(_adapter *padapter)
{
}

2878
core/rtw_ieee80211.c Normal file

File diff suppressed because it is too large Load Diff

903
core/rtw_io.c Normal file
View File

@ -0,0 +1,903 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
/*
The purpose of rtw_io.c
a. provides the API
b. provides the protocol engine
c. provides the software interface between caller and the hardware interface
Compiler Flag Option:
1. CONFIG_SDIO_HCI:
a. USE_SYNC_IRP: Only sync operations are provided.
b. USE_ASYNC_IRP:Both sync/async operations are provided.
2. CONFIG_USB_HCI:
a. USE_ASYNC_IRP: Both sync/async operations are provided.
3. CONFIG_CFIO_HCI:
b. USE_SYNC_IRP: Only sync operations are provided.
Only sync read/rtw_write_mem operations are provided.
jackson@realtek.com.tw
*/
#define _RTW_IO_C_
#include <drv_types.h>
#include <hal_data.h>
#if defined(PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
#error "Shall be Linux or Windows, but not both!\n"
#endif
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_PLATFORM_RTL8197D)
#define rtw_le16_to_cpu(val) val
#define rtw_le32_to_cpu(val) val
#define rtw_cpu_to_le16(val) val
#define rtw_cpu_to_le32(val) val
#else
#define rtw_le16_to_cpu(val) le16_to_cpu(val)
#define rtw_le32_to_cpu(val) le32_to_cpu(val)
#define rtw_cpu_to_le16(val) cpu_to_le16(val)
#define rtw_cpu_to_le32(val) cpu_to_le32(val)
#endif
u8 _rtw_read8(_adapter *adapter, u32 addr)
{
u8 r_val;
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u8(*_read8)(struct intf_hdl *pintfhdl, u32 addr);
_read8 = pintfhdl->io_ops._read8;
r_val = _read8(pintfhdl, addr);
return r_val;
}
u16 _rtw_read16(_adapter *adapter, u32 addr)
{
u16 r_val;
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u16(*_read16)(struct intf_hdl *pintfhdl, u32 addr);
_read16 = pintfhdl->io_ops._read16;
r_val = _read16(pintfhdl, addr);
return rtw_le16_to_cpu(r_val);
}
u32 _rtw_read32(_adapter *adapter, u32 addr)
{
u32 r_val;
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u32(*_read32)(struct intf_hdl *pintfhdl, u32 addr);
_read32 = pintfhdl->io_ops._read32;
r_val = _read32(pintfhdl, addr);
return rtw_le32_to_cpu(r_val);
}
int _rtw_write8(_adapter *adapter, u32 addr, u8 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret;
_write8 = pintfhdl->io_ops._write8;
ret = _write8(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write16(_adapter *adapter, u32 addr, u16 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret;
_write16 = pintfhdl->io_ops._write16;
val = rtw_cpu_to_le16(val);
ret = _write16(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write32(_adapter *adapter, u32 addr, u32 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret;
_write32 = pintfhdl->io_ops._write32;
val = rtw_cpu_to_le32(val);
ret = _write32(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_writeN(_adapter *adapter, u32 addr , u32 length , u8 *pdata)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = (struct intf_hdl *)(&(pio_priv->intf));
int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata);
int ret;
_writeN = pintfhdl->io_ops._writeN;
ret = _writeN(pintfhdl, addr, length, pdata);
return RTW_STATUS_CODE(ret);
}
#ifdef CONFIG_SDIO_HCI
u8 _rtw_sd_f0_read8(_adapter *adapter, u32 addr)
{
u8 r_val = 0x00;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u8(*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr);
_sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8;
if (_sd_f0_read8)
r_val = _sd_f0_read8(pintfhdl, addr);
else
RTW_WARN(FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return r_val;
}
#ifdef CONFIG_SDIO_INDIRECT_ACCESS
u8 _rtw_sd_iread8(_adapter *adapter, u32 addr)
{
u8 r_val = 0x00;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u8(*_sd_iread8)(struct intf_hdl *pintfhdl, u32 addr);
_sd_iread8 = pintfhdl->io_ops._sd_iread8;
if (_sd_iread8)
r_val = _sd_iread8(pintfhdl, addr);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iread8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return r_val;
}
u16 _rtw_sd_iread16(_adapter *adapter, u32 addr)
{
u16 r_val = 0x00;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u16(*_sd_iread16)(struct intf_hdl *pintfhdl, u32 addr);
_sd_iread16 = pintfhdl->io_ops._sd_iread16;
if (_sd_iread16)
r_val = _sd_iread16(pintfhdl, addr);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iread16 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return r_val;
}
u32 _rtw_sd_iread32(_adapter *adapter, u32 addr)
{
u32 r_val = 0x00;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u32(*_sd_iread32)(struct intf_hdl *pintfhdl, u32 addr);
_sd_iread32 = pintfhdl->io_ops._sd_iread32;
if (_sd_iread32)
r_val = _sd_iread32(pintfhdl, addr);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iread32 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return r_val;
}
int _rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_sd_iwrite8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret = -1;
_sd_iwrite8 = pintfhdl->io_ops._sd_iwrite8;
if (_sd_iwrite8)
ret = _sd_iwrite8(pintfhdl, addr, val);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return RTW_STATUS_CODE(ret);
}
int _rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_sd_iwrite16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret = -1;
_sd_iwrite16 = pintfhdl->io_ops._sd_iwrite16;
if (_sd_iwrite16)
ret = _sd_iwrite16(pintfhdl, addr, val);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite16 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return RTW_STATUS_CODE(ret);
}
int _rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_sd_iwrite32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret = -1;
_sd_iwrite32 = pintfhdl->io_ops._sd_iwrite32;
if (_sd_iwrite32)
ret = _sd_iwrite32(pintfhdl, addr, val);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite32 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return RTW_STATUS_CODE(ret);
}
#endif /* CONFIG_SDIO_INDIRECT_ACCESS */
#endif /* CONFIG_SDIO_HCI */
int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret;
_write8_async = pintfhdl->io_ops._write8_async;
ret = _write8_async(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret;
_write16_async = pintfhdl->io_ops._write16_async;
val = rtw_cpu_to_le16(val);
ret = _write16_async(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret;
_write32_async = pintfhdl->io_ops._write32_async;
val = rtw_cpu_to_le32(val);
ret = _write32_async(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
if (RTW_CANNOT_RUN(adapter)) {
return;
}
_read_mem = pintfhdl->io_ops._read_mem;
_read_mem(pintfhdl, addr, cnt, pmem);
}
void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_write_mem = pintfhdl->io_ops._write_mem;
_write_mem(pintfhdl, addr, cnt, pmem);
}
void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
u32(*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
if (RTW_CANNOT_RUN(adapter)) {
return;
}
_read_port = pintfhdl->io_ops._read_port;
_read_port(pintfhdl, addr, cnt, pmem);
}
void _rtw_read_port_cancel(_adapter *adapter)
{
void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_read_port_cancel = pintfhdl->io_ops._read_port_cancel;
RTW_DISABLE_FUNC(adapter, DF_RX_BIT);
if (_read_port_cancel)
_read_port_cancel(pintfhdl);
}
u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
u32(*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u32 ret = _SUCCESS;
_write_port = pintfhdl->io_ops._write_port;
ret = _write_port(pintfhdl, addr, cnt, pmem);
return ret;
}
u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
{
int ret = _SUCCESS;
struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
struct submit_ctx sctx;
rtw_sctx_init(&sctx, timeout_ms);
pxmitbuf->sctx = &sctx;
ret = _rtw_write_port(adapter, addr, cnt, pmem);
if (ret == _SUCCESS) {
ret = rtw_sctx_wait(&sctx, __func__);
if (ret != _SUCCESS)
pxmitbuf->sctx = NULL;
}
return ret;
}
void _rtw_write_port_cancel(_adapter *adapter)
{
void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_write_port_cancel = pintfhdl->io_ops._write_port_cancel;
RTW_DISABLE_FUNC(adapter, DF_TX_BIT);
if (_write_port_cancel)
_write_port_cancel(pintfhdl);
}
int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter, struct _io_ops *pops))
{
struct io_priv *piopriv = &padapter->iopriv;
struct intf_hdl *pintf = &piopriv->intf;
if (set_intf_ops == NULL)
return _FAIL;
piopriv->padapter = padapter;
pintf->padapter = padapter;
pintf->pintf_dev = adapter_to_dvobj(padapter);
set_intf_ops(padapter, &pintf->io_ops);
return _SUCCESS;
}
/*
* Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR
* @return _TRUE:
* @return _FALSE:
*/
int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)
{
int ret = _FALSE;
int value;
value = ATOMIC_INC_RETURN(&dvobj->continual_io_error);
if (value > MAX_CONTINUAL_IO_ERR) {
RTW_INFO("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR);
ret = _TRUE;
} else {
/* RTW_INFO("[dvobj:%p] continual_io_error:%d\n", dvobj, value); */
}
return ret;
}
/*
* Set the continual_io_error of this @param dvobjprive to 0
*/
void rtw_reset_continual_io_error(struct dvobj_priv *dvobj)
{
ATOMIC_SET(&dvobj->continual_io_error, 0);
}
#ifdef DBG_IO
#define RTW_IO_SNIFF_TYPE_RANGE 0 /* specific address range is accessed */
#define RTW_IO_SNIFF_TYPE_EN 1 /* part or all sniffed range is enabled */
#define RTW_IO_SNIFF_TYPE_DIS 2 /* part or all sniffed range is disabled */
struct rtw_io_sniff_ent {
u8 chip;
u8 hci;
u32 addr;
u8 type;
union {
u32 end_addr;
u32 mask;
} u;
char *tag;
};
const char *rtw_io_sniff_ent_get_tag(const struct rtw_io_sniff_ent *ent)
{
return ent->tag;
}
#define RTW_IO_SNIFF_RANGE_ENT(_chip, _hci, _addr, _end_addr, _tag) \
{.chip = _chip, .hci = _hci, .addr = _addr, .u.end_addr = _end_addr, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_RANGE,}
#define RTW_IO_SNIFF_EN_ENT(_chip, _hci, _addr, _mask, _tag) \
{.chip = _chip, .hci = _hci, .addr = _addr, .u.mask = _mask, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_EN,}
#define RTW_IO_SNIFF_DIS_ENT(_chip, _hci, _addr, _mask, _tag) \
{.chip = _chip, .hci = _hci, .addr = _addr, .u.mask = _mask, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_DIS,}
const struct rtw_io_sniff_ent read_sniff[] = {
#ifdef DBG_IO_HCI_EN_CHK
RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_SDIO, 0x02, 0x1FC, "SDIO 0x02[8:2] not all 0"),
RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_USB, 0x02, 0x1E0, "USB 0x02[8:5] not all 0"),
RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_PCIE, 0x02, 0x01C, "PCI 0x02[4:2] not all 0"),
#endif
#ifdef DBG_IO_SNIFF_EXAMPLE
RTW_IO_SNIFF_RANGE_ENT(MAX_CHIP_TYPE, 0, 0x522, 0x522, "read TXPAUSE"),
RTW_IO_SNIFF_DIS_ENT(MAX_CHIP_TYPE, 0, 0x02, 0x3, "0x02[1:0] not all 1"),
#endif
};
const int read_sniff_num = sizeof(read_sniff) / sizeof(struct rtw_io_sniff_ent);
const struct rtw_io_sniff_ent write_sniff[] = {
#ifdef DBG_IO_HCI_EN_CHK
RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_SDIO, 0x02, 0x1FC, "SDIO 0x02[8:2] not all 0"),
RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_USB, 0x02, 0x1E0, "USB 0x02[8:5] not all 0"),
RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_PCIE, 0x02, 0x01C, "PCI 0x02[4:2] not all 0"),
#endif
#ifdef DBG_IO_SNIFF_EXAMPLE
RTW_IO_SNIFF_RANGE_ENT(MAX_CHIP_TYPE, 0, 0x522, 0x522, "write TXPAUSE"),
RTW_IO_SNIFF_DIS_ENT(MAX_CHIP_TYPE, 0, 0x02, 0x3, "0x02[1:0] not all 1"),
#endif
};
const int write_sniff_num = sizeof(write_sniff) / sizeof(struct rtw_io_sniff_ent);
static bool match_io_sniff_ranges(_adapter *adapter
, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u16 len)
{
/* check if IO range after sniff end address */
if (addr > sniff->u.end_addr)
return 0;
return 1;
}
static bool match_io_sniff_en(_adapter *adapter
, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u8 len, u32 val)
{
u8 sniff_len;
u8 shift;
u32 mask;
bool ret = 0;
/* check if IO range after sniff end address */
sniff_len = 4;
while (!(sniff->u.mask & (0xFF << ((sniff_len - 1) * 8)))) {
sniff_len--;
if (sniff_len == 0)
goto exit;
}
if (sniff->addr + sniff_len <= addr)
goto exit;
if (sniff->addr > addr) {
shift = (sniff->addr - addr) * 8;
mask = sniff->u.mask << shift;
} else if (sniff->addr < addr) {
shift = (addr - sniff->addr) * 8;
mask = sniff->u.mask >> shift;
} else {
shift = 0;
mask = sniff->u.mask;
}
if (sniff->type == RTW_IO_SNIFF_TYPE_DIS) {
if (len == 4)
mask &= 0xFFFFFFFF;
else if (len == 3)
mask &= 0x00FFFFFF;
else if (len == 2)
mask &= 0x0000FFFF;
else if (len == 1)
mask &= 0x000000FF;
else
mask &= 0x00000000;
}
if ((sniff->type == RTW_IO_SNIFF_TYPE_EN && (mask & val))
|| (sniff->type == RTW_IO_SNIFF_TYPE_DIS && (mask & val) != mask)
) {
ret = 1;
if (0)
RTW_INFO(FUNC_ADPT_FMT" addr:0x%x len:%u val:0x%x i:%d sniff_len:%u shift:%u mask:0x%x\n"
, FUNC_ADPT_ARG(adapter), addr, len, val, i, sniff_len, shift, mask);
}
exit:
return ret;
}
static bool match_io_sniff(_adapter *adapter
, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u8 len, u32 val)
{
bool ret = 0;
if (sniff->chip != MAX_CHIP_TYPE
&& sniff->chip != rtw_get_chip_type(adapter))
goto exit;
if (sniff->hci
&& !(sniff->hci & rtw_get_intf_type(adapter)))
goto exit;
if (sniff->addr >= addr + len) /* IO range below sniff start address */
goto exit;
switch (sniff->type) {
case RTW_IO_SNIFF_TYPE_RANGE:
ret = match_io_sniff_ranges(adapter, sniff, i, addr, len);
break;
case RTW_IO_SNIFF_TYPE_EN:
case RTW_IO_SNIFF_TYPE_DIS:
if (len == 1 || len == 2 || len == 4)
ret = match_io_sniff_en(adapter, sniff, i, addr, len, val);
break;
default:
rtw_warn_on(1);
break;
}
exit:
return ret;
}
const struct rtw_io_sniff_ent *match_read_sniff(_adapter *adapter
, u32 addr, u16 len, u32 val)
{
int i;
bool ret = 0;
for (i = 0; i < read_sniff_num; i++) {
ret = match_io_sniff(adapter, &read_sniff[i], i, addr, len, val);
if (ret)
goto exit;
}
exit:
return ret ? &read_sniff[i] : NULL;
}
const struct rtw_io_sniff_ent *match_write_sniff(_adapter *adapter
, u32 addr, u16 len, u32 val)
{
int i;
bool ret = 0;
for (i = 0; i < write_sniff_num; i++) {
ret = match_io_sniff(adapter, &write_sniff[i], i, addr, len, val);
if (ret)
goto exit;
}
exit:
return ret ? &write_sniff[i] : NULL;
}
struct rf_sniff_ent {
u8 path;
u16 reg;
u32 mask;
};
struct rf_sniff_ent rf_read_sniff_ranges[] = {
/* example for all path addr 0x55 with all RF Reg mask */
/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */
};
struct rf_sniff_ent rf_write_sniff_ranges[] = {
/* example for all path addr 0x55 with all RF Reg mask */
/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */
};
int rf_read_sniff_num = sizeof(rf_read_sniff_ranges) / sizeof(struct rf_sniff_ent);
int rf_write_sniff_num = sizeof(rf_write_sniff_ranges) / sizeof(struct rf_sniff_ent);
bool match_rf_read_sniff_ranges(_adapter *adapter, u8 path, u32 addr, u32 mask)
{
int i;
for (i = 0; i < rf_read_sniff_num; i++) {
if (rf_read_sniff_ranges[i].path == MAX_RF_PATH || rf_read_sniff_ranges[i].path == path)
if (addr == rf_read_sniff_ranges[i].reg && (mask & rf_read_sniff_ranges[i].mask))
return _TRUE;
}
return _FALSE;
}
bool match_rf_write_sniff_ranges(_adapter *adapter, u8 path, u32 addr, u32 mask)
{
int i;
for (i = 0; i < rf_write_sniff_num; i++) {
if (rf_write_sniff_ranges[i].path == MAX_RF_PATH || rf_write_sniff_ranges[i].path == path)
if (addr == rf_write_sniff_ranges[i].reg && (mask & rf_write_sniff_ranges[i].mask))
return _TRUE;
}
return _FALSE;
}
u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u8 val = _rtw_read8(adapter, addr);
const struct rtw_io_sniff_ent *ent = match_read_sniff(adapter, addr, 1, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return val;
}
u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u16 val = _rtw_read16(adapter, addr);
const struct rtw_io_sniff_ent *ent = match_read_sniff(adapter, addr, 2, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return val;
}
u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u32 val = _rtw_read32(adapter, addr);
const struct rtw_io_sniff_ent *ent = match_read_sniff(adapter, addr, 4, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return val;
}
int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(adapter, addr, 1, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x) %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_write8(adapter, addr, val);
}
int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(adapter, addr, 2, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x) %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_write16(adapter, addr, val);
}
int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(adapter, addr, 4, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x) %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_write32(adapter, addr, val);
}
int dbg_rtw_writeN(_adapter *adapter, u32 addr , u32 length , u8 *data, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(adapter, addr, length, 0);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_writeN(0x%04x, %u) %s\n"
, caller, line, addr, length, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_writeN(adapter, addr, length, data);
}
#ifdef CONFIG_SDIO_HCI
u8 dbg_rtw_sd_f0_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u8 val = _rtw_sd_f0_read8(adapter, addr);
#if 0
const struct rtw_io_sniff_ent *ent = match_read_sniff(adapter, addr, 1, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_sd_f0_read8(0x%04x) return 0x%02x %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
#endif
return val;
}
#ifdef CONFIG_SDIO_INDIRECT_ACCESS
u8 dbg_rtw_sd_iread8(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u8 val = rtw_sd_iread8(adapter, addr);
const struct rtw_io_sniff_ent *ent = match_read_sniff(adapter, addr, 1, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_sd_iread8(0x%04x) return 0x%02x %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return val;
}
u16 dbg_rtw_sd_iread16(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u16 val = _rtw_sd_iread16(adapter, addr);
const struct rtw_io_sniff_ent *ent = match_read_sniff(adapter, addr, 2, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_sd_iread16(0x%04x) return 0x%04x %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return val;
}
u32 dbg_rtw_sd_iread32(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u32 val = _rtw_sd_iread32(adapter, addr);
const struct rtw_io_sniff_ent *ent = match_read_sniff(adapter, addr, 4, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_sd_iread32(0x%04x) return 0x%08x %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return val;
}
int dbg_rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(adapter, addr, 1, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite8(0x%04x, 0x%02x) %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_sd_iwrite8(adapter, addr, val);
}
int dbg_rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(adapter, addr, 2, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite16(0x%04x, 0x%04x) %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_sd_iwrite16(adapter, addr, val);
}
int dbg_rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(adapter, addr, 4, val);
if (ent) {
RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite32(0x%04x, 0x%08x) %s\n"
, caller, line, addr, val, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_sd_iwrite32(adapter, addr, val);
}
#endif /* CONFIG_SDIO_INDIRECT_ACCESS */
#endif /* CONFIG_SDIO_HCI */
#endif

166
core/rtw_ioctl_query.c Normal file
View File

@ -0,0 +1,166 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_IOCTL_QUERY_C_
#include <drv_types.h>
#ifdef PLATFORM_WINDOWS
/*
* Added for WPA2-PSK, by Annie, 2005-09-20.
* */
u8
query_802_11_capability(
_adapter *Adapter,
u8 *pucBuf,
u32 *pulOutLen
)
{
static NDIS_802_11_AUTHENTICATION_ENCRYPTION szAuthEnc[] = {
{Ndis802_11AuthModeOpen, Ndis802_11EncryptionDisabled},
{Ndis802_11AuthModeOpen, Ndis802_11Encryption1Enabled},
{Ndis802_11AuthModeShared, Ndis802_11EncryptionDisabled},
{Ndis802_11AuthModeShared, Ndis802_11Encryption1Enabled},
{Ndis802_11AuthModeWPA, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPA, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPANone, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPANone, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPA2, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPA2, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled}
};
static ULONG ulNumOfPairSupported = sizeof(szAuthEnc) / sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION);
NDIS_802_11_CAPABILITY *pCap = (NDIS_802_11_CAPABILITY *)pucBuf;
u8 *pucAuthEncryptionSupported = (u8 *) pCap->AuthenticationEncryptionSupported;
pCap->Length = sizeof(NDIS_802_11_CAPABILITY);
if (ulNumOfPairSupported > 1)
pCap->Length += (ulNumOfPairSupported - 1) * sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION);
pCap->Version = 2;
pCap->NoOfPMKIDs = NUM_PMKID_CACHE;
pCap->NoOfAuthEncryptPairsSupported = ulNumOfPairSupported;
if (sizeof(szAuthEnc) <= 240) /* 240 = 256 - 4*4 */ { /* SecurityInfo.szCapability: only 256 bytes in size. */
_rtw_memcpy(pucAuthEncryptionSupported, (u8 *)szAuthEnc, sizeof(szAuthEnc));
*pulOutLen = pCap->Length;
return _TRUE;
} else {
*pulOutLen = 0;
return _FALSE;
}
}
u8 query_802_11_association_information(_adapter *padapter, PNDIS_802_11_ASSOCIATION_INFORMATION pAssocInfo)
{
struct wlan_network *tgt_network;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct security_priv *psecuritypriv = &(padapter->securitypriv);
WLAN_BSSID_EX *psecnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
u8 *pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
unsigned char i, *auth_ie, *supp_ie;
/* NdisZeroMemory(pAssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)); */
_rtw_memset(pAssocInfo, 0, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
/* pAssocInfo->Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); */
/* ------------------------------------------------------ */
/* Association Request related information */
/* ------------------------------------------------------ */
/* Req_1. AvailableRequestFixedIEs */
if (psecnetwork != NULL) {
pAssocInfo->AvailableRequestFixedIEs |= NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_CURRENTAPADDRESS;
pAssocInfo->RequestFixedIEs.Capabilities = (unsigned short) *&psecnetwork->IEs[10];
_rtw_memcpy(pAssocInfo->RequestFixedIEs.CurrentAPAddress,
&psecnetwork->MacAddress, 6);
pAssocInfo->OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING | _FW_LINKED) == _TRUE) {
if (psecuritypriv->ndisauthtype >= Ndis802_11AuthModeWPA2)
pDest[0] = 48; /* RSN Information Element */
else
pDest[0] = 221; /* WPA(SSN) Information Element */
supp_ie = &psecuritypriv->supplicant_ie[0];
i = 13; /* 0~11 is fixed information element */
while ((i < supp_ie[0]) && (i < 256)) {
if ((unsigned char)supp_ie[i] == pDest[0]) {
_rtw_memcpy((u8 *)(pDest),
&supp_ie[i],
supp_ie[1 + i] + 2);
break;
}
i = i + supp_ie[i + 1] + 2;
if (supp_ie[1 + i] == 0)
i = i + 1;
}
pAssocInfo->RequestIELength += (2 + supp_ie[1 + i]); /* (2 + psecnetwork->IEs[1+i]+4); */
}
}
/* ------------------------------------------------------ */
/* Association Response related information */
/* ------------------------------------------------------ */
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
tgt_network = &(pmlmepriv->cur_network);
if (tgt_network != NULL) {
pAssocInfo->AvailableResponseFixedIEs =
NDIS_802_11_AI_RESFI_CAPABILITIES
| NDIS_802_11_AI_RESFI_ASSOCIATIONID
;
pAssocInfo->ResponseFixedIEs.Capabilities = (unsigned short) *&tgt_network->network.IEs[10];
pAssocInfo->ResponseFixedIEs.StatusCode = 0;
pAssocInfo->ResponseFixedIEs.AssociationId = (unsigned short) tgt_network->aid;
pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAssocInfo->RequestIELength;
auth_ie = &psecuritypriv->authenticator_ie[0];
i = auth_ie[0] - 12;
if (i > 0) {
_rtw_memcpy((u8 *)&pDest[0], &auth_ie[1], i);
pAssocInfo->ResponseIELength = i;
}
pAssocInfo->OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAssocInfo->RequestIELength;
}
}
return _TRUE;
}
#endif

901
core/rtw_ioctl_rtl.c Normal file
View File

@ -0,0 +1,901 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_IOCTL_RTL_C_
#include <drv_types.h>
#ifdef CONFIG_MP_INCLUDED
#include <rtw_mp_ioctl.h>
#endif
struct oid_obj_priv oid_rtl_seg_01_01[] = {
{1, &oid_null_function}, /* 0x80 */
{1, &oid_null_function}, /* 0x81 */
{1, &oid_null_function}, /* 0x82 */
{1, &oid_null_function}, /* 0x83 */ /* OID_RT_SET_SNIFFER_MODE */
{1, &oid_rt_get_signal_quality_hdl}, /* 0x84 */
{1, &oid_rt_get_small_packet_crc_hdl}, /* 0x85 */
{1, &oid_rt_get_middle_packet_crc_hdl}, /* 0x86 */
{1, &oid_rt_get_large_packet_crc_hdl}, /* 0x87 */
{1, &oid_rt_get_tx_retry_hdl}, /* 0x88 */
{1, &oid_rt_get_rx_retry_hdl}, /* 0x89 */
{1, &oid_rt_pro_set_fw_dig_state_hdl}, /* 0x8A */
{1, &oid_rt_pro_set_fw_ra_state_hdl} , /* 0x8B */
{1, &oid_null_function}, /* 0x8C */
{1, &oid_null_function}, /* 0x8D */
{1, &oid_null_function}, /* 0x8E */
{1, &oid_null_function}, /* 0x8F */
{1, &oid_rt_get_rx_total_packet_hdl}, /* 0x90 */
{1, &oid_rt_get_tx_beacon_ok_hdl}, /* 0x91 */
{1, &oid_rt_get_tx_beacon_err_hdl}, /* 0x92 */
{1, &oid_rt_get_rx_icv_err_hdl}, /* 0x93 */
{1, &oid_rt_set_encryption_algorithm_hdl}, /* 0x94 */
{1, &oid_null_function}, /* 0x95 */
{1, &oid_rt_get_preamble_mode_hdl}, /* 0x96 */
{1, &oid_null_function}, /* 0x97 */
{1, &oid_rt_get_ap_ip_hdl}, /* 0x98 */
{1, &oid_rt_get_channelplan_hdl}, /* 0x99 */
{1, &oid_rt_set_preamble_mode_hdl}, /* 0x9A */
{1, &oid_rt_set_bcn_intvl_hdl}, /* 0x9B */
{1, &oid_null_function}, /* 0x9C */
{1, &oid_rt_dedicate_probe_hdl}, /* 0x9D */
{1, &oid_null_function}, /* 0x9E */
{1, &oid_null_function}, /* 0x9F */
{1, &oid_null_function}, /* 0xA0 */
{1, &oid_null_function}, /* 0xA1 */
{1, &oid_null_function}, /* 0xA2 */
{1, &oid_null_function}, /* 0xA3 */
{1, &oid_null_function}, /* 0xA4 */
{1, &oid_null_function}, /* 0xA5 */
{1, &oid_null_function}, /* 0xA6 */
{1, &oid_rt_get_total_tx_bytes_hdl}, /* 0xA7 */
{1, &oid_rt_get_total_rx_bytes_hdl}, /* 0xA8 */
{1, &oid_rt_current_tx_power_level_hdl}, /* 0xA9 */
{1, &oid_rt_get_enc_key_mismatch_count_hdl}, /* 0xAA */
{1, &oid_rt_get_enc_key_match_count_hdl}, /* 0xAB */
{1, &oid_rt_get_channel_hdl}, /* 0xAC */
{1, &oid_rt_set_channelplan_hdl}, /* 0xAD */
{1, &oid_rt_get_hardware_radio_off_hdl}, /* 0xAE */
{1, &oid_null_function}, /* 0xAF */
{1, &oid_null_function}, /* 0xB0 */
{1, &oid_null_function}, /* 0xB1 */
{1, &oid_null_function}, /* 0xB2 */
{1, &oid_null_function}, /* 0xB3 */
{1, &oid_rt_get_key_mismatch_hdl}, /* 0xB4 */
{1, &oid_null_function}, /* 0xB5 */
{1, &oid_null_function}, /* 0xB6 */
{1, &oid_null_function}, /* 0xB7 */
{1, &oid_null_function}, /* 0xB8 */
{1, &oid_null_function}, /* 0xB9 */
{1, &oid_null_function}, /* 0xBA */
{1, &oid_rt_supported_wireless_mode_hdl}, /* 0xBB */
{1, &oid_rt_get_channel_list_hdl}, /* 0xBC */
{1, &oid_rt_get_scan_in_progress_hdl}, /* 0xBD */
{1, &oid_null_function}, /* 0xBE */
{1, &oid_null_function}, /* 0xBF */
{1, &oid_null_function}, /* 0xC0 */
{1, &oid_rt_forced_data_rate_hdl}, /* 0xC1 */
{1, &oid_rt_wireless_mode_for_scan_list_hdl}, /* 0xC2 */
{1, &oid_rt_get_bss_wireless_mode_hdl}, /* 0xC3 */
{1, &oid_rt_scan_with_magic_packet_hdl}, /* 0xC4 */
{1, &oid_null_function}, /* 0xC5 */
{1, &oid_null_function}, /* 0xC6 */
{1, &oid_null_function}, /* 0xC7 */
{1, &oid_null_function}, /* 0xC8 */
{1, &oid_null_function}, /* 0xC9 */
{1, &oid_null_function}, /* 0xCA */
{1, &oid_null_function}, /* 0xCB */
{1, &oid_null_function}, /* 0xCC */
{1, &oid_null_function}, /* 0xCD */
{1, &oid_null_function}, /* 0xCE */
{1, &oid_null_function}, /* 0xCF */
};
struct oid_obj_priv oid_rtl_seg_01_03[] = {
{1, &oid_rt_ap_get_associated_station_list_hdl}, /* 0x00 */
{1, &oid_null_function}, /* 0x01 */
{1, &oid_rt_ap_switch_into_ap_mode_hdl}, /* 0x02 */
{1, &oid_null_function}, /* 0x03 */
{1, &oid_rt_ap_supported_hdl}, /* 0x04 */
{1, &oid_rt_ap_set_passphrase_hdl}, /* 0x05 */
};
struct oid_obj_priv oid_rtl_seg_01_11[] = {
{1, &oid_null_function}, /* 0xC0 OID_RT_PRO_RX_FILTER */
{1, &oid_null_function}, /* 0xC1 OID_CE_USB_WRITE_REGISTRY */
{1, &oid_null_function}, /* 0xC2 OID_CE_USB_READ_REGISTRY */
{1, &oid_null_function}, /* 0xC3 OID_RT_PRO_SET_INITIAL_GAIN */
{1, &oid_null_function}, /* 0xC4 OID_RT_PRO_SET_BB_RF_STANDBY_MODE */
{1, &oid_null_function}, /* 0xC5 OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE */
{1, &oid_null_function}, /* 0xC6 OID_RT_PRO_SET_TX_CHARGE_PUMP */
{1, &oid_null_function}, /* 0xC7 OID_RT_PRO_SET_RX_CHARGE_PUMP */
{1, &oid_rt_pro_rf_write_registry_hdl}, /* 0xC8 */
{1, &oid_rt_pro_rf_read_registry_hdl}, /* 0xC9 */
{1, &oid_null_function} /* 0xCA OID_RT_PRO_QUERY_RF_TYPE */
};
struct oid_obj_priv oid_rtl_seg_03_00[] = {
{1, &oid_null_function}, /* 0x00 */
{1, &oid_rt_get_connect_state_hdl}, /* 0x01 */
{1, &oid_null_function}, /* 0x02 */
{1, &oid_null_function}, /* 0x03 */
{1, &oid_rt_set_default_key_id_hdl}, /* 0x04 */
};
/* ************** oid_rtl_seg_01_01 section start ************** */
NDIS_STATUS oid_rt_pro_set_fw_dig_state_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
#if 0
PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context);
_irqL oldirql;
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
_irqlevel_changed_(&oldirql, LOWER);
if (poid_par_priv->information_buf_len >= sizeof(struct setdig_parm)) {
/* DEBUG_ERR(("===> oid_rt_pro_set_fw_dig_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf ))); */
if (!rtw_setfwdig_cmd(Adapter, *((unsigned char *)poid_par_priv->information_buf)))
status = NDIS_STATUS_NOT_ACCEPTED;
} else
status = NDIS_STATUS_NOT_ACCEPTED;
_irqlevel_changed_(&oldirql, RAISE);
#endif
return status;
}
/* ----------------------------------------------------------------------------- */
NDIS_STATUS oid_rt_pro_set_fw_ra_state_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
#if 0
PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context);
_irqL oldirql;
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
_irqlevel_changed_(&oldirql, LOWER);
if (poid_par_priv->information_buf_len >= sizeof(struct setra_parm)) {
/* DEBUG_ERR(("===> oid_rt_pro_set_fw_ra_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf ))); */
if (!rtw_setfwra_cmd(Adapter, *((unsigned char *)poid_par_priv->information_buf)))
status = NDIS_STATUS_NOT_ACCEPTED;
} else
status = NDIS_STATUS_NOT_ACCEPTED;
_irqlevel_changed_(&oldirql, RAISE);
#endif
return status;
}
/* ----------------------------------------------------------------------------- */
NDIS_STATUS oid_rt_get_signal_quality_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
/* DEBUG_ERR(("<**********************oid_rt_get_signal_quality_hdl\n")); */
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
#if 0
if (pMgntInfo->mAssoc || pMgntInfo->mIbss) {
ulInfo = pAdapter->RxStats.SignalQuality;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else {
ulInfo = 0xffffffff; /* It stands for -1 in 4-byte integer. */
}
break;
#endif
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_small_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_smallpacket_crcerr;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_middlepacket_crcerr;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_large_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_largepacket_crcerr;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_tx_retry_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_rx_retry_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_rx_total_packet_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_pkts + padapter->recvpriv.rx_drop;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(u32)) {
/* _rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32)); */
*(uint *)poid_par_priv->information_buf = padapter->recvpriv.rx_icv_err;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
ULONG preamblemode = 0 ;
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
if (padapter->registrypriv.preamble == PREAMBLE_LONG)
preamblemode = 0;
else if (padapter->registrypriv.preamble == PREAMBLE_AUTO)
preamblemode = 1;
else if (padapter->registrypriv.preamble == PREAMBLE_SHORT)
preamblemode = 2;
*(ULONG *)poid_par_priv->information_buf = preamblemode ;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_ap_ip_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_channelplan_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
*(u16 *)poid_par_priv->information_buf = rfctl->ChannelPlan;
return status;
}
NDIS_STATUS oid_rt_set_channelplan_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
rfctl->ChannelPlan = *(u16 *)poid_par_priv->information_buf;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_set_preamble_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
ULONG preamblemode = 0;
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
preamblemode = *(ULONG *)poid_par_priv->information_buf ;
if (preamblemode == 0)
padapter->registrypriv.preamble = PREAMBLE_LONG;
else if (preamblemode == 1)
padapter->registrypriv.preamble = PREAMBLE_AUTO;
else if (preamblemode == 2)
padapter->registrypriv.preamble = PREAMBLE_SHORT;
*(ULONG *)poid_par_priv->information_buf = preamblemode ;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_set_bcn_intvl_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_dedicate_probe_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(u64 *)poid_par_priv->information_buf = padapter->xmitpriv.tx_bytes;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
/* _rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32)); */
*(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_bytes;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_current_tx_power_level_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_channel_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
NDIS_802_11_CONFIGURATION *pnic_Config;
ULONG channelnum;
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
pnic_Config = &pmlmepriv->cur_network.network.Configuration;
else
pnic_Config = &padapter->registrypriv.dev_network.Configuration;
channelnum = pnic_Config->DSConfig;
*(ULONG *)poid_par_priv->information_buf = channelnum;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
return status;
}
NDIS_STATUS oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_key_mismatch_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_supported_wireless_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
ULONG ulInfo = 0 ;
/* DEBUG_ERR(("<**********************oid_rt_supported_wireless_mode_hdl\n")); */
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
ulInfo |= 0x0100; /* WIRELESS_MODE_B */
ulInfo |= 0x0200; /* WIRELESS_MODE_G */
ulInfo |= 0x0400; /* WIRELESS_MODE_A */
*(ULONG *) poid_par_priv->information_buf = ulInfo;
/* DEBUG_ERR(("<===oid_rt_supported_wireless_mode %x\n",ulInfo)); */
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
NDIS_STATUS oid_rt_get_channel_list_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_scan_in_progress_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_forced_data_rate_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
/* ************** oid_rtl_seg_01_01 section end ************** */
/* ************** oid_rtl_seg_01_03 section start ************** */
NDIS_STATUS oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_ap_supported_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_ap_set_passphrase_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
/* ************** oid_rtl_seg_01_03 section end ************** */
/* **************** oid_rtl_seg_01_11 section start **************** */
NDIS_STATUS oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context);
_irqL oldirql;
/* DEBUG_ERR(("<**********************oid_rt_pro_rf_write_registry_hdl\n")); */
if (poid_par_priv->type_of_oid != SET_OID) { /* QUERY_OID */
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
_irqlevel_changed_(&oldirql, LOWER);
if (poid_par_priv->information_buf_len == (sizeof(unsigned long) * 3)) {
/* RegOffsetValue - The offset of RF register to write. */
/* RegDataWidth - The data width of RF register to write. */
/* RegDataValue - The value to write. */
/* RegOffsetValue = *((unsigned long*)InformationBuffer); */
/* RegDataWidth = *((unsigned long*)InformationBuffer+1); */
/* RegDataValue = *((unsigned long*)InformationBuffer+2); */
if (!rtw_setrfreg_cmd(Adapter,
*(unsigned char *)poid_par_priv->information_buf,
(unsigned long)(*((unsigned long *)poid_par_priv->information_buf + 2))))
status = NDIS_STATUS_NOT_ACCEPTED;
} else
status = NDIS_STATUS_INVALID_LENGTH;
_irqlevel_changed_(&oldirql, RAISE);
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
#if 0
PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context);
_irqL oldirql;
/* DEBUG_ERR(("<**********************oid_rt_pro_rf_read_registry_hdl\n")); */
if (poid_par_priv->type_of_oid != SET_OID) { /* QUERY_OID */
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
_irqlevel_changed_(&oldirql, LOWER);
if (poid_par_priv->information_buf_len == (sizeof(unsigned long) * 3)) {
if (Adapter->mppriv.act_in_progress == _TRUE)
status = NDIS_STATUS_NOT_ACCEPTED;
else {
/* init workparam */
Adapter->mppriv.act_in_progress = _TRUE;
Adapter->mppriv.workparam.bcompleted = _FALSE;
Adapter->mppriv.workparam.act_type = MPT_READ_RF;
Adapter->mppriv.workparam.io_offset = *(unsigned long *)poid_par_priv->information_buf;
Adapter->mppriv.workparam.io_value = 0xcccccccc;
/* RegOffsetValue - The offset of RF register to read. */
/* RegDataWidth - The data width of RF register to read. */
/* RegDataValue - The value to read. */
/* RegOffsetValue = *((unsigned long*)InformationBuffer); */
/* RegDataWidth = *((unsigned long*)InformationBuffer+1); */
/* RegDataValue = *((unsigned long*)InformationBuffer+2); */
if (!rtw_getrfreg_cmd(Adapter,
*(unsigned char *)poid_par_priv->information_buf,
(unsigned char *)&Adapter->mppriv.workparam.io_value))
status = NDIS_STATUS_NOT_ACCEPTED;
}
} else
status = NDIS_STATUS_INVALID_LENGTH;
_irqlevel_changed_(&oldirql, RAISE);
#endif
return status;
}
/* **************** oid_rtl_seg_01_11 section end**************** */
/* ************** oid_rtl_seg_03_00 section start ************** */
enum _CONNECT_STATE_ {
CHECKINGSTATUS,
ASSOCIATED,
ADHOCMODE,
NOTASSOCIATED
};
NDIS_STATUS oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
ULONG ulInfo;
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
/* nStatus==0 CheckingStatus */
/* nStatus==1 Associated */
/* nStatus==2 AdHocMode */
/* nStatus==3 NotAssociated */
if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
ulInfo = CHECKINGSTATUS;
else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
ulInfo = ASSOCIATED;
else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
ulInfo = ADHOCMODE;
else
ulInfo = NOTASSOCIATED ;
*(ULONG *)poid_par_priv->information_buf = ulInfo;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
#if 0
/* Rearrange the order to let the UI still shows connection when scan is in progress */
if (pMgntInfo->mAssoc)
ulInfo = 1;
else if (pMgntInfo->mIbss)
ulInfo = 2;
else if (pMgntInfo->bScanInProgress)
ulInfo = 0;
else
ulInfo = 3;
ulInfoLen = sizeof(ULONG);
#endif
return status;
}
NDIS_STATUS oid_rt_set_default_key_id_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
/* ************** oid_rtl_seg_03_00 section end ************** */

930
core/rtw_ioctl_set.c Normal file
View File

@ -0,0 +1,930 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_IOCTL_SET_C_
#include <drv_types.h>
#include <hal_data.h>
extern void indicate_wx_scan_complete_event(_adapter *padapter);
#define IS_MAC_ADDRESS_BROADCAST(addr) \
(\
((addr[0] == 0xff) && (addr[1] == 0xff) && \
(addr[2] == 0xff) && (addr[3] == 0xff) && \
(addr[4] == 0xff) && (addr[5] == 0xff)) ? _TRUE : _FALSE \
)
u8 rtw_validate_bssid(u8 *bssid)
{
u8 ret = _TRUE;
if (is_zero_mac_addr(bssid)
|| is_broadcast_mac_addr(bssid)
|| is_multicast_mac_addr(bssid)
)
ret = _FALSE;
return ret;
}
u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid)
{
#ifdef CONFIG_VALIDATE_SSID
u8 i;
#endif
u8 ret = _TRUE;
if (ssid->SsidLength > 32) {
ret = _FALSE;
goto exit;
}
#ifdef CONFIG_VALIDATE_SSID
for (i = 0; i < ssid->SsidLength; i++) {
/* wifi, printable ascii code must be supported */
if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) {
ret = _FALSE;
break;
}
}
#endif /* CONFIG_VALIDATE_SSID */
exit:
return ret;
}
u8 rtw_do_join(_adapter *padapter);
u8 rtw_do_join(_adapter *padapter)
{
_irqL irqL;
_list *plist, *phead;
u8 *pibss = NULL;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct sitesurvey_parm parm;
_queue *queue = &(pmlmepriv->scanned_queue);
u8 ret = _SUCCESS;
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
phead = get_list_head(queue);
plist = get_next(phead);
pmlmepriv->cur_network.join_res = -2;
set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
pmlmepriv->pscanned = plist;
pmlmepriv->to_join = _TRUE;
rtw_init_sitesurvey_parm(padapter, &parm);
_rtw_memcpy(&parm.ssid[0], &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
parm.ssid_num = 1;
if (_rtw_queue_empty(queue) == _TRUE) {
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
/* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
/* we try to issue sitesurvey firstly */
if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
|| rtw_to_roam(padapter) > 0
) {
u8 ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
if ((ssc_chk == SS_ALLOW) || (ssc_chk == SS_DENY_BUSY_TRAFFIC) ){
/* submit site_survey_cmd */
ret = rtw_sitesurvey_cmd(padapter, &parm);
if (_SUCCESS != ret)
pmlmepriv->to_join = _FALSE;
} else {
/*if (ssc_chk == SS_DENY_BUDDY_UNDER_SURVEY)*/
pmlmepriv->to_join = _FALSE;
ret = _FAIL;
}
} else {
pmlmepriv->to_join = _FALSE;
ret = _FAIL;
}
goto exit;
} else {
int select_ret;
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
if (select_ret == _SUCCESS) {
pmlmepriv->to_join = _FALSE;
_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
} else {
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
/* submit createbss_cmd to change to a ADHOC_MASTER */
/* pmlmepriv->lock has been acquired by caller... */
WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network);
/*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
pibss = padapter->registrypriv.dev_network.MacAddress;
_rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
_rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
rtw_update_registrypriv_dev_network(padapter);
rtw_generate_random_ibss(pibss);
if (rtw_create_ibss_cmd(padapter, 0) != _SUCCESS) {
ret = _FALSE;
goto exit;
}
pmlmepriv->to_join = _FALSE;
} else {
/* can't associate ; reset under-linking */
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
/* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
/* we try to issue sitesurvey firstly */
if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
|| rtw_to_roam(padapter) > 0
) {
u8 ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
if ((ssc_chk == SS_ALLOW) || (ssc_chk == SS_DENY_BUSY_TRAFFIC)){
/* RTW_INFO(("rtw_do_join() when no desired bss in scanning queue\n"); */
ret = rtw_sitesurvey_cmd(padapter, &parm);
if (_SUCCESS != ret)
pmlmepriv->to_join = _FALSE;
} else {
/*if (ssc_chk == SS_DENY_BUDDY_UNDER_SURVEY) {
} else {*/
ret = _FAIL;
pmlmepriv->to_join = _FALSE;
}
} else {
ret = _FAIL;
pmlmepriv->to_join = _FALSE;
}
}
}
}
exit:
return ret;
}
#ifdef PLATFORM_WINDOWS
u8 rtw_pnp_set_power_wakeup(_adapter *padapter)
{
u8 res = _SUCCESS;
res = rtw_setstandby_cmd(padapter, 0);
return res;
}
u8 rtw_pnp_set_power_sleep(_adapter *padapter)
{
u8 res = _SUCCESS;
/* DbgPrint("+rtw_pnp_set_power_sleep\n"); */
res = rtw_setstandby_cmd(padapter, 1);
return res;
}
u8 rtw_set_802_11_reload_defaults(_adapter *padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults)
{
/* SecClearAllKeys(Adapter); */
/* 8711 CAM was not for En/Decrypt only */
/* so, we can't clear all keys. */
/* should we disable WPAcfg (ox0088) bit 1-2, instead of clear all CAM */
/* TO DO... */
return _TRUE;
}
u8 set_802_11_test(_adapter *padapter, NDIS_802_11_TEST *test)
{
u8 ret = _TRUE;
switch (test->Type) {
case 1:
NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->AuthenticationEvent, test->Length - 8);
NdisMIndicateStatusComplete(padapter->hndis_adapter);
break;
case 2:
NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->RssiTrigger, sizeof(NDIS_802_11_RSSI));
NdisMIndicateStatusComplete(padapter->hndis_adapter);
break;
default:
ret = _FALSE;
break;
}
return ret;
}
u8 rtw_set_802_11_pmkid(_adapter *padapter, NDIS_802_11_PMKID *pmkid)
{
u8 ret = _SUCCESS;
return ret;
}
#endif
u8 rtw_set_802_11_bssid(_adapter *padapter, u8 *bssid)
{
_irqL irqL;
u8 status = _SUCCESS;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
RTW_PRINT("set bssid:%pM\n", bssid);
if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
(bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
status = _FAIL;
goto exit;
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
RTW_INFO("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
goto handle_tkip_countermeasure;
else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
goto release_mlme_lock;
if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) {
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)
goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
} else {
rtw_disassoc_cmd(padapter, 0, 0);
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
rtw_indicate_disconnect(padapter, 0, _FALSE);
rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
}
}
}
handle_tkip_countermeasure:
if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
status = _FAIL;
goto release_mlme_lock;
}
_rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
_rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
pmlmepriv->assoc_by_bssid = _TRUE;
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
pmlmepriv->to_join = _TRUE;
else
status = rtw_do_join(padapter);
release_mlme_lock:
_exit_critical_bh(&pmlmepriv->lock, &irqL);
exit:
return status;
}
u8 rtw_set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid)
{
_irqL irqL;
u8 status = _SUCCESS;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_network *pnetwork = &pmlmepriv->cur_network;
RTW_PRINT("set ssid [%s] fw_state=0x%08x\n",
ssid->Ssid, get_fwstate(pmlmepriv));
if (!rtw_is_hw_init_completed(padapter)) {
status = _FAIL;
goto exit;
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
RTW_INFO("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
goto handle_tkip_countermeasure;
else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
goto release_mlme_lock;
if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
(_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) {
if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) {
if (rtw_is_same_ibss(padapter, pnetwork) == _FALSE) {
/* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
rtw_disassoc_cmd(padapter, 0, 0);
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
rtw_indicate_disconnect(padapter, 0, _FALSE);
rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
}
} else {
goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
}
}
#ifdef CONFIG_LPS
else
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
#endif
} else {
rtw_disassoc_cmd(padapter, 0, 0);
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
rtw_indicate_disconnect(padapter, 0, _FALSE);
rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
}
}
}
handle_tkip_countermeasure:
if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
status = _FAIL;
goto release_mlme_lock;
}
if (rtw_validate_ssid(ssid) == _FALSE) {
status = _FAIL;
goto release_mlme_lock;
}
_rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
pmlmepriv->assoc_by_bssid = _FALSE;
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
pmlmepriv->to_join = _TRUE;
else
status = rtw_do_join(padapter);
release_mlme_lock:
_exit_critical_bh(&pmlmepriv->lock, &irqL);
exit:
return status;
}
u8 rtw_set_802_11_connect(_adapter *padapter, u8 *bssid, NDIS_802_11_SSID *ssid)
{
_irqL irqL;
u8 status = _SUCCESS;
bool bssid_valid = _TRUE;
bool ssid_valid = _TRUE;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
if (!ssid || rtw_validate_ssid(ssid) == _FALSE)
ssid_valid = _FALSE;
if (!bssid || rtw_validate_bssid(bssid) == _FALSE)
bssid_valid = _FALSE;
if (ssid_valid == _FALSE && bssid_valid == _FALSE) {
RTW_INFO(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
status = _FAIL;
goto exit;
}
if (!rtw_is_hw_init_completed(padapter)) {
status = _FAIL;
goto exit;
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
RTW_PRINT(FUNC_ADPT_FMT" fw_state=0x%08x\n",
FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
goto handle_tkip_countermeasure;
else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
goto release_mlme_lock;
handle_tkip_countermeasure:
if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
status = _FAIL;
goto release_mlme_lock;
}
if (ssid && ssid_valid)
_rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
else
_rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
if (bssid && bssid_valid) {
_rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
pmlmepriv->assoc_by_bssid = _TRUE;
} else
pmlmepriv->assoc_by_bssid = _FALSE;
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
pmlmepriv->to_join = _TRUE;
else
status = rtw_do_join(padapter);
release_mlme_lock:
_exit_critical_bh(&pmlmepriv->lock, &irqL);
exit:
return status;
}
u8 rtw_set_802_11_infrastructure_mode(_adapter *padapter,
NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, u8 flags)
{
_irqL irqL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = &(cur_network->network.InfrastructureMode);
u8 ap2sta_mode = _FALSE;
u8 ret = _TRUE;
u8 is_linked = _FALSE, is_adhoc_master = _FALSE;
if (*pold_state != networktype) {
/* RTW_INFO("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
if (*pold_state == Ndis802_11APMode
|| *pold_state == Ndis802_11_mesh
) {
/* change to other mode from Ndis802_11APMode/Ndis802_11_mesh */
cur_network->join_res = -1;
ap2sta_mode = _TRUE;
#ifdef CONFIG_NATIVEAP_MLME
stop_ap_mode(padapter);
#endif
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
is_linked = check_fwstate(pmlmepriv, _FW_LINKED);
is_adhoc_master = check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
/* flags = 0, means enqueue cmd and no wait */
if (flags != 0)
_exit_critical_bh(&pmlmepriv->lock, &irqL);
if ((is_linked == _TRUE) || (*pold_state == Ndis802_11IBSS))
rtw_disassoc_cmd(padapter, 0, flags);
if ((is_linked == _TRUE) ||
(is_adhoc_master == _TRUE))
rtw_free_assoc_resources_cmd(padapter, _TRUE, flags);
if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
if (is_linked == _TRUE) {
rtw_indicate_disconnect(padapter, 0, _FALSE); /*will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not*/
}
}
/* flags = 0, means enqueue cmd and no wait */
if (flags != 0)
_enter_critical_bh(&pmlmepriv->lock, &irqL);
*pold_state = networktype;
_clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
switch (networktype) {
case Ndis802_11IBSS:
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
break;
case Ndis802_11Infrastructure:
set_fwstate(pmlmepriv, WIFI_STATION_STATE);
if (ap2sta_mode)
rtw_init_bcmc_stainfo(padapter);
break;
case Ndis802_11APMode:
set_fwstate(pmlmepriv, WIFI_AP_STATE);
#ifdef CONFIG_NATIVEAP_MLME
start_ap_mode(padapter);
/* rtw_indicate_connect(padapter); */
#endif
break;
#ifdef CONFIG_RTW_MESH
case Ndis802_11_mesh:
set_fwstate(pmlmepriv, WIFI_MESH_STATE);
start_ap_mode(padapter);
break;
#endif
case Ndis802_11AutoUnknown:
case Ndis802_11InfrastructureMax:
break;
case Ndis802_11Monitor:
set_fwstate(pmlmepriv, WIFI_MONITOR_STATE);
break;
default:
ret = _FALSE;
rtw_warn_on(1);
}
/* SecClearAllKeys(adapter); */
_exit_critical_bh(&pmlmepriv->lock, &irqL);
}
return ret;
}
u8 rtw_set_802_11_disassociate(_adapter *padapter)
{
_irqL irqL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
_enter_critical_bh(&pmlmepriv->lock, &irqL);
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
rtw_disassoc_cmd(padapter, 0, 0);
rtw_indicate_disconnect(padapter, 0, _FALSE);
/* modify for CONFIG_IEEE80211W, none 11w can use it */
rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
if (_FAIL == rtw_pwr_wakeup(padapter))
RTW_INFO("%s(): rtw_pwr_wakeup fail !!!\n", __FUNCTION__);
}
_exit_critical_bh(&pmlmepriv->lock, &irqL);
return _TRUE;
}
#if 1
u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, struct sitesurvey_parm *pparm)
{
_irqL irqL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
u8 res = _TRUE;
_enter_critical_bh(&pmlmepriv->lock, &irqL);
res = rtw_sitesurvey_cmd(padapter, pparm);
_exit_critical_bh(&pmlmepriv->lock, &irqL);
return res;
}
#else
u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, struct sitesurvey_parm *pparm)
{
_irqL irqL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
u8 res = _TRUE;
if (padapter == NULL) {
res = _FALSE;
goto exit;
}
if (!rtw_is_hw_init_completed(padapter)) {
res = _FALSE;
goto exit;
}
if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) ||
(pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) {
/* Scan or linking is in progress, do nothing. */
res = _TRUE;
} else {
if (rtw_is_scan_deny(padapter)) {
RTW_INFO(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
indicate_wx_scan_complete_event(padapter);
return _SUCCESS;
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
res = rtw_sitesurvey_cmd(padapter, pparm);
_exit_critical_bh(&pmlmepriv->lock, &irqL);
}
exit:
return res;
}
#endif
u8 rtw_set_802_11_authentication_mode(_adapter *padapter, NDIS_802_11_AUTHENTICATION_MODE authmode)
{
struct security_priv *psecuritypriv = &padapter->securitypriv;
int res;
u8 ret;
psecuritypriv->ndisauthtype = authmode;
if (psecuritypriv->ndisauthtype > 3)
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
#ifdef CONFIG_WAPI_SUPPORT
if (psecuritypriv->ndisauthtype == 6)
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
#endif
res = rtw_set_auth(padapter, psecuritypriv);
if (res == _SUCCESS)
ret = _TRUE;
else
ret = _FALSE;
return ret;
}
u8 rtw_set_802_11_add_wep(_adapter *padapter, NDIS_802_11_WEP *wep)
{
u8 bdefaultkey;
u8 btransmitkey;
sint keyid, res;
struct security_priv *psecuritypriv = &(padapter->securitypriv);
u8 ret = _SUCCESS;
bdefaultkey = (wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE; /* for ??? */
btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? _TRUE : _FALSE; /* for ??? */
keyid = wep->KeyIndex & 0x3fffffff;
if (keyid >= 4) {
ret = _FALSE;
goto exit;
}
switch (wep->KeyLength) {
case 5:
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
break;
case 13:
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
break;
default:
psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
break;
}
_rtw_memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
psecuritypriv->dot11PrivacyKeyIndex = keyid;
res = rtw_set_key(padapter, psecuritypriv, keyid, 1, _TRUE);
if (res == _FAIL)
ret = _FALSE;
exit:
return ret;
}
/*
* rtw_get_cur_max_rate -
* @adapter: pointer to _adapter structure
*
* Return 0 or 100Kbps
*/
u16 rtw_get_cur_max_rate(_adapter *adapter)
{
int j;
int i = 0;
u16 rate = 0, max_rate = 0;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
int sta_bssrate_len = 0;
unsigned char sta_bssrate[NumRates];
struct sta_info *psta = NULL;
u8 short_GI = 0;
#ifdef CONFIG_80211N_HT
u8 rf_type = 0;
#endif
#ifdef CONFIG_MP_INCLUDED
if (adapter->registrypriv.mp_mode == 1) {
if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
return 0;
}
#endif
if ((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
&& (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE))
return 0;
psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
if (psta == NULL)
return 0;
short_GI = query_ra_short_GI(psta, rtw_get_tx_bw_mode(adapter, psta));
#ifdef CONFIG_80211N_HT
if (is_supported_ht(psta->wireless_mode)) {
rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
max_rate = rtw_mcs_rate(rf_type
, (psta->cmn.bw_mode == CHANNEL_WIDTH_40) ? 1 : 0
, short_GI
, psta->htpriv.ht_cap.supp_mcs_set
);
}
#ifdef CONFIG_80211AC_VHT
else if (is_supported_vht(psta->wireless_mode))
max_rate = ((rtw_vht_mcs_to_data_rate(psta->cmn.bw_mode, short_GI, pmlmepriv->vhtpriv.vht_highest_rate) + 1) >> 1) * 10;
#endif /* CONFIG_80211AC_VHT */
else
#endif /* CONFIG_80211N_HT */
{
/*station mode show :station && ap support rate; softap :show ap support rate*/
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
get_rate_set(adapter, sta_bssrate, &sta_bssrate_len);/*get sta rate and length*/
while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
rate = pcur_bss->SupportedRates[i] & 0x7F;/*AP support rates*/
/*RTW_INFO("%s rate=%02X \n", __func__, rate);*/
/*check STA support rate or not */
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
for (j = 0; j < sta_bssrate_len; j++) {
/* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
if ((rate | IEEE80211_BASIC_RATE_MASK)
== (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
if (rate > max_rate) {
max_rate = rate;
}
break;
}
}
} else {
if (rate > max_rate)
max_rate = rate;
}
i++;
}
max_rate = max_rate * 10 / 2;
}
return max_rate;
}
/*
* rtw_set_scan_mode -
* @adapter: pointer to _adapter structure
* @scan_mode:
*
* Return _SUCCESS or _FAIL
*/
int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode)
{
if (scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE)
return _FAIL;
adapter->mlmepriv.scan_mode = scan_mode;
return _SUCCESS;
}
/*
* rtw_set_channel_plan -
* @adapter: pointer to _adapter structure
* @channel_plan:
*
* Return _SUCCESS or _FAIL
*/
int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan)
{
/* handle by cmd_thread to sync with scan operation */
return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, 1);
}
/*
* rtw_set_country -
* @adapter: pointer to _adapter structure
* @country_code: string of country code
*
* Return _SUCCESS or _FAIL
*/
int rtw_set_country(_adapter *adapter, const char *country_code)
{
#ifdef CONFIG_RTW_IOCTL_SET_COUNTRY
return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, 1);
#else
RTW_INFO("%s(): not applied\n", __func__);
return _SUCCESS;
#endif
}
/*
* rtw_set_band -
* @adapter: pointer to _adapter structure
* @band: band to set
*
* Return _SUCCESS or _FAIL
*/
int rtw_set_band(_adapter *adapter, u8 band)
{
if (rtw_band_valid(band)) {
RTW_INFO(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band);
adapter->setband = band;
return _SUCCESS;
}
RTW_PRINT(FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band);
return _FAIL;
}

394
core/rtw_iol.c Normal file
View File

@ -0,0 +1,394 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#ifdef CONFIG_IOL
struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter)
{
struct xmit_frame *xmit_frame;
struct xmit_buf *xmitbuf;
struct pkt_attrib *pattrib;
struct xmit_priv *pxmitpriv = &(adapter->xmitpriv);
#if 1
xmit_frame = rtw_alloc_xmitframe(pxmitpriv);
if (xmit_frame == NULL) {
RTW_INFO("%s rtw_alloc_xmitframe return null\n", __FUNCTION__);
goto exit;
}
xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
if (xmitbuf == NULL) {
RTW_INFO("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__);
rtw_free_xmitframe(pxmitpriv, xmit_frame);
xmit_frame = NULL;
goto exit;
}
xmit_frame->frame_tag = MGNT_FRAMETAG;
xmit_frame->pxmitbuf = xmitbuf;
xmit_frame->buf_addr = xmitbuf->pbuf;
xmitbuf->priv_data = xmit_frame;
pattrib = &xmit_frame->attrib;
update_mgntframe_attrib(adapter, pattrib);
pattrib->qsel = QSLT_BEACON;/* Beacon */
pattrib->subtype = WIFI_BEACON;
pattrib->pktlen = pattrib->last_txcmdsz = 0;
#else
xmit_frame = alloc_mgtxmitframe(pxmitpriv);
if (xmit_frame == NULL)
RTW_INFO("%s alloc_mgtxmitframe return null\n", __FUNCTION__);
else {
pattrib = &xmit_frame->attrib;
update_mgntframe_attrib(adapter, pattrib);
pattrib->qsel = QSLT_BEACON;
pattrib->pktlen = pattrib->last_txcmdsz = 0;
}
#endif
exit:
return xmit_frame;
}
int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
{
struct pkt_attrib *pattrib = &xmit_frame->attrib;
u16 buf_offset;
u32 ori_len;
buf_offset = TXDESC_OFFSET;
ori_len = buf_offset + pattrib->pktlen;
/* check if the io_buf can accommodate new cmds */
if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
RTW_INFO("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__
, ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
return _FAIL;
}
_rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
pattrib->pktlen += cmd_len;
pattrib->last_txcmdsz += cmd_len;
/* RTW_INFO("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen); */
return _SUCCESS;
}
bool rtw_IOL_applied(ADAPTER *adapter)
{
if (1 == adapter->registrypriv.fw_iol)
return _TRUE;
#ifdef CONFIG_USB_HCI
if ((2 == adapter->registrypriv.fw_iol) && (IS_FULL_SPEED_USB(adapter)))
return _TRUE;
#endif
return _FALSE;
}
int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
{
return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt);
}
#ifdef CONFIG_IOL_NEW_GENERATION
int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
{
return _SUCCESS;
}
int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, addr); */
/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
cmd.address = cpu_to_le16(addr);
cmd.data = cpu_to_le32(value);
if (mask != 0xFF) {
cmd.length = 12;
/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
cmd.mask = cpu_to_le32(mask);
}
/* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, addr); */
/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
cmd.address = cpu_to_le16(addr);
cmd.data = cpu_to_le32(value);
if (mask != 0xFFFF) {
cmd.length = 12;
/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
cmd.mask = cpu_to_le32(mask);
}
/* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, addr); */
/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
cmd.address = cpu_to_le16(addr);
cmd.data = cpu_to_le32(value);
if (mask != 0xFFFFFFFF) {
cmd.length = 12;
/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
cmd.mask = cpu_to_le32(mask);
}
/* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__, addr,value,mask); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, addr); */
/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
cmd.address = (rf_path << 8) | ((addr) & 0xFF);
cmd.data = cpu_to_le32(value);
if (mask != 0x000FFFFF) {
cmd.length = 12;
/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
cmd.mask = cpu_to_le32(mask);
}
/* RTW_INFO("%s rf_path:0x%02x addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__,rf_path, addr,value,mask); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
{
struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, us); */
cmd.address = cpu_to_le16(us);
/* RTW_INFO("%s %u\n", __FUNCTION__, us); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
}
int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
{
struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, ms); */
cmd.address = cpu_to_le16(ms);
/* RTW_INFO("%s %u\n", __FUNCTION__, ms); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
}
int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
{
struct ioreg_cfg cmd = {4, IOREG_CMD_END, 0xFFFF, 0xFF, 0x0};
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
}
u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
{
u8 is_cmd_bndy = _FALSE;
if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {
rtw_IOL_append_END_cmd(pxmit_frame);
pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);
/* printk("==> %s, pktlen(%d)\n",__FUNCTION__,pxmit_frame->attrib.pktlen); */
pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
is_cmd_bndy = _TRUE;
}
return is_cmd_bndy;
}
void rtw_IOL_cmd_buf_dump(ADAPTER *Adapter, int buf_len, u8 *pbuf)
{
int i;
int j = 1;
printk("###### %s ######\n", __FUNCTION__);
for (i = 0; i < buf_len; i++) {
printk("%02x-", *(pbuf + i));
if (j % 32 == 0)
printk("\n");
j++;
}
printk("\n");
printk("============= ioreg_cmd len = %d ===============\n", buf_len);
}
#else /* CONFIG_IOL_NEW_GENERATION */
int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
{
IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0};
RTW_PUT_BE32((u8 *)&cmd.value, (u32)page_boundary);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value)
{
IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0};
RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value)
{
IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0};
RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value)
{
IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0};
u8 *pos = (u8 *)&cmd;
RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
#ifdef DBG_IO
int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(xmit_frame->padapter, addr, 1, value);
if (ent) {
RTW_INFO("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x) %s\n"
, caller, line, addr, value, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value);
}
int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(xmit_frame->padapter, addr, 2, value);
if (ent) {
RTW_INFO("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x) %s\n"
, caller, line, addr, value, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value);
}
int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line)
{
const struct rtw_io_sniff_ent *ent = match_write_sniff(xmit_frame->padapter, addr, 4, value);
if (ent) {
RTW_INFO("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x) %s\n"
, caller, line, addr, value, rtw_io_sniff_ent_get_tag(ent));
}
return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value);
}
#endif
int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
{
IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0};
RTW_PUT_BE32((u8 *)&cmd.value, (u32)us);
/* RTW_INFO("%s %u\n", __FUNCTION__, us); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
{
IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0};
RTW_PUT_BE32((u8 *)&cmd.value, (u32)ms);
/* RTW_INFO("%s %u\n", __FUNCTION__, ms); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
{
IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&end_cmd, 8);
}
int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms)
{
struct xmit_frame *xmit_frame;
xmit_frame = rtw_IOL_accquire_xmit_frame(adapter);
if (xmit_frame == NULL)
return _FAIL;
if (rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num << 3) == _FAIL)
return _FAIL;
return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms, 0);
}
int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms)
{
IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
return rtw_IOL_exec_cmd_array_sync(adapter, (u8 *)&end_cmd, 1, max_wating_ms);
}
#endif /* CONFIG_IOL_NEW_GENERATION */
#endif /* CONFIG_IOL */

128
core/rtw_mem.c Normal file
View File

@ -0,0 +1,128 @@
/******************************************************************************
*
* Copyright(c) 2016 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <rtw_mem.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek Wireless Lan Driver");
MODULE_AUTHOR("Realtek Semiconductor Corp.");
MODULE_VERSION("DRIVERVERSION");
struct sk_buff_head rtk_skb_mem_q;
struct u8 *rtk_buf_mem[NR_RECVBUFF];
struct u8 *rtw_get_buf_premem(int index)
{
printk("%s, rtk_buf_mem index : %d\n", __func__, index);
return rtk_buf_mem[index];
}
u16 rtw_rtkm_get_buff_size(void)
{
return MAX_RTKM_RECVBUF_SZ;
}
EXPORT_SYMBOL(rtw_rtkm_get_buff_size);
u8 rtw_rtkm_get_nr_recv_skb(void)
{
return MAX_RTKM_NR_PREALLOC_RECV_SKB;
}
EXPORT_SYMBOL(rtw_rtkm_get_nr_recv_skb);
struct sk_buff *rtw_alloc_skb_premem(u16 in_size)
{
struct sk_buff *skb = NULL;
if (in_size > MAX_RTKM_RECVBUF_SZ) {
pr_info("warning %s: driver buffer size(%d) > rtkm buffer size(%d)\n", __func__, in_size, MAX_RTKM_RECVBUF_SZ);
WARN_ON(1);
return skb;
}
skb = skb_dequeue(&rtk_skb_mem_q);
printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
return skb;
}
EXPORT_SYMBOL(rtw_alloc_skb_premem);
int rtw_free_skb_premem(struct sk_buff *pskb)
{
if (!pskb)
return -1;
if (skb_queue_len(&rtk_skb_mem_q) >= MAX_RTKM_NR_PREALLOC_RECV_SKB)
return -1;
skb_queue_tail(&rtk_skb_mem_q, pskb);
printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
return 0;
}
EXPORT_SYMBOL(rtw_free_skb_premem);
static int __init rtw_mem_init(void)
{
int i;
SIZE_PTR tmpaddr = 0;
SIZE_PTR alignment = 0;
struct sk_buff *pskb = NULL;
printk("%s\n", __func__);
pr_info("MAX_RTKM_NR_PREALLOC_RECV_SKB: %d\n", MAX_RTKM_NR_PREALLOC_RECV_SKB);
pr_info("MAX_RTKM_RECVBUF_SZ: %d\n", MAX_RTKM_RECVBUF_SZ);
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
for (i = 0; i < NR_RECVBUFF; i++)
rtk_buf_mem[i] = usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma);
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
skb_queue_head_init(&rtk_skb_mem_q);
for (i = 0; i < MAX_RTKM_NR_PREALLOC_RECV_SKB; i++) {
pskb = __dev_alloc_skb(MAX_RTKM_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
if (pskb) {
tmpaddr = (SIZE_PTR)pskb->data;
alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
skb_queue_tail(&rtk_skb_mem_q, pskb);
} else
printk("%s, alloc skb memory fail!\n", __func__);
pskb = NULL;
}
printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
return 0;
}
static void __exit rtw_mem_exit(void)
{
if (skb_queue_len(&rtk_skb_mem_q))
printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
skb_queue_purge(&rtk_skb_mem_q);
printk("%s\n", __func__);
}
module_init(rtw_mem_init);
module_exit(rtw_mem_exit);

1571
core/rtw_mi.c Normal file

File diff suppressed because it is too large Load Diff

5351
core/rtw_mlme.c Normal file

File diff suppressed because it is too large Load Diff

16783
core/rtw_mlme_ext.c Executable file

File diff suppressed because it is too large Load Diff

3910
core/rtw_mp.c Normal file

File diff suppressed because it is too large Load Diff

2529
core/rtw_mp_ioctl.c Normal file

File diff suppressed because it is too large Load Diff

420
core/rtw_odm.c Normal file
View File

@ -0,0 +1,420 @@
/******************************************************************************
*
* Copyright(c) 2013 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <rtw_odm.h>
#include <hal_data.h>
u32 rtw_phydm_ability_ops(_adapter *adapter, HAL_PHYDM_OPS ops, u32 ability)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
struct dm_struct *podmpriv = &pHalData->odmpriv;
u32 result = 0;
switch (ops) {
case HAL_PHYDM_DIS_ALL_FUNC:
podmpriv->support_ability = DYNAMIC_FUNC_DISABLE;
halrf_cmn_info_set(podmpriv, HALRF_CMNINFO_ABILITY, DYNAMIC_FUNC_DISABLE);
break;
case HAL_PHYDM_FUNC_SET:
podmpriv->support_ability |= ability;
break;
case HAL_PHYDM_FUNC_CLR:
podmpriv->support_ability &= ~(ability);
break;
case HAL_PHYDM_ABILITY_BK:
/* dm flag backup*/
podmpriv->bk_support_ability = podmpriv->support_ability;
pHalData->bk_rf_ability = halrf_cmn_info_get(podmpriv, HALRF_CMNINFO_ABILITY);
break;
case HAL_PHYDM_ABILITY_RESTORE:
/* restore dm flag */
podmpriv->support_ability = podmpriv->bk_support_ability;
halrf_cmn_info_set(podmpriv, HALRF_CMNINFO_ABILITY, pHalData->bk_rf_ability);
break;
case HAL_PHYDM_ABILITY_SET:
podmpriv->support_ability = ability;
break;
case HAL_PHYDM_ABILITY_GET:
result = podmpriv->support_ability;
break;
}
return result;
}
/* set ODM_CMNINFO_IC_TYPE based on chip_type */
void rtw_odm_init_ic_type(_adapter *adapter)
{
struct dm_struct *odm = adapter_to_phydm(adapter);
u4Byte ic_type = chip_type_to_odm_ic_type(rtw_get_chip_type(adapter));
rtw_warn_on(!ic_type);
odm_cmn_info_init(odm, ODM_CMNINFO_IC_TYPE, ic_type);
}
void rtw_odm_adaptivity_ver_msg(void *sel, _adapter *adapter)
{
RTW_PRINT_SEL(sel, "ADAPTIVITY_VERSION "ADAPTIVITY_VERSION"\n");
}
#define RTW_ADAPTIVITY_EN_DISABLE 0
#define RTW_ADAPTIVITY_EN_ENABLE 1
void rtw_odm_adaptivity_en_msg(void *sel, _adapter *adapter)
{
struct registry_priv *regsty = &adapter->registrypriv;
RTW_PRINT_SEL(sel, "RTW_ADAPTIVITY_EN_");
if (regsty->adaptivity_en == RTW_ADAPTIVITY_EN_DISABLE)
_RTW_PRINT_SEL(sel, "DISABLE\n");
else if (regsty->adaptivity_en == RTW_ADAPTIVITY_EN_ENABLE)
_RTW_PRINT_SEL(sel, "ENABLE\n");
else
_RTW_PRINT_SEL(sel, "INVALID\n");
}
#define RTW_ADAPTIVITY_MODE_NORMAL 0
#define RTW_ADAPTIVITY_MODE_CARRIER_SENSE 1
void rtw_odm_adaptivity_mode_msg(void *sel, _adapter *adapter)
{
struct registry_priv *regsty = &adapter->registrypriv;
RTW_PRINT_SEL(sel, "RTW_ADAPTIVITY_MODE_");
if (regsty->adaptivity_mode == RTW_ADAPTIVITY_MODE_NORMAL)
_RTW_PRINT_SEL(sel, "NORMAL\n");
else if (regsty->adaptivity_mode == RTW_ADAPTIVITY_MODE_CARRIER_SENSE)
_RTW_PRINT_SEL(sel, "CARRIER_SENSE\n");
else
_RTW_PRINT_SEL(sel, "INVALID\n");
}
void rtw_odm_adaptivity_config_msg(void *sel, _adapter *adapter)
{
rtw_odm_adaptivity_ver_msg(sel, adapter);
rtw_odm_adaptivity_en_msg(sel, adapter);
rtw_odm_adaptivity_mode_msg(sel, adapter);
}
bool rtw_odm_adaptivity_needed(_adapter *adapter)
{
struct registry_priv *regsty = &adapter->registrypriv;
bool ret = _FALSE;
if (regsty->adaptivity_en == RTW_ADAPTIVITY_EN_ENABLE)
ret = _TRUE;
return ret;
}
void rtw_odm_adaptivity_parm_msg(void *sel, _adapter *adapter)
{
struct dm_struct *odm = adapter_to_phydm(adapter);
rtw_odm_adaptivity_config_msg(sel, adapter);
RTW_PRINT_SEL(sel, "%10s %16s\n"
, "th_l2h_ini", "th_edcca_hl_diff");
RTW_PRINT_SEL(sel, "0x%-8x %-16d\n"
, (u8)odm->th_l2h_ini
, odm->th_edcca_hl_diff
);
}
void rtw_odm_adaptivity_parm_set(_adapter *adapter, s8 th_l2h_ini, s8 th_edcca_hl_diff)
{
struct dm_struct *odm = adapter_to_phydm(adapter);
odm->th_l2h_ini = th_l2h_ini;
odm->th_edcca_hl_diff = th_edcca_hl_diff;
}
void rtw_odm_get_perpkt_rssi(void *sel, _adapter *adapter)
{
struct dm_struct *odm = adapter_to_phydm(adapter);
RTW_PRINT_SEL(sel, "rx_rate = %s, rssi_a = %d(%%), rssi_b = %d(%%)\n",
HDATA_RATE(odm->rx_rate), odm->rssi_a, odm->rssi_b);
}
void rtw_odm_acquirespinlock(_adapter *adapter, enum rt_spinlock_type type)
{
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
_irqL irqL;
switch (type) {
case RT_IQK_SPINLOCK:
_enter_critical_bh(&pHalData->IQKSpinLock, &irqL);
default:
break;
}
}
void rtw_odm_releasespinlock(_adapter *adapter, enum rt_spinlock_type type)
{
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
_irqL irqL;
switch (type) {
case RT_IQK_SPINLOCK:
_exit_critical_bh(&pHalData->IQKSpinLock, &irqL);
default:
break;
}
}
inline u8 rtw_odm_get_dfs_domain(struct dvobj_priv *dvobj)
{
#ifdef CONFIG_DFS_MASTER
struct dm_struct *pDM_Odm = dvobj_to_phydm(dvobj);
return pDM_Odm->dfs_region_domain;
#else
return PHYDM_DFS_DOMAIN_UNKNOWN;
#endif
}
inline u8 rtw_odm_dfs_domain_unknown(struct dvobj_priv *dvobj)
{
#ifdef CONFIG_DFS_MASTER
return rtw_odm_get_dfs_domain(dvobj) == PHYDM_DFS_DOMAIN_UNKNOWN;
#else
return 1;
#endif
}
#ifdef CONFIG_DFS_MASTER
inline VOID rtw_odm_radar_detect_reset(_adapter *adapter)
{
phydm_radar_detect_reset(adapter_to_phydm(adapter));
}
inline VOID rtw_odm_radar_detect_disable(_adapter *adapter)
{
phydm_radar_detect_disable(adapter_to_phydm(adapter));
}
/* called after ch, bw is set */
inline VOID rtw_odm_radar_detect_enable(_adapter *adapter)
{
phydm_radar_detect_enable(adapter_to_phydm(adapter));
}
inline BOOLEAN rtw_odm_radar_detect(_adapter *adapter)
{
return phydm_radar_detect(adapter_to_phydm(adapter));
}
inline u8 rtw_odm_radar_detect_polling_int_ms(struct dvobj_priv *dvobj)
{
return phydm_dfs_polling_time(dvobj_to_phydm(dvobj));
}
#endif /* CONFIG_DFS_MASTER */
void rtw_odm_parse_rx_phy_status_chinfo(union recv_frame *rframe, u8 *phys)
{
#ifndef DBG_RX_PHYSTATUS_CHINFO
#define DBG_RX_PHYSTATUS_CHINFO 0
#endif
#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
_adapter *adapter = rframe->u.hdr.adapter;
struct dm_struct *phydm = adapter_to_phydm(adapter);
struct rx_pkt_attrib *attrib = &rframe->u.hdr.attrib;
u8 *wlanhdr = get_recvframe_data(rframe);
if (phydm->support_ic_type & PHYSTS_2ND_TYPE_IC) {
/*
* 8723D:
* type_0(CCK)
* l_rxsc
* is filled with primary channel SC, not real rxsc.
* 0:LSC, 1:USC
* type_1(OFDM)
* rf_mode
* RF bandwidth when RX
* l_rxsc(legacy), ht_rxsc
* see below RXSC N-series
* type_2(Not used)
*/
/*
* 8821C, 8822B:
* type_0(CCK)
* l_rxsc
* is filled with primary channel SC, not real rxsc.
* 0:LSC, 1:USC
* type_1(OFDM)
* rf_mode
* RF bandwidth when RX
* l_rxsc(legacy), ht_rxsc
* see below RXSC AC-series
* type_2(Not used)
*/
if ((*phys & 0xf) == 0) {
struct phy_sts_rpt_jgr2_type0 *phys_t0 = (struct phy_sts_rpt_jgr2_type0 *)phys;
if (DBG_RX_PHYSTATUS_CHINFO) {
RTW_PRINT("phys_t%u ta="MAC_FMT" %s, %s(band:%u, ch:%u, l_rxsc:%u)\n"
, *phys & 0xf
, MAC_ARG(get_ta(wlanhdr))
, is_broadcast_mac_addr(get_ra(wlanhdr)) ? "BC" : is_multicast_mac_addr(get_ra(wlanhdr)) ? "MC" : "UC"
, HDATA_RATE(attrib->data_rate)
, phys_t0->band, phys_t0->channel, phys_t0->rxsc
);
}
} else if ((*phys & 0xf) == 1) {
struct phy_sts_rpt_jgr2_type1 *phys_t1 = (struct phy_sts_rpt_jgr2_type1 *)phys;
u8 rxsc = (attrib->data_rate > DESC_RATE11M && attrib->data_rate < DESC_RATEMCS0) ? phys_t1->l_rxsc : phys_t1->ht_rxsc;
u8 pkt_cch = 0;
u8 pkt_bw = CHANNEL_WIDTH_20;
#if ODM_IC_11N_SERIES_SUPPORT
if (phydm->support_ic_type & ODM_IC_11N_SERIES) {
/* RXSC N-series */
#define RXSC_DUP 0
#define RXSC_LSC 1
#define RXSC_USC 2
#define RXSC_40M 3
static const s8 cch_offset_by_rxsc[4] = {0, -2, 2, 0};
if (phys_t1->rf_mode == 0) {
pkt_cch = phys_t1->channel;
pkt_bw = CHANNEL_WIDTH_20;
} else if (phys_t1->rf_mode == 1) {
if (rxsc == RXSC_LSC || rxsc == RXSC_USC) {
pkt_cch = phys_t1->channel + cch_offset_by_rxsc[rxsc];
pkt_bw = CHANNEL_WIDTH_20;
} else if (rxsc == RXSC_40M) {
pkt_cch = phys_t1->channel;
pkt_bw = CHANNEL_WIDTH_40;
}
} else
rtw_warn_on(1);
goto type1_end;
}
#endif /* ODM_IC_11N_SERIES_SUPPORT */
#if ODM_IC_11AC_SERIES_SUPPORT
if (phydm->support_ic_type & ODM_IC_11AC_SERIES) {
/* RXSC AC-series */
#define RXSC_DUP 0 /* 0: RX from all SC of current rf_mode */
#define RXSC_LL20M_OF_160M 8 /* 1~8: RX from 20MHz SC */
#define RXSC_L20M_OF_160M 6
#define RXSC_L20M_OF_80M 4
#define RXSC_L20M_OF_40M 2
#define RXSC_U20M_OF_40M 1
#define RXSC_U20M_OF_80M 3
#define RXSC_U20M_OF_160M 5
#define RXSC_UU20M_OF_160M 7
#define RXSC_L40M_OF_160M 12 /* 9~12: RX from 40MHz SC */
#define RXSC_L40M_OF_80M 10
#define RXSC_U40M_OF_80M 9
#define RXSC_U40M_OF_160M 11
#define RXSC_L80M_OF_160M 14 /* 13~14: RX from 80MHz SC */
#define RXSC_U80M_OF_160M 13
static const s8 cch_offset_by_rxsc[15] = {0, 2, -2, 6, -6, 10, -10, 14, -14, 4, -4, 12, -12, 8, -8};
if (phys_t1->rf_mode > 3) {
/* invalid rf_mode */
rtw_warn_on(1);
goto type1_end;
}
if (phys_t1->rf_mode == 0) {
/* RF 20MHz */
pkt_cch = phys_t1->channel;
pkt_bw = CHANNEL_WIDTH_20;
goto type1_end;
}
if (rxsc == 0) {
/* RF and RX with same BW */
if (attrib->data_rate >= DESC_RATEMCS0) {
pkt_cch = phys_t1->channel;
pkt_bw = phys_t1->rf_mode;
}
goto type1_end;
}
if ((phys_t1->rf_mode == 1 && rxsc >= 1 && rxsc <= 2) /* RF 40MHz, RX 20MHz */
|| (phys_t1->rf_mode == 2 && rxsc >= 1 && rxsc <= 4) /* RF 80MHz, RX 20MHz */
|| (phys_t1->rf_mode == 3 && rxsc >= 1 && rxsc <= 8) /* RF 160MHz, RX 20MHz */
) {
pkt_cch = phys_t1->channel + cch_offset_by_rxsc[rxsc];
pkt_bw = CHANNEL_WIDTH_20;
} else if ((phys_t1->rf_mode == 2 && rxsc >= 9 && rxsc <= 10) /* RF 80MHz, RX 40MHz */
|| (phys_t1->rf_mode == 3 && rxsc >= 9 && rxsc <= 12) /* RF 160MHz, RX 40MHz */
) {
if (attrib->data_rate >= DESC_RATEMCS0) {
pkt_cch = phys_t1->channel + cch_offset_by_rxsc[rxsc];
pkt_bw = CHANNEL_WIDTH_40;
}
} else if ((phys_t1->rf_mode == 3 && rxsc >= 13 && rxsc <= 14) /* RF 160MHz, RX 80MHz */
) {
if (attrib->data_rate >= DESC_RATEMCS0) {
pkt_cch = phys_t1->channel + cch_offset_by_rxsc[rxsc];
pkt_bw = CHANNEL_WIDTH_80;
}
} else
rtw_warn_on(1);
}
#endif /* ODM_IC_11AC_SERIES_SUPPORT */
type1_end:
if (DBG_RX_PHYSTATUS_CHINFO) {
RTW_PRINT("phys_t%u ta="MAC_FMT" %s, %s(band:%u, ch:%u, rf_mode:%u, l_rxsc:%u, ht_rxsc:%u) => %u,%u\n"
, *phys & 0xf
, MAC_ARG(get_ta(wlanhdr))
, is_broadcast_mac_addr(get_ra(wlanhdr)) ? "BC" : is_multicast_mac_addr(get_ra(wlanhdr)) ? "MC" : "UC"
, HDATA_RATE(attrib->data_rate)
, phys_t1->band, phys_t1->channel, phys_t1->rf_mode, phys_t1->l_rxsc, phys_t1->ht_rxsc
, pkt_cch, pkt_bw
);
}
/* for now, only return cneter channel of 20MHz packet */
if (pkt_cch && pkt_bw == CHANNEL_WIDTH_20)
attrib->ch = pkt_cch;
} else {
struct phy_sts_rpt_jgr2_type2 *phys_t2 = (struct phy_sts_rpt_jgr2_type2 *)phys;
if (DBG_RX_PHYSTATUS_CHINFO) {
RTW_PRINT("phys_t%u ta="MAC_FMT" %s, %s(band:%u, ch:%u, l_rxsc:%u, ht_rxsc:%u)\n"
, *phys & 0xf
, MAC_ARG(get_ta(wlanhdr))
, is_broadcast_mac_addr(get_ra(wlanhdr)) ? "BC" : is_multicast_mac_addr(get_ra(wlanhdr)) ? "MC" : "UC"
, HDATA_RATE(attrib->data_rate)
, phys_t2->band, phys_t2->channel, phys_t2->l_rxsc, phys_t2->ht_rxsc
);
}
}
}
#endif /* (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) */
}

5455
core/rtw_p2p.c Normal file

File diff suppressed because it is too large Load Diff

2792
core/rtw_pwrctrl.c Normal file

File diff suppressed because it is too large Load Diff

5090
core/rtw_recv.c Executable file

File diff suppressed because it is too large Load Diff

1384
core/rtw_rf.c Normal file

File diff suppressed because it is too large Load Diff

2470
core/rtw_rm.c Normal file

File diff suppressed because it is too large Load Diff

998
core/rtw_rm_fsm.c Normal file
View File

@ -0,0 +1,998 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <hal_data.h>
#include "rtw_rm_fsm.h"
#ifdef CONFIG_RTW_80211K
struct fsm_state {
u8 *name;
int(*fsm_func)(struct rm_obj *prm, enum RM_EV_ID evid);
};
static void rm_state_initial(struct rm_obj *prm);
static void rm_state_goto(struct rm_obj *prm, enum RM_STATE rm_state);
static void rm_state_run(struct rm_obj *prm, enum RM_EV_ID evid);
static struct rm_event *rm_dequeue_ev(_queue *queue);
static struct rm_obj *rm_dequeue_rm(_queue *queue);
void rm_timer_callback(void *data)
{
int i;
_adapter *padapter = (_adapter *)data;
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_clock *pclock;
/* deal with clock */
for (i=0;i<RM_TIMER_NUM;i++) {
pclock = &prmpriv->clock[i];
if (pclock->prm == NULL
||(ATOMIC_READ(&(pclock->counter)) == 0))
continue;
ATOMIC_DEC(&(pclock->counter));
if (ATOMIC_READ(&(pclock->counter)) == 0)
rm_post_event(pclock->prm->psta->padapter,
pclock->prm->rmid, prmpriv->clock[i].evid);
}
_set_timer(&prmpriv->rm_timer, CLOCK_UNIT);
}
int rtw_init_rm(_adapter *padapter)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
RTW_INFO("RM: %s\n",__func__);
_rtw_init_queue(&(prmpriv->rm_queue));
_rtw_init_queue(&(prmpriv->ev_queue));
/* bit 0-7 */
prmpriv->rm_en_cap_def[0] = 0
/*| BIT(RM_LINK_MEAS_CAP_EN)*/
| BIT(RM_NB_REP_CAP_EN)
/*| BIT(RM_PARAL_MEAS_CAP_EN)*/
| BIT(RM_REPEAT_MEAS_CAP_EN)
| BIT(RM_BCN_PASSIVE_MEAS_CAP_EN)
| BIT(RM_BCN_ACTIVE_MEAS_CAP_EN)
| BIT(RM_BCN_TABLE_MEAS_CAP_EN)
/*| BIT(RM_BCN_MEAS_REP_COND_CAP_EN)*/;
/* bit 8-15 */
prmpriv->rm_en_cap_def[1] = 0
/*| BIT(RM_FRAME_MEAS_CAP_EN - 8)*/
#ifdef CONFIG_RTW_ACS
| BIT(RM_CH_LOAD_CAP_EN - 8)
| BIT(RM_NOISE_HISTO_CAP_EN - 8)
#endif
/*| BIT(RM_STATIS_MEAS_CAP_EN - 8)*/
/*| BIT(RM_LCI_MEAS_CAP_EN - 8)*/
/*| BIT(RM_LCI_AMIMUTH_CAP_EN - 8)*/
/*| BIT(RM_TRANS_STREAM_CAT_MEAS_CAP_EN - 8)*/
/*| BIT(RM_TRIG_TRANS_STREAM_CAT_MEAS_CAP_EN - 8)*/;
/* bit 16-23 */
prmpriv->rm_en_cap_def[2] = 0
/*| BIT(RM_AP_CH_REP_CAP_EN - 16)*/
/*| BIT(RM_RM_MIB_CAP_EN - 16)*/
/*| BIT(RM_OP_CH_MAX_MEAS_DUR0 - 16)*/
/*| BIT(RM_OP_CH_MAX_MEAS_DUR1 - 16)*/
/*| BIT(RM_OP_CH_MAX_MEAS_DUR2 - 16)*/
/*| BIT(RM_NONOP_CH_MAX_MEAS_DUR0 - 16)*/
/*| BIT(RM_NONOP_CH_MAX_MEAS_DUR1 - 16)*/
/*| BIT(RM_NONOP_CH_MAX_MEAS_DUR2 - 16)*/;
/* bit 24-31 */
prmpriv->rm_en_cap_def[3] = 0
/*| BIT(RM_MEAS_PILOT_CAP0 - 24)*/
/*| BIT(RM_MEAS_PILOT_CAP1 - 24)*/
/*| BIT(RM_MEAS_PILOT_CAP2 - 24)*/
/*| BIT(RM_MEAS_PILOT_TRANS_INFO_CAP_EN - 24)*/
/*| BIT(RM_NB_REP_TSF_OFFSET_CAP_EN - 24)*/
| BIT(RM_RCPI_MEAS_CAP_EN - 24)
| BIT(RM_RSNI_MEAS_CAP_EN - 24)
/*| BIT(RM_BSS_AVG_ACCESS_DELAY_CAP_EN - 24)*/;
/* bit 32-39 */
prmpriv->rm_en_cap_def[4] = 0
/*| BIT(RM_BSS_AVG_ACCESS_DELAY_CAP_EN - 32)*/
/*| BIT(RM_AVALB_ADMIS_CAPACITY_CAP_EN - 32)*/
/*| BIT(RM_ANT_CAP_EN - 32)*/;
prmpriv->enable = _TRUE;
/* clock timer */
rtw_init_timer(&prmpriv->rm_timer,
padapter, rm_timer_callback, padapter);
_set_timer(&prmpriv->rm_timer, CLOCK_UNIT);
return _SUCCESS;
}
int rtw_deinit_rm(_adapter *padapter)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_obj *prm;
struct rm_event *pev;
RTW_INFO("RM: %s\n",__func__);
prmpriv->enable = _FALSE;
_cancel_timer_ex(&prmpriv->rm_timer);
/* free all events and measurements */
while((pev = rm_dequeue_ev(&prmpriv->ev_queue)) != NULL)
rtw_mfree((void *)pev, sizeof(struct rm_event));
while((prm = rm_dequeue_rm(&prmpriv->rm_queue)) != NULL)
rm_state_run(prm, RM_EV_cancel);
_rtw_deinit_queue(&(prmpriv->rm_queue));
_rtw_deinit_queue(&(prmpriv->ev_queue));
return _SUCCESS;
}
int rtw_free_rm_priv(_adapter *padapter)
{
return rtw_deinit_rm(padapter);
}
static int rm_enqueue_ev(_queue *queue, struct rm_event *obj, bool to_head)
{
_irqL irqL;
if (obj == NULL)
return _FAIL;
_enter_critical(&queue->lock, &irqL);
if (to_head)
rtw_list_insert_head(&obj->list, &queue->queue);
else
rtw_list_insert_tail(&obj->list, &queue->queue);
_exit_critical(&queue->lock, &irqL);
return _SUCCESS;
}
static void rm_set_clock(struct rm_obj *prm, u32 ms, enum RM_EV_ID evid)
{
ATOMIC_SET(&(prm->pclock->counter), (ms/CLOCK_UNIT));
prm->pclock->evid = evid;
}
static struct rm_clock *rm_alloc_clock(_adapter *padapter, struct rm_obj *prm)
{
int i;
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_clock *pclock = NULL;
for (i=0;i<RM_TIMER_NUM;i++) {
pclock = &prmpriv->clock[i];
if (pclock->prm == NULL) {
pclock->prm = prm;
ATOMIC_SET(&(pclock->counter), 0);
pclock->evid = RM_EV_max;
break;
}
}
return pclock;
}
static void rm_cancel_clock(struct rm_obj *prm)
{
ATOMIC_SET(&(prm->pclock->counter), 0);
prm->pclock->evid = RM_EV_max;
}
static void rm_free_clock(struct rm_clock *pclock)
{
pclock->prm = NULL;
ATOMIC_SET(&(pclock->counter), 0);
pclock->evid = RM_EV_max;
}
static int is_list_linked(const struct list_head *head)
{
return head->prev != NULL;
}
void rm_free_rmobj(struct rm_obj *prm)
{
if (is_list_linked(&prm->list))
rtw_list_delete(&prm->list);
if (prm->q.pssid)
rtw_mfree(prm->q.pssid, strlen(prm->q.pssid)+1);
if (prm->q.opt.bcn.req_start)
rtw_mfree(prm->q.opt.bcn.req_start,
prm->q.opt.bcn.req_len);
if (prm->pclock)
rm_free_clock(prm->pclock);
rtw_mfree((void *)prm, sizeof(struct rm_obj));
}
struct rm_obj *rm_alloc_rmobj(_adapter *padapter)
{
struct rm_obj *prm;
prm = (struct rm_obj *)rtw_malloc(sizeof(struct rm_obj));
if (prm == NULL)
return NULL;
_rtw_memset(prm, 0, sizeof(struct rm_obj));
/* alloc timer */
if ((prm->pclock = rm_alloc_clock(padapter, prm)) == NULL) {
rm_free_rmobj(prm);
return NULL;
}
return prm;
}
int rm_enqueue_rmobj(_adapter *padapter, struct rm_obj *prm, bool to_head)
{
_irqL irqL;
struct rm_priv *prmpriv = &padapter->rmpriv;
_queue *queue = &prmpriv->rm_queue;
if (prm == NULL)
return _FAIL;
_enter_critical(&queue->lock, &irqL);
if (to_head)
rtw_list_insert_head(&prm->list, &queue->queue);
else
rtw_list_insert_tail(&prm->list, &queue->queue);
_exit_critical(&queue->lock, &irqL);
rm_state_initial(prm);
return _SUCCESS;
}
static struct rm_obj *rm_dequeue_rm(_queue *queue)
{
_irqL irqL;
struct rm_obj *prm;
_enter_critical(&queue->lock, &irqL);
if (rtw_is_list_empty(&(queue->queue)))
prm = NULL;
else {
prm = LIST_CONTAINOR(get_next(&(queue->queue)),
struct rm_obj, list);
/* rtw_list_delete(&prm->list); */
}
_exit_critical(&queue->lock, &irqL);
return prm;
}
static struct rm_event *rm_dequeue_ev(_queue *queue)
{
_irqL irqL;
struct rm_event *ev;
_enter_critical(&queue->lock, &irqL);
if (rtw_is_list_empty(&(queue->queue)))
ev = NULL;
else {
ev = LIST_CONTAINOR(get_next(&(queue->queue)),
struct rm_event, list);
rtw_list_delete(&ev->list);
}
_exit_critical(&queue->lock, &irqL);
return ev;
}
static struct rm_obj *_rm_get_rmobj(_queue *queue, u32 rmid)
{
_irqL irqL;
_list *phead, *plist;
struct rm_obj *prm = NULL;
if (rmid == 0)
return NULL;
_enter_critical(&queue->lock, &irqL);
phead = get_list_head(queue);
plist = get_next(phead);
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
prm = LIST_CONTAINOR(plist, struct rm_obj, list);
if (rmid == (prm->rmid)) {
_exit_critical(&queue->lock, &irqL);
return prm;
}
plist = get_next(plist);
}
_exit_critical(&queue->lock, &irqL);
return NULL;
}
struct sta_info *rm_get_psta(_adapter *padapter, u32 rmid)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_obj *prm;
prm = _rm_get_rmobj(&prmpriv->rm_queue, rmid);
if (prm)
return prm->psta;
return NULL;
}
struct rm_obj *rm_get_rmobj(_adapter *padapter, u32 rmid)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
return _rm_get_rmobj(&prmpriv->rm_queue, rmid);
}
u8 rtw_rm_post_envent_cmd(_adapter *padapter, u32 rmid, u8 evid)
{
struct cmd_obj *pcmd;
struct rm_event *pev;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
u8 res = _SUCCESS;
pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
if (pcmd == NULL) {
res = _FAIL;
goto exit;
}
pev = (struct rm_event*)rtw_zmalloc(sizeof(struct rm_event));
if (pev == NULL) {
rtw_mfree((u8 *) pcmd, sizeof(struct cmd_obj));
res = _FAIL;
goto exit;
}
pev->rmid = rmid;
pev->evid = evid;
init_h2fwcmd_w_parm_no_rsp(pcmd, pev, GEN_CMD_CODE(_RM_POST_EVENT));
res = rtw_enqueue_cmd(pcmdpriv, pcmd);
exit:
return res;
}
int rm_post_event(_adapter *padapter, u32 rmid, enum RM_EV_ID evid)
{
if (padapter->rmpriv.enable == _FALSE)
return _FALSE;
RTW_INFO("RM: post asyn %s to rmid=%x\n", rm_event_name(evid), rmid);
rtw_rm_post_envent_cmd(padapter, rmid, evid);
return _SUCCESS;
}
int _rm_post_event(_adapter *padapter, u32 rmid, enum RM_EV_ID evid)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_event *pev;
if (evid >= RM_EV_max || rmid == 0)
return _FALSE;
pev = (struct rm_event *)rtw_malloc(sizeof(struct rm_event));
if (pev == NULL)
return _FALSE;
pev->rmid = rmid;
pev->evid = evid;
RTW_INFO("RM: post sync %s to rmid=%x\n", rm_event_name(evid), rmid);
rm_enqueue_ev(&prmpriv->ev_queue, pev, FALSE);
return _SUCCESS;
}
static void rm_bcast_aid_handler(_adapter *padapter, struct rm_event *pev)
{
_irqL irqL;
_list *phead, *plist;
_queue *queue = &padapter->rmpriv.rm_queue;
struct rm_obj *prm;
_enter_critical(&queue->lock, &irqL);
phead = get_list_head(queue);
plist = get_next(phead);
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
prm = LIST_CONTAINOR(plist, struct rm_obj, list);
plist = get_next(plist);
if (RM_GET_AID(pev->rmid) == RM_GET_AID(prm->rmid)) {
_exit_critical(&queue->lock, &irqL);
rm_state_run(prm, pev->evid);
_enter_critical(&queue->lock, &irqL);
}
}
_exit_critical(&queue->lock, &irqL);
return;
}
/* main handler of RM (Resource Management) */
void rm_handler(_adapter *padapter, struct rm_event *pe)
{
int i;
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_obj *prm;
struct rm_event *pev;
/* dequeue event */
while((pev = rm_dequeue_ev(&prmpriv->ev_queue)) != NULL)
{
if (RM_IS_ID_FOR_ALL(pev->rmid)) {
/* apply to all aid mateched measurement */
rm_bcast_aid_handler(padapter, pev);
rtw_mfree((void *)pev, sizeof(struct rm_event));
continue;
}
/* retrieve rmobj */
prm = _rm_get_rmobj(&prmpriv->rm_queue, pev->rmid);
if (prm == NULL) {
RTW_ERR("RM: rmid=%x event=%s doesn't find rm obj\n",
pev->rmid, rm_event_name(pev->evid));
rtw_mfree((void *)pev, sizeof(struct rm_event));
return;
}
/* run state machine */
rm_state_run(prm, pev->evid);
rtw_mfree((void *)pev, sizeof(struct rm_event));
}
}
static int rm_issue_meas_req(struct rm_obj *prm)
{
switch (prm->q.action_code) {
case RM_ACT_RADIO_MEAS_REQ:
switch (prm->q.m_type) {
case bcn_req:
case ch_load_req:
case noise_histo_req:
issue_radio_meas_req(prm);
break;
default:
break;
} /* meas_type */
break;
case RM_ACT_NB_REP_REQ:
/* issue neighbor request */
issue_nb_req(prm);
break;
case RM_ACT_LINK_MEAS_REQ:
default:
return _FALSE;
} /* action_code */
return _SUCCESS;
}
/*
* RM state machine
*/
static int rm_state_idle(struct rm_obj *prm, enum RM_EV_ID evid)
{
_adapter *padapter = prm->psta->padapter;
u8 val8;
u32 val32;
prm->p.category = RTW_WLAN_CATEGORY_RADIO_MEAS;
switch (evid) {
case RM_EV_state_in:
switch (prm->q.action_code) {
case RM_ACT_RADIO_MEAS_REQ:
/* copy attrib from meas_req to meas_rep */
prm->p.action_code = RM_ACT_RADIO_MEAS_REP;
prm->p.diag_token = prm->q.diag_token;
prm->p.e_id = _MEAS_RSP_IE_;
prm->p.m_token = prm->q.m_token;
prm->p.m_type = prm->q.m_type;
prm->p.rpt = prm->q.rpt;
prm->p.ch_num = prm->q.ch_num;
prm->p.op_class = prm->q.op_class;
if (prm->q.m_type == ch_load_req
|| prm->q.m_type == noise_histo_req) {
/*
* phydm measure current ch periodically
* scan current ch is not necessary
*/
val8 = padapter->mlmeextpriv.cur_channel;
if (prm->q.ch_num == val8)
prm->poll_mode = 1;
}
RTW_INFO("RM: rmid=%x %s switch in repeat=%u\n",
prm->rmid, rm_type_req_name(prm->q.m_type),
prm->q.rpt);
break;
case RM_ACT_NB_REP_REQ:
prm->p.action_code = RM_ACT_NB_REP_RESP;
RTW_INFO("RM: rmid=%x Neighbor request switch in\n",
prm->rmid);
break;
case RM_ACT_LINK_MEAS_REQ:
prm->p.action_code = RM_ACT_LINK_MEAS_REP;
rm_set_rep_mode(prm, MEAS_REP_MOD_INCAP);
RTW_INFO("RM: rmid=%x Link meas switch in\n",
prm->rmid);
break;
default:
prm->p.action_code = prm->q.action_code;
rm_set_rep_mode(prm, MEAS_REP_MOD_INCAP);
RTW_INFO("RM: rmid=%x recv unknown action %d\n",
prm->rmid,prm->p.action_code);
break;
} /* switch() */
if (prm->rmid & RM_MASTER) {
if (rm_issue_meas_req(prm) == _SUCCESS)
rm_state_goto(prm, RM_ST_WAIT_MEAS);
else
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
} else {
rm_state_goto(prm, RM_ST_DO_MEAS);
return _SUCCESS;
}
if (prm->p.m_mode) {
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
if (prm->q.rand_intvl) {
/* get low tsf to generate random interval */
val32 = rtw_read32(padapter, REG_TSFTR);
val32 = val32 % prm->q.rand_intvl;
RTW_INFO("RM: rmid=%x rand_intval=%d, rand=%d\n",
prm->rmid, (int)prm->q.rand_intvl,val32);
rm_set_clock(prm, prm->q.rand_intvl,
RM_EV_delay_timer_expire);
return _SUCCESS;
}
break;
case RM_EV_delay_timer_expire:
rm_state_goto(prm, RM_ST_DO_MEAS);
break;
case RM_EV_cancel:
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
break;
default:
break;
}
return _SUCCESS;
}
/* we do the measuring */
static int rm_state_do_meas(struct rm_obj *prm, enum RM_EV_ID evid)
{
_adapter *padapter = prm->psta->padapter;
u8 val8;
u64 val64;
switch (evid) {
case RM_EV_state_in:
if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
switch (prm->q.m_type) {
case bcn_req:
if (prm->q.m_mode == bcn_req_bcn_table) {
RTW_INFO("RM: rmid=%x Beacon table\n",
prm->rmid);
_rm_post_event(padapter, prm->rmid,
RM_EV_survey_done);
return _SUCCESS;
}
break;
case ch_load_req:
case noise_histo_req:
if (prm->poll_mode)
_rm_post_event(padapter, prm->rmid,
RM_EV_survey_done);
return _SUCCESS;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
if (!ready_for_scan(prm)) {
prm->wait_busy = RM_BUSY_TRAFFIC_TIMES;
RTW_INFO("RM: wait busy traffic - %d\n",
prm->wait_busy);
rm_set_clock(prm, RM_WAIT_BUSY_TIMEOUT,
RM_EV_busy_timer_expire);
return _SUCCESS;
}
}
_rm_post_event(padapter, prm->rmid, RM_EV_start_meas);
break;
case RM_EV_start_meas:
if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
/* resotre measurement start time */
prm->meas_start_time = rtw_hal_get_tsftr_by_port(padapter
, rtw_hal_get_port(padapter));
switch (prm->q.m_type) {
case bcn_req:
val8 = 1; /* Enable free run counter */
rtw_hal_set_hwreg(padapter,
HW_VAR_FREECNT, &val8);
rm_sitesurvey(prm);
break;
case ch_load_req:
case noise_histo_req:
rm_sitesurvey(prm);
break;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
break;
}
}
/* handle measurement timeout */
rm_set_clock(prm, RM_MEAS_TIMEOUT, RM_EV_meas_timer_expire);
break;
case RM_EV_survey_done:
if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
switch (prm->q.m_type) {
case bcn_req:
rm_cancel_clock(prm);
rm_state_goto(prm, RM_ST_SEND_REPORT);
return _SUCCESS;
case ch_load_req:
case noise_histo_req:
retrieve_radio_meas_result(prm);
if (rm_radio_meas_report_cond(prm) == _SUCCESS)
rm_state_goto(prm, RM_ST_SEND_REPORT);
else
rm_set_clock(prm, RM_COND_INTVL,
RM_EV_retry_timer_expire);
break;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
}
break;
case RM_EV_meas_timer_expire:
RTW_INFO("RM: rmid=%x measurement timeount\n",prm->rmid);
rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_busy_timer_expire:
if (!ready_for_scan(prm) && prm->wait_busy--) {
RTW_INFO("RM: wait busy - %d\n",prm->wait_busy);
rm_set_clock(prm, RM_WAIT_BUSY_TIMEOUT,
RM_EV_busy_timer_expire);
break;
}
else if (prm->wait_busy <= 0) {
RTW_INFO("RM: wait busy timeout\n");
rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
_rm_post_event(padapter, prm->rmid, RM_EV_start_meas);
break;
case RM_EV_request_timer_expire:
rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_retry_timer_expire:
/* expired due to meas condition mismatch, meas again */
_rm_post_event(padapter, prm->rmid, RM_EV_start_meas);
break;
case RM_EV_cancel:
rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
/* resotre measurement end time */
prm->meas_end_time = rtw_hal_get_tsftr_by_port(padapter
, rtw_hal_get_port(padapter));
val8 = 0; /* Disable free run counter */
rtw_hal_set_hwreg(padapter, HW_VAR_FREECNT, &val8);
break;
default:
break;
}
return _SUCCESS;
}
static int rm_state_wait_meas(struct rm_obj *prm, enum RM_EV_ID evid)
{
u8 val8;
u64 val64;
switch (evid) {
case RM_EV_state_in:
/* we create meas_req, waiting for peer report */
rm_set_clock(prm, RM_REQ_TIMEOUT,
RM_EV_request_timer_expire);
break;
case RM_EV_recv_rep:
rm_state_goto(prm, RM_ST_RECV_REPORT);
break;
case RM_EV_request_timer_expire:
case RM_EV_cancel:
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
break;
default:
break;
}
return _SUCCESS;
}
static int rm_state_send_report(struct rm_obj *prm, enum RM_EV_ID evid)
{
u8 val8;
switch (evid) {
case RM_EV_state_in:
/* we have to issue report */
switch (prm->q.m_type) {
case bcn_req:
issue_beacon_rep(prm);
break;
case ch_load_req:
case noise_histo_req:
issue_radio_meas_rep(prm);
break;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
/* check repeat */
if (prm->p.rpt) {
RTW_INFO("RM: rmid=%x repeat=%u/%u\n",
prm->rmid, prm->p.rpt,
prm->q.rpt);
prm->p.rpt--;
/*
* we recv meas_req,
* delay for a wihile and than meas again
*/
if (prm->poll_mode)
rm_set_clock(prm, RM_REPT_POLL_INTVL,
RM_EV_repeat_delay_expire);
else
rm_set_clock(prm, RM_REPT_SCAN_INTVL,
RM_EV_repeat_delay_expire);
return _SUCCESS;
}
/* we are done */
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_repeat_delay_expire:
rm_state_goto(prm, RM_ST_DO_MEAS);
break;
case RM_EV_cancel:
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
break;
default:
break;
}
return _SUCCESS;
}
static int rm_state_recv_report(struct rm_obj *prm, enum RM_EV_ID evid)
{
u8 val8;
switch (evid) {
case RM_EV_state_in:
/* we issue meas_req, got peer's meas report */
switch (prm->p.action_code) {
case RM_ACT_RADIO_MEAS_REP:
/* check refuse, incapable and repeat */
val8 = prm->p.m_mode;
if (val8) {
RTW_INFO("RM: rmid=%x peer reject (%s repeat=%d)\n",
prm->rmid,
val8|MEAS_REP_MOD_INCAP?"INCAP":
val8|MEAS_REP_MOD_REFUSE?"REFUSE":
val8|MEAS_REP_MOD_LATE?"LATE":"",
prm->p.rpt);
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
break;
case RM_ACT_NB_REP_RESP:
/* report to upper layer if needing */
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
/* check repeat */
if (prm->p.rpt) {
RTW_INFO("RM: rmid=%x repeat=%u/%u\n",
prm->rmid, prm->p.rpt,
prm->q.rpt);
prm->p.rpt--;
/* waitting more report */
rm_state_goto(prm, RM_ST_WAIT_MEAS);
break;
}
/* we are done */
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_cancel:
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
break;
default:
break;
}
return _SUCCESS;
}
static int rm_state_end(struct rm_obj *prm, enum RM_EV_ID evid)
{
switch (evid) {
case RM_EV_state_in:
_rm_post_event(prm->psta->padapter, prm->rmid, RM_EV_state_out);
break;
case RM_EV_cancel:
case RM_EV_state_out:
default:
rm_free_rmobj(prm);
break;
}
return _SUCCESS;
}
struct fsm_state rm_fsm[] = {
{"RM_ST_IDLE", rm_state_idle},
{"RM_ST_DO_MEAS", rm_state_do_meas},
{"RM_ST_WAIT_MEAS", rm_state_wait_meas},
{"RM_ST_SEND_REPORT", rm_state_send_report},
{"RM_ST_RECV_REPORT", rm_state_recv_report},
{"RM_ST_END", rm_state_end}
};
char *rm_state_name(enum RM_STATE state)
{
return rm_fsm[state].name;
}
char *rm_event_name(enum RM_EV_ID evid)
{
switch(evid) {
case RM_EV_state_in:
return "RM_EV_state_in";
case RM_EV_busy_timer_expire:
return "RM_EV_busy_timer_expire";
case RM_EV_delay_timer_expire:
return "RM_EV_delay_timer_expire";
case RM_EV_meas_timer_expire:
return "RM_EV_meas_timer_expire";
case RM_EV_repeat_delay_expire:
return "RM_EV_repeat_delay_expire";
case RM_EV_retry_timer_expire:
return "RM_EV_retry_timer_expire";
case RM_EV_request_timer_expire:
return "RM_EV_request_timer_expire";
case RM_EV_wait_report:
return "RM_EV_wait_report";
case RM_EV_start_meas:
return "RM_EV_start_meas";
case RM_EV_survey_done:
return "RM_EV_survey_done";
case RM_EV_recv_rep:
return "RM_EV_recv_report";
case RM_EV_cancel:
return "RM_EV_cancel";
case RM_EV_state_out:
return "RM_EV_state_out";
case RM_EV_max:
return "RM_EV_max";
default:
return "RM_EV_unknown";
}
return "UNKNOWN";
}
static void rm_state_initial(struct rm_obj *prm)
{
prm->state = RM_ST_IDLE;
RTW_INFO("\n");
RTW_INFO("RM: rmid=%x %-18s -> %s\n",prm->rmid,
"new measurement", rm_fsm[prm->state].name);
rm_post_event(prm->psta->padapter, prm->rmid, RM_EV_state_in);
}
static void rm_state_run(struct rm_obj *prm, enum RM_EV_ID evid)
{
RTW_INFO("RM: rmid=%x %-18s %s\n",prm->rmid,
rm_fsm[prm->state].name,rm_event_name(evid));
rm_fsm[prm->state].fsm_func(prm, evid);
}
static void rm_state_goto(struct rm_obj *prm, enum RM_STATE rm_state)
{
if (prm->state == rm_state)
return;
rm_state_run(prm, RM_EV_state_out);
RTW_INFO("\n");
RTW_INFO("RM: rmid=%x %-18s -> %s\n",prm->rmid,
rm_fsm[prm->state].name, rm_fsm[rm_state].name);
prm->state = rm_state;
rm_state_run(prm, RM_EV_state_in);
}
#endif /* CONFIG_RTW_80211K */

595
core/rtw_rson.c Normal file
View File

@ -0,0 +1,595 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_RSON_C_
#include <drv_types.h>
#ifdef CONFIG_RTW_REPEATER_SON
/******** Custommize Part ***********************/
unsigned char RTW_RSON_OUI[] = {0xFA, 0xFA, 0xFA};
#define RSON_SCORE_DIFF_TH 8
/*
Calculate the corresponding score.
*/
inline u8 rtw_cal_rson_score(struct rtw_rson_struct *cand_rson_data, NDIS_802_11_RSSI Rssi)
{
if ((cand_rson_data->hopcnt == RTW_RSON_HC_NOTREADY)
|| (cand_rson_data->connectible == RTW_RSON_DENYCONNECT))
return RTW_RSON_SCORE_NOTCNNT;
return RTW_RSON_SCORE_MAX - (cand_rson_data->hopcnt * 10) + (Rssi/10);
}
/*************************************************/
static u8 rtw_rson_block_bssid_idx = 0;
u8 rtw_rson_block_bssid[10][6] = {
/*{0x02, 0xE0, 0x4C, 0x07, 0xC3, 0xF6}*/
};
/* fake root, regard a real AP as a SO root */
static u8 rtw_rson_root_bssid_idx = 0;
u8 rtw_rson_root_bssid[10][6] = {
/*{0x1c, 0x5f, 0x2b, 0x5a, 0x60, 0x24}*/
};
int is_match_bssid(u8 *mac, u8 bssid_array[][6], int num)
{
int i;
for (i = 0; i < num; i++)
if (_rtw_memcmp(mac, bssid_array[i], 6) == _TRUE)
return _TRUE;
return _FALSE;
}
void init_rtw_rson_data(struct dvobj_priv *dvobj)
{
/*Aries todo. if pdvobj->rson_data.ver == 1 */
dvobj->rson_data.ver = RTW_RSON_VER;
dvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;
#ifdef CONFIG_RTW_REPEATER_SON_ROOT
dvobj->rson_data.hopcnt = RTW_RSON_HC_ROOT;
dvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;
#else
dvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;
dvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;
#endif
dvobj->rson_data.loading = 0;
_rtw_memset(dvobj->rson_data.res, 0xAA, sizeof(dvobj->rson_data.res));
}
void rtw_rson_get_property_str(_adapter *padapter, char *rson_data_str)
{
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
sprintf(rson_data_str, "version : \t%d\nid : \t\t%08x\nhop count : \t%d\nconnectible : \t%s\nloading : \t%d\nreserve : \t%16ph\n",
pdvobj->rson_data.ver,
pdvobj->rson_data.id,
pdvobj->rson_data.hopcnt,
pdvobj->rson_data.connectible ? "connectable":"unconnectable",
pdvobj->rson_data.loading,
pdvobj->rson_data.res);
}
int str2hexbuf(char *str, u8 *hexbuf, int len)
{
u8 *p;
int i, slen, idx = 0;
p = (unsigned char *)str;
if ((*p != '0') || (*(p+1) != 'x'))
return _FALSE;
slen = strlen(str);
if (slen > (len*2) + 2)
return _FALSE;
p += 2;
for (i = 0 ; i < len; i++, idx = idx+2) {
hexbuf[i] = key_2char2num(p[idx], p[idx + 1]);
if (slen <= idx+2)
break;
}
return _TRUE;
}
int rtw_rson_set_property(_adapter *padapter, char *field, char *value)
{
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
int num = 0;
if (_rtw_memcmp(field, (u8 *)"ver", 3) == _TRUE)
pdvobj->rson_data.ver = rtw_atoi(value);
else if (_rtw_memcmp(field, (u8 *)"id", 2) == _TRUE)
num = sscanf(value, "%08x", &(pdvobj->rson_data.id));
else if (_rtw_memcmp(field, (u8 *)"hc", 2) == _TRUE)
num = sscanf(value, "%hhu", &(pdvobj->rson_data.hopcnt));
else if (_rtw_memcmp(field, (u8 *)"cnt", 3) == _TRUE)
num = sscanf(value, "%hhu", &(pdvobj->rson_data.connectible));
else if (_rtw_memcmp(field, (u8 *)"loading", 2) == _TRUE)
num = sscanf(value, "%hhu", &(pdvobj->rson_data.loading));
else if (_rtw_memcmp(field, (u8 *)"res", 2) == _TRUE) {
str2hexbuf(value, pdvobj->rson_data.res, 16);
return 1;
} else
return _FALSE;
return num;
}
/*
return : TRUE -- competitor is taking advantage than condidate
FALSE -- we should continue keeping candidate
*/
int rtw_rson_choose(struct wlan_network **candidate, struct wlan_network *competitor)
{
s16 comp_score = 0, cand_score = 0;
struct rtw_rson_struct rson_cand, rson_comp;
if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)
return _FALSE;
if ((competitor == NULL)
|| (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)
|| (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))
return _FALSE;
comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);
if (comp_score == RTW_RSON_SCORE_NOTCNNT)
return _FALSE;
if (*candidate == NULL)
return _TRUE;
if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE)
return _FALSE;
cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);
RTW_INFO("%s: competitor_score=%d, candidate_score=%d\n", __func__, comp_score, cand_score);
if (comp_score - cand_score > RSON_SCORE_DIFF_TH)
return _TRUE;
return _FALSE;
}
inline u8 rtw_rson_varify_ie(u8 *p)
{
u8 *ptr = NULL;
u8 ver;
u32 id;
u8 hopcnt;
u8 allcnnt;
ptr = p + 2 + sizeof(RTW_RSON_OUI);
ver = *ptr;
/* for (ver == 1) */
if (ver != 1)
return _FALSE;
return _TRUE;
}
/*
Parsing RTK self-organization vendor IE
*/
int rtw_get_rson_struct(WLAN_BSSID_EX *bssid, struct rtw_rson_struct *rson_data)
{
sint limit = 0;
u32 len;
u8 *p;
if ((rson_data == NULL) || (bssid == NULL))
return -EINVAL;
/* Default */
rson_data->id = 0;
rson_data->ver = 0;
rson_data->hopcnt = 0;
rson_data->connectible = 0;
rson_data->loading = 0;
/* fake root */
if (is_match_bssid(bssid->MacAddress, rtw_rson_root_bssid, rtw_rson_root_bssid_idx) == _TRUE) {
rson_data->id = CONFIG_RTW_REPEATER_SON_ID;
rson_data->ver = RTW_RSON_VER;
rson_data->hopcnt = RTW_RSON_HC_ROOT;
rson_data->connectible = RTW_RSON_ALLOWCONNECT;
rson_data->loading = 0;
return _TRUE;
}
limit = bssid->IELength - _BEACON_IE_OFFSET_;
for (p = bssid->IEs + _BEACON_IE_OFFSET_; ; p += (len + 2)) {
p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, limit);
limit -= len;
if ((p == NULL) || (len == 0))
break;
if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)
&& rtw_rson_varify_ie(p)) {
p = p + 2 + sizeof(RTW_RSON_OUI);
rson_data->ver = *p;
/* for (ver == 1) */
p = p + 1;
rson_data->id = le32_to_cpup((__le32 *)p);
p = p + 4;
rson_data->hopcnt = *p;
p = p + 1;
rson_data->connectible = *p;
p = p + 1;
rson_data->loading = *p;
return _TRUE;
}
}
return -EBADMSG;
}
u32 rtw_rson_append_ie(_adapter *padapter, unsigned char *pframe, u32 *len)
{
u8 *ptr, *ori, ie_len = 0;
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
/* static int iii = 0;*/
if ((!pdvobj) || (!pframe))
return 0;
ptr = ori = pframe;
*ptr++ = _VENDOR_SPECIFIC_IE_;
*ptr++ = ie_len = sizeof(RTW_RSON_OUI)+sizeof(pdvobj->rson_data);
_rtw_memcpy(ptr, RTW_RSON_OUI, sizeof(RTW_RSON_OUI));
ptr = ptr + sizeof(RTW_RSON_OUI);
*ptr++ = pdvobj->rson_data.ver;
*(s32 *)ptr = cpu_to_le32(pdvobj->rson_data.id);
ptr = ptr + sizeof(pdvobj->rson_data.id);
*ptr++ = pdvobj->rson_data.hopcnt;
*ptr++ = pdvobj->rson_data.connectible;
*ptr++ = pdvobj->rson_data.loading;
_rtw_memcpy(ptr, pdvobj->rson_data.res, sizeof(pdvobj->rson_data.res));
pframe = ptr;
/*
iii = iii % 20;
if (iii++ == 0)
RTW_INFO("%s : RTW RSON IE : %20ph\n", __func__, ori);
*/
*len += (ie_len+2);
return ie_len;
}
void rtw_rson_do_disconnect(_adapter *padapter)
{
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
#ifndef CONFIG_RTW_REPEATER_SON_ROOT
pdvobj->rson_data.ver = RTW_RSON_VER;
pdvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;
pdvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;
pdvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;
pdvobj->rson_data.loading = 0;
rtw_mi_tx_beacon_hdl(padapter);
#endif
}
void rtw_rson_join_done(_adapter *padapter)
{
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
WLAN_BSSID_EX *cur_network = NULL;
struct rtw_rson_struct rson_data;
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
if (!padapter->mlmepriv.cur_network_scanned)
return;
cur_network = &(padapter->mlmepriv.cur_network_scanned->network);
if (rtw_get_rson_struct(cur_network, &rson_data) != _TRUE) {
RTW_ERR("%s: try to join a improper network(%s)\n", __func__, cur_network->Ssid.Ssid);
return;
}
#ifndef CONFIG_RTW_REPEATER_SON_ROOT
/* update rson_data */
pdvobj->rson_data.ver = RTW_RSON_VER;
pdvobj->rson_data.id = rson_data.id;
pdvobj->rson_data.hopcnt = rson_data.hopcnt + 1;
pdvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;
pdvobj->rson_data.loading = 0;
rtw_mi_tx_beacon_hdl(padapter);
#endif
}
int rtw_rson_isupdate_roamcan(struct mlme_priv *mlme
, struct wlan_network **candidate, struct wlan_network *competitor)
{
struct rtw_rson_struct rson_cand, rson_comp, rson_curr;
s16 comp_score, cand_score, curr_score;
if ((competitor == NULL)
|| (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)
|| (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))
return _FALSE;
if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)
return _FALSE;
if ((!mlme->cur_network_scanned)
|| (mlme->cur_network_scanned == competitor)
|| (rtw_get_rson_struct(&(mlme->cur_network_scanned->network), &rson_curr)) != _TRUE)
return _FALSE;
if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
return _FALSE;
comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);
curr_score = rtw_cal_rson_score(&rson_curr, mlme->cur_network_scanned->network.Rssi);
if (comp_score - curr_score < RSON_SCORE_DIFF_TH)
return _FALSE;
if (*candidate == NULL)
return _TRUE;
if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE) {
RTW_ERR("%s : Unable to get rson_struct from candidate(%s -- " MAC_FMT")\n",
__func__, (*candidate)->network.Ssid.Ssid, MAC_ARG((*candidate)->network.MacAddress));
return _FALSE;
}
cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);
RTW_DBG("comp_score=%d , cand_score=%d , curr_score=%d\n", comp_score, cand_score, curr_score);
if (cand_score < comp_score)
return _TRUE;
#if 0 /* Handle 11R protocol */
#ifdef CONFIG_RTW_80211R
if (rtw_chk_ft_flags(adapter, RTW_FT_SUPPORTED)) {
ptmp = rtw_get_ie(&competitor->network.IEs[12], _MDIE_, &mdie_len, competitor->network.IELength-12);
if (ptmp) {
if (!_rtw_memcmp(&pftpriv->mdid, ptmp+2, 2))
goto exit;
/*The candidate don't support over-the-DS*/
if (rtw_chk_ft_flags(adapter, RTW_FT_STA_OVER_DS_SUPPORTED)) {
if ((rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && !(*(ptmp+4) & 0x01)) ||
(!rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && (*(ptmp+4) & 0x01))) {
RTW_INFO("FT: ignore the candidate(" MAC_FMT ") for over-the-DS\n", MAC_ARG(competitor->network.MacAddress));
rtw_clr_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED);
goto exit;
}
}
} else
goto exit;
}
#endif
#endif
return _FALSE;
}
void rtw_rson_show_survey_info(struct seq_file *m, _list *plist, _list *phead)
{
struct wlan_network *pnetwork = NULL;
struct rtw_rson_struct rson_data;
s16 rson_score;
u16 index = 0;
RTW_PRINT_SEL(m, "%5s %-17s %3s %5s %14s %10s %-3s %5s %32s\n", "index", "bssid", "ch", "id", "hop_cnt", "loading", "RSSI", "score", "ssid");
while (1) {
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
break;
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
if (!pnetwork)
break;
_rtw_memset(&rson_data, 0, sizeof(rson_data));
rson_score = 0;
if (rtw_get_rson_struct(&(pnetwork->network), &rson_data) == _TRUE)
rson_score = rtw_cal_rson_score(&rson_data, pnetwork->network.Rssi);
RTW_PRINT_SEL(m, "%5d "MAC_FMT" %3d 0x%08x %6d %10d %6d %6d %32s\n",
++index,
MAC_ARG(pnetwork->network.MacAddress),
pnetwork->network.Configuration.DSConfig,
rson_data.id,
rson_data.hopcnt,
rson_data.loading,
(int)pnetwork->network.Rssi,
rson_score,
pnetwork->network.Ssid.Ssid);
plist = get_next(plist);
}
}
/*
Description : As a AP role, We need to check the qualify of associating STA.
We also need to check if we are ready to be associated.
return : TRUE -- AP REJECT this STA
FALSE -- AP ACCEPT this STA
*/
u8 rtw_rson_ap_check_sta(_adapter *padapter, u8 *pframe, uint pkt_len, unsigned short ie_offset)
{
struct wlan_network *pnetwork = NULL;
struct rtw_rson_struct rson_target;
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
int len = 0;
u8 ret = _FALSE;
u8 *p;
#ifndef CONFIG_RTW_REPEATER_SON_ROOT
_rtw_memset(&rson_target, 0, sizeof(rson_target));
for (p = pframe + WLAN_HDR_A3_LEN + ie_offset; ; p += (len + 2)) {
p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
if ((p == NULL) || (len == 0))
break;
if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)
&& rtw_rson_varify_ie(p)) {
p = p + 2 + sizeof(RTW_RSON_OUI);
rson_target.ver = *p;
/* for (ver == 1) */
p = p + 1;
rson_target.id = le32_to_cpup((__le32 *)p);
p = p + 4;
rson_target.hopcnt = *p;
p = p + 1;
rson_target.connectible = *p;
p = p + 1;
rson_target.loading = *p;
break;
}
}
if (rson_target.id == 0) /* Normal STA, not a RSON STA */
ret = _FALSE;
else if (rson_target.id != pdvobj->rson_data.id) {
ret = _TRUE;
RTW_INFO("%s : Reject AssoReq because RSON ID not match, STA=%08x, our=%08x\n",
__func__, rson_target.id, pdvobj->rson_data.id);
} else if ((pdvobj->rson_data.hopcnt == RTW_RSON_HC_NOTREADY)
|| (pdvobj->rson_data.connectible == RTW_RSON_DENYCONNECT)) {
ret = _TRUE;
RTW_INFO("%s : Reject AssoReq becuase our hopcnt=%d or connectbile=%d\n",
__func__, pdvobj->rson_data.hopcnt, pdvobj->rson_data.connectible);
}
#endif
return ret;
}
u8 rtw_rson_scan_wk_cmd(_adapter *padapter, int op)
{
struct cmd_obj *ph2c;
struct drvextra_cmd_parm *pdrvextra_cmd_parm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
u8 *extra_cmd_buf;
u8 res = _SUCCESS;
ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
if (pdrvextra_cmd_parm == NULL) {
rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));
res = _FAIL;
goto exit;
}
pdrvextra_cmd_parm->ec_id = RSON_SCAN_WK_CID;
pdrvextra_cmd_parm->type = op;
pdrvextra_cmd_parm->size = 0;
pdrvextra_cmd_parm->pbuf = NULL;
init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
exit:
return res;
}
void rtw_rson_scan_cmd_hdl(_adapter *padapter, int op)
{
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
u8 val8;
if (mlmeext_chk_scan_state(pmlmeext, SCAN_DISABLE) != _TRUE)
return;
if (op == RSON_SCAN_PROCESS) {
padapter->rtw_rson_scanstage = RSON_SCAN_PROCESS;
val8 = 0x1e;
rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);
val8 = 1;
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
issue_probereq(padapter, NULL, NULL);
/* stop rson_scan after 100ms */
_set_timer(&(pmlmeext->rson_scan_timer), 100);
} else if (op == RSON_SCAN_DISABLE) {
padapter->rtw_rson_scanstage = RSON_SCAN_DISABLE;
val8 = 0;
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
val8 = 0xff;
rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);
/* report_surveydone_event(padapter);*/
if (pmlmepriv->to_join == _TRUE) {
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) != _TRUE) {
int s_ret;
set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
pmlmepriv->to_join = _FALSE;
s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
if (s_ret == _SUCCESS)
_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
else if (s_ret == 2) {
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
rtw_indicate_connect(padapter);
} else {
RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(padapter));
if (rtw_to_roam(padapter) != 0) {
if (rtw_dec_to_roam(padapter) == 0) {
rtw_set_to_roam(padapter, 0);
#ifdef CONFIG_INTEL_WIDI
if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) {
_rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
RTW_INFO("change to widi listen\n");
}
#endif /* CONFIG_INTEL_WIDI */
rtw_free_assoc_resources(padapter, _TRUE);
rtw_indicate_disconnect(padapter, 0, _FALSE);
} else
pmlmepriv->to_join = _TRUE;
} else
rtw_indicate_disconnect(padapter, 0, _FALSE);
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
}
}
} else {
if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
&& check_fwstate(pmlmepriv, _FW_LINKED)) {
if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
#ifdef CONFIG_RTW_80211R
if (rtw_chk_ft_flags(padapter, RTW_FT_OVER_DS_SUPPORTED)) {
start_clnt_ft_action(adapter, (u8 *)pmlmepriv->roam_network->network.MacAddress);
} else {
/*wait a little time to retrieve packets buffered in the current ap while scan*/
_set_timer(&pmlmeext->ft_roam_timer, 30);
}
#else
receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress
, WLAN_REASON_ACTIVE_ROAM, _FALSE);
#endif
}
}
}
issue_action_BSSCoexistPacket(padapter);
issue_action_BSSCoexistPacket(padapter);
issue_action_BSSCoexistPacket(padapter);
}
} else {
RTW_ERR("%s : improper parameter -- op = %d\n", __func__, op);
}
}
#endif /* CONFIG_RTW_REPEATER_SON */

130
core/rtw_sdio.c Normal file
View File

@ -0,0 +1,130 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_SDIO_C_
#include <drv_types.h> /* struct dvobj_priv and etc. */
#include <drv_types_sdio.h> /* RTW_SDIO_ADDR_CMD52_GEN */
/*
* Description:
* Use SDIO cmd52 or cmd53 to read/write data
*
* Parameters:
* d pointer of device object(struct dvobj_priv)
* addr SDIO address, 17 bits
* buf buffer for I/O
* len length
* write 0:read, 1:write
* cmd52 0:cmd52, 1:cmd53
*
* Return:
* _SUCCESS I/O ok.
* _FAIL I/O fail.
*/
static u8 sdio_io(struct dvobj_priv *d, u32 addr, void *buf, size_t len, u8 write, u8 cmd52)
{
u32 addr_drv; /* address with driver defined bit */
int err;
u8 retry = 0;
u8 stop_retry = _FALSE; /* flag for stopping retry or not */
if (rtw_is_surprise_removed(dvobj_get_primary_adapter(d))) {
RTW_ERR("%s: bSurpriseRemoved, skip %s 0x%05x, %zu bytes\n",
__FUNCTION__, write?"write":"read", addr, len);
return _FAIL;
}
addr_drv = addr;
if (cmd52)
addr_drv = RTW_SDIO_ADDR_CMD52_GEN(addr_drv);
do {
if (write)
err = d->intf_ops->write(d, addr_drv, buf, len, 0);
else
err = d->intf_ops->read(d, addr_drv, buf, len, 0);
if (!err) {
if (retry) {
RTW_INFO("%s: Retry %s OK! addr=0x%05x %zu bytes, retry=%u,%u\n",
__FUNCTION__, write?"write":"read",
addr, len, retry, ATOMIC_READ(&d->continual_io_error));
RTW_INFO_DUMP("Data: ", buf, len);
}
rtw_reset_continual_io_error(d);
break;
}
RTW_ERR("%s: %s FAIL! error(%d) addr=0x%05x %zu bytes, retry=%u,%u\n",
__FUNCTION__, write?"write":"read", err, addr, len,
retry, ATOMIC_READ(&d->continual_io_error));
retry++;
stop_retry = rtw_inc_and_chk_continual_io_error(d);
if ((err == -1) || (stop_retry == _TRUE) || (retry > SD_IO_TRY_CNT)) {
/* critical error, unrecoverable */
RTW_ERR("%s: Fatal error! Set surprise remove flag ON! (retry=%u,%u)\n",
__FUNCTION__, retry, ATOMIC_READ(&d->continual_io_error));
rtw_set_surprise_removed(dvobj_get_primary_adapter(d));
return _FAIL;
}
/* WLAN IOREG or SDIO Local */
if ((addr & 0x10000) || !(addr & 0xE000)) {
RTW_WARN("%s: Retry %s addr=0x%05x %zu bytes, retry=%u,%u\n",
__FUNCTION__, write?"write":"read", addr, len,
retry, ATOMIC_READ(&d->continual_io_error));
continue;
}
return _FAIL;
} while (1);
return _SUCCESS;
}
u8 rtw_sdio_read_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
return sdio_io(d, addr, buf, len, 0, 1);
}
u8 rtw_sdio_read_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
return sdio_io(d, addr, buf, len, 0, 0);
}
u8 rtw_sdio_write_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
return sdio_io(d, addr, buf, len, 1, 1);
}
u8 rtw_sdio_write_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
return sdio_io(d, addr, buf, len, 1, 0);
}
u8 rtw_sdio_f0_read(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
int err;
u8 ret;
ret = _SUCCESS;
addr = RTW_SDIO_ADDR_F0_GEN(addr);
err = d->intf_ops->read(d, addr, buf, len, 0);
if (err)
ret = _FAIL;
return ret;
}

3408
core/rtw_security.c Normal file

File diff suppressed because it is too large Load Diff

314
core/rtw_sreset.c Normal file
View File

@ -0,0 +1,314 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <hal_data.h>
#include <rtw_sreset.h>
void sreset_init_value(_adapter *padapter)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
_rtw_mutex_init(&psrtpriv->silentreset_mutex);
psrtpriv->silent_reset_inprogress = _FALSE;
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
psrtpriv->last_tx_time = 0;
psrtpriv->last_tx_complete_time = 0;
#endif
}
void sreset_reset_value(_adapter *padapter)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
psrtpriv->last_tx_time = 0;
psrtpriv->last_tx_complete_time = 0;
#endif
}
u8 sreset_get_wifi_status(_adapter *padapter)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
u8 status = WIFI_STATUS_SUCCESS;
u32 val32 = 0;
if (psrtpriv->silent_reset_inprogress == _TRUE)
return status;
val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
if (val32 == 0xeaeaeaea)
psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
else if (val32 != 0) {
RTW_INFO("txdmastatu(%x)\n", val32);
psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
}
if (WIFI_STATUS_SUCCESS != psrtpriv->Wifi_Error_Status) {
RTW_INFO("==>%s error_status(0x%x)\n", __FUNCTION__, psrtpriv->Wifi_Error_Status);
status = (psrtpriv->Wifi_Error_Status & (~(USB_READ_PORT_FAIL | USB_WRITE_PORT_FAIL)));
}
RTW_INFO("==> %s wifi_status(0x%x)\n", __FUNCTION__, status);
/* status restore */
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
return status;
#else
return WIFI_STATUS_SUCCESS;
#endif
}
void sreset_set_wifi_error_status(_adapter *padapter, u32 status)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
pHalData->srestpriv.Wifi_Error_Status = status;
#endif
}
void sreset_set_trigger_point(_adapter *padapter, s32 tgp)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
pHalData->srestpriv.dbg_trigger_point = tgp;
#endif
}
bool sreset_inprogress(_adapter *padapter)
{
#if defined(DBG_CONFIG_ERROR_RESET)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
return pHalData->srestpriv.silent_reset_inprogress;
#else
return _FALSE;
#endif
}
void sreset_restore_security_station(_adapter *padapter)
{
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
struct sta_priv *pstapriv = &padapter->stapriv;
struct sta_info *psta;
struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info;
{
u8 val8;
if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) {
val8 = 0xcc;
#ifdef CONFIG_WAPI_SUPPORT
} else if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) {
/* Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. */
val8 = 0x4c;
#endif
} else
val8 = 0xcf;
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
}
if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
psta = rtw_get_stainfo(pstapriv, get_bssid(mlmepriv));
if (psta == NULL) {
/* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
} else {
/* pairwise key */
rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _FALSE);
/* group key */
rtw_set_key(padapter, &padapter->securitypriv, padapter->securitypriv.dot118021XGrpKeyid, 0, _FALSE);
}
}
}
void sreset_restore_network_station(_adapter *padapter)
{
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
u8 doiqk = _FALSE;
rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure, RTW_CMDF_DIRECTLY);
{
u8 threshold;
#ifdef CONFIG_USB_HCI
/* TH=1 => means that invalidate usb rx aggregation */
/* TH=0 => means that validate usb rx aggregation, use init value. */
#ifdef CONFIG_80211N_HT
if (mlmepriv->htpriv.ht_option) {
if (padapter->registrypriv.wifi_spec == 1)
threshold = 1;
else
threshold = 0;
rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
} else {
threshold = 1;
rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
}
#endif /* CONFIG_80211N_HT */
#endif
}
doiqk = _TRUE;
rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK , &doiqk);
set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
doiqk = _FALSE;
rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
/* disable dynamic functions, such as high power, DIG */
/*rtw_phydm_func_disable_all(padapter);*/
rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
{
u8 join_type = 0;
rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_CONNECTING);
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
}
Set_MSR(padapter, (pmlmeinfo->state & 0x3));
mlmeext_joinbss_event_callback(padapter, 1);
/* restore Sequence No. */
rtw_hal_set_hwreg(padapter, HW_VAR_RESTORE_HW_SEQ, 0);
sreset_restore_security_station(padapter);
}
void sreset_restore_network_status(_adapter *padapter)
{
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) {
RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
sreset_restore_network_station(padapter);
} else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(padapter), MLME_IS_AP(padapter) ? "AP" : "MESH");
rtw_ap_restore_network(padapter);
} else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE))
RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
else
RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
}
void sreset_stop_adapter(_adapter *padapter)
{
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
if (padapter == NULL)
return;
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
rtw_netif_stop_queue(padapter->pnetdev);
rtw_cancel_all_timer(padapter);
/* TODO: OS and HCI independent */
#if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI)
tasklet_kill(&pxmitpriv->xmit_tasklet);
#endif
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
rtw_scan_abort(padapter);
if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
rtw_set_to_roam(padapter, 0);
rtw_join_timeout_handler(padapter);
}
}
void sreset_start_adapter(_adapter *padapter)
{
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
if (padapter == NULL)
return;
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
if (check_fwstate(pmlmepriv, _FW_LINKED))
sreset_restore_network_status(padapter);
/* TODO: OS and HCI independent */
#if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI)
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
#endif
if (is_primary_adapter(padapter))
_set_timer(&adapter_to_dvobj(padapter)->dynamic_chk_timer, 2000);
rtw_netif_wake_queue(padapter->pnetdev);
}
void sreset_reset(_adapter *padapter)
{
#ifdef DBG_CONFIG_ERROR_RESET
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
_irqL irqL;
systime start = rtw_get_current_time();
struct dvobj_priv *psdpriv = padapter->dvobj;
struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
RTW_INFO("%s\n", __FUNCTION__);
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
#ifdef CONFIG_LPS
rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "SRESET");
#endif/* #ifdef CONFIG_LPS */
_enter_pwrlock(&pwrpriv->lock);
psrtpriv->silent_reset_inprogress = _TRUE;
pwrpriv->change_rfpwrstate = rf_off;
rtw_mi_sreset_adapter_hdl(padapter, _FALSE);/*sreset_stop_adapter*/
#ifdef CONFIG_IPS
_ips_enter(padapter);
_ips_leave(padapter);
#endif
#ifdef CONFIG_CONCURRENT_MODE
rtw_mi_ap_info_restore(padapter);
#endif
rtw_mi_sreset_adapter_hdl(padapter, _TRUE);/*sreset_start_adapter*/
psrtpriv->silent_reset_inprogress = _FALSE;
_exit_pwrlock(&pwrpriv->lock);
RTW_INFO("%s done in %d ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
pdbgpriv->dbg_sreset_cnt++;
psrtpriv->self_dect_fw = _FALSE;
psrtpriv->rx_cnt = 0;
#endif
}

1330
core/rtw_sta_mgt.c Normal file

File diff suppressed because it is too large Load Diff

3505
core/rtw_tdls.c Normal file

File diff suppressed because it is too large Load Diff

1135
core/rtw_vht.c Normal file

File diff suppressed because it is too large Load Diff

1312
core/rtw_wapi.c Normal file

File diff suppressed because it is too large Load Diff

922
core/rtw_wapi_sms4.c Normal file
View File

@ -0,0 +1,922 @@
/******************************************************************************
*
* Copyright(c) 2016 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifdef CONFIG_WAPI_SUPPORT
#include <linux/unistd.h>
#include <linux/etherdevice.h>
#include <drv_types.h>
#include <rtw_wapi.h>
#ifdef CONFIG_WAPI_SW_SMS4
#define WAPI_LITTLE_ENDIAN
/* #define BIG_ENDIAN */
#define ENCRYPT 0
#define DECRYPT 1
/**********************************************************
**********************************************************/
const u8 Sbox[256] = {
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
};
const u32 CK[32] = {
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
};
#define Rotl(_x, _y) (((_x) << (_y)) | ((_x) >> (32 - (_y))))
#define ByteSub(_A) (Sbox[(_A) >> 24 & 0xFF] << 24 | \
Sbox[(_A) >> 16 & 0xFF] << 16 | \
Sbox[(_A) >> 8 & 0xFF] << 8 | \
Sbox[(_A) & 0xFF])
#define L1(_B) ((_B) ^ Rotl(_B, 2) ^ Rotl(_B, 10) ^ Rotl(_B, 18) ^ Rotl(_B, 24))
#define L2(_B) ((_B) ^ Rotl(_B, 13) ^ Rotl(_B, 23))
static void
xor_block(void *dst, void *src1, void *src2)
/* 128-bit xor: *dst = *src1 xor *src2. Pointers must be 32-bit aligned */
{
((u32 *)dst)[0] = ((u32 *)src1)[0] ^ ((u32 *)src2)[0];
((u32 *)dst)[1] = ((u32 *)src1)[1] ^ ((u32 *)src2)[1];
((u32 *)dst)[2] = ((u32 *)src1)[2] ^ ((u32 *)src2)[2];
((u32 *)dst)[3] = ((u32 *)src1)[3] ^ ((u32 *)src2)[3];
}
void SMS4Crypt(u8 *Input, u8 *Output, u32 *rk)
{
u32 r, mid, x0, x1, x2, x3, *p;
p = (u32 *)Input;
x0 = p[0];
x1 = p[1];
x2 = p[2];
x3 = p[3];
#ifdef WAPI_LITTLE_ENDIAN
x0 = Rotl(x0, 16);
x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
x1 = Rotl(x1, 16);
x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
x2 = Rotl(x2, 16);
x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
x3 = Rotl(x3, 16);
x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
#endif
for (r = 0; r < 32; r += 4) {
mid = x1 ^ x2 ^ x3 ^ rk[r + 0];
mid = ByteSub(mid);
x0 ^= L1(mid);
mid = x2 ^ x3 ^ x0 ^ rk[r + 1];
mid = ByteSub(mid);
x1 ^= L1(mid);
mid = x3 ^ x0 ^ x1 ^ rk[r + 2];
mid = ByteSub(mid);
x2 ^= L1(mid);
mid = x0 ^ x1 ^ x2 ^ rk[r + 3];
mid = ByteSub(mid);
x3 ^= L1(mid);
}
#ifdef WAPI_LITTLE_ENDIAN
x0 = Rotl(x0, 16);
x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
x1 = Rotl(x1, 16);
x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
x2 = Rotl(x2, 16);
x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
x3 = Rotl(x3, 16);
x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
#endif
p = (u32 *)Output;
p[0] = x3;
p[1] = x2;
p[2] = x1;
p[3] = x0;
}
void SMS4KeyExt(u8 *Key, u32 *rk, u32 CryptFlag)
{
u32 r, mid, x0, x1, x2, x3, *p;
p = (u32 *)Key;
x0 = p[0];
x1 = p[1];
x2 = p[2];
x3 = p[3];
#ifdef WAPI_LITTLE_ENDIAN
x0 = Rotl(x0, 16);
x0 = ((x0 & 0xFF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
x1 = Rotl(x1, 16);
x1 = ((x1 & 0xFF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
x2 = Rotl(x2, 16);
x2 = ((x2 & 0xFF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
x3 = Rotl(x3, 16);
x3 = ((x3 & 0xFF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
#endif
x0 ^= 0xa3b1bac6;
x1 ^= 0x56aa3350;
x2 ^= 0x677d9197;
x3 ^= 0xb27022dc;
for (r = 0; r < 32; r += 4) {
mid = x1 ^ x2 ^ x3 ^ CK[r + 0];
mid = ByteSub(mid);
rk[r + 0] = x0 ^= L2(mid);
mid = x2 ^ x3 ^ x0 ^ CK[r + 1];
mid = ByteSub(mid);
rk[r + 1] = x1 ^= L2(mid);
mid = x3 ^ x0 ^ x1 ^ CK[r + 2];
mid = ByteSub(mid);
rk[r + 2] = x2 ^= L2(mid);
mid = x0 ^ x1 ^ x2 ^ CK[r + 3];
mid = ByteSub(mid);
rk[r + 3] = x3 ^= L2(mid);
}
if (CryptFlag == DECRYPT) {
for (r = 0; r < 16; r++)
mid = rk[r], rk[r] = rk[31 - r], rk[31 - r] = mid;
}
}
void WapiSMS4Cryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
u8 *Output, u16 *OutputLength, u32 CryptFlag)
{
u32 blockNum, i, j, rk[32];
u16 remainder;
u8 blockIn[16], blockOut[16], tempIV[16], k;
*OutputLength = 0;
remainder = InputLength & 0x0F;
blockNum = InputLength >> 4;
if (remainder != 0)
blockNum++;
else
remainder = 16;
for (k = 0; k < 16; k++)
tempIV[k] = IV[15 - k];
memcpy(blockIn, tempIV, 16);
SMS4KeyExt((u8 *)Key, rk, CryptFlag);
for (i = 0; i < blockNum - 1; i++) {
SMS4Crypt((u8 *)blockIn, blockOut, rk);
xor_block(&Output[i * 16], &Input[i * 16], blockOut);
memcpy(blockIn, blockOut, 16);
}
*OutputLength = i * 16;
SMS4Crypt((u8 *)blockIn, blockOut, rk);
for (j = 0; j < remainder; j++)
Output[i * 16 + j] = Input[i * 16 + j] ^ blockOut[j];
*OutputLength += remainder;
}
void WapiSMS4Encryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
u8 *Output, u16 *OutputLength)
{
WapiSMS4Cryption(Key, IV, Input, InputLength, Output, OutputLength, ENCRYPT);
}
void WapiSMS4Decryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
u8 *Output, u16 *OutputLength)
{
/* OFB mode: is also ENCRYPT flag */
WapiSMS4Cryption(Key, IV, Input, InputLength, Output, OutputLength, ENCRYPT);
}
void WapiSMS4CalculateMic(u8 *Key, u8 *IV, u8 *Input1, u8 Input1Length,
u8 *Input2, u16 Input2Length, u8 *Output, u8 *OutputLength)
{
u32 blockNum, i, remainder, rk[32];
u8 BlockIn[16], BlockOut[16], TempBlock[16], tempIV[16], k;
*OutputLength = 0;
remainder = Input1Length & 0x0F;
blockNum = Input1Length >> 4;
for (k = 0; k < 16; k++)
tempIV[k] = IV[15 - k];
memcpy(BlockIn, tempIV, 16);
SMS4KeyExt((u8 *)Key, rk, ENCRYPT);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
for (i = 0; i < blockNum; i++) {
xor_block(BlockIn, (Input1 + i * 16), BlockOut);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
}
if (remainder != 0) {
memset(TempBlock, 0, 16);
memcpy(TempBlock, (Input1 + blockNum * 16), remainder);
xor_block(BlockIn, TempBlock, BlockOut);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
}
remainder = Input2Length & 0x0F;
blockNum = Input2Length >> 4;
for (i = 0; i < blockNum; i++) {
xor_block(BlockIn, (Input2 + i * 16), BlockOut);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
}
if (remainder != 0) {
memset(TempBlock, 0, 16);
memcpy(TempBlock, (Input2 + blockNum * 16), remainder);
xor_block(BlockIn, TempBlock, BlockOut);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
}
memcpy(Output, BlockOut, 16);
*OutputLength = 16;
}
void SecCalculateMicSMS4(
u8 KeyIdx,
u8 *MicKey,
u8 *pHeader,
u8 *pData,
u16 DataLen,
u8 *MicBuffer
)
{
#if 0
struct ieee80211_hdr_3addr_qos *header;
u8 TempBuf[34], TempLen = 32, MicLen, QosOffset, *IV;
u16 *pTemp, fc;
WAPI_TRACE(WAPI_TX | WAPI_RX, "=========>%s\n", __FUNCTION__);
header = (struct ieee80211_hdr_3addr_qos *)pHeader;
memset(TempBuf, 0, 34);
memcpy(TempBuf, pHeader, 2); /* FrameCtrl */
pTemp = (u16 *)TempBuf;
*pTemp &= 0xc78f; /* bit4,5,6,11,12,13 */
memcpy((TempBuf + 2), (pHeader + 4), 12); /* Addr1, Addr2 */
memcpy((TempBuf + 14), (pHeader + 22), 2); /* SeqCtrl */
pTemp = (u16 *)(TempBuf + 14);
*pTemp &= 0x000f;
memcpy((TempBuf + 16), (pHeader + 16), 6); /* Addr3 */
fc = le16_to_cpu(header->frame_ctl);
if (GetFrDs((u16 *)&fc) && GetToDs((u16 *)&fc)) {
memcpy((TempBuf + 22), (pHeader + 24), 6);
QosOffset = 30;
} else {
memset((TempBuf + 22), 0, 6);
QosOffset = 24;
}
if ((fc & 0x0088) == 0x0088) {
memcpy((TempBuf + 28), (pHeader + QosOffset), 2);
TempLen += 2;
/* IV = pHeader + QosOffset + 2 + SNAP_SIZE + sizeof(u16) + 2; */
IV = pHeader + QosOffset + 2 + 2;
} else {
IV = pHeader + QosOffset + 2;
/* IV = pHeader + QosOffset + SNAP_SIZE + sizeof(u16) + 2; */
}
TempBuf[TempLen - 1] = (u8)(DataLen & 0xff);
TempBuf[TempLen - 2] = (u8)((DataLen & 0xff00) >> 8);
TempBuf[TempLen - 4] = KeyIdx;
WAPI_DATA(WAPI_TX, "CalculateMic - KEY", MicKey, 16);
WAPI_DATA(WAPI_TX, "CalculateMic - IV", IV, 16);
WAPI_DATA(WAPI_TX, "CalculateMic - TempBuf", TempBuf, TempLen);
WAPI_DATA(WAPI_TX, "CalculateMic - pData", pData, DataLen);
WapiSMS4CalculateMic(MicKey, IV, TempBuf, TempLen,
pData, DataLen, MicBuffer, &MicLen);
if (MicLen != 16)
WAPI_TRACE(WAPI_ERR, "%s: MIC Length Error!!\n", __FUNCTION__);
WAPI_TRACE(WAPI_TX | WAPI_RX, "<=========%s\n", __FUNCTION__);
#endif
}
/* AddCount: 1 or 2.
* If overflow, return 1,
* else return 0.
*/
u8 WapiIncreasePN(u8 *PN, u8 AddCount)
{
u8 i;
if (NULL == PN)
return 1;
/* YJ,test,091102 */
/*
if(AddCount == 2){
RTW_INFO("############################%s(): PN[0]=0x%x\n", __FUNCTION__, PN[0]);
if(PN[0] == 0x48){
PN[0] += AddCount;
return 1;
}else{
PN[0] += AddCount;
return 0;
}
}
*/
/* YJ,test,091102,end */
for (i = 0; i < 16; i++) {
if (PN[i] + AddCount <= 0xff) {
PN[i] += AddCount;
return 0;
} else {
PN[i] += AddCount;
AddCount = 1;
}
}
return 1;
}
void WapiGetLastRxUnicastPNForQoSData(
u8 UserPriority,
PRT_WAPI_STA_INFO pWapiStaInfo,
u8 *PNOut
)
{
WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
switch (UserPriority) {
case 0:
case 3:
memcpy(PNOut, pWapiStaInfo->lastRxUnicastPNBEQueue, 16);
break;
case 1:
case 2:
memcpy(PNOut, pWapiStaInfo->lastRxUnicastPNBKQueue, 16);
break;
case 4:
case 5:
memcpy(PNOut, pWapiStaInfo->lastRxUnicastPNVIQueue, 16);
break;
case 6:
case 7:
memcpy(PNOut, pWapiStaInfo->lastRxUnicastPNVOQueue, 16);
break;
default:
WAPI_TRACE(WAPI_ERR, "%s: Unknown TID\n", __FUNCTION__);
break;
}
WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__);
}
void WapiSetLastRxUnicastPNForQoSData(
u8 UserPriority,
u8 *PNIn,
PRT_WAPI_STA_INFO pWapiStaInfo
)
{
WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
switch (UserPriority) {
case 0:
case 3:
memcpy(pWapiStaInfo->lastRxUnicastPNBEQueue, PNIn, 16);
break;
case 1:
case 2:
memcpy(pWapiStaInfo->lastRxUnicastPNBKQueue, PNIn, 16);
break;
case 4:
case 5:
memcpy(pWapiStaInfo->lastRxUnicastPNVIQueue, PNIn, 16);
break;
case 6:
case 7:
memcpy(pWapiStaInfo->lastRxUnicastPNVOQueue, PNIn, 16);
break;
default:
WAPI_TRACE(WAPI_ERR, "%s: Unknown TID\n", __FUNCTION__);
break;
}
WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__);
}
/****************************************************************************
FALSE not RX-Reorder
TRUE do RX Reorder
add to support WAPI to N-mode
*****************************************************************************/
u8 WapiCheckPnInSwDecrypt(
_adapter *padapter,
struct sk_buff *pskb
)
{
u8 ret = false;
#if 0
struct ieee80211_hdr_3addr_qos *header;
u16 fc;
u8 *pDaddr, *pTaddr, *pRaddr;
header = (struct ieee80211_hdr_3addr_qos *)pskb->data;
pTaddr = header->addr2;
pRaddr = header->addr1;
fc = le16_to_cpu(header->frame_ctl);
if (GetToDs(&fc))
pDaddr = header->addr3;
else
pDaddr = header->addr1;
if ((_rtw_memcmp(pRaddr, padapter->pnetdev->dev_addr, ETH_ALEN) == 0)
&& !(pDaddr)
&& (GetFrameType(&fc) == WIFI_QOS_DATA_TYPE))
/* && ieee->pHTInfo->bCurrentHTSupport && */
/* ieee->pHTInfo->bCurRxReorderEnable) */
ret = false;
else
ret = true;
#endif
WAPI_TRACE(WAPI_RX, "%s: return %d\n", __FUNCTION__, ret);
return ret;
}
int SecSMS4HeaderFillIV(_adapter *padapter, u8 *pxmitframe)
{
struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
u8 *frame = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
u8 *pSecHeader = NULL, *pos = NULL, *pRA = NULL;
u8 bPNOverflow = false, bFindMatchPeer = false, hdr_len = 0;
PWLAN_HEADER_WAPI_EXTENSION pWapiExt = NULL;
PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
PRT_WAPI_STA_INFO pWapiSta = NULL;
int ret = 0;
WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
return ret;
#if 0
hdr_len = sMacHdrLng;
if (GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE)
hdr_len += 2;
/* hdr_len += SNAP_SIZE + sizeof(u16); */
pos = skb_push(pskb, padapter->wapiInfo.extra_prefix_len);
memmove(pos, pos + padapter->wapiInfo.extra_prefix_len, hdr_len);
pSecHeader = pskb->data + hdr_len;
pWapiExt = (PWLAN_HEADER_WAPI_EXTENSION)pSecHeader;
pRA = pskb->data + 4;
WAPI_DATA(WAPI_TX, "FillIV - Before Fill IV", pskb->data, pskb->len);
/* Address 1 is always receiver's address */
if (IS_MCAST(pRA)) {
if (!pWapiInfo->wapiTxMsk.bTxEnable) {
WAPI_TRACE(WAPI_ERR, "%s: bTxEnable = 0!!\n", __FUNCTION__);
return -2;
}
if (pWapiInfo->wapiTxMsk.keyId <= 1) {
pWapiExt->KeyIdx = pWapiInfo->wapiTxMsk.keyId;
pWapiExt->Reserved = 0;
bPNOverflow = WapiIncreasePN(pWapiInfo->lastTxMulticastPN, 1);
memcpy(pWapiExt->PN, pWapiInfo->lastTxMulticastPN, 16);
if (bPNOverflow) {
/* Update MSK Notification. */
WAPI_TRACE(WAPI_ERR, "===============>%s():multicast PN overflow\n", __FUNCTION__);
rtw_wapi_app_event_handler(padapter, NULL, 0, pRA, false, false, true, 0, false);
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Invalid Wapi Multicast KeyIdx!!\n", __FUNCTION__);
ret = -3;
}
} else {
list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
if (!memcmp(pWapiSta->PeerMacAddr, pRA, 6)) {
bFindMatchPeer = true;
break;
}
}
if (bFindMatchPeer) {
if ((!pWapiSta->wapiUskUpdate.bTxEnable) && (!pWapiSta->wapiUsk.bTxEnable)) {
WAPI_TRACE(WAPI_ERR, "%s: bTxEnable = 0!!\n", __FUNCTION__);
return -4;
}
if (pWapiSta->wapiUsk.keyId <= 1) {
if (pWapiSta->wapiUskUpdate.bTxEnable)
pWapiExt->KeyIdx = pWapiSta->wapiUskUpdate.keyId;
else
pWapiExt->KeyIdx = pWapiSta->wapiUsk.keyId;
pWapiExt->Reserved = 0;
bPNOverflow = WapiIncreasePN(pWapiSta->lastTxUnicastPN, 2);
memcpy(pWapiExt->PN, pWapiSta->lastTxUnicastPN, 16);
if (bPNOverflow) {
/* Update USK Notification. */
WAPI_TRACE(WAPI_ERR, "===============>%s():unicast PN overflow\n", __FUNCTION__);
rtw_wapi_app_event_handler(padapter, NULL, 0, pWapiSta->PeerMacAddr, false, true, false, 0, false);
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Invalid Wapi Unicast KeyIdx!!\n", __FUNCTION__);
ret = -5;
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Can not find Peer Sta "MAC_FMT"!!\n", __FUNCTION__, MAC_ARG(pRA));
ret = -6;
}
}
WAPI_DATA(WAPI_TX, "FillIV - After Fill IV", pskb->data, pskb->len);
WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
return ret;
#endif
}
/* WAPI SW Enc: must have done Coalesce! */
void SecSWSMS4Encryption(
_adapter *padapter,
u8 *pxmitframe
)
{
PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
PRT_WAPI_STA_INFO pWapiSta = NULL;
u8 *pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_SIZE;
struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
u8 *SecPtr = NULL, *pRA, *pMicKey = NULL, *pDataKey = NULL, *pIV = NULL;
u8 IVOffset, DataOffset, bFindMatchPeer = false, KeyIdx = 0, MicBuffer[16];
u16 OutputLength;
WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
WAPI_TRACE(WAPI_TX, "hdrlen: %d\n", pattrib->hdrlen);
return;
DataOffset = pattrib->hdrlen + pattrib->iv_len;
pRA = pframe + 4;
if (IS_MCAST(pRA)) {
KeyIdx = pWapiInfo->wapiTxMsk.keyId;
pIV = pWapiInfo->lastTxMulticastPN;
pMicKey = pWapiInfo->wapiTxMsk.micKey;
pDataKey = pWapiInfo->wapiTxMsk.dataKey;
} else {
if (!list_empty(&(pWapiInfo->wapiSTAUsedList))) {
list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
if (0 == memcmp(pWapiSta->PeerMacAddr, pRA, 6)) {
bFindMatchPeer = true;
break;
}
}
if (bFindMatchPeer) {
if (pWapiSta->wapiUskUpdate.bTxEnable) {
KeyIdx = pWapiSta->wapiUskUpdate.keyId;
WAPI_TRACE(WAPI_TX, "%s(): Use update USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx);
pIV = pWapiSta->lastTxUnicastPN;
pMicKey = pWapiSta->wapiUskUpdate.micKey;
pDataKey = pWapiSta->wapiUskUpdate.dataKey;
} else {
KeyIdx = pWapiSta->wapiUsk.keyId;
WAPI_TRACE(WAPI_TX, "%s(): Use USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx);
pIV = pWapiSta->lastTxUnicastPN;
pMicKey = pWapiSta->wapiUsk.micKey;
pDataKey = pWapiSta->wapiUsk.dataKey;
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Can not find Peer Sta!!\n", __FUNCTION__);
return;
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: wapiSTAUsedList is empty!!\n", __FUNCTION__);
return;
}
}
SecPtr = pframe;
SecCalculateMicSMS4(KeyIdx, pMicKey, SecPtr, (SecPtr + DataOffset), pattrib->pktlen, MicBuffer);
WAPI_DATA(WAPI_TX, "Encryption - MIC", MicBuffer, padapter->wapiInfo.extra_postfix_len);
memcpy(pframe + pattrib->hdrlen + pattrib->iv_len + pattrib->pktlen - pattrib->icv_len,
(u8 *)MicBuffer,
padapter->wapiInfo.extra_postfix_len
);
WapiSMS4Encryption(pDataKey, pIV, (SecPtr + DataOffset), pattrib->pktlen + pattrib->icv_len, (SecPtr + DataOffset), &OutputLength);
WAPI_DATA(WAPI_TX, "Encryption - After SMS4 encryption", pframe, pattrib->hdrlen + pattrib->iv_len + pattrib->pktlen);
WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
}
u8 SecSWSMS4Decryption(
_adapter *padapter,
u8 *precv_frame,
struct recv_priv *precv_priv
)
{
PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
struct recv_frame_hdr *precv_hdr;
PRT_WAPI_STA_INFO pWapiSta = NULL;
u8 IVOffset, DataOffset, bFindMatchPeer = false, bUseUpdatedKey = false;
u8 KeyIdx, MicBuffer[16], lastRxPNforQoS[16];
u8 *pRA, *pTA, *pMicKey, *pDataKey, *pLastRxPN, *pRecvPN, *pSecData, *pRecvMic, *pos;
u8 TID = 0;
u16 OutputLength, DataLen;
u8 bQosData;
struct sk_buff *pskb;
WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__);
return 0;
precv_hdr = &((union recv_frame *)precv_frame)->u.hdr;
pskb = (struct sk_buff *)(precv_hdr->rx_data);
precv_hdr->bWapiCheckPNInDecrypt = WapiCheckPnInSwDecrypt(padapter, pskb);
WAPI_TRACE(WAPI_RX, "=========>%s: check PN %d\n", __FUNCTION__, precv_hdr->bWapiCheckPNInDecrypt);
WAPI_DATA(WAPI_RX, "Decryption - Before decryption", pskb->data, pskb->len);
IVOffset = sMacHdrLng;
bQosData = GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE;
if (bQosData)
IVOffset += 2;
/* if(GetHTC()) */
/* IVOffset += 4; */
/* IVOffset += SNAP_SIZE + sizeof(u16); */
DataOffset = IVOffset + padapter->wapiInfo.extra_prefix_len;
pRA = pskb->data + 4;
pTA = pskb->data + 10;
KeyIdx = *(pskb->data + IVOffset);
pRecvPN = pskb->data + IVOffset + 2;
pSecData = pskb->data + DataOffset;
DataLen = pskb->len - DataOffset;
pRecvMic = pskb->data + pskb->len - padapter->wapiInfo.extra_postfix_len;
TID = GetTid(pskb->data);
if (!list_empty(&(pWapiInfo->wapiSTAUsedList))) {
list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
if (0 == memcmp(pWapiSta->PeerMacAddr, pTA, 6)) {
bFindMatchPeer = true;
break;
}
}
}
if (!bFindMatchPeer) {
WAPI_TRACE(WAPI_ERR, "%s: Can not find Peer Sta "MAC_FMT" for Key Info!!!\n", __FUNCTION__, MAC_ARG(pTA));
return false;
}
if (IS_MCAST(pRA)) {
WAPI_TRACE(WAPI_RX, "%s: Multicast decryption !!!\n", __FUNCTION__);
if (pWapiSta->wapiMsk.keyId == KeyIdx && pWapiSta->wapiMsk.bSet) {
pLastRxPN = pWapiSta->lastRxMulticastPN;
if (!WapiComparePN(pRecvPN, pLastRxPN)) {
WAPI_TRACE(WAPI_ERR, "%s: MSK PN is not larger than last, Dropped!!!\n", __FUNCTION__);
WAPI_DATA(WAPI_ERR, "pRecvPN:", pRecvPN, 16);
WAPI_DATA(WAPI_ERR, "pLastRxPN:", pLastRxPN, 16);
return false;
}
memcpy(pLastRxPN, pRecvPN, 16);
pMicKey = pWapiSta->wapiMsk.micKey;
pDataKey = pWapiSta->wapiMsk.dataKey;
} else if (pWapiSta->wapiMskUpdate.keyId == KeyIdx && pWapiSta->wapiMskUpdate.bSet) {
WAPI_TRACE(WAPI_RX, "%s: Use Updated MSK for Decryption !!!\n", __FUNCTION__);
bUseUpdatedKey = true;
memcpy(pWapiSta->lastRxMulticastPN, pRecvPN, 16);
pMicKey = pWapiSta->wapiMskUpdate.micKey;
pDataKey = pWapiSta->wapiMskUpdate.dataKey;
} else {
WAPI_TRACE(WAPI_ERR, "%s: Can not find MSK with matched KeyIdx(%d), Dropped !!!\n", __FUNCTION__, KeyIdx);
return false;
}
} else {
WAPI_TRACE(WAPI_RX, "%s: Unicast decryption !!!\n", __FUNCTION__);
if (pWapiSta->wapiUsk.keyId == KeyIdx && pWapiSta->wapiUsk.bSet) {
WAPI_TRACE(WAPI_RX, "%s: Use USK for Decryption!!!\n", __FUNCTION__);
if (precv_hdr->bWapiCheckPNInDecrypt) {
if (GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE) {
WapiGetLastRxUnicastPNForQoSData(TID, pWapiSta, lastRxPNforQoS);
pLastRxPN = lastRxPNforQoS;
} else
pLastRxPN = pWapiSta->lastRxUnicastPN;
if (!WapiComparePN(pRecvPN, pLastRxPN))
return false;
if (bQosData)
WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta);
else
memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16);
} else
memcpy(precv_hdr->WapiTempPN, pRecvPN, 16);
if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) {
if ((pRecvPN[0] & 0x1) == 0) {
WAPI_TRACE(WAPI_ERR, "%s: Rx USK PN is not odd when Infra STA mode, Dropped !!!\n", __FUNCTION__);
return false;
}
}
pMicKey = pWapiSta->wapiUsk.micKey;
pDataKey = pWapiSta->wapiUsk.dataKey;
} else if (pWapiSta->wapiUskUpdate.keyId == KeyIdx && pWapiSta->wapiUskUpdate.bSet) {
WAPI_TRACE(WAPI_RX, "%s: Use Updated USK for Decryption!!!\n", __FUNCTION__);
if (pWapiSta->bAuthenticatorInUpdata)
bUseUpdatedKey = true;
else
bUseUpdatedKey = false;
if (bQosData)
WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta);
else
memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16);
pMicKey = pWapiSta->wapiUskUpdate.micKey;
pDataKey = pWapiSta->wapiUskUpdate.dataKey;
} else {
WAPI_TRACE(WAPI_ERR, "%s: No valid USK!!!KeyIdx=%d pWapiSta->wapiUsk.keyId=%d pWapiSta->wapiUskUpdate.keyId=%d\n", __FUNCTION__, KeyIdx, pWapiSta->wapiUsk.keyId,
pWapiSta->wapiUskUpdate.keyId);
/* dump_buf(pskb->data,pskb->len); */
return false;
}
}
WAPI_DATA(WAPI_RX, "Decryption - DataKey", pDataKey, 16);
WAPI_DATA(WAPI_RX, "Decryption - IV", pRecvPN, 16);
WapiSMS4Decryption(pDataKey, pRecvPN, pSecData, DataLen, pSecData, &OutputLength);
if (OutputLength != DataLen)
WAPI_TRACE(WAPI_ERR, "%s: Output Length Error!!!!\n", __FUNCTION__);
WAPI_DATA(WAPI_RX, "Decryption - After decryption", pskb->data, pskb->len);
DataLen -= padapter->wapiInfo.extra_postfix_len;
SecCalculateMicSMS4(KeyIdx, pMicKey, pskb->data, pSecData, DataLen, MicBuffer);
WAPI_DATA(WAPI_RX, "Decryption - MIC received", pRecvMic, SMS4_MIC_LEN);
WAPI_DATA(WAPI_RX, "Decryption - MIC calculated", MicBuffer, SMS4_MIC_LEN);
if (0 == memcmp(MicBuffer, pRecvMic, padapter->wapiInfo.extra_postfix_len)) {
WAPI_TRACE(WAPI_RX, "%s: Check MIC OK!!\n", __FUNCTION__);
if (bUseUpdatedKey) {
/* delete the old key */
if (IS_MCAST(pRA)) {
WAPI_TRACE(WAPI_API, "%s(): AE use new update MSK!!\n", __FUNCTION__);
pWapiSta->wapiMsk.keyId = pWapiSta->wapiMskUpdate.keyId;
memcpy(pWapiSta->wapiMsk.dataKey, pWapiSta->wapiMskUpdate.dataKey, 16);
memcpy(pWapiSta->wapiMsk.micKey, pWapiSta->wapiMskUpdate.micKey, 16);
pWapiSta->wapiMskUpdate.bTxEnable = pWapiSta->wapiMskUpdate.bSet = false;
} else {
WAPI_TRACE(WAPI_API, "%s(): AE use new update USK!!\n", __FUNCTION__);
pWapiSta->wapiUsk.keyId = pWapiSta->wapiUskUpdate.keyId;
memcpy(pWapiSta->wapiUsk.dataKey, pWapiSta->wapiUskUpdate.dataKey, 16);
memcpy(pWapiSta->wapiUsk.micKey, pWapiSta->wapiUskUpdate.micKey, 16);
pWapiSta->wapiUskUpdate.bTxEnable = pWapiSta->wapiUskUpdate.bSet = false;
}
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Check MIC Error, Dropped !!!!\n", __FUNCTION__);
return false;
}
pos = pskb->data;
memmove(pos + padapter->wapiInfo.extra_prefix_len, pos, IVOffset);
skb_pull(pskb, padapter->wapiInfo.extra_prefix_len);
WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__);
return true;
}
u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe)
{
u8 *pframe;
u32 res = _SUCCESS;
WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) {
WAPI_TRACE(WAPI_TX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__);
return _FAIL;
}
if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
return _FAIL;
pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
SecSWSMS4Encryption(padapter, pxmitframe);
WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
return res;
}
u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe)
{
u8 *pframe;
u32 res = _SUCCESS;
WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__);
if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) {
WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__);
return _FAIL;
}
/* drop packet when hw decrypt fail
* return tempraily */
return _FAIL;
/* pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; */
if (false == SecSWSMS4Decryption(padapter, precvframe, &padapter->recvpriv)) {
WAPI_TRACE(WAPI_ERR, "%s():SMS4 decrypt frame error\n", __FUNCTION__);
return _FAIL;
}
WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__);
return res;
}
#else
u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe)
{
WAPI_TRACE(WAPI_TX, "=========>Dummy %s\n", __FUNCTION__);
WAPI_TRACE(WAPI_TX, "<=========Dummy %s\n", __FUNCTION__);
return _SUCCESS;
}
u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe)
{
WAPI_TRACE(WAPI_RX, "=========>Dummy %s\n", __FUNCTION__);
WAPI_TRACE(WAPI_RX, "<=========Dummy %s\n", __FUNCTION__);
return _SUCCESS;
}
#endif
#endif

4971
core/rtw_wlan_util.c Normal file

File diff suppressed because it is too large Load Diff

5880
core/rtw_xmit.c Normal file

File diff suppressed because it is too large Load Diff

34
dkms-install.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "You must run this with superuser priviliges. Try \"sudo ./dkms-install.sh\"" 2>&1
exit 1
else
echo "About to run dkms install steps..."
fi
DRV_DIR="$(pwd)"
DRV_NAME=rtl8812au
DRV_VERSION=5.6.4.1
cp -r ${DRV_DIR} /usr/src/${DRV_NAME}-${DRV_VERSION}
dkms add -m ${DRV_NAME} -v ${DRV_VERSION}
dkms build -m ${DRV_NAME} -v ${DRV_VERSION}
dkms install -m ${DRV_NAME} -v ${DRV_VERSION}
RESULT=$?
echo "Finished running dkms install steps."
if grep -q -e "^CONFIG_DISABLE_IPV6 = y$" "$DRV_DIR/Makefile" ; then
if echo "net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf; then
echo "Disabled IPv6 Successfuly "
sysctl -p
else
echo "Could not disable IPv6"
fi
fi
exit $RESULT

24
dkms-remove.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "You must run this with superuser priviliges. Try \"sudo ./dkms-remove.sh\"" 2>&1
exit 1
else
echo "About to run dkms removal steps..."
fi
DRV_DIR="$(pwd)"
DRV_NAME=rtl8812au
DRV_VERSION=5.6.4.1
dkms remove ${DRV_NAME}/${DRV_VERSION} --all
rm -rf /usr/src/${DRV_NAME}-${DRV_VERSION}
RESULT=$?
if [[ "$RESULT" != "0" ]]; then
echo "Error occurred while running dkms remove." 2>&1
else
echo "Finished running dkms removal steps."
fi
exit $RESULT

10
dkms.conf Normal file
View File

@ -0,0 +1,10 @@
PACKAGE_NAME="realtek-rtl88xxau"
PACKAGE_VERSION="5.6.4.1~20190622"
CLEAN="'make' clean"
BUILT_MODULE_NAME[0]=88XXau
PROCS_NUM=`nproc`
[ $PROCS_NUM -gt 16 ] && PROCS_NUM=16
DEST_MODULE_LOCATION[0]="/updates"
MAKE="'make' -j$PROCS_NUM KVER=${kernelver} KSRC=/lib/modules/${kernelver}/build"
AUTOINSTALL="yes"
REMAKE_INITRD=no

View File

@ -0,0 +1 @@
options 88XXau rtw_power_mgnt=0 rtw_enusbss=0

Some files were not shown because too many files have changed in this diff Show More