Browse Source
GPLv2 firmware for carl9170, Atheros AR9170 802.11 draft-n USB driver. Cc: Christian Lamparter <chunkeey@googlemail.com> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>main
Xose Vazquez Perez
13 years ago
committed by
Ben Hutchings
113 changed files with 26232 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 2.8) |
||||
|
||||
project(carl9170) |
||||
|
||||
#if you don't want the full compiler output, remove the following line |
||||
#set(CMAKE_VERBOSE_MAKEFILE ON) |
||||
|
||||
include("config.cmake") |
||||
|
||||
add_subdirectory(carlfw) |
||||
|
||||
if (CONFIG_CARL9170FW_BUILD_MINIBOOT) |
||||
add_subdirectory(minifw) |
||||
endif (CONFIG_CARL9170FW_BUILD_MINIBOOT) |
||||
|
||||
if (CONFIG_CARL9170FW_BUILD_TOOLS) |
||||
add_subdirectory(tools) |
||||
endif (CONFIG_CARL9170FW_BUILD_TOOLS) |
||||
|
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
Atheros carl9170 firmware - used by the ar9170 wireless device |
||||
|
||||
Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
Copyright (c) 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
|
||||
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. |
@ -0,0 +1,339 @@
@@ -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. |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
mainmenu "CARL9170 Firmware Configuration" |
||||
|
||||
source "carlfw/Kconfig" |
||||
source "minifw/Kconfig" |
||||
source "tools/Kconfig" |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
Community AR9170 Linux firmware |
||||
----------------------- |
||||
|
||||
This is the firmware for the Atheros ar9170 802.11n devices. |
||||
|
||||
To build the firmware you will need an SH-2 toolchain. |
||||
You can build your own toolchain: |
||||
|
||||
make -C toolchain |
||||
|
||||
but be aware that this will take some time and requires |
||||
about 1.2 GiB disk space. |
||||
|
||||
The resulting firmware, carl9170.fw, can be used only |
||||
with the carl9170 Linux driver. |
||||
|
||||
After getting a toolchain, you will need to get more |
||||
tools & libs: |
||||
|
||||
* gcc 4.4+ |
||||
|
||||
* gperf, bison/flex |
||||
|
||||
* cmake 2.8.0+ |
||||
|
||||
* libusb 1.0+ |
||||
|
||||
* SDL SDK 1.2.13+ |
||||
|
||||
afterwards, simply execute: |
||||
|
||||
autogen.sh |
||||
|
||||
to start the configuration and build process. |
||||
|
||||
if you want to "install" your own firmware, you can either |
||||
do this manually, or by executing: |
||||
|
||||
autogen.sh install |
||||
|
||||
This will place a copy with the right filename [adds API rev] |
||||
into /lib/firmware/[the default path on most Distributions]. |
||||
|
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash |
||||
|
||||
set -e |
||||
|
||||
case "$1" in |
||||
config) |
||||
echo "Configuring..." |
||||
pushd config |
||||
cmake . |
||||
make |
||||
popd |
||||
config/conf Kconfig |
||||
cmake . |
||||
;; |
||||
|
||||
compile) |
||||
echo "Compile time..." |
||||
make |
||||
;; |
||||
|
||||
install) |
||||
if [ ! -e .config ]; then |
||||
exit 1 |
||||
fi |
||||
|
||||
. ./.config |
||||
make |
||||
|
||||
echo -n "Installing firmware..." |
||||
if [ "$CONFIG_CARL9170FW_BUILD_TOOLS" = "y" ] && |
||||
[ "$CONFIG_CARL9170FW_BUILD_MINIBOOT" = "y" ]; then |
||||
echo -n "Apply miniboot..." |
||||
tools/src/miniboot a carlfw/carl9170.fw minifw/miniboot.fw |
||||
fi |
||||
|
||||
sudo install -m 644 carlfw/carl9170.fw \ |
||||
/lib/firmware/carl9170-$CONFIG_CARL9170FW_RELEASE_VERSION.fw |
||||
echo "done." |
||||
;; |
||||
|
||||
*) |
||||
$0 config |
||||
$0 compile |
||||
;; |
||||
|
||||
|
||||
esac |
@ -0,0 +1,67 @@
@@ -0,0 +1,67 @@
|
||||
cmake_minimum_required(VERSION 2.8) |
||||
|
||||
project(carl9170.fw) |
||||
|
||||
include("../extra/sh-elf-linux.cmake") |
||||
include("../config.cmake") |
||||
|
||||
set(CARLFW_CFLAGS_WARNING "-W -Wall -Wextra -Wunreachable-code -Winline -Wlogical-op -Wno-packed-bitfield-compat -Winit-self -Wshadow -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wformat=2 -Wcast-align -Wmissing-format-attribute -Wmissing-prototypes -Wtype-limits -Wmissing-declarations -Wmissing-noreturn -Wredundant-decls -Wnested-externs -Wdisabled-optimization -Wpointer-arith -Wvolatile-register-var -Waddress -Wbad-function-cast -Wunsafe-loop-optimizations") |
||||
set(CARLFW_CFLAGS_EXTRA "-mbitops -std=gnu99 -ffunction-sections -Wframe-larger-than=128 -Werror") |
||||
set(CARLFW_CFLAGS_DEF "-D__CARL9170FW__") |
||||
if (CONFIG_CARL9170FW_AGGRESSIVE_CFLAGS) |
||||
set(CARLFW_CFLAGS_AGGRESSIVE "-fomit-frame-pointer -fsee -frename-registers -ftree-vectorize -flto -fstrict-volatile-bitfields -fmodulo-sched") |
||||
endif (CONFIG_CARL9170FW_AGGRESSIVE_CFLAGS) |
||||
|
||||
include_directories (../include/linux ../include/shared ../include include) |
||||
|
||||
set(carl9170_main_src src/main.c src/wlan.c src/fw.c src/gpio.c |
||||
src/cmd.c src/uart.c src/dma.c src/hostif.c src/reboot.S |
||||
src/printf.c src/rf.c src/cam.c src/wol.c) |
||||
|
||||
set(carl9170_lib_src src/ashlsi3.S src/memcpy.S src/memset.S src/udivsi3_i4i-Os.S) |
||||
set(carl9170_usb_src usb/main.c usb/usb.c usb/fifo.c) |
||||
|
||||
set(carl9170_src ${carl9170_main_src} ${carl9170_lib_src} ${carl9170_usb_src}) |
||||
|
||||
set_source_files_properties(src/ashlsi3.S PROPERTIES LANGUAGE C) |
||||
set_source_files_properties(src/memcpy.S PROPERTIES LANGUAGE C) |
||||
set_source_files_properties(src/memset.S PROPERTIES LANGUAGE C) |
||||
set_source_files_properties(src/reboot.S PROPERTIES LANGUAGE C) |
||||
set_source_files_properties(src/udivsi3_i4i-Os.S PROPERTIES LANGUAGE C) |
||||
|
||||
add_executable(carl9170.elf ${carl9170_src}) |
||||
|
||||
set_target_properties(carl9170.elf PROPERTIES LINKER_LANGUAGE C) |
||||
|
||||
set_target_properties(carl9170.elf PROPERTIES COMPILE_FLAGS |
||||
" ${CARLFW_CFLAGS_DEF} ${CARLFW_CFLAGS_EXTRA} ${CARLFW_CFLAGS_AGGRESSIVE} ${CARLFW_CFLAGS_WARNING}") |
||||
set_target_properties(carl9170.elf PROPERTIES LINK_FLAGS "-Tcarl9170.lds") |
||||
|
||||
|
||||
|
||||
add_custom_target(firmware ALL) |
||||
|
||||
add_custom_command( |
||||
SOURCE carl9170.elf |
||||
COMMAND ${OBJCOPY} |
||||
ARGS --strip-unneeded -O binary -R .sram -R .eeprom -R .fwdsc carl9170.elf carl9170.bin |
||||
TARGET firmware |
||||
OUTPUTS carl9170.bin) |
||||
|
||||
add_custom_command( |
||||
SOURCE carl9170.elf |
||||
COMMAND ${OBJCOPY} |
||||
ARGS --strip-unneeded -O binary -j .fwdsc carl9170.elf carl9170.dsc |
||||
TARGET firmware |
||||
OUTPUTS carl9170.dsc) |
||||
|
||||
add_custom_command( |
||||
SOURCE firmware |
||||
TARGET firmware |
||||
COMMAND cat |
||||
ARGS "carl9170.bin" "carl9170.dsc" > "carl9170.fw" |
||||
DEPENDS carl9170.elf carl9170.bin carl9170.dsc |
||||
OUTPUTS carl9170.fw) |
||||
|
||||
SET_DIRECTORY_PROPERTIES( |
||||
PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "carl9170.fw") |
@ -0,0 +1,233 @@
@@ -0,0 +1,233 @@
|
||||
menu "General" |
||||
|
||||
config CARL9170FW_RELEASE_VERSION |
||||
int |
||||
default 1 |
||||
|
||||
menu "Selectable Hardware Options" |
||||
|
||||
choice |
||||
prompt "Receiver Max. Frame Length" |
||||
default CARL9170FW_RX_FRAME_LEN_8192 |
||||
|
||||
config CARL9170FW_RX_FRAME_LEN_4096 |
||||
bool "4096" |
||||
|
||||
config CARL9170FW_RX_FRAME_LEN_8192 |
||||
bool "8192" |
||||
|
||||
config CARL9170FW_RX_FRAME_LEN_16384 |
||||
bool "16384" |
||||
|
||||
config CARL9170FW_RX_FRAME_LEN_32768 |
||||
bool "32768" |
||||
|
||||
endchoice |
||||
|
||||
config CARL9170FW_RX_FRAME_LEN |
||||
int |
||||
default 4096 if CARL9170FW_RX_FRAME_LEN_4096 |
||||
default 8192 if CARL9170FW_RX_FRAME_LEN_8192 |
||||
default 16384 if CARL9170FW_RX_FRAME_LEN_16384 |
||||
default 32768 if CARL9170FW_RX_FRAME_LEN_32768 |
||||
|
||||
config CARL9170FW_GPIO_INTERRUPT |
||||
def_bool y |
||||
prompt "GPIO Software Interrupt" |
||||
---help--- |
||||
When this option is enabled, the firmware will poll the GPIO |
||||
registers and reports to the driver whenever the GPIO state |
||||
has changed from a previous state. |
||||
|
||||
Note: This feature is necessary to monitor the WPS button, |
||||
if you have one on your device, then say Y. |
||||
|
||||
config CARL9170FW_SECURITY_ENGINE |
||||
def_bool y |
||||
prompt "Support Hardware Crypto Engine" |
||||
---help--- |
||||
This options controls if the firmware will allow the driver |
||||
to program the security engine / CAM through a firmware |
||||
interface. |
||||
|
||||
Say Y. Unless you want to do the en- and decryption for |
||||
CCMP(AES), TKIP/WEP(RC4) in the application anyway. |
||||
|
||||
config CARL9170FW_RADIO_FUNCTIONS |
||||
def_bool y |
||||
prompt "Enable Firmware-supported Radio/RF functions" |
||||
---help--- |
||||
Some PHY/RF functions (e.g.: AGC and Noise calibration) need |
||||
to be done in the firmware. |
||||
|
||||
Say Y, unless you really don't need the Radio/RF for |
||||
your project. |
||||
|
||||
endmenu |
||||
|
||||
menu "802.11 Firmware Features" |
||||
|
||||
config CARL9170FW_CAB_QUEUE |
||||
def_bool y |
||||
prompt "Support software-based Content after Beacon Queue" |
||||
---help--- |
||||
This (software) queue is used to send any broad-/multi-cast buffered |
||||
frames after the next DTIM beacon. |
||||
|
||||
This feature is required for Accesspoint mode operation. |
||||
|
||||
Say Y. |
||||
|
||||
endmenu |
||||
|
||||
source "carlfw/usb/Kconfig" |
||||
|
||||
menu "Experimental, Unstable & Testing Extensions" |
||||
|
||||
config CARL9170FW_PRINTF |
||||
def_bool y |
||||
prompt "Advanced printf" |
||||
depends on CARL9170FW_DEBUG_UART || CARL9170FW_DEBUG_USB |
||||
---help--- |
||||
Advanced printf (very useful for debugging purposes) |
||||
The formats supported by this implementation are: |
||||
'd' 'u' 'c' 's' 'x' 'X' 'p'. |
||||
|
||||
Note: If this option is disabled, the firmware will be only |
||||
capable of reported _preformated_ string. |
||||
|
||||
config CARL9170FW_EXPERIMENTAL |
||||
def_bool y |
||||
prompt "Experimental Features" |
||||
|
||||
config CARL9170FW_WOL_OPTION |
||||
def_bool n |
||||
prompt "Wakeup on WLAN" |
||||
depends on CARL9170FW_EXPERIMENTAL |
||||
---help--- |
||||
With this option enabled, the firmware can wake-up |
||||
suspended hosts... As long as they fully support |
||||
USB remote wakeup. |
||||
|
||||
config CARL9170FW_WOL |
||||
def_bool n |
||||
depends on CARL9170FW_WOL_OPTION |
||||
|
||||
config CARL9170FW_WOL_NL80211_TRIGGERS |
||||
def_bool n |
||||
prompt "Standard NL80211 wakeup triggers" |
||||
depends on CARL9170FW_WOL_OPTION |
||||
select CARL9170FW_WOL |
||||
---help--- |
||||
Available triggers: |
||||
* Magic Packet(tm) pattern |
||||
* disconnect event |
||||
|
||||
config CARL9170FW_WOL_PROBE_REQUEST |
||||
def_bool n |
||||
prompt "Probe Request" |
||||
depends on CARL9170FW_WOL_OPTION |
||||
select CARL9170FW_WOL |
||||
---help--- |
||||
Scan probe requests for a given SSID. |
||||
|
||||
config CARL9170FW_WOL_PROBE_REQUEST_SSID |
||||
string |
||||
prompt "Wakeup on WLAN SSID" |
||||
default "CARL9170_WAKEUP" |
||||
depends on CARL9170FW_WOL_PROBE_REQUEST |
||||
|
||||
config CARL9170FW_VIFS_NUM |
||||
default 1 |
||||
int |
||||
prompt "Number of additional pseudo virtual interfaces" |
||||
depends on CARL9170FW_EXPERIMENTAL |
||||
|
||||
config CARL9170FW_FW_MAC_RESET |
||||
def_bool y |
||||
prompt "Firmware MAC Chip recovery" |
||||
depends on CARL9170FW_EXPERIMENTAL |
||||
|
||||
config CARL9170FW_NOISY_MAC_RESET |
||||
def_bool n |
||||
prompt "Notify MAC RESET events" |
||||
depends on CARL9170FW_FW_MAC_RESET |
||||
|
||||
config CARL9170FW_BROKEN_FEATURES |
||||
def_bool n |
||||
prompt "Broken Featurs" |
||||
|
||||
config CARL9170FW_DEBUG |
||||
def_bool n |
||||
depends on CARL9170FW_BROKEN_FEATURES && CARL9170FW_PRINTF |
||||
prompt "Enable verbose debugging messages" |
||||
|
||||
config CARL9170FW_DEBUG_LED_HEARTBEAT |
||||
def_bool n |
||||
prompt "LED Heartbeat" |
||||
depends on CARL9170FW_BROKEN_FEATURES |
||||
---help--- |
||||
This option conflicts with the application's LED code. |
||||
Also, it assumes that you have two LEDs, which is not |
||||
necessarily true. |
||||
|
||||
config CARL9170FW_DEBUG_UART |
||||
def_bool n |
||||
prompt "Pass debug messages through Highspeed UART" |
||||
depends on CARL9170FW_BROKEN_FEATURES |
||||
---help--- |
||||
This option allows the firmware to send BUG/ERR/INFO/DBG and |
||||
hexdumps through the UART _as well_. However, first: you must |
||||
connect a working logger. |
||||
|
||||
config CARL9170FW_WATCHDOG_BUTTON |
||||
def_bool n |
||||
depends on CARL9170FW_BROKEN && CARL9170FW_GPIO_INTERRUPT |
||||
prompt "Trigger Watchdog by pressing the WPS button" |
||||
|
||||
choice CARL9170FW_UART_CLOCK |
||||
prompt "UART Clock" |
||||
depends on CARL9170FW_DEBUG_UART |
||||
default CARL9170FW_UART_CLOCK_40M |
||||
|
||||
config CARL9170FW_UART_CLOCK_25M |
||||
bool "25" |
||||
|
||||
config CARL9170FW_UART_CLOCK_40M |
||||
bool "40" |
||||
|
||||
endchoice |
||||
|
||||
config CARL9170FW_UNUSABLE |
||||
def_bool y |
||||
depends on CARL9170FW_BROKEN || CARL9170FW_DEBUG |
||||
|
||||
config CARL9170FW_USB_MODESWITCH |
||||
def_bool n |
||||
prompt "USB 1.1 / 2.0 switching support" |
||||
depends on CARL9170FW_BROKEN_FEATURES |
||||
---help--- |
||||
Mostly implemented, but untested and some serious |
||||
doubts remain. |
||||
|
||||
config CARL9170FW_DMA_QUEUE_BUMP |
||||
def_bool n |
||||
prompt "Bump a stuck TX queue before doing a MAC reset" |
||||
depends on CARL9170FW_BROKEN_FEATURES |
||||
|
||||
menu "Build Options" |
||||
config CARL9170FW_AGGRESSIVE_CFLAGS |
||||
def_bool y |
||||
prompt "Enable aggressive size optimization" |
||||
---help--- |
||||
This option adds several more optimization compiler flags, |
||||
which can greatly reduce the firmware size... at the expense |
||||
of machine-code readability. |
||||
|
||||
Say Y. Else the firmware might not fit onto the device! |
||||
|
||||
endmenu |
||||
|
||||
endmenu |
||||
|
||||
endmenu |
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
/* |
||||
* The carl9170 firwmare gets copied into the device's |
||||
* Program RAM (pram), which has a size of 16K, but |
||||
* also has to accomodate the stack the device uses, |
||||
* which starts at the top of the 16k, so we pretend |
||||
* that we just have 16256 (16k - 128) of pram. |
||||
* |
||||
* This section documents some of the other areas |
||||
* mapped into the firmware processor's address space |
||||
* as well. |
||||
*/ |
||||
|
||||
ENTRY(_start); |
||||
|
||||
MEMORY |
||||
{ |
||||
eeprom : ORIGIN = 0x000000, LENGTH = 1024k |
||||
sram : ORIGIN = 0x100000, LENGTH = 96k |
||||
uart : ORIGIN = 0x1c0000, LENGTH = 4k |
||||
timer : ORIGIN = 0x1c1000, LENGTH = 4k |
||||
vflash : ORIGIN = 0x1c2000, LENGTH = 4k |
||||
wlan : ORIGIN = 0x1c3000, LENGTH = 4k |
||||
pci2ahb : ORIGIN = 0x1c4000, LENGTH = 4k |
||||
security : ORIGIN = 0x1c5000, LENGTH = 4k |
||||
gpio : ORIGIN = 0x1d0000, LENGTH = 4k |
||||
memctl : ORIGIN = 0x1d1000, LENGTH = 4k |
||||
irqctl : ORIGIN = 0x1d2000, LENGTH = 4k |
||||
usb : ORIGIN = 0x1e1000, LENGTH = 4k |
||||
pta : ORIGIN = 0x1e2000, LENGTH = 4k |
||||
pram : ORIGIN = 0x200000, LENGTH = 16256 |
||||
bogus : ORIGIN = 0x300000, LENGTH = 8k |
||||
} |
||||
|
||||
SECTIONS |
||||
{ |
||||
.eeprom : { *(.eeprom*) } > eeprom |
||||
.sram : { *(.sram*) } > sram |
||||
|
||||
/* |
||||
* The ar9170 boot code will execute the code |
||||
* at address 0x04 from the loaded firmware as |
||||
* such we must ensure our starting routine |
||||
* is kept at that address. |
||||
*/ |
||||
.padding : { |
||||
/* NOP NOP just in case */ |
||||
LONG(0x00090009) |
||||
} > pram |
||||
|
||||
.boot : { *(.boot) } > pram |
||||
/* anything else can be anywhere */ |
||||
|
||||
.text : { *(.text*) } > pram |
||||
.rodata : { *(.rodata*) } > pram |
||||
.bss : { *(.bss) } > pram |
||||
.data : { *(.data*) } > pram |
||||
|
||||
.fwdsc : { KEEP(*(.fwdsc)) } > bogus |
||||
} |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* CAM (Security Engine) definitions |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_CAM_H |
||||
#define __CARL9170FW_CAM_H |
||||
|
||||
#include "config.h" |
||||
#include "cmd.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_SECURITY_ENGINE |
||||
|
||||
#define ENCRY_TYPE_START_ADDR 24 |
||||
#define DEFAULT_ENCRY_TYPE 26 |
||||
#define KEY_START_ADDR 27 |
||||
#define STA_KEY_START_ADDR 155 |
||||
#define COUNTER_START_ADDR 163 |
||||
#define STA_COUNTER_START_ADDR 165 |
||||
|
||||
/* CAM */ |
||||
#define MIC_FINISH 0x1 |
||||
|
||||
void set_key(const struct carl9170_set_key_cmd *key); |
||||
void disable_key(const struct carl9170_disable_key_cmd *key); |
||||
|
||||
#endif /* CONFIG_CARL9170FW_SECURITY_ENGINE */ |
||||
|
||||
#endif /* __CARL9170FW_CAM_H */ |
@ -0,0 +1,222 @@
@@ -0,0 +1,222 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Firmware context definition |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_CARL9170_H |
||||
#define __CARL9170FW_CARL9170_H |
||||
|
||||
#include "generated/autoconf.h" |
||||
#include "version.h" |
||||
#include "config.h" |
||||
#include "types.h" |
||||
#include "compiler.h" |
||||
#include "fwcmd.h" |
||||
#include "hw.h" |
||||
#include "dma.h" |
||||
#include "usb.h" |
||||
#include "cmd.h" |
||||
|
||||
struct carl9170_bar_ctx { |
||||
uint8_t ta[6]; |
||||
uint8_t ra[6]; |
||||
__le16 start_seq_num; |
||||
__le16 control; |
||||
}; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_CAB_QUEUE |
||||
enum carl9170_cab_trigger { |
||||
CARL9170_CAB_TRIGGER_EMPTY = 0, |
||||
CARL9170_CAB_TRIGGER_ARMED = BIT(0), |
||||
CARL9170_CAB_TRIGGER_DEFER = BIT(1), |
||||
}; |
||||
#endif /* CONFIG_CARL9170FW_CAB_QUEUE */ |
||||
|
||||
enum carl9170_ep0_action { |
||||
CARL9170_EP0_NO_ACTION = 0, |
||||
CARL9170_EP0_STALL = BIT(0), |
||||
CARL9170_EP0_TRIGGER = BIT(1), |
||||
}; |
||||
|
||||
enum carl9170_mac_reset_state { |
||||
CARL9170_MAC_RESET_OFF = 0, |
||||
CARL9170_MAC_RESET_ARMED, |
||||
CARL9170_MAC_RESET_RESET, |
||||
CARL9170_MAC_RESET_FORCE, |
||||
}; |
||||
|
||||
enum carl9170_suspend_mode { |
||||
CARL9170_HOST_AWAKE = 0, |
||||
CARL9170_HOST_SUSPENDED, |
||||
CARL9170_AWAKE_HOST, |
||||
}; |
||||
|
||||
enum carl9170_phy_state { |
||||
CARL9170_PHY_OFF = 0, |
||||
CARL9170_PHY_ON |
||||
}; |
||||
|
||||
typedef void (*fw_desc_callback_t)(void *, const bool); |
||||
|
||||
/* |
||||
* This platform - being an odd 32-bit architecture - prefers to |
||||
* have 32-Bit variables. |
||||
*/ |
||||
|
||||
struct firmware_context_struct { |
||||
/* timer / clocks */ |
||||
unsigned int ticks_per_usec; |
||||
unsigned int counter; /* main() cycles */ |
||||
|
||||
/* misc */ |
||||
unsigned int watchdog_enable; |
||||
unsigned int reboot; |
||||
unsigned int suspend_mode; |
||||
|
||||
struct { |
||||
/* Host Interface DMA queues */ |
||||
struct dma_queue up_queue; /* used to send frames to the host */ |
||||
struct dma_queue down_queue; /* stores incoming frames from the host */ |
||||
} pta; |
||||
|
||||
struct { |
||||
/* Hardware DMA queues */ |
||||
struct dma_queue tx_queue[__AR9170_NUM_TX_QUEUES]; /* wlan tx queue */ |
||||
struct dma_queue tx_retry; |
||||
struct dma_queue rx_queue; /* wlan rx queue */ |
||||
|
||||
/* tx aggregate scheduling */ |
||||
struct carl9170_tx_superframe *ampdu_prev[__AR9170_NUM_TX_QUEUES]; |
||||
|
||||
/* Hardware DMA queue unstuck/fix detection */ |
||||
unsigned int last_super_num[__AR9170_NUM_TX_QUEUES]; |
||||
struct carl9170_tx_superframe *last_super[__AR9170_NUM_TX_QUEUES]; |
||||
unsigned int mac_reset; |
||||
unsigned int soft_int; |
||||
|
||||
/* rx filter */ |
||||
unsigned int rx_filter; |
||||
|
||||
/* tx sequence control counters */ |
||||
unsigned int sequence[CARL9170_INTF_NUM]; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_CAB_QUEUE |
||||
/* CAB */ |
||||
struct dma_queue cab_queue[CARL9170_INTF_NUM]; |
||||
unsigned int cab_queue_len[CARL9170_INTF_NUM]; |
||||
unsigned int cab_flush_time; |
||||
enum carl9170_cab_trigger cab_flush_trigger[CARL9170_INTF_NUM]; |
||||
#endif /* CONFIG_CARL9170FW_CAB_QUEUE */ |
||||
|
||||
/* tx status */ |
||||
unsigned int tx_status_pending, |
||||
tx_status_head_idx, |
||||
tx_status_tail_idx; |
||||
struct carl9170_tx_status tx_status_cache[CARL9170_TX_STATUS_NUM]; |
||||
|
||||
/* internal descriptor for use within the service routines */ |
||||
struct dma_desc *fw_desc; |
||||
unsigned int fw_desc_available; |
||||
void *fw_desc_data; |
||||
fw_desc_callback_t fw_desc_callback; |
||||
|
||||
/* BA(R) Request Handler */ |
||||
struct carl9170_bar_ctx ba_cache[CONFIG_CARL9170FW_BACK_REQS_NUM]; |
||||
unsigned int ba_tail_idx, |
||||
ba_head_idx, |
||||
queued_ba; |
||||
|
||||
unsigned int queued_bar; |
||||
} wlan; |
||||
|
||||
struct { |
||||
unsigned int config, |
||||
interface_setting, |
||||
alternate_interface_setting, |
||||
device_feature; |
||||
enum carl9170_ep0_action ep0_action; |
||||
|
||||
void *ep0_txrx_buffer; |
||||
unsigned int ep0_txrx_len, |
||||
ep0_txrx_pos; |
||||
|
||||
struct ar9170_usb_config *cfg_desc; |
||||
struct ar9170_usb_config *os_cfg_desc; |
||||
|
||||
/* |
||||
* special buffers for command & response handling |
||||
* |
||||
* the firmware uses a sort of ring-buffer to communicate |
||||
* to the host. |
||||
*/ |
||||
unsigned int int_pending, |
||||
int_desc_available, |
||||
int_head_index, |
||||
int_tail_index; |
||||
struct dma_desc *int_desc; |
||||
struct carl9170_rsp int_buf[CARL9170_INT_RQ_CACHES]; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_USB |
||||
/* USB printf */ |
||||
unsigned int put_index; |
||||
uint8_t put_buffer[CARL9170_MAX_CMD_PAYLOAD_LEN]; |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_USB */ |
||||
|
||||
} usb; |
||||
|
||||
struct { |
||||
#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS |
||||
/* (cached) ar9170_rf_init */ |
||||
|
||||
/* PHY/RF state */ |
||||
unsigned int frequency; |
||||
unsigned int ht_settings; |
||||
|
||||
enum carl9170_phy_state state; |
||||
struct carl9170_psm psm; |
||||
#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ |
||||
} phy; |
||||
|
||||
unsigned int tally_clock; |
||||
struct carl9170_tally_rsp tally; |
||||
unsigned int tx_time; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
struct { |
||||
struct carl9170_wol_cmd cmd; |
||||
unsigned int last_beacon; |
||||
unsigned int lost_null; |
||||
unsigned int last_null; |
||||
bool wake_up; |
||||
} wol; |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT |
||||
struct carl9170_gpio cached_gpio_state; |
||||
#endif /*CONFIG_CARL9170FW_GPIO_INTERRUPT */ |
||||
}; |
||||
|
||||
/* |
||||
* global firmware context struct. |
||||
* |
||||
* NOTE: This struct will zeroed out in start() |
||||
*/ |
||||
extern struct firmware_context_struct fw; |
||||
#endif /* __CARL9170FW_CARL9170_H */ |
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Firmware command interface definition |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_CMD_H |
||||
#define __CARL9170FW_CMD_H |
||||
|
||||
#include "config.h" |
||||
#include "compiler.h" |
||||
#include "types.h" |
||||
|
||||
#include "fwcmd.h" |
||||
|
||||
static inline void __check(void) |
||||
{ |
||||
BUILD_BUG_ON(sizeof(struct carl9170_cmd) != CARL9170_MAX_CMD_LEN); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_rsp) != CARL9170_MAX_CMD_LEN); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_set_key_cmd) != CARL9170_SET_KEY_CMD_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_disable_key_cmd) != CARL9170_DISABLE_KEY_CMD_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_rf_init) != CARL9170_RF_INIT_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_rf_init_result) != CARL9170_RF_INIT_RESULT_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_psm) != CARL9170_PSM_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_tsf_rsp) != CARL9170_TSF_RSP_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_bcn_ctrl_cmd) != CARL9170_BCN_CTRL_CMD_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_tx_status) != CARL9170_TX_STATUS_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct _carl9170_tx_status) != CARL9170_TX_STATUS_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_gpio) != CARL9170_GPIO_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_rx_filter_cmd) != CARL9170_RX_FILTER_CMD_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_wol_cmd) != CARL9170_WOL_CMD_SIZE); |
||||
} |
||||
|
||||
void handle_cmd(struct carl9170_rsp *resp); |
||||
|
||||
#endif /* __CARL9170FW_CMD_H */ |
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
/* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "generated/autoconf.h" |
||||
#include "version.h" |
||||
#include "types.h" |
||||
#include "compiler.h" |
||||
#include "fwcmd.h" |
||||
#include "hw.h" |
||||
|
||||
#ifndef __CARL9170FW_CONFIG_H |
||||
#define __CARL9170FW_CONFIG_H |
||||
|
||||
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) |
||||
|
||||
#if GCC_VERSION < 40400 |
||||
# error "This firmware will not work if it is compiled with gcc versions < 4.4" |
||||
# error "See: http://gcc.gnu.org/gcc-4.4/changes.html / Caveats No. 4" |
||||
#endif |
||||
|
||||
#if ((defined CONFIG_CARL9170FW_PRINTF) && \ |
||||
(!defined CONFIG_CARL9170FW_DEBUG_USB) && \ |
||||
(!defined CONFIG_CARL9170FW_DEBUG_UART)) |
||||
# warning "You have disabled all debug message transports." |
||||
# warning "However CONFIG_CARL9170FW_PRINTF is still set..." |
||||
# warning "Which is a waste of firmware space, if you ask me." |
||||
#endif |
||||
|
||||
#define CARL9170_TX_STATUS_NUM (CARL9170_RSP_TX_STATUS_NUM) |
||||
#define CARL9170_INT_RQ_CACHES 16 |
||||
#define AR9170_INT_MAGIC_HEADER_SIZE 12 |
||||
#define CARL9170_TBTT_DELTA (CARL9170_PRETBTT_KUS + 1) |
||||
|
||||
#define CARL9170_GPIO_MASK (AR9170_GPIO_PORT_WPS_BUTTON_PRESSED) |
||||
|
||||
#ifdef CONFIG_CARL9170FW_VIFS_NUM |
||||
#define CARL9170_INTF_NUM (1 + CONFIG_CARL9170FW_VIFS_NUM) |
||||
#else |
||||
#define CARL9170_INTF_NUM (1) |
||||
#endif /* CONFIG_CARL9170FW_VIFS_NUM */ |
||||
|
||||
#define CONFIG_CARL9170FW_BACK_REQS_NUM 4 |
||||
|
||||
static inline void __config_check(void) |
||||
{ |
||||
BUILD_BUG_ON(!CARL9170_TX_STATUS_NUM); |
||||
BUILD_BUG_ON(CARL9170_INTF_NUM < 1); |
||||
BUILD_BUG_ON(CARL9170_INTF_NUM >= AR9170_MAX_VIRTUAL_MAC); |
||||
} |
||||
|
||||
#endif /* __CARL9170FW_CONFIG_H */ |
@ -0,0 +1,349 @@
@@ -0,0 +1,349 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* This module contains DMA descriptor related definitions. |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_DMA_H |
||||
#define __CARL9170FW_DMA_H |
||||
|
||||
#include "config.h" |
||||
#include "types.h" |
||||
#include "compiler.h" |
||||
#include "hw.h" |
||||
#include "ieee80211.h" |
||||
#include "wlan.h" |
||||
|
||||
struct dma_desc { |
||||
volatile uint16_t status; /* Descriptor status */ |
||||
volatile uint16_t ctrl; /* Descriptor control */ |
||||
volatile uint16_t dataSize; /* Data size */ |
||||
volatile uint16_t totalLen; /* Total length */ |
||||
struct dma_desc *lastAddr; /* Last address of this chain */ |
||||
union { |
||||
uint8_t *_dataAddr; /* Data buffer address */ |
||||
void *dataAddr; |
||||
} __packed; |
||||
struct dma_desc *nextAddr; /* Next TD address */ |
||||
} __packed __aligned(4); |
||||
|
||||
/* Up, Dn, 5x Tx, retry, Rx, [USB Int], (CAB), FW */ |
||||
#define AR9170_TERMINATOR_NUMBER_B 10 |
||||
|
||||
#define AR9170_TERMINATOR_NUMBER_INT 1 |
||||
|
||||
#ifdef CONFIG_CARL9170FW_CAB_QUEUE |
||||
#define AR9170_TERMINATOR_NUMBER_CAB CARL9170_INTF_NUM |
||||
#else |
||||
#define AR9170_TERMINATOR_NUMBER_CAB 0 |
||||
#endif /* CONFIG_CARL9170FW_CAB_QUEUE */ |
||||
|
||||
#define AR9170_TERMINATOR_NUMBER (AR9170_TERMINATOR_NUMBER_B + \ |
||||
AR9170_TERMINATOR_NUMBER_INT + \ |
||||
AR9170_TERMINATOR_NUMBER_CAB) |
||||
|
||||
#define AR9170_BLOCK_SIZE (256 + 64) |
||||
|
||||
#define AR9170_DESCRIPTOR_SIZE (sizeof(struct dma_desc)) |
||||
|
||||
struct ar9170_tx_ba_frame { |
||||
struct ar9170_tx_hwdesc hdr; |
||||
struct ieee80211_ba ba; |
||||
} __packed; |
||||
|
||||
struct carl9170_tx_ba_superframe { |
||||
struct carl9170_tx_superdesc s; |
||||
struct ar9170_tx_ba_frame f; |
||||
} __packed; |
||||
|
||||
struct ar9170_tx_null_frame { |
||||
struct ar9170_tx_hwdesc hdr; |
||||
struct ieee80211_hdr null; |
||||
} __packed; |
||||
|
||||
struct carl9170_tx_null_superframe { |
||||
struct carl9170_tx_superdesc s; |
||||
struct ar9170_tx_null_frame f; |
||||
} __packed; |
||||
|
||||
#define CARL9170_BA_BUFFER_LEN (__roundup(sizeof(struct carl9170_tx_ba_superframe), 16)) |
||||
#define CARL9170_RSP_BUFFER_LEN AR9170_BLOCK_SIZE |
||||
|
||||
struct carl9170_sram_reserved { |
||||
union { |
||||
uint32_t buf[CARL9170_BA_BUFFER_LEN / sizeof(uint32_t)]; |
||||
struct carl9170_tx_ba_superframe ba; |
||||
} ba; |
||||
|
||||
union { |
||||
uint32_t buf[CARL9170_MAX_CMD_LEN / sizeof(uint32_t)]; |
||||
struct carl9170_cmd cmd; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
struct carl9170_tx_null_superframe null; |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
} cmd; |
||||
|
||||
union { |
||||
uint32_t buf[CARL9170_RSP_BUFFER_LEN / sizeof(uint32_t)]; |
||||
struct carl9170_rsp rsp; |
||||
} rsp; |
||||
|
||||
union { |
||||
uint32_t buf[CARL9170_INTF_NUM][AR9170_MAC_BCN_LENGTH_MAX / sizeof(uint32_t)]; |
||||
} bcn; |
||||
}; |
||||
|
||||
/* |
||||
* Memory layout in RAM: |
||||
* |
||||
* 0x100000 +-- |
||||
* | terminator descriptors (dma_desc) |
||||
* | - Up (to USB host) |
||||
* | - Down (from USB host) |
||||
* | - TX (5x, to wifi) |
||||
* | - AMPDU TX retry |
||||
* | - RX (from wifi) |
||||
* | - CAB Queue |
||||
* | - FW cmd & req descriptor |
||||
* | - BlockAck descriptor |
||||
* | total: AR9170_TERMINATOR_NUMBER |
||||
* +-- |
||||
* | block descriptors (dma_desc) |
||||
* | (AR9170_BLOCK_NUMBER) |
||||
* AR9170_BLOCK_BUFFER_BASE +-- align to multiple of 64 |
||||
* | block buffers (AR9170_BLOCK_SIZE each) |
||||
* | (AR9170_BLOCK_NUMBER) |
||||
* approx. 0x117c00 +-- |
||||
* | BA buffer (128 bytes) |
||||
* +-- |
||||
* | CMD buffer (128 bytes) |
||||
* | - used as NULLFRAME buffer (128 bytes) for WOL |
||||
* +-- |
||||
* | RSP buffer (320 bytes) |
||||
* +-- |
||||
* | BEACON buffer (256 bytes) |
||||
* +-- |
||||
* | unaccounted space / padding |
||||
* +-- |
||||
* 0x18000 |
||||
*/ |
||||
|
||||
#define CARL9170_SRAM_RESERVED (sizeof(struct carl9170_sram_reserved)) |
||||
|
||||
#define AR9170_FRAME_MEMORY_SIZE (AR9170_SRAM_SIZE - CARL9170_SRAM_RESERVED) |
||||
|
||||
#define BLOCK_ALIGNMENT 64 |
||||
|
||||
#define NONBLOCK_DESCRIPTORS_SIZE \ |
||||
(AR9170_DESCRIPTOR_SIZE * (AR9170_TERMINATOR_NUMBER)) |
||||
|
||||
#define NONBLOCK_DESCRIPTORS_SIZE_ALIGNED \ |
||||
(ALIGN(NONBLOCK_DESCRIPTORS_SIZE, BLOCK_ALIGNMENT)) |
||||
|
||||
#define AR9170_BLOCK_NUMBER ((AR9170_FRAME_MEMORY_SIZE - NONBLOCK_DESCRIPTORS_SIZE_ALIGNED) / \ |
||||
(AR9170_BLOCK_SIZE + AR9170_DESCRIPTOR_SIZE)) |
||||
|
||||
struct ar9170_data_block { |
||||
uint8_t data[AR9170_BLOCK_SIZE]; |
||||
}; |
||||
|
||||
struct ar9170_dma_memory { |
||||
struct dma_desc terminator[AR9170_TERMINATOR_NUMBER]; |
||||
struct dma_desc block[AR9170_BLOCK_NUMBER]; |
||||
struct ar9170_data_block data[AR9170_BLOCK_NUMBER] __aligned(BLOCK_ALIGNMENT); |
||||
struct carl9170_sram_reserved reserved __aligned(BLOCK_ALIGNMENT); |
||||
}; |
||||
|
||||
extern struct ar9170_dma_memory dma_mem; |
||||
|
||||
#define AR9170_DOWN_BLOCK_RATIO 2 |
||||
#define AR9170_RX_BLOCK_RATIO 1 |
||||
/* Tx 16*2 = 32 packets => 32*(5*320) */ |
||||
#define AR9170_TX_BLOCK_NUMBER (AR9170_BLOCK_NUMBER * AR9170_DOWN_BLOCK_RATIO / \ |
||||
(AR9170_RX_BLOCK_RATIO + AR9170_DOWN_BLOCK_RATIO)) |
||||
#define AR9170_RX_BLOCK_NUMBER (AR9170_BLOCK_NUMBER - AR9170_TX_BLOCK_NUMBER) |
||||
|
||||
/* Error code */ |
||||
#define AR9170_ERR_FS_BIT 1 |
||||
#define AR9170_ERR_LS_BIT 2 |
||||
#define AR9170_ERR_OWN_BITS 3 |
||||
#define AR9170_ERR_DATA_SIZE 4 |
||||
#define AR9170_ERR_TOTAL_LEN 5 |
||||
#define AR9170_ERR_DATA 6 |
||||
#define AR9170_ERR_SEQ 7 |
||||
#define AR9170_ERR_LEN 8 |
||||
|
||||
/* Status bits definitions */ |
||||
/* Own bits definitions */ |
||||
#define AR9170_OWN_BITS 0x3 |
||||
#define AR9170_OWN_BITS_S 0 |
||||
#define AR9170_OWN_BITS_SW 0x0 |
||||
#define AR9170_OWN_BITS_HW 0x1 |
||||
#define AR9170_OWN_BITS_SE 0x2 |
||||
|
||||
/* Control bits definitions */ |
||||
#define AR9170_CTRL_TXFAIL 1 |
||||
#define AR9170_CTRL_BAFAIL 2 |
||||
#define AR9170_CTRL_FAIL (AR9170_CTRL_TXFAIL | AR9170_CTRL_BAFAIL) |
||||
|
||||
/* First segament bit */ |
||||
#define AR9170_CTRL_LS_BIT 0x100 |
||||
/* Last segament bit */ |
||||
#define AR9170_CTRL_FS_BIT 0x200 |
||||
|
||||
struct dma_queue { |
||||
struct dma_desc *head; |
||||
struct dma_desc *terminator; |
||||
}; |
||||
|
||||
#define DESC_PAYLOAD(a) ((void *)a->dataAddr) |
||||
#define DESC_PAYLOAD_OFF(a, offset) ((void *)((unsigned long)(a->_dataAddr) + offset)) |
||||
|
||||
struct dma_desc *dma_unlink_head(struct dma_queue *queue); |
||||
void dma_init_descriptors(void); |
||||
void dma_reclaim(struct dma_queue *q, struct dma_desc *desc); |
||||
void dma_put(struct dma_queue *q, struct dma_desc *desc); |
||||
|
||||
static inline __inline bool is_terminator(struct dma_queue *q, struct dma_desc *desc) |
||||
{ |
||||
return q->terminator == desc; |
||||
} |
||||
|
||||
static inline __inline bool queue_empty(struct dma_queue *q) |
||||
{ |
||||
return q->head == q->terminator; |
||||
} |
||||
|
||||
/* |
||||
* Get a completed packet with # descriptors. Return the first |
||||
* descriptor and pointer the head directly by lastAddr->nextAddr |
||||
*/ |
||||
static inline __inline struct dma_desc *dma_dequeue_bits(struct dma_queue *q, |
||||
uint16_t bits) |
||||
{ |
||||
struct dma_desc *desc = NULL; |
||||
|
||||
if ((q->head->status & AR9170_OWN_BITS) == bits) |
||||
desc = dma_unlink_head(q); |
||||
|
||||
return desc; |
||||
} |
||||
|
||||
static inline __inline struct dma_desc *dma_dequeue_not_bits(struct dma_queue *q, |
||||
uint16_t bits) |
||||
{ |
||||
struct dma_desc *desc = NULL; |
||||
|
||||
/* AR9170_OWN_BITS_HW will be filtered out here too. */ |
||||
if ((q->head->status & AR9170_OWN_BITS) != bits) |
||||
desc = dma_unlink_head(q); |
||||
|
||||
return desc; |
||||
} |
||||
|
||||
#define for_each_desc_bits(desc, queue, bits) \ |
||||
while ((desc = dma_dequeue_bits(queue, bits))) |
||||
|
||||
#define for_each_desc_not_bits(desc, queue, bits) \ |
||||
while ((desc = dma_dequeue_not_bits(queue, bits))) |
||||
|
||||
#define for_each_desc(desc, queue) \ |
||||
while ((desc = dma_unlink_head(queue))) |
||||
|
||||
#define __for_each_desc_bits(desc, queue, bits) \ |
||||
for (desc = (queue)->head; \ |
||||
(desc != (queue)->terminator && \ |
||||
(desc->status & AR9170_OWN_BITS) == bits); \ |
||||
desc = desc->lastAddr->nextAddr) |
||||
|
||||
#define __while_desc_bits(desc, queue, bits) \ |
||||
for (desc = (queue)->head; \ |
||||
(!queue_empty(queue) && \ |
||||
(desc->status & AR9170_OWN_BITS) == bits); \ |
||||
desc = (queue)->head) |
||||
|
||||
#define __for_each_desc_continue(desc, queue) \ |
||||
for (; desc != (queue)->terminator; \ |
||||
desc = (desc)->lastAddr->nextAddr) |
||||
|
||||
#define __for_each_desc(desc, queue) \ |
||||
for (desc = (queue)->head; \ |
||||
desc != (queue)->terminator; \ |
||||
desc = (desc)->lastAddr->nextAddr) |
||||
|
||||
#define __for_each_desc_safe(desc, tmp, queue) \ |
||||
for (desc = (queue)->head, tmp = desc->lastAddr->nextAddr; \ |
||||
desc != (queue)->terminator; \ |
||||
desc = tmp, tmp = tmp->lastAddr->nextAddr) |
||||
|
||||
#define __while_subdesc(desc, queue) \ |
||||
for (desc = (queue)->head; \ |
||||
desc != (queue)->terminator; \ |
||||
desc = (desc)->nextAddr) |
||||
|
||||
static inline __inline unsigned int queue_len(struct dma_queue *q) |
||||
{ |
||||
struct dma_desc *desc; |
||||
unsigned int i = 0; |
||||
|
||||
__while_subdesc(desc, q) |
||||
i++; |
||||
|
||||
return i; |
||||
} |
||||
|
||||
/* |
||||
* rearm a completed packet, so it will be processed agian. |
||||
*/ |
||||
static inline __inline void dma_rearm(struct dma_desc *desc) |
||||
{ |
||||
/* Set OWN bit to HW */ |
||||
desc->status = ((desc->status & (~AR9170_OWN_BITS)) | |
||||
AR9170_OWN_BITS_HW); |
||||
} |
||||
|
||||
static inline __inline void dma_fix_downqueue(struct dma_desc *desc) |
||||
{ |
||||
desc->status = AR9170_OWN_BITS_HW; |
||||
desc->ctrl = 0; |
||||
desc->dataSize = 0; |
||||
desc->totalLen = AR9170_BLOCK_SIZE; |
||||
desc->lastAddr = desc; |
||||
} |
||||
|
||||
static inline void __check_desc(void) |
||||
{ |
||||
struct ar9170_dma_memory mem; |
||||
BUILD_BUG_ON(sizeof(struct ar9170_data_block) != AR9170_BLOCK_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct dma_desc) != 20); |
||||
|
||||
BUILD_BUG_ON(sizeof(mem) > AR9170_SRAM_SIZE); |
||||
|
||||
BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, ba.buf) & (BLOCK_ALIGNMENT - 1)); |
||||
BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, cmd.buf) & (BLOCK_ALIGNMENT - 1)); |
||||
BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, rsp.buf) & (BLOCK_ALIGNMENT - 1)); |
||||
BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, bcn.buf) & (BLOCK_ALIGNMENT - 1)); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_tx_null_superframe) > CARL9170_MAX_CMD_LEN); |
||||
} |
||||
|
||||
#endif /* __CARL9170FW_DMA_H */ |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Firmware definition |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_FWDSC_H |
||||
#define __CARL9170FW_FWDSC_H |
||||
|
||||
#include "config.h" |
||||
#include "compiler.h" |
||||
#include "types.h" |
||||
#include "fwdesc.h" |
||||
|
||||
struct carl9170_firmware_descriptor { |
||||
struct carl9170fw_otus_desc otus; |
||||
struct carl9170fw_txsq_desc txsq; |
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
struct carl9170fw_wol_desc wol; |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
struct carl9170fw_motd_desc motd; |
||||
struct carl9170fw_dbg_desc dbg; |
||||
struct carl9170fw_last_desc last; |
||||
} __packed; |
||||
|
||||
extern const struct carl9170_firmware_descriptor carl9170fw_desc; |
||||
|
||||
static inline void __check_fw(void) |
||||
{ |
||||
BUILD_BUG_ON(sizeof(carl9170fw_desc) & 0x3); |
||||
BUILD_BUG_ON(sizeof(carl9170fw_desc) > CARL9170FW_DESC_MAX_LENGTH); |
||||
} |
||||
|
||||
#endif /* __CARL9170FW_FWDSC_H */ |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* GPIO definitions |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_GPIO_H |
||||
#define __CARL9170FW_GPIO_H |
||||
|
||||
#include "config.h" |
||||
#include "hw.h" |
||||
#include "io.h" |
||||
|
||||
static inline __inline void led_init(void) |
||||
{ |
||||
set(AR9170_GPIO_REG_PORT_TYPE, 3); |
||||
} |
||||
|
||||
static inline __inline void led_set(const unsigned int ledstate) |
||||
{ |
||||
set(AR9170_GPIO_REG_PORT_DATA, ledstate); |
||||
} |
||||
|
||||
#ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT |
||||
|
||||
void gpio_timer(void); |
||||
|
||||
#endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ |
||||
#endif /* __CARL9170FW_GPIO_H */ |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* HostIF definition |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_HOSTIF_H |
||||
#define __CARL9170FW_HOSTIF_H |
||||
|
||||
#include "config.h" |
||||
#include "compiler.h" |
||||
#include "types.h" |
||||
#include "hw.h" |
||||
#include "io.h" |
||||
|
||||
static inline __inline void down_trigger(void) |
||||
{ |
||||
set(AR9170_PTA_REG_DN_DMA_TRIGGER, 1); |
||||
} |
||||
|
||||
static inline __inline void up_trigger(void) |
||||
{ |
||||
set(AR9170_PTA_REG_UP_DMA_TRIGGER, 1); |
||||
} |
||||
|
||||
void handle_host_interface(void); |
||||
|
||||
#endif /* __CARL9170FW_HOSTIF_H */ |
@ -0,0 +1,153 @@
@@ -0,0 +1,153 @@
|
||||
/* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_IO_H |
||||
#define __CARL9170FW_IO_H |
||||
|
||||
#include "config.h" |
||||
#include "types.h" |
||||
#include "compiler.h" |
||||
|
||||
static inline __inline uint8_t readb(const volatile void *addr) |
||||
{ |
||||
return *(const volatile uint8_t *) addr; |
||||
} |
||||
|
||||
static inline __inline uint16_t readw(const volatile void *addr) |
||||
{ |
||||
return *(const volatile uint16_t *) addr; |
||||
} |
||||
|
||||
static inline __inline volatile void *readp(const volatile void *addr) |
||||
{ |
||||
return *(volatile void **) addr; |
||||
} |
||||
|
||||
static inline __inline uint32_t readl(const volatile void *addr) |
||||
{ |
||||
return *(const volatile unsigned int *) addr; |
||||
} |
||||
|
||||
static inline __inline void writeb(volatile void *addr, const volatile uint8_t val) |
||||
{ |
||||
*(volatile uint8_t *) addr = val; |
||||
} |
||||
|
||||
static inline __inline void writew(volatile void *addr, const volatile uint16_t val) |
||||
{ |
||||
*(volatile uint16_t *) addr = val; |
||||
} |
||||
|
||||
static inline __inline void writel(volatile void *addr, const volatile uint32_t val) |
||||
{ |
||||
*(volatile uint32_t *) addr = val; |
||||
} |
||||
|
||||
static inline __inline void __orl(volatile void *addr, const volatile uint32_t val) |
||||
{ |
||||
*(volatile uint32_t *) addr |= val; |
||||
} |
||||
|
||||
static inline __inline void __andl(volatile void *addr, const volatile uint32_t val) |
||||
{ |
||||
*(volatile uint32_t *) addr &= val; |
||||
} |
||||
|
||||
static inline __inline void __xorl(volatile void *addr, const volatile uint32_t val) |
||||
{ |
||||
*(volatile uint32_t *) addr ^= val; |
||||
} |
||||
|
||||
static inline __inline void __incl(volatile void *addr) |
||||
{ |
||||
(*(volatile uint32_t *)addr)++; |
||||
} |
||||
|
||||
static inline __inline uint32_t readl_async(const volatile void *addr) |
||||
{ |
||||
uint32_t i = 0, read, tmp; |
||||
|
||||
read = readl(addr); |
||||
do { |
||||
tmp = read; |
||||
tmp = readl(addr); |
||||
i++; |
||||
} while (tmp != read && i <= 10); |
||||
|
||||
return read; |
||||
} |
||||
|
||||
static inline __inline void set(const volatile uint32_t addr, const volatile uint32_t val) |
||||
{ |
||||
writel((volatile void *) addr, val); |
||||
} |
||||
|
||||
static inline __inline void orl(volatile uint32_t addr, const volatile uint32_t val) |
||||
{ |
||||
__orl((volatile void *) addr, val); |
||||
} |
||||
|
||||
static inline __inline void xorl(const volatile uint32_t addr, const volatile uint32_t val) |
||||
{ |
||||
__xorl((volatile void *) addr, val); |
||||
} |
||||
|
||||
static inline __inline void andl(const volatile uint32_t addr, const volatile uint32_t val) |
||||
{ |
||||
__andl((volatile void *) addr, val); |
||||
} |
||||
|
||||
static inline __inline void incl(const volatile uint32_t addr) |
||||
{ |
||||
__incl((volatile void *) addr); |
||||
} |
||||
|
||||
static inline __inline uint32_t get(const volatile uint32_t addr) |
||||
{ |
||||
return readl((volatile void *) addr); |
||||
} |
||||
|
||||
static inline __inline volatile void *getp(const volatile uint32_t addr) |
||||
{ |
||||
return readp((const volatile void *) addr); |
||||
} |
||||
|
||||
static inline __inline uint32_t get_async(const volatile uint32_t addr) |
||||
{ |
||||
return readl_async((const volatile void *) addr); |
||||
} |
||||
|
||||
static inline __inline void setb(const volatile uint32_t addr, const volatile uint8_t val) |
||||
{ |
||||
writeb((volatile void *) addr, val); |
||||
} |
||||
|
||||
static inline __inline uint8_t getb(const volatile uint32_t addr) |
||||
{ |
||||
return readb((const volatile void *) addr); |
||||
} |
||||
|
||||
static inline __inline void andb(const volatile uint32_t addr, const volatile uint8_t val) |
||||
{ |
||||
setb(addr, getb(addr) & val); |
||||
} |
||||
|
||||
static inline __inline void orb(const volatile uint32_t addr, const volatile uint32_t val) |
||||
{ |
||||
setb(addr, getb(addr) | val); |
||||
} |
||||
|
||||
#endif /* __CARL9170FW_IO_H */ |
@ -0,0 +1,107 @@
@@ -0,0 +1,107 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* printf and his friends... |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_PRINTF_H |
||||
#define __CARL9170FW_PRINTF_H |
||||
|
||||
#include <stdarg.h> |
||||
#include <string.h> |
||||
#include "config.h" |
||||
#include "carl9170.h" |
||||
#include "uart.h" |
||||
#include "fwcmd.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_PRINTF |
||||
void __attribute__((format (printf, 1, 2))) tfp_printf(const char *fmt, ...); |
||||
|
||||
#define printf tfp_printf |
||||
|
||||
#else |
||||
void __attribute__((format (printf, 1, 2))) min_printf(const char *fmt, ...); |
||||
|
||||
#define printf min_printf |
||||
#endif /* CONFIG_CARL9170FW_PRINTF */ |
||||
|
||||
#define PRINT(fmt, args...) \ |
||||
do { \ |
||||
printf(fmt, ## args); \ |
||||
} while (0) |
||||
|
||||
#define INFO(fmt, args...) PRINT(fmt, ## args) |
||||
|
||||
#define ERR(fmt, args...) PRINT(CARL9170_ERR_MAGIC fmt, ## args) |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG |
||||
#define DBG(fmt, args...) PRINT(fmt, ## args) |
||||
#else |
||||
#define DBG(...) do { } while (0); |
||||
#endif |
||||
|
||||
/* |
||||
* NB: even though the MACRO is called "stall". It isn't supposed |
||||
* to stall since this will render the device unresponsive, until |
||||
* someone pulls the plug. |
||||
*/ |
||||
#define STALL() |
||||
|
||||
#define BUG(fmt, args...) \ |
||||
do { \ |
||||
PRINT(CARL9170_BUG_MAGIC" %s()@%d \"" fmt "\"" , \ |
||||
__func__, __LINE__, ## args); \ |
||||
STALL() \ |
||||
} while (0); |
||||
|
||||
#define BUG_ON(condition) \ |
||||
({ \ |
||||
int __ret = !!(condition); \ |
||||
if (unlikely(!!(__ret))) \ |
||||
BUG(#condition); \ |
||||
(__ret); \ |
||||
}) |
||||
|
||||
static inline __inline void putcharacter(const char c __unused) |
||||
{ |
||||
#ifdef CONFIG_CARL9170FW_DEBUG_USB |
||||
usb_putc(c); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_USB */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_UART |
||||
uart_putc(c); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_UART */ |
||||
} |
||||
|
||||
static inline __inline void print_hex_dump(const void *buf __unused, int len __unused) |
||||
{ |
||||
#ifdef CONFIG_CARL9170FW_DEBUG_USB |
||||
usb_print_hex_dump(buf, len); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_USB */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_UART |
||||
uart_print_hex_dump(buf, len); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_UART */ |
||||
} |
||||
|
||||
#endif /* __CARL9170FW_PRINTF_H */ |
||||
|
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* RF routine definitions |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_RF_H |
||||
#define __CARL9170FW_RF_H |
||||
|
||||
#include "config.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS |
||||
void rf_notify_set_channel(void); |
||||
void rf_cmd(const struct carl9170_cmd *cmd, struct carl9170_rsp *resp); |
||||
void rf_psm(void); |
||||
#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ |
||||
|
||||
#endif /* __CARL9170FW_RF_H */ |
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* ROM layout |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_ROM_H |
||||
#define __CARL9170FW_ROM_H |
||||
|
||||
#include "types.h" |
||||
#include "config.h" |
||||
#include "compiler.h" |
||||
#include "usb.h" |
||||
#include "eeprom.h" |
||||
|
||||
struct ar9170_hwtype { |
||||
/* 0x00001370 */ |
||||
uint8_t data[4]; |
||||
|
||||
/* 0x00001374 */ |
||||
struct ar9170_led_mode led_mode[AR9170_NUM_LEDS]; |
||||
|
||||
/* 0x00001378 */ |
||||
uint8_t nulldata[2]; |
||||
|
||||
struct { |
||||
/* 0x0000137a */ |
||||
struct usb_device_descriptor device_desc; |
||||
|
||||
/* 0x0000138c */ |
||||
uint8_t string0_desc[4]; |
||||
|
||||
/* 0x00001390 */ |
||||
uint8_t string1_desc[32]; |
||||
|
||||
/* 0x000013b0 */ |
||||
uint8_t string2_desc[48]; |
||||
|
||||
/* 0x000013e0 */ |
||||
uint8_t string3_desc[32]; |
||||
} usb; |
||||
} __packed; |
||||
|
||||
struct ar9170_rom { |
||||
/* 0x00000000 */ |
||||
uint32_t *irq_table[2]; |
||||
|
||||
/* 0x00000008 */ |
||||
uint8_t bootcode[4968]; |
||||
|
||||
/* 0x00001370 */ |
||||
struct ar9170_hwtype hw; |
||||
|
||||
/* 0x00001400 */ |
||||
uint8_t data[512]; |
||||
|
||||
/* eeprom */ |
||||
struct ar9170_eeprom sys; |
||||
} __packed; |
||||
|
||||
static const struct ar9170_rom rom __section(eeprom); |
||||
|
||||
#endif /* __CARL9170FW_ROM_H */ |
@ -0,0 +1,88 @@
@@ -0,0 +1,88 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Clock, Timer & Timing |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_TIMER_H |
||||
#define __CARL9170FW_TIMER_H |
||||
|
||||
#include "config.h" |
||||
|
||||
enum cpu_clock_t { |
||||
AHB_40MHZ_OSC = 0, |
||||
AHB_20_22MHZ = 1, |
||||
AHB_40_44MHZ = 2, |
||||
AHB_80_88MHZ = 3 |
||||
}; |
||||
|
||||
static inline __inline uint32_t get_clock_counter(void) |
||||
{ |
||||
return (get(AR9170_TIMER_REG_CLOCK_HIGH) << 16) | get(AR9170_TIMER_REG_CLOCK_LOW); |
||||
} |
||||
|
||||
/* |
||||
* works only up to 97 secs [44 MHz] or 107 secs for 40 MHz |
||||
* Also, the delay wait will be affected by 2.4GHz<->5GHz |
||||
* band changes. |
||||
*/ |
||||
static inline __inline bool is_after_msecs(const uint32_t t0, const uint32_t msecs) |
||||
{ |
||||
return ((get_clock_counter() - t0) / 1000) > (msecs * fw.ticks_per_usec); |
||||
} |
||||
|
||||
/* |
||||
* Note: Be careful with [u]delay. They won't service the |
||||
* hardware watchdog timer. It might trigger if you |
||||
* wait long enough. Also they don't terminate if sec is |
||||
* above 97 sec [44MHz] or more than 107 sec [40MHz]. |
||||
*/ |
||||
static inline __inline void delay(const uint32_t msec) |
||||
{ |
||||
uint32_t t1, t2, dt, wt; |
||||
|
||||
wt = msec * fw.ticks_per_usec; |
||||
|
||||
t1 = get_clock_counter(); |
||||
while (1) { |
||||
t2 = get_clock_counter(); |
||||
dt = (t2 - t1) / 1000; |
||||
if (dt >= wt) |
||||
break; |
||||
} |
||||
} |
||||
|
||||
static inline __inline void udelay(const uint32_t usec) |
||||
{ |
||||
uint32_t t1, t2, dt; |
||||
|
||||
t1 = get_clock_counter(); |
||||
while (1) { |
||||
t2 = get_clock_counter(); |
||||
dt = (t2 - t1); |
||||
if (dt >= (usec * fw.ticks_per_usec)) |
||||
break; |
||||
} |
||||
} |
||||
|
||||
void clock_set(enum cpu_clock_t _clock, bool on); |
||||
#endif /* __CARL9170FW_TIMER_H */ |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* UART functions definition |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_UART_H |
||||
#define __CARL9170FW_UART_H |
||||
|
||||
#include "config.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_UART |
||||
void uart_putc(const char c); |
||||
void uart_print_hex_dump(const void *buf, const int len); |
||||
void uart_init(void); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_UART */ |
||||
|
||||
#endif /* __CARL9170FW_UART_H */ |
@ -0,0 +1,191 @@
@@ -0,0 +1,191 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* USB definitions |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_USB_H |
||||
#define __CARL9170FW_USB_H |
||||
|
||||
#include "config.h" |
||||
#include "types.h" |
||||
#include "io.h" |
||||
#include "hw.h" |
||||
#include "ch9.h" |
||||
|
||||
struct ar9170_usb_config { |
||||
struct usb_config_descriptor cfg; |
||||
struct usb_interface_descriptor intf; |
||||
struct usb_endpoint_descriptor ep[AR9170_USB_NUM_EXTRA_EP]; |
||||
} __packed; |
||||
|
||||
static inline __inline bool usb_detect_highspeed(void) |
||||
{ |
||||
return !!(getb(AR9170_USB_REG_MAIN_CTRL) & |
||||
AR9170_USB_MAIN_CTRL_HIGHSPEED); |
||||
} |
||||
|
||||
static inline __inline bool usb_configured(void) |
||||
{ |
||||
return !!(getb(AR9170_USB_REG_DEVICE_ADDRESS) & |
||||
AR9170_USB_DEVICE_ADDRESS_CONFIGURE); |
||||
} |
||||
|
||||
static inline __inline void usb_enable_remote_wakeup(void) |
||||
{ |
||||
orb(AR9170_USB_REG_MAIN_CTRL, AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP); |
||||
} |
||||
|
||||
static inline __inline void usb_disable_remote_wakeup(void) |
||||
{ |
||||
andb(AR9170_USB_REG_MAIN_CTRL, ~AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP); |
||||
} |
||||
|
||||
static inline __inline void usb_enable_global_int(void) |
||||
{ |
||||
orb(AR9170_USB_REG_MAIN_CTRL, AR9170_USB_MAIN_CTRL_ENABLE_GLOBAL_INT); |
||||
} |
||||
|
||||
static inline __inline void usb_trigger_out(void) |
||||
{ |
||||
andb(AR9170_USB_REG_INTR_MASK_BYTE_4, |
||||
(uint8_t) ~AR9170_USB_INTR_DISABLE_OUT_INT); |
||||
} |
||||
|
||||
static inline __inline void usb_reset_out(void) |
||||
{ |
||||
orb(AR9170_USB_REG_INTR_MASK_BYTE_4, AR9170_USB_INTR_DISABLE_OUT_INT); |
||||
} |
||||
|
||||
static inline __inline void usb_trigger_in(void) |
||||
{ |
||||
andb(AR9170_USB_REG_INTR_MASK_BYTE_6, ~AR9170_USB_INTR_DISABLE_IN_INT); |
||||
} |
||||
|
||||
static inline __inline void usb_reset_in(void) |
||||
{ |
||||
orb(AR9170_USB_REG_INTR_MASK_BYTE_6, AR9170_USB_INTR_DISABLE_IN_INT); |
||||
} |
||||
|
||||
static inline __inline void usb_ep3_xfer_done(void) |
||||
{ |
||||
orb(AR9170_USB_REG_EP3_BYTE_COUNT_HIGH, 0x08); |
||||
} |
||||
|
||||
static inline __inline void usb_suspend_ack(void) |
||||
{ |
||||
/* |
||||
* uP must do-over everything it should handle |
||||
* and do before into the suspend mode |
||||
*/ |
||||
andb(AR9170_USB_REG_INTR_SOURCE_7, ~BIT(2)); |
||||
} |
||||
|
||||
static inline __inline void usb_resume_ack(void) |
||||
{ |
||||
/* |
||||
* uP must do-over everything it should handle |
||||
* and do before into the suspend mode |
||||
*/ |
||||
|
||||
andb(AR9170_USB_REG_INTR_SOURCE_7, ~BIT(3)); |
||||
} |
||||
|
||||
static inline __inline void usb_reset_ack(void) |
||||
{ |
||||
andb(AR9170_USB_REG_INTR_SOURCE_7, ~BIT(1)); |
||||
} |
||||
|
||||
static inline __inline void usb_data_out0Byte(void) |
||||
{ |
||||
andb(AR9170_USB_REG_INTR_SOURCE_7, (uint8_t) ~BIT(7)); |
||||
} |
||||
|
||||
static inline __inline void usb_data_in0Byte(void) |
||||
{ |
||||
andb(AR9170_USB_REG_INTR_SOURCE_7, ~BIT(6)); |
||||
} |
||||
|
||||
static inline __inline void usb_stop_down_queue(void) |
||||
{ |
||||
andl(AR9170_USB_REG_DMA_CTL, ~AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE); |
||||
} |
||||
|
||||
static inline __inline void usb_start_down_queue(void) |
||||
{ |
||||
orl(AR9170_USB_REG_DMA_CTL, AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE); |
||||
} |
||||
|
||||
static inline __inline void usb_clear_input_ep_toggle(unsigned int ep) |
||||
{ |
||||
andl(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (ep << 1), |
||||
~AR9170_USB_EP_IN_TOGGLE); |
||||
} |
||||
|
||||
static inline __inline void usb_set_input_ep_toggle(unsigned int ep) |
||||
{ |
||||
orl(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (ep << 1), |
||||
AR9170_USB_EP_IN_TOGGLE); |
||||
} |
||||
|
||||
static inline __inline void usb_clear_output_ep_toggle(unsigned int ep) |
||||
{ |
||||
andl(AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH + (ep << 1), |
||||
~AR9170_USB_EP_OUT_TOGGLE); |
||||
} |
||||
|
||||
static inline __inline void usb_set_output_ep_toggle(unsigned int ep) |
||||
{ |
||||
orl(AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH + (ep << 1), |
||||
AR9170_USB_EP_OUT_TOGGLE); |
||||
} |
||||
|
||||
static inline void usb_structure_check(void) |
||||
{ |
||||
BUILD_BUG_ON(sizeof(struct usb_config_descriptor) != USB_DT_CONFIG_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct usb_device_descriptor) != USB_DT_DEVICE_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct usb_endpoint_descriptor) != USB_DT_ENDPOINT_SIZE); |
||||
BUILD_BUG_ON(sizeof(struct usb_interface_descriptor) != USB_DT_INTERFACE_SIZE); |
||||
} |
||||
|
||||
void __noreturn jump_to_bootcode(void); |
||||
|
||||
void send_cmd_to_host(const uint8_t len, const uint8_t type, |
||||
const uint8_t ext, const uint8_t *body); |
||||
|
||||
void usb_init(void); |
||||
void usb_ep0rx(void); |
||||
void usb_ep0tx(void); |
||||
void usb_ep0setup(void); |
||||
void handle_usb(void); |
||||
|
||||
void usb_timer(void); |
||||
void usb_putc(const char c); |
||||
void usb_print_hex_dump(const void *buf, int len); |
||||
|
||||
void usb_init_highspeed_fifo_cfg(void); |
||||
void usb_init_fullspeed_fifo_cfg(void); |
||||
|
||||
void __noreturn start(void); |
||||
void __noreturn reboot(void); |
||||
|
||||
#endif /* __CARL9170FW_USB_H */ |
@ -0,0 +1,244 @@
@@ -0,0 +1,244 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* USB definitions |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_USB_FIFO_H |
||||
#define __CARL9170FW_USB_FIFO_H |
||||
|
||||
#include "config.h" |
||||
|
||||
#define MASK_F0 0xf0 |
||||
|
||||
/* Block Size define */ |
||||
#define BLK512BYTE 1 |
||||
#define BLK1024BYTE 2 |
||||
|
||||
#define BLK64BYTE 1 |
||||
#define BLK128BYTE 2 |
||||
|
||||
/* Block toggle number define */ |
||||
#define SINGLE_BLK 1 |
||||
#define DOUBLE_BLK 2 |
||||
#define TRIBLE_BLK 3 |
||||
|
||||
/* Endpoint transfer type */ |
||||
#define TF_TYPE_ISOCHRONOUS 1 |
||||
#define TF_TYPE_BULK 2 |
||||
#define TF_TYPE_INTERRUPT 3 |
||||
|
||||
/* Endpoint or FIFO direction define */ |
||||
#define DIRECTION_IN 0 |
||||
#define DIRECTION_OUT 1 |
||||
|
||||
#define HS_C1_I0_A0_EP1_MAX_PACKET 512 |
||||
#define HS_C1_I0_A0_EP1_bInterval 0 |
||||
|
||||
#define HS_C1_I0_A0_EP_NUMBER 0x04 |
||||
#define HS_C1_I0_A0_EP_LENGTH (EP_LENGTH * HS_C1_I0_A0_EP_NUMBER) |
||||
#define HS_C1_I0_ALT_LENGTH (HS_C1_I0_A0_EP_LENGTH) |
||||
#define HS_C1_INTERFACE_LENGTH (HS_C1_I0_ALT_LENGTH) |
||||
|
||||
#define HS_C1_CONFIG_TOTAL_LENGTH (CONFIG_LENGTH + INTERFACE_LENGTH + HS_C1_INTERFACE_LENGTH) |
||||
#define FS_C1_CONFIG_TOTAL_LENGTH (CONFIG_LENGTH + INTERFACE_LENGTH + FS_C1_INTERFACE_LENGTH) |
||||
|
||||
#define FS_C1_I0_A0_EP1_MAX_PACKET 64 |
||||
/* #define FS_C1_I0_A0_EP1_bInterval HS_C1_I0_A0_EP1_bInterval */ |
||||
|
||||
#define HS_CONFIGURATION_NUMBER 1 |
||||
#define FS_CONFIGURATION_NUMBER 1 |
||||
|
||||
#define fDOUBLE_BUF 1 |
||||
#define fDOUBLE_BUF_IN 0 |
||||
|
||||
#define fFLASH_DISK 0 |
||||
#define fENABLE_ISO 0 |
||||
|
||||
#define HS_C1_INTERFACE_NUMBER 0x01 |
||||
#define HS_C1 0x01 |
||||
#define HS_C1_iConfiguration 0x00 |
||||
#define HS_C1_bmAttribute 0x80 |
||||
|
||||
#define HS_C1_iMaxPower 0xFA |
||||
|
||||
/* Interface 0 */ |
||||
#define HS_C1_I0_ALT_NUMBER 0X01 |
||||
/* AlternateSetting 0 */ |
||||
#define HS_C1_I0_A0_bInterfaceNumber 0x00 |
||||
#define HS_C1_I0_A0_bAlternateSetting 0x00 |
||||
/* JWEI 2003/07/14 */ |
||||
#define HS_C1_I0_A0_EP_NUMBER 0x04 |
||||
#define HS_C1_I0_A0_bInterfaceClass 0xff |
||||
#define HS_C1_I0_A0_bInterfaceSubClass 0x00 |
||||
#define HS_C1_I0_A0_bInterfaceProtocol 0x00 |
||||
#define HS_C1_I0_A0_iInterface 0x00 |
||||
|
||||
/* EP 1 */ |
||||
#define HS_C1_I0_A0_EP1_BLKSIZE 512 |
||||
#define HS_C1_I0_A0_EP1_BLKNO DOUBLE_BLK |
||||
#define HS_C1_I0_A0_EP1_DIRECTION DIRECTION_OUT |
||||
#define HS_C1_I0_A0_EP1_TYPE TF_TYPE_BULK |
||||
|
||||
#define HS_C1_I0_A0_EP1_MAX_PACKET 512 |
||||
#define HS_C1_I0_A0_EP1_bInterval 0 |
||||
|
||||
/* EP 2 */ |
||||
#define HS_C1_I0_A0_EP2_BLKSIZE 512 |
||||
/* JWEI 2003/08/20 */ |
||||
#define HS_C1_I0_A0_EP2_BLKNO SINGLE_BLK |
||||
#define HS_C1_I0_A0_EP2_DIRECTION DIRECTION_IN |
||||
#define HS_C1_I0_A0_EP2_TYPE TF_TYPE_BULK |
||||
#define HS_C1_I0_A0_EP2_MAX_PACKET 512 |
||||
#define HS_C1_I0_A0_EP2_bInterval 0 |
||||
|
||||
/* EP 3 */ |
||||
#define HS_C1_I0_A0_EP3_BLKSIZE 64 |
||||
#define HS_C1_I0_A0_EP3_BLKNO SINGLE_BLK |
||||
#define HS_C1_I0_A0_EP3_DIRECTION DIRECTION_IN |
||||
#define HS_C1_I0_A0_EP3_TYPE TF_TYPE_INTERRUPT |
||||
#define HS_C1_I0_A0_EP3_MAX_PACKET 0x0040 |
||||
#define HS_C1_I0_A0_EP3_bInterval 01 |
||||
|
||||
/* |
||||
* Note: HS Bulk type require max pkt size = 512 |
||||
* ==> must use Interrupt type for max pkt size = 64 |
||||
*/ |
||||
|
||||
/* EP 4 */ |
||||
#define HS_C1_I0_A0_EP4_BLKSIZE 64 |
||||
#define HS_C1_I0_A0_EP4_BLKNO SINGLE_BLK |
||||
#define HS_C1_I0_A0_EP4_DIRECTION DIRECTION_OUT |
||||
#define HS_C1_I0_A0_EP4_TYPE TF_TYPE_INTERRUPT |
||||
#define HS_C1_I0_A0_EP4_MAX_PACKET 0x0040 |
||||
#define HS_C1_I0_A0_EP4_bInterval 01 |
||||
|
||||
#define HS_C1_I0_A0_EP_LENGTH (EP_LENGTH * HS_C1_I0_A0_EP_NUMBER) |
||||
/* EP 1 */ |
||||
#define HS_C1_I0_A0_EP1_FIFO_START 0 |
||||
#define HS_C1_I0_A0_EP1_FIFO_NO (HS_C1_I0_A0_EP1_BLKNO * HS_C1_I0_A0_EP1_BLKSIZE) |
||||
#define HS_C1_I0_A0_EP1_FIFO_CONFIG (uint8_t)(0x80 | ((HS_C1_I0_A0_EP1_BLKSIZE - 1) << 4) | ((HS_C1_I0_A0_EP1_BLKNO - 1) << 2) | HS_C1_I0_A0_EP1_TYPE) |
||||
#define HS_C1_I0_A0_EP1_FIFO_MAP (((1 - HS_C1_I0_A0_EP1_DIRECTION) << 4) | 1) |
||||
#define HS_C1_I0_A0_EP1_MAP (HS_C1_I0_A0_EP1_FIFO_START | (HS_C1_I0_A0_EP1_FIFO_START << 4) | (MASK_F0 >> (4*HS_C1_I0_A0_EP1_DIRECTION))) |
||||
|
||||
/* EP 2 */ |
||||
#define HS_C1_I0_A0_EP2_FIFO_START (uint8_t)(HS_C1_I0_A0_EP1_FIFO_START + HS_C1_I0_A0_EP1_FIFO_NO) |
||||
#define HS_C1_I0_A0_EP2_FIFO_NO (uint8_t)(HS_C1_I0_A0_EP2_BLKNO * HS_C1_I0_A0_EP2_BLKSIZE) |
||||
#define HS_C1_I0_A0_EP2_FIFO_CONFIG (uint8_t)(0x80 | ((HS_C1_I0_A0_EP2_BLKSIZE - 1) << 4) | ((HS_C1_I0_A0_EP2_BLKNO - 1) << 2) | HS_C1_I0_A0_EP2_TYPE) |
||||
#define HS_C1_I0_A0_EP2_FIFO_MAP (uint8_t)(((1 - HS_C1_I0_A0_EP2_DIRECTION) << 4) | 2) |
||||
#define HS_C1_I0_A0_EP2_MAP (uint8_t)(HS_C1_I0_A0_EP2_FIFO_START | (HS_C1_I0_A0_EP2_FIFO_START << 4) | (MASK_F0 >> (4*HS_C1_I0_A0_EP2_DIRECTION))) |
||||
|
||||
/* EP 3 */ |
||||
#define HS_C1_I0_A0_EP3_FIFO_START 14 |
||||
#define HS_C1_I0_A0_EP3_FIFO_NO (HS_C1_I0_A0_EP3_BLKNO * HS_C1_I0_A0_EP3_BLKSIZE) |
||||
#define HS_C1_I0_A0_EP3_FIFO_CONFIG (uint8_t)(0x80 | ((HS_C1_I0_A0_EP3_BLKSIZE - 1) << 4) | ((HS_C1_I0_A0_EP3_BLKNO - 1) << 2) | HS_C1_I0_A0_EP3_TYPE) |
||||
#define HS_C1_I0_A0_EP3_FIFO_MAP (uint8_t)(((1 - HS_C1_I0_A0_EP3_DIRECTION) << 4) | 3) |
||||
#define HS_C1_I0_A0_EP3_MAP (uint8_t)(HS_C1_I0_A0_EP3_FIFO_START | (HS_C1_I0_A0_EP3_FIFO_START << 4) | (MASK_F0 >> (4*HS_C1_I0_A0_EP3_DIRECTION))) |
||||
|
||||
/* EP 4 */ |
||||
#define HS_C1_I0_A0_EP4_FIFO_START (HS_C1_I0_A0_EP3_FIFO_START + HS_C1_I0_A0_EP3_FIFO_NO) |
||||
#define HS_C1_I0_A0_EP4_FIFO_NO (HS_C1_I0_A0_EP4_BLKNO * HS_C1_I0_A0_EP4_BLKSIZE) |
||||
#define HS_C1_I0_A0_EP4_FIFO_CONFIG (uint8_t)(0x80 | ((HS_C1_I0_A0_EP4_BLKSIZE - 1) << 4) | ((HS_C1_I0_A0_EP4_BLKNO - 1) << 2) | HS_C1_I0_A0_EP4_TYPE) |
||||
#define HS_C1_I0_A0_EP4_FIFO_MAP (((1 - HS_C1_I0_A0_EP4_DIRECTION) << 4) | 4) |
||||
#define HS_C1_I0_A0_EP4_MAP (uint8_t)(HS_C1_I0_A0_EP4_FIFO_START | (HS_C1_I0_A0_EP4_FIFO_START << 4) | (MASK_F0 >> (4*HS_C1_I0_A0_EP4_DIRECTION))) |
||||
|
||||
/* Configuration 1 */ |
||||
#define FS_C1_INTERFACE_NUMBER 0x01 |
||||
#define FS_C1 0x01 |
||||
#define FS_C1_iConfiguration 0x00 |
||||
#define FS_C1_bmAttribute 0x80 |
||||
#define FS_C1_iMaxPower 0xfa |
||||
|
||||
/* Interface 0 */ |
||||
#define FS_C1_I0_ALT_NUMBER 0x01 |
||||
/* AlternateSetting 0x00 */ |
||||
#define FS_C1_I0_A0_bInterfaceNumber 0x00 |
||||
#define FS_C1_I0_A0_bAlternateSetting 0x00 |
||||
#define FS_C1_I0_A0_EP_NUMBER 0x04 |
||||
#define FS_C1_I0_A0_bInterfaceClass 0xff |
||||
#define FS_C1_I0_A0_bInterfaceSubClass 0x00 |
||||
#define FS_C1_I0_A0_bInterfaceProtocol 0x00 |
||||
|
||||
/* EP 1 */ |
||||
#define FS_C1_I0_A0_EP1_BLKSIZE 512 |
||||
/* JWEI 2003/05/19 */ |
||||
#define FS_C1_I0_A0_EP1_BLKNO DOUBLE_BLK |
||||
#define FS_C1_I0_A0_EP1_DIRECTION DIRECTION_OUT |
||||
#define FS_C1_I0_A0_EP1_TYPE TF_TYPE_BULK |
||||
#define FS_C1_I0_A0_EP1_MAX_PACKET 64 |
||||
#define FS_C1_I0_A0_EP1_bInterval 0 |
||||
|
||||
/* EP 2 */ |
||||
#define FS_C1_I0_A0_EP2_BLKSIZE 512 |
||||
/* JWEI 2003/08/20 */ |
||||
#define FS_C1_I0_A0_EP2_BLKNO SINGLE_BLK |
||||
#define FS_C1_I0_A0_EP2_DIRECTION DIRECTION_IN |
||||
#define FS_C1_I0_A0_EP2_TYPE TF_TYPE_BULK |
||||
#define FS_C1_I0_A0_EP2_MAX_PACKET 64 |
||||
#define FS_C1_I0_A0_EP2_bInterval 0 |
||||
|
||||
/* EP 3 */ |
||||
#define FS_C1_I0_A0_EP3_BLKSIZE 64 |
||||
#define FS_C1_I0_A0_EP3_BLKNO SINGLE_BLK |
||||
#define FS_C1_I0_A0_EP3_DIRECTION DIRECTION_IN |
||||
#define FS_C1_I0_A0_EP3_TYPE TF_TYPE_INTERRUPT |
||||
#define FS_C1_I0_A0_EP3_MAX_PACKET 0x0040 |
||||
#define FS_C1_I0_A0_EP3_bInterval 1 |
||||
|
||||
/* EP 4 */ |
||||
#define FS_C1_I0_A0_EP4_BLKSIZE 64 |
||||
#define FS_C1_I0_A0_EP4_BLKNO SINGLE_BLK |
||||
#define FS_C1_I0_A0_EP4_DIRECTION DIRECTION_OUT |
||||
#define FS_C1_I0_A0_EP4_TYPE TF_TYPE_BULK |
||||
#define FS_C1_I0_A0_EP4_MAX_PACKET 0x0040 |
||||
#define FS_C1_I0_A0_EP4_bInterval 0 |
||||
|
||||
#define FS_C1_I0_A0_EP_LENGTH (EP_LENGTH * FS_C1_I0_A0_EP_NUMBER) |
||||
/* EP 1 */ |
||||
#define FS_C1_I0_A0_EP1_FIFO_START 0 |
||||
#define FS_C1_I0_A0_EP1_FIFO_NO (uint8_t)(FS_C1_I0_A0_EP1_BLKNO * FS_C1_I0_A0_EP1_BLKSIZE) |
||||
#define FS_C1_I0_A0_EP1_FIFO_CONFIG (uint8_t)(0x80 | ((FS_C1_I0_A0_EP1_BLKSIZE - 1) << 4) | ((FS_C1_I0_A0_EP1_BLKNO - 1) << 2) | FS_C1_I0_A0_EP1_TYPE) |
||||
#define FS_C1_I0_A0_EP1_FIFO_MAP (uint8_t)(((1 - FS_C1_I0_A0_EP1_DIRECTION) << 4) | 1) |
||||
#define FS_C1_I0_A0_EP1_MAP (uint8_t)(FS_C1_I0_A0_EP1_FIFO_START | (FS_C1_I0_A0_EP1_FIFO_START << 4) | (MASK_F0 >> (4*FS_C1_I0_A0_EP1_DIRECTION))) |
||||
|
||||
/* EP 2 */ |
||||
#define FS_C1_I0_A0_EP2_FIFO_START (uint8_t)(FS_C1_I0_A0_EP1_FIFO_START + FS_C1_I0_A0_EP1_FIFO_NO) |
||||
#define FS_C1_I0_A0_EP2_FIFO_NO (uint8_t)(FS_C1_I0_A0_EP2_BLKNO * FS_C1_I0_A0_EP2_BLKSIZE) |
||||
#define FS_C1_I0_A0_EP2_FIFO_CONFIG (uint8_t)(0x80 | ((FS_C1_I0_A0_EP2_BLKSIZE - 1) << 4) | ((FS_C1_I0_A0_EP2_BLKNO - 1) << 2) | FS_C1_I0_A0_EP2_TYPE) |
||||
#define FS_C1_I0_A0_EP2_FIFO_MAP (uint8_t)(((1 - FS_C1_I0_A0_EP2_DIRECTION) << 4) | 2) |
||||
#define FS_C1_I0_A0_EP2_MAP (uint8_t)(FS_C1_I0_A0_EP2_FIFO_START | (FS_C1_I0_A0_EP2_FIFO_START << 4) | (MASK_F0 >> (4*FS_C1_I0_A0_EP2_DIRECTION))) |
||||
|
||||
/* EP 3 */ |
||||
#define FS_C1_I0_A0_EP3_FIFO_START 14 |
||||
#define FS_C1_I0_A0_EP3_FIFO_NO (uint8_t)(FS_C1_I0_A0_EP3_BLKNO * FS_C1_I0_A0_EP3_BLKSIZE) |
||||
#define FS_C1_I0_A0_EP3_FIFO_CONFIG (uint8_t)(0x80 | ((FS_C1_I0_A0_EP3_BLKSIZE - 1) << 4) | ((FS_C1_I0_A0_EP3_BLKNO - 1) << 2) | FS_C1_I0_A0_EP3_TYPE) |
||||
#define FS_C1_I0_A0_EP3_FIFO_MAP (uint8_t)(((1 - FS_C1_I0_A0_EP3_DIRECTION) << 4) | 3) |
||||
#define FS_C1_I0_A0_EP3_MAP (uint8_t)(FS_C1_I0_A0_EP3_FIFO_START | (FS_C1_I0_A0_EP3_FIFO_START << 4) | (MASK_F0 >> (4*FS_C1_I0_A0_EP3_DIRECTION))) |
||||
|
||||
/* EP 4 */ |
||||
#define FS_C1_I0_A0_EP4_FIFO_START (uint8_t)(FS_C1_I0_A0_EP3_FIFO_START + FS_C1_I0_A0_EP3_FIFO_NO) |
||||
#define FS_C1_I0_A0_EP4_FIFO_NO (uint8_t)(FS_C1_I0_A0_EP4_BLKNO * FS_C1_I0_A0_EP4_BLKSIZE) |
||||
#define FS_C1_I0_A0_EP4_FIFO_CONFIG (uint8_t)(0x80 | ((FS_C1_I0_A0_EP4_BLKSIZE - 1) << 4) | ((FS_C1_I0_A0_EP4_BLKNO - 1) << 2) | FS_C1_I0_A0_EP4_TYPE) |
||||
#define FS_C1_I0_A0_EP4_FIFO_MAP (uint8_t)(((1 - FS_C1_I0_A0_EP4_DIRECTION) << 4) | 4) |
||||
#define FS_C1_I0_A0_EP4_MAP (uint8_t)(FS_C1_I0_A0_EP4_FIFO_START | (FS_C1_I0_A0_EP4_FIFO_START << 4) | (MASK_F0 >> (4*FS_C1_I0_A0_EP4_DIRECTION))) |
||||
|
||||
#endif /* __CARL9170FW_USB_FIFO_H */ |
@ -0,0 +1,296 @@
@@ -0,0 +1,296 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* WLAN |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_WLAN_H |
||||
#define __CARL9170FW_WLAN_H |
||||
|
||||
#include "config.h" |
||||
#include "carl9170.h" |
||||
#include "io.h" |
||||
|
||||
struct ieee80211_hdr; |
||||
|
||||
static inline __inline void set_wlan_txq_dma_addr(const unsigned int q, const uint32_t v) |
||||
{ |
||||
set(AR9170_MAC_REG_DMA_TXQ_ADDR + (q << 3), v); |
||||
} |
||||
|
||||
static inline __inline void set_wlan_txq_dma_curr_addr(const unsigned int q, const uint32_t v) |
||||
{ |
||||
set(AR9170_MAC_REG_DMA_TXQ_CURR_ADDR + (q << 3), v); |
||||
} |
||||
|
||||
static inline __inline volatile struct dma_desc *get_wlan_txq_dma_addr(const unsigned int q) |
||||
{ |
||||
return getp(AR9170_MAC_REG_DMA_TXQ_ADDR + (q << 3)); |
||||
} |
||||
|
||||
static inline __inline volatile struct dma_desc *get_wlan_txq_addr(const unsigned int q) |
||||
{ |
||||
return getp(AR9170_MAC_REG_DMA_TXQ_CURR_ADDR + (q << 3)); |
||||
} |
||||
|
||||
static inline __inline volatile struct dma_desc *get_wlan_txq_last_addr(const unsigned int q) |
||||
{ |
||||
return getp(AR9170_MAC_REG_DMA_TXQ_LAST_ADDR + (q << 2)); |
||||
} |
||||
|
||||
static inline __inline void wlan_trigger(const uint32_t queue_bit) |
||||
{ |
||||
set(AR9170_MAC_REG_DMA_TRIGGER, queue_bit); |
||||
} |
||||
|
||||
static inline __inline uint8_t ar9170_get_rx_macstatus_status(struct dma_desc *desc) |
||||
{ |
||||
return *((uint8_t *) DESC_PAYLOAD_OFF(desc->lastAddr, |
||||
(unsigned int) desc->lastAddr->dataSize - 1)); |
||||
} |
||||
|
||||
static inline __inline uint8_t ar9170_get_rx_macstatus_error(struct dma_desc *desc) |
||||
{ |
||||
unsigned int offset; |
||||
|
||||
if (desc->lastAddr->dataSize == 1) { |
||||
while (desc->lastAddr != desc->nextAddr) |
||||
desc = desc->nextAddr; |
||||
|
||||
offset = (unsigned int) (desc->dataSize - 1); |
||||
} else { |
||||
desc = desc->lastAddr; |
||||
offset = desc->dataSize - |
||||
(sizeof(struct ar9170_rx_macstatus) - |
||||
offsetof(struct ar9170_rx_macstatus, error)); |
||||
} |
||||
|
||||
return *((uint8_t *) DESC_PAYLOAD_OFF(desc, offset)); |
||||
} |
||||
|
||||
static inline __inline struct ieee80211_hdr *ar9170_get_rx_i3e(struct dma_desc *desc) |
||||
{ |
||||
if (!((ar9170_get_rx_macstatus_status(desc) & |
||||
AR9170_RX_STATUS_MPDU) & AR9170_RX_STATUS_MPDU_LAST)) { |
||||
return (void *)(DESC_PAYLOAD_OFF(desc, |
||||
offsetof(struct ar9170_rx_frame_head, i3e))); |
||||
} else { |
||||
return (void *)(DESC_PAYLOAD_OFF(desc, |
||||
offsetof(struct ar9170_rx_frame_tail, i3e))); |
||||
} |
||||
} |
||||
|
||||
static inline __inline struct ar9170_rx_head *ar9170_get_rx_head(struct dma_desc *desc) |
||||
{ |
||||
if (!((ar9170_get_rx_macstatus_status(desc) & |
||||
AR9170_RX_STATUS_MPDU) & AR9170_RX_STATUS_MPDU_LAST)) { |
||||
return (void *)((uint8_t *)DESC_PAYLOAD(desc) + |
||||
offsetof(struct ar9170_rx_frame_head, phy_head)); |
||||
} else { |
||||
return (void *) NULL; |
||||
} |
||||
} |
||||
|
||||
static inline __inline uint32_t ar9170_rx_to_phy(struct dma_desc *rx) |
||||
{ |
||||
struct ar9170_tx_hw_phy_control phy; |
||||
struct ar9170_rx_head *head; |
||||
uint8_t mac_status; |
||||
|
||||
phy.set = 0; |
||||
|
||||
head = ar9170_get_rx_head(rx); |
||||
if (!head) |
||||
return le32_to_cpu(phy.set); |
||||
|
||||
mac_status = ar9170_get_rx_macstatus_status(rx); |
||||
|
||||
phy.modulation = mac_status & AR9170_RX_STATUS_MODULATION; |
||||
phy.chains = AR9170_TX_PHY_TXCHAIN_1; |
||||
|
||||
switch (phy.modulation) { |
||||
case AR9170_RX_STATUS_MODULATION_CCK: |
||||
if (mac_status & AR9170_RX_STATUS_SHORT_PREAMBLE) |
||||
phy.preamble = 1; |
||||
|
||||
switch (head->plcp[0]) { |
||||
case AR9170_RX_PHY_RATE_CCK_2M: |
||||
phy.mcs = AR9170_TX_PHY_RATE_CCK_2M; |
||||
break; |
||||
|
||||
case AR9170_RX_PHY_RATE_CCK_5M: |
||||
phy.mcs = AR9170_TX_PHY_RATE_CCK_5M; |
||||
break; |
||||
|
||||
case AR9170_RX_PHY_RATE_CCK_11M: |
||||
phy.mcs = AR9170_TX_PHY_RATE_CCK_11M; |
||||
break; |
||||
|
||||
case AR9170_RX_PHY_RATE_CCK_1M: |
||||
default: |
||||
phy.mcs = AR9170_TX_PHY_RATE_CCK_1M; |
||||
break; |
||||
|
||||
} |
||||
break; |
||||
|
||||
case AR9170_RX_STATUS_MODULATION_DUPOFDM: |
||||
case AR9170_RX_STATUS_MODULATION_OFDM: |
||||
phy.mcs = head->plcp[0] & 0xf; |
||||
break; |
||||
|
||||
case AR9170_RX_STATUS_MODULATION_HT: |
||||
if (head->plcp[3] & 0x80) |
||||
phy.bandwidth = 2; |
||||
|
||||
if (head->plcp[6] & 0x80) |
||||
phy.short_gi = 1; |
||||
|
||||
/* TODO: Enable both chains for MCS > 7 */ |
||||
phy.mcs = head->plcp[6] & 0x7; |
||||
break; |
||||
} |
||||
|
||||
return le32_to_cpu(phy.set); |
||||
} |
||||
|
||||
static inline __inline unsigned int ar9170_get_rx_mpdu_len(struct dma_desc *desc) |
||||
{ |
||||
/* |
||||
* WARNING: you have to check the error bits in macstatus first! |
||||
*/ |
||||
|
||||
unsigned int mpdu_len = desc->totalLen; |
||||
|
||||
mpdu_len -= sizeof(struct ar9170_rx_macstatus); |
||||
|
||||
switch (ar9170_get_rx_macstatus_status(desc) & AR9170_RX_STATUS_MPDU) { |
||||
case AR9170_RX_STATUS_MPDU_LAST: |
||||
mpdu_len -= sizeof(struct ar9170_rx_phystatus); |
||||
break; |
||||
|
||||
case AR9170_RX_STATUS_MPDU_SINGLE: |
||||
mpdu_len -= sizeof(struct ar9170_rx_phystatus); |
||||
|
||||
case AR9170_RX_STATUS_MPDU_FIRST: |
||||
mpdu_len -= sizeof(struct ar9170_rx_head); |
||||
break; |
||||
|
||||
case AR9170_RX_STATUS_MPDU_MIDDLE: |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
return mpdu_len; |
||||
} |
||||
|
||||
static inline __inline bool ar9170_tx_length_check(const uint16_t len) |
||||
{ |
||||
return len > (sizeof(struct carl9170_tx_superframe) + 24 + |
||||
FCS_LEN); |
||||
} |
||||
|
||||
static inline __inline struct carl9170_tx_superframe *get_super(struct dma_desc *desc) |
||||
{ |
||||
return container_of(DESC_PAYLOAD(desc), struct carl9170_tx_superframe, |
||||
f); |
||||
} |
||||
|
||||
static inline __inline struct carl9170_tx_superframe *__get_super(struct dma_desc *desc) |
||||
{ |
||||
return DESC_PAYLOAD(desc); |
||||
} |
||||
|
||||
static inline __inline void hide_super(struct dma_desc *desc) |
||||
{ |
||||
desc->dataAddr = (uint8_t *) |
||||
(((unsigned long)(DESC_PAYLOAD(desc)) + |
||||
offsetof(struct carl9170_tx_superframe, f))); |
||||
|
||||
desc->dataSize -= sizeof(struct carl9170_tx_superdesc); |
||||
desc->totalLen -= sizeof(struct carl9170_tx_superdesc); |
||||
} |
||||
|
||||
static inline __inline void unhide_super(struct dma_desc *desc) |
||||
{ |
||||
desc->dataAddr = (uint8_t *) get_super(desc); |
||||
desc->dataSize += sizeof(struct carl9170_tx_superdesc); |
||||
desc->totalLen += sizeof(struct carl9170_tx_superdesc); |
||||
} |
||||
|
||||
static inline __inline __hot void read_tsf(uint32_t *tsf) |
||||
{ |
||||
/* |
||||
* "According to the [hardware] documentation: |
||||
* > when TSF_LOW is read, TSF_HI is automatically concurrently |
||||
* > copied into a temporary register so that an immediate read |
||||
* > of TSF_HI will get the value that was present when TSF_LOW |
||||
* > was read. " |
||||
* |
||||
* (David H. Lynch Jr. - mail from 2010-05-22) |
||||
* http://permalink.gmane.org/gmane.linux.kernel.wireless.general/51249 |
||||
*/ |
||||
|
||||
tsf[0] = get(AR9170_MAC_REG_TSF_L); |
||||
tsf[1] = get(AR9170_MAC_REG_TSF_H); |
||||
} |
||||
|
||||
/* This function will only work on uint32_t-aligned pointers! */ |
||||
static inline bool compare_ether_address(const void *_d0, const void *_d1) |
||||
{ |
||||
const uint32_t *d0 = _d0; |
||||
const uint32_t *d1 = _d1; |
||||
|
||||
/* BUG_ON((unsigned long)d0 & 3 || (unsigned long)d1 & 3)) */ |
||||
return !((d0[0] ^ d1[0]) | (unsigned short)(d0[1] ^ d1[1])); |
||||
} |
||||
|
||||
void wlan_tx(struct dma_desc *desc); |
||||
void wlan_tx_fw(struct carl9170_tx_superdesc *super, fw_desc_callback_t cb); |
||||
void wlan_timer(void); |
||||
void handle_wlan(void); |
||||
|
||||
void wlan_cab_flush_queue(const unsigned int vif); |
||||
void wlan_modify_beacon(const unsigned int vif, |
||||
const unsigned int bcn_addr, |
||||
const unsigned int bcn_len); |
||||
|
||||
void wlan_tx_complete(struct carl9170_tx_superframe *super, bool txs); |
||||
void wlan_prepare_wol(void); |
||||
|
||||
static inline void __check_wlantx(void) |
||||
{ |
||||
BUILD_BUG_ON(CARL9170_TX_SUPERDESC_LEN & 3); |
||||
BUILD_BUG_ON(sizeof(struct carl9170_tx_superdesc) != CARL9170_TX_SUPERDESC_LEN); |
||||
BUILD_BUG_ON(sizeof(struct _carl9170_tx_superdesc) != CARL9170_TX_SUPERDESC_LEN); |
||||
BUILD_BUG_ON(sizeof(struct _carl9170_tx_superframe) != CARL9170_TX_SUPERFRAME_LEN); |
||||
BUILD_BUG_ON((offsetof(struct carl9170_tx_superframe, f) & 3) != 0); |
||||
BUILD_BUG_ON(offsetof(struct _carl9170_tx_superframe, f) != |
||||
(offsetof(struct _carl9170_tx_superframe, f))); |
||||
BUILD_BUG_ON(sizeof(struct ar9170_tx_hwdesc) != AR9170_TX_HWDESC_LEN); |
||||
BUILD_BUG_ON(sizeof(struct _ar9170_tx_hwdesc) != AR9170_TX_HWDESC_LEN); |
||||
BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != AR9170_RX_HEAD_LEN); |
||||
BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != AR9170_RX_PHYSTATUS_LEN); |
||||
BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != AR9170_RX_MACSTATUS_LEN); |
||||
} |
||||
|
||||
#endif /* __CARL9170FW_WLAN_H */ |
@ -0,0 +1,67 @@
@@ -0,0 +1,67 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* WakeUp on WLAN definitions |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170FW_WOL_H |
||||
#define __CARL9170FW_WOL_H |
||||
|
||||
#include "config.h" |
||||
#include "compiler.h" |
||||
#include "types.h" |
||||
|
||||
#include "fwcmd.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
|
||||
struct ieee80211_hdr; |
||||
|
||||
void wol_prepare(void); |
||||
void wol_janitor(void); |
||||
void wol_rx(const unsigned int rx_filter __unused, |
||||
const struct ieee80211_hdr *hdr __unused, |
||||
const unsigned int len __unused); |
||||
void wol_cmd(const struct carl9170_wol_cmd *cmd); |
||||
|
||||
#else |
||||
|
||||
static inline void wol_cmd(const struct carl9170_wol_cmd *cmd __unused) |
||||
{ |
||||
} |
||||
|
||||
static inline void wol_prepare(void) |
||||
{ |
||||
} |
||||
|
||||
static inline void wol_janitor(void) |
||||
{ |
||||
} |
||||
|
||||
static inline void wol_rx(const unsigned int rx_filter __unused, |
||||
const struct ieee80211_hdr *hdr __unused, |
||||
const unsigned int len __unused) |
||||
{ |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
|
||||
#endif /* __CARL9170FW_CMD_H */ |
@ -0,0 +1,193 @@
@@ -0,0 +1,193 @@
|
||||
/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, |
||||
2004, 2005, 2006 |
||||
Free Software Foundation, Inc. |
||||
|
||||
This file 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, or (at your option) any |
||||
later version. |
||||
|
||||
In addition to the permissions in the GNU General Public License, the |
||||
Free Software Foundation gives you unlimited permission to link the |
||||
compiled version of this file into combinations with other programs, |
||||
and to distribute those combinations without any restriction coming |
||||
from the use of this file. (The General Public License restrictions |
||||
do apply in other respects; for example, they cover modification of |
||||
the file, and distribution when not linked into a combine |
||||
executable.) |
||||
|
||||
This file 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; see the file COPYING. If not, write to |
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
||||
Boston, MA 02110-1301, USA. */ |
||||
|
||||
!! libgcc routines for the Renesas / SuperH SH CPUs. |
||||
!! Contributed by Steve Chamberlain. |
||||
!! sac@cygnus.com |
||||
|
||||
!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines |
||||
!! recoded in assembly by Toshiyasu Morita |
||||
!! tm@netcom.com |
||||
|
||||
/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and |
||||
ELF local label prefixes by J"orn Rennecke |
||||
amylaar@cygnus.com */ |
||||
|
||||
! |
||||
! __ashlsi3 |
||||
! |
||||
! Entry: |
||||
! |
||||
! r4: Value to shift |
||||
! r5: Shifts |
||||
! |
||||
! Exit: |
||||
! |
||||
! r0: Result |
||||
! |
||||
! Destroys: |
||||
! |
||||
! (none) |
||||
! |
||||
.global ___ashlsi3 |
||||
|
||||
.align 2 |
||||
___ashlsi3: |
||||
mov #31,r0 |
||||
and r0,r5 |
||||
mova ashlsi3_table,r0 |
||||
mov.b @(r0,r5),r5 |
||||
#ifdef __sh1__ |
||||
add r5,r0 |
||||
jmp @r0 |
||||
#else |
||||
braf r5 |
||||
#endif |
||||
mov r4,r0 |
||||
|
||||
.align 2 |
||||
ashlsi3_table: |
||||
.byte ashlsi3_0-ashlsi3_table |
||||
.byte ashlsi3_1-ashlsi3_table |
||||
.byte ashlsi3_2-ashlsi3_table |
||||
.byte ashlsi3_3-ashlsi3_table |
||||
.byte ashlsi3_4-ashlsi3_table |
||||
.byte ashlsi3_5-ashlsi3_table |
||||
.byte ashlsi3_6-ashlsi3_table |
||||
.byte ashlsi3_7-ashlsi3_table |
||||
.byte ashlsi3_8-ashlsi3_table |
||||
.byte ashlsi3_9-ashlsi3_table |
||||
.byte ashlsi3_10-ashlsi3_table |
||||
.byte ashlsi3_11-ashlsi3_table |
||||
.byte ashlsi3_12-ashlsi3_table |
||||
.byte ashlsi3_13-ashlsi3_table |
||||
.byte ashlsi3_14-ashlsi3_table |
||||
.byte ashlsi3_15-ashlsi3_table |
||||
.byte ashlsi3_16-ashlsi3_table |
||||
.byte ashlsi3_17-ashlsi3_table |
||||
.byte ashlsi3_18-ashlsi3_table |
||||
.byte ashlsi3_19-ashlsi3_table |
||||
.byte ashlsi3_20-ashlsi3_table |
||||
.byte ashlsi3_21-ashlsi3_table |
||||
.byte ashlsi3_22-ashlsi3_table |
||||
.byte ashlsi3_23-ashlsi3_table |
||||
.byte ashlsi3_24-ashlsi3_table |
||||
.byte ashlsi3_25-ashlsi3_table |
||||
.byte ashlsi3_26-ashlsi3_table |
||||
.byte ashlsi3_27-ashlsi3_table |
||||
.byte ashlsi3_28-ashlsi3_table |
||||
.byte ashlsi3_29-ashlsi3_table |
||||
.byte ashlsi3_30-ashlsi3_table |
||||
.byte ashlsi3_31-ashlsi3_table |
||||
|
||||
ashlsi3_6: |
||||
shll2 r0 |
||||
ashlsi3_4: |
||||
shll2 r0 |
||||
ashlsi3_2: |
||||
rts |
||||
shll2 r0 |
||||
|
||||
ashlsi3_7: |
||||
shll2 r0 |
||||
ashlsi3_5: |
||||
shll2 r0 |
||||
ashlsi3_3: |
||||
shll2 r0 |
||||
ashlsi3_1: |
||||
rts |
||||
shll r0 |
||||
|
||||
ashlsi3_14: |
||||
shll2 r0 |
||||
ashlsi3_12: |
||||
shll2 r0 |
||||
ashlsi3_10: |
||||
shll2 r0 |
||||
ashlsi3_8: |
||||
rts |
||||
shll8 r0 |
||||
|
||||
ashlsi3_15: |
||||
shll2 r0 |
||||
ashlsi3_13: |
||||
shll2 r0 |
||||
ashlsi3_11: |
||||
shll2 r0 |
||||
ashlsi3_9: |
||||
shll8 r0 |
||||
rts |
||||
shll r0 |
||||
|
||||
ashlsi3_22: |
||||
shll2 r0 |
||||
ashlsi3_20: |
||||
shll2 r0 |
||||
ashlsi3_18: |
||||
shll2 r0 |
||||
ashlsi3_16: |
||||
rts |
||||
shll16 r0 |
||||
|
||||
ashlsi3_23: |
||||
shll2 r0 |
||||
ashlsi3_21: |
||||
shll2 r0 |
||||
ashlsi3_19: |
||||
shll2 r0 |
||||
ashlsi3_17: |
||||
shll16 r0 |
||||
rts |
||||
shll r0 |
||||
|
||||
ashlsi3_30: |
||||
shll2 r0 |
||||
ashlsi3_28: |
||||
shll2 r0 |
||||
ashlsi3_26: |
||||
shll2 r0 |
||||
ashlsi3_24: |
||||
shll16 r0 |
||||
rts |
||||
shll8 r0 |
||||
|
||||
ashlsi3_31: |
||||
shll2 r0 |
||||
ashlsi3_29: |
||||
shll2 r0 |
||||
ashlsi3_27: |
||||
shll2 r0 |
||||
ashlsi3_25: |
||||
shll16 r0 |
||||
shll8 r0 |
||||
rts |
||||
shll r0 |
||||
|
||||
ashlsi3_0: |
||||
rts |
||||
nop |
@ -0,0 +1,161 @@
@@ -0,0 +1,161 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Security Engine |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "cam.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_SECURITY_ENGINE |
||||
static void disable_cam_user(const uint16_t userId) |
||||
{ |
||||
if (userId <= 31) |
||||
andl(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L, (~((uint32_t) 1 << userId))); |
||||
else if (userId <= 63) |
||||
andl(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H, (~((uint32_t) 1 << (userId - 32)))); |
||||
} |
||||
|
||||
static void enable_cam_user(const uint16_t userId) |
||||
{ |
||||
if (userId <= 31) |
||||
orl(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L, (((uint32_t) 1) << userId)); |
||||
else if (userId <= 63) |
||||
orl(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H, (((uint32_t) 1) << (userId - 32))); |
||||
} |
||||
|
||||
static void wait_for_cam_read_ready(void) |
||||
{ |
||||
while ((get(AR9170_MAC_REG_CAM_STATE) & AR9170_MAC_CAM_STATE_READ_PENDING) == 0) { |
||||
/* |
||||
* wait |
||||
*/ |
||||
} |
||||
} |
||||
|
||||
static void wait_for_cam_write_ready(void) |
||||
{ |
||||
while ((get(AR9170_MAC_REG_CAM_STATE) & AR9170_MAC_CAM_STATE_WRITE_PENDING) == 0) { |
||||
/* |
||||
* wait some more |
||||
*/ |
||||
} |
||||
} |
||||
|
||||
static void HW_CAM_Avail(void) |
||||
{ |
||||
uint32_t tmpValue; |
||||
|
||||
do { |
||||
tmpValue = get(AR9170_MAC_REG_CAM_MODE); |
||||
} while (tmpValue & AR9170_MAC_CAM_HOST_PENDING); |
||||
} |
||||
|
||||
static void HW_CAM_Write128(const uint32_t address, const uint32_t *data) |
||||
{ |
||||
HW_CAM_Avail(); |
||||
|
||||
set(AR9170_MAC_REG_CAM_DATA0, data[0]); |
||||
set(AR9170_MAC_REG_CAM_DATA1, data[1]); |
||||
set(AR9170_MAC_REG_CAM_DATA2, data[2]); |
||||
set(AR9170_MAC_REG_CAM_DATA3, data[3]); |
||||
|
||||
set(AR9170_MAC_REG_CAM_ADDR, address | AR9170_MAC_CAM_ADDR_WRITE); |
||||
|
||||
wait_for_cam_write_ready(); |
||||
} |
||||
|
||||
static void HW_CAM_Read128(const uint32_t address, uint32_t *data) |
||||
{ |
||||
|
||||
HW_CAM_Avail(); |
||||
set(AR9170_MAC_REG_CAM_ADDR, address); |
||||
|
||||
wait_for_cam_read_ready(); |
||||
HW_CAM_Avail(); |
||||
data[0] = get(AR9170_MAC_REG_CAM_DATA0); |
||||
data[1] = get(AR9170_MAC_REG_CAM_DATA1); |
||||
data[2] = get(AR9170_MAC_REG_CAM_DATA2); |
||||
data[3] = get(AR9170_MAC_REG_CAM_DATA3); |
||||
} |
||||
|
||||
void set_key(const struct carl9170_set_key_cmd *key) |
||||
{ |
||||
uint32_t data[4]; |
||||
uint16_t row, wordId, nibbleId, i; |
||||
|
||||
if (key->user > (AR9170_CAM_MAX_USER + 3)) |
||||
return ; |
||||
|
||||
if (key->keyId > 1) |
||||
return ; |
||||
|
||||
/* Disable Key */ |
||||
disable_cam_user(key->user); |
||||
|
||||
/* Set encrypt type */ |
||||
if (key->user >= AR9170_CAM_MAX_USER) { |
||||
/* default */ |
||||
row = DEFAULT_ENCRY_TYPE; |
||||
wordId = 0; |
||||
nibbleId = (key->user - AR9170_CAM_MAX_USER) & 0x7; |
||||
} else { |
||||
row = ENCRY_TYPE_START_ADDR + (key->user >> 5); |
||||
wordId = (key->user >> 3) & 0x3; |
||||
nibbleId = key->user & 0x7; |
||||
} |
||||
|
||||
HW_CAM_Read128(row, data); |
||||
data[wordId] &= (~(0xf << ((uint32_t) nibbleId * 4))); |
||||
data[wordId] |= (key->type << ((uint32_t) nibbleId * 4)); |
||||
HW_CAM_Write128(row, data); |
||||
|
||||
/* Set MAC address */ |
||||
if (key->user < AR9170_CAM_MAX_USER) { |
||||
uint16_t byteId; |
||||
wordId = (key->user >> 2) & 0x3; |
||||
byteId = key->user & 0x3; |
||||
row = (key->user >> 4) * 6; |
||||
|
||||
for (i = 0; i < 6; i++) { |
||||
HW_CAM_Read128(row + i, data); |
||||
data[wordId] &= (~(0xff << ((uint32_t) byteId * 8))); |
||||
data[wordId] |= (key->macAddr[i] << ((uint32_t) byteId * 8)); |
||||
HW_CAM_Write128(row + i, data); |
||||
} |
||||
} |
||||
|
||||
/* Set key */ |
||||
row = KEY_START_ADDR + (key->user * 2) + key->keyId; |
||||
|
||||
HW_CAM_Write128(row, key->key); |
||||
|
||||
/* Enable Key */ |
||||
enable_cam_user(key->user); |
||||
} |
||||
|
||||
void disable_key(const struct carl9170_disable_key_cmd *key) |
||||
{ |
||||
disable_cam_user(key->user); |
||||
} |
||||
|
||||
#endif /* CONFIG_CARL9170FW_SECURITY_ENGINE */ |
@ -0,0 +1,154 @@
@@ -0,0 +1,154 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Code to handle commands from the host driver. |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "io.h" |
||||
#include "cam.h" |
||||
#include "rf.h" |
||||
#include "printf.h" |
||||
#include "timer.h" |
||||
#include "wl.h" |
||||
#include "wol.h" |
||||
|
||||
void handle_cmd(struct carl9170_rsp *resp) |
||||
{ |
||||
struct carl9170_cmd *cmd = &dma_mem.reserved.cmd.cmd; |
||||
unsigned int i; |
||||
|
||||
/* copies cmd, len and extra fields */ |
||||
resp->hdr.len = cmd->hdr.len; |
||||
resp->hdr.cmd = cmd->hdr.cmd; |
||||
resp->hdr.ext = cmd->hdr.ext; |
||||
resp->hdr.seq |= cmd->hdr.seq; |
||||
|
||||
switch (cmd->hdr.cmd & ~CARL9170_CMD_ASYNC_FLAG) { |
||||
case CARL9170_CMD_RREG: |
||||
for (i = 0; i < (cmd->hdr.len / 4); i++) |
||||
resp->rreg_res.vals[i] = get(cmd->rreg.regs[i]); |
||||
break; |
||||
|
||||
case CARL9170_CMD_WREG: |
||||
resp->hdr.len = 0; |
||||
for (i = 0; i < (cmd->hdr.len / 8); i++) |
||||
set(cmd->wreg.regs[i].addr, cmd->wreg.regs[i].val); |
||||
break; |
||||
|
||||
case CARL9170_CMD_ECHO: |
||||
memcpy(resp->echo.vals, cmd->echo.vals, cmd->hdr.len); |
||||
break; |
||||
|
||||
case CARL9170_CMD_SWRST: |
||||
#ifdef CONFIG_CARL9170FW_FW_MAC_RESET |
||||
/* |
||||
* Command has no payload, so the response |
||||
* has no payload either. |
||||
* resp->hdr.len = 0; |
||||
*/ |
||||
fw.wlan.mac_reset = CARL9170_MAC_RESET_FORCE; |
||||
#endif /* CONFIG_CARL9170FW_FW_MAC_RESET */ |
||||
break; |
||||
|
||||
case CARL9170_CMD_REBOOT: |
||||
/* |
||||
* resp->len = 0; |
||||
*/ |
||||
fw.reboot = 1; |
||||
break; |
||||
|
||||
case CARL9170_CMD_READ_TSF: |
||||
resp->hdr.len = 8; |
||||
read_tsf((uint32_t *)resp->tsf.tsf); |
||||
break; |
||||
|
||||
case CARL9170_CMD_RX_FILTER: |
||||
resp->hdr.len = 0; |
||||
fw.wlan.rx_filter = cmd->rx_filter.rx_filter; |
||||
break; |
||||
|
||||
case CARL9170_CMD_WOL: |
||||
wol_cmd(&cmd->wol); |
||||
break; |
||||
|
||||
case CARL9170_CMD_TALLY: |
||||
resp->hdr.len = sizeof(struct carl9170_tally_rsp); |
||||
memcpy(&resp->tally, &fw.tally, sizeof(struct carl9170_tally_rsp)); |
||||
resp->tally.tick = fw.ticks_per_usec; |
||||
memset(&fw.tally, 0, sizeof(struct carl9170_tally_rsp)); |
||||
break; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_CAB_QUEUE |
||||
case CARL9170_CMD_BCN_CTRL: |
||||
resp->hdr.len = 0; |
||||
|
||||
if (cmd->bcn_ctrl.mode & CARL9170_BCN_CTRL_CAB_TRIGGER) { |
||||
wlan_modify_beacon(cmd->bcn_ctrl.vif_id, |
||||
cmd->bcn_ctrl.bcn_addr, cmd->bcn_ctrl.bcn_len); |
||||
set(AR9170_MAC_REG_BCN_ADDR, cmd->bcn_ctrl.bcn_addr); |
||||
set(AR9170_MAC_REG_BCN_LENGTH, cmd->bcn_ctrl.bcn_len); |
||||
set(AR9170_MAC_REG_BCN_CTRL, AR9170_BCN_CTRL_READY); |
||||
} else { |
||||
wlan_cab_flush_queue(cmd->bcn_ctrl.vif_id); |
||||
fw.wlan.cab_flush_trigger[cmd->bcn_ctrl.vif_id] = CARL9170_CAB_TRIGGER_EMPTY; |
||||
} |
||||
break; |
||||
#endif /* CONFIG_CARL9170FW_CAB_QUEUE */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_SECURITY_ENGINE |
||||
case CARL9170_CMD_EKEY: |
||||
resp->hdr.len = 0; |
||||
set_key(&cmd->setkey); |
||||
break; |
||||
|
||||
case CARL9170_CMD_DKEY: |
||||
resp->hdr.len = 0; |
||||
disable_key(&cmd->disablekey); |
||||
break; |
||||
#endif /* CONFIG_CARL9170FW_SECURITY_ENGINE */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS |
||||
case CARL9170_CMD_FREQUENCY: |
||||
case CARL9170_CMD_RF_INIT: |
||||
rf_cmd(cmd, resp); |
||||
break; |
||||
|
||||
case CARL9170_CMD_FREQ_START: |
||||
/* |
||||
* resp->hdr.len = 0; |
||||
*/ |
||||
rf_notify_set_channel(); |
||||
break; |
||||
|
||||
case CARL9170_CMD_PSM: |
||||
resp->hdr.len = 0; |
||||
fw.phy.psm.state = le32_to_cpu(cmd->psm.state); |
||||
rf_psm(); |
||||
break; |
||||
#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ |
||||
|
||||
default: |
||||
BUG("Unknown command %x\n", cmd->hdr.cmd); |
||||
break; |
||||
} |
||||
} |
@ -0,0 +1,255 @@
@@ -0,0 +1,255 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* DMA descriptor handling functions |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "wl.h" |
||||
#include "printf.h" |
||||
|
||||
struct ar9170_dma_memory dma_mem __section(sram); |
||||
|
||||
static void copy_dma_desc(struct dma_desc *dst, |
||||
struct dma_desc *src) |
||||
{ |
||||
memcpy(dst, src, sizeof(struct dma_desc)); |
||||
} |
||||
|
||||
static void clear_descriptor(struct dma_desc *d) |
||||
{ |
||||
d->status = AR9170_OWN_BITS_SW; |
||||
d->ctrl = 0; |
||||
d->dataSize = 0; |
||||
d->totalLen = 0; |
||||
d->lastAddr = d; |
||||
d->dataAddr = NULL; |
||||
d->nextAddr = d; |
||||
} |
||||
|
||||
static void fill_descriptor(struct dma_desc *d, uint16_t size, uint8_t *data) |
||||
{ |
||||
d->status = AR9170_OWN_BITS_SW; |
||||
d->ctrl = 0; |
||||
d->dataSize = size; |
||||
d->totalLen = 0; |
||||
d->lastAddr = d; |
||||
d->dataAddr = data; |
||||
d->nextAddr = NULL; |
||||
} |
||||
|
||||
static void init_queue(struct dma_queue *q, struct dma_desc *d) |
||||
{ |
||||
q->head = q->terminator = d; |
||||
} |
||||
|
||||
/* |
||||
* - Init up_queue, down_queue, tx_queue[5], rx_queue. |
||||
* - Setup descriptors and data buffer address. |
||||
* - Ring descriptors rx_queue and down_queue by dma_reclaim(). |
||||
* |
||||
* NOTE: LastAddr tempary point (same) to nextAddr after initialize. |
||||
* Because LastAddr is don't care in function dma_reclaim(). |
||||
*/ |
||||
void dma_init_descriptors(void) |
||||
{ |
||||
unsigned int i, j; |
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dma_mem.terminator); i++) |
||||
clear_descriptor(&dma_mem.terminator[i]); |
||||
|
||||
/* Assign terminators to DMA queues */ |
||||
i = 0; |
||||
init_queue(&fw.pta.up_queue, &dma_mem.terminator[i++]); |
||||
init_queue(&fw.pta.down_queue, &dma_mem.terminator[i++]); |
||||
for (j = 0; j < __AR9170_NUM_TX_QUEUES; j++) |
||||
init_queue(&fw.wlan.tx_queue[j], &dma_mem.terminator[i++]); |
||||
init_queue(&fw.wlan.tx_retry, &dma_mem.terminator[i++]); |
||||
init_queue(&fw.wlan.rx_queue, &dma_mem.terminator[i++]); |
||||
fw.usb.int_desc = &dma_mem.terminator[i++]; |
||||
fw.wlan.fw_desc = &dma_mem.terminator[i++]; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_CAB_QUEUE |
||||
for (j = 0; j < CARL9170_INTF_NUM; j++) |
||||
init_queue(&fw.wlan.cab_queue[j], &dma_mem.terminator[i++]); |
||||
#endif /* CONFIG_CARL9170FW_CAB_QUEUE */ |
||||
|
||||
BUG_ON(AR9170_TERMINATOR_NUMBER != i); |
||||
|
||||
DBG("Blocks:%d [tx:%d, rx:%d] Terminators:%d/%d\n", |
||||
AR9170_BLOCK_NUMBER, AR9170_TX_BLOCK_NUMBER, |
||||
AR9170_RX_BLOCK_NUMBER, AR9170_TERMINATOR_NUMBER, i); |
||||
|
||||
/* Init descriptors and memory blocks */ |
||||
for (i = 0; i < AR9170_BLOCK_NUMBER; i++) { |
||||
fill_descriptor(&dma_mem.block[i], AR9170_BLOCK_SIZE, dma_mem.data[i].data); |
||||
|
||||
if (i < AR9170_TX_BLOCK_NUMBER) |
||||
dma_reclaim(&fw.pta.down_queue, &dma_mem.block[i]); |
||||
else |
||||
dma_reclaim(&fw.wlan.rx_queue, &dma_mem.block[i]); |
||||
} |
||||
|
||||
/* Set DMA address registers */ |
||||
set(AR9170_PTA_REG_DN_DMA_ADDRH, (uint32_t) fw.pta.down_queue.head >> 16); |
||||
set(AR9170_PTA_REG_DN_DMA_ADDRL, (uint32_t) fw.pta.down_queue.head & 0xffff); |
||||
set(AR9170_PTA_REG_UP_DMA_ADDRH, (uint32_t) fw.pta.up_queue.head >> 16); |
||||
set(AR9170_PTA_REG_UP_DMA_ADDRL, (uint32_t) fw.pta.up_queue.head & 0xffff); |
||||
|
||||
for (i = 0; i < __AR9170_NUM_TX_QUEUES; i++) |
||||
set_wlan_txq_dma_addr(i, (uint32_t) fw.wlan.tx_queue[i].head); |
||||
|
||||
set(AR9170_MAC_REG_DMA_RXQ_ADDR, (uint32_t) fw.wlan.rx_queue.head); |
||||
fw.usb.int_desc->dataSize = AR9170_BLOCK_SIZE; |
||||
fw.usb.int_desc->dataAddr = (void *) &dma_mem.reserved.rsp; |
||||
|
||||
memset(DESC_PAYLOAD(fw.usb.int_desc), 0xff, |
||||
AR9170_INT_MAGIC_HEADER_SIZE); |
||||
memset(DESC_PAYLOAD_OFF(fw.usb.int_desc, AR9170_INT_MAGIC_HEADER_SIZE), |
||||
0, AR9170_BLOCK_SIZE - AR9170_INT_MAGIC_HEADER_SIZE); |
||||
|
||||
/* rsp is now available for use */ |
||||
fw.usb.int_desc_available = 1; |
||||
|
||||
memset(DESC_PAYLOAD(fw.wlan.fw_desc), 0, 128); |
||||
fw.wlan.fw_desc_available = 1; |
||||
} |
||||
|
||||
/* |
||||
* Free descriptor. |
||||
* |
||||
* Exchange the terminator and the first descriptor of the packet |
||||
* for hardware ascy... |
||||
*/ |
||||
void dma_reclaim(struct dma_queue *q, struct dma_desc *desc) |
||||
{ |
||||
struct dma_desc *tmpDesc, *last; |
||||
struct dma_desc tdesc; |
||||
|
||||
/* 1. Set OWN bit to HW for all TDs to be added, clear ctrl and size */ |
||||
tmpDesc = desc; |
||||
last = desc->lastAddr; |
||||
|
||||
while (1) { |
||||
tmpDesc->status = AR9170_OWN_BITS_HW; |
||||
tmpDesc->ctrl = 0; |
||||
tmpDesc->totalLen = 0; |
||||
tmpDesc->dataSize = AR9170_BLOCK_SIZE; |
||||
|
||||
/* TODO : Exception handle */ |
||||
|
||||
tmpDesc->lastAddr = tmpDesc; |
||||
|
||||
if (tmpDesc == last) |
||||
break; |
||||
|
||||
tmpDesc = tmpDesc->nextAddr; |
||||
} |
||||
|
||||
/* 2. Next address of Last TD to be added = first TD */ |
||||
tmpDesc->nextAddr = desc; |
||||
|
||||
/* Link first TD to self */ |
||||
desc->lastAddr = q->terminator; |
||||
|
||||
/* 3. Copy first TD to be added to TTD */ |
||||
copy_dma_desc(&tdesc, desc); |
||||
|
||||
/* 4. Initialize new terminator */ |
||||
clear_descriptor(desc); |
||||
|
||||
/* 5. Copy TTD to last TD */ |
||||
tdesc.status = 0; |
||||
copy_dma_desc((void *)q->terminator, (void *)&tdesc); |
||||
q->terminator->status |= AR9170_OWN_BITS_HW; |
||||
|
||||
/* Update terminator pointer */ |
||||
q->terminator = desc; |
||||
} |
||||
|
||||
/* |
||||
* Put a complete packet into the tail of the Queue q. |
||||
* Exchange the terminator and the first descriptor of the packet |
||||
* for hardware ascy... |
||||
*/ |
||||
void dma_put(struct dma_queue *q, struct dma_desc *desc) |
||||
{ |
||||
struct dma_desc *tmpDesc; |
||||
struct dma_desc tdesc; |
||||
|
||||
tmpDesc = desc; |
||||
|
||||
while (1) { |
||||
/* update totalLen */ |
||||
tmpDesc->totalLen = desc->totalLen; |
||||
|
||||
/* 1. Set OWN bit to HW for all TDs to be added */ |
||||
tmpDesc->status = AR9170_OWN_BITS_HW; |
||||
/* TODO : Exception handle */ |
||||
|
||||
tmpDesc->lastAddr = desc->lastAddr; |
||||
|
||||
if (desc->lastAddr == tmpDesc) |
||||
break; |
||||
|
||||
tmpDesc = tmpDesc->nextAddr; |
||||
} |
||||
|
||||
/* 2. Next address of Last TD to be added = first TD */ |
||||
desc->lastAddr->nextAddr = desc; |
||||
|
||||
/* If there is only one descriptor, update pointer of last descriptor */ |
||||
if (desc->lastAddr == desc) |
||||
desc->lastAddr = q->terminator; |
||||
|
||||
/* 3. Copy first TD to be added to TTD */ |
||||
copy_dma_desc(&tdesc, desc); |
||||
|
||||
/* 4. Initialize new terminator */ |
||||
clear_descriptor(desc); |
||||
|
||||
/* 5. Copy TTD to last TD */ |
||||
tdesc.status &= (~AR9170_OWN_BITS); |
||||
copy_dma_desc((void *)q->terminator, (void *)&tdesc); |
||||
q->terminator->status |= AR9170_OWN_BITS_HW; |
||||
|
||||
/* Update terminator pointer */ |
||||
q->terminator = desc; |
||||
} |
||||
|
||||
struct dma_desc *dma_unlink_head(struct dma_queue *queue) |
||||
{ |
||||
struct dma_desc *desc; |
||||
|
||||
if (queue_empty(queue)) |
||||
return NULL; |
||||
|
||||
desc = queue->head; |
||||
|
||||
queue->head = desc->lastAddr->nextAddr; |
||||
|
||||
/* poison nextAddr address */ |
||||
desc->lastAddr->nextAddr = desc->lastAddr; |
||||
desc->lastAddr->lastAddr = desc->lastAddr; |
||||
|
||||
return desc; |
||||
} |
@ -0,0 +1,116 @@
@@ -0,0 +1,116 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Firmware descriptor |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
#include "carl9170.h" |
||||
#include "fwdsc.h" |
||||
|
||||
#define FILL(small, big, more...) \ |
||||
.small = { \ |
||||
CARL9170FW_FILL_DESC(big##_MAGIC, \ |
||||
sizeof(struct carl9170fw_## small##_desc), \ |
||||
CARL9170FW_## big##_DESC_MIN_VER, \ |
||||
CARL9170FW_## big##_DESC_CUR_VER), \ |
||||
more \ |
||||
} |
||||
|
||||
const struct carl9170_firmware_descriptor __section(fwdsc) carl9170fw_desc = { |
||||
FILL(otus, OTUS, |
||||
.feature_set = cpu_to_le32(BIT(CARL9170FW_DUMMY_FEATURE) | |
||||
BIT(CARL9170FW_USB_RESP_EP2) | |
||||
BIT(CARL9170FW_HANDLE_BACK_REQ) | |
||||
BIT(CARL9170FW_RX_FILTER) | |
||||
BIT(CARL9170FW_HW_COUNTERS) | |
||||
BIT(CARL9170FW_RX_BA_FILTER) | |
||||
BIT(CARL9170FW_USB_INIT_FIRMWARE) | |
||||
#ifdef CONFIG_CARL9170FW_USB_UP_STREAM |
||||
BIT(CARL9170FW_USB_UP_STREAM) | |
||||
#endif /* CONFIG_CARL9170FW_USB_UP_STREAM */ |
||||
#ifdef CONFIG_CARL9170FW_USB_DOWN_STREAM |
||||
BIT(CARL9170FW_USB_DOWN_STREAM) | |
||||
#endif /* CONFIG_CARL9170FW_USB_DOWN_STREAM */ |
||||
#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS |
||||
BIT(CARL9170FW_COMMAND_PHY) | |
||||
BIT(CARL9170FW_PSM) | |
||||
BIT(CARL9170FW_FIXED_5GHZ_PSM) | |
||||
#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ |
||||
#ifdef CONFIG_CARL9170FW_SECURITY_ENGINE |
||||
BIT(CARL9170FW_COMMAND_CAM) | |
||||
#endif /* CONFIG_CARL9170FW_SECURITY_ENGINE */ |
||||
#ifdef CONFIG_CARL9170FW_CAB_QUEUE |
||||
BIT(CARL9170FW_WLANTX_CAB) | |
||||
#endif /* CONFIG_CARL9170FW_CAB_QUEUE */ |
||||
#ifdef CONFIG_CARL9170FW_UNUSABLE |
||||
BIT(CARL9170FW_UNUSABLE) | |
||||
#endif /* CONFIG_CARL9170FW_UNUSABLE */ |
||||
#ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT |
||||
BIT(CARL9170FW_GPIO_INTERRUPT) | |
||||
#endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ |
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
BIT(CARL9170FW_WOL) | |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
(0)), |
||||
|
||||
.miniboot_size = cpu_to_le16(0), |
||||
.tx_descs = AR9170_TX_BLOCK_NUMBER, |
||||
.cmd_bufs = CARL9170_INT_RQ_CACHES, |
||||
.rx_max_frame_len = cpu_to_le16(CONFIG_CARL9170FW_RX_FRAME_LEN), |
||||
.tx_frag_len = cpu_to_le16(AR9170_BLOCK_SIZE), |
||||
.fw_address = cpu_to_le32(AR9170_PRAM_OFFSET), |
||||
.bcn_addr = (__le32) cpu_to_le32(&dma_mem.reserved.bcn), |
||||
.bcn_len = (__le16) cpu_to_le16(sizeof(dma_mem.reserved.bcn)), |
||||
.vif_num = CARL9170_INTF_NUM, |
||||
.api_ver = CONFIG_CARL9170FW_RELEASE_VERSION, |
||||
), |
||||
|
||||
FILL(txsq, TXSQ, |
||||
.seq_table_addr = cpu_to_le32(&fw.wlan.sequence), |
||||
), |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
FILL(wol, WOL, |
||||
.supported_triggers = BIT(CARL9170_WOL_DISCONNECT) | |
||||
BIT(CARL9170_WOL_MAGIC_PKT), |
||||
), |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
|
||||
|
||||
FILL(motd, MOTD, |
||||
.fw_year_month_day = cpu_to_le32( |
||||
CARL9170FW_SET_DAY(CARL9170FW_VERSION_DAY) + |
||||
CARL9170FW_SET_MONTH(CARL9170FW_VERSION_MONTH) + |
||||
CARL9170FW_SET_YEAR(CARL9170FW_VERSION_YEAR)), |
||||
.desc = "Community AR9170 Linux", |
||||
.release = CARL9170FW_VERSION_GIT), |
||||
|
||||
FILL(dbg, DBG, |
||||
.bogoclock_addr = cpu_to_le32(0), |
||||
.counter_addr = cpu_to_le32(&fw.counter), |
||||
.rx_total_addr = cpu_to_le32(0), |
||||
.rx_overrun_addr = cpu_to_le32(0), |
||||
.rx_filter = cpu_to_le32(&fw.wlan.rx_filter), |
||||
), |
||||
|
||||
FILL(last, LAST), |
||||
}; |
||||
|
||||
#undef FILL |
||||
|
||||
struct firmware_context_struct fw; |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* GPIO interrupt service |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "gpio.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT |
||||
void gpio_timer(void) |
||||
{ |
||||
uint32_t cur; |
||||
|
||||
cur = get(AR9170_GPIO_REG_PORT_DATA) & CARL9170_GPIO_MASK; |
||||
|
||||
if (cur != fw.cached_gpio_state.gpio) { |
||||
fw.cached_gpio_state.gpio = cur; |
||||
|
||||
send_cmd_to_host(sizeof(struct carl9170_gpio), |
||||
CARL9170_RSP_GPIO, 0x00, |
||||
(uint8_t *)&fw.cached_gpio_state); |
||||
|
||||
# ifdef CONFIG_CARL9170FW_WATCHDOG_BUTTON |
||||
for (;;) { |
||||
/* |
||||
* Loop forever... Until the watchdog triggers. |
||||
*/ |
||||
} |
||||
# endif /* CONFIG_CARL9170FW_WATCHDOG_BUTTON */ |
||||
} |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ |
@ -0,0 +1,165 @@
@@ -0,0 +1,165 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Host interface routines |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "hostif.h" |
||||
#include "printf.h" |
||||
#include "wl.h" |
||||
|
||||
static bool length_check(struct dma_desc *desc) |
||||
{ |
||||
volatile struct carl9170_tx_superframe *super = __get_super(desc); |
||||
|
||||
if (unlikely(desc->totalLen < sizeof(struct carl9170_tx_superdesc))) |
||||
return false; |
||||
|
||||
/* |
||||
* check if the DMA is complete, or clipped. |
||||
* |
||||
* NB: The hardware aligns the descriptor length to |
||||
* a 4 byte boundary. This makes the direct comparison |
||||
* difficult, or unnecessary complex for a hot-path. |
||||
*/ |
||||
if (unlikely(super->s.len > desc->totalLen)) |
||||
return false; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
static void handle_download(void) |
||||
{ |
||||
struct dma_desc *desc; |
||||
|
||||
/* |
||||
* Under normal conditions, all completed descs should have |
||||
* the AR9170_OWN_BITS_SE status flag set. |
||||
* However there seems to be a undocumented case where the flag |
||||
* is _SW ( handle_download_exception ) |
||||
*/ |
||||
|
||||
for_each_desc_not_bits(desc, &fw.pta.down_queue, AR9170_OWN_BITS_HW) { |
||||
if (unlikely((length_check(desc) == false))) { |
||||
/* |
||||
* There is no easy way of telling what was lost. |
||||
* |
||||
* Therefore we just reclaim the data. |
||||
* The driver has to have some sort frame |
||||
* timeout mechanism. |
||||
*/ |
||||
|
||||
wlan_tx_complete(__get_super(desc), false); |
||||
dma_reclaim(&fw.pta.down_queue, desc); |
||||
down_trigger(); |
||||
} else { |
||||
wlan_tx(desc); |
||||
} |
||||
} |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT |
||||
xorl(AR9170_GPIO_REG_PORT_DATA, 2); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */ |
||||
} |
||||
|
||||
static void handle_upload(void) |
||||
{ |
||||
struct dma_desc *desc; |
||||
|
||||
for_each_desc_not_bits(desc, &fw.pta.up_queue, AR9170_OWN_BITS_HW) { |
||||
/* |
||||
* BIG FAT NOTE: |
||||
* |
||||
* DO NOT compare the descriptor addresses. |
||||
*/ |
||||
if (DESC_PAYLOAD(desc) == (void *) &dma_mem.reserved.rsp) { |
||||
fw.usb.int_desc = desc; |
||||
fw.usb.int_desc_available = 1; |
||||
} else { |
||||
dma_reclaim(&fw.wlan.rx_queue, desc); |
||||
wlan_trigger(AR9170_DMA_TRIGGER_RXQ); |
||||
} |
||||
} |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT |
||||
xorl(AR9170_GPIO_REG_PORT_DATA, 2); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */ |
||||
} |
||||
|
||||
static void handle_download_exception(void) |
||||
{ |
||||
struct dma_desc *desc, *target; |
||||
|
||||
/* actually, the queue should be stopped by now? */ |
||||
usb_stop_down_queue(); |
||||
|
||||
target = (void *)((get(AR9170_PTA_REG_DN_CURR_ADDRH) << 16) | |
||||
get(AR9170_PTA_REG_DN_CURR_ADDRL)); |
||||
|
||||
/* |
||||
* Put "forgotten" packets from the head of the queue, back |
||||
* to the current position |
||||
*/ |
||||
__while_desc_bits(desc, &fw.pta.down_queue, AR9170_OWN_BITS_HW) { |
||||
if (desc == target) |
||||
break; |
||||
|
||||
dma_reclaim(&fw.pta.down_queue, |
||||
dma_unlink_head(&fw.pta.down_queue)); |
||||
} |
||||
|
||||
__for_each_desc_continue(desc, &fw.pta.down_queue) { |
||||
if ((desc->status & AR9170_OWN_BITS) == AR9170_OWN_BITS_SW) |
||||
dma_fix_downqueue(desc); |
||||
} |
||||
|
||||
|
||||
usb_start_down_queue(); |
||||
|
||||
down_trigger(); |
||||
} |
||||
|
||||
/* handle interrupts from DMA chip */ |
||||
void handle_host_interface(void) |
||||
{ |
||||
uint32_t pta_int; |
||||
|
||||
pta_int = get(AR9170_PTA_REG_INT_FLAG); |
||||
|
||||
#define HANDLER(intr, flag, func) \ |
||||
do { \ |
||||
if ((intr & flag) != 0) { \ |
||||
func(); \ |
||||
} \ |
||||
} while (0) |
||||
|
||||
HANDLER(pta_int, AR9170_PTA_INT_FLAG_DN, handle_download); |
||||
|
||||
HANDLER(pta_int, AR9170_PTA_INT_FLAG_UP, handle_upload); |
||||
|
||||
/* This is just guesswork and MAGIC */ |
||||
pta_int = get(AR9170_PTA_REG_DMA_STATUS); |
||||
HANDLER(pta_int, 0x1, handle_download_exception); |
||||
|
||||
#undef HANDLER |
||||
} |
@ -0,0 +1,256 @@
@@ -0,0 +1,256 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* initialization and main() loop |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "timer.h" |
||||
#include "hostif.h" |
||||
#include "printf.h" |
||||
#include "gpio.h" |
||||
#include "wl.h" |
||||
#include "rf.h" |
||||
#include "usb.h" |
||||
|
||||
#define AR9170_WATCH_DOG_TIMER 0x100 |
||||
|
||||
static void timer_init(const unsigned int timer, const unsigned int interval) |
||||
{ |
||||
/* Set timer to periodic mode */ |
||||
orl(AR9170_TIMER_REG_CONTROL, BIT(timer)); |
||||
|
||||
/* Set time interval */ |
||||
set(AR9170_TIMER_REG_TIMER0 + (timer << 2), interval - 1); |
||||
|
||||
/* Clear timer interrupt flag */ |
||||
orl(AR9170_TIMER_REG_INTERRUPT, BIT(timer)); |
||||
} |
||||
|
||||
void clock_set(enum cpu_clock_t clock_, bool on) |
||||
{ |
||||
/* |
||||
* Word of Warning! |
||||
* This setting does more than just mess with the CPU Clock. |
||||
* So watch out, if you need _stable_ timer interrupts. |
||||
*/ |
||||
#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS |
||||
if (fw.phy.frequency < 3000000) |
||||
set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); |
||||
else |
||||
set(AR9170_PWR_REG_PLL_ADDAC, 0x5143); |
||||
#else |
||||
set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); |
||||
#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ |
||||
|
||||
fw.ticks_per_usec = GET_VAL(AR9170_PWR_PLL_ADDAC_DIV, |
||||
get(AR9170_PWR_REG_PLL_ADDAC)); |
||||
|
||||
set(AR9170_PWR_REG_CLOCK_SEL, (uint32_t) ((on ? 0x70 : 0x600) | clock_)); |
||||
|
||||
switch (clock_) { |
||||
case AHB_20_22MHZ: |
||||
fw.ticks_per_usec >>= 1; |
||||
case AHB_40MHZ_OSC: |
||||
case AHB_40_44MHZ: |
||||
fw.ticks_per_usec >>= 1; |
||||
case AHB_80_88MHZ: |
||||
break; |
||||
} |
||||
} |
||||
|
||||
static void init(void) |
||||
{ |
||||
led_init(); |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_UART |
||||
uart_init(); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_UART */ |
||||
|
||||
/* 25/50/100ms timer (depends on cpu clock) */ |
||||
timer_init(0, 50000); |
||||
|
||||
/* USB init */ |
||||
usb_init(); |
||||
|
||||
/* initialize DMA memory */ |
||||
memset(&dma_mem, 0, sizeof(dma_mem)); |
||||
|
||||
/* fill DMA rings */ |
||||
dma_init_descriptors(); |
||||
|
||||
/* clear all interrupt */ |
||||
set(AR9170_MAC_REG_INT_CTRL, 0xffff); |
||||
|
||||
orl(AR9170_MAC_REG_AFTER_PNP, 1); |
||||
|
||||
/* Init watch dog control flag */ |
||||
fw.watchdog_enable = 1; |
||||
|
||||
set(AR9170_TIMER_REG_WATCH_DOG, AR9170_WATCH_DOG_TIMER); |
||||
|
||||
#ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT |
||||
fw.cached_gpio_state.gpio = get(AR9170_GPIO_REG_PORT_DATA) & |
||||
CARL9170_GPIO_MASK; |
||||
#endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ |
||||
|
||||
/* this will get the downqueue moving. */ |
||||
down_trigger(); |
||||
} |
||||
|
||||
static void handle_fw(void) |
||||
{ |
||||
if (fw.watchdog_enable == 1) |
||||
set(AR9170_TIMER_REG_WATCH_DOG, AR9170_WATCH_DOG_TIMER); |
||||
|
||||
if (fw.reboot) |
||||
reboot(); |
||||
} |
||||
|
||||
static void timer0_isr(void) |
||||
{ |
||||
wlan_timer(); |
||||
|
||||
#ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT |
||||
gpio_timer(); |
||||
#endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT |
||||
set(AR9170_GPIO_REG_PORT_DATA, get(AR9170_GPIO_REG_PORT_DATA) ^ 1); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */ |
||||
} |
||||
|
||||
static void handle_timer(void) |
||||
{ |
||||
uint32_t intr; |
||||
|
||||
intr = get(AR9170_TIMER_REG_INTERRUPT); |
||||
|
||||
/* ACK timer interrupt */ |
||||
set(AR9170_TIMER_REG_INTERRUPT, intr); |
||||
|
||||
#define HANDLER(intr, flag, func) \ |
||||
do { \ |
||||
if ((intr & flag) != 0) { \ |
||||
intr &= ~flag; \ |
||||
func(); \ |
||||
} \ |
||||
} while (0) |
||||
|
||||
HANDLER(intr, BIT(0), timer0_isr); |
||||
|
||||
if (intr) |
||||
DBG("Unhandled Timer Event %x", (unsigned int) intr); |
||||
|
||||
#undef HANDLER |
||||
} |
||||
|
||||
static void tally_update(void) |
||||
{ |
||||
unsigned int boff, time, delta; |
||||
|
||||
time = get_clock_counter(); |
||||
if (fw.phy.state == CARL9170_PHY_ON) { |
||||
delta = (time - fw.tally_clock); |
||||
|
||||
fw.tally.active += delta; |
||||
|
||||
boff = get(AR9170_MAC_REG_BACKOFF_STATUS); |
||||
if (boff & AR9170_MAC_BACKOFF_TX_PE) |
||||
fw.tally.tx_time += delta; |
||||
if (boff & AR9170_MAC_BACKOFF_CCA) |
||||
fw.tally.cca += delta; |
||||
} |
||||
|
||||
fw.tally_clock = time; |
||||
fw.counter++; |
||||
} |
||||
|
||||
static void __noreturn main_loop(void) |
||||
{ |
||||
/* main loop */ |
||||
while (1) { |
||||
handle_fw(); |
||||
|
||||
/* |
||||
* Due to frame order persevation, the wlan subroutines |
||||
* must be executed before handle_host_interface. |
||||
*/ |
||||
handle_wlan(); |
||||
|
||||
handle_host_interface(); |
||||
|
||||
handle_usb(); |
||||
|
||||
handle_timer(); |
||||
|
||||
tally_update(); |
||||
} |
||||
} |
||||
|
||||
/* |
||||
* The bootcode will work with the device driver to load the firmware |
||||
* onto the device's Program SRAM. The Program SRAM has a size of 16 KB |
||||
* and also contains the stack, which grows down from 0x204000. |
||||
* |
||||
* The Program SRAM starts at address 0x200000 on the device. |
||||
* The firmware entry point (0x200004) is located in boot.S. |
||||
* we put _start() there with the linker script carl9170.lds. |
||||
*/ |
||||
|
||||
void __section(boot) start(void) |
||||
{ |
||||
clock_set(AHB_40MHZ_OSC, true); |
||||
|
||||
/* watchdog magic pattern check */ |
||||
if ((get(AR9170_PWR_REG_WATCH_DOG_MAGIC) & 0xffff0000) == 0x12340000) { |
||||
/* watch dog warm start */ |
||||
incl(AR9170_PWR_REG_WATCH_DOG_MAGIC); |
||||
usb_trigger_out(); |
||||
} else if ((get(AR9170_PWR_REG_WATCH_DOG_MAGIC) & 0xffff0000) == 0x98760000) { |
||||
/* suspend/resume */ |
||||
} |
||||
|
||||
/* write the magic pattern for watch dog */ |
||||
andl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0xFFFF); |
||||
orl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0x12340000); |
||||
|
||||
init(); |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG |
||||
|
||||
BUG("TEST BUG"); |
||||
BUG_ON(0x2b || !0x2b); |
||||
INFO("INFO MESSAGE"); |
||||
|
||||
/* a set of unique characters to detect transfer data corruptions */ |
||||
DBG("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" |
||||
" ~`!1@2#3$4%%5^6&7*8(9)0_-+={[}]|\\:;\"'<,>.?/"); |
||||
#endif /* CONFIG_CARL9170FW_DEBUG */ |
||||
|
||||
/* |
||||
* Tell the host, that the firmware has booted and is |
||||
* now ready to process requests. |
||||
*/ |
||||
send_cmd_to_host(0, CARL9170_RSP_BOOT, 0x00, NULL); |
||||
main_loop(); |
||||
} |
@ -0,0 +1,228 @@
@@ -0,0 +1,228 @@
|
||||
/* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $ |
||||
* |
||||
* "memcpy" implementation of SuperH |
||||
* |
||||
* Copyright (C) 1999 Niibe Yutaka |
||||
* |
||||
*/ |
||||
|
||||
/* |
||||
* void *memcpy(void *dst, const void *src, size_t n); |
||||
* No overlap between the memory of DST and of SRC are assumed. |
||||
*/ |
||||
|
||||
.globl _memcpy |
||||
.align 2 |
||||
_memcpy: |
||||
tst r6,r6 |
||||
bt/s 9f ! if n=0, do nothing |
||||
mov r4,r0 |
||||
sub r4,r5 ! From here, r5 has the distance to r0 |
||||
add r6,r0 ! From here, r0 points the end of copying point |
||||
mov #12,r1 |
||||
cmp/gt r6,r1 |
||||
bt/s 7f ! if it's too small, copy a byte at once |
||||
add #-1,r5 |
||||
add #1,r5 |
||||
! From here, r6 is free |
||||
! |
||||
! r4 --> [ ... ] DST [ ... ] SRC |
||||
! [ ... ] [ ... ] |
||||
! : : |
||||
! r0 --> [ ... ] r0+r5 --> [ ... ] |
||||
! |
||||
! |
||||
mov r5,r1 |
||||
mov #3,r2 |
||||
and r2,r1 |
||||
shll2 r1 |
||||
mov r0,r3 ! Save the value on R0 to R3 |
||||
mova jmptable,r0 |
||||
add r1,r0 |
||||
mov.l @r0,r1 |
||||
jmp @r1 |
||||
mov r3,r0 ! and back to R0 |
||||
.balign 4 |
||||
jmptable: |
||||
.long case0 |
||||
.long case1 |
||||
.long case2 |
||||
.long case3 |
||||
|
||||
! copy a byte at once |
||||
7: mov r4,r2 |
||||
add #1,r2 |
||||
8: |
||||
cmp/hi r2,r0 |
||||
mov.b @(r0,r5),r1 |
||||
bt/s 8b ! while (r0>r2) |
||||
mov.b r1,@-r0 |
||||
9: |
||||
rts |
||||
nop |
||||
|
||||
case0: |
||||
! |
||||
! GHIJ KLMN OPQR --> GHIJ KLMN OPQR |
||||
! |
||||
! First, align to long word boundary |
||||
mov r0,r3 |
||||
and r2,r3 |
||||
tst r3,r3 |
||||
bt/s 2f |
||||
add #-4,r5 |
||||
add #3,r5 |
||||
1: dt r3 |
||||
mov.b @(r0,r5),r1 |
||||
bf/s 1b |
||||
mov.b r1,@-r0 |
||||
! |
||||
add #-3,r5 |
||||
2: ! Second, copy a long word at once |
||||
mov r4,r2 |
||||
add #7,r2 |
||||
3: mov.l @(r0,r5),r1 |
||||
cmp/hi r2,r0 |
||||
bt/s 3b |
||||
mov.l r1,@-r0 |
||||
! |
||||
! Third, copy a byte at once, if necessary |
||||
cmp/eq r4,r0 |
||||
bt/s 9b |
||||
add #3,r5 |
||||
bra 8b |
||||
add #-6,r2 |
||||
|
||||
case1: |
||||
! |
||||
! GHIJ KLMN OPQR --> ...G HIJK LMNO PQR. |
||||
! |
||||
! First, align to long word boundary |
||||
mov r0,r3 |
||||
and r2,r3 |
||||
tst r3,r3 |
||||
bt/s 2f |
||||
add #-1,r5 |
||||
1: dt r3 |
||||
mov.b @(r0,r5),r1 |
||||
bf/s 1b |
||||
mov.b r1,@-r0 |
||||
! |
||||
2: ! Second, read a long word and write a long word at once |
||||
mov.l @(r0,r5),r1 |
||||
add #-4,r5 |
||||
mov r4,r2 |
||||
add #7,r2 |
||||
! |
||||
#ifdef __LITTLE_ENDIAN__ |
||||
3: mov r1,r3 ! RQPO |
||||
shll16 r3 |
||||
shll8 r3 ! Oxxx |
||||
mov.l @(r0,r5),r1 ! NMLK |
||||
mov r1,r6 |
||||
shlr8 r6 ! xNML |
||||
or r6,r3 ! ONML |
||||
cmp/hi r2,r0 |
||||
bt/s 3b |
||||
mov.l r3,@-r0 |
||||
#else |
||||
3: mov r1,r3 ! OPQR |
||||
shlr16 r3 |
||||
shlr8 r3 ! xxxO |
||||
mov.l @(r0,r5),r1 ! KLMN |
||||
mov r1,r6 |
||||
shll8 r6 ! LMNx |
||||
or r6,r3 ! LMNO |
||||
cmp/hi r2,r0 |
||||
bt/s 3b |
||||
mov.l r3,@-r0 |
||||
#endif |
||||
! |
||||
! Third, copy a byte at once, if necessary |
||||
cmp/eq r4,r0 |
||||
bt/s 9b |
||||
add #4,r5 |
||||
bra 8b |
||||
add #-6,r2 |
||||
|
||||
case2: |
||||
! |
||||
! GHIJ KLMN OPQR --> ..GH IJKL MNOP QR.. |
||||
! |
||||
! First, align to word boundary |
||||
tst #1,r0 |
||||
bt/s 2f |
||||
add #-1,r5 |
||||
mov.b @(r0,r5),r1 |
||||
mov.b r1,@-r0 |
||||
! |
||||
2: ! Second, read a word and write a word at once |
||||
add #-1,r5 |
||||
mov r4,r2 |
||||
add #3,r2 |
||||
! |
||||
3: mov.w @(r0,r5),r1 |
||||
cmp/hi r2,r0 |
||||
bt/s 3b |
||||
mov.w r1,@-r0 |
||||
! |
||||
! Third, copy a byte at once, if necessary |
||||
cmp/eq r4,r0 |
||||
bt/s 9b |
||||
add #1,r5 |
||||
mov.b @(r0,r5),r1 |
||||
rts |
||||
mov.b r1,@-r0 |
||||
|
||||
case3: |
||||
! |
||||
! GHIJ KLMN OPQR --> .GHI JKLM NOPQ R... |
||||
! |
||||
! First, align to long word boundary |
||||
mov r0,r3 |
||||
and r2,r3 |
||||
tst r3,r3 |
||||
bt/s 2f |
||||
add #-1,r5 |
||||
1: dt r3 |
||||
mov.b @(r0,r5),r1 |
||||
bf/s 1b |
||||
mov.b r1,@-r0 |
||||
! |
||||
2: ! Second, read a long word and write a long word at once |
||||
add #-2,r5 |
||||
mov.l @(r0,r5),r1 |
||||
add #-4,r5 |
||||
mov r4,r2 |
||||
add #7,r2 |
||||
! |
||||
#ifdef __LITTLE_ENDIAN__ |
||||
3: mov r1,r3 ! RQPO |
||||
shll8 r3 ! QPOx |
||||
mov.l @(r0,r5),r1 ! NMLK |
||||
mov r1,r6 |
||||
shlr16 r6 |
||||
shlr8 r6 ! xxxN |
||||
or r6,r3 ! QPON |
||||
cmp/hi r2,r0 |
||||
bt/s 3b |
||||
mov.l r3,@-r0 |
||||
#else |
||||
3: mov r1,r3 ! OPQR |
||||
shlr8 r3 ! xOPQ |
||||
mov.l @(r0,r5),r1 ! KLMN |
||||
mov r1,r6 |
||||
shll16 r6 |
||||
shll8 r6 ! Nxxx |
||||
or r6,r3 ! NOPQ |
||||
cmp/hi r2,r0 |
||||
bt/s 3b |
||||
mov.l r3,@-r0 |
||||
#endif |
||||
! |
||||
! Third, copy a byte at once, if necessary |
||||
cmp/eq r4,r0 |
||||
bt/s 9b |
||||
add #6,r5 |
||||
bra 8b |
||||
add #-6,r2 |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
/* $Id: memset.S,v 1.1 2000/04/14 16:49:01 mjd Exp $ |
||||
* |
||||
* "memset" implementation of SuperH |
||||
* |
||||
* Copyright (C) 1999 Niibe Yutaka |
||||
* |
||||
*/ |
||||
|
||||
/* |
||||
* void *memset(void *s, int c, size_t n); |
||||
*/ |
||||
|
||||
.globl _memset |
||||
.align 2 |
||||
_memset: |
||||
tst r6,r6 |
||||
bt/s 5f ! if n=0, do nothing |
||||
add r6,r4 |
||||
mov #12,r0 |
||||
cmp/gt r6,r0 |
||||
bt/s 4f ! if it's too small, set a byte at once |
||||
mov r4,r0 |
||||
and #3,r0 |
||||
cmp/eq #0,r0 |
||||
bt/s 2f ! It's aligned |
||||
sub r0,r6 |
||||
1: |
||||
dt r0 |
||||
bf/s 1b |
||||
mov.b r5,@-r4 |
||||
2: ! make VVVV |
||||
extu.b r5,r5 |
||||
swap.b r5,r0 ! V0 |
||||
or r0,r5 ! VV |
||||
swap.w r5,r0 ! VV00 |
||||
or r0,r5 ! VVVV |
||||
! |
||||
mov r6,r0 |
||||
shlr2 r0 |
||||
shlr r0 ! r0 = r6 >> 3 |
||||
3: |
||||
dt r0 |
||||
mov.l r5,@-r4 ! set 8-byte at once |
||||
bf/s 3b |
||||
mov.l r5,@-r4 |
||||
! |
||||
mov #7,r0 |
||||
and r0,r6 |
||||
tst r6,r6 |
||||
bt 5f |
||||
! fill bytes |
||||
4: |
||||
dt r6 |
||||
bf/s 4b |
||||
mov.b r5,@-r4 |
||||
5: |
||||
rts |
||||
mov r4,r0 |
@ -0,0 +1,161 @@
@@ -0,0 +1,161 @@
|
||||
/* |
||||
* Copyright (C) 2004,2008 Kustaa Nyholm |
||||
* |
||||
* This library is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* This library 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 |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with this library; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "printf.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_PRINTF |
||||
static char *bf; |
||||
static char buf[12]; |
||||
static unsigned int num; |
||||
static char uc; |
||||
static char zs; |
||||
|
||||
static void out(const char c) |
||||
{ |
||||
*bf++ = c; |
||||
} |
||||
|
||||
static void outDgt(const char dgt) |
||||
{ |
||||
out(dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10)); |
||||
zs = 1; |
||||
} |
||||
|
||||
static void divOut(const unsigned int d) |
||||
{ |
||||
unsigned char dgt = 0; |
||||
|
||||
while (num >= d) { |
||||
num -= d; |
||||
dgt++; |
||||
} |
||||
|
||||
if (zs || dgt > 0) |
||||
outDgt(dgt); |
||||
} |
||||
|
||||
void tfp_printf(const char *fmt, ...) |
||||
{ |
||||
va_list va; |
||||
char *p; |
||||
unsigned int i; |
||||
char ch; |
||||
|
||||
va_start(va, fmt); |
||||
|
||||
while ((ch = *(fmt++))) { |
||||
if (ch != '%') { |
||||
putcharacter(ch); |
||||
} else { |
||||
char lz = 0; |
||||
char w = 0; |
||||
ch = *(fmt++); |
||||
|
||||
if (ch == '0') { |
||||
ch = *(fmt++); |
||||
lz = 1; |
||||
} |
||||
|
||||
if (ch >= '0' && ch <= '9') { |
||||
w = 0; |
||||
while (ch >= '0' && ch <= '9') { |
||||
w = (((w << 2) + w) << 1) + ch - '0'; |
||||
ch = *fmt++; |
||||
} |
||||
} |
||||
|
||||
bf = buf; |
||||
p = bf; |
||||
zs = 0; |
||||
|
||||
switch (ch) { |
||||
case 0: |
||||
goto abort; |
||||
|
||||
case 'u': |
||||
case 'd': |
||||
num = va_arg(va, unsigned int); |
||||
if (ch == 'd' && (int) num < 0) { |
||||
num = -(int)num; |
||||
out('-'); |
||||
} |
||||
|
||||
for (i = 100000000; i != 1; i /= 10) |
||||
divOut(i); |
||||
|
||||
outDgt(num); |
||||
break; |
||||
|
||||
case 'p': |
||||
case 'x': |
||||
case 'X': |
||||
uc = ch == 'X'; |
||||
num = va_arg(va, unsigned int); |
||||
for (i = 0x10000000; i != 0x1; i >>= 4) |
||||
divOut(i); |
||||
|
||||
outDgt(num); |
||||
break; |
||||
|
||||
case 'c': |
||||
out((char)(va_arg(va, int))); |
||||
break; |
||||
|
||||
case 's': |
||||
p = va_arg(va, char*); |
||||
break; |
||||
case '%': |
||||
out('%'); |
||||
break; |
||||
|
||||
default: |
||||
break; |
||||
} |
||||
|
||||
*bf = 0; |
||||
bf = p; |
||||
while (*bf++ && w > 0) |
||||
w--; |
||||
|
||||
while (w-- > 0) |
||||
putcharacter(lz ? '0' : ' '); |
||||
|
||||
while ((ch = *p++)) |
||||
putcharacter(ch); |
||||
} |
||||
} |
||||
|
||||
abort: |
||||
putcharacter('\0'); |
||||
va_end(va); |
||||
} |
||||
|
||||
#else |
||||
|
||||
void min_printf(const char *fmt, ...) |
||||
{ |
||||
char ch; |
||||
|
||||
do { |
||||
ch = *(fmt++); |
||||
putcharacter(ch); |
||||
} while (ch); |
||||
} |
||||
|
||||
#endif /* CONFIG_CARL9170FW_PRINTF */ |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
.globl _jump_to_bootcode |
||||
.type _jump_to_bootcode, @function |
||||
_jump_to_bootcode: |
||||
mov.l stack_start, r0 |
||||
mov.l @r0, sp |
||||
mov.l eeprom_start, r0 |
||||
mov.l @r0, r0 |
||||
jmp @r0 |
||||
.align 4 |
||||
stack_start: .long 0x00000004 |
||||
eeprom_start: .long 0x00000000 |
@ -0,0 +1,277 @@
@@ -0,0 +1,277 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* PHY and RF functions |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "timer.h" |
||||
#include "printf.h" |
||||
#include "rf.h" |
||||
#include "shared/phy.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS |
||||
static void set_channel_end(void) |
||||
{ |
||||
/* Manipulate CCA threshold to resume transmission */ |
||||
set(AR9170_PHY_REG_CCA_THRESHOLD, 0x0); |
||||
/* Disable Virtual CCA */ |
||||
andl(AR9170_MAC_REG_QOS_PRIORITY_VIRTUAL_CCA, |
||||
~AR9170_MAC_VIRTUAL_CCA_ALL); |
||||
|
||||
fw.phy.state = CARL9170_PHY_ON; |
||||
} |
||||
|
||||
void rf_notify_set_channel(void) |
||||
{ |
||||
/* Manipulate CCA threshold to stop transmission */ |
||||
set(AR9170_PHY_REG_CCA_THRESHOLD, 0x300); |
||||
/* Enable Virtual CCA */ |
||||
orl(AR9170_MAC_REG_QOS_PRIORITY_VIRTUAL_CCA, |
||||
AR9170_MAC_VIRTUAL_CCA_ALL); |
||||
|
||||
/* reset CCA stats */ |
||||
fw.tally.active = 0; |
||||
fw.tally.cca = 0; |
||||
fw.tally.tx_time = 0; |
||||
fw.phy.state = CARL9170_PHY_OFF; |
||||
} |
||||
|
||||
/* |
||||
* Update delta slope coeff man and exp |
||||
*/ |
||||
static void hw_turn_off_dyn(const uint32_t delta_slope_coeff_exp, |
||||
const uint32_t delta_slope_coeff_man, |
||||
const uint32_t delta_slope_coeff_exp_shgi, |
||||
const uint32_t delta_slope_coeff_man_shgi) |
||||
{ |
||||
uint32_t tmp; |
||||
|
||||
tmp = get_async(AR9170_PHY_REG_TIMING3) & 0x00001fff; |
||||
tmp |= (delta_slope_coeff_man << AR9170_PHY_TIMING3_DSC_MAN_S) & |
||||
AR9170_PHY_TIMING3_DSC_MAN; |
||||
tmp |= (delta_slope_coeff_exp << AR9170_PHY_TIMING3_DSC_EXP_S) & |
||||
AR9170_PHY_TIMING3_DSC_EXP; |
||||
|
||||
set(AR9170_PHY_REG_TIMING3, tmp); |
||||
|
||||
tmp = (delta_slope_coeff_man_shgi << AR9170_PHY_HALFGI_DSC_MAN_S) & |
||||
AR9170_PHY_HALFGI_DSC_MAN; |
||||
|
||||
tmp |= (delta_slope_coeff_exp_shgi << AR9170_PHY_HALFGI_DSC_EXP_S) & |
||||
AR9170_PHY_HALFGI_DSC_EXP; |
||||
|
||||
set(AR9170_PHY_REG_HALFGI, tmp); |
||||
} |
||||
|
||||
static void program_ADDAC(void) |
||||
{ |
||||
/* ??? Select Internal ADDAC ??? (is external radio) */ |
||||
set(AR9170_PHY_REG_ADC_SERIAL_CTL, AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO); |
||||
|
||||
delay(10); |
||||
|
||||
set(0x1c589c, 0x00000000); /*# 7-0 */ |
||||
set(0x1c589c, 0x00000000); /*# 15-8 */ |
||||
set(0x1c589c, 0x00000000); /*# 23-16 */ |
||||
set(0x1c589c, 0x00000000); /*# 31- */ |
||||
|
||||
set(0x1c589c, 0x00000000); /*# 39- */ |
||||
set(0x1c589c, 0x00000000); /*# 47- */ |
||||
set(0x1c589c, 0x00000000); /*# 55- [48]:doubles the xtalosc bias current */ |
||||
set(0x1c589c, 0x00000000); /*# 63- */ |
||||
|
||||
set(0x1c589c, 0x00000000); /*# 71- */ |
||||
set(0x1c589c, 0x00000000); /*# 79- */ |
||||
set(0x1c589c, 0x00000000); /*# 87- */ |
||||
set(0x1c589c, 0x00000000); /*# 95- */ |
||||
|
||||
set(0x1c589c, 0x00000000); /*# 103- */ |
||||
set(0x1c589c, 0x00000000); /*# 111- */ |
||||
set(0x1c589c, 0x00000000); /*# 119- */ |
||||
set(0x1c589c, 0x00000000); /*# 127- */ |
||||
|
||||
set(0x1c589c, 0x00000000); /*# 135- */ |
||||
set(0x1c589c, 0x00000000); /*# 143- */ |
||||
set(0x1c589c, 0x00000000); /*# 151- */ |
||||
set(0x1c589c, 0x00000030); /*# 159- #[158:156]=xlnabufmode */ |
||||
|
||||
set(0x1c589c, 0x00000004); /*# 167- [162]:disable clkp_driver to flow */ |
||||
set(0x1c589c, 0x00000000); /*# 175- */ |
||||
set(0x1c589c, 0x00000000); /*# 183-176 */ |
||||
set(0x1c589c, 0x00000000); /*# 191-184 */ |
||||
|
||||
set(0x1c589c, 0x00000000); /*# 199- */ |
||||
set(0x1c589c, 0x00000000); /*# 207- */ |
||||
set(0x1c589c, 0x00000000); /*# 215- */ |
||||
set(0x1c589c, 0x00000000); /*# 223- */ |
||||
|
||||
set(0x1c589c, 0x00000000); /*# 231- */ |
||||
set(0x1c58c4, 0x00000000); /*# 233-232 */ |
||||
|
||||
delay(10); |
||||
|
||||
/* Select External Flow ???? (is internal addac??) */ |
||||
set(AR9170_PHY_REG_ADC_SERIAL_CTL, AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC); |
||||
} |
||||
|
||||
static uint32_t AGC_calibration(uint32_t loop) |
||||
{ |
||||
uint32_t wrdata; |
||||
uint32_t ret; |
||||
|
||||
#define AGC_CAL_NF (AR9170_PHY_AGC_CONTROL_CAL | AR9170_PHY_AGC_CONTROL_NF) |
||||
|
||||
wrdata = get_async(AR9170_PHY_REG_AGC_CONTROL) | AGC_CAL_NF; |
||||
set(AR9170_PHY_REG_AGC_CONTROL, wrdata); |
||||
|
||||
ret = get_async(AR9170_PHY_REG_AGC_CONTROL) & AGC_CAL_NF; |
||||
|
||||
/* sitesurvey : 100 ms / current connected 200 ms */ |
||||
while ((ret != 0) && loop--) { |
||||
udelay(100); |
||||
|
||||
ret = get_async(AR9170_PHY_REG_AGC_CONTROL) & AGC_CAL_NF; |
||||
} |
||||
|
||||
/* return the AGC/Noise calibration state to the driver */ |
||||
return ret; |
||||
} |
||||
|
||||
#define EIGHTY_FLAG (CARL9170FW_PHY_HT_ENABLE | CARL9170FW_PHY_HT_DYN2040) |
||||
|
||||
static uint32_t rf_init(const uint32_t delta_slope_coeff_exp, |
||||
const uint32_t delta_slope_coeff_man, |
||||
const uint32_t delta_slope_coeff_exp_shgi, |
||||
const uint32_t delta_slope_coeff_man_shgi, |
||||
const uint32_t finiteLoopCount, |
||||
const bool initialize) |
||||
{ |
||||
uint32_t ret; |
||||
|
||||
hw_turn_off_dyn(delta_slope_coeff_exp, |
||||
delta_slope_coeff_man, |
||||
delta_slope_coeff_exp_shgi, |
||||
delta_slope_coeff_man_shgi); |
||||
|
||||
if (initialize) { |
||||
/* Real Chip */ |
||||
program_ADDAC(); |
||||
|
||||
/* inverse chain 0 <-> chain 2 */ |
||||
set(AR9170_PHY_REG_ANALOG_SWAP, AR9170_PHY_ANALOG_SWAP_AB); |
||||
|
||||
/* swap chain 0 and chain 2 */ |
||||
set(AR9170_PHY_REG_ANALOG_SWAP, AR9170_PHY_ANALOG_SWAP_AB | |
||||
AR9170_PHY_ANALOG_SWAP_ALT_CHAIN); |
||||
|
||||
/* Activate BB */ |
||||
set(AR9170_PHY_REG_ACTIVE, AR9170_PHY_ACTIVE_EN); |
||||
delay(10); |
||||
} |
||||
|
||||
ret = AGC_calibration(finiteLoopCount); |
||||
|
||||
set_channel_end(); |
||||
return ret; |
||||
} |
||||
|
||||
void rf_cmd(const struct carl9170_cmd *cmd, struct carl9170_rsp *resp) |
||||
{ |
||||
uint32_t ret; |
||||
|
||||
fw.phy.ht_settings = cmd->rf_init.ht_settings; |
||||
fw.phy.frequency = cmd->rf_init.freq; |
||||
|
||||
/* |
||||
* Is the clock controlled by the PHY? |
||||
*/ |
||||
if ((fw.phy.ht_settings & EIGHTY_FLAG) == EIGHTY_FLAG) |
||||
clock_set(AHB_80_88MHZ, true); |
||||
else |
||||
clock_set(AHB_40_44MHZ, true); |
||||
|
||||
ret = rf_init(le32_to_cpu(cmd->rf_init.delta_slope_coeff_exp), |
||||
le32_to_cpu(cmd->rf_init.delta_slope_coeff_man), |
||||
le32_to_cpu(cmd->rf_init.delta_slope_coeff_exp_shgi), |
||||
le32_to_cpu(cmd->rf_init.delta_slope_coeff_man_shgi), |
||||
le32_to_cpu(cmd->rf_init.finiteLoopCount), |
||||
cmd->hdr.cmd == CARL9170_CMD_RF_INIT); |
||||
|
||||
resp->hdr.len = sizeof(struct carl9170_rf_init_result); |
||||
resp->rf_init_res.ret = cpu_to_le32(ret); |
||||
} |
||||
|
||||
void rf_psm(void) |
||||
{ |
||||
u32 bank3; |
||||
|
||||
if (fw.phy.psm.state == CARL9170_PSM_SOFTWARE) { |
||||
/* not enabled by the driver */ |
||||
return; |
||||
} |
||||
|
||||
if (fw.phy.psm.state & CARL9170_PSM_SLEEP) { |
||||
fw.phy.psm.state &= ~CARL9170_PSM_SLEEP; |
||||
|
||||
/* disable all agc gain and offset updates to a2 */ |
||||
set(AR9170_PHY_REG_TEST2, 0x8000000); |
||||
|
||||
/* power down ADDAC */ |
||||
set(AR9170_PHY_REG_ADC_CTL, |
||||
AR9170_PHY_ADC_CTL_OFF_PWDDAC | |
||||
AR9170_PHY_ADC_CTL_OFF_PWDADC | |
||||
0xa0000000); |
||||
|
||||
/* Synthesizer off + RX off */ |
||||
bank3 = 0x00400018; |
||||
|
||||
fw.phy.state = CARL9170_PHY_OFF; |
||||
} else { |
||||
/* advance to the next PSM step */ |
||||
fw.phy.psm.state--; |
||||
|
||||
if (fw.phy.psm.state == CARL9170_PSM_WAKE) { |
||||
/* wake up ADDAC */ |
||||
set(AR9170_PHY_REG_ADC_CTL, |
||||
AR9170_PHY_ADC_CTL_OFF_PWDDAC | |
||||
AR9170_PHY_ADC_CTL_OFF_PWDADC); |
||||
|
||||
/* enable all agc gain and offset updates to a2 */ |
||||
set(AR9170_PHY_REG_TEST2, 0x0); |
||||
|
||||
/* Synthesizer on + RX on */ |
||||
bank3 = 0x01420098; |
||||
|
||||
fw.phy.state = CARL9170_PHY_ON; |
||||
} else { |
||||
return ; |
||||
} |
||||
} |
||||
|
||||
if (fw.phy.frequency < 3000000) |
||||
bank3 |= 0x00800000; |
||||
|
||||
set(0x1c58f0, bank3); |
||||
} |
||||
|
||||
#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ |
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* UART debug interface functions. |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "uart.h" |
||||
#include "io.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_UART |
||||
void uart_putc(const char c) |
||||
{ |
||||
set(AR9170_UART_REG_TX_HOLDING, c); |
||||
|
||||
while (get(AR9170_UART_REG_LINE_STATUS) & |
||||
AR9170_UART_LINE_STS_TX_FIFO_ALMOST_EMPTY) { |
||||
/* |
||||
* wait until the byte has made it |
||||
*/ |
||||
} |
||||
} |
||||
|
||||
void uart_print_hex_dump(const void *buf, const int len) |
||||
{ |
||||
unsigned int offset = 0; |
||||
|
||||
uart_putc('H'); |
||||
uart_putc('D'); |
||||
uart_putc(':'); |
||||
|
||||
while (len > 0) { |
||||
uart_putc(*((uint8_t *) buf + offset)); |
||||
offset++; |
||||
} |
||||
} |
||||
|
||||
void uart_init(void) |
||||
{ |
||||
unsigned int timeout = 0; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_UART_CLOCK_25M |
||||
set(AR9170_UART_REG_DIVISOR_LSB, 0xc); |
||||
#elif CONFIG_CARL9170FW_UART_CLOCK_40M |
||||
set(AR9170_UART_REG_DIVISOR_LSB, 0x14); /* 40 MHz */ |
||||
set(AR9170_UART_REG_REMAINDER, 0xb38e); |
||||
#else |
||||
#error "Unsupported UART clock" |
||||
#endif /* CARL9170FW_UART_CLOCK_25M */ |
||||
|
||||
while (get(AR9170_UART_REG_LINE_STATUS) & |
||||
AR9170_UART_LINE_STS_TRANSMITTER_EMPTY) { |
||||
if (timeout++ >= 10000) |
||||
break; |
||||
} |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_UART */ |
@ -0,0 +1,149 @@
@@ -0,0 +1,149 @@
|
||||
/* Copyright (C) 2006 Free Software Foundation, Inc. |
||||
|
||||
This file 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, or (at your option) any |
||||
later version. |
||||
|
||||
In addition to the permissions in the GNU General Public License, the |
||||
Free Software Foundation gives you unlimited permission to link the |
||||
compiled version of this file into combinations with other programs, |
||||
and to distribute those combinations without any restriction coming |
||||
from the use of this file. (The General Public License restrictions |
||||
do apply in other respects; for example, they cover modification of |
||||
the file, and distribution when not linked into a combine |
||||
executable.) |
||||
|
||||
This file 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; see the file COPYING. If not, write to |
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
||||
Boston, MA 02110-1301, USA. */ |
||||
|
||||
/* Moderately Space-optimized libgcc routines for the Renesas SH / |
||||
STMicroelectronics ST40 CPUs. |
||||
Contributed by J"orn Rennecke joern.rennecke@st.com. */ |
||||
|
||||
/* Size: 186 bytes jointly for udivsi3_i4i and sdivsi3_i4i |
||||
sh4-200 run times: |
||||
udiv small divisor: 55 cycles |
||||
udiv large divisor: 52 cycles |
||||
sdiv small divisor, positive result: 59 cycles |
||||
sdiv large divisor, positive result: 56 cycles |
||||
sdiv small divisor, negative result: 65 cycles (*) |
||||
sdiv large divisor, negative result: 62 cycles (*) |
||||
(*): r2 is restored in the rts delay slot and has a lingering latency |
||||
of two more cycles. */ |
||||
.balign 4 |
||||
.global ___udivsi3_i4i |
||||
.global ___udivsi3_i4 |
||||
.set ___udivsi3_i4, ___udivsi3_i4i |
||||
.type ___udivsi3_i4i, @function |
||||
.type ___sdivsi3_i4i, @function |
||||
___udivsi3_i4i: |
||||
sts pr,r1 |
||||
mov.l r4,@-r15 |
||||
extu.w r5,r0 |
||||
cmp/eq r5,r0 |
||||
swap.w r4,r0 |
||||
shlr16 r4 |
||||
bf/s large_divisor |
||||
div0u |
||||
mov.l r5,@-r15 |
||||
shll16 r5 |
||||
sdiv_small_divisor: |
||||
div1 r5,r4 |
||||
bsr div6 |
||||
div1 r5,r4 |
||||
div1 r5,r4 |
||||
bsr div6 |
||||
div1 r5,r4 |
||||
xtrct r4,r0 |
||||
xtrct r0,r4 |
||||
bsr div7 |
||||
swap.w r4,r4 |
||||
div1 r5,r4 |
||||
bsr div7 |
||||
div1 r5,r4 |
||||
xtrct r4,r0 |
||||
mov.l @r15+,r5 |
||||
swap.w r0,r0 |
||||
mov.l @r15+,r4 |
||||
jmp @r1 |
||||
rotcl r0 |
||||
div7: |
||||
div1 r5,r4 |
||||
div6: |
||||
div1 r5,r4; div1 r5,r4; div1 r5,r4 |
||||
div1 r5,r4; div1 r5,r4; rts; div1 r5,r4 |
||||
|
||||
divx3: |
||||
rotcl r0 |
||||
div1 r5,r4 |
||||
rotcl r0 |
||||
div1 r5,r4 |
||||
rotcl r0 |
||||
rts |
||||
div1 r5,r4 |
||||
|
||||
large_divisor: |
||||
mov.l r5,@-r15 |
||||
sdiv_large_divisor: |
||||
xor r4,r0 |
||||
.rept 4 |
||||
rotcl r0 |
||||
bsr divx3 |
||||
div1 r5,r4 |
||||
.endr |
||||
mov.l @r15+,r5 |
||||
mov.l @r15+,r4 |
||||
jmp @r1 |
||||
rotcl r0 |
||||
|
||||
.global __sdivsi3_i4i |
||||
.global __sdivsi3_i4 |
||||
.global __sdivsi3 |
||||
.set __sdivsi3_i4, __sdivsi3_i4i |
||||
.set __sdivsi3, __sdivsi3_i4i |
||||
__sdivsi3_i4i: |
||||
mov.l r4,@-r15 |
||||
cmp/pz r5 |
||||
mov.l r5,@-r15 |
||||
bt/s pos_divisor |
||||
cmp/pz r4 |
||||
neg r5,r5 |
||||
extu.w r5,r0 |
||||
bt/s neg_result |
||||
cmp/eq r5,r0 |
||||
neg r4,r4 |
||||
pos_result: |
||||
swap.w r4,r0 |
||||
bra sdiv_check_divisor |
||||
sts pr,r1 |
||||
pos_divisor: |
||||
extu.w r5,r0 |
||||
bt/s pos_result |
||||
cmp/eq r5,r0 |
||||
neg r4,r4 |
||||
neg_result: |
||||
mova negate_result,r0 |
||||
; |
||||
mov r0,r1 |
||||
swap.w r4,r0 |
||||
lds r2,macl |
||||
sts pr,r2 |
||||
sdiv_check_divisor: |
||||
shlr16 r4 |
||||
bf/s sdiv_large_divisor |
||||
div0u |
||||
bra sdiv_small_divisor |
||||
shll16 r5 |
||||
.balign 4 |
||||
negate_result: |
||||
neg r0,r0 |
||||
jmp @r2 |
||||
sts macl,r2 |
@ -0,0 +1,287 @@
@@ -0,0 +1,287 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* WakeUp on WLAN functions |
||||
* |
||||
* Copyright 2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "shared/phy.h" |
||||
#include "timer.h" |
||||
#include "wl.h" |
||||
#include "printf.h" |
||||
#include "rf.h" |
||||
#include "wol.h" |
||||
#include "linux/ieee80211.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
|
||||
void wol_cmd(const struct carl9170_wol_cmd *cmd) |
||||
{ |
||||
memcpy(&fw.wol.cmd, cmd, sizeof(cmd)); |
||||
} |
||||
|
||||
void wol_prepare(void) |
||||
{ |
||||
/* set MAC filter */ |
||||
memcpy((void *)AR9170_MAC_REG_MAC_ADDR_L, fw.wol.cmd.mac, 6); |
||||
memcpy((void *)AR9170_MAC_REG_BSSID_L, fw.wol.cmd.bssid, 6); |
||||
set(AR9170_MAC_REG_RX_CONTROL, AR9170_MAC_RX_CTRL_DEAGG); |
||||
|
||||
/* set filter policy to: discard everything */ |
||||
fw.wlan.rx_filter = CARL9170_RX_FILTER_EVERYTHING; |
||||
|
||||
/* reenable rx dma */ |
||||
wlan_trigger(AR9170_DMA_TRIGGER_RXQ); |
||||
|
||||
/* initialize the last_beacon timer */ |
||||
fw.wol.last_null = fw.wol.last_beacon = get_clock_counter(); |
||||
} |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL_NL80211_TRIGGERS |
||||
static bool wlan_rx_wol_magic_packet(const struct ieee80211_hdr *hdr, const unsigned int len) |
||||
{ |
||||
const unsigned char *data, *end, *mac; |
||||
unsigned int found = 0; |
||||
|
||||
/* |
||||
* LIMITATION: |
||||
* We can only scan the first AR9170_BLOCK_SIZE [=~320] bytes |
||||
* for MAGIC patterns! |
||||
*/ |
||||
|
||||
mac = (const unsigned char *) AR9170_MAC_REG_MAC_ADDR_L; |
||||
|
||||
data = (u8 *)((unsigned long)hdr + ieee80211_hdrlen(hdr->frame_control)); |
||||
end = (u8 *)((unsigned long)hdr + len); |
||||
|
||||
/* |
||||
* scan for standard WOL Magic frame |
||||
* |
||||
* "A physical WakeOnLAN (Magic Packet) will look like this: |
||||
* --------------------------------------------------------------- |
||||
* | Synchronization Stream | Target MAC | Password (optional) | |
||||
* | 6 octets | 96 octets | 0, 4 or 6 | |
||||
* --------------------------------------------------------------- |
||||
* |
||||
* The Synchronization Stream is defined as 6 bytes of FFh. |
||||
* The Target MAC block contains 16 duplications of the IEEEaddress |
||||
* of the target, with no breaks or interruptions. |
||||
* |
||||
* The Password field is optional, but if present, contains either |
||||
* 4 bytes or 6 bytes. The WakeOnLAN dissector was implemented to |
||||
* dissect the password, if present, according to the command-line |
||||
* format that ether-wake uses, therefore, if a 4-byte password is |
||||
* present, it will be dissected as an IPv4 address and if a 6-byte |
||||
* password is present, it will be dissected as an Ethernet address. |
||||
* |
||||
* <http://wiki.wireshark.org/WakeOnLAN> |
||||
*/ |
||||
|
||||
while (data < end) { |
||||
if (found >= 6) { |
||||
if (*data == mac[found % 6]) |
||||
found++; |
||||
else |
||||
found = 0; |
||||
} |
||||
|
||||
/* previous check might reset found counter */ |
||||
if (found < 6) { |
||||
if (*data == 0xff) |
||||
found++; |
||||
else |
||||
found = 0; |
||||
} |
||||
|
||||
if (found == (6 + 16 * 6)) |
||||
return true; |
||||
|
||||
data++; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
static void wlan_wol_connect_callback(void __unused *dummy, bool success) |
||||
{ |
||||
if (success) |
||||
fw.wol.lost_null = 0; |
||||
else |
||||
fw.wol.lost_null++; |
||||
} |
||||
|
||||
static void wlan_wol_connection_monitor(void) |
||||
{ |
||||
struct carl9170_tx_null_superframe *nullf = &dma_mem.reserved.cmd.null; |
||||
struct ieee80211_hdr *null = (struct ieee80211_hdr *) &nullf->f.null; |
||||
|
||||
if (!fw.wlan.fw_desc_available) |
||||
return; |
||||
|
||||
memset(nullf, 0, sizeof(*nullf)); |
||||
|
||||
nullf->s.len = sizeof(struct carl9170_tx_superdesc) + |
||||
sizeof(struct ar9170_tx_hwdesc) + |
||||
sizeof(struct ieee80211_hdr); |
||||
nullf->s.ri[0].tries = 3; |
||||
nullf->s.assign_seq = true; |
||||
nullf->s.queue = AR9170_TXQ_VO; |
||||
nullf->f.hdr.length = sizeof(struct ieee80211_hdr) + FCS_LEN; |
||||
|
||||
nullf->f.hdr.mac.backoff = 1; |
||||
nullf->f.hdr.mac.hw_duration = 1; |
||||
nullf->f.hdr.mac.erp_prot = AR9170_TX_MAC_PROT_RTS; |
||||
|
||||
nullf->f.hdr.phy.modulation = AR9170_TX_PHY_MOD_OFDM; |
||||
nullf->f.hdr.phy.bandwidth = AR9170_TX_PHY_BW_20MHZ; |
||||
nullf->f.hdr.phy.chains = AR9170_TX_PHY_TXCHAIN_2; |
||||
nullf->f.hdr.phy.tx_power = 29; /* 14.5 dBm */ |
||||
nullf->f.hdr.phy.mcs = AR9170_TXRX_PHY_RATE_OFDM_6M; |
||||
|
||||
/* format outgoing nullfunc */ |
||||
null->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | |
||||
IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS); |
||||
|
||||
memcpy(null->addr1, fw.wol.cmd.bssid, 6); |
||||
memcpy(null->addr2, fw.wol.cmd.mac, 6); |
||||
memcpy(null->addr3, fw.wol.cmd.bssid, 6); |
||||
|
||||
wlan_tx_fw(&nullf->s, wlan_wol_connect_callback); |
||||
} |
||||
|
||||
static bool wlan_rx_wol_disconnect(const unsigned int rx_filter, |
||||
const struct ieee80211_hdr *hdr, |
||||
const unsigned int __unused len) |
||||
{ |
||||
const unsigned char *bssid; |
||||
bssid = (const unsigned char *) AR9170_MAC_REG_BSSID_L; |
||||
|
||||
/* should catch both broadcast and unicast MLMEs */ |
||||
if (!(rx_filter & CARL9170_RX_FILTER_OTHER_RA)) { |
||||
if (ieee80211_is_deauth(hdr->frame_control) || |
||||
ieee80211_is_disassoc(hdr->frame_control)) |
||||
return true; |
||||
} |
||||
|
||||
if (ieee80211_is_beacon(hdr->frame_control) && |
||||
compare_ether_address(hdr->addr3, bssid)) { |
||||
fw.wol.last_beacon = get_clock_counter(); |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
#endif /* CARL9170FW_WOL_NL80211_TRIGGERS */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL_PROBE_REQUEST |
||||
|
||||
/* |
||||
* Note: CONFIG_CARL9170FW_WOL_PROBE_REQUEST_SSID is not a real |
||||
* string. We have to be careful not to add a \0 at the end. |
||||
*/ |
||||
static const struct { |
||||
u8 ssid_ie; |
||||
u8 ssid_len; |
||||
u8 ssid[sizeof(CONFIG_CARL9170FW_WOL_PROBE_REQUEST_SSID) - 1]; |
||||
} __packed probe_req = { |
||||
.ssid_ie = WLAN_EID_SSID, |
||||
.ssid_len = sizeof(CONFIG_CARL9170FW_WOL_PROBE_REQUEST_SSID) - 1, |
||||
.ssid = CONFIG_CARL9170FW_WOL_PROBE_REQUEST_SSID, |
||||
}; |
||||
|
||||
static bool wlan_rx_wol_probe_ssid(const struct ieee80211_hdr *hdr, const unsigned int len) |
||||
{ |
||||
const unsigned char *data, *end, *scan = (void *) &probe_req; |
||||
|
||||
/* |
||||
* IEEE 802.11-2007 7.3.2.1 specifies that the SSID is no |
||||
* longer than 32 octets. |
||||
*/ |
||||
BUILD_BUG_ON((sizeof(CONFIG_CARL9170FW_WOL_PROBE_REQUEST_SSID) - 1) > 32); |
||||
|
||||
if (ieee80211_is_probe_req(hdr->frame_control)) { |
||||
unsigned int i; |
||||
end = (u8 *)((unsigned long)hdr + len); |
||||
|
||||
/* |
||||
* The position of the SSID information element inside |
||||
* a probe request frame is more or less "fixed". |
||||
*/ |
||||
data = (u8 *)((struct ieee80211_mgmt *)hdr)->u.probe_req.variable; |
||||
for (i = 0; i < (unsigned int)(probe_req.ssid_len + 1); i++) { |
||||
if (data > end || scan[i] != data[i]) |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_WOL_PROBE_REQUEST */ |
||||
|
||||
void wol_rx(const unsigned int rx_filter __unused, const struct ieee80211_hdr *hdr __unused, const unsigned int len __unused) |
||||
{ |
||||
#ifdef CONFIG_CARL9170FW_WOL_NL80211_TRIGGERS |
||||
/* Disconnect is always enabled */ |
||||
if (fw.wol.cmd.flags & CARL9170_WOL_DISCONNECT && |
||||
rx_filter & CARL9170_RX_FILTER_MGMT) |
||||
fw.wol.wake_up |= wlan_rx_wol_disconnect(rx_filter, hdr, len); |
||||
|
||||
if (fw.wol.cmd.flags & CARL9170_WOL_MAGIC_PKT && |
||||
rx_filter & CARL9170_RX_FILTER_DATA) |
||||
fw.wol.wake_up |= wlan_rx_wol_magic_packet(hdr, len); |
||||
#endif /* CONFIG_CARL9170FW_WOL_NL80211_TRIGGERS */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL_PROBE_REQUEST |
||||
if (rx_filter & CARL9170_RX_FILTER_MGMT) |
||||
fw.wol.wake_up |= wlan_rx_wol_probe_ssid(hdr, len); |
||||
#endif /* CONFIG_CARL9170FW_WOL_PROBE_REQUEST */ |
||||
} |
||||
|
||||
void wol_janitor(void) |
||||
{ |
||||
if (unlikely(fw.suspend_mode == CARL9170_HOST_SUSPENDED)) { |
||||
#ifdef CONFIG_CARL9170FW_WOL_NL80211_TRIGGERS |
||||
if (fw.wol.cmd.flags & CARL9170_WOL_DISCONNECT) { |
||||
/* |
||||
* connection lost after 10sec without receiving |
||||
* a beacon |
||||
*/ |
||||
if (is_after_msecs(fw.wol.last_beacon, 10000)) |
||||
fw.wol.wake_up |= true; |
||||
|
||||
if (fw.wol.cmd.null_interval && |
||||
is_after_msecs(fw.wol.last_null, fw.wol.cmd.null_interval)) |
||||
wlan_wol_connection_monitor(); |
||||
|
||||
if (fw.wol.lost_null >= 5) |
||||
fw.wol.wake_up |= true; |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_WOL_NL80211_TRIGGERS */ |
||||
|
||||
if (fw.wol.wake_up) { |
||||
fw.suspend_mode = CARL9170_AWAKE_HOST; |
||||
set(AR9170_USB_REG_WAKE_UP, AR9170_USB_WAKE_UP_WAKE); |
||||
} |
||||
} |
||||
} |
||||
#else |
||||
|
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
menu "USB Firmware Configuration Settings" |
||||
|
||||
config CARL9170FW_USB_STANDARD_CMDS |
||||
def_bool y |
||||
prompt "Basic USB Interface" |
||||
---help--- |
||||
Allows the device to be queried about Standard USB 2.0 Device |
||||
Description Descriptors. |
||||
|
||||
Say Y, unless you don't care if lsusb -v fails. |
||||
|
||||
config CARL9170FW_USB_UP_STREAM |
||||
def_bool y |
||||
prompt "USB Upload Stream" |
||||
---help--- |
||||
This features allows the USB silicon to combine small, single |
||||
frames into bigger transfers. This can help to reduce |
||||
some per-transfer overhead in the application. |
||||
|
||||
Say Y, unless you have experienced strange rx corruptions. |
||||
|
||||
config CARL9170FW_USB_DN_STREAM |
||||
def_bool n |
||||
prompt "USB Download Stream" |
||||
|
||||
config CARL9170FW_DEBUG_USB |
||||
def_bool y |
||||
prompt "Pass debug messages through USB transport" |
||||
---help--- |
||||
Report all firmware messages through the USB transport. |
||||
But there is a catch: In case of a BUG, the USB transport |
||||
needs to be functional, otherwise the application won't |
||||
receive anything. |
||||
|
||||
Say Y. |
||||
|
||||
endmenu |
@ -0,0 +1,206 @@
@@ -0,0 +1,206 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
#include "printf.h" |
||||
#include "rom.h" |
||||
#include "usb_fifo.h" |
||||
|
||||
/* TODO / TOTEST */ |
||||
#ifdef CONFIG_CARL9170FW_USB_MODESWITCH |
||||
static inline void usb_ep_map(const uint8_t ep, const uint8_t map) |
||||
{ |
||||
setb(AR9170_USB_REG_EP_MAP + (ep - 1), map); |
||||
} |
||||
|
||||
static inline void usb_fifo_map(const uint8_t fifo, const uint8_t map) |
||||
{ |
||||
setb(AR9170_USB_REG_FIFO_MAP + (fifo - 1), map); |
||||
} |
||||
|
||||
static inline void usb_fifo_config(const uint8_t fifo, const uint8_t cfg) |
||||
{ |
||||
setb(AR9170_USB_REG_FIFO_CONFIG + (fifo - 1), cfg); |
||||
} |
||||
|
||||
static inline void usb_ep_packet_size_hi(const uint8_t ep, const uint8_t dir, |
||||
const uint16_t size) |
||||
{ |
||||
setb(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (((dir * 0x20) + ep) << 1), |
||||
(size >> 8) & 0xf); |
||||
} |
||||
|
||||
static inline void usb_ep_packet_size_lo(const uint8_t ep, const uint8_t dir, |
||||
const uint16_t size) |
||||
{ |
||||
setb(AR9170_USB_REG_EP_IN_MAX_SIZE_LOW + (((dir * 0x20) + ep) << 1), |
||||
size & 0xff); |
||||
} |
||||
|
||||
static void usb_ep_in_highbandset(const uint8_t ep, const uint8_t dir, |
||||
const uint16_t size) |
||||
{ |
||||
andb(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (ep << 1), ~(BIT(6) | BIT(5))); |
||||
|
||||
switch (dir) { |
||||
case DIRECTION_IN: |
||||
setb(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (ep << 1), |
||||
((size >> 11) + 1) << 5); |
||||
break; |
||||
case DIRECTION_OUT: |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/* |
||||
* vUsbFIFO_EPxCfg_HS(void) |
||||
* Description: |
||||
* 1. Configure the FIFO and EPx map |
||||
* input: none |
||||
* output: none |
||||
*/ |
||||
|
||||
void usb_init_highspeed_fifo_cfg(void) |
||||
{ |
||||
int i; |
||||
|
||||
/* EP 1 */ |
||||
usb_ep_map(1, HS_C1_I0_A0_EP1_MAP); |
||||
usb_fifo_map(HS_C1_I0_A0_EP1_FIFO_START, HS_C1_I0_A0_EP1_FIFO_MAP); |
||||
usb_fifo_config(HS_C1_I0_A0_EP1_FIFO_START, HS_C1_I0_A0_EP1_FIFO_CONFIG); |
||||
|
||||
for (i = HS_C1_I0_A0_EP1_FIFO_START + 1; |
||||
i < HS_C1_I0_A0_EP1_FIFO_START + HS_C1_I0_A0_EP1_FIFO_NO; i++) { |
||||
usb_fifo_config(i, (HS_C1_I0_A0_EP1_FIFO_CONFIG & (~BIT(7)))); |
||||
} |
||||
|
||||
usb_ep_packet_size_hi(1, HS_C1_I0_A0_EP1_DIRECTION, (HS_C1_I0_A0_EP1_MAX_PACKET & 0x7ff)); |
||||
usb_ep_packet_size_lo(1, HS_C1_I0_A0_EP1_DIRECTION, (HS_C1_I0_A0_EP1_MAX_PACKET & 0x7ff)); |
||||
usb_ep_in_highbandset(1, HS_C1_I0_A0_EP1_DIRECTION, HS_C1_I0_A0_EP1_MAX_PACKET); |
||||
|
||||
/* EP 2 */ |
||||
usb_ep_map(2, HS_C1_I0_A0_EP2_MAP); |
||||
usb_fifo_map(HS_C1_I0_A0_EP2_FIFO_START, HS_C1_I0_A0_EP2_FIFO_MAP); |
||||
usb_fifo_config(HS_C1_I0_A0_EP2_FIFO_START, HS_C1_I0_A0_EP2_FIFO_CONFIG); |
||||
|
||||
for (i = HS_C1_I0_A0_EP2_FIFO_START + 1; |
||||
i < HS_C1_I0_A0_EP2_FIFO_START + HS_C1_I0_A0_EP2_FIFO_NO; i++) { |
||||
usb_fifo_config(i, (HS_C1_I0_A0_EP2_FIFO_CONFIG & (~BIT(7)))); |
||||
} |
||||
|
||||
usb_ep_packet_size_hi(2, HS_C1_I0_A0_EP2_DIRECTION, (HS_C1_I0_A0_EP2_MAX_PACKET & 0x7ff)); |
||||
usb_ep_packet_size_lo(2, HS_C1_I0_A0_EP2_DIRECTION, (HS_C1_I0_A0_EP2_MAX_PACKET & 0x7ff)); |
||||
usb_ep_in_highbandset(2, HS_C1_I0_A0_EP2_DIRECTION, HS_C1_I0_A0_EP2_MAX_PACKET); |
||||
|
||||
/* EP 3 */ |
||||
usb_ep_map(3, HS_C1_I0_A0_EP3_MAP); |
||||
usb_fifo_map(HS_C1_I0_A0_EP3_FIFO_START, HS_C1_I0_A0_EP3_FIFO_MAP); |
||||
usb_fifo_config(HS_C1_I0_A0_EP3_FIFO_START, HS_C1_I0_A0_EP3_FIFO_CONFIG); |
||||
|
||||
for (i = HS_C1_I0_A0_EP3_FIFO_START + 1; |
||||
i < HS_C1_I0_A0_EP3_FIFO_START + HS_C1_I0_A0_EP3_FIFO_NO; i++) { |
||||
usb_fifo_config(i, (HS_C1_I0_A0_EP3_FIFO_CONFIG & (~BIT(7)))); |
||||
} |
||||
|
||||
usb_ep_packet_size_hi(3, HS_C1_I0_A0_EP3_DIRECTION, (HS_C1_I0_A0_EP3_MAX_PACKET & 0x7ff)); |
||||
usb_ep_packet_size_lo(3, HS_C1_I0_A0_EP3_DIRECTION, (HS_C1_I0_A0_EP3_MAX_PACKET & 0x7ff)); |
||||
usb_ep_in_highbandset(3, HS_C1_I0_A0_EP3_DIRECTION, HS_C1_I0_A0_EP3_MAX_PACKET); |
||||
|
||||
/* EP 4 */ |
||||
usb_ep_map(4, HS_C1_I0_A0_EP4_MAP); |
||||
usb_fifo_map(HS_C1_I0_A0_EP4_FIFO_START, HS_C1_I0_A0_EP4_FIFO_MAP); |
||||
usb_fifo_config(HS_C1_I0_A0_EP4_FIFO_START, HS_C1_I0_A0_EP4_FIFO_CONFIG); |
||||
|
||||
for (i = HS_C1_I0_A0_EP4_FIFO_START + 1; |
||||
i < HS_C1_I0_A0_EP4_FIFO_START + HS_C1_I0_A0_EP4_FIFO_NO; i++) { |
||||
usb_fifo_config(i, (HS_C1_I0_A0_EP4_FIFO_CONFIG & (~BIT(7)))); |
||||
} |
||||
|
||||
usb_ep_packet_size_hi(4, HS_C1_I0_A0_EP4_DIRECTION, (HS_C1_I0_A0_EP4_MAX_PACKET & 0x7ff)); |
||||
usb_ep_packet_size_lo(4, HS_C1_I0_A0_EP4_DIRECTION, (HS_C1_I0_A0_EP4_MAX_PACKET & 0x7ff)); |
||||
usb_ep_in_highbandset(4, HS_C1_I0_A0_EP4_DIRECTION, HS_C1_I0_A0_EP4_MAX_PACKET); |
||||
} |
||||
|
||||
void usb_init_fullspeed_fifo_cfg(void) |
||||
{ |
||||
int i; |
||||
|
||||
/* EP 1 */ |
||||
usb_ep_map(1, FS_C1_I0_A0_EP1_MAP); |
||||
usb_fifo_map(FS_C1_I0_A0_EP1_FIFO_START, FS_C1_I0_A0_EP1_FIFO_MAP); |
||||
usb_fifo_config(FS_C1_I0_A0_EP1_FIFO_START, FS_C1_I0_A0_EP1_FIFO_CONFIG); |
||||
|
||||
for (i = FS_C1_I0_A0_EP1_FIFO_START + 1; |
||||
i < FS_C1_I0_A0_EP1_FIFO_START + FS_C1_I0_A0_EP1_FIFO_NO; i++) { |
||||
usb_fifo_config(i, (FS_C1_I0_A0_EP1_FIFO_CONFIG & (~BIT(7)))); |
||||
} |
||||
|
||||
usb_ep_packet_size_hi(1, FS_C1_I0_A0_EP1_DIRECTION, (FS_C1_I0_A0_EP1_MAX_PACKET & 0x7ff)); |
||||
usb_ep_packet_size_lo(1, FS_C1_I0_A0_EP1_DIRECTION, (FS_C1_I0_A0_EP1_MAX_PACKET & 0x7ff)); |
||||
/* ``.JWEI 2003/04/29 */ |
||||
usb_ep_in_highbandset(1, FS_C1_I0_A0_EP1_DIRECTION, FS_C1_I0_A0_EP1_MAX_PACKET); |
||||
|
||||
/* EP 2 */ |
||||
usb_ep_map(2, FS_C1_I0_A0_EP2_MAP); |
||||
usb_fifo_map(FS_C1_I0_A0_EP2_FIFO_START, FS_C1_I0_A0_EP2_FIFO_MAP); |
||||
usb_fifo_config(FS_C1_I0_A0_EP2_FIFO_START, FS_C1_I0_A0_EP2_FIFO_CONFIG); |
||||
|
||||
for (i = FS_C1_I0_A0_EP2_FIFO_START + 1; |
||||
i < FS_C1_I0_A0_EP2_FIFO_START + FS_C1_I0_A0_EP2_FIFO_NO; i++) { |
||||
usb_fifo_config(i, (FS_C1_I0_A0_EP2_FIFO_CONFIG & (~BIT(7)))); |
||||
} |
||||
|
||||
usb_ep_packet_size_hi(2, FS_C1_I0_A0_EP2_DIRECTION, (FS_C1_I0_A0_EP2_MAX_PACKET & 0x7ff)); |
||||
usb_ep_packet_size_lo(2, FS_C1_I0_A0_EP2_DIRECTION, (FS_C1_I0_A0_EP2_MAX_PACKET & 0x7ff)); |
||||
usb_ep_in_highbandset(2, FS_C1_I0_A0_EP2_DIRECTION, FS_C1_I0_A0_EP2_MAX_PACKET); |
||||
|
||||
/* EP 3 */ |
||||
usb_ep_map(3, FS_C1_I0_A0_EP3_MAP); |
||||
usb_fifo_map(FS_C1_I0_A0_EP3_FIFO_START, FS_C1_I0_A0_EP3_FIFO_MAP); |
||||
usb_fifo_config(FS_C1_I0_A0_EP3_FIFO_START, FS_C1_I0_A0_EP3_FIFO_CONFIG); |
||||
|
||||
for (i = FS_C1_I0_A0_EP3_FIFO_START + 1; |
||||
i < FS_C1_I0_A0_EP3_FIFO_START + FS_C1_I0_A0_EP3_FIFO_NO; i++) { |
||||
usb_fifo_config(i, (FS_C1_I0_A0_EP3_FIFO_CONFIG & (~BIT(7)))); |
||||
} |
||||
|
||||
usb_ep_packet_size_hi(3, FS_C1_I0_A0_EP3_DIRECTION, (FS_C1_I0_A0_EP3_MAX_PACKET & 0x7ff)); |
||||
usb_ep_packet_size_lo(3, FS_C1_I0_A0_EP3_DIRECTION, (FS_C1_I0_A0_EP3_MAX_PACKET & 0x7ff)); |
||||
usb_ep_in_highbandset(3, FS_C1_I0_A0_EP3_DIRECTION, FS_C1_I0_A0_EP3_MAX_PACKET); |
||||
|
||||
/* EP 4 */ |
||||
usb_ep_map(4, FS_C1_I0_A0_EP4_MAP); |
||||
usb_fifo_map(FS_C1_I0_A0_EP4_FIFO_START, FS_C1_I0_A0_EP4_FIFO_MAP); |
||||
usb_fifo_config(FS_C1_I0_A0_EP4_FIFO_START, FS_C1_I0_A0_EP4_FIFO_CONFIG); |
||||
|
||||
for (i = FS_C1_I0_A0_EP4_FIFO_START + 1; |
||||
i < FS_C1_I0_A0_EP4_FIFO_START + FS_C1_I0_A0_EP4_FIFO_NO; i++) { |
||||
usb_fifo_config(i, (FS_C1_I0_A0_EP4_FIFO_CONFIG & (~BIT(7)))); |
||||
} |
||||
|
||||
usb_ep_packet_size_hi(4, FS_C1_I0_A0_EP4_DIRECTION, (FS_C1_I0_A0_EP4_MAX_PACKET & 0x7ff)); |
||||
usb_ep_packet_size_lo(4, FS_C1_I0_A0_EP4_DIRECTION, (FS_C1_I0_A0_EP4_MAX_PACKET & 0x7ff)); |
||||
usb_ep_in_highbandset(4, FS_C1_I0_A0_EP4_DIRECTION, FS_C1_I0_A0_EP4_MAX_PACKET); |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_USB_MODESWITCH */ |
@ -0,0 +1,432 @@
@@ -0,0 +1,432 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#include "carl9170.h" |
||||
|
||||
#include "shared/phy.h" |
||||
#include "hostif.h" |
||||
#include "printf.h" |
||||
#include "timer.h" |
||||
#include "rom.h" |
||||
#include "wl.h" |
||||
#include "wol.h" |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG_USB |
||||
void usb_putc(const char c) |
||||
{ |
||||
fw.usb.put_buffer[fw.usb.put_index++] = (uint8_t) c; |
||||
|
||||
if (fw.usb.put_index == CARL9170_MAX_CMD_PAYLOAD_LEN || c == '\0') { |
||||
fw.usb.put_buffer[fw.usb.put_index] = 0; |
||||
|
||||
send_cmd_to_host(__roundup(fw.usb.put_index, 4), |
||||
CARL9170_RSP_TEXT, fw.usb.put_index, |
||||
fw.usb.put_buffer); |
||||
fw.usb.put_index = 0; |
||||
} |
||||
} |
||||
|
||||
void usb_print_hex_dump(const void *buf, int len) |
||||
{ |
||||
unsigned int offset = 0, block = 0; |
||||
while (len > 0) { |
||||
block = min(__roundup(len, 4), CARL9170_MAX_CMD_PAYLOAD_LEN); |
||||
|
||||
send_cmd_to_host(block, CARL9170_RSP_HEXDUMP, len, |
||||
(const uint8_t *) buf + offset); |
||||
|
||||
offset += block; |
||||
len -= block; |
||||
} |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_DEBUG_USB */ |
||||
|
||||
/* grab a buffer from the interrupt in queue ring-buffer */ |
||||
static struct carl9170_rsp *get_int_buf(void) |
||||
{ |
||||
struct carl9170_rsp *tmp; |
||||
|
||||
/* fetch the _oldest_ buffer from the ring */ |
||||
tmp = &fw.usb.int_buf[fw.usb.int_tail_index]; |
||||
|
||||
/* assign a unique sequence for every response/trap */ |
||||
tmp->hdr.seq = fw.usb.int_tail_index; |
||||
|
||||
fw.usb.int_tail_index++; |
||||
|
||||
fw.usb.int_tail_index %= CARL9170_INT_RQ_CACHES; |
||||
if (fw.usb.int_pending != CARL9170_INT_RQ_CACHES) |
||||
fw.usb.int_pending++; |
||||
|
||||
return tmp; |
||||
} |
||||
|
||||
/* Pop up data from Interrupt IN Queue to USB Response buffer */ |
||||
static struct carl9170_rsp *dequeue_int_buf(unsigned int space) |
||||
{ |
||||
struct carl9170_rsp *tmp = NULL; |
||||
|
||||
if (fw.usb.int_pending > 0) { |
||||
tmp = &fw.usb.int_buf[fw.usb.int_head_index]; |
||||
|
||||
if ((unsigned int)(tmp->hdr.len + 8) > space) |
||||
return NULL; |
||||
|
||||
fw.usb.int_head_index++; |
||||
fw.usb.int_head_index %= CARL9170_INT_RQ_CACHES; |
||||
fw.usb.int_pending--; |
||||
} |
||||
|
||||
return tmp; |
||||
} |
||||
|
||||
static void usb_data_in(void) |
||||
{ |
||||
} |
||||
|
||||
static void usb_reg_out(void) |
||||
{ |
||||
uint32_t *regaddr = (uint32_t *) &dma_mem.reserved.cmd; |
||||
uint16_t usbfifolen, i; |
||||
|
||||
usb_reset_out(); |
||||
|
||||
usbfifolen = getb(AR9170_USB_REG_EP4_BYTE_COUNT_LOW) | |
||||
getb(AR9170_USB_REG_EP4_BYTE_COUNT_HIGH) << 8; |
||||
|
||||
if (usbfifolen & 0x3) |
||||
usbfifolen = (usbfifolen >> 2) + 1; |
||||
else |
||||
usbfifolen = usbfifolen >> 2; |
||||
|
||||
for (i = 0; i < usbfifolen; i++) |
||||
*regaddr++ = get(AR9170_USB_REG_EP4_DATA); |
||||
|
||||
handle_cmd(get_int_buf()); |
||||
|
||||
usb_trigger_in(); |
||||
} |
||||
|
||||
static void usb_status_in(void) |
||||
{ |
||||
struct carl9170_rsp *rsp; |
||||
unsigned int rem, tlen, elen; |
||||
|
||||
if (!fw.usb.int_desc_available) |
||||
return ; |
||||
|
||||
fw.usb.int_desc_available = 0; |
||||
|
||||
rem = AR9170_BLOCK_SIZE - AR9170_INT_MAGIC_HEADER_SIZE; |
||||
tlen = AR9170_INT_MAGIC_HEADER_SIZE; |
||||
|
||||
usb_reset_in(); |
||||
|
||||
while (fw.usb.int_pending) { |
||||
rsp = dequeue_int_buf(rem); |
||||
if (!rsp) |
||||
break; |
||||
|
||||
elen = rsp->hdr.len + 4; |
||||
|
||||
memcpy(DESC_PAYLOAD_OFF(fw.usb.int_desc, tlen), rsp, elen); |
||||
|
||||
rem -= elen; |
||||
tlen += elen; |
||||
} |
||||
|
||||
if (tlen == AR9170_INT_MAGIC_HEADER_SIZE) { |
||||
DBG("attempted to send an empty int response!\n"); |
||||
goto reclaim; |
||||
} |
||||
|
||||
fw.usb.int_desc->ctrl = AR9170_CTRL_FS_BIT | AR9170_CTRL_LS_BIT; |
||||
fw.usb.int_desc->totalLen = tlen; |
||||
fw.usb.int_desc->dataSize = tlen; |
||||
|
||||
/* Put to UpQ */ |
||||
dma_put(&fw.pta.up_queue, fw.usb.int_desc); |
||||
|
||||
/* Trigger PTA UP DMA */ |
||||
set(AR9170_PTA_REG_UP_DMA_TRIGGER, 1); |
||||
usb_trigger_out(); |
||||
|
||||
return ; |
||||
|
||||
reclaim: |
||||
/* TODO: not sure what to do here */ |
||||
fw.usb.int_desc_available = 1; |
||||
} |
||||
|
||||
void send_cmd_to_host(const uint8_t len, const uint8_t type, |
||||
const uint8_t ext, const uint8_t *body) |
||||
{ |
||||
struct carl9170_cmd *resp; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_DEBUG |
||||
if (unlikely(len > sizeof(resp->data))) { |
||||
DBG("CMD too long:%x %d\n", type, len); |
||||
return ; |
||||
} |
||||
|
||||
/* Element length must be a multiple of 4. */ |
||||
if (unlikely(len & 0x3)) { |
||||
DBG("CMD length not mult. of 4:%x %d\n", type, len); |
||||
return ; |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_DEBUG */ |
||||
|
||||
resp = (struct carl9170_cmd *) get_int_buf(); |
||||
if (unlikely(resp == NULL)) { |
||||
/* not very helpful for NON UART users */ |
||||
DBG("out of msg buffers\n"); |
||||
return ; |
||||
} |
||||
|
||||
resp->hdr.len = len; |
||||
resp->hdr.cmd = type; |
||||
resp->hdr.ext = ext; |
||||
|
||||
memcpy(resp->data, body, len); |
||||
usb_trigger_in(); |
||||
} |
||||
|
||||
/* Turn off ADDA/RF power, PLL */ |
||||
static void turn_power_off(void) |
||||
{ |
||||
set(AR9170_PHY_REG_ACTIVE, AR9170_PHY_ACTIVE_DIS); |
||||
set(AR9170_PHY_REG_ADC_CTL, 0xa0000000 | |
||||
AR9170_PHY_ADC_CTL_OFF_PWDADC | AR9170_PHY_ADC_CTL_OFF_PWDDAC); |
||||
|
||||
/* This will also turn-off the LEDs */ |
||||
set(AR9170_GPIO_REG_PORT_DATA, 0); |
||||
set(AR9170_GPIO_REG_PORT_TYPE, 0xf); |
||||
|
||||
set(AR9170_PWR_REG_BASE, 0x40021); |
||||
|
||||
set(AR9170_MAC_REG_DMA_TRIGGER, 0); |
||||
|
||||
andl(AR9170_USB_REG_DMA_CTL, ~(AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE | |
||||
AR9170_USB_DMA_CTL_ENABLE_FROM_DEVICE | |
||||
AR9170_USB_DMA_CTL_UP_PACKET_MODE | |
||||
AR9170_USB_DMA_CTL_DOWN_STREAM)); |
||||
|
||||
/* Do a software reset to PTA component */ |
||||
orl(AR9170_PTA_REG_DMA_MODE_CTRL, AR9170_PTA_DMA_MODE_CTRL_RESET); |
||||
andl(AR9170_PTA_REG_DMA_MODE_CTRL, ~AR9170_PTA_DMA_MODE_CTRL_RESET); |
||||
|
||||
orl(AR9170_PTA_REG_DMA_MODE_CTRL, AR9170_PTA_DMA_MODE_CTRL_DISABLE_USB); |
||||
|
||||
set(AR9170_MAC_REG_POWER_STATE_CTRL, |
||||
AR9170_MAC_POWER_STATE_CTRL_RESET); |
||||
|
||||
/* Reset USB FIFO */ |
||||
set(AR9170_PWR_REG_RESET, AR9170_PWR_RESET_COMMIT_RESET_MASK | |
||||
AR9170_PWR_RESET_DMA_MASK | |
||||
AR9170_PWR_RESET_WLAN_MASK); |
||||
set(AR9170_PWR_REG_RESET, 0x0); |
||||
|
||||
clock_set(AHB_20_22MHZ, false); |
||||
|
||||
set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); /* 0x502b; */ |
||||
set(AR9170_PHY_REG_ADC_SERIAL_CTL, AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO); |
||||
set(0x1c589c, 0); /* 7-0 */ |
||||
set(0x1c589c, 0); /* 15-8 */ |
||||
set(0x1c589c, 0); /* 23-16 */ |
||||
set(0x1c589c, 0); /* 31- */ |
||||
set(0x1c589c, 0); /* 39- */ |
||||
set(0x1c589c, 0); /* 47- */ |
||||
set(0x1c589c, 0); /* 55- */ |
||||
set(0x1c589c, 0xf8); /* 63- */ |
||||
set(0x1c589c, 0x27); /* 0x24; 71- modified */ |
||||
set(0x1c589c, 0xf9); /* 79- */ |
||||
set(0x1c589c, 0x90); /* 87- */ |
||||
set(0x1c589c, 0x04); /* 95- */ |
||||
set(0x1c589c, 0x48); /* 103- */ |
||||
set(0x1c589c, 0x19); /* 0; 111- modified */ |
||||
set(0x1c589c, 0); /* 119- */ |
||||
set(0x1c589c, 0); /* 127- */ |
||||
set(0x1c589c, 0); /* 135- */ |
||||
set(0x1c589c, 0); /* 143- */ |
||||
set(0x1c589c, 0); /* 151- */ |
||||
set(0x1c589c, 0x70); /* 159- */ |
||||
set(0x1c589c, 0x0c); /* 167- */ |
||||
set(0x1c589c, 0); /* 175- */ |
||||
set(0x1c589c, 0); /* 183-176 */ |
||||
set(0x1c589c, 0); /* 191-184 */ |
||||
set(0x1c589c, 0); /* 199- */ |
||||
set(0x1c589c, 0); /* 207- */ |
||||
set(0x1c589c, 0); /* 215- */ |
||||
set(0x1c589c, 0); /* 223- */ |
||||
set(0x1c589c, 0); /* 231- */ |
||||
set(0x1c58c4, 0); /* 233- 232 */ |
||||
set(AR9170_PHY_REG_ADC_SERIAL_CTL, AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC); |
||||
} |
||||
|
||||
static void disable_watchdog(void) |
||||
{ |
||||
if (!fw.watchdog_enable) |
||||
return; |
||||
|
||||
/* write watchdog magic pattern for suspend */ |
||||
andl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0xffff); |
||||
orl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0x98760000); |
||||
|
||||
/* Disable watchdog */ |
||||
set(AR9170_TIMER_REG_WATCH_DOG, 0xffff); |
||||
} |
||||
|
||||
void __noreturn reboot(void) |
||||
{ |
||||
disable_watchdog(); |
||||
|
||||
/* Turn off power */ |
||||
turn_power_off(); |
||||
|
||||
/* clean bootloader workspace */ |
||||
memset(&dma_mem, 0, sizeof(dma_mem)); |
||||
|
||||
/* add by ygwei for work around USB PHY chirp sequence problem */ |
||||
set(0x10f100, 0x12345678); |
||||
|
||||
/* Jump to boot code */ |
||||
jump_to_bootcode(); |
||||
} |
||||
|
||||
/* service USB events and re-enable USB interrupt */ |
||||
static void usb_handler(uint8_t usb_interrupt_level1) |
||||
{ |
||||
uint8_t usb_interrupt_level2; |
||||
|
||||
if (usb_interrupt_level1 & BIT(5)) |
||||
usb_data_in(); |
||||
|
||||
if (usb_interrupt_level1 & BIT(4)) |
||||
usb_reg_out(); |
||||
|
||||
if (usb_interrupt_level1 & BIT(6)) |
||||
usb_status_in(); |
||||
|
||||
if (usb_interrupt_level1 & BIT(0)) { |
||||
usb_interrupt_level2 = getb(AR9170_USB_REG_INTR_SOURCE_0); |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_SETUP) |
||||
usb_ep0setup(); |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_IN) |
||||
usb_ep0tx(); |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_OUT) |
||||
usb_ep0rx(); |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_ABORT) { |
||||
/* Clear the command abort interrupt */ |
||||
andb(AR9170_USB_REG_INTR_SOURCE_0, (uint8_t) |
||||
~AR9170_USB_INTR_SRC0_ABORT); |
||||
} |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_FAIL || |
||||
fw.usb.ep0_action & CARL9170_EP0_STALL) { |
||||
/* |
||||
* transmission failure. |
||||
* stall ep 0 |
||||
*/ |
||||
setb(AR9170_USB_REG_CX_CONFIG_STATUS, BIT(2)); |
||||
fw.usb.ep0_action &= ~CARL9170_EP0_STALL; |
||||
} |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_END || |
||||
fw.usb.ep0_action & CARL9170_EP0_TRIGGER) { |
||||
/* |
||||
* transmission done. |
||||
* set DONE bit. |
||||
*/ |
||||
setb(AR9170_USB_REG_CX_CONFIG_STATUS, BIT(0)); |
||||
fw.usb.ep0_action &= ~CARL9170_EP0_TRIGGER; |
||||
} |
||||
} |
||||
|
||||
if (usb_interrupt_level1 & BIT(7)) { |
||||
usb_interrupt_level2 = getb(AR9170_USB_REG_INTR_SOURCE_7); |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_RX0BYTE) |
||||
usb_data_out0Byte(); |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_TX0BYTE) |
||||
usb_data_in0Byte(); |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_USB_RESET) { |
||||
usb_reset_ack(); |
||||
reboot(); |
||||
} |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_USB_SUSPEND) { |
||||
usb_suspend_ack(); |
||||
|
||||
fw.suspend_mode = CARL9170_HOST_SUSPENDED; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
if (!(fw.usb.device_feature & USB_DEVICE_REMOTE_WAKEUP) || |
||||
!fw.wol.cmd.flags) { |
||||
disable_watchdog(); |
||||
|
||||
/* GO_TO_SUSPEND stops the CPU clock too. */ |
||||
orb(AR9170_USB_REG_MAIN_CTRL, AR9170_USB_MAIN_CTRL_GO_TO_SUSPEND); |
||||
} else { |
||||
wol_prepare(); |
||||
} |
||||
#else /* CONFIG_CARL9170FW_WOL */ |
||||
disable_watchdog(); |
||||
|
||||
/* GO_TO_SUSPEND stops the CPU clock too. */ |
||||
orb(AR9170_USB_REG_MAIN_CTRL, AR9170_USB_MAIN_CTRL_GO_TO_SUSPEND); |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
} |
||||
|
||||
if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_USB_RESUME) { |
||||
usb_resume_ack(); |
||||
|
||||
fw.suspend_mode = CARL9170_HOST_AWAKE; |
||||
set(AR9170_USB_REG_WAKE_UP, 0); |
||||
|
||||
reboot(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void handle_usb(void) |
||||
{ |
||||
uint8_t usb_interrupt_level1; |
||||
|
||||
usb_interrupt_level1 = getb(AR9170_USB_REG_INTR_GROUP); |
||||
|
||||
if (usb_interrupt_level1) |
||||
usb_handler(usb_interrupt_level1); |
||||
|
||||
if (fw.usb.int_pending > 0) |
||||
usb_trigger_in(); |
||||
} |
||||
|
||||
void usb_timer(void) |
||||
{ |
||||
} |
@ -0,0 +1,758 @@
@@ -0,0 +1,758 @@
|
||||
/* |
||||
* carl9170 firmware - used by the ar9170 wireless device |
||||
* |
||||
* USB Controller |
||||
* |
||||
* Copyright (c) 2000-2005 ZyDAS Technology Corporation |
||||
* Copyright (c) 2007-2009 Atheros Communications, Inc. |
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
#include "carl9170.h" |
||||
#include "usb.h" |
||||
#include "printf.h" |
||||
#include "rom.h" |
||||
|
||||
/* |
||||
* NB: The firmware has to write into these structures |
||||
* so don't try to make them "const". |
||||
*/ |
||||
|
||||
static struct ar9170_usb_config usb_config_highspeed = { |
||||
.cfg = { |
||||
.bLength = USB_DT_CONFIG_SIZE, |
||||
.bDescriptorType = USB_DT_CONFIG, |
||||
.wTotalLength = cpu_to_le16(sizeof(usb_config_highspeed)), |
||||
.bNumInterfaces = 1, |
||||
.bConfigurationValue = 1, |
||||
.iConfiguration = 0, |
||||
.bmAttributes = USB_CONFIG_ATT_ONE | |
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
USB_CONFIG_ATT_WAKEUP | |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
0, |
||||
.bMaxPower = 0xfa, /* 500 mA */ |
||||
}, |
||||
|
||||
.intf = { |
||||
.bLength = USB_DT_INTERFACE_SIZE, |
||||
.bDescriptorType = USB_DT_INTERFACE, |
||||
.bInterfaceNumber = 0, |
||||
.bAlternateSetting = 0, |
||||
.bNumEndpoints = AR9170_USB_NUM_EXTRA_EP, |
||||
.bInterfaceClass = USB_CLASS_VENDOR_SPEC, |
||||
.bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, |
||||
.bInterfaceProtocol = 0, |
||||
.iInterface = 0, |
||||
}, |
||||
|
||||
.ep = { |
||||
{ /* EP 1 */ |
||||
.bLength = USB_DT_ENDPOINT_SIZE, |
||||
.bDescriptorType = USB_DT_ENDPOINT, |
||||
.bEndpointAddress = USB_DIR_OUT | AR9170_USB_EP_TX, |
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK, |
||||
.wMaxPacketSize = cpu_to_le16(512), |
||||
.bInterval = 0, |
||||
}, |
||||
|
||||
{ /* EP 2 */ |
||||
.bLength = USB_DT_ENDPOINT_SIZE, |
||||
.bDescriptorType = USB_DT_ENDPOINT, |
||||
.bEndpointAddress = USB_DIR_IN | AR9170_USB_EP_RX, |
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK, |
||||
.wMaxPacketSize = cpu_to_le16(512), |
||||
.bInterval = 0, |
||||
}, |
||||
|
||||
{ /* EP 3 */ |
||||
.bLength = USB_DT_ENDPOINT_SIZE, |
||||
.bDescriptorType = USB_DT_ENDPOINT, |
||||
.bEndpointAddress = USB_DIR_IN | AR9170_USB_EP_IRQ, |
||||
.bmAttributes = USB_ENDPOINT_XFER_INT, |
||||
.wMaxPacketSize = cpu_to_le16(64), |
||||
.bInterval = 1, |
||||
}, |
||||
|
||||
{ /* EP 4 */ |
||||
.bLength = USB_DT_ENDPOINT_SIZE, |
||||
.bDescriptorType = USB_DT_ENDPOINT, |
||||
.bEndpointAddress = USB_DIR_OUT | AR9170_USB_EP_CMD, |
||||
.bmAttributes = USB_ENDPOINT_XFER_INT, |
||||
.wMaxPacketSize = cpu_to_le16(64), |
||||
.bInterval = 1, |
||||
}, |
||||
}, |
||||
}; |
||||
|
||||
static struct ar9170_usb_config usb_config_fullspeed = { |
||||
.cfg = { |
||||
.bLength = USB_DT_CONFIG_SIZE, |
||||
.bDescriptorType = USB_DT_CONFIG, |
||||
.wTotalLength = cpu_to_le16(sizeof(usb_config_fullspeed)), |
||||
.bNumInterfaces = 1, |
||||
.bConfigurationValue = 1, |
||||
.iConfiguration = 0, |
||||
.bmAttributes = USB_CONFIG_ATT_ONE | |
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
USB_CONFIG_ATT_WAKEUP | |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
0, |
||||
.bMaxPower = 0xfa, /* 500 mA */ |
||||
}, |
||||
|
||||
.intf = { |
||||
.bLength = USB_DT_INTERFACE_SIZE, |
||||
.bDescriptorType = USB_DT_INTERFACE, |
||||
.bInterfaceNumber = 0, |
||||
.bAlternateSetting = 0, |
||||
.bNumEndpoints = AR9170_USB_NUM_EXTRA_EP, |
||||
.bInterfaceClass = USB_CLASS_VENDOR_SPEC, |
||||
.bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, |
||||
.bInterfaceProtocol = 0, |
||||
.iInterface = 0, |
||||
}, |
||||
|
||||
.ep = { |
||||
{ /* EP 1 */ |
||||
.bLength = USB_DT_ENDPOINT_SIZE, |
||||
.bDescriptorType = USB_DT_ENDPOINT, |
||||
.bEndpointAddress = USB_DIR_OUT | AR9170_USB_EP_TX, |
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK, |
||||
.wMaxPacketSize = cpu_to_le16(64), |
||||
.bInterval = 0, |
||||
}, |
||||
|
||||
{ /* EP 2 */ |
||||
.bLength = USB_DT_ENDPOINT_SIZE, |
||||
.bDescriptorType = USB_DT_ENDPOINT, |
||||
.bEndpointAddress = USB_DIR_IN | AR9170_USB_EP_RX, |
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK, |
||||
.wMaxPacketSize = cpu_to_le16(64), |
||||
.bInterval = 0, |
||||
}, |
||||
|
||||
{ /* EP 3 */ |
||||
.bLength = USB_DT_ENDPOINT_SIZE, |
||||
.bDescriptorType = USB_DT_ENDPOINT, |
||||
.bEndpointAddress = USB_DIR_IN | AR9170_USB_EP_IRQ, |
||||
.bmAttributes = USB_ENDPOINT_XFER_INT, |
||||
.wMaxPacketSize = cpu_to_le16(64), |
||||
.bInterval = 1, |
||||
}, |
||||
|
||||
{ /* EP 4 */ |
||||
.bLength = USB_DT_ENDPOINT_SIZE, |
||||
.bDescriptorType = USB_DT_ENDPOINT, |
||||
.bEndpointAddress = USB_DIR_OUT | AR9170_USB_EP_CMD, |
||||
.bmAttributes = USB_ENDPOINT_XFER_INT, |
||||
.wMaxPacketSize = cpu_to_le16(64), |
||||
.bInterval = 1, |
||||
}, |
||||
}, |
||||
}; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_USB_MODESWITCH |
||||
static void usb_reset_eps(void) |
||||
{ |
||||
unsigned int i; |
||||
|
||||
/* clear all EPs' toggle bit */ |
||||
for (i = 1; i < __AR9170_USB_NUM_MAX_EP; i++) { |
||||
usb_set_input_ep_toggle(i); |
||||
usb_clear_input_ep_toggle(i); |
||||
} |
||||
|
||||
/* |
||||
* NB: I've no idea why this cannot be integrated into the |
||||
* previous loop? |
||||
*/ |
||||
for (i = 1; i < __AR9170_USB_NUM_MAX_EP; i++) { |
||||
usb_set_output_ep_toggle(i); |
||||
usb_clear_output_ep_toggle(i); |
||||
} |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_USB_MODESWITCH */ |
||||
|
||||
|
||||
static void usb_pta_init(void) |
||||
{ |
||||
unsigned int usb_dma_ctrl = 0; |
||||
/* Set PTA mode to USB */ |
||||
andl(AR9170_PTA_REG_DMA_MODE_CTRL, |
||||
~AR9170_PTA_DMA_MODE_CTRL_DISABLE_USB); |
||||
|
||||
/* Do a software reset to PTA component */ |
||||
orl(AR9170_PTA_REG_DMA_MODE_CTRL, AR9170_PTA_DMA_MODE_CTRL_RESET); |
||||
andl(AR9170_PTA_REG_DMA_MODE_CTRL, ~AR9170_PTA_DMA_MODE_CTRL_RESET); |
||||
|
||||
if (usb_detect_highspeed()) { |
||||
fw.usb.os_cfg_desc = &usb_config_fullspeed; |
||||
fw.usb.cfg_desc = &usb_config_highspeed; |
||||
|
||||
/* 512 Byte DMA transfers */ |
||||
usb_dma_ctrl |= AR9170_USB_DMA_CTL_HIGH_SPEED; |
||||
} else { |
||||
fw.usb.cfg_desc = &usb_config_fullspeed; |
||||
fw.usb.os_cfg_desc = &usb_config_highspeed; |
||||
} |
||||
|
||||
#ifdef CONFIG_CARL9170FW_USB_UP_STREAM |
||||
# if (CONFIG_CARL9170FW_RX_FRAME_LEN == 4096) |
||||
usb_dma_ctrl |= AR9170_USB_DMA_CTL_UP_STREAM_4K; |
||||
# elif (CONFIG_CARL9170FW_RX_FRAME_LEN == 8192) |
||||
usb_dma_ctrl |= AR9170_USB_DMA_CTL_UP_STREAM_8K; |
||||
# elif (CONFIG_CARL9170FW_RX_FRAME_LEN == 16384) |
||||
usb_dma_ctrl |= AR9170_USB_DMA_CTL_UP_STREAM_16K; |
||||
# elif (CONFIG_CARL9170FW_RX_FRAME_LEN == 32768) |
||||
usb_dma_ctrl |= AR9170_USB_DMA_CTL_UP_STREAM_32K; |
||||
# else |
||||
# error "Invalid AR9170_RX_FRAME_LEN setting" |
||||
# endif |
||||
|
||||
#else /* CONFIG_CARL9170FW_USB_UP_STREAM */ |
||||
usb_dma_ctrl |= AR9170_USB_DMA_CTL_UP_PACKET_MODE; |
||||
#endif /* CONFIG_CARL9170FW_USB_UP_STREAM */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_USB_DOWN_STREAM |
||||
/* Enable down stream mode */ |
||||
usb_dma_ctrl |= AR9170_USB_DMA_CTL_DOWN_STREAM; |
||||
#endif /* CONFIG_CARL9170FW_USB_DOWN_STREAM */ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_USB_UP_STREAM |
||||
/* Set the up stream mode maximum aggregate number */ |
||||
set(AR9170_USB_REG_MAX_AGG_UPLOAD, 4); |
||||
|
||||
/* |
||||
* Set the up stream mode timeout value. |
||||
* NB: The vendor driver (otus) set 0x80? |
||||
*/ |
||||
set(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80); |
||||
#endif /* CONFIG_CARL9170FW_USB_UP_STREAM */ |
||||
|
||||
/* Enable up stream and down stream */ |
||||
usb_dma_ctrl |= AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE | |
||||
AR9170_USB_DMA_CTL_ENABLE_FROM_DEVICE; |
||||
|
||||
set(AR9170_USB_REG_DMA_CTL, usb_dma_ctrl); |
||||
} |
||||
|
||||
void usb_init(void) |
||||
{ |
||||
usb_pta_init(); |
||||
|
||||
fw.usb.config = 1; |
||||
/* |
||||
* The fw structure is always initialized with "0" |
||||
* during boot(); No need to waste precious bytes here. |
||||
* |
||||
* fw.usb.interface_setting = 0; |
||||
* fw.usb.alternate_interface_setting = 0; |
||||
* fw.usb.device_feature = 0; |
||||
*/ |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
fw.usb.device_feature |= USB_DEVICE_REMOTE_WAKEUP; |
||||
usb_enable_remote_wakeup(); |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
} |
||||
|
||||
#define GET_ARRAY(a, o) ((uint32_t *) (((unsigned long) data) + offset)) |
||||
|
||||
static void usb_ep0rx_data(const void *data, const unsigned int len) |
||||
{ |
||||
unsigned int offset; |
||||
uint32_t value; |
||||
|
||||
BUG_ON(len > AR9170_USB_EP_CTRL_MAX); |
||||
BUILD_BUG_ON(len > AR9170_USB_EP_CTRL_MAX); |
||||
|
||||
for (offset = 0; offset < ((len + 3) & ~3); offset += 4) { |
||||
value = get(AR9170_USB_REG_EP0_DATA); |
||||
memcpy(GET_ARRAY(data, offset), &value, |
||||
min(len - offset, (unsigned int)4)); |
||||
} |
||||
} |
||||
|
||||
static int usb_ep0tx_data(const void *data, const unsigned int len) |
||||
{ |
||||
unsigned int offset = 0, block, last_block = 0; |
||||
uint32_t value; |
||||
|
||||
BUG_ON(len > AR9170_USB_EP_CTRL_MAX); |
||||
BUILD_BUG_ON(len > AR9170_USB_EP_CTRL_MAX); |
||||
|
||||
block = min(len, (unsigned int) 4); |
||||
offset = 0; |
||||
while (offset < len) { |
||||
|
||||
if (last_block != block || block < 4) |
||||
setb(AR9170_USB_REG_FIFO_SIZE, (1 << block) - 1); |
||||
|
||||
memcpy(&value, GET_ARRAY(data, offset), block); |
||||
|
||||
set(AR9170_USB_REG_EP0_DATA, value); |
||||
|
||||
offset += block; |
||||
last_block = block = min(len - offset, (unsigned int) 4); |
||||
} |
||||
|
||||
setb(AR9170_USB_REG_FIFO_SIZE, 0xf); |
||||
|
||||
/* this will push the data to the host */ |
||||
return 1; |
||||
} |
||||
#undef GET_ARRAY |
||||
|
||||
#ifdef CONFIG_CARL9170FW_USB_STANDARD_CMDS |
||||
static int usb_get_status(const struct usb_ctrlrequest *ctrl) |
||||
{ |
||||
__le16 status = cpu_to_le16(fw.usb.device_feature); |
||||
|
||||
if ((ctrl->bRequestType & USB_DIR_MASK) != USB_DIR_IN) |
||||
return -1; |
||||
|
||||
switch (ctrl->bRequestType & USB_RECIP_MASK) { |
||||
case USB_RECIP_DEVICE: |
||||
status &= cpu_to_le16(~USB_DEVICE_SELF_POWERED); |
||||
status &= cpu_to_le16(~USB_DEVICE_REMOTE_WAKEUP); |
||||
break; |
||||
|
||||
case USB_RECIP_INTERFACE: |
||||
/* USB spec: This is reserved for future use. */ |
||||
status = cpu_to_le16(0); |
||||
break; |
||||
|
||||
case USB_RECIP_ENDPOINT: |
||||
case USB_RECIP_OTHER: |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
return usb_ep0tx_data((const void *) &status, sizeof(status)); |
||||
} |
||||
|
||||
static int usb_get_string_desc(const struct usb_ctrlrequest *ctrl) |
||||
{ |
||||
const struct usb_string_descriptor *string_desc = NULL; |
||||
|
||||
switch (le16_to_cpu(ctrl->wValue) & 0xff) { |
||||
case 0x00: |
||||
string_desc = (const struct usb_string_descriptor *) |
||||
rom.hw.usb.string0_desc; |
||||
break; |
||||
|
||||
case 0x10: |
||||
string_desc = (const struct usb_string_descriptor *) |
||||
rom.hw.usb.string1_desc; |
||||
break; |
||||
|
||||
case 0x20: |
||||
string_desc = (const struct usb_string_descriptor *) |
||||
rom.hw.usb.string2_desc; |
||||
break; |
||||
|
||||
case 0x30: |
||||
string_desc = (const struct usb_string_descriptor *) |
||||
rom.hw.usb.string3_desc; |
||||
break; |
||||
|
||||
default: |
||||
break; |
||||
} |
||||
|
||||
if (string_desc) |
||||
return usb_ep0tx_data(string_desc, string_desc->bLength); |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
static int usb_get_device_desc(const struct usb_ctrlrequest *ctrl __unused) |
||||
{ |
||||
return usb_ep0tx_data(&rom.hw.usb.device_desc, |
||||
rom.hw.usb.device_desc.bLength); |
||||
} |
||||
|
||||
static int usb_get_config_desc(const struct usb_ctrlrequest *ctrl __unused) |
||||
{ |
||||
fw.usb.cfg_desc->cfg.bDescriptorType = USB_DT_CONFIG; |
||||
|
||||
return usb_ep0tx_data(fw.usb.cfg_desc, |
||||
le16_to_cpu(fw.usb.cfg_desc->cfg.wTotalLength)); |
||||
} |
||||
|
||||
#ifdef CONFIG_CARL9170FW_USB_MODESWITCH |
||||
static int usb_get_otherspeed_desc(const struct usb_ctrlrequest *ctrl __unused) |
||||
{ |
||||
|
||||
fw.usb.os_cfg_desc->cfg.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG; |
||||
|
||||
return usb_ep0tx_data(fw.usb.os_cfg_desc, |
||||
le16_to_cpu(fw.usb.os_cfg_desc->cfg.wTotalLength)); |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_USB_MODESWITCH */ |
||||
|
||||
static int usb_get_qualifier_desc(const struct usb_ctrlrequest *ctrl __unused) |
||||
{ |
||||
struct usb_qualifier_descriptor qual; |
||||
|
||||
/* |
||||
* The qualifier descriptor shares some structural details |
||||
* with the main device descriptor. |
||||
*/ |
||||
|
||||
memcpy(&qual, &rom.hw.usb.device_desc, sizeof(qual)); |
||||
|
||||
/* (Re)-Initialize fields */ |
||||
qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER; |
||||
qual.bLength = sizeof(qual); |
||||
qual.bNumConfigurations = rom.hw.usb.device_desc.bNumConfigurations; |
||||
qual.bRESERVED = 0; |
||||
|
||||
return usb_ep0tx_data(&qual, qual.bLength); |
||||
} |
||||
|
||||
#define USB_CHECK_REQTYPE(ctrl, recip, dir) \ |
||||
(((ctrl->bRequestType & USB_RECIP_MASK) != recip) || \ |
||||
((ctrl->bRequestType & USB_DIR_MASK) != dir)) |
||||
|
||||
static int usb_get_descriptor(const struct usb_ctrlrequest *ctrl) |
||||
{ |
||||
int status = -1; |
||||
|
||||
if (USB_CHECK_REQTYPE(ctrl, USB_RECIP_DEVICE, USB_DIR_IN)) |
||||
return status; |
||||
|
||||
switch (le16_to_cpu(ctrl->wValue) >> 8) { |
||||
case USB_DT_DEVICE: |
||||
status = usb_get_device_desc(ctrl); |
||||
break; |
||||
|
||||
case USB_DT_CONFIG: |
||||
status = usb_get_config_desc(ctrl); |
||||
break; |
||||
|
||||
case USB_DT_STRING: |
||||
status = usb_get_string_desc(ctrl); |
||||
break; |
||||
|
||||
case USB_DT_INTERFACE: |
||||
break; |
||||
|
||||
case USB_DT_ENDPOINT: |
||||
break; |
||||
|
||||
case USB_DT_DEVICE_QUALIFIER: |
||||
status = usb_get_qualifier_desc(ctrl); |
||||
break; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_USB_MODESWITCH |
||||
case USB_DT_OTHER_SPEED_CONFIG: |
||||
status = usb_get_otherspeed_desc(ctrl); |
||||
break; |
||||
#endif /* CONFIG_CARL9170FW_USB_MODESWITCH */ |
||||
default: |
||||
break; |
||||
|
||||
} |
||||
|
||||
return status; |
||||
} |
||||
|
||||
static int usb_get_configuration(const struct usb_ctrlrequest *ctrl) |
||||
{ |
||||
if (USB_CHECK_REQTYPE(ctrl, USB_RECIP_DEVICE, USB_DIR_IN)) |
||||
return -1; |
||||
|
||||
return usb_ep0tx_data(&fw.usb.config, 1); |
||||
} |
||||
|
||||
static int usb_set_configuration(const struct usb_ctrlrequest *ctrl) |
||||
{ |
||||
unsigned int config; |
||||
|
||||
if (USB_CHECK_REQTYPE(ctrl, USB_RECIP_DEVICE, USB_DIR_OUT)) |
||||
return -1; |
||||
|
||||
config = le16_to_cpu(ctrl->wValue); |
||||
switch (config) { |
||||
case 0: |
||||
/* Disable Device */ |
||||
andb(AR9170_USB_REG_DEVICE_ADDRESS, |
||||
(uint8_t) ~(AR9170_USB_DEVICE_ADDRESS_CONFIGURE)); |
||||
#ifdef CONFIG_CARL9170FW_USB_MODESWITCH |
||||
case 1: |
||||
fw.usb.config = config; |
||||
|
||||
if (usb_detect_highspeed()) { |
||||
/* High Speed Configuration */ |
||||
usb_init_highspeed_fifo_cfg(); |
||||
} else { |
||||
/* Full Speed Configuration */ |
||||
usb_init_fullspeed_fifo_cfg(); |
||||
} |
||||
break; |
||||
|
||||
default: |
||||
return -1; |
||||
} |
||||
/* usb_pta_init() ? */ |
||||
|
||||
usb_reset_eps(); |
||||
orb(AR9170_USB_REG_DEVICE_ADDRESS, |
||||
(AR9170_USB_DEVICE_ADDRESS_CONFIGURE)); |
||||
|
||||
usb_enable_global_int(); |
||||
usb_trigger_out(); |
||||
return 1; |
||||
#else |
||||
default: |
||||
return -1; |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_USB_MODESWITCH */ |
||||
} |
||||
|
||||
static int usb_set_address(const struct usb_ctrlrequest *ctrl) |
||||
{ |
||||
unsigned int address; |
||||
|
||||
if (USB_CHECK_REQTYPE(ctrl, USB_RECIP_DEVICE, USB_DIR_OUT)) |
||||
return -1; |
||||
|
||||
address = le16_to_cpu(ctrl->wValue); |
||||
|
||||
/* |
||||
* The original firmware used 0x100 (which is, of course, |
||||
* too big to fit into uint8_t). |
||||
* However based on the available information (hw.h), BIT(7) |
||||
* is used as some sort of flag and should not be |
||||
* part of the device address. |
||||
*/ |
||||
if (address >= BIT(7)) |
||||
return -1; |
||||
|
||||
setb(AR9170_USB_REG_DEVICE_ADDRESS, (uint8_t) address); |
||||
return 1; |
||||
} |
||||
|
||||
static int usb_get_interface(const struct usb_ctrlrequest *ctrl) |
||||
{ |
||||
if (USB_CHECK_REQTYPE(ctrl, USB_RECIP_INTERFACE, USB_DIR_IN)) |
||||
return -1; |
||||
|
||||
if (usb_configured() == false) |
||||
return -1; |
||||
|
||||
switch (fw.usb.config) { |
||||
case 1: |
||||
break; |
||||
|
||||
default: |
||||
return -1; |
||||
} |
||||
|
||||
return usb_ep0tx_data(&fw.usb.alternate_interface_setting, 1); |
||||
} |
||||
|
||||
static int usb_manipulate_feature(const struct usb_ctrlrequest *ctrl, bool __unused clear) |
||||
{ |
||||
unsigned int feature; |
||||
if (USB_CHECK_REQTYPE(ctrl, USB_RECIP_DEVICE, USB_DIR_OUT)) |
||||
return -1; |
||||
|
||||
if (usb_configured() == false) |
||||
return -1; |
||||
|
||||
feature = le16_to_cpu(ctrl->wValue); |
||||
|
||||
#ifdef CONFIG_CARL9170FW_WOL |
||||
if (feature & USB_DEVICE_REMOTE_WAKEUP) { |
||||
if (clear) |
||||
usb_disable_remote_wakeup(); |
||||
else |
||||
usb_enable_remote_wakeup(); |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_WOL */ |
||||
|
||||
if (clear) |
||||
fw.usb.device_feature &= ~feature; |
||||
else |
||||
fw.usb.device_feature |= feature; |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
#ifdef CONFIG_CARL9170FW_USB_MODESWITCH |
||||
static int usb_set_interface(const struct usb_ctrlrequest *ctrl) |
||||
{ |
||||
unsigned int intf, alt_intf; |
||||
if (USB_CHECK_REQTYPE(ctrl, USB_RECIP_INTERFACE, USB_DIR_OUT)) |
||||
return -1; |
||||
|
||||
if (usb_configured() == false) |
||||
return -1; |
||||
|
||||
intf = le16_to_cpu(ctrl->wIndex); |
||||
alt_intf = le16_to_cpu(ctrl->wValue); |
||||
|
||||
switch (intf) { |
||||
case 0: |
||||
if (alt_intf != fw.usb.cfg_desc->intf.bAlternateSetting) |
||||
return -1; |
||||
|
||||
fw.usb.interface_setting = (uint8_t) intf; |
||||
fw.usb.alternate_interface_setting = (uint8_t) alt_intf; |
||||
if (usb_detect_highspeed()) |
||||
usb_init_highspeed_fifo_cfg(); |
||||
else |
||||
usb_init_fullspeed_fifo_cfg(); |
||||
|
||||
usb_reset_eps(); |
||||
usb_enable_global_int(); |
||||
usb_trigger_out(); |
||||
return 1; |
||||
|
||||
default: |
||||
return -1; |
||||
} |
||||
} |
||||
#endif /* CONFIG_CARL9170FW_USB_MODESWITCH */ |
||||
#endif /* CONFIG_CARL9170FW_USB_STANDARD_CMDS */ |
||||
|
||||
static int usb_standard_command(const struct usb_ctrlrequest *ctrl __unused) |
||||
{ |
||||
int status = -1; |
||||
|
||||
#ifdef CONFIG_CARL9170FW_USB_STANDARD_CMDS |
||||
switch (ctrl->bRequest) { |
||||
case USB_REQ_GET_STATUS: |
||||
status = usb_get_status(ctrl); |
||||
break; |
||||
|
||||
case USB_REQ_CLEAR_FEATURE: |
||||
case USB_REQ_SET_FEATURE: |
||||
usb_manipulate_feature(ctrl, ctrl->bRequest == USB_REQ_CLEAR_FEATURE); |
||||
break; |
||||
|
||||
case USB_REQ_SET_ADDRESS: |
||||
status = usb_set_address(ctrl); |
||||
break; |
||||
|
||||
case USB_REQ_GET_DESCRIPTOR: |
||||
status = usb_get_descriptor(ctrl); |
||||
break; |
||||
|
||||
case USB_REQ_SET_DESCRIPTOR: |
||||
break; |
||||
|
||||
case USB_REQ_GET_CONFIGURATION: |
||||
status = usb_get_configuration(ctrl); |
||||
break; |
||||
|
||||
case USB_REQ_SET_CONFIGURATION: |
||||
status = usb_set_configuration(ctrl); |
||||
break; |
||||
|
||||
case USB_REQ_GET_INTERFACE: |
||||
status = usb_get_interface(ctrl); |
||||
break; |
||||
|
||||
case USB_REQ_SET_INTERFACE: |
||||
#ifdef CONFIG_CARL9170FW_USB_MODESWITCH |
||||
status = usb_set_interface(ctrl); |
||||
#endif /* CONFIG_CARL9170FW_USB_MODESWITCH */ |
||||
break; |
||||
|
||||
case USB_REQ_SYNCH_FRAME: |
||||
break; |
||||
|
||||
default: |
||||
break; |
||||
|
||||
} |
||||
#endif /* CONFIG_CARL9170FW_USB_STANDARD_CMDS */ |
||||
|
||||
return status; |
||||
} |
||||
|
||||
static int usb_class_command(const struct usb_ctrlrequest *ctrl __unused) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
static int usb_vendor_command(const struct usb_ctrlrequest *ctrl __unused) |
||||
{ |
||||
/* |
||||
* Note: Firmware upload/boot is not implemented. |
||||
* It's impossible to replace the current image |
||||
* in place. |
||||
*/ |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
#undef USB_CHECK_TYPE |
||||
|
||||
void usb_ep0setup(void) |
||||
{ |
||||
struct usb_ctrlrequest ctrl; |
||||
int status = -1; |
||||
usb_ep0rx_data(&ctrl, sizeof(ctrl)); |
||||
|
||||
switch (ctrl.bRequestType & USB_TYPE_MASK) { |
||||
case USB_TYPE_STANDARD: |
||||
status = usb_standard_command(&ctrl); |
||||
break; |
||||
|
||||
case USB_TYPE_CLASS: |
||||
status = usb_class_command(&ctrl); |
||||
break; |
||||
|
||||
case USB_TYPE_VENDOR: |
||||
status = usb_vendor_command(&ctrl); |
||||
break; |
||||
|
||||
default: |
||||
break; |
||||
|
||||
} |
||||
|
||||
if (status < 0) |
||||
fw.usb.ep0_action |= CARL9170_EP0_STALL; |
||||
#ifdef CONFIG_CARL9170FW_USB_STANDARD_CMDS |
||||
if (status > 0) |
||||
fw.usb.ep0_action |= CARL9170_EP0_TRIGGER; |
||||
#endif /* CONFIG_CARL9170FW_USB_STANDARD_CMDS */ |
||||
} |
||||
|
||||
void usb_ep0rx(void) |
||||
{ |
||||
if (BUG_ON(!fw.usb.ep0_txrx_buffer || !fw.usb.ep0_txrx_len)) |
||||
return ; |
||||
|
||||
usb_ep0rx_data(fw.usb.ep0_txrx_buffer, fw.usb.ep0_txrx_len); |
||||
fw.usb.ep0_txrx_pos = fw.usb.ep0_txrx_len; |
||||
} |
||||
|
||||
void usb_ep0tx(void) |
||||
{ |
||||
if (BUG_ON(!fw.usb.ep0_txrx_buffer || !fw.usb.ep0_txrx_len)) |
||||
return ; |
||||
|
||||
usb_ep0tx_data(fw.usb.ep0_txrx_buffer, fw.usb.ep0_txrx_len); |
||||
fw.usb.ep0_txrx_pos = fw.usb.ep0_txrx_len; |
||||
} |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
cmake_minimum_required(VERSION 2.8) |
||||
|
||||
project(config) |
||||
|
||||
#set(CMAKE_VERBOSE_MAKEFILE ON) |
||||
|
||||
find_package(BISON REQUIRED) |
||||
find_package(FLEX REQUIRED) |
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) |
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../include/generated") |
||||
|
||||
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../extra") |
||||
FIND_PACKAGE(GPERF REQUIRED) |
||||
|
||||
BISON_TARGET(zconf zconf.y zconf.tab.c COMPILE_FLAGS "-l -b zconf -p zconf -t") |
||||
FLEX_TARGET(zconfscan zconf.l zconf.lex.c COMPILE_FLAGS "-Pzconf -L") |
||||
GPERF_TARGET(zconfhash zconf.gperf zconf.hash.c) |
||||
|
||||
SET(zconf_deps ${FLEX_zconfscan_OUTPUTS} ${GPERF_zconfhash_OUTPUTS}) |
||||
SET_SOURCE_FILES_PROPERTIES(${BISON_zconf_OUTPUTS} |
||||
PROPERTIES OBJECT_DEPENDS "${zconf_deps}") |
||||
|
||||
set(conf_src conf.c ${BISON_zconf_OUTPUTS}) |
||||
|
||||
add_executable(conf ${conf_src}) |
@ -0,0 +1,646 @@
@@ -0,0 +1,646 @@
|
||||
/* |
||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |
||||
* Released under the terms of the GNU GPL v2.0. |
||||
*/ |
||||
|
||||
#include <locale.h> |
||||
#include <ctype.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <time.h> |
||||
#include <unistd.h> |
||||
#include <getopt.h> |
||||
#include <sys/stat.h> |
||||
#include <sys/time.h> |
||||
|
||||
#include "lkc.h" |
||||
|
||||
static void conf(struct menu *menu); |
||||
static void check_conf(struct menu *menu); |
||||
static void xfgets(char *str, int size, FILE *in); |
||||
|
||||
enum input_mode { |
||||
oldaskconfig, |
||||
oldconfig, |
||||
allnoconfig, |
||||
allyesconfig, |
||||
allmodconfig, |
||||
alldefconfig, |
||||
randconfig, |
||||
defconfig, |
||||
savedefconfig, |
||||
listnewconfig, |
||||
oldnoconfig, |
||||
} input_mode = oldaskconfig; |
||||
|
||||
static int indent = 1; |
||||
static int valid_stdin = 1; |
||||
static int conf_cnt; |
||||
static char line[128]; |
||||
static struct menu *rootEntry; |
||||
|
||||
static void print_help(struct menu *menu) |
||||
{ |
||||
struct gstr help = str_new(); |
||||
|
||||
menu_get_ext_help(menu, &help); |
||||
|
||||
printf("\n%s\n", str_get(&help)); |
||||
str_free(&help); |
||||
} |
||||
|
||||
static void strip(char *str) |
||||
{ |
||||
char *p = str; |
||||
int l; |
||||
|
||||
while ((isspace(*p))) |
||||
p++; |
||||
l = strlen(p); |
||||
if (p != str) |
||||
memmove(str, p, l + 1); |
||||
if (!l) |
||||
return; |
||||
p = str + l - 1; |
||||
while ((isspace(*p))) |
||||
*p-- = 0; |
||||
} |
||||
|
||||
static void check_stdin(void) |
||||
{ |
||||
if (!valid_stdin) { |
||||
printf(_("aborted!\n\n")); |
||||
printf(_("Console input/output is redirected. ")); |
||||
printf(_("Run 'make config' to update configuration.\n\n")); |
||||
exit(1); |
||||
} |
||||
} |
||||
|
||||
static int conf_askvalue(struct symbol *sym, const char *def) |
||||
{ |
||||
enum symbol_type type = sym_get_type(sym); |
||||
|
||||
if (!sym_has_value(sym)) |
||||
printf(_("(NEW) ")); |
||||
|
||||
line[0] = '\n'; |
||||
line[1] = 0; |
||||
|
||||
if (!sym_is_changable(sym)) { |
||||
printf("%s\n", def); |
||||
line[0] = '\n'; |
||||
line[1] = 0; |
||||
return 0; |
||||
} |
||||
|
||||
switch (input_mode) { |
||||
case oldconfig: |
||||
if (sym_has_value(sym)) { |
||||
printf("%s\n", def); |
||||
return 0; |
||||
} |
||||
check_stdin(); |
||||
/* fall through */ |
||||
case oldaskconfig: |
||||
fflush(stdout); |
||||
xfgets(line, 128, stdin); |
||||
return 1; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
switch (type) { |
||||
case S_INT: |
||||
case S_HEX: |
||||
case S_STRING: |
||||
printf("%s\n", def); |
||||
return 1; |
||||
default: |
||||
; |
||||
} |
||||
printf("%s", line); |
||||
return 1; |
||||
} |
||||
|
||||
static int conf_string(struct menu *menu) |
||||
{ |
||||
struct symbol *sym = menu->sym; |
||||
const char *def; |
||||
|
||||
while (1) { |
||||
printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); |
||||
printf("(%s) ", sym->name); |
||||
def = sym_get_string_value(sym); |
||||
if (sym_get_string_value(sym)) |
||||
printf("[%s] ", def); |
||||
if (!conf_askvalue(sym, def)) |
||||
return 0; |
||||
switch (line[0]) { |
||||
case '\n': |
||||
break; |
||||
case '?': |
||||
/* print help */ |
||||
if (line[1] == '\n') { |
||||
print_help(menu); |
||||
def = NULL; |
||||
break; |
||||
} |
||||
/* fall through */ |
||||
default: |
||||
line[strlen(line)-1] = 0; |
||||
def = line; |
||||
} |
||||
if (def && sym_set_string_value(sym, def)) |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
static int conf_sym(struct menu *menu) |
||||
{ |
||||
struct symbol *sym = menu->sym; |
||||
tristate oldval, newval; |
||||
|
||||
while (1) { |
||||
printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); |
||||
if (sym->name) |
||||
printf("(%s) ", sym->name); |
||||
putchar('['); |
||||
oldval = sym_get_tristate_value(sym); |
||||
switch (oldval) { |
||||
case no: |
||||
putchar('N'); |
||||
break; |
||||
case mod: |
||||
putchar('M'); |
||||
break; |
||||
case yes: |
||||
putchar('Y'); |
||||
break; |
||||
} |
||||
if (oldval != no && sym_tristate_within_range(sym, no)) |
||||
printf("/n"); |
||||
if (oldval != mod && sym_tristate_within_range(sym, mod)) |
||||
printf("/m"); |
||||
if (oldval != yes && sym_tristate_within_range(sym, yes)) |
||||
printf("/y"); |
||||
if (menu_has_help(menu)) |
||||
printf("/?"); |
||||
printf("] "); |
||||
if (!conf_askvalue(sym, sym_get_string_value(sym))) |
||||
return 0; |
||||
strip(line); |
||||
|
||||
switch (line[0]) { |
||||
case 'n': |
||||
case 'N': |
||||
newval = no; |
||||
if (!line[1] || !strcmp(&line[1], "o")) |
||||
break; |
||||
continue; |
||||
case 'm': |
||||
case 'M': |
||||
newval = mod; |
||||
if (!line[1]) |
||||
break; |
||||
continue; |
||||
case 'y': |
||||
case 'Y': |
||||
newval = yes; |
||||
if (!line[1] || !strcmp(&line[1], "es")) |
||||
break; |
||||
continue; |
||||
case 0: |
||||
newval = oldval; |
||||
break; |
||||
case '?': |
||||
goto help; |
||||
default: |
||||
continue; |
||||
} |
||||
if (sym_set_tristate_value(sym, newval)) |
||||
return 0; |
||||
help: |
||||
print_help(menu); |
||||
} |
||||
} |
||||
|
||||
static int conf_choice(struct menu *menu) |
||||
{ |
||||
struct symbol *sym, *def_sym; |
||||
struct menu *child; |
||||
bool is_new; |
||||
|
||||
sym = menu->sym; |
||||
is_new = !sym_has_value(sym); |
||||
if (sym_is_changable(sym)) { |
||||
conf_sym(menu); |
||||
sym_calc_value(sym); |
||||
switch (sym_get_tristate_value(sym)) { |
||||
case no: |
||||
return 1; |
||||
case mod: |
||||
return 0; |
||||
case yes: |
||||
break; |
||||
} |
||||
} else { |
||||
switch (sym_get_tristate_value(sym)) { |
||||
case no: |
||||
return 1; |
||||
case mod: |
||||
printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); |
||||
return 0; |
||||
case yes: |
||||
break; |
||||
} |
||||
} |
||||
|
||||
while (1) { |
||||
int cnt, def; |
||||
|
||||
printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); |
||||
def_sym = sym_get_choice_value(sym); |
||||
cnt = def = 0; |
||||
line[0] = 0; |
||||
for (child = menu->list; child; child = child->next) { |
||||
if (!menu_is_visible(child)) |
||||
continue; |
||||
if (!child->sym) { |
||||
printf("%*c %s\n", indent, '*', _(menu_get_prompt(child))); |
||||
continue; |
||||
} |
||||
cnt++; |
||||
if (child->sym == def_sym) { |
||||
def = cnt; |
||||
printf("%*c", indent, '>'); |
||||
} else |
||||
printf("%*c", indent, ' '); |
||||
printf(" %d. %s", cnt, _(menu_get_prompt(child))); |
||||
if (child->sym->name) |
||||
printf(" (%s)", child->sym->name); |
||||
if (!sym_has_value(child->sym)) |
||||
printf(_(" (NEW)")); |
||||
printf("\n"); |
||||
} |
||||
printf(_("%*schoice"), indent - 1, ""); |
||||
if (cnt == 1) { |
||||
printf("[1]: 1\n"); |
||||
goto conf_childs; |
||||
} |
||||
printf("[1-%d", cnt); |
||||
if (menu_has_help(menu)) |
||||
printf("?"); |
||||
printf("]: "); |
||||
switch (input_mode) { |
||||
case oldconfig: |
||||
if (!is_new) { |
||||
cnt = def; |
||||
printf("%d\n", cnt); |
||||
break; |
||||
} |
||||
check_stdin(); |
||||
/* fall through */ |
||||
case oldaskconfig: |
||||
fflush(stdout); |
||||
xfgets(line, 128, stdin); |
||||
strip(line); |
||||
if (line[0] == '?') { |
||||
print_help(menu); |
||||
continue; |
||||
} |
||||
if (!line[0]) |
||||
cnt = def; |
||||
else if (isdigit(line[0])) |
||||
cnt = atoi(line); |
||||
else |
||||
continue; |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
conf_childs: |
||||
for (child = menu->list; child; child = child->next) { |
||||
if (!child->sym || !menu_is_visible(child)) |
||||
continue; |
||||
if (!--cnt) |
||||
break; |
||||
} |
||||
if (!child) |
||||
continue; |
||||
if (line[0] && line[strlen(line) - 1] == '?') { |
||||
print_help(child); |
||||
continue; |
||||
} |
||||
sym_set_choice_value(sym, child->sym); |
||||
for (child = child->list; child; child = child->next) { |
||||
indent += 2; |
||||
conf(child); |
||||
indent -= 2; |
||||
} |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
static void conf(struct menu *menu) |
||||
{ |
||||
struct symbol *sym; |
||||
struct property *prop; |
||||
struct menu *child; |
||||
|
||||
if (!menu_is_visible(menu)) |
||||
return; |
||||
|
||||
sym = menu->sym; |
||||
prop = menu->prompt; |
||||
if (prop) { |
||||
const char *prompt; |
||||
|
||||
switch (prop->type) { |
||||
case P_MENU: |
||||
if ((input_mode == listnewconfig || |
||||
input_mode == oldnoconfig) && |
||||
rootEntry != menu) { |
||||
check_conf(menu); |
||||
return; |
||||
} |
||||
/* fall through */ |
||||
case P_COMMENT: |
||||
prompt = menu_get_prompt(menu); |
||||
if (prompt) |
||||
printf("%*c\n%*c %s\n%*c\n", |
||||
indent, '*', |
||||
indent, '*', _(prompt), |
||||
indent, '*'); |
||||
default: |
||||
; |
||||
} |
||||
} |
||||
|
||||
if (!sym) |
||||
goto conf_childs; |
||||
|
||||
if (sym_is_choice(sym)) { |
||||
conf_choice(menu); |
||||
if (sym->curr.tri != mod) |
||||
return; |
||||
goto conf_childs; |
||||
} |
||||
|
||||
switch (sym->type) { |
||||
case S_INT: |
||||
case S_HEX: |
||||
case S_STRING: |
||||
conf_string(menu); |
||||
break; |
||||
default: |
||||
conf_sym(menu); |
||||
break; |
||||
} |
||||
|
||||
conf_childs: |
||||
if (sym) |
||||
indent += 2; |
||||
for (child = menu->list; child; child = child->next) |
||||
conf(child); |
||||
if (sym) |
||||
indent -= 2; |
||||
} |
||||
|
||||
static void check_conf(struct menu *menu) |
||||
{ |
||||
struct symbol *sym; |
||||
struct menu *child; |
||||
|
||||
if (!menu_is_visible(menu)) |
||||
return; |
||||
|
||||
sym = menu->sym; |
||||
if (sym && !sym_has_value(sym)) { |
||||
if (sym_is_changable(sym) || |
||||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { |
||||
if (input_mode == listnewconfig) { |
||||
if (sym->name && !sym_is_choice_value(sym)) { |
||||
printf("%s%s\n", CONFIG_, sym->name); |
||||
} |
||||
} else if (input_mode != oldnoconfig) { |
||||
if (!conf_cnt++) |
||||
printf(_("*\n* Restart config...\n*\n")); |
||||
rootEntry = menu_get_parent_menu(menu); |
||||
conf(rootEntry); |
||||
} |
||||
} |
||||
} |
||||
|
||||
for (child = menu->list; child; child = child->next) |
||||
check_conf(child); |
||||
} |
||||
|
||||
static struct option long_opts[] = { |
||||
{"askconfig", no_argument, NULL, oldaskconfig}, |
||||
{"config", no_argument, NULL, oldconfig}, |
||||
{"defconfig", optional_argument, NULL, defconfig}, |
||||
{"savedefconfig", required_argument, NULL, savedefconfig}, |
||||
{"allnoconfig", no_argument, NULL, allnoconfig}, |
||||
{"allyesconfig", no_argument, NULL, allyesconfig}, |
||||
{"allmodconfig", no_argument, NULL, allmodconfig}, |
||||
{"alldefconfig", no_argument, NULL, alldefconfig}, |
||||
{"randconfig", no_argument, NULL, randconfig}, |
||||
{"listnewconfig", no_argument, NULL, listnewconfig}, |
||||
{"noconfig", no_argument, NULL, oldnoconfig}, |
||||
{NULL, 0, NULL, 0} |
||||
}; |
||||
|
||||
static void conf_usage(const char *progname) |
||||
{ |
||||
|
||||
printf("Usage: %s [option] <kconfig-file>\n", progname); |
||||
printf("[option] is _one_ of the following:\n"); |
||||
printf(" --listnewconfig List new options\n"); |
||||
printf(" --askconfig Start a new configuration using a line-oriented program\n"); |
||||
printf(" --config Update a configuration using a provided .config as base\n"); |
||||
printf(" --silentconfig Same as config, but quietly, additionally update deps\n"); |
||||
printf(" --noconfig Same as silentconfig but set new symbols to no\n"); |
||||
printf(" --defconfig <file> New config with default defined in <file>\n"); |
||||
printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n"); |
||||
printf(" --allnoconfig New config where all options are answered with no\n"); |
||||
printf(" --allyesconfig New config where all options are answered with yes\n"); |
||||
printf(" --allmodconfig New config where all options are answered with mod\n"); |
||||
printf(" --alldefconfig New config with all symbols set to default\n"); |
||||
printf(" --randconfig New config with random answer to all options\n"); |
||||
} |
||||
|
||||
int main(int ac, char **av) |
||||
{ |
||||
const char *progname = av[0]; |
||||
int opt; |
||||
const char *name, *defconfig_file = NULL /* gcc uninit */; |
||||
struct stat tmpstat; |
||||
|
||||
setlocale(LC_ALL, ""); |
||||
bindtextdomain(PACKAGE, LOCALEDIR); |
||||
textdomain(PACKAGE); |
||||
|
||||
while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) { |
||||
input_mode = (enum input_mode)opt; |
||||
switch (opt) { |
||||
case defconfig: |
||||
case savedefconfig: |
||||
defconfig_file = optarg; |
||||
break; |
||||
case randconfig: |
||||
{ |
||||
struct timeval now; |
||||
unsigned int seed; |
||||
|
||||
/* |
||||
* Use microseconds derived seed, |
||||
* compensate for systems where it may be zero |
||||
*/ |
||||
gettimeofday(&now, NULL); |
||||
|
||||
seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); |
||||
srand(seed); |
||||
break; |
||||
} |
||||
case oldaskconfig: |
||||
case oldconfig: |
||||
case allnoconfig: |
||||
case allyesconfig: |
||||
case allmodconfig: |
||||
case alldefconfig: |
||||
case listnewconfig: |
||||
case oldnoconfig: |
||||
break; |
||||
case '?': |
||||
conf_usage(progname); |
||||
exit(1); |
||||
break; |
||||
} |
||||
} |
||||
if (ac == optind) { |
||||
printf(_("%s: Kconfig file missing\n"), av[0]); |
||||
conf_usage(progname); |
||||
exit(1); |
||||
} |
||||
name = av[optind]; |
||||
conf_parse(name); |
||||
//zconfdump(stdout); |
||||
|
||||
switch (input_mode) { |
||||
case defconfig: |
||||
if (!defconfig_file) |
||||
defconfig_file = conf_get_default_confname(); |
||||
if (conf_read(defconfig_file)) { |
||||
printf(_("***\n" |
||||
"*** Can't find default configuration \"%s\"!\n" |
||||
"***\n"), defconfig_file); |
||||
exit(1); |
||||
} |
||||
break; |
||||
case savedefconfig: |
||||
case oldaskconfig: |
||||
case oldconfig: |
||||
case listnewconfig: |
||||
case oldnoconfig: |
||||
conf_read(NULL); |
||||
break; |
||||
case allnoconfig: |
||||
case allyesconfig: |
||||
case allmodconfig: |
||||
case alldefconfig: |
||||
case randconfig: |
||||
name = getenv("KCONFIG_ALLCONFIG"); |
||||
if (name && !stat(name, &tmpstat)) { |
||||
conf_read_simple(name, S_DEF_USER); |
||||
break; |
||||
} |
||||
switch (input_mode) { |
||||
case allnoconfig: name = "allno.config"; break; |
||||
case allyesconfig: name = "allyes.config"; break; |
||||
case allmodconfig: name = "allmod.config"; break; |
||||
case alldefconfig: name = "alldef.config"; break; |
||||
case randconfig: name = "allrandom.config"; break; |
||||
default: break; |
||||
} |
||||
if (!stat(name, &tmpstat)) |
||||
conf_read_simple(name, S_DEF_USER); |
||||
else if (!stat("all.config", &tmpstat)) |
||||
conf_read_simple("all.config", S_DEF_USER); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
valid_stdin = isatty(0) && isatty(1) && isatty(2); |
||||
|
||||
switch (input_mode) { |
||||
case allnoconfig: |
||||
conf_set_all_new_symbols(def_no); |
||||
break; |
||||
case allyesconfig: |
||||
conf_set_all_new_symbols(def_yes); |
||||
break; |
||||
case allmodconfig: |
||||
conf_set_all_new_symbols(def_mod); |
||||
break; |
||||
case alldefconfig: |
||||
conf_set_all_new_symbols(def_default); |
||||
break; |
||||
case randconfig: |
||||
conf_set_all_new_symbols(def_random); |
||||
break; |
||||
case defconfig: |
||||
conf_set_all_new_symbols(def_default); |
||||
break; |
||||
case savedefconfig: |
||||
break; |
||||
case oldaskconfig: |
||||
rootEntry = &rootmenu; |
||||
conf(&rootmenu); |
||||
input_mode = oldconfig; |
||||
/* fall through */ |
||||
case oldconfig: |
||||
case listnewconfig: |
||||
case oldnoconfig: |
||||
/* Update until a loop caused no more changes */ |
||||
do { |
||||
conf_cnt = 0; |
||||
check_conf(&rootmenu); |
||||
} while (conf_cnt && |
||||
(input_mode != listnewconfig && |
||||
input_mode != oldnoconfig)); |
||||
break; |
||||
} |
||||
|
||||
if (input_mode == savedefconfig) { |
||||
if (conf_write_defconfig(defconfig_file)) { |
||||
fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), |
||||
defconfig_file); |
||||
return 1; |
||||
} |
||||
} else if (input_mode != listnewconfig) { |
||||
/* |
||||
* build so we shall update autoconf. |
||||
*/ |
||||
if (conf_write(NULL)) { |
||||
fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); |
||||
exit(1); |
||||
} |
||||
if (conf_write_autoconf()) { |
||||
fprintf(stderr, _("\n*** Error during update of the configuration.\n\n")); |
||||
return 1; |
||||
} |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
/* |
||||
* Helper function to facilitate fgets() by Jean Sacren. |
||||
*/ |
||||
void xfgets(char *str, int size, FILE *in) |
||||
{ |
||||
if (fgets(str, size, in) == NULL) |
||||
fprintf(stderr, "\nError in reading or end of file.\n"); |
||||
} |
@ -0,0 +1,225 @@
@@ -0,0 +1,225 @@
|
||||
/* |
||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |
||||
* Released under the terms of the GNU GPL v2.0. |
||||
*/ |
||||
|
||||
#ifndef EXPR_H |
||||
#define EXPR_H |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#include <assert.h> |
||||
#include <stdio.h> |
||||
#ifndef __cplusplus |
||||
#include <stdbool.h> |
||||
#endif |
||||
|
||||
struct file { |
||||
struct file *next; |
||||
struct file *parent; |
||||
const char *name; |
||||
int lineno; |
||||
}; |
||||
|
||||
typedef enum tristate { |
||||
no, mod, yes |
||||
} tristate; |
||||
|
||||
enum expr_type { |
||||
E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE |
||||
}; |
||||
|
||||
union expr_data { |
||||
struct expr *expr; |
||||
struct symbol *sym; |
||||
}; |
||||
|
||||
struct expr { |
||||
enum expr_type type; |
||||
union expr_data left, right; |
||||
}; |
||||
|
||||
#define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) |
||||
#define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) |
||||
#define EXPR_NOT(dep) (2-(dep)) |
||||
|
||||
#define expr_list_for_each_sym(l, e, s) \ |
||||
for (e = (l); e && (s = e->right.sym); e = e->left.expr) |
||||
|
||||
struct expr_value { |
||||
struct expr *expr; |
||||
tristate tri; |
||||
}; |
||||
|
||||
struct symbol_value { |
||||
void *val; |
||||
tristate tri; |
||||
}; |
||||
|
||||
enum symbol_type { |
||||
S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER |
||||
}; |
||||
|
||||
/* enum values are used as index to symbol.def[] */ |
||||
enum { |
||||
S_DEF_USER, /* main user value */ |
||||
S_DEF_AUTO, /* values read from auto.conf */ |
||||
S_DEF_DEF3, /* Reserved for UI usage */ |
||||
S_DEF_DEF4, /* Reserved for UI usage */ |
||||
S_DEF_COUNT |
||||
}; |
||||
|
||||
struct symbol { |
||||
struct symbol *next; |
||||
char *name; |
||||
enum symbol_type type; |
||||
struct symbol_value curr; |
||||
struct symbol_value def[S_DEF_COUNT]; |
||||
tristate visible; |
||||
int flags; |
||||
struct property *prop; |
||||
struct expr_value dir_dep; |
||||
struct expr_value rev_dep; |
||||
}; |
||||
|
||||
#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) |
||||
|
||||
#define SYMBOL_CONST 0x0001 /* symbol is const */ |
||||
#define SYMBOL_CHECK 0x0008 /* used during dependency checking */ |
||||
#define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */ |
||||
#define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */ |
||||
#define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ |
||||
#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ |
||||
#define SYMBOL_WRITE 0x0200 /* ? */ |
||||
#define SYMBOL_CHANGED 0x0400 /* ? */ |
||||
#define SYMBOL_AUTO 0x1000 /* value from environment variable */ |
||||
#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ |
||||
#define SYMBOL_WARNED 0x8000 /* warning has been issued */ |
||||
|
||||
/* Set when symbol.def[] is used */ |
||||
#define SYMBOL_DEF 0x10000 /* First bit of SYMBOL_DEF */ |
||||
#define SYMBOL_DEF_USER 0x10000 /* symbol.def[S_DEF_USER] is valid */ |
||||
#define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */ |
||||
#define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ |
||||
#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ |
||||
|
||||
#define SYMBOL_MAXLENGTH 256 |
||||
#define SYMBOL_HASHSIZE 9973 |
||||
|
||||
/* A property represent the config options that can be associated |
||||
* with a config "symbol". |
||||
* Sample: |
||||
* config FOO |
||||
* default y |
||||
* prompt "foo prompt" |
||||
* select BAR |
||||
* config BAZ |
||||
* int "BAZ Value" |
||||
* range 1..255 |
||||
*/ |
||||
enum prop_type { |
||||
P_UNKNOWN, |
||||
P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */ |
||||
P_COMMENT, /* text associated with a comment */ |
||||
P_MENU, /* prompt associated with a menuconfig option */ |
||||
P_DEFAULT, /* default y */ |
||||
P_CHOICE, /* choice value */ |
||||
P_SELECT, /* select BAR */ |
||||
P_RANGE, /* range 7..100 (for a symbol) */ |
||||
P_ENV, /* value from environment variable */ |
||||
P_SYMBOL, /* where a symbol is defined */ |
||||
}; |
||||
|
||||
struct property { |
||||
struct property *next; /* next property - null if last */ |
||||
struct symbol *sym; /* the symbol for which the property is associated */ |
||||
enum prop_type type; /* type of property */ |
||||
const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ |
||||
struct expr_value visible; |
||||
struct expr *expr; /* the optional conditional part of the property */ |
||||
struct menu *menu; /* the menu the property are associated with |
||||
* valid for: P_SELECT, P_RANGE, P_CHOICE, |
||||
* P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ |
||||
struct file *file; /* what file was this property defined */ |
||||
int lineno; /* what lineno was this property defined */ |
||||
}; |
||||
|
||||
#define for_all_properties(sym, st, tok) \ |
||||
for (st = sym->prop; st; st = st->next) \ |
||||
if (st->type == (tok)) |
||||
#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) |
||||
#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) |
||||
#define for_all_prompts(sym, st) \ |
||||
for (st = sym->prop; st; st = st->next) \ |
||||
if (st->text) |
||||
|
||||
struct menu { |
||||
struct menu *next; |
||||
struct menu *parent; |
||||
struct menu *list; |
||||
struct symbol *sym; |
||||
struct property *prompt; |
||||
struct expr *visibility; |
||||
struct expr *dep; |
||||
unsigned int flags; |
||||
char *help; |
||||
struct file *file; |
||||
int lineno; |
||||
void *data; |
||||
}; |
||||
|
||||
#define MENU_CHANGED 0x0001 |
||||
#define MENU_ROOT 0x0002 |
||||
|
||||
extern struct file *file_list; |
||||
extern struct file *current_file; |
||||
struct file *lookup_file(const char *name); |
||||
|
||||
extern struct symbol symbol_yes, symbol_no, symbol_mod; |
||||
extern struct symbol *modules_sym; |
||||
extern struct symbol *sym_defconfig_list; |
||||
extern int cdebug; |
||||
struct expr *expr_alloc_symbol(struct symbol *sym); |
||||
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); |
||||
struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); |
||||
struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); |
||||
struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); |
||||
struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); |
||||
struct expr *expr_copy(const struct expr *org); |
||||
void expr_free(struct expr *e); |
||||
int expr_eq(struct expr *e1, struct expr *e2); |
||||
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); |
||||
tristate expr_calc_value(struct expr *e); |
||||
struct expr *expr_eliminate_yn(struct expr *e); |
||||
struct expr *expr_trans_bool(struct expr *e); |
||||
struct expr *expr_eliminate_dups(struct expr *e); |
||||
struct expr *expr_transform(struct expr *e); |
||||
int expr_contains_symbol(struct expr *dep, struct symbol *sym); |
||||
bool expr_depends_symbol(struct expr *dep, struct symbol *sym); |
||||
struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); |
||||
struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); |
||||
void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); |
||||
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); |
||||
struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2); |
||||
|
||||
void expr_fprint(struct expr *e, FILE *out); |
||||
struct gstr; /* forward */ |
||||
void expr_gstr_print(struct expr *e, struct gstr *gs); |
||||
|
||||
static inline int expr_is_yes(struct expr *e) |
||||
{ |
||||
return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); |
||||
} |
||||
|
||||
static inline int expr_is_no(struct expr *e) |
||||
{ |
||||
return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); |
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* EXPR_H */ |
@ -0,0 +1,190 @@
@@ -0,0 +1,190 @@
|
||||
/* |
||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |
||||
* Released under the terms of the GNU GPL v2.0. |
||||
*/ |
||||
|
||||
#ifndef LKC_H |
||||
#define LKC_H |
||||
|
||||
#include "expr.h" |
||||
|
||||
#ifndef KBUILD_NO_NLS |
||||
# include <libintl.h> |
||||
#else |
||||
static inline const char *gettext(const char *txt) { return txt; } |
||||
static inline void textdomain(const char *domainname) {} |
||||
static inline void bindtextdomain(const char *name, const char *dir) {} |
||||
static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; } |
||||
#endif |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#define P(name,type,arg) extern type name arg |
||||
#include "lkc_proto.h" |
||||
#undef P |
||||
|
||||
#define SRCTREE "srctree" |
||||
|
||||
#ifndef PACKAGE |
||||
#define PACKAGE "linux" |
||||
#endif |
||||
|
||||
#define LOCALEDIR "/usr/share/locale" |
||||
|
||||
#define _(text) gettext(text) |
||||
#define N_(text) (text) |
||||
|
||||
#ifndef CONFIG_ |
||||
#define CONFIG_ "CONFIG_" |
||||
#endif |
||||
|
||||
#define TF_COMMAND 0x0001 |
||||
#define TF_PARAM 0x0002 |
||||
#define TF_OPTION 0x0004 |
||||
|
||||
enum conf_def_mode { |
||||
def_default, |
||||
def_yes, |
||||
def_mod, |
||||
def_no, |
||||
def_random |
||||
}; |
||||
|
||||
#define T_OPT_MODULES 1 |
||||
#define T_OPT_DEFCONFIG_LIST 2 |
||||
#define T_OPT_ENV 3 |
||||
|
||||
struct kconf_id { |
||||
int name; |
||||
int token; |
||||
unsigned int flags; |
||||
enum symbol_type stype; |
||||
}; |
||||
|
||||
extern int zconfdebug; |
||||
|
||||
int zconfparse(void); |
||||
void zconfdump(FILE *out); |
||||
void zconf_starthelp(void); |
||||
FILE *zconf_fopen(const char *name); |
||||
void zconf_initscan(const char *name); |
||||
void zconf_nextfile(const char *name); |
||||
int zconf_lineno(void); |
||||
const char *zconf_curname(void); |
||||
|
||||
/* confdata.c */ |
||||
const char *conf_get_configname(void); |
||||
const char *conf_get_autoconfig_name(void); |
||||
char *conf_get_default_confname(void); |
||||
void sym_set_change_count(int count); |
||||
void sym_add_change_count(int count); |
||||
void conf_set_all_new_symbols(enum conf_def_mode mode); |
||||
|
||||
struct conf_printer { |
||||
void (*print_symbol)(FILE *, struct symbol *, const char *, void *); |
||||
void (*print_comment)(FILE *, const char *, void *); |
||||
}; |
||||
|
||||
/* confdata.c and expr.c */ |
||||
static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) |
||||
{ |
||||
assert(len != 0); |
||||
|
||||
if (fwrite(str, len, count, out) != count) |
||||
fprintf(stderr, "Error in writing or end of file.\n"); |
||||
} |
||||
|
||||
/* menu.c */ |
||||
void _menu_init(void); |
||||
void menu_warn(struct menu *menu, const char *fmt, ...); |
||||
struct menu *menu_add_menu(void); |
||||
void menu_end_menu(void); |
||||
void menu_add_entry(struct symbol *sym); |
||||
void menu_end_entry(void); |
||||
void menu_add_dep(struct expr *dep); |
||||
void menu_add_visibility(struct expr *dep); |
||||
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); |
||||
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); |
||||
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); |
||||
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); |
||||
void menu_add_option(int token, char *arg); |
||||
void menu_finalize(struct menu *parent); |
||||
void menu_set_type(int type); |
||||
|
||||
/* util.c */ |
||||
struct file *file_lookup(const char *name); |
||||
int file_write_dep(const char *name); |
||||
|
||||
struct gstr { |
||||
size_t len; |
||||
char *s; |
||||
/* |
||||
* when max_width is not zero long lines in string s (if any) get |
||||
* wrapped not to exceed the max_width value |
||||
*/ |
||||
int max_width; |
||||
}; |
||||
struct gstr str_new(void); |
||||
struct gstr str_assign(const char *s); |
||||
void str_free(struct gstr *gs); |
||||
void str_append(struct gstr *gs, const char *s); |
||||
void str_printf(struct gstr *gs, const char *fmt, ...); |
||||
const char *str_get(struct gstr *gs); |
||||
|
||||
/* symbol.c */ |
||||
extern struct expr *sym_env_list; |
||||
|
||||
void sym_init(void); |
||||
void sym_clear_all_valid(void); |
||||
void sym_set_all_changed(void); |
||||
void sym_set_changed(struct symbol *sym); |
||||
struct symbol *sym_choice_default(struct symbol *sym); |
||||
const char *sym_get_string_default(struct symbol *sym); |
||||
struct symbol *sym_check_deps(struct symbol *sym); |
||||
struct property *prop_alloc(enum prop_type type, struct symbol *sym); |
||||
struct symbol *prop_get_symbol(struct property *prop); |
||||
struct property *sym_get_env_prop(struct symbol *sym); |
||||
|
||||
static inline tristate sym_get_tristate_value(struct symbol *sym) |
||||
{ |
||||
return sym->curr.tri; |
||||
} |
||||
|
||||
|
||||
static inline struct symbol *sym_get_choice_value(struct symbol *sym) |
||||
{ |
||||
return (struct symbol *)sym->curr.val; |
||||
} |
||||
|
||||
static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval) |
||||
{ |
||||
return sym_set_tristate_value(chval, yes); |
||||
} |
||||
|
||||
static inline bool sym_is_choice(struct symbol *sym) |
||||
{ |
||||
return sym->flags & SYMBOL_CHOICE ? true : false; |
||||
} |
||||
|
||||
static inline bool sym_is_choice_value(struct symbol *sym) |
||||
{ |
||||
return sym->flags & SYMBOL_CHOICEVAL ? true : false; |
||||
} |
||||
|
||||
static inline bool sym_is_optional(struct symbol *sym) |
||||
{ |
||||
return sym->flags & SYMBOL_OPTIONAL ? true : false; |
||||
} |
||||
|
||||
static inline bool sym_has_value(struct symbol *sym) |
||||
{ |
||||
return sym->flags & SYMBOL_DEF_USER ? true : false; |
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* LKC_H */ |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
#include <stdarg.h> |
||||
|
||||
/* confdata.c */ |
||||
P(conf_parse,void,(const char *name)); |
||||
P(conf_read,int,(const char *name)); |
||||
P(conf_read_simple,int,(const char *name, int)); |
||||
P(conf_write_defconfig,int,(const char *name)); |
||||
P(conf_write,int,(const char *name)); |
||||
P(conf_write_autoconf,int,(void)); |
||||
P(conf_get_changed,bool,(void)); |
||||
P(conf_set_changed_callback, void,(void (*fn)(void))); |
||||
P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap))); |
||||
|
||||
/* menu.c */ |
||||
P(rootmenu,struct menu,); |
||||
|
||||
P(menu_is_visible, bool, (struct menu *menu)); |
||||
P(menu_has_prompt, bool, (struct menu *menu)); |
||||
P(menu_get_prompt,const char *,(struct menu *menu)); |
||||
P(menu_get_root_menu,struct menu *,(struct menu *menu)); |
||||
P(menu_get_parent_menu,struct menu *,(struct menu *menu)); |
||||
P(menu_has_help,bool,(struct menu *menu)); |
||||
P(menu_get_help,const char *,(struct menu *menu)); |
||||
P(get_symbol_str, void, (struct gstr *r, struct symbol *sym)); |
||||
P(get_relations_str, struct gstr, (struct symbol **sym_arr)); |
||||
P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); |
||||
|
||||
/* symbol.c */ |
||||
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); |
||||
|
||||
P(sym_lookup,struct symbol *,(const char *name, int flags)); |
||||
P(sym_find,struct symbol *,(const char *name)); |
||||
P(sym_expand_string_value,const char *,(const char *in)); |
||||
P(sym_escape_string_value, const char *,(const char *in)); |
||||
P(sym_re_search,struct symbol **,(const char *pattern)); |
||||
P(sym_type_name,const char *,(enum symbol_type type)); |
||||
P(sym_calc_value,void,(struct symbol *sym)); |
||||
P(sym_get_type,enum symbol_type,(struct symbol *sym)); |
||||
P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); |
||||
P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); |
||||
P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); |
||||
P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); |
||||
P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); |
||||
P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); |
||||
P(sym_is_changable,bool,(struct symbol *sym)); |
||||
P(sym_get_choice_prop,struct property *,(struct symbol *sym)); |
||||
P(sym_get_default_prop,struct property *,(struct symbol *sym)); |
||||
P(sym_get_string_value,const char *,(struct symbol *sym)); |
||||
|
||||
P(prop_get_type_name,const char *,(enum prop_type type)); |
||||
|
||||
/* expr.c */ |
||||
P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); |
||||
P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)); |
@ -0,0 +1,607 @@
@@ -0,0 +1,607 @@
|
||||
/* |
||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |
||||
* Released under the terms of the GNU GPL v2.0. |
||||
*/ |
||||
|
||||
#include <ctype.h> |
||||
#include <stdarg.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "lkc.h" |
||||
|
||||
static const char nohelp_text[] = "There is no help available for this option."; |
||||
|
||||
struct menu rootmenu; |
||||
static struct menu **last_entry_ptr; |
||||
|
||||
struct file *file_list; |
||||
struct file *current_file; |
||||
|
||||
void menu_warn(struct menu *menu, const char *fmt, ...) |
||||
{ |
||||
va_list ap; |
||||
va_start(ap, fmt); |
||||
fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno); |
||||
vfprintf(stderr, fmt, ap); |
||||
fprintf(stderr, "\n"); |
||||
va_end(ap); |
||||
} |
||||
|
||||
static void prop_warn(struct property *prop, const char *fmt, ...) |
||||
{ |
||||
va_list ap; |
||||
va_start(ap, fmt); |
||||
fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno); |
||||
vfprintf(stderr, fmt, ap); |
||||
fprintf(stderr, "\n"); |
||||
va_end(ap); |
||||
} |
||||
|
||||
void _menu_init(void) |
||||
{ |
||||
current_entry = current_menu = &rootmenu; |
||||
last_entry_ptr = &rootmenu.list; |
||||
} |
||||
|
||||
void menu_add_entry(struct symbol *sym) |
||||
{ |
||||
struct menu *menu; |
||||
|
||||
menu = malloc(sizeof(*menu)); |
||||
memset(menu, 0, sizeof(*menu)); |
||||
menu->sym = sym; |
||||
menu->parent = current_menu; |
||||
menu->file = current_file; |
||||
menu->lineno = zconf_lineno(); |
||||
|
||||
*last_entry_ptr = menu; |
||||
last_entry_ptr = &menu->next; |
||||
current_entry = menu; |
||||
if (sym) |
||||
menu_add_symbol(P_SYMBOL, sym, NULL); |
||||
} |
||||
|
||||
void menu_end_entry(void) |
||||
{ |
||||
} |
||||
|
||||
struct menu *menu_add_menu(void) |
||||
{ |
||||
menu_end_entry(); |
||||
last_entry_ptr = ¤t_entry->list; |
||||
return current_menu = current_entry; |
||||
} |
||||
|
||||
void menu_end_menu(void) |
||||
{ |
||||
last_entry_ptr = ¤t_menu->next; |
||||
current_menu = current_menu->parent; |
||||
} |
||||
|
||||
static struct expr *menu_check_dep(struct expr *e) |
||||
{ |
||||
if (!e) |
||||
return e; |
||||
|
||||
switch (e->type) { |
||||
case E_NOT: |
||||
e->left.expr = menu_check_dep(e->left.expr); |
||||
break; |
||||
case E_OR: |
||||
case E_AND: |
||||
e->left.expr = menu_check_dep(e->left.expr); |
||||
e->right.expr = menu_check_dep(e->right.expr); |
||||
break; |
||||
case E_SYMBOL: |
||||
/* change 'm' into 'm' && MODULES */ |
||||
if (e->left.sym == &symbol_mod) |
||||
return expr_alloc_and(e, expr_alloc_symbol(modules_sym)); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
return e; |
||||
} |
||||
|
||||
void menu_add_dep(struct expr *dep) |
||||
{ |
||||
current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); |
||||
} |
||||
|
||||
void menu_set_type(int type) |
||||
{ |
||||
struct symbol *sym = current_entry->sym; |
||||
|
||||
if (sym->type == type) |
||||
return; |
||||
if (sym->type == S_UNKNOWN) { |
||||
sym->type = type; |
||||
return; |
||||
} |
||||
menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'", |
||||
sym->name ? sym->name : "<choice>", |
||||
sym_type_name(sym->type), sym_type_name(type)); |
||||
} |
||||
|
||||
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) |
||||
{ |
||||
struct property *prop = prop_alloc(type, current_entry->sym); |
||||
|
||||
prop->menu = current_entry; |
||||
prop->expr = expr; |
||||
prop->visible.expr = menu_check_dep(dep); |
||||
|
||||
if (prompt) { |
||||
if (isspace(*prompt)) { |
||||
prop_warn(prop, "leading whitespace ignored"); |
||||
while (isspace(*prompt)) |
||||
prompt++; |
||||
} |
||||
if (current_entry->prompt && current_entry != &rootmenu) |
||||
prop_warn(prop, "prompt redefined"); |
||||
|
||||
/* Apply all upper menus' visibilities to actual prompts. */ |
||||
if(type == P_PROMPT) { |
||||
struct menu *menu = current_entry; |
||||
|
||||
while ((menu = menu->parent) != NULL) { |
||||
if (!menu->visibility) |
||||
continue; |
||||
prop->visible.expr |
||||
= expr_alloc_and(prop->visible.expr, |
||||
menu->visibility); |
||||
} |
||||
} |
||||
|
||||
current_entry->prompt = prop; |
||||
} |
||||
prop->text = prompt; |
||||
|
||||
return prop; |
||||
} |
||||
|
||||
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) |
||||
{ |
||||
return menu_add_prop(type, prompt, NULL, dep); |
||||
} |
||||
|
||||
void menu_add_visibility(struct expr *expr) |
||||
{ |
||||
current_entry->visibility = expr_alloc_and(current_entry->visibility, |
||||
expr); |
||||
} |
||||
|
||||
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) |
||||
{ |
||||
menu_add_prop(type, NULL, expr, dep); |
||||
} |
||||
|
||||
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) |
||||
{ |
||||
menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); |
||||
} |
||||
|
||||
void menu_add_option(int token, char *arg) |
||||
{ |
||||
struct property *prop; |
||||
|
||||
switch (token) { |
||||
case T_OPT_MODULES: |
||||
prop = prop_alloc(P_DEFAULT, modules_sym); |
||||
prop->expr = expr_alloc_symbol(current_entry->sym); |
||||
break; |
||||
case T_OPT_DEFCONFIG_LIST: |
||||
if (!sym_defconfig_list) |
||||
sym_defconfig_list = current_entry->sym; |
||||
else if (sym_defconfig_list != current_entry->sym) |
||||
zconf_error("trying to redefine defconfig symbol"); |
||||
break; |
||||
case T_OPT_ENV: |
||||
prop_add_env(arg); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
static int menu_validate_number(struct symbol *sym, struct symbol *sym2) |
||||
{ |
||||
return sym2->type == S_INT || sym2->type == S_HEX || |
||||
(sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); |
||||
} |
||||
|
||||
static void sym_check_prop(struct symbol *sym) |
||||
{ |
||||
struct property *prop; |
||||
struct symbol *sym2; |
||||
for (prop = sym->prop; prop; prop = prop->next) { |
||||
switch (prop->type) { |
||||
case P_DEFAULT: |
||||
if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && |
||||
prop->expr->type != E_SYMBOL) |
||||
prop_warn(prop, |
||||
"default for config symbol '%s'" |
||||
" must be a single symbol", sym->name); |
||||
if (prop->expr->type != E_SYMBOL) |
||||
break; |
||||
sym2 = prop_get_symbol(prop); |
||||
if (sym->type == S_HEX || sym->type == S_INT) { |
||||
if (!menu_validate_number(sym, sym2)) |
||||
prop_warn(prop, |
||||
"'%s': number is invalid", |
||||
sym->name); |
||||
} |
||||
break; |
||||
case P_SELECT: |
||||
sym2 = prop_get_symbol(prop); |
||||
if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) |
||||
prop_warn(prop, |
||||
"config symbol '%s' uses select, but is " |
||||
"not boolean or tristate", sym->name); |
||||
else if (sym2->type != S_UNKNOWN && |
||||
sym2->type != S_BOOLEAN && |
||||
sym2->type != S_TRISTATE) |
||||
prop_warn(prop, |
||||
"'%s' has wrong type. 'select' only " |
||||
"accept arguments of boolean and " |
||||
"tristate type", sym2->name); |
||||
break; |
||||
case P_RANGE: |
||||
if (sym->type != S_INT && sym->type != S_HEX) |
||||
prop_warn(prop, "range is only allowed " |
||||
"for int or hex symbols"); |
||||
if (!menu_validate_number(sym, prop->expr->left.sym) || |
||||
!menu_validate_number(sym, prop->expr->right.sym)) |
||||
prop_warn(prop, "range is invalid"); |
||||
break; |
||||
default: |
||||
; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void menu_finalize(struct menu *parent) |
||||
{ |
||||
struct menu *menu, *last_menu; |
||||
struct symbol *sym; |
||||
struct property *prop; |
||||
struct expr *parentdep, *basedep, *dep, *dep2, **ep; |
||||
|
||||
sym = parent->sym; |
||||
if (parent->list) { |
||||
if (sym && sym_is_choice(sym)) { |
||||
if (sym->type == S_UNKNOWN) { |
||||
/* find the first choice value to find out choice type */ |
||||
current_entry = parent; |
||||
for (menu = parent->list; menu; menu = menu->next) { |
||||
if (menu->sym && menu->sym->type != S_UNKNOWN) { |
||||
menu_set_type(menu->sym->type); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
/* set the type of the remaining choice values */ |
||||
for (menu = parent->list; menu; menu = menu->next) { |
||||
current_entry = menu; |
||||
if (menu->sym && menu->sym->type == S_UNKNOWN) |
||||
menu_set_type(sym->type); |
||||
} |
||||
parentdep = expr_alloc_symbol(sym); |
||||
} else if (parent->prompt) |
||||
parentdep = parent->prompt->visible.expr; |
||||
else |
||||
parentdep = parent->dep; |
||||
|
||||
for (menu = parent->list; menu; menu = menu->next) { |
||||
basedep = expr_transform(menu->dep); |
||||
basedep = expr_alloc_and(expr_copy(parentdep), basedep); |
||||
basedep = expr_eliminate_dups(basedep); |
||||
menu->dep = basedep; |
||||
if (menu->sym) |
||||
prop = menu->sym->prop; |
||||
else |
||||
prop = menu->prompt; |
||||
for (; prop; prop = prop->next) { |
||||
if (prop->menu != menu) |
||||
continue; |
||||
dep = expr_transform(prop->visible.expr); |
||||
dep = expr_alloc_and(expr_copy(basedep), dep); |
||||
dep = expr_eliminate_dups(dep); |
||||
if (menu->sym && menu->sym->type != S_TRISTATE) |
||||
dep = expr_trans_bool(dep); |
||||
prop->visible.expr = dep; |
||||
if (prop->type == P_SELECT) { |
||||
struct symbol *es = prop_get_symbol(prop); |
||||
es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, |
||||
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); |
||||
} |
||||
} |
||||
} |
||||
for (menu = parent->list; menu; menu = menu->next) |
||||
menu_finalize(menu); |
||||
} else if (sym) { |
||||
basedep = parent->prompt ? parent->prompt->visible.expr : NULL; |
||||
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); |
||||
basedep = expr_eliminate_dups(expr_transform(basedep)); |
||||
last_menu = NULL; |
||||
for (menu = parent->next; menu; menu = menu->next) { |
||||
dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; |
||||
if (!expr_contains_symbol(dep, sym)) |
||||
break; |
||||
if (expr_depends_symbol(dep, sym)) |
||||
goto next; |
||||
dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); |
||||
dep = expr_eliminate_dups(expr_transform(dep)); |
||||
dep2 = expr_copy(basedep); |
||||
expr_eliminate_eq(&dep, &dep2); |
||||
expr_free(dep); |
||||
if (!expr_is_yes(dep2)) { |
||||
expr_free(dep2); |
||||
break; |
||||
} |
||||
expr_free(dep2); |
||||
next: |
||||
menu_finalize(menu); |
||||
menu->parent = parent; |
||||
last_menu = menu; |
||||
} |
||||
if (last_menu) { |
||||
parent->list = parent->next; |
||||
parent->next = last_menu->next; |
||||
last_menu->next = NULL; |
||||
} |
||||
|
||||
sym->dir_dep.expr = expr_alloc_or(sym->dir_dep.expr, parent->dep); |
||||
} |
||||
for (menu = parent->list; menu; menu = menu->next) { |
||||
if (sym && sym_is_choice(sym) && |
||||
menu->sym && !sym_is_choice_value(menu->sym)) { |
||||
current_entry = menu; |
||||
menu->sym->flags |= SYMBOL_CHOICEVAL; |
||||
if (!menu->prompt) |
||||
menu_warn(menu, "choice value must have a prompt"); |
||||
for (prop = menu->sym->prop; prop; prop = prop->next) { |
||||
if (prop->type == P_DEFAULT) |
||||
prop_warn(prop, "defaults for choice " |
||||
"values not supported"); |
||||
if (prop->menu == menu) |
||||
continue; |
||||
if (prop->type == P_PROMPT && |
||||
prop->menu->parent->sym != sym) |
||||
prop_warn(prop, "choice value used outside its choice group"); |
||||
} |
||||
/* Non-tristate choice values of tristate choices must |
||||
* depend on the choice being set to Y. The choice |
||||
* values' dependencies were propagated to their |
||||
* properties above, so the change here must be re- |
||||
* propagated. |
||||
*/ |
||||
if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) { |
||||
basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes); |
||||
menu->dep = expr_alloc_and(basedep, menu->dep); |
||||
for (prop = menu->sym->prop; prop; prop = prop->next) { |
||||
if (prop->menu != menu) |
||||
continue; |
||||
prop->visible.expr = expr_alloc_and(expr_copy(basedep), |
||||
prop->visible.expr); |
||||
} |
||||
} |
||||
menu_add_symbol(P_CHOICE, sym, NULL); |
||||
prop = sym_get_choice_prop(sym); |
||||
for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) |
||||
; |
||||
*ep = expr_alloc_one(E_LIST, NULL); |
||||
(*ep)->right.sym = menu->sym; |
||||
} |
||||
if (menu->list && (!menu->prompt || !menu->prompt->text)) { |
||||
for (last_menu = menu->list; ; last_menu = last_menu->next) { |
||||
last_menu->parent = parent; |
||||
if (!last_menu->next) |
||||
break; |
||||
} |
||||
last_menu->next = menu->next; |
||||
menu->next = menu->list; |
||||
menu->list = NULL; |
||||
} |
||||
} |
||||
|
||||
if (sym && !(sym->flags & SYMBOL_WARNED)) { |
||||
if (sym->type == S_UNKNOWN) |
||||
menu_warn(parent, "config symbol defined without type"); |
||||
|
||||
if (sym_is_choice(sym) && !parent->prompt) |
||||
menu_warn(parent, "choice must have a prompt"); |
||||
|
||||
/* Check properties connected to this symbol */ |
||||
sym_check_prop(sym); |
||||
sym->flags |= SYMBOL_WARNED; |
||||
} |
||||
|
||||
if (sym && !sym_is_optional(sym) && parent->prompt) { |
||||
sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, |
||||
expr_alloc_and(parent->prompt->visible.expr, |
||||
expr_alloc_symbol(&symbol_mod))); |
||||
} |
||||
} |
||||
|
||||
bool menu_has_prompt(struct menu *menu) |
||||
{ |
||||
if (!menu->prompt) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
bool menu_is_visible(struct menu *menu) |
||||
{ |
||||
struct menu *child; |
||||
struct symbol *sym; |
||||
tristate visible; |
||||
|
||||
if (!menu->prompt) |
||||
return false; |
||||
|
||||
if (menu->visibility) { |
||||
if (expr_calc_value(menu->visibility) == no) |
||||
return no; |
||||
} |
||||
|
||||
sym = menu->sym; |
||||
if (sym) { |
||||
sym_calc_value(sym); |
||||
visible = menu->prompt->visible.tri; |
||||
} else |
||||
visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr); |
||||
|
||||
if (visible != no) |
||||
return true; |
||||
|
||||
if (!sym || sym_get_tristate_value(menu->sym) == no) |
||||
return false; |
||||
|
||||
for (child = menu->list; child; child = child->next) { |
||||
if (menu_is_visible(child)) { |
||||
if (sym) |
||||
sym->flags |= SYMBOL_DEF_USER; |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
const char *menu_get_prompt(struct menu *menu) |
||||
{ |
||||
if (menu->prompt) |
||||
return menu->prompt->text; |
||||
else if (menu->sym) |
||||
return menu->sym->name; |
||||
return NULL; |
||||
} |
||||
|
||||
struct menu *menu_get_root_menu(struct menu *menu) |
||||
{ |
||||
return &rootmenu; |
||||
} |
||||
|
||||
struct menu *menu_get_parent_menu(struct menu *menu) |
||||
{ |
||||
enum prop_type type; |
||||
|
||||
for (; menu != &rootmenu; menu = menu->parent) { |
||||
type = menu->prompt ? menu->prompt->type : 0; |
||||
if (type == P_MENU) |
||||
break; |
||||
} |
||||
return menu; |
||||
} |
||||
|
||||
bool menu_has_help(struct menu *menu) |
||||
{ |
||||
return menu->help != NULL; |
||||
} |
||||
|
||||
const char *menu_get_help(struct menu *menu) |
||||
{ |
||||
if (menu->help) |
||||
return menu->help; |
||||
else |
||||
return ""; |
||||
} |
||||
|
||||
static void get_prompt_str(struct gstr *r, struct property *prop) |
||||
{ |
||||
int i, j; |
||||
struct menu *submenu[8], *menu; |
||||
|
||||
str_printf(r, _("Prompt: %s\n"), _(prop->text)); |
||||
str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, |
||||
prop->menu->lineno); |
||||
if (!expr_is_yes(prop->visible.expr)) { |
||||
str_append(r, _(" Depends on: ")); |
||||
expr_gstr_print(prop->visible.expr, r); |
||||
str_append(r, "\n"); |
||||
} |
||||
menu = prop->menu->parent; |
||||
for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) |
||||
submenu[i++] = menu; |
||||
if (i > 0) { |
||||
str_printf(r, _(" Location:\n")); |
||||
for (j = 4; --i >= 0; j += 2) { |
||||
menu = submenu[i]; |
||||
str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); |
||||
if (menu->sym) { |
||||
str_printf(r, " (%s [=%s])", menu->sym->name ? |
||||
menu->sym->name : _("<choice>"), |
||||
sym_get_string_value(menu->sym)); |
||||
} |
||||
str_append(r, "\n"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void get_symbol_str(struct gstr *r, struct symbol *sym) |
||||
{ |
||||
bool hit; |
||||
struct property *prop; |
||||
|
||||
if (sym && sym->name) { |
||||
str_printf(r, "Symbol: %s [=%s]\n", sym->name, |
||||
sym_get_string_value(sym)); |
||||
str_printf(r, "Type : %s\n", sym_type_name(sym->type)); |
||||
if (sym->type == S_INT || sym->type == S_HEX) { |
||||
prop = sym_get_range_prop(sym); |
||||
if (prop) { |
||||
str_printf(r, "Range : "); |
||||
expr_gstr_print(prop->expr, r); |
||||
str_append(r, "\n"); |
||||
} |
||||
} |
||||
} |
||||
for_all_prompts(sym, prop) |
||||
get_prompt_str(r, prop); |
||||
hit = false; |
||||
for_all_properties(sym, prop, P_SELECT) { |
||||
if (!hit) { |
||||
str_append(r, " Selects: "); |
||||
hit = true; |
||||
} else |
||||
str_printf(r, " && "); |
||||
expr_gstr_print(prop->expr, r); |
||||
} |
||||
if (hit) |
||||
str_append(r, "\n"); |
||||
if (sym->rev_dep.expr) { |
||||
str_append(r, _(" Selected by: ")); |
||||
expr_gstr_print(sym->rev_dep.expr, r); |
||||
str_append(r, "\n"); |
||||
} |
||||
str_append(r, "\n\n"); |
||||
} |
||||
|
||||
struct gstr get_relations_str(struct symbol **sym_arr) |
||||
{ |
||||
struct symbol *sym; |
||||
struct gstr res = str_new(); |
||||
int i; |
||||
|
||||
for (i = 0; sym_arr && (sym = sym_arr[i]); i++) |
||||
get_symbol_str(&res, sym); |
||||
if (!i) |
||||
str_append(&res, _("No matches found.\n")); |
||||
return res; |
||||
} |
||||
|
||||
|
||||
void menu_get_ext_help(struct menu *menu, struct gstr *help) |
||||
{ |
||||
struct symbol *sym = menu->sym; |
||||
const char *help_text = nohelp_text; |
||||
|
||||
if (menu_has_help(menu)) { |
||||
if (sym->name) |
||||
str_printf(help, "%s%s:\n\n", CONFIG_, sym->name); |
||||
help_text = menu_get_help(menu); |
||||
} |
||||
str_printf(help, "%s\n", _(help_text)); |
||||
if (sym) |
||||
get_symbol_str(help, sym); |
||||
} |
@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
|
||||
/* |
||||
* Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org> |
||||
* Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org> |
||||
* |
||||
* Released under the terms of the GNU GPL v2.0. |
||||
*/ |
||||
|
||||
#include <stdarg.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include "lkc.h" |
||||
|
||||
/* file already present in list? If not add it */ |
||||
struct file *file_lookup(const char *name) |
||||
{ |
||||
struct file *file; |
||||
const char *file_name = sym_expand_string_value(name); |
||||
|
||||
for (file = file_list; file; file = file->next) { |
||||
if (!strcmp(name, file->name)) { |
||||
free((void *)file_name); |
||||
return file; |
||||
} |
||||
} |
||||
|
||||
file = malloc(sizeof(*file)); |
||||
memset(file, 0, sizeof(*file)); |
||||
file->name = file_name; |
||||
file->next = file_list; |
||||
file_list = file; |
||||
return file; |
||||
} |
||||
|
||||
/* write a dependency file as used by kbuild to track dependencies */ |
||||
int file_write_dep(const char *name) |
||||
{ |
||||
struct symbol *sym, *env_sym; |
||||
struct expr *e; |
||||
struct file *file; |
||||
FILE *out; |
||||
|
||||
if (!name) |
||||
name = ".kconfig.d"; |
||||
out = fopen("..config.tmp", "w"); |
||||
if (!out) |
||||
return 1; |
||||
fprintf(out, "deps_config := \\\n"); |
||||
for (file = file_list; file; file = file->next) { |
||||
if (file->next) |
||||
fprintf(out, "\t%s \\\n", file->name); |
||||
else |
||||
fprintf(out, "\t%s\n", file->name); |
||||
} |
||||
fprintf(out, "\n%s: \\\n" |
||||
"\t$(deps_config)\n\n", conf_get_autoconfig_name()); |
||||
|
||||
expr_list_for_each_sym(sym_env_list, e, sym) { |
||||
struct property *prop; |
||||
const char *value; |
||||
|
||||
prop = sym_get_env_prop(sym); |
||||
env_sym = prop_get_symbol(prop); |
||||
if (!env_sym) |
||||
continue; |
||||
value = getenv(env_sym->name); |
||||
if (!value) |
||||
value = ""; |
||||
fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value); |
||||
fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name()); |
||||
fprintf(out, "endif\n"); |
||||
} |
||||
|
||||
fprintf(out, "\n$(deps_config): ;\n"); |
||||
fclose(out); |
||||
rename("..config.tmp", name); |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/* Allocate initial growable string */ |
||||
struct gstr str_new(void) |
||||
{ |
||||
struct gstr gs; |
||||
gs.s = malloc(sizeof(char) * 64); |
||||
gs.len = 64; |
||||
gs.max_width = 0; |
||||
strcpy(gs.s, "\0"); |
||||
return gs; |
||||
} |
||||
|
||||
/* Allocate and assign growable string */ |
||||
struct gstr str_assign(const char *s) |
||||
{ |
||||
struct gstr gs; |
||||
gs.s = strdup(s); |
||||
gs.len = strlen(s) + 1; |
||||
gs.max_width = 0; |
||||
return gs; |
||||
} |
||||
|
||||
/* Free storage for growable string */ |
||||
void str_free(struct gstr *gs) |
||||
{ |
||||
if (gs->s) |
||||
free(gs->s); |
||||
gs->s = NULL; |
||||
gs->len = 0; |
||||
} |
||||
|
||||
/* Append to growable string */ |
||||
void str_append(struct gstr *gs, const char *s) |
||||
{ |
||||
size_t l; |
||||
if (s) { |
||||
l = strlen(gs->s) + strlen(s) + 1; |
||||
if (l > gs->len) { |
||||
gs->s = realloc(gs->s, l); |
||||
gs->len = l; |
||||
} |
||||
strcat(gs->s, s); |
||||
} |
||||
} |
||||
|
||||
/* Append printf formatted string to growable string */ |
||||
void str_printf(struct gstr *gs, const char *fmt, ...) |
||||
{ |
||||
va_list ap; |
||||
char s[10000]; /* big enough... */ |
||||
va_start(ap, fmt); |
||||
vsnprintf(s, sizeof(s), fmt, ap); |
||||
str_append(gs, s); |
||||
va_end(ap); |
||||
} |
||||
|
||||
/* Retrieve value of growable string */ |
||||
const char *str_get(struct gstr *gs) |
||||
{ |
||||
return gs->s; |
||||
} |
||||
|
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
%language=ANSI-C |
||||
%define hash-function-name kconf_id_hash |
||||
%define lookup-function-name kconf_id_lookup |
||||
%define string-pool-name kconf_id_strings |
||||
%compare-strncmp |
||||
%enum |
||||
%pic |
||||
%struct-type |
||||
|
||||
struct kconf_id; |
||||
|
||||
struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); |
||||
|
||||
%% |
||||
mainmenu, T_MAINMENU, TF_COMMAND |
||||
menu, T_MENU, TF_COMMAND |
||||
endmenu, T_ENDMENU, TF_COMMAND |
||||
source, T_SOURCE, TF_COMMAND |
||||
choice, T_CHOICE, TF_COMMAND |
||||
endchoice, T_ENDCHOICE, TF_COMMAND |
||||
comment, T_COMMENT, TF_COMMAND |
||||
config, T_CONFIG, TF_COMMAND |
||||
menuconfig, T_MENUCONFIG, TF_COMMAND |
||||
help, T_HELP, TF_COMMAND |
||||
if, T_IF, TF_COMMAND|TF_PARAM |
||||
endif, T_ENDIF, TF_COMMAND |
||||
depends, T_DEPENDS, TF_COMMAND |
||||
optional, T_OPTIONAL, TF_COMMAND |
||||
default, T_DEFAULT, TF_COMMAND, S_UNKNOWN |
||||
prompt, T_PROMPT, TF_COMMAND |
||||
tristate, T_TYPE, TF_COMMAND, S_TRISTATE |
||||
def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE |
||||
bool, T_TYPE, TF_COMMAND, S_BOOLEAN |
||||
boolean, T_TYPE, TF_COMMAND, S_BOOLEAN |
||||
def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN |
||||
int, T_TYPE, TF_COMMAND, S_INT |
||||
hex, T_TYPE, TF_COMMAND, S_HEX |
||||
string, T_TYPE, TF_COMMAND, S_STRING |
||||
select, T_SELECT, TF_COMMAND |
||||
range, T_RANGE, TF_COMMAND |
||||
visible, T_VISIBLE, TF_COMMAND |
||||
option, T_OPTION, TF_COMMAND |
||||
on, T_ON, TF_PARAM |
||||
modules, T_OPT_MODULES, TF_OPTION |
||||
defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION |
||||
env, T_OPT_ENV, TF_OPTION |
||||
%% |
@ -0,0 +1,364 @@
@@ -0,0 +1,364 @@
|
||||
%option nostdinit noyywrap never-interactive full ecs |
||||
%option 8bit nodefault perf-report perf-report |
||||
%option noinput |
||||
%x COMMAND HELP STRING PARAM |
||||
%{ |
||||
/* |
||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |
||||
* Released under the terms of the GNU GPL v2.0. |
||||
*/ |
||||
|
||||
#include <limits.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <unistd.h> |
||||
|
||||
#include "lkc.h" |
||||
|
||||
#define START_STRSIZE 16 |
||||
|
||||
static struct { |
||||
struct file *file; |
||||
int lineno; |
||||
} current_pos; |
||||
|
||||
static char *text; |
||||
static int text_size, text_asize; |
||||
|
||||
struct buffer { |
||||
struct buffer *parent; |
||||
YY_BUFFER_STATE state; |
||||
}; |
||||
|
||||
struct buffer *current_buf; |
||||
|
||||
static int last_ts, first_ts; |
||||
|
||||
static void zconf_endhelp(void); |
||||
static void zconf_endfile(void); |
||||
|
||||
static void new_string(void) |
||||
{ |
||||
text = malloc(START_STRSIZE); |
||||
text_asize = START_STRSIZE; |
||||
text_size = 0; |
||||
*text = 0; |
||||
} |
||||
|
||||
static void append_string(const char *str, int size) |
||||
{ |
||||
int new_size = text_size + size + 1; |
||||
if (new_size > text_asize) { |
||||
new_size += START_STRSIZE - 1; |
||||
new_size &= -START_STRSIZE; |
||||
text = realloc(text, new_size); |
||||
text_asize = new_size; |
||||
} |
||||
memcpy(text + text_size, str, size); |
||||
text_size += size; |
||||
text[text_size] = 0; |
||||
} |
||||
|
||||
static void alloc_string(const char *str, int size) |
||||
{ |
||||
text = malloc(size + 1); |
||||
memcpy(text, str, size); |
||||
text[size] = 0; |
||||
} |
||||
%} |
||||
|
||||
ws [ \n\t] |
||||
n [A-Za-z0-9_] |
||||
|
||||
%% |
||||
int str = 0; |
||||
int ts, i; |
||||
|
||||
[ \t]*#.*\n | |
||||
[ \t]*\n { |
||||
current_file->lineno++; |
||||
return T_EOL; |
||||
} |
||||
[ \t]*#.* |
||||
|
||||
|
||||
[ \t]+ { |
||||
BEGIN(COMMAND); |
||||
} |
||||
|
||||
. { |
||||
unput(yytext[0]); |
||||
BEGIN(COMMAND); |
||||
} |
||||
|
||||
|
||||
<COMMAND>{ |
||||
{n}+ { |
||||
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); |
||||
BEGIN(PARAM); |
||||
current_pos.file = current_file; |
||||
current_pos.lineno = current_file->lineno; |
||||
if (id && id->flags & TF_COMMAND) { |
||||
zconflval.id = id; |
||||
return id->token; |
||||
} |
||||
alloc_string(yytext, yyleng); |
||||
zconflval.string = text; |
||||
return T_WORD; |
||||
} |
||||
. |
||||
\n { |
||||
BEGIN(INITIAL); |
||||
current_file->lineno++; |
||||
return T_EOL; |
||||
} |
||||
} |
||||
|
||||
<PARAM>{ |
||||
"&&" return T_AND; |
||||
"||" return T_OR; |
||||
"(" return T_OPEN_PAREN; |
||||
")" return T_CLOSE_PAREN; |
||||
"!" return T_NOT; |
||||
"=" return T_EQUAL; |
||||
"!=" return T_UNEQUAL; |
||||
\"|\' { |
||||
str = yytext[0]; |
||||
new_string(); |
||||
BEGIN(STRING); |
||||
} |
||||
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL; |
||||
--- /* ignore */ |
||||
({n}|[-/.])+ { |
||||
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); |
||||
if (id && id->flags & TF_PARAM) { |
||||
zconflval.id = id; |
||||
return id->token; |
||||
} |
||||
alloc_string(yytext, yyleng); |
||||
zconflval.string = text; |
||||
return T_WORD; |
||||
} |
||||
#.* /* comment */ |
||||
\\\n current_file->lineno++; |
||||
. |
||||
<<EOF>> { |
||||
BEGIN(INITIAL); |
||||
} |
||||
} |
||||
|
||||
<STRING>{ |
||||
[^'"\\\n]+/\n { |
||||
append_string(yytext, yyleng); |
||||
zconflval.string = text; |
||||
return T_WORD_QUOTE; |
||||
} |
||||
[^'"\\\n]+ { |
||||
append_string(yytext, yyleng); |
||||
} |
||||
\\.?/\n { |
||||
append_string(yytext + 1, yyleng - 1); |
||||
zconflval.string = text; |
||||
return T_WORD_QUOTE; |
||||
} |
||||
\\.? { |
||||
append_string(yytext + 1, yyleng - 1); |
||||
} |
||||
\'|\" { |
||||
if (str == yytext[0]) { |
||||
BEGIN(PARAM); |
||||
zconflval.string = text; |
||||
return T_WORD_QUOTE; |
||||
} else |
||||
append_string(yytext, 1); |
||||
} |
||||
\n { |
||||
printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); |
||||
current_file->lineno++; |
||||
BEGIN(INITIAL); |
||||
return T_EOL; |
||||
} |
||||
<<EOF>> { |
||||
BEGIN(INITIAL); |
||||
} |
||||
} |
||||
|
||||
<HELP>{ |
||||
[ \t]+ { |
||||
ts = 0; |
||||
for (i = 0; i < yyleng; i++) { |
||||
if (yytext[i] == '\t') |
||||
ts = (ts & ~7) + 8; |
||||
else |
||||
ts++; |
||||
} |
||||
last_ts = ts; |
||||
if (first_ts) { |
||||
if (ts < first_ts) { |
||||
zconf_endhelp(); |
||||
return T_HELPTEXT; |
||||
} |
||||
ts -= first_ts; |
||||
while (ts > 8) { |
||||
append_string(" ", 8); |
||||
ts -= 8; |
||||
} |
||||
append_string(" ", ts); |
||||
} |
||||
} |
||||
[ \t]*\n/[^ \t\n] { |
||||
current_file->lineno++; |
||||
zconf_endhelp(); |
||||
return T_HELPTEXT; |
||||
} |
||||
[ \t]*\n { |
||||
current_file->lineno++; |
||||
append_string("\n", 1); |
||||
} |
||||
[^ \t\n].* { |
||||
while (yyleng) { |
||||
if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t')) |
||||
break; |
||||
yyleng--; |
||||
} |
||||
append_string(yytext, yyleng); |
||||
if (!first_ts) |
||||
first_ts = last_ts; |
||||
} |
||||
<<EOF>> { |
||||
zconf_endhelp(); |
||||
return T_HELPTEXT; |
||||
} |
||||
} |
||||
|
||||
<<EOF>> { |
||||
if (current_file) { |
||||
zconf_endfile(); |
||||
return T_EOL; |
||||
} |
||||
fclose(yyin); |
||||
yyterminate(); |
||||
} |
||||
|
||||
%% |
||||
void zconf_starthelp(void) |
||||
{ |
||||
new_string(); |
||||
last_ts = first_ts = 0; |
||||
BEGIN(HELP); |
||||
} |
||||
|
||||
static void zconf_endhelp(void) |
||||
{ |
||||
zconflval.string = text; |
||||
BEGIN(INITIAL); |
||||
} |
||||
|
||||
|
||||
/* |
||||
* Try to open specified file with following names: |
||||
* ./name |
||||
* $(srctree)/name |
||||
* The latter is used when srctree is separate from objtree |
||||
* when compiling the firmware. |
||||
* Return NULL if file is not found. |
||||
*/ |
||||
FILE *zconf_fopen(const char *name) |
||||
{ |
||||
char *env, fullname[PATH_MAX+1]; |
||||
FILE *f; |
||||
|
||||
f = fopen(name, "r"); |
||||
if (!f && name != NULL && name[0] != '/') { |
||||
env = getenv(SRCTREE); |
||||
if (env) { |
||||
sprintf(fullname, "%s/%s", env, name); |
||||
f = fopen(fullname, "r"); |
||||
} |
||||
} |
||||
return f; |
||||
} |
||||
|
||||
void zconf_initscan(const char *name) |
||||
{ |
||||
yyin = zconf_fopen(name); |
||||
if (!yyin) { |
||||
printf("can't find file %s\n", name); |
||||
exit(1); |
||||
} |
||||
|
||||
current_buf = malloc(sizeof(*current_buf)); |
||||
memset(current_buf, 0, sizeof(*current_buf)); |
||||
|
||||
current_file = file_lookup(name); |
||||
current_file->lineno = 1; |
||||
} |
||||
|
||||
void zconf_nextfile(const char *name) |
||||
{ |
||||
struct file *iter; |
||||
struct file *file = file_lookup(name); |
||||
struct buffer *buf = malloc(sizeof(*buf)); |
||||
memset(buf, 0, sizeof(*buf)); |
||||
|
||||
current_buf->state = YY_CURRENT_BUFFER; |
||||
yyin = zconf_fopen(file->name); |
||||
if (!yyin) { |
||||
printf("%s:%d: can't open file \"%s\"\n", |
||||
zconf_curname(), zconf_lineno(), file->name); |
||||
exit(1); |
||||
} |
||||
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); |
||||
buf->parent = current_buf; |
||||
current_buf = buf; |
||||
|
||||
for (iter = current_file->parent; iter; iter = iter->parent ) { |
||||
if (!strcmp(current_file->name,iter->name) ) { |
||||
printf("%s:%d: recursive inclusion detected. " |
||||
"Inclusion path:\n current file : '%s'\n", |
||||
zconf_curname(), zconf_lineno(), |
||||
zconf_curname()); |
||||
iter = current_file->parent; |
||||
while (iter && \ |
||||
strcmp(iter->name,current_file->name)) { |
||||
printf(" included from: '%s:%d'\n", |
||||
iter->name, iter->lineno-1); |
||||
iter = iter->parent; |
||||
} |
||||
if (iter) |
||||
printf(" included from: '%s:%d'\n", |
||||
iter->name, iter->lineno+1); |
||||
exit(1); |
||||
} |
||||
} |
||||
file->lineno = 1; |
||||
file->parent = current_file; |
||||
current_file = file; |
||||
} |
||||
|
||||
static void zconf_endfile(void) |
||||
{ |
||||
struct buffer *parent; |
||||
|
||||
current_file = current_file->parent; |
||||
|
||||
parent = current_buf->parent; |
||||
if (parent) { |
||||
fclose(yyin); |
||||
yy_delete_buffer(YY_CURRENT_BUFFER); |
||||
yy_switch_to_buffer(parent->state); |
||||
} |
||||
free(current_buf); |
||||
current_buf = parent; |
||||
} |
||||
|
||||
int zconf_lineno(void) |
||||
{ |
||||
return current_pos.lineno; |
||||
} |
||||
|
||||
const char *zconf_curname(void) |
||||
{ |
||||
return current_pos.file ? current_pos.file->name : "<none>"; |
||||
} |
@ -0,0 +1,740 @@
@@ -0,0 +1,740 @@
|
||||
%{ |
||||
/* |
||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |
||||
* Released under the terms of the GNU GPL v2.0. |
||||
*/ |
||||
|
||||
#include <ctype.h> |
||||
#include <stdarg.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <stdbool.h> |
||||
|
||||
#include "lkc.h" |
||||
|
||||
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) |
||||
|
||||
#define PRINTD 0x0001 |
||||
#define DEBUG_PARSE 0x0002 |
||||
|
||||
int cdebug = PRINTD; |
||||
|
||||
extern int zconflex(void); |
||||
static void zconfprint(const char *err, ...); |
||||
static void zconf_error(const char *err, ...); |
||||
static void zconferror(const char *err); |
||||
static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); |
||||
|
||||
struct symbol *symbol_hash[SYMBOL_HASHSIZE]; |
||||
|
||||
static struct menu *current_menu, *current_entry; |
||||
|
||||
%} |
||||
%expect 30 |
||||
|
||||
%union |
||||
{ |
||||
char *string; |
||||
struct file *file; |
||||
struct symbol *symbol; |
||||
struct expr *expr; |
||||
struct menu *menu; |
||||
const struct kconf_id *id; |
||||
} |
||||
|
||||
%token <id>T_MAINMENU |
||||
%token <id>T_MENU |
||||
%token <id>T_ENDMENU |
||||
%token <id>T_SOURCE |
||||
%token <id>T_CHOICE |
||||
%token <id>T_ENDCHOICE |
||||
%token <id>T_COMMENT |
||||
%token <id>T_CONFIG |
||||
%token <id>T_MENUCONFIG |
||||
%token <id>T_HELP |
||||
%token <string> T_HELPTEXT |
||||
%token <id>T_IF |
||||
%token <id>T_ENDIF |
||||
%token <id>T_DEPENDS |
||||
%token <id>T_OPTIONAL |
||||
%token <id>T_PROMPT |
||||
%token <id>T_TYPE |
||||
%token <id>T_DEFAULT |
||||
%token <id>T_SELECT |
||||
%token <id>T_RANGE |
||||
%token <id>T_VISIBLE |
||||
%token <id>T_OPTION |
||||
%token <id>T_ON |
||||
%token <string> T_WORD |
||||
%token <string> T_WORD_QUOTE |
||||
%token T_UNEQUAL |
||||
%token T_CLOSE_PAREN |
||||
%token T_OPEN_PAREN |
||||
%token T_EOL |
||||
|
||||
%left T_OR |
||||
%left T_AND |
||||
%left T_EQUAL T_UNEQUAL |
||||
%nonassoc T_NOT |
||||
|
||||
%type <string> prompt |
||||
%type <symbol> symbol |
||||
%type <expr> expr |
||||
%type <expr> if_expr |
||||
%type <id> end |
||||
%type <id> option_name |
||||
%type <menu> if_entry menu_entry choice_entry |
||||
%type <string> symbol_option_arg word_opt |
||||
|
||||
%destructor { |
||||
fprintf(stderr, "%s:%d: missing end statement for this entry\n", |
||||
$$->file->name, $$->lineno); |
||||
if (current_menu == $$) |
||||
menu_end_menu(); |
||||
} if_entry menu_entry choice_entry |
||||
|
||||
%{ |
||||
/* Include zconf.hash.c here so it can see the token constants. */ |
||||
#include "zconf.hash.c" |
||||
%} |
||||
|
||||
%% |
||||
input: nl start | start; |
||||
|
||||
start: mainmenu_stmt stmt_list | stmt_list; |
||||
|
||||
stmt_list: |
||||
/* empty */ |
||||
| stmt_list common_stmt |
||||
| stmt_list choice_stmt |
||||
| stmt_list menu_stmt |
||||
| stmt_list end { zconf_error("unexpected end statement"); } |
||||
| stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } |
||||
| stmt_list option_name error T_EOL |
||||
{ |
||||
zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name); |
||||
} |
||||
| stmt_list error T_EOL { zconf_error("invalid statement"); } |
||||
; |
||||
|
||||
option_name: |
||||
T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE |
||||
; |
||||
|
||||
common_stmt: |
||||
T_EOL |
||||
| if_stmt |
||||
| comment_stmt |
||||
| config_stmt |
||||
| menuconfig_stmt |
||||
| source_stmt |
||||
; |
||||
|
||||
option_error: |
||||
T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); } |
||||
| error T_EOL { zconf_error("invalid option"); } |
||||
; |
||||
|
||||
|
||||
/* config/menuconfig entry */ |
||||
|
||||
config_entry_start: T_CONFIG T_WORD T_EOL |
||||
{ |
||||
struct symbol *sym = sym_lookup($2, 0); |
||||
sym->flags |= SYMBOL_OPTIONAL; |
||||
menu_add_entry(sym); |
||||
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); |
||||
}; |
||||
|
||||
config_stmt: config_entry_start config_option_list |
||||
{ |
||||
menu_end_entry(); |
||||
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL |
||||
{ |
||||
struct symbol *sym = sym_lookup($2, 0); |
||||
sym->flags |= SYMBOL_OPTIONAL; |
||||
menu_add_entry(sym); |
||||
printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2); |
||||
}; |
||||
|
||||
menuconfig_stmt: menuconfig_entry_start config_option_list |
||||
{ |
||||
if (current_entry->prompt) |
||||
current_entry->prompt->type = P_MENU; |
||||
else |
||||
zconfprint("warning: menuconfig statement without prompt"); |
||||
menu_end_entry(); |
||||
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
config_option_list: |
||||
/* empty */ |
||||
| config_option_list config_option |
||||
| config_option_list symbol_option |
||||
| config_option_list depends |
||||
| config_option_list help |
||||
| config_option_list option_error |
||||
| config_option_list T_EOL |
||||
; |
||||
|
||||
config_option: T_TYPE prompt_stmt_opt T_EOL |
||||
{ |
||||
menu_set_type($1->stype); |
||||
printd(DEBUG_PARSE, "%s:%d:type(%u)\n", |
||||
zconf_curname(), zconf_lineno(), |
||||
$1->stype); |
||||
}; |
||||
|
||||
config_option: T_PROMPT prompt if_expr T_EOL |
||||
{ |
||||
menu_add_prompt(P_PROMPT, $2, $3); |
||||
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
config_option: T_DEFAULT expr if_expr T_EOL |
||||
{ |
||||
menu_add_expr(P_DEFAULT, $2, $3); |
||||
if ($1->stype != S_UNKNOWN) |
||||
menu_set_type($1->stype); |
||||
printd(DEBUG_PARSE, "%s:%d:default(%u)\n", |
||||
zconf_curname(), zconf_lineno(), |
||||
$1->stype); |
||||
}; |
||||
|
||||
config_option: T_SELECT T_WORD if_expr T_EOL |
||||
{ |
||||
menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); |
||||
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
config_option: T_RANGE symbol symbol if_expr T_EOL |
||||
{ |
||||
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); |
||||
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
symbol_option: T_OPTION symbol_option_list T_EOL |
||||
; |
||||
|
||||
symbol_option_list: |
||||
/* empty */ |
||||
| symbol_option_list T_WORD symbol_option_arg |
||||
{ |
||||
const struct kconf_id *id = kconf_id_lookup($2, strlen($2)); |
||||
if (id && id->flags & TF_OPTION) |
||||
menu_add_option(id->token, $3); |
||||
else |
||||
zconfprint("warning: ignoring unknown option %s", $2); |
||||
free($2); |
||||
}; |
||||
|
||||
symbol_option_arg: |
||||
/* empty */ { $$ = NULL; } |
||||
| T_EQUAL prompt { $$ = $2; } |
||||
; |
||||
|
||||
/* choice entry */ |
||||
|
||||
choice: T_CHOICE word_opt T_EOL |
||||
{ |
||||
struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); |
||||
sym->flags |= SYMBOL_AUTO; |
||||
menu_add_entry(sym); |
||||
menu_add_expr(P_CHOICE, NULL, NULL); |
||||
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
choice_entry: choice choice_option_list |
||||
{ |
||||
$$ = menu_add_menu(); |
||||
}; |
||||
|
||||
choice_end: end |
||||
{ |
||||
if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { |
||||
menu_end_menu(); |
||||
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); |
||||
} |
||||
}; |
||||
|
||||
choice_stmt: choice_entry choice_block choice_end |
||||
; |
||||
|
||||
choice_option_list: |
||||
/* empty */ |
||||
| choice_option_list choice_option |
||||
| choice_option_list depends |
||||
| choice_option_list help |
||||
| choice_option_list T_EOL |
||||
| choice_option_list option_error |
||||
; |
||||
|
||||
choice_option: T_PROMPT prompt if_expr T_EOL |
||||
{ |
||||
menu_add_prompt(P_PROMPT, $2, $3); |
||||
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
choice_option: T_TYPE prompt_stmt_opt T_EOL |
||||
{ |
||||
if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) { |
||||
menu_set_type($1->stype); |
||||
printd(DEBUG_PARSE, "%s:%d:type(%u)\n", |
||||
zconf_curname(), zconf_lineno(), |
||||
$1->stype); |
||||
} else |
||||
YYERROR; |
||||
}; |
||||
|
||||
choice_option: T_OPTIONAL T_EOL |
||||
{ |
||||
current_entry->sym->flags |= SYMBOL_OPTIONAL; |
||||
printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
choice_option: T_DEFAULT T_WORD if_expr T_EOL |
||||
{ |
||||
if ($1->stype == S_UNKNOWN) { |
||||
menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); |
||||
printd(DEBUG_PARSE, "%s:%d:default\n", |
||||
zconf_curname(), zconf_lineno()); |
||||
} else |
||||
YYERROR; |
||||
}; |
||||
|
||||
choice_block: |
||||
/* empty */ |
||||
| choice_block common_stmt |
||||
; |
||||
|
||||
/* if entry */ |
||||
|
||||
if_entry: T_IF expr nl |
||||
{ |
||||
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); |
||||
menu_add_entry(NULL); |
||||
menu_add_dep($2); |
||||
$$ = menu_add_menu(); |
||||
}; |
||||
|
||||
if_end: end |
||||
{ |
||||
if (zconf_endtoken($1, T_IF, T_ENDIF)) { |
||||
menu_end_menu(); |
||||
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); |
||||
} |
||||
}; |
||||
|
||||
if_stmt: if_entry if_block if_end |
||||
; |
||||
|
||||
if_block: |
||||
/* empty */ |
||||
| if_block common_stmt |
||||
| if_block menu_stmt |
||||
| if_block choice_stmt |
||||
; |
||||
|
||||
/* mainmenu entry */ |
||||
|
||||
mainmenu_stmt: T_MAINMENU prompt nl |
||||
{ |
||||
menu_add_prompt(P_MENU, $2, NULL); |
||||
}; |
||||
|
||||
/* menu entry */ |
||||
|
||||
menu: T_MENU prompt T_EOL |
||||
{ |
||||
menu_add_entry(NULL); |
||||
menu_add_prompt(P_MENU, $2, NULL); |
||||
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
menu_entry: menu visibility_list depends_list |
||||
{ |
||||
$$ = menu_add_menu(); |
||||
}; |
||||
|
||||
menu_end: end |
||||
{ |
||||
if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { |
||||
menu_end_menu(); |
||||
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); |
||||
} |
||||
}; |
||||
|
||||
menu_stmt: menu_entry menu_block menu_end |
||||
; |
||||
|
||||
menu_block: |
||||
/* empty */ |
||||
| menu_block common_stmt |
||||
| menu_block menu_stmt |
||||
| menu_block choice_stmt |
||||
; |
||||
|
||||
source_stmt: T_SOURCE prompt T_EOL |
||||
{ |
||||
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); |
||||
zconf_nextfile($2); |
||||
}; |
||||
|
||||
/* comment entry */ |
||||
|
||||
comment: T_COMMENT prompt T_EOL |
||||
{ |
||||
menu_add_entry(NULL); |
||||
menu_add_prompt(P_COMMENT, $2, NULL); |
||||
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
comment_stmt: comment depends_list |
||||
{ |
||||
menu_end_entry(); |
||||
}; |
||||
|
||||
/* help option */ |
||||
|
||||
help_start: T_HELP T_EOL |
||||
{ |
||||
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); |
||||
zconf_starthelp(); |
||||
}; |
||||
|
||||
help: help_start T_HELPTEXT |
||||
{ |
||||
current_entry->help = $2; |
||||
}; |
||||
|
||||
/* depends option */ |
||||
|
||||
depends_list: |
||||
/* empty */ |
||||
| depends_list depends |
||||
| depends_list T_EOL |
||||
| depends_list option_error |
||||
; |
||||
|
||||
depends: T_DEPENDS T_ON expr T_EOL |
||||
{ |
||||
menu_add_dep($3); |
||||
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); |
||||
}; |
||||
|
||||
/* visibility option */ |
||||
|
||||
visibility_list: |
||||
/* empty */ |
||||
| visibility_list visible |
||||
| visibility_list T_EOL |
||||
; |
||||
|
||||
visible: T_VISIBLE if_expr |
||||
{ |
||||
menu_add_visibility($2); |
||||
}; |
||||
|
||||
/* prompt statement */ |
||||
|
||||
prompt_stmt_opt: |
||||
/* empty */ |
||||
| prompt if_expr |
||||
{ |
||||
menu_add_prompt(P_PROMPT, $1, $2); |
||||
}; |
||||
|
||||
prompt: T_WORD |
||||
| T_WORD_QUOTE |
||||
; |
||||
|
||||
end: T_ENDMENU T_EOL { $$ = $1; } |
||||
| T_ENDCHOICE T_EOL { $$ = $1; } |
||||
| T_ENDIF T_EOL { $$ = $1; } |
||||
; |
||||
|
||||
nl: |
||||
T_EOL |
||||
| nl T_EOL |
||||
; |
||||
|
||||
if_expr: /* empty */ { $$ = NULL; } |
||||
| T_IF expr { $$ = $2; } |
||||
; |
||||
|
||||
expr: symbol { $$ = expr_alloc_symbol($1); } |
||||
| symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } |
||||
| symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } |
||||
| T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } |
||||
| T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } |
||||
| expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } |
||||
| expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } |
||||
; |
||||
|
||||
symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } |
||||
| T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } |
||||
; |
||||
|
||||
word_opt: /* empty */ { $$ = NULL; } |
||||
| T_WORD |
||||
|
||||
%% |
||||
|
||||
void conf_parse(const char *name) |
||||
{ |
||||
struct symbol *sym; |
||||
int i; |
||||
|
||||
zconf_initscan(name); |
||||
|
||||
sym_init(); |
||||
_menu_init(); |
||||
modules_sym = sym_lookup(NULL, 0); |
||||
modules_sym->type = S_BOOLEAN; |
||||
modules_sym->flags |= SYMBOL_AUTO; |
||||
rootmenu.prompt = menu_add_prompt(P_MENU, "CARL9170 Firmware Configuration", NULL); |
||||
|
||||
if (getenv("ZCONF_DEBUG")) |
||||
zconfdebug = 1; |
||||
zconfparse(); |
||||
if (zconfnerrs) |
||||
exit(1); |
||||
if (!modules_sym->prop) { |
||||
struct property *prop; |
||||
|
||||
prop = prop_alloc(P_DEFAULT, modules_sym); |
||||
prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); |
||||
} |
||||
|
||||
rootmenu.prompt->text = _(rootmenu.prompt->text); |
||||
rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); |
||||
|
||||
menu_finalize(&rootmenu); |
||||
for_all_symbols(i, sym) { |
||||
if (sym_check_deps(sym)) |
||||
zconfnerrs++; |
||||
} |
||||
if (zconfnerrs) |
||||
exit(1); |
||||
sym_set_change_count(1); |
||||
} |
||||
|
||||
static const char *zconf_tokenname(int token) |
||||
{ |
||||
switch (token) { |
||||
case T_MENU: return "menu"; |
||||
case T_ENDMENU: return "endmenu"; |
||||
case T_CHOICE: return "choice"; |
||||
case T_ENDCHOICE: return "endchoice"; |
||||
case T_IF: return "if"; |
||||
case T_ENDIF: return "endif"; |
||||
case T_DEPENDS: return "depends"; |
||||
case T_VISIBLE: return "visible"; |
||||
} |
||||
return "<token>"; |
||||
} |
||||
|
||||
static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken) |
||||
{ |
||||
if (id->token != endtoken) { |
||||
zconf_error("unexpected '%s' within %s block", |
||||
kconf_id_strings + id->name, zconf_tokenname(starttoken)); |
||||
zconfnerrs++; |
||||
return false; |
||||
} |
||||
if (current_menu->file != current_file) { |
||||
zconf_error("'%s' in different file than '%s'", |
||||
kconf_id_strings + id->name, zconf_tokenname(starttoken)); |
||||
fprintf(stderr, "%s:%d: location of the '%s'\n", |
||||
current_menu->file->name, current_menu->lineno, |
||||
zconf_tokenname(starttoken)); |
||||
zconfnerrs++; |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
static void zconfprint(const char *err, ...) |
||||
{ |
||||
va_list ap; |
||||
|
||||
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); |
||||
va_start(ap, err); |
||||
vfprintf(stderr, err, ap); |
||||
va_end(ap); |
||||
fprintf(stderr, "\n"); |
||||
} |
||||
|
||||
static void zconf_error(const char *err, ...) |
||||
{ |
||||
va_list ap; |
||||
|
||||
zconfnerrs++; |
||||
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); |
||||
va_start(ap, err); |
||||
vfprintf(stderr, err, ap); |
||||
va_end(ap); |
||||
fprintf(stderr, "\n"); |
||||
} |
||||
|
||||
static void zconferror(const char *err) |
||||
{ |
||||
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); |
||||
} |
||||
|
||||
static void print_quoted_string(FILE *out, const char *str) |
||||
{ |
||||
const char *p; |
||||
int len; |
||||
|
||||
putc('"', out); |
||||
while ((p = strchr(str, '"'))) { |
||||
len = p - str; |
||||
if (len) |
||||
fprintf(out, "%.*s", len, str); |
||||
fputs("\\\"", out); |
||||
str = p + 1; |
||||
} |
||||
fputs(str, out); |
||||
putc('"', out); |
||||
} |
||||
|
||||
static void print_symbol(FILE *out, struct menu *menu) |
||||
{ |
||||
struct symbol *sym = menu->sym; |
||||
struct property *prop; |
||||
|
||||
if (sym_is_choice(sym)) |
||||
fprintf(out, "\nchoice\n"); |
||||
else |
||||
fprintf(out, "\nconfig %s\n", sym->name); |
||||
switch (sym->type) { |
||||
case S_BOOLEAN: |
||||
fputs(" boolean\n", out); |
||||
break; |
||||
case S_TRISTATE: |
||||
fputs(" tristate\n", out); |
||||
break; |
||||
case S_STRING: |
||||
fputs(" string\n", out); |
||||
break; |
||||
case S_INT: |
||||
fputs(" integer\n", out); |
||||
break; |
||||
case S_HEX: |
||||
fputs(" hex\n", out); |
||||
break; |
||||
default: |
||||
fputs(" ???\n", out); |
||||
break; |
||||
} |
||||
for (prop = sym->prop; prop; prop = prop->next) { |
||||
if (prop->menu != menu) |
||||
continue; |
||||
switch (prop->type) { |
||||
case P_PROMPT: |
||||
fputs(" prompt ", out); |
||||
print_quoted_string(out, prop->text); |
||||
if (!expr_is_yes(prop->visible.expr)) { |
||||
fputs(" if ", out); |
||||
expr_fprint(prop->visible.expr, out); |
||||
} |
||||
fputc('\n', out); |
||||
break; |
||||
case P_DEFAULT: |
||||
fputs( " default ", out); |
||||
expr_fprint(prop->expr, out); |
||||
if (!expr_is_yes(prop->visible.expr)) { |
||||
fputs(" if ", out); |
||||
expr_fprint(prop->visible.expr, out); |
||||
} |
||||
fputc('\n', out); |
||||
break; |
||||
case P_CHOICE: |
||||
fputs(" #choice value\n", out); |
||||
break; |
||||
case P_SELECT: |
||||
fputs( " select ", out); |
||||
expr_fprint(prop->expr, out); |
||||
fputc('\n', out); |
||||
break; |
||||
case P_RANGE: |
||||
fputs( " range ", out); |
||||
expr_fprint(prop->expr, out); |
||||
fputc('\n', out); |
||||
break; |
||||
case P_MENU: |
||||
fputs( " menu ", out); |
||||
print_quoted_string(out, prop->text); |
||||
fputc('\n', out); |
||||
break; |
||||
default: |
||||
fprintf(out, " unknown prop %d!\n", prop->type); |
||||
break; |
||||
} |
||||
} |
||||
if (menu->help) { |
||||
int len = strlen(menu->help); |
||||
while (menu->help[--len] == '\n') |
||||
menu->help[len] = 0; |
||||
fprintf(out, " help\n%s\n", menu->help); |
||||
} |
||||
} |
||||
|
||||
void zconfdump(FILE *out) |
||||
{ |
||||
struct property *prop; |
||||
struct symbol *sym; |
||||
struct menu *menu; |
||||
|
||||
menu = rootmenu.list; |
||||
while (menu) { |
||||
if ((sym = menu->sym)) |
||||
print_symbol(out, menu); |
||||
else if ((prop = menu->prompt)) { |
||||
switch (prop->type) { |
||||
case P_COMMENT: |
||||
fputs("\ncomment ", out); |
||||
print_quoted_string(out, prop->text); |
||||
fputs("\n", out); |
||||
break; |
||||
case P_MENU: |
||||
fputs("\nmenu ", out); |
||||
print_quoted_string(out, prop->text); |
||||
fputs("\n", out); |
||||
break; |
||||
default: |
||||
; |
||||
} |
||||
if (!expr_is_yes(prop->visible.expr)) { |
||||
fputs(" depends ", out); |
||||
expr_fprint(prop->visible.expr, out); |
||||
fputc('\n', out); |
||||
} |
||||
} |
||||
|
||||
if (menu->list) |
||||
menu = menu->list; |
||||
else if (menu->next) |
||||
menu = menu->next; |
||||
else while ((menu = menu->parent)) { |
||||
if (menu->prompt && menu->prompt->type == P_MENU) |
||||
fputs("\nendmenu\n", out); |
||||
if (menu->next) { |
||||
menu = menu->next; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
#include "zconf.lex.c" |
||||
#include "util.c" |
||||
#include "confdata.c" |
||||
#include "expr.c" |
||||
#include "symbol.c" |
||||
#include "menu.c" |
@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
|
||||
# - Find gperf executable and provides a macro to generate custom build rules |
||||
# |
||||
# The module defines the following variables: |
||||
# GPERF_FOUND - true is gperf executable is found |
||||
# GPERF_EXECUTABLE - the path to the gperf executable |
||||
# GPERF_VERSION - the version of gperf |
||||
# GPERF_LIBRARIES - The gperf libraries |
||||
# |
||||
# The minimum required version of gperf can be specified using the |
||||
# standard syntax, e.g. FIND_PACKAGE(GPERF 2.5.13) |
||||
# |
||||
# |
||||
# If gperf is found on the system, the module provides the macro: |
||||
# GPERF_TARGET(Name GperfInput GperfOutput [COMPILE_FLAGS <string>]) |
||||
# which creates a custom command to generate the <GperfOutput> file from |
||||
# the <GperfInput> file. If COMPILE_FLAGS option is specified, the next |
||||
# parameter is added to the gperf command line. Name is an alias used to |
||||
# get details of this custom command. Indeed the macro defines the |
||||
# following variables: |
||||
# GPERF_${Name}_DEFINED - true is the macro ran successfully |
||||
# GPERF_${Name}_OUTPUTS - the source file generated by the custom rule, an |
||||
# alias for GperfOutput |
||||
# GPERF_${Name}_INPUT - the gperf source file, an alias for ${GperfInput} |
||||
# |
||||
# Gperf scanners oftenly use tokens defined by Bison: the code generated |
||||
# by Gperf depends of the header generated by Bison. This module also |
||||
# defines a macro: |
||||
# ADD_GPERF_BISON_DEPENDENCY(GperfTarget BisonTarget) |
||||
# which adds the required dependency between a scanner and a parser |
||||
# where <GperfTarget> and <BisonTarget> are the first parameters of |
||||
# respectively GPERF_TARGET and BISON_TARGET macros. |
||||
# |
||||
# ==================================================================== |
||||
# Example: |
||||
# |
||||
# find_package(GPERF) |
||||
# |
||||
# GPERF_TARGET(MyHash hash.gperf ${CMAKE_CURRENT_BINARY_DIR}/hash.c) |
||||
# |
||||
# ==================================================================== |
||||
|
||||
#============================================================================= |
||||
# Copyright 2009 Kitware, Inc. |
||||
# Copyright 2006 Tristan Carel |
||||
# |
||||
# Distributed under the OSI-approved BSD License (the "License"); |
||||
# see accompanying file Copyright.txt for details. |
||||
# |
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the |
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||||
# See the License for more information. |
||||
#============================================================================= |
||||
# (To distribute this file outside of CMake, substitute the full |
||||
# License text for the above reference.) |
||||
|
||||
FIND_PROGRAM(GPERF_EXECUTABLE gperf DOC "path to the gperf executable") |
||||
MARK_AS_ADVANCED(GPERF_EXECUTABLE) |
||||
|
||||
FIND_LIBRARY(FL_LIBRARY NAMES fl |
||||
DOC "path to the fl library") |
||||
MARK_AS_ADVANCED(FL_LIBRARY) |
||||
SET(GPERF_LIBRARIES ${FL_LIBRARY}) |
||||
|
||||
IF(GPERF_EXECUTABLE) |
||||
|
||||
EXECUTE_PROCESS(COMMAND ${GPERF_EXECUTABLE} --version |
||||
OUTPUT_VARIABLE GPERF_version_output |
||||
ERROR_VARIABLE GPERF_version_error |
||||
RESULT_VARIABLE GPERF_version_result |
||||
OUTPUT_STRIP_TRAILING_WHITESPACE) |
||||
|
||||
SET(ENV{LC_ALL} ${_Bison_SAVED_LC_ALL}) |
||||
|
||||
IF(NOT ${GPERF_version_result} EQUAL 0) |
||||
MESSAGE(SEND_ERROR "Command \"${GPERF_EXECUTABLE} --version\" failed with output:\n${GPERF_version_error}") |
||||
ELSE() |
||||
STRING(REGEX REPLACE "^GNU gperf ([^\n]+)\n.*" "\\1" |
||||
GPERF_VERSION "${GPERF_version_output}") |
||||
ENDIF() |
||||
|
||||
#============================================================ |
||||
# GPERF_TARGET (public macro) |
||||
#============================================================ |
||||
# |
||||
MACRO(GPERF_TARGET Name Input Output) |
||||
SET(GPERF_TARGET_usage "GPERF_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>]") |
||||
IF(${ARGC} GREATER 3) |
||||
IF(${ARGC} EQUAL 5) |
||||
IF("${ARGV3}" STREQUAL "COMPILE_FLAGS") |
||||
SET(GPERF_EXECUTABLE_opts "${ARGV4}") |
||||
SEPARATE_ARGUMENTS(GPERF_EXECUTABLE_opts) |
||||
ELSE() |
||||
MESSAGE(SEND_ERROR ${GPERF_TARGET_usage}) |
||||
ENDIF() |
||||
ELSE() |
||||
MESSAGE(SEND_ERROR ${GPERF_TARGET_usage}) |
||||
ENDIF() |
||||
ENDIF() |
||||
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${Output} |
||||
COMMAND ${GPERF_EXECUTABLE} |
||||
ARGS ${GPERF_EXECUTABLE_opts} < ${Input} > ${Output} |
||||
DEPENDS ${Input} |
||||
COMMENT "[GPERF][${Name}] Building hash with gperf ${GPERF_VERSION}" |
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) |
||||
|
||||
SET(GPERF_${Name}_DEFINED TRUE) |
||||
SET(GPERF_${Name}_OUTPUTS ${Output}) |
||||
SET(GPERF_${Name}_INPUT ${Input}) |
||||
SET(GPERF_${Name}_COMPILE_FLAGS ${GPERF_EXECUTABLE_opts}) |
||||
ENDMACRO(GPERF_TARGET) |
||||
#============================================================ |
||||
|
||||
|
||||
#============================================================ |
||||
# ADD_GPERF_BISON_DEPENDENCY (public macro) |
||||
#============================================================ |
||||
# |
||||
MACRO(ADD_GPERF_BISON_DEPENDENCY GperfTarget BisonTarget) |
||||
|
||||
IF(NOT GPERF_${GperfTarget}_OUTPUTS) |
||||
MESSAGE(SEND_ERROR "Gperf target `${GperfTarget}' does not exists.") |
||||
ENDIF() |
||||
|
||||
IF(NOT BISON_${BisonTarget}_OUTPUT_HEADER) |
||||
MESSAGE(SEND_ERROR "Bison target `${BisonTarget}' does not exists.") |
||||
ENDIF() |
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(${GPERF_${GperfTarget}_OUTPUTS} |
||||
PROPERTIES OBJECT_DEPENDS ${BISON_${BisonTarget}_OUTPUT_HEADER}) |
||||
ENDMACRO(ADD_GPERF_BISON_DEPENDENCY) |
||||
#============================================================ |
||||
|
||||
ENDIF(GPERF_EXECUTABLE) |
||||
|
||||
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) |
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GPERF REQUIRED_VARS GPERF_EXECUTABLE |
||||
VERSION_VAR GPERF_VERSION) |
||||
|
||||
# FindGPERF.cmake ends here |
@ -0,0 +1,260 @@
@@ -0,0 +1,260 @@
|
||||
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> ... ) |
||||
# |
||||
# This function is intended to be used in FindXXX.cmake modules files. |
||||
# It handles the REQUIRED, QUIET and version-related arguments to FIND_PACKAGE(). |
||||
# It also sets the <UPPERCASED_NAME>_FOUND variable. |
||||
# The package is considered found if all variables <var1>... listed contain |
||||
# valid results, e.g. valid filepaths. |
||||
# |
||||
# There are two modes of this function. The first argument in both modes is |
||||
# the name of the Find-module where it is called (in original casing). |
||||
# |
||||
# The first simple mode looks like this: |
||||
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> (DEFAULT_MSG|"Custom failure message") <var1>...<varN> ) |
||||
# If the variables <var1> to <varN> are all valid, then <UPPERCASED_NAME>_FOUND |
||||
# will be set to TRUE. |
||||
# If DEFAULT_MSG is given as second argument, then the function will generate |
||||
# itself useful success and error messages. You can also supply a custom error message |
||||
# for the failure case. This is not recommended. |
||||
# |
||||
# The second mode is more powerful and also supports version checking: |
||||
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS <var1>...<varN>] |
||||
# [VERSION_VAR <versionvar> |
||||
# [CONFIG_MODE] |
||||
# [FAIL_MESSAGE "Custom failure message"] ) |
||||
# |
||||
# As above, if <var1> through <varN> are all valid, <UPPERCASED_NAME>_FOUND |
||||
# will be set to TRUE. |
||||
# After REQUIRED_VARS the variables which are required for this package are listed. |
||||
# Following VERSION_VAR the name of the variable can be specified which holds |
||||
# the version of the package which has been found. If this is done, this version |
||||
# will be checked against the (potentially) specified required version used |
||||
# in the find_package() call. The EXACT keyword is also handled. The default |
||||
# messages include information about the required version and the version |
||||
# which has been actually found, both if the version is ok or not. |
||||
# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for |
||||
# a find_package(... NO_MODULE) call, in this case all the information |
||||
# provided by the config-mode of find_package() will be evaluated |
||||
# automatically. |
||||
# Via FAIL_MESSAGE a custom failure message can be specified, if this is not |
||||
# used, the default message will be displayed. |
||||
# |
||||
# Example for mode 1: |
||||
# |
||||
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) |
||||
# |
||||
# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and |
||||
# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. |
||||
# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, |
||||
# independent whether QUIET was used or not. |
||||
# If it is found, success will be reported, including the content of <var1>. |
||||
# On repeated Cmake runs, the same message won't be printed again. |
||||
# |
||||
# Example for mode 2: |
||||
# |
||||
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE |
||||
# VERSION_VAR BISON_VERSION) |
||||
# In this case, BISON is considered to be found if the variable(s) listed |
||||
# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case. |
||||
# Also the version of BISON will be checked by using the version contained |
||||
# in BISON_VERSION. |
||||
# Since no FAIL_MESSAGE is given, the default messages will be printed. |
||||
# |
||||
# Another example for mode 2: |
||||
# |
||||
# FIND_PACKAGE(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) |
||||
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4 CONFIG_MODE) |
||||
# In this case, FindAutmoc4.cmake wraps a call to FIND_PACKAGE(Automoc4 NO_MODULE) |
||||
# and adds an additional search directory for automoc4. |
||||
# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper |
||||
# success/error message. |
||||
|
||||
#============================================================================= |
||||
# Copyright 2007-2009 Kitware, Inc. |
||||
# |
||||
# Distributed under the OSI-approved BSD License (the "License"); |
||||
# see accompanying file Copyright.txt for details. |
||||
# |
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the |
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||||
# See the License for more information. |
||||
#============================================================================= |
||||
# (To distribute this file outside of CMake, substitute the full |
||||
# License text for the above reference.) |
||||
|
||||
INCLUDE(FindPackageMessage) |
||||
INCLUDE(CMakeParseArguments) |
||||
|
||||
# internal helper macro |
||||
MACRO(_FPHSA_FAILURE_MESSAGE _msg) |
||||
IF (${_NAME}_FIND_REQUIRED) |
||||
MESSAGE(FATAL_ERROR "${_msg}") |
||||
ELSE (${_NAME}_FIND_REQUIRED) |
||||
IF (NOT ${_NAME}_FIND_QUIETLY) |
||||
MESSAGE(STATUS "${_msg}") |
||||
ENDIF (NOT ${_NAME}_FIND_QUIETLY) |
||||
ENDIF (${_NAME}_FIND_REQUIRED) |
||||
ENDMACRO(_FPHSA_FAILURE_MESSAGE _msg) |
||||
|
||||
|
||||
# internal helper macro to generate the failure message when used in CONFIG_MODE: |
||||
MACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) |
||||
# <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: |
||||
IF(${_NAME}_CONFIG) |
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") |
||||
ELSE(${_NAME}_CONFIG) |
||||
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. |
||||
# List them all in the error message: |
||||
IF(${_NAME}_CONSIDERED_CONFIGS) |
||||
SET(configsText "") |
||||
LIST(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) |
||||
MATH(EXPR configsCount "${configsCount} - 1") |
||||
FOREACH(currentConfigIndex RANGE ${configsCount}) |
||||
LIST(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) |
||||
LIST(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) |
||||
SET(configsText "${configsText} ${filename} (version ${version})\n") |
||||
ENDFOREACH(currentConfigIndex) |
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") |
||||
|
||||
ELSE(${_NAME}_CONSIDERED_CONFIGS) |
||||
# Simple case: No Config-file was found at all: |
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") |
||||
ENDIF(${_NAME}_CONSIDERED_CONFIGS) |
||||
ENDIF(${_NAME}_CONFIG) |
||||
ENDMACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) |
||||
|
||||
|
||||
FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) |
||||
|
||||
# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in |
||||
# new extended or in the "old" mode: |
||||
SET(options CONFIG_MODE) |
||||
SET(oneValueArgs FAIL_MESSAGE VERSION_VAR) |
||||
SET(multiValueArgs REQUIRED_VARS) |
||||
SET(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) |
||||
LIST(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) |
||||
|
||||
IF(${INDEX} EQUAL -1) |
||||
SET(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) |
||||
SET(FPHSA_REQUIRED_VARS ${ARGN}) |
||||
SET(FPHSA_VERSION_VAR) |
||||
ELSE(${INDEX} EQUAL -1) |
||||
|
||||
CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) |
||||
|
||||
IF(FPHSA_UNPARSED_ARGUMENTS) |
||||
MESSAGE(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") |
||||
ENDIF(FPHSA_UNPARSED_ARGUMENTS) |
||||
|
||||
IF(NOT FPHSA_FAIL_MESSAGE) |
||||
SET(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") |
||||
ENDIF(NOT FPHSA_FAIL_MESSAGE) |
||||
ENDIF(${INDEX} EQUAL -1) |
||||
|
||||
# now that we collected all arguments, process them |
||||
|
||||
IF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") |
||||
SET(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") |
||||
ENDIF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") |
||||
|
||||
# In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package() |
||||
# when it successfully found the config-file, including version checking: |
||||
IF(FPHSA_CONFIG_MODE) |
||||
LIST(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) |
||||
LIST(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) |
||||
SET(FPHSA_VERSION_VAR ${_NAME}_VERSION) |
||||
ENDIF(FPHSA_CONFIG_MODE) |
||||
|
||||
IF(NOT FPHSA_REQUIRED_VARS) |
||||
MESSAGE(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") |
||||
ENDIF(NOT FPHSA_REQUIRED_VARS) |
||||
|
||||
LIST(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) |
||||
|
||||
STRING(TOUPPER ${_NAME} _NAME_UPPER) |
||||
STRING(TOLOWER ${_NAME} _NAME_LOWER) |
||||
|
||||
# collect all variables which were not found, so they can be printed, so the |
||||
# user knows better what went wrong (#6375) |
||||
SET(MISSING_VARS "") |
||||
SET(DETAILS "") |
||||
SET(${_NAME_UPPER}_FOUND TRUE) |
||||
# check if all passed variables are valid |
||||
FOREACH(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) |
||||
IF(NOT ${_CURRENT_VAR}) |
||||
SET(${_NAME_UPPER}_FOUND FALSE) |
||||
SET(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}") |
||||
ELSE(NOT ${_CURRENT_VAR}) |
||||
SET(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]") |
||||
ENDIF(NOT ${_CURRENT_VAR}) |
||||
ENDFOREACH(_CURRENT_VAR) |
||||
|
||||
|
||||
# version handling: |
||||
SET(VERSION_MSG "") |
||||
SET(VERSION_OK TRUE) |
||||
SET(VERSION ${${FPHSA_VERSION_VAR}} ) |
||||
IF (${_NAME}_FIND_VERSION) |
||||
|
||||
IF(VERSION) |
||||
|
||||
IF(${_NAME}_FIND_VERSION_EXACT) # exact version required |
||||
IF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") |
||||
SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") |
||||
SET(VERSION_OK FALSE) |
||||
ELSE (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") |
||||
SET(VERSION_MSG "(found suitable exact version \"${VERSION}\")") |
||||
ENDIF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") |
||||
|
||||
ELSE(${_NAME}_FIND_VERSION_EXACT) # minimum version specified: |
||||
IF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") |
||||
SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") |
||||
SET(VERSION_OK FALSE) |
||||
ELSE ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") |
||||
SET(VERSION_MSG "(found suitable version \"${VERSION}\", required is \"${${_NAME}_FIND_VERSION}\")") |
||||
ENDIF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") |
||||
ENDIF(${_NAME}_FIND_VERSION_EXACT) |
||||
|
||||
ELSE(VERSION) |
||||
|
||||
# if the package was not found, but a version was given, add that to the output: |
||||
IF(${_NAME}_FIND_VERSION_EXACT) |
||||
SET(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") |
||||
ELSE(${_NAME}_FIND_VERSION_EXACT) |
||||
SET(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") |
||||
ENDIF(${_NAME}_FIND_VERSION_EXACT) |
||||
|
||||
ENDIF(VERSION) |
||||
ELSE (${_NAME}_FIND_VERSION) |
||||
IF(VERSION) |
||||
SET(VERSION_MSG "(found version \"${VERSION}\")") |
||||
ENDIF(VERSION) |
||||
ENDIF (${_NAME}_FIND_VERSION) |
||||
|
||||
IF(VERSION_OK) |
||||
SET(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]") |
||||
ELSE(VERSION_OK) |
||||
SET(${_NAME_UPPER}_FOUND FALSE) |
||||
ENDIF(VERSION_OK) |
||||
|
||||
|
||||
# print the result: |
||||
IF (${_NAME_UPPER}_FOUND) |
||||
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG}" "${DETAILS}") |
||||
ELSE (${_NAME_UPPER}_FOUND) |
||||
|
||||
IF(FPHSA_CONFIG_MODE) |
||||
_FPHSA_HANDLE_FAILURE_CONFIG_MODE() |
||||
ELSE(FPHSA_CONFIG_MODE) |
||||
IF(NOT VERSION_OK) |
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") |
||||
ELSE(NOT VERSION_OK) |
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}") |
||||
ENDIF(NOT VERSION_OK) |
||||
ENDIF(FPHSA_CONFIG_MODE) |
||||
|
||||
ENDIF (${_NAME_UPPER}_FOUND) |
||||
|
||||
SET(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE) |
||||
|
||||
ENDFUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _FIRST_ARG) |
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
# - Try to find USB-1.0 |
||||
# Once done this will define |
||||
# |
||||
# USB-1.0_FOUND - system has USB-1.0 |
||||
# USB-1.0_INCLUDE_DIRS - the USB-1.0 include directory |
||||
# USB-1.0_LIBRARIES - Link these to use USB-1.0 |
||||
# USB-1.0_DEFINITIONS - Compiler switches required for using USB-1.0 |
||||
# |
||||
# Copyright (c) 2009 Andreas Schneider <mail@cynapses.org> |
||||
# |
||||
# Redistribution and use is allowed according to the terms of the New |
||||
# BSD license. |
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. |
||||
# |
||||
|
||||
|
||||
if (USB-1.0_LIBRARIES AND USB-1.0_INCLUDE_DIRS) |
||||
# in cache already |
||||
set(USB-1.0_FOUND TRUE) |
||||
else (USB-1.0_LIBRARIES AND USB-1.0_INCLUDE_DIRS) |
||||
# use pkg-config to get the directories and then use these values |
||||
# in the FIND_PATH() and FIND_LIBRARY() calls |
||||
if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) |
||||
include(UsePkgConfig) |
||||
pkgconfig(libusb-1.0 _USB-1.0_INCLUDEDIR _USB-1.0_LIBDIR _USB-1.0_LDFLAGS _USB-1.0_CFLAGS) |
||||
else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) |
||||
find_package(PkgConfig) |
||||
if (PKG_CONFIG_FOUND) |
||||
pkg_check_modules(_USB-1.0 libusb-1.0) |
||||
endif (PKG_CONFIG_FOUND) |
||||
endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) |
||||
|
||||
find_path(USB-1.0_INCLUDE_DIR |
||||
NAMES |
||||
libusb.h |
||||
PATHS |
||||
${_USB-1.0_INCLUDEDIR} |
||||
/usr/include |
||||
/usr/local/include |
||||
/opt/local/include |
||||
/sw/include |
||||
PATH_SUFFIXES |
||||
libusb-1.0 |
||||
) |
||||
mark_as_advanced(USB-1.0_INCLUDE_DIR) |
||||
|
||||
find_library(USB-1.0_LIBRARY |
||||
NAMES |
||||
usb-1.0 |
||||
PATHS |
||||
${_USB-1.0_LIBDIR} |
||||
/usr/lib |
||||
/usr/local/lib |
||||
/opt/local/lib |
||||
/sw/lib |
||||
) |
||||
mark_as_advanced(USB-1.0_LIBRARY) |
||||
|
||||
if (USB-1.0_LIBRARY) |
||||
set(USB-1.0_FOUND TRUE) |
||||
mark_as_advanced(USB-1.0_FOUND) |
||||
endif (USB-1.0_LIBRARY) |
||||
|
||||
set(USB-1.0_INCLUDE_DIRS |
||||
${USB-1.0_INCLUDE_DIR} |
||||
) |
||||
|
||||
if (USB-1.0_FOUND) |
||||
set(USB-1.0_LIBRARIES |
||||
${USB-1.0_LIBRARIES} |
||||
${USB-1.0_LIBRARY} |
||||
) |
||||
endif (USB-1.0_FOUND) |
||||
|
||||
if (USB-1.0_INCLUDE_DIRS AND USB-1.0_LIBRARIES) |
||||
set(USB-1.0_FOUND TRUE) |
||||
endif (USB-1.0_INCLUDE_DIRS AND USB-1.0_LIBRARIES) |
||||
|
||||
if (USB-1.0_FOUND) |
||||
if (NOT USB-1.0_FIND_QUIETLY) |
||||
message(STATUS "Found USB-1.0: ${USB-1.0_LIBRARIES}") |
||||
endif (NOT USB-1.0_FIND_QUIETLY) |
||||
else (USB-1.0_FOUND) |
||||
if (USB-1.0_FIND_REQUIRED) |
||||
message(FATAL_ERROR "Could not find USB-1.0") |
||||
endif (USB-1.0_FIND_REQUIRED) |
||||
endif (USB-1.0_FOUND) |
||||
|
||||
# show the USB-1.0_INCLUDE_DIRS and USB-1.0_LIBRARIES variables only in the advanced view |
||||
mark_as_advanced(USB-1.0_INCLUDE_DIRS USB-1.0_LIBRARIES) |
||||
|
||||
endif (USB-1.0_LIBRARIES AND USB-1.0_INCLUDE_DIRS) |
||||
|
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
#============================================================================= |
||||
# Copyright 2006-2009 Kitware, Inc. |
||||
# Copyright 2006-2008 Andreas Schneider <mail@cynapses.org> |
||||
# Copyright 2007 Wengo |
||||
# Copyright 2007 Mike Jackson |
||||
# Copyright 2008 Andreas Pakulat <apaku@gmx.de> |
||||
# Copyright 2008-2009 Philip Lowman <philip@yhbt.com> |
||||
# |
||||
# Distributed under the OSI-approved BSD License (the "License"); |
||||
# see accompanying file Copyright.txt for details. |
||||
# |
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the |
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||||
# See the License for more information. |
||||
#============================================================================= |
||||
# (To distributed this file outside of CMake, substitute the full |
||||
# License text for the above reference.) |
||||
|
||||
#------------------------------------------------------------------------------- |
||||
|
||||
# |
||||
# Runs compiler with "-dumpversion" and parses major/minor |
||||
# version with a regex. |
||||
# |
||||
FUNCTION(_COMPILER_DUMPVERSION _OUTPUT_VERSION) |
||||
|
||||
EXEC_PROGRAM(${CMAKE_C_COMPILER} |
||||
ARGS ${CMAKE_C_COMPILER_ARG1} -dumpversion |
||||
OUTPUT_VARIABLE _COMPILER_VERSION |
||||
) |
||||
STRING(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2" |
||||
_COMPILER_VERSION ${_COMPILER_VERSION}) |
||||
|
||||
SET(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE) |
||||
ENDFUNCTION() |
||||
|
||||
# |
||||
# End functions/macros |
||||
# |
||||
#------------------------------------------------------------------------------- |
||||
|
||||
|
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
diff -Nurp libusb-1.0-1.0.2/libusb/libusb.h libusb-1.0-1.0.2-orig/libusb/libusb.h |
||||
--- libusb-1.0-1.0.2/libusb/libusb.h 2009-06-07 23:18:19.000000000 +0200 |
||||
+++ libusb-1.0-1.0.2-orig/libusb/libusb.h 2009-08-10 22:07:41.000000000 +0200 |
||||
@@ -673,6 +673,9 @@ enum libusb_transfer_flags { |
||||
* from your transfer callback, as this will result in a double-free |
||||
* when this flag is acted upon. */ |
||||
LIBUSB_TRANSFER_FREE_TRANSFER = 1<<2, |
||||
+ |
||||
+ /** Send an extra termination packet, when needed */ |
||||
+ LIBUSB_TRANSFER_ZERO_PACKET = 1<<3, |
||||
}; |
||||
|
||||
/** \ingroup asyncio |
||||
diff -Nurp libusb-1.0-1.0.2/libusb/os/linux_usbfs.c libusb-1.0-1.0.2-orig/libusb/os/linux_usbfs.c |
||||
--- libusb-1.0-1.0.2/libusb/os/linux_usbfs.c 2009-06-10 22:41:26.000000000 +0200 |
||||
+++ libusb-1.0-1.0.2-orig/libusb/os/linux_usbfs.c 2009-08-10 22:10:14.000000000 +0200 |
||||
@@ -1298,6 +1298,8 @@ static int submit_bulk_transfer(struct u |
||||
urb->type = urb_type; |
||||
urb->endpoint = transfer->endpoint; |
||||
urb->buffer = transfer->buffer + (i * MAX_BULK_BUFFER_LENGTH); |
||||
+ if (transfer->flags & LIBUSB_TRANSFER_ZERO_PACKET) |
||||
+ urb->flags = USBFS_URB_ZERO_PACKET; |
||||
if (i == num_urbs - 1 && last_urb_partial) |
||||
urb->buffer_length = transfer->length % MAX_BULK_BUFFER_LENGTH; |
||||
else |
||||
diff -Nurp libusb-1.0-1.0.2/libusb/os/linux_usbfs.h libusb-1.0-1.0.2-orig/libusb/os/linux_usbfs.h |
||||
--- libusb-1.0-1.0.2/libusb/os/linux_usbfs.h 2008-07-16 16:17:57.000000000 +0200 |
||||
+++ libusb-1.0-1.0.2-orig/libusb/os/linux_usbfs.h 2009-08-10 22:13:15.000000000 +0200 |
||||
@@ -63,6 +63,9 @@ struct usbfs_getdriver { |
||||
#define USBFS_URB_DISABLE_SPD 1 |
||||
#define USBFS_URB_ISO_ASAP 2 |
||||
#define USBFS_URB_QUEUE_BULK 0x10 |
||||
+#define USBFS_URB_NO_FSBR 0x20 |
||||
+#define USBFS_URB_ZERO_PACKET 0x40 |
||||
+#define USBFS_URB_NO_INTERRUPT 0x80 |
||||
|
||||
enum usbfs_urb_type { |
||||
USBFS_URB_TYPE_ISO = 0, |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
set(CMAKE_SYSTEM_NAME "Generic") |
||||
set(CMAKE_SYSTEM_PROCESSOR "sh2") |
||||
|
||||
set_property(DIRECTORY PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) |
||||
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SOURCE_DIR}/toolchain/inst/) |
||||
|
||||
set(CMAKE_C_FLAGS "-m2 -ml -Os -ffreestanding -nostartfiles") |
||||
set(CMAKE_C_LINK_FLAGS "-static -EL -x --gc-sections") |
||||
|
||||
set(OBJCOPY ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-objcopy) |
||||
set(CMAKE_C_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-gcc") |
||||
set(CMAKE_AR ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-ar) |
||||
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-as) |
||||
set(CMAKE_ASM-ATT_COMPILER ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-as) |
||||
set(CMAKE_LINKER ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-ld) |
||||
set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-ld <OBJECTS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> -o <TARGET>") |
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh |
||||
|
||||
cat <<EOF > include/shared/version.h |
||||
#ifndef __CARL9170_SHARED_VERSION_H |
||||
#define __CARL9170_SHARED_VERSION_H |
||||
#define CARL9170FW_VERSION_YEAR $((100`date +%Y`%100)) |
||||
#define CARL9170FW_VERSION_MONTH $((100`date +%m`%100)) |
||||
#define CARL9170FW_VERSION_DAY $((100`date +%d`%100)) |
||||
#define CARL9170FW_VERSION_GIT "`git describe 2>/dev/null`" |
||||
#endif /* __CARL9170_SHARED_VERSION_H */ |
||||
EOF |
@ -0,0 +1,803 @@
@@ -0,0 +1,803 @@
|
||||
/* |
||||
* This file holds USB constants and structures that are needed for |
||||
* USB device APIs. These are used by the USB device model, which is |
||||
* defined in chapter 9 of the USB 2.0 specification and in the |
||||
* Wireless USB 1.0 (spread around). Linux has several APIs in C that |
||||
* need these: |
||||
* |
||||
* - the master/host side Linux-USB kernel driver API; |
||||
* - the "usbfs" user space API; and |
||||
* - the Linux "gadget" slave/device/peripheral side driver API. |
||||
* |
||||
* USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems |
||||
* act either as a USB master/host or as a USB slave/device. That means |
||||
* the master and slave side APIs benefit from working well together. |
||||
* |
||||
* There's also "Wireless USB", using low power short range radios for |
||||
* peripheral interconnection but otherwise building on the USB framework. |
||||
* |
||||
* Note all descriptors are declared '__attribute__((packed))' so that: |
||||
* |
||||
* [a] they never get padded, either internally (USB spec writers |
||||
* probably handled that) or externally; |
||||
* |
||||
* [b] so that accessing bigger-than-a-bytes fields will never |
||||
* generate bus errors on any platform, even when the location of |
||||
* its descriptor inside a bundle isn't "naturally aligned", and |
||||
* |
||||
* [c] for consistency, removing all doubt even when it appears to |
||||
* someone that the two other points are non-issues for that |
||||
* particular descriptor type. |
||||
*/ |
||||
|
||||
#ifndef __LINUX_USB_CH9_H |
||||
#define __LINUX_USB_CH9_H |
||||
|
||||
#include <linux/types.h> /* __u8 etc */ |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* CONTROL REQUEST SUPPORT */ |
||||
|
||||
/* |
||||
* USB directions |
||||
* |
||||
* This bit flag is used in endpoint descriptors' bEndpointAddress field. |
||||
* It's also one of three fields in control requests bRequestType. |
||||
*/ |
||||
#define USB_DIR_MASK 0x80 |
||||
#define USB_DIR_OUT 0 /* to device */ |
||||
#define USB_DIR_IN 0x80 /* to host */ |
||||
|
||||
/* |
||||
* USB types, the second of three bRequestType fields |
||||
*/ |
||||
#define USB_TYPE_MASK (0x03 << 5) |
||||
#define USB_TYPE_STANDARD (0x00 << 5) |
||||
#define USB_TYPE_CLASS (0x01 << 5) |
||||
#define USB_TYPE_VENDOR (0x02 << 5) |
||||
#define USB_TYPE_RESERVED (0x03 << 5) |
||||
|
||||
/* |
||||
* USB recipients, the third of three bRequestType fields |
||||
*/ |
||||
#define USB_RECIP_MASK 0x1f |
||||
#define USB_RECIP_DEVICE 0x00 |
||||
#define USB_RECIP_INTERFACE 0x01 |
||||
#define USB_RECIP_ENDPOINT 0x02 |
||||
#define USB_RECIP_OTHER 0x03 |
||||
/* From Wireless USB 1.0 */ |
||||
#define USB_RECIP_PORT 0x04 |
||||
#define USB_RECIP_RPIPE 0x05 |
||||
|
||||
/* |
||||
* Standard requests, for the bRequest field of a SETUP packet. |
||||
* |
||||
* These are qualified by the bRequestType field, so that for example |
||||
* TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved |
||||
* by a GET_STATUS request. |
||||
*/ |
||||
#define USB_REQ_GET_STATUS 0x00 |
||||
#define USB_REQ_CLEAR_FEATURE 0x01 |
||||
#define USB_REQ_SET_FEATURE 0x03 |
||||
#define USB_REQ_SET_ADDRESS 0x05 |
||||
#define USB_REQ_GET_DESCRIPTOR 0x06 |
||||
#define USB_REQ_SET_DESCRIPTOR 0x07 |
||||
#define USB_REQ_GET_CONFIGURATION 0x08 |
||||
#define USB_REQ_SET_CONFIGURATION 0x09 |
||||
#define USB_REQ_GET_INTERFACE 0x0A |
||||
#define USB_REQ_SET_INTERFACE 0x0B |
||||
#define USB_REQ_SYNCH_FRAME 0x0C |
||||
|
||||
#define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */ |
||||
#define USB_REQ_GET_ENCRYPTION 0x0E |
||||
#define USB_REQ_RPIPE_ABORT 0x0E |
||||
#define USB_REQ_SET_HANDSHAKE 0x0F |
||||
#define USB_REQ_RPIPE_RESET 0x0F |
||||
#define USB_REQ_GET_HANDSHAKE 0x10 |
||||
#define USB_REQ_SET_CONNECTION 0x11 |
||||
#define USB_REQ_SET_SECURITY_DATA 0x12 |
||||
#define USB_REQ_GET_SECURITY_DATA 0x13 |
||||
#define USB_REQ_SET_WUSB_DATA 0x14 |
||||
#define USB_REQ_LOOPBACK_DATA_WRITE 0x15 |
||||
#define USB_REQ_LOOPBACK_DATA_READ 0x16 |
||||
#define USB_REQ_SET_INTERFACE_DS 0x17 |
||||
|
||||
/* The Link Power Management (LPM) ECN defines USB_REQ_TEST_AND_SET command, |
||||
* used by hubs to put ports into a new L1 suspend state, except that it |
||||
* forgot to define its number ... |
||||
*/ |
||||
|
||||
/* |
||||
* USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and |
||||
* are read as a bit array returned by USB_REQ_GET_STATUS. (So there |
||||
* are at most sixteen features of each type.) Hubs may also support a |
||||
* new USB_REQ_TEST_AND_SET_FEATURE to put ports into L1 suspend. |
||||
*/ |
||||
#define USB_DEVICE_SELF_POWERED 0 /* (read only) */ |
||||
#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */ |
||||
#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */ |
||||
#define USB_DEVICE_BATTERY 2 /* (wireless) */ |
||||
#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */ |
||||
#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/ |
||||
#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */ |
||||
#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */ |
||||
#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */ |
||||
|
||||
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ |
||||
|
||||
|
||||
/** |
||||
* struct usb_ctrlrequest - SETUP data for a USB device control request |
||||
* @bRequestType: matches the USB bmRequestType field |
||||
* @bRequest: matches the USB bRequest field |
||||
* @wValue: matches the USB wValue field (le16 byte order) |
||||
* @wIndex: matches the USB wIndex field (le16 byte order) |
||||
* @wLength: matches the USB wLength field (le16 byte order) |
||||
* |
||||
* This structure is used to send control requests to a USB device. It matches |
||||
* the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the |
||||
* USB spec for a fuller description of the different fields, and what they are |
||||
* used for. |
||||
* |
||||
* Note that the driver for any interface can issue control requests. |
||||
* For most devices, interfaces don't coordinate with each other, so |
||||
* such requests may be made at any time. |
||||
*/ |
||||
struct usb_ctrlrequest { |
||||
__u8 bRequestType; |
||||
__u8 bRequest; |
||||
__le16 wValue; |
||||
__le16 wIndex; |
||||
__le16 wLength; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* |
||||
* STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or |
||||
* (rarely) accepted by SET_DESCRIPTOR. |
||||
* |
||||
* Note that all multi-byte values here are encoded in little endian |
||||
* byte order "on the wire". Within the kernel and when exposed |
||||
* through the Linux-USB APIs, they are not converted to cpu byte |
||||
* order; it is the responsibility of the client code to do this. |
||||
* The single exception is when device and configuration descriptors (but |
||||
* not other descriptors) are read from usbfs (i.e. /proc/bus/usb/BBB/DDD); |
||||
* in this case the fields are converted to host endianness by the kernel. |
||||
*/ |
||||
|
||||
/* |
||||
* Descriptor types ... USB 2.0 spec table 9.5 |
||||
*/ |
||||
#define USB_DT_DEVICE 0x01 |
||||
#define USB_DT_CONFIG 0x02 |
||||
#define USB_DT_STRING 0x03 |
||||
#define USB_DT_INTERFACE 0x04 |
||||
#define USB_DT_ENDPOINT 0x05 |
||||
#define USB_DT_DEVICE_QUALIFIER 0x06 |
||||
#define USB_DT_OTHER_SPEED_CONFIG 0x07 |
||||
#define USB_DT_INTERFACE_POWER 0x08 |
||||
/* these are from a minor usb 2.0 revision (ECN) */ |
||||
#define USB_DT_OTG 0x09 |
||||
#define USB_DT_DEBUG 0x0a |
||||
#define USB_DT_INTERFACE_ASSOCIATION 0x0b |
||||
/* these are from the Wireless USB spec */ |
||||
#define USB_DT_SECURITY 0x0c |
||||
#define USB_DT_KEY 0x0d |
||||
#define USB_DT_ENCRYPTION_TYPE 0x0e |
||||
#define USB_DT_BOS 0x0f |
||||
#define USB_DT_DEVICE_CAPABILITY 0x10 |
||||
#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11 |
||||
#define USB_DT_WIRE_ADAPTER 0x21 |
||||
#define USB_DT_RPIPE 0x22 |
||||
#define USB_DT_CS_RADIO_CONTROL 0x23 |
||||
/* From the USB 3.0 spec */ |
||||
#define USB_DT_SS_ENDPOINT_COMP 0x30 |
||||
|
||||
/* Conventional codes for class-specific descriptors. The convention is |
||||
* defined in the USB "Common Class" Spec (3.11). Individual class specs |
||||
* are authoritative for their usage, not the "common class" writeup. |
||||
*/ |
||||
#define USB_DT_CS_DEVICE (USB_TYPE_CLASS | USB_DT_DEVICE) |
||||
#define USB_DT_CS_CONFIG (USB_TYPE_CLASS | USB_DT_CONFIG) |
||||
#define USB_DT_CS_STRING (USB_TYPE_CLASS | USB_DT_STRING) |
||||
#define USB_DT_CS_INTERFACE (USB_TYPE_CLASS | USB_DT_INTERFACE) |
||||
#define USB_DT_CS_ENDPOINT (USB_TYPE_CLASS | USB_DT_ENDPOINT) |
||||
|
||||
/* All standard descriptors have these 2 fields at the beginning */ |
||||
struct usb_descriptor_header { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
} __attribute__ ((packed)); |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_DEVICE: Device descriptor */ |
||||
struct usb_device_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 bcdUSB; |
||||
__u8 bDeviceClass; |
||||
__u8 bDeviceSubClass; |
||||
__u8 bDeviceProtocol; |
||||
__u8 bMaxPacketSize0; |
||||
__le16 idVendor; |
||||
__le16 idProduct; |
||||
__le16 bcdDevice; |
||||
__u8 iManufacturer; |
||||
__u8 iProduct; |
||||
__u8 iSerialNumber; |
||||
__u8 bNumConfigurations; |
||||
} __attribute__ ((packed)); |
||||
|
||||
#define USB_DT_DEVICE_SIZE 18 |
||||
|
||||
|
||||
/* |
||||
* Device and/or Interface Class codes |
||||
* as found in bDeviceClass or bInterfaceClass |
||||
* and defined by www.usb.org documents |
||||
*/ |
||||
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ |
||||
#define USB_CLASS_AUDIO 1 |
||||
#define USB_CLASS_COMM 2 |
||||
#define USB_CLASS_HID 3 |
||||
#define USB_CLASS_PHYSICAL 5 |
||||
#define USB_CLASS_STILL_IMAGE 6 |
||||
#define USB_CLASS_PRINTER 7 |
||||
#define USB_CLASS_MASS_STORAGE 8 |
||||
#define USB_CLASS_HUB 9 |
||||
#define USB_CLASS_CDC_DATA 0x0a |
||||
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */ |
||||
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */ |
||||
#define USB_CLASS_VIDEO 0x0e |
||||
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0 |
||||
#define USB_CLASS_MISC 0xef |
||||
#define USB_CLASS_APP_SPEC 0xfe |
||||
#define USB_CLASS_VENDOR_SPEC 0xff |
||||
|
||||
#define USB_SUBCLASS_VENDOR_SPEC 0xff |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_CONFIG: Configuration descriptor information. |
||||
* |
||||
* USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the |
||||
* descriptor type is different. Highspeed-capable devices can look |
||||
* different depending on what speed they're currently running. Only |
||||
* devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG |
||||
* descriptors. |
||||
*/ |
||||
struct usb_config_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 wTotalLength; |
||||
__u8 bNumInterfaces; |
||||
__u8 bConfigurationValue; |
||||
__u8 iConfiguration; |
||||
__u8 bmAttributes; |
||||
__u8 bMaxPower; |
||||
} __attribute__ ((packed)); |
||||
|
||||
#define USB_DT_CONFIG_SIZE 9 |
||||
|
||||
/* from config descriptor bmAttributes */ |
||||
#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */ |
||||
#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */ |
||||
#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */ |
||||
#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */ |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_STRING: String descriptor */ |
||||
struct usb_string_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 wData[1]; /* UTF-16LE encoded */ |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* note that "string" zero is special, it holds language codes that |
||||
* the device supports, not Unicode characters. |
||||
*/ |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_INTERFACE: Interface descriptor */ |
||||
struct usb_interface_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bInterfaceNumber; |
||||
__u8 bAlternateSetting; |
||||
__u8 bNumEndpoints; |
||||
__u8 bInterfaceClass; |
||||
__u8 bInterfaceSubClass; |
||||
__u8 bInterfaceProtocol; |
||||
__u8 iInterface; |
||||
} __attribute__ ((packed)); |
||||
|
||||
#define USB_DT_INTERFACE_SIZE 9 |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_ENDPOINT: Endpoint descriptor */ |
||||
struct usb_endpoint_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bEndpointAddress; |
||||
__u8 bmAttributes; |
||||
__le16 wMaxPacketSize; |
||||
__u8 bInterval; |
||||
} __attribute__ ((packed)); |
||||
|
||||
#define USB_DT_ENDPOINT_SIZE 7 |
||||
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ |
||||
|
||||
|
||||
/* |
||||
* Endpoints |
||||
*/ |
||||
#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ |
||||
#define USB_ENDPOINT_DIR_MASK 0x80 |
||||
|
||||
#define USB_ENDPOINT_SYNCTYPE 0x0c |
||||
#define USB_ENDPOINT_SYNC_NONE (0 << 2) |
||||
#define USB_ENDPOINT_SYNC_ASYNC (1 << 2) |
||||
#define USB_ENDPOINT_SYNC_ADAPTIVE (2 << 2) |
||||
#define USB_ENDPOINT_SYNC_SYNC (3 << 2) |
||||
|
||||
#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ |
||||
#define USB_ENDPOINT_XFER_CONTROL 0 |
||||
#define USB_ENDPOINT_XFER_ISOC 1 |
||||
#define USB_ENDPOINT_XFER_BULK 2 |
||||
#define USB_ENDPOINT_XFER_INT 3 |
||||
#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/** |
||||
* usb_endpoint_num - get the endpoint's number |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns @epd's number: 0 to 15. |
||||
*/ |
||||
static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_type - get the endpoint's transfer type |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns one of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according |
||||
* to @epd's transfer type. |
||||
*/ |
||||
static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_dir_in - check if the endpoint has IN direction |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint is of type IN, otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_dir_out - check if the endpoint has OUT direction |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint is of type OUT, otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_dir_out( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint is of type bulk, otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_xfer_bulk( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
||||
USB_ENDPOINT_XFER_BULK); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_xfer_control - check if the endpoint has control transfer type |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint is of type control, otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_xfer_control( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
||||
USB_ENDPOINT_XFER_CONTROL); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint is of type interrupt, otherwise it returns |
||||
* false. |
||||
*/ |
||||
static inline int usb_endpoint_xfer_int( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
||||
USB_ENDPOINT_XFER_INT); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint is of type isochronous, otherwise it returns |
||||
* false. |
||||
*/ |
||||
static inline int usb_endpoint_xfer_isoc( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
||||
USB_ENDPOINT_XFER_ISOC; |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_is_bulk_in - check if the endpoint is bulk IN |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint has bulk transfer type and IN direction, |
||||
* otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_is_bulk_in( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint has bulk transfer type and OUT direction, |
||||
* otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_is_bulk_out( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_is_int_in - check if the endpoint is interrupt IN |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint has interrupt transfer type and IN direction, |
||||
* otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_is_int_in( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_is_int_out - check if the endpoint is interrupt OUT |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint has interrupt transfer type and OUT direction, |
||||
* otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_is_int_out( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint has isochronous transfer type and IN direction, |
||||
* otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_is_isoc_in( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd); |
||||
} |
||||
|
||||
/** |
||||
* usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT |
||||
* @epd: endpoint to be checked |
||||
* |
||||
* Returns true if the endpoint has isochronous transfer type and OUT direction, |
||||
* otherwise it returns false. |
||||
*/ |
||||
static inline int usb_endpoint_is_isoc_out( |
||||
const struct usb_endpoint_descriptor *epd) |
||||
{ |
||||
return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd); |
||||
} |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_SS_ENDPOINT_COMP: SuperSpeed Endpoint Companion descriptor */ |
||||
struct usb_ss_ep_comp_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bMaxBurst; |
||||
__u8 bmAttributes; |
||||
__le16 wBytesPerInterval; |
||||
} __attribute__ ((packed)); |
||||
|
||||
#define USB_DT_SS_EP_COMP_SIZE 6 |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */ |
||||
struct usb_qualifier_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 bcdUSB; |
||||
__u8 bDeviceClass; |
||||
__u8 bDeviceSubClass; |
||||
__u8 bDeviceProtocol; |
||||
__u8 bMaxPacketSize0; |
||||
__u8 bNumConfigurations; |
||||
__u8 bRESERVED; |
||||
} __attribute__ ((packed)); |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_OTG (from OTG 1.0a supplement) */ |
||||
struct usb_otg_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bmAttributes; /* support for HNP, SRP, etc */ |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* from usb_otg_descriptor.bmAttributes */ |
||||
#define USB_OTG_SRP (1 << 0) |
||||
#define USB_OTG_HNP (1 << 1) /* swap host/device roles */ |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */ |
||||
struct usb_debug_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
/* bulk endpoints with 8 byte maxpacket */ |
||||
__u8 bDebugInEndpoint; |
||||
__u8 bDebugOutEndpoint; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */ |
||||
struct usb_interface_assoc_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bFirstInterface; |
||||
__u8 bInterfaceCount; |
||||
__u8 bFunctionClass; |
||||
__u8 bFunctionSubClass; |
||||
__u8 bFunctionProtocol; |
||||
__u8 iFunction; |
||||
} __attribute__ ((packed)); |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_SECURITY: group of wireless security descriptors, including |
||||
* encryption types available for setting up a CC/association. |
||||
*/ |
||||
struct usb_security_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 wTotalLength; |
||||
__u8 bNumEncryptionTypes; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_KEY: used with {GET,SET}_SECURITY_DATA; only public keys |
||||
* may be retrieved. |
||||
*/ |
||||
struct usb_key_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 tTKID[3]; |
||||
__u8 bReserved; |
||||
__u8 bKeyData[0]; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_ENCRYPTION_TYPE: bundled in DT_SECURITY groups */ |
||||
struct usb_encryption_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bEncryptionType; |
||||
#define USB_ENC_TYPE_UNSECURE 0 |
||||
#define USB_ENC_TYPE_WIRED 1 /* non-wireless mode */ |
||||
#define USB_ENC_TYPE_CCM_1 2 /* aes128/cbc session */ |
||||
#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */ |
||||
__u8 bEncryptionValue; /* use in SET_ENCRYPTION */ |
||||
__u8 bAuthKeyIndex; |
||||
} __attribute__((packed)); |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_BOS: group of device-level capabilities */ |
||||
struct usb_bos_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 wTotalLength; |
||||
__u8 bNumDeviceCaps; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_DEVICE_CAPABILITY: grouped with BOS */ |
||||
struct usb_dev_cap_header { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDevCapabilityType; |
||||
} __attribute__((packed)); |
||||
|
||||
#define USB_CAP_TYPE_WIRELESS_USB 1 |
||||
|
||||
struct usb_wireless_cap_descriptor { /* Ultra Wide Band */ |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDevCapabilityType; |
||||
|
||||
__u8 bmAttributes; |
||||
#define USB_WIRELESS_P2P_DRD (1 << 1) |
||||
#define USB_WIRELESS_BEACON_MASK (3 << 2) |
||||
#define USB_WIRELESS_BEACON_SELF (1 << 2) |
||||
#define USB_WIRELESS_BEACON_DIRECTED (2 << 2) |
||||
#define USB_WIRELESS_BEACON_NONE (3 << 2) |
||||
__le16 wPHYRates; /* bit rates, Mbps */ |
||||
#define USB_WIRELESS_PHY_53 (1 << 0) /* always set */ |
||||
#define USB_WIRELESS_PHY_80 (1 << 1) |
||||
#define USB_WIRELESS_PHY_107 (1 << 2) /* always set */ |
||||
#define USB_WIRELESS_PHY_160 (1 << 3) |
||||
#define USB_WIRELESS_PHY_200 (1 << 4) /* always set */ |
||||
#define USB_WIRELESS_PHY_320 (1 << 5) |
||||
#define USB_WIRELESS_PHY_400 (1 << 6) |
||||
#define USB_WIRELESS_PHY_480 (1 << 7) |
||||
__u8 bmTFITXPowerInfo; /* TFI power levels */ |
||||
__u8 bmFFITXPowerInfo; /* FFI power levels */ |
||||
__le16 bmBandGroup; |
||||
__u8 bReserved; |
||||
} __attribute__((packed)); |
||||
|
||||
#define USB_CAP_TYPE_EXT 2 |
||||
|
||||
struct usb_ext_cap_descriptor { /* Link Power Management */ |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDevCapabilityType; |
||||
__u8 bmAttributes; |
||||
#define USB_LPM_SUPPORT (1 << 1) /* supports LPM */ |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with |
||||
* each endpoint descriptor for a wireless device |
||||
*/ |
||||
struct usb_wireless_ep_comp_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bMaxBurst; |
||||
__u8 bMaxSequence; |
||||
__le16 wMaxStreamDelay; |
||||
__le16 wOverTheAirPacketSize; |
||||
__u8 bOverTheAirInterval; |
||||
__u8 bmCompAttributes; |
||||
#define USB_ENDPOINT_SWITCH_MASK 0x03 /* in bmCompAttributes */ |
||||
#define USB_ENDPOINT_SWITCH_NO 0 |
||||
#define USB_ENDPOINT_SWITCH_SWITCH 1 |
||||
#define USB_ENDPOINT_SWITCH_SCALE 2 |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_REQ_SET_HANDSHAKE is a four-way handshake used between a wireless |
||||
* host and a device for connection set up, mutual authentication, and |
||||
* exchanging short lived session keys. The handshake depends on a CC. |
||||
*/ |
||||
struct usb_handshake { |
||||
__u8 bMessageNumber; |
||||
__u8 bStatus; |
||||
__u8 tTKID[3]; |
||||
__u8 bReserved; |
||||
__u8 CDID[16]; |
||||
__u8 nonce[16]; |
||||
__u8 MIC[8]; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_REQ_SET_CONNECTION modifies or revokes a connection context (CC). |
||||
* A CC may also be set up using non-wireless secure channels (including |
||||
* wired USB!), and some devices may support CCs with multiple hosts. |
||||
*/ |
||||
struct usb_connection_context { |
||||
__u8 CHID[16]; /* persistent host id */ |
||||
__u8 CDID[16]; /* device id (unique w/in host context) */ |
||||
__u8 CK[16]; /* connection key */ |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB 2.0 defines three speeds, here's how Linux identifies them */ |
||||
|
||||
enum usb_device_speed { |
||||
USB_SPEED_UNKNOWN = 0, /* enumerating */ |
||||
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ |
||||
USB_SPEED_HIGH, /* usb 2.0 */ |
||||
USB_SPEED_WIRELESS, /* wireless (usb 2.5) */ |
||||
USB_SPEED_SUPER, /* usb 3.0 */ |
||||
}; |
||||
|
||||
enum usb_device_state { |
||||
/* NOTATTACHED isn't in the USB spec, and this state acts |
||||
* the same as ATTACHED ... but it's clearer this way. |
||||
*/ |
||||
USB_STATE_NOTATTACHED = 0, |
||||
|
||||
/* chapter 9 and authentication (wireless) device states */ |
||||
USB_STATE_ATTACHED, |
||||
USB_STATE_POWERED, /* wired */ |
||||
USB_STATE_RECONNECTING, /* auth */ |
||||
USB_STATE_UNAUTHENTICATED, /* auth */ |
||||
USB_STATE_DEFAULT, /* limited function */ |
||||
USB_STATE_ADDRESS, |
||||
USB_STATE_CONFIGURED, /* most functions */ |
||||
|
||||
USB_STATE_SUSPENDED |
||||
|
||||
/* NOTE: there are actually four different SUSPENDED |
||||
* states, returning to POWERED, DEFAULT, ADDRESS, or |
||||
* CONFIGURED respectively when SOF tokens flow again. |
||||
* At this level there's no difference between L1 and L2 |
||||
* suspend states. (L2 being original USB 1.1 suspend.) |
||||
*/ |
||||
}; |
||||
|
||||
#endif /* __LINUX_USB_CH9_H */ |
@ -0,0 +1,107 @@
@@ -0,0 +1,107 @@
|
||||
/* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __SHARED_COMPILER_H |
||||
#define __SHARED_COMPILER_H |
||||
|
||||
#define __noinline __attribute__((noinline)) |
||||
#define __noreturn __attribute__((noreturn)) |
||||
#define __inline __attribute__((always_inline)) |
||||
#define __hot __attribute__((hot)) |
||||
#define __cold __attribute__((cold)) |
||||
#define __unused __attribute__((unused)) |
||||
#define __force __attribute__((force)) |
||||
#define __section(s) __attribute__((section("." # s))) |
||||
#define __aligned(a) __attribute__((aligned(a))) |
||||
#define __packed __attribute__((packed)) |
||||
|
||||
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) |
||||
#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) |
||||
|
||||
#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1) |
||||
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) |
||||
|
||||
#define __roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) |
||||
|
||||
#define __must_be_array(a) \ |
||||
BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) |
||||
#define ARRAY_SIZE(arr) (sizeof((arr)) / sizeof((arr)[0]) + __must_be_array(arr)) |
||||
|
||||
#define BIT(b) (1 << (b)) |
||||
#define MASK(w) (BIT(w) - 1) |
||||
|
||||
#undef offsetof |
||||
#ifdef __compiler_offsetof |
||||
# define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER) |
||||
#else |
||||
# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) |
||||
#endif |
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1) |
||||
#define unlikely(x) __builtin_expect(!!(x), 0) |
||||
|
||||
#define min(x, y) ({ \ |
||||
typeof(x) _min1 = (x); \ |
||||
typeof(y) _min2 = (y); \ |
||||
(void) (&_min1 == &_min2); \ |
||||
_min1 < _min2 ? _min1 : _min2; }) |
||||
|
||||
#define max(x, y) ({ \ |
||||
typeof(x) _max1 = (x); \ |
||||
typeof(y) _max2 = (y); \ |
||||
(void) (&_max1 == &_max2); \ |
||||
_max1 > _max2 ? _max1 : _max2; }) |
||||
|
||||
#define min_t(type, x, y) ({ \ |
||||
type __min1 = (x); \ |
||||
type __min2 = (y); \ |
||||
__min1 < __min2 ? __min1 : __min2; }) |
||||
|
||||
#define max_t(type, x, y) ({ \ |
||||
type __max1 = (x); \ |
||||
type __max2 = (y); \ |
||||
__max1 > __max2 ? __max1 : __max2; }) |
||||
|
||||
|
||||
#define container_of(ptr, type, member) ({ \ |
||||
const typeof(((type *)0)->member) * __mptr = (ptr); \ |
||||
(type *)(((unsigned long)__mptr - offsetof(type, member))); }) |
||||
|
||||
#define MAX_ERRNO 4095 |
||||
|
||||
#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) |
||||
|
||||
static inline void *ERR_PTR(long errornr) |
||||
{ |
||||
return (void *) errornr; |
||||
} |
||||
|
||||
static inline long PTR_ERR(const void *ptr) |
||||
{ |
||||
return (long) ptr; |
||||
} |
||||
|
||||
static inline long IS_ERR(const void *ptr) |
||||
{ |
||||
return IS_ERR_VALUE((unsigned long)ptr); |
||||
} |
||||
|
||||
static inline long IS_ERR_OR_NULL(const void *ptr) |
||||
{ |
||||
return !ptr || IS_ERR_VALUE((unsigned long)ptr); |
||||
} |
||||
|
||||
#endif /* __SHARED_COMPILER_H */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
/* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __LINUX_TYPES_H |
||||
#define __LINUX_TYPES_H |
||||
|
||||
#include <stdint.h> |
||||
#include <stdbool.h> |
||||
#include <stdlib.h> |
||||
#include <sys/param.h> |
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN |
||||
#error "big endian is not supported by target" |
||||
#endif |
||||
|
||||
typedef uint16_t __le16; |
||||
typedef uint32_t __le32; |
||||
typedef uint64_t __le64; |
||||
|
||||
typedef uint8_t u8; |
||||
typedef uint8_t __u8; |
||||
typedef uint16_t u16; |
||||
typedef uint16_t __u16; |
||||
typedef uint32_t u32; |
||||
typedef uint32_t __u32; |
||||
typedef uint64_t u64; |
||||
typedef uint64_t __u64; |
||||
typedef int8_t s8; |
||||
typedef int8_t __s8; |
||||
typedef int16_t s16; |
||||
typedef int16_t __s16; |
||||
typedef int32_t s32; |
||||
typedef int32_t __s32; |
||||
typedef int64_t s64; |
||||
typedef int64_t __s64; |
||||
|
||||
#define cpu_to_le16(x) ((__le16)(uint16_t)(x)) |
||||
#define le16_to_cpu(x) ((uint16_t)(__le16)(x)) |
||||
#define cpu_to_le32(x) ((__le32)(uint32_t)(x)) |
||||
#define le32_to_cpu(x) ((uint32_t)(__le32)(x)) |
||||
#define cpu_to_le64(x) ((__le64)(uint64_t)(x)) |
||||
#define le64_to_cpu(x) ((uint64_t)(__le64)(x)) |
||||
|
||||
typedef uint16_t __be16; |
||||
typedef uint32_t __be32; |
||||
typedef uint64_t __be64; |
||||
|
||||
#endif /* __LINUX_TYPES_H */ |
@ -0,0 +1,216 @@
@@ -0,0 +1,216 @@
|
||||
/* |
||||
* Shared Atheros AR9170 Header |
||||
* |
||||
* EEPROM layout |
||||
* |
||||
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net> |
||||
* |
||||
* 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; see the file COPYING. If not, see |
||||
* http://www.gnu.org/licenses/. |
||||
* |
||||
* This file incorporates work covered by the following copyright and |
||||
* permission notice: |
||||
* Copyright (c) 2007-2008 Atheros Communications, Inc. |
||||
* |
||||
* Permission to use, copy, modify, and/or distribute this software for any |
||||
* purpose with or without fee is hereby granted, provided that the above |
||||
* copyright notice and this permission notice appear in all copies. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
*/ |
||||
#ifndef __CARL9170_SHARED_EEPROM_H |
||||
#define __CARL9170_SHARED_EEPROM_H |
||||
|
||||
#define AR9170_EEPROM_START 0x1600 |
||||
|
||||
#define AR5416_MAX_CHAINS 2 |
||||
#define AR5416_MODAL_SPURS 5 |
||||
|
||||
struct ar9170_eeprom_modal { |
||||
__le32 antCtrlChain[AR5416_MAX_CHAINS]; |
||||
__le32 antCtrlCommon; |
||||
s8 antennaGainCh[AR5416_MAX_CHAINS]; |
||||
u8 switchSettling; |
||||
u8 txRxAttenCh[AR5416_MAX_CHAINS]; |
||||
u8 rxTxMarginCh[AR5416_MAX_CHAINS]; |
||||
s8 adcDesiredSize; |
||||
s8 pgaDesiredSize; |
||||
u8 xlnaGainCh[AR5416_MAX_CHAINS]; |
||||
u8 txEndToXpaOff; |
||||
u8 txEndToRxOn; |
||||
u8 txFrameToXpaOn; |
||||
u8 thresh62; |
||||
s8 noiseFloorThreshCh[AR5416_MAX_CHAINS]; |
||||
u8 xpdGain; |
||||
u8 xpd; |
||||
s8 iqCalICh[AR5416_MAX_CHAINS]; |
||||
s8 iqCalQCh[AR5416_MAX_CHAINS]; |
||||
u8 pdGainOverlap; |
||||
u8 ob; |
||||
u8 db; |
||||
u8 xpaBiasLvl; |
||||
u8 pwrDecreaseFor2Chain; |
||||
u8 pwrDecreaseFor3Chain; |
||||
u8 txFrameToDataStart; |
||||
u8 txFrameToPaOn; |
||||
u8 ht40PowerIncForPdadc; |
||||
u8 bswAtten[AR5416_MAX_CHAINS]; |
||||
u8 bswMargin[AR5416_MAX_CHAINS]; |
||||
u8 swSettleHt40; |
||||
u8 reserved[22]; |
||||
struct spur_channel { |
||||
__le16 spurChan; |
||||
u8 spurRangeLow; |
||||
u8 spurRangeHigh; |
||||
} __packed spur_channels[AR5416_MODAL_SPURS]; |
||||
} __packed; |
||||
|
||||
#define AR5416_NUM_PD_GAINS 4 |
||||
#define AR5416_PD_GAIN_ICEPTS 5 |
||||
|
||||
struct ar9170_calibration_data_per_freq { |
||||
u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; |
||||
u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; |
||||
} __packed; |
||||
|
||||
#define AR5416_NUM_5G_CAL_PIERS 8 |
||||
#define AR5416_NUM_2G_CAL_PIERS 4 |
||||
|
||||
#define AR5416_NUM_5G_TARGET_PWRS 8 |
||||
#define AR5416_NUM_2G_CCK_TARGET_PWRS 3 |
||||
#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4 |
||||
#define AR5416_MAX_NUM_TGT_PWRS 8 |
||||
|
||||
struct ar9170_calibration_target_power_legacy { |
||||
u8 freq; |
||||
u8 power[4]; |
||||
} __packed; |
||||
|
||||
struct ar9170_calibration_target_power_ht { |
||||
u8 freq; |
||||
u8 power[8]; |
||||
} __packed; |
||||
|
||||
#define AR5416_NUM_CTLS 24 |
||||
|
||||
struct ar9170_calctl_edges { |
||||
u8 channel; |
||||
#define AR9170_CALCTL_EDGE_FLAGS 0xC0 |
||||
u8 power_flags; |
||||
} __packed; |
||||
|
||||
#define AR5416_NUM_BAND_EDGES 8 |
||||
|
||||
struct ar9170_calctl_data { |
||||
struct ar9170_calctl_edges |
||||
control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; |
||||
} __packed; |
||||
|
||||
struct ar9170_eeprom { |
||||
__le16 length; |
||||
__le16 checksum; |
||||
__le16 version; |
||||
u8 operating_flags; |
||||
#define AR9170_OPFLAG_5GHZ 1 |
||||
#define AR9170_OPFLAG_2GHZ 2 |
||||
u8 misc; |
||||
__le16 reg_domain[2]; |
||||
u8 mac_address[6]; |
||||
u8 rx_mask; |
||||
u8 tx_mask; |
||||
__le16 rf_silent; |
||||
__le16 bluetooth_options; |
||||
__le16 device_capabilities; |
||||
__le32 build_number; |
||||
u8 deviceType; |
||||
u8 reserved[33]; |
||||
|
||||
u8 customer_data[64]; |
||||
|
||||
struct ar9170_eeprom_modal |
||||
modal_header[2]; |
||||
|
||||
u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS]; |
||||
u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS]; |
||||
|
||||
struct ar9170_calibration_data_per_freq |
||||
cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS], |
||||
cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; |
||||
|
||||
/* power calibration data */ |
||||
struct ar9170_calibration_target_power_legacy |
||||
cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS]; |
||||
struct ar9170_calibration_target_power_ht |
||||
cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS], |
||||
cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS]; |
||||
|
||||
struct ar9170_calibration_target_power_legacy |
||||
cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS], |
||||
cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS]; |
||||
struct ar9170_calibration_target_power_ht |
||||
cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS], |
||||
cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS]; |
||||
|
||||
/* conformance testing limits */ |
||||
u8 ctl_index[AR5416_NUM_CTLS]; |
||||
struct ar9170_calctl_data |
||||
ctl_data[AR5416_NUM_CTLS]; |
||||
|
||||
u8 pad; |
||||
__le16 subsystem_id; |
||||
} __packed; |
||||
|
||||
#define AR9170_LED_MODE_POWER_ON 0x0001 |
||||
#define AR9170_LED_MODE_RESERVED 0x0002 |
||||
#define AR9170_LED_MODE_DISABLE_STATE 0x0004 |
||||
#define AR9170_LED_MODE_OFF_IN_PSM 0x0008 |
||||
|
||||
/* AR9170_LED_MODE BIT is set */ |
||||
#define AR9170_LED_MODE_FREQUENCY_S 4 |
||||
#define AR9170_LED_MODE_FREQUENCY 0x0030 |
||||
#define AR9170_LED_MODE_FREQUENCY_1HZ 0x0000 |
||||
#define AR9170_LED_MODE_FREQUENCY_0_5HZ 0x0010 |
||||
#define AR9170_LED_MODE_FREQUENCY_0_25HZ 0x0020 |
||||
#define AR9170_LED_MODE_FREQUENCY_0_125HZ 0x0030 |
||||
|
||||
/* AR9170_LED_MODE BIT is not set */ |
||||
#define AR9170_LED_MODE_CONN_STATE_S 4 |
||||
#define AR9170_LED_MODE_CONN_STATE 0x0030 |
||||
#define AR9170_LED_MODE_CONN_STATE_FORCE_OFF 0x0000 |
||||
#define AR9170_LED_MODE_CONN_STATE_FORCE_ON 0x0010 |
||||
/* Idle off / Active on */ |
||||
#define AR9170_LED_MODE_CONN_STATE_IOFF_AON 0x0020 |
||||
/* Idle on / Active off */ |
||||
#define AR9170_LED_MODE_CONN_STATE_ION_AOFF 0x0010 |
||||
|
||||
#define AR9170_LED_MODE_MODE 0x0040 |
||||
#define AR9170_LED_MODE_RESERVED2 0x0080 |
||||
|
||||
#define AR9170_LED_MODE_TON_SCAN_S 8 |
||||
#define AR9170_LED_MODE_TON_SCAN 0x0f00 |
||||
|
||||
#define AR9170_LED_MODE_TOFF_SCAN_S 12 |
||||
#define AR9170_LED_MODE_TOFF_SCAN 0xf000 |
||||
|
||||
struct ar9170_led_mode { |
||||
__le16 led; |
||||
}; |
||||
|
||||
#endif /* __CARL9170_SHARED_EEPROM_H */ |
@ -0,0 +1,318 @@
@@ -0,0 +1,318 @@
|
||||
/* |
||||
* Shared Atheros AR9170 Header |
||||
* |
||||
* Firmware command interface definitions |
||||
* |
||||
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
* |
||||
* 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; see the file COPYING. If not, see |
||||
* http://www.gnu.org/licenses/. |
||||
* |
||||
* This file incorporates work covered by the following copyright and |
||||
* permission notice: |
||||
* Copyright (c) 2007-2008 Atheros Communications, Inc. |
||||
* |
||||
* Permission to use, copy, modify, and/or distribute this software for any |
||||
* purpose with or without fee is hereby granted, provided that the above |
||||
* copyright notice and this permission notice appear in all copies. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170_SHARED_FWCMD_H |
||||
#define __CARL9170_SHARED_FWCMD_H |
||||
|
||||
#define CARL9170_MAX_CMD_LEN 64 |
||||
#define CARL9170_MAX_CMD_PAYLOAD_LEN 60 |
||||
|
||||
#define CARL9170FW_API_MIN_VER 1 |
||||
#define CARL9170FW_API_MAX_VER 1 |
||||
|
||||
enum carl9170_cmd_oids { |
||||
CARL9170_CMD_RREG = 0x00, |
||||
CARL9170_CMD_WREG = 0x01, |
||||
CARL9170_CMD_ECHO = 0x02, |
||||
CARL9170_CMD_SWRST = 0x03, |
||||
CARL9170_CMD_REBOOT = 0x04, |
||||
CARL9170_CMD_BCN_CTRL = 0x05, |
||||
CARL9170_CMD_READ_TSF = 0x06, |
||||
CARL9170_CMD_RX_FILTER = 0x07, |
||||
CARL9170_CMD_WOL = 0x08, |
||||
CARL9170_CMD_TALLY = 0x09, |
||||
|
||||
/* CAM */ |
||||
CARL9170_CMD_EKEY = 0x10, |
||||
CARL9170_CMD_DKEY = 0x11, |
||||
|
||||
/* RF / PHY */ |
||||
CARL9170_CMD_FREQUENCY = 0x20, |
||||
CARL9170_CMD_RF_INIT = 0x21, |
||||
CARL9170_CMD_SYNTH = 0x22, |
||||
CARL9170_CMD_FREQ_START = 0x23, |
||||
CARL9170_CMD_PSM = 0x24, |
||||
|
||||
/* Asychronous command flag */ |
||||
CARL9170_CMD_ASYNC_FLAG = 0x40, |
||||
CARL9170_CMD_WREG_ASYNC = (CARL9170_CMD_WREG | |
||||
CARL9170_CMD_ASYNC_FLAG), |
||||
CARL9170_CMD_REBOOT_ASYNC = (CARL9170_CMD_REBOOT | |
||||
CARL9170_CMD_ASYNC_FLAG), |
||||
CARL9170_CMD_BCN_CTRL_ASYNC = (CARL9170_CMD_BCN_CTRL | |
||||
CARL9170_CMD_ASYNC_FLAG), |
||||
CARL9170_CMD_PSM_ASYNC = (CARL9170_CMD_PSM | |
||||
CARL9170_CMD_ASYNC_FLAG), |
||||
|
||||
/* responses and traps */ |
||||
CARL9170_RSP_FLAG = 0xc0, |
||||
CARL9170_RSP_PRETBTT = 0xc0, |
||||
CARL9170_RSP_TXCOMP = 0xc1, |
||||
CARL9170_RSP_BEACON_CONFIG = 0xc2, |
||||
CARL9170_RSP_ATIM = 0xc3, |
||||
CARL9170_RSP_WATCHDOG = 0xc6, |
||||
CARL9170_RSP_TEXT = 0xca, |
||||
CARL9170_RSP_HEXDUMP = 0xcc, |
||||
CARL9170_RSP_RADAR = 0xcd, |
||||
CARL9170_RSP_GPIO = 0xce, |
||||
CARL9170_RSP_BOOT = 0xcf, |
||||
}; |
||||
|
||||
struct carl9170_set_key_cmd { |
||||
__le16 user; |
||||
__le16 keyId; |
||||
__le16 type; |
||||
u8 macAddr[6]; |
||||
u32 key[4]; |
||||
} __packed __aligned(4); |
||||
#define CARL9170_SET_KEY_CMD_SIZE 28 |
||||
|
||||
struct carl9170_disable_key_cmd { |
||||
__le16 user; |
||||
__le16 padding; |
||||
} __packed __aligned(4); |
||||
#define CARL9170_DISABLE_KEY_CMD_SIZE 4 |
||||
|
||||
struct carl9170_u32_list { |
||||
u32 vals[0]; |
||||
} __packed; |
||||
|
||||
struct carl9170_reg_list { |
||||
__le32 regs[0]; |
||||
} __packed; |
||||
|
||||
struct carl9170_write_reg { |
||||
struct { |
||||
__le32 addr; |
||||
__le32 val; |
||||
} regs[0] __packed; |
||||
} __packed; |
||||
|
||||
#define CARL9170FW_PHY_HT_ENABLE 0x4 |
||||
#define CARL9170FW_PHY_HT_DYN2040 0x8 |
||||
#define CARL9170FW_PHY_HT_EXT_CHAN_OFF 0x3 |
||||
#define CARL9170FW_PHY_HT_EXT_CHAN_OFF_S 2 |
||||
|
||||
struct carl9170_rf_init { |
||||
__le32 freq; |
||||
u8 ht_settings; |
||||
u8 padding2[3]; |
||||
__le32 delta_slope_coeff_exp; |
||||
__le32 delta_slope_coeff_man; |
||||
__le32 delta_slope_coeff_exp_shgi; |
||||
__le32 delta_slope_coeff_man_shgi; |
||||
__le32 finiteLoopCount; |
||||
} __packed; |
||||
#define CARL9170_RF_INIT_SIZE 28 |
||||
|
||||
struct carl9170_rf_init_result { |
||||
__le32 ret; /* AR9170_PHY_REG_AGC_CONTROL */ |
||||
} __packed; |
||||
#define CARL9170_RF_INIT_RESULT_SIZE 4 |
||||
|
||||
#define CARL9170_PSM_SLEEP 0x1000 |
||||
#define CARL9170_PSM_SOFTWARE 0 |
||||
#define CARL9170_PSM_WAKE 0 /* internally used. */ |
||||
#define CARL9170_PSM_COUNTER 0xfff |
||||
#define CARL9170_PSM_COUNTER_S 0 |
||||
|
||||
struct carl9170_psm { |
||||
__le32 state; |
||||
} __packed; |
||||
#define CARL9170_PSM_SIZE 4 |
||||
|
||||
struct carl9170_rx_filter_cmd { |
||||
__le32 rx_filter; |
||||
} __packed; |
||||
#define CARL9170_RX_FILTER_CMD_SIZE 4 |
||||
|
||||
#define CARL9170_RX_FILTER_BAD 0x01 |
||||
#define CARL9170_RX_FILTER_OTHER_RA 0x02 |
||||
#define CARL9170_RX_FILTER_DECRY_FAIL 0x04 |
||||
#define CARL9170_RX_FILTER_CTL_OTHER 0x08 |
||||
#define CARL9170_RX_FILTER_CTL_PSPOLL 0x10 |
||||
#define CARL9170_RX_FILTER_CTL_BACKR 0x20 |
||||
#define CARL9170_RX_FILTER_MGMT 0x40 |
||||
#define CARL9170_RX_FILTER_DATA 0x80 |
||||
#define CARL9170_RX_FILTER_EVERYTHING (~0) |
||||
|
||||
struct carl9170_bcn_ctrl_cmd { |
||||
__le32 vif_id; |
||||
__le32 mode; |
||||
__le32 bcn_addr; |
||||
__le32 bcn_len; |
||||
} __packed; |
||||
#define CARL9170_BCN_CTRL_CMD_SIZE 16 |
||||
|
||||
#define CARL9170_BCN_CTRL_DRAIN 0 |
||||
#define CARL9170_BCN_CTRL_CAB_TRIGGER 1 |
||||
|
||||
struct carl9170_wol_cmd { |
||||
__le32 flags; |
||||
u8 mac[6]; |
||||
u8 bssid[6]; |
||||
__le32 null_interval; |
||||
__le32 free_for_use2; |
||||
__le32 mask; |
||||
u8 pattern[32]; |
||||
} __packed; |
||||
|
||||
#define CARL9170_WOL_CMD_SIZE 60 |
||||
|
||||
#define CARL9170_WOL_DISCONNECT 1 |
||||
#define CARL9170_WOL_MAGIC_PKT 2 |
||||
|
||||
struct carl9170_cmd_head { |
||||
union { |
||||
struct { |
||||
u8 len; |
||||
u8 cmd; |
||||
u8 seq; |
||||
u8 ext; |
||||
} __packed; |
||||
|
||||
u32 hdr_data; |
||||
} __packed; |
||||
} __packed; |
||||
|
||||
struct carl9170_cmd { |
||||
struct carl9170_cmd_head hdr; |
||||
union { |
||||
struct carl9170_set_key_cmd setkey; |
||||
struct carl9170_disable_key_cmd disablekey; |
||||
struct carl9170_u32_list echo; |
||||
struct carl9170_reg_list rreg; |
||||
struct carl9170_write_reg wreg; |
||||
struct carl9170_rf_init rf_init; |
||||
struct carl9170_psm psm; |
||||
struct carl9170_wol_cmd wol; |
||||
struct carl9170_bcn_ctrl_cmd bcn_ctrl; |
||||
struct carl9170_rx_filter_cmd rx_filter; |
||||
u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; |
||||
} __packed; |
||||
} __packed __aligned(4); |
||||
|
||||
#define CARL9170_TX_STATUS_QUEUE 3 |
||||
#define CARL9170_TX_STATUS_QUEUE_S 0 |
||||
#define CARL9170_TX_STATUS_RIX_S 2 |
||||
#define CARL9170_TX_STATUS_RIX (3 << CARL9170_TX_STATUS_RIX_S) |
||||
#define CARL9170_TX_STATUS_TRIES_S 4 |
||||
#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S) |
||||
#define CARL9170_TX_STATUS_SUCCESS 0x80 |
||||
|
||||
#ifdef __CARL9170FW__ |
||||
/* |
||||
* NOTE: |
||||
* Both structs [carl9170_tx_status and _carl9170_tx_status] |
||||
* need to be "bit for bit" in sync. |
||||
*/ |
||||
struct carl9170_tx_status { |
||||
/* |
||||
* Beware of compiler bugs in all gcc pre 4.4! |
||||
*/ |
||||
|
||||
u8 cookie; |
||||
u8 queue:2; |
||||
u8 rix:2; |
||||
u8 tries:3; |
||||
u8 success:1; |
||||
} __packed; |
||||
#endif /* __CARL9170FW__ */ |
||||
|
||||
struct _carl9170_tx_status { |
||||
/* |
||||
* This version should be immune to all alignment bugs. |
||||
*/ |
||||
|
||||
u8 cookie; |
||||
u8 info; |
||||
} __packed; |
||||
#define CARL9170_TX_STATUS_SIZE 2 |
||||
|
||||
#define CARL9170_RSP_TX_STATUS_NUM (CARL9170_MAX_CMD_PAYLOAD_LEN / \ |
||||
sizeof(struct _carl9170_tx_status)) |
||||
|
||||
#define CARL9170_TX_MAX_RATE_TRIES 7 |
||||
|
||||
#define CARL9170_TX_MAX_RATES 4 |
||||
#define CARL9170_TX_MAX_RETRY_RATES (CARL9170_TX_MAX_RATES - 1) |
||||
#define CARL9170_ERR_MAGIC "ERR:" |
||||
#define CARL9170_BUG_MAGIC "BUG:" |
||||
|
||||
struct carl9170_gpio { |
||||
__le32 gpio; |
||||
} __packed; |
||||
#define CARL9170_GPIO_SIZE 4 |
||||
|
||||
struct carl9170_tsf_rsp { |
||||
union { |
||||
__le32 tsf[2]; |
||||
__le64 tsf_64; |
||||
} __packed; |
||||
} __packed; |
||||
#define CARL9170_TSF_RSP_SIZE 8 |
||||
|
||||
struct carl9170_tally_rsp { |
||||
__le32 active; |
||||
__le32 cca; |
||||
__le32 tx_time; |
||||
__le32 rx_total; |
||||
__le32 rx_overrun; |
||||
__le32 tick; |
||||
} __packed; |
||||
|
||||
struct carl9170_rsp { |
||||
struct carl9170_cmd_head hdr; |
||||
|
||||
union { |
||||
struct carl9170_rf_init_result rf_init_res; |
||||
struct carl9170_u32_list rreg_res; |
||||
struct carl9170_u32_list echo; |
||||
#ifdef __CARL9170FW__ |
||||
struct carl9170_tx_status tx_status[0]; |
||||
#endif /* __CARL9170FW__ */ |
||||
struct _carl9170_tx_status _tx_status[0]; |
||||
struct carl9170_gpio gpio; |
||||
struct carl9170_tsf_rsp tsf; |
||||
struct carl9170_psm psm; |
||||
struct carl9170_tally_rsp tally; |
||||
u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; |
||||
} __packed; |
||||
} __packed __aligned(4); |
||||
|
||||
#endif /* __CARL9170_SHARED_FWCMD_H */ |
@ -0,0 +1,277 @@
@@ -0,0 +1,277 @@
|
||||
/* |
||||
* Shared CARL9170 Header |
||||
* |
||||
* Firmware descriptor format |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
* |
||||
* 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; see the file COPYING. If not, see |
||||
* http://www.gnu.org/licenses/. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170_SHARED_FWDESC_H |
||||
#define __CARL9170_SHARED_FWDESC_H |
||||
|
||||
/* NOTE: Don't mess with the order of the flags! */ |
||||
enum carl9170fw_feature_list { |
||||
/* Always set */ |
||||
CARL9170FW_DUMMY_FEATURE, |
||||
|
||||
/* |
||||
* Indicates that this image has special boot block which prevents |
||||
* legacy drivers to drive the firmware. |
||||
*/ |
||||
CARL9170FW_MINIBOOT, |
||||
|
||||
/* usb registers are initialized by the firmware */ |
||||
CARL9170FW_USB_INIT_FIRMWARE, |
||||
|
||||
/* command traps & notifications are send through EP2 */ |
||||
CARL9170FW_USB_RESP_EP2, |
||||
|
||||
/* usb download (app -> fw) stream */ |
||||
CARL9170FW_USB_DOWN_STREAM, |
||||
|
||||
/* usb upload (fw -> app) stream */ |
||||
CARL9170FW_USB_UP_STREAM, |
||||
|
||||
/* unusable - reserved to flag non-functional debug firmwares */ |
||||
CARL9170FW_UNUSABLE, |
||||
|
||||
/* AR9170_CMD_RF_INIT, AR9170_CMD_FREQ_START, AR9170_CMD_FREQUENCY */ |
||||
CARL9170FW_COMMAND_PHY, |
||||
|
||||
/* AR9170_CMD_EKEY, AR9170_CMD_DKEY */ |
||||
CARL9170FW_COMMAND_CAM, |
||||
|
||||
/* Firmware has a software Content After Beacon Queueing mechanism */ |
||||
CARL9170FW_WLANTX_CAB, |
||||
|
||||
/* The firmware is capable of responding to incoming BAR frames */ |
||||
CARL9170FW_HANDLE_BACK_REQ, |
||||
|
||||
/* GPIO Interrupt | CARL9170_RSP_GPIO */ |
||||
CARL9170FW_GPIO_INTERRUPT, |
||||
|
||||
/* Firmware PSM support | CARL9170_CMD_PSM */ |
||||
CARL9170FW_PSM, |
||||
|
||||
/* Firmware RX filter | CARL9170_CMD_RX_FILTER */ |
||||
CARL9170FW_RX_FILTER, |
||||
|
||||
/* Wake up on WLAN */ |
||||
CARL9170FW_WOL, |
||||
|
||||
/* Firmware supports PSM in the 5GHZ Band */ |
||||
CARL9170FW_FIXED_5GHZ_PSM, |
||||
|
||||
/* HW (ANI, CCA, MIB) tally counters */ |
||||
CARL9170FW_HW_COUNTERS, |
||||
|
||||
/* Firmware will pass BA when BARs are queued */ |
||||
CARL9170FW_RX_BA_FILTER, |
||||
|
||||
/* KEEP LAST */ |
||||
__CARL9170FW_FEATURE_NUM |
||||
}; |
||||
|
||||
#define OTUS_MAGIC "OTAR" |
||||
#define MOTD_MAGIC "MOTD" |
||||
#define FIX_MAGIC "FIX\0" |
||||
#define DBG_MAGIC "DBG\0" |
||||
#define CHK_MAGIC "CHK\0" |
||||
#define TXSQ_MAGIC "TXSQ" |
||||
#define WOL_MAGIC "WOL\0" |
||||
#define LAST_MAGIC "LAST" |
||||
|
||||
#define CARL9170FW_SET_DAY(d) (((d) - 1) % 31) |
||||
#define CARL9170FW_SET_MONTH(m) ((((m) - 1) % 12) * 31) |
||||
#define CARL9170FW_SET_YEAR(y) (((y) - 10) * 372) |
||||
|
||||
#define CARL9170FW_GET_DAY(d) (((d) % 31) + 1) |
||||
#define CARL9170FW_GET_MONTH(m) ((((m) / 31) % 12) + 1) |
||||
#define CARL9170FW_GET_YEAR(y) ((y) / 372 + 10) |
||||
|
||||
#define CARL9170FW_MAGIC_SIZE 4 |
||||
|
||||
struct carl9170fw_desc_head { |
||||
u8 magic[CARL9170FW_MAGIC_SIZE]; |
||||
__le16 length; |
||||
u8 min_ver; |
||||
u8 cur_ver; |
||||
} __packed; |
||||
#define CARL9170FW_DESC_HEAD_SIZE \ |
||||
(sizeof(struct carl9170fw_desc_head)) |
||||
|
||||
#define CARL9170FW_OTUS_DESC_MIN_VER 6 |
||||
#define CARL9170FW_OTUS_DESC_CUR_VER 7 |
||||
struct carl9170fw_otus_desc { |
||||
struct carl9170fw_desc_head head; |
||||
__le32 feature_set; |
||||
__le32 fw_address; |
||||
__le32 bcn_addr; |
||||
__le16 bcn_len; |
||||
__le16 miniboot_size; |
||||
__le16 tx_frag_len; |
||||
__le16 rx_max_frame_len; |
||||
u8 tx_descs; |
||||
u8 cmd_bufs; |
||||
u8 api_ver; |
||||
u8 vif_num; |
||||
} __packed; |
||||
#define CARL9170FW_OTUS_DESC_SIZE \ |
||||
(sizeof(struct carl9170fw_otus_desc)) |
||||
|
||||
#define CARL9170FW_MOTD_STRING_LEN 24 |
||||
#define CARL9170FW_MOTD_RELEASE_LEN 20 |
||||
#define CARL9170FW_MOTD_DESC_MIN_VER 1 |
||||
#define CARL9170FW_MOTD_DESC_CUR_VER 2 |
||||
struct carl9170fw_motd_desc { |
||||
struct carl9170fw_desc_head head; |
||||
__le32 fw_year_month_day; |
||||
char desc[CARL9170FW_MOTD_STRING_LEN]; |
||||
char release[CARL9170FW_MOTD_RELEASE_LEN]; |
||||
} __packed; |
||||
#define CARL9170FW_MOTD_DESC_SIZE \ |
||||
(sizeof(struct carl9170fw_motd_desc)) |
||||
|
||||
#define CARL9170FW_FIX_DESC_MIN_VER 1 |
||||
#define CARL9170FW_FIX_DESC_CUR_VER 2 |
||||
struct carl9170fw_fix_entry { |
||||
__le32 address; |
||||
__le32 mask; |
||||
__le32 value; |
||||
} __packed; |
||||
|
||||
struct carl9170fw_fix_desc { |
||||
struct carl9170fw_desc_head head; |
||||
struct carl9170fw_fix_entry data[0]; |
||||
} __packed; |
||||
#define CARL9170FW_FIX_DESC_SIZE \ |
||||
(sizeof(struct carl9170fw_fix_desc)) |
||||
|
||||
#define CARL9170FW_DBG_DESC_MIN_VER 1 |
||||
#define CARL9170FW_DBG_DESC_CUR_VER 3 |
||||
struct carl9170fw_dbg_desc { |
||||
struct carl9170fw_desc_head head; |
||||
|
||||
__le32 bogoclock_addr; |
||||
__le32 counter_addr; |
||||
__le32 rx_total_addr; |
||||
__le32 rx_overrun_addr; |
||||
__le32 rx_filter; |
||||
|
||||
/* Put your debugging definitions here */ |
||||
} __packed; |
||||
#define CARL9170FW_DBG_DESC_SIZE \ |
||||
(sizeof(struct carl9170fw_dbg_desc)) |
||||
|
||||
#define CARL9170FW_CHK_DESC_MIN_VER 1 |
||||
#define CARL9170FW_CHK_DESC_CUR_VER 2 |
||||
struct carl9170fw_chk_desc { |
||||
struct carl9170fw_desc_head head; |
||||
__le32 fw_crc32; |
||||
__le32 hdr_crc32; |
||||
} __packed; |
||||
#define CARL9170FW_CHK_DESC_SIZE \ |
||||
(sizeof(struct carl9170fw_chk_desc)) |
||||
|
||||
#define CARL9170FW_TXSQ_DESC_MIN_VER 1 |
||||
#define CARL9170FW_TXSQ_DESC_CUR_VER 1 |
||||
struct carl9170fw_txsq_desc { |
||||
struct carl9170fw_desc_head head; |
||||
|
||||
__le32 seq_table_addr; |
||||
} __packed; |
||||
#define CARL9170FW_TXSQ_DESC_SIZE \ |
||||
(sizeof(struct carl9170fw_txsq_desc)) |
||||
|
||||
#define CARL9170FW_WOL_DESC_MIN_VER 1 |
||||
#define CARL9170FW_WOL_DESC_CUR_VER 1 |
||||
struct carl9170fw_wol_desc { |
||||
struct carl9170fw_desc_head head; |
||||
|
||||
__le32 supported_triggers; /* CARL9170_WOL_ */ |
||||
} __packed; |
||||
#define CARL9170FW_WOL_DESC_SIZE \ |
||||
(sizeof(struct carl9170fw_wol_desc)) |
||||
|
||||
#define CARL9170FW_LAST_DESC_MIN_VER 1 |
||||
#define CARL9170FW_LAST_DESC_CUR_VER 2 |
||||
struct carl9170fw_last_desc { |
||||
struct carl9170fw_desc_head head; |
||||
} __packed; |
||||
#define CARL9170FW_LAST_DESC_SIZE \ |
||||
(sizeof(struct carl9170fw_fix_desc)) |
||||
|
||||
#define CARL9170FW_DESC_MAX_LENGTH 8192 |
||||
|
||||
#define CARL9170FW_FILL_DESC(_magic, _length, _min_ver, _cur_ver) \ |
||||
.head = { \ |
||||
.magic = _magic, \ |
||||
.length = cpu_to_le16(_length), \ |
||||
.min_ver = _min_ver, \ |
||||
.cur_ver = _cur_ver, \ |
||||
} |
||||
|
||||
static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head, |
||||
u8 magic[CARL9170FW_MAGIC_SIZE], |
||||
__le16 length, u8 min_ver, u8 cur_ver) |
||||
{ |
||||
head->magic[0] = magic[0]; |
||||
head->magic[1] = magic[1]; |
||||
head->magic[2] = magic[2]; |
||||
head->magic[3] = magic[3]; |
||||
|
||||
head->length = length; |
||||
head->min_ver = min_ver; |
||||
head->cur_ver = cur_ver; |
||||
} |
||||
|
||||
#define carl9170fw_for_each_hdr(desc, fw_desc) \ |
||||
for (desc = fw_desc; \ |
||||
memcmp(desc->magic, LAST_MAGIC, CARL9170FW_MAGIC_SIZE) && \ |
||||
le16_to_cpu(desc->length) >= CARL9170FW_DESC_HEAD_SIZE && \ |
||||
le16_to_cpu(desc->length) < CARL9170FW_DESC_MAX_LENGTH; \ |
||||
desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length))) |
||||
|
||||
#define CHECK_HDR_VERSION(head, _min_ver) \ |
||||
(((head)->cur_ver < _min_ver) || ((head)->min_ver > _min_ver)) \ |
||||
|
||||
static inline bool carl9170fw_supports(__le32 list, u8 feature) |
||||
{ |
||||
return le32_to_cpu(list) & BIT(feature); |
||||
} |
||||
|
||||
static inline bool carl9170fw_desc_cmp(const struct carl9170fw_desc_head *head, |
||||
const u8 descid[CARL9170FW_MAGIC_SIZE], |
||||
u16 min_len, u8 compatible_revision) |
||||
{ |
||||
if (descid[0] == head->magic[0] && descid[1] == head->magic[1] && |
||||
descid[2] == head->magic[2] && descid[3] == head->magic[3] && |
||||
!CHECK_HDR_VERSION(head, compatible_revision) && |
||||
(le16_to_cpu(head->length) >= min_len)) |
||||
return true; |
||||
|
||||
return false; |
||||
} |
||||
|
||||
#define CARL9170FW_MIN_SIZE 32 |
||||
#define CARL9170FW_MAX_SIZE 16384 |
||||
|
||||
static inline bool carl9170fw_size_check(unsigned int len) |
||||
{ |
||||
return (len <= CARL9170FW_MAX_SIZE && len >= CARL9170FW_MIN_SIZE); |
||||
} |
||||
|
||||
#endif /* __CARL9170_SHARED_FWDESC_H */ |
@ -0,0 +1,817 @@
@@ -0,0 +1,817 @@
|
||||
/* |
||||
* Shared Atheros AR9170 Header |
||||
* |
||||
* Register map, hardware-specific definitions |
||||
* |
||||
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
* |
||||
* 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; see the file COPYING. If not, see |
||||
* http://www.gnu.org/licenses/. |
||||
* |
||||
* This file incorporates work covered by the following copyright and |
||||
* permission notice: |
||||
* Copyright (c) 2007-2008 Atheros Communications, Inc. |
||||
* |
||||
* Permission to use, copy, modify, and/or distribute this software for any |
||||
* purpose with or without fee is hereby granted, provided that the above |
||||
* copyright notice and this permission notice appear in all copies. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170_SHARED_HW_H |
||||
#define __CARL9170_SHARED_HW_H |
||||
|
||||
/* High Speed UART */ |
||||
#define AR9170_UART_REG_BASE 0x1c0000 |
||||
|
||||
/* Definitions of interrupt registers */ |
||||
#define AR9170_UART_REG_RX_BUFFER (AR9170_UART_REG_BASE + 0x000) |
||||
#define AR9170_UART_REG_TX_HOLDING (AR9170_UART_REG_BASE + 0x004) |
||||
#define AR9170_UART_REG_FIFO_CONTROL (AR9170_UART_REG_BASE + 0x010) |
||||
#define AR9170_UART_FIFO_CTRL_RESET_RX_FIFO 0x02 |
||||
#define AR9170_UART_FIFO_CTRL_RESET_TX_FIFO 0x04 |
||||
|
||||
#define AR9170_UART_REG_LINE_CONTROL (AR9170_UART_REG_BASE + 0x014) |
||||
#define AR9170_UART_REG_MODEM_CONTROL (AR9170_UART_REG_BASE + 0x018) |
||||
#define AR9170_UART_MODEM_CTRL_DTR_BIT 0x01 |
||||
#define AR9170_UART_MODEM_CTRL_RTS_BIT 0x02 |
||||
#define AR9170_UART_MODEM_CTRL_INTERNAL_LOOP_BACK 0x10 |
||||
#define AR9170_UART_MODEM_CTRL_AUTO_RTS 0x20 |
||||
#define AR9170_UART_MODEM_CTRL_AUTO_CTR 0x40 |
||||
|
||||
#define AR9170_UART_REG_LINE_STATUS (AR9170_UART_REG_BASE + 0x01c) |
||||
#define AR9170_UART_LINE_STS_RX_DATA_READY 0x01 |
||||
#define AR9170_UART_LINE_STS_RX_BUFFER_OVERRUN 0x02 |
||||
#define AR9170_UART_LINE_STS_RX_BREAK_IND 0x10 |
||||
#define AR9170_UART_LINE_STS_TX_FIFO_NEAR_EMPTY 0x20 |
||||
#define AR9170_UART_LINE_STS_TRANSMITTER_EMPTY 0x40 |
||||
|
||||
#define AR9170_UART_REG_MODEM_STATUS (AR9170_UART_REG_BASE + 0x020) |
||||
#define AR9170_UART_MODEM_STS_CTS_CHANGE 0x01 |
||||
#define AR9170_UART_MODEM_STS_DSR_CHANGE 0x02 |
||||
#define AR9170_UART_MODEM_STS_DCD_CHANGE 0x08 |
||||
#define AR9170_UART_MODEM_STS_CTS_COMPL 0x10 |
||||
#define AR9170_UART_MODEM_STS_DSR_COMPL 0x20 |
||||
#define AR9170_UART_MODEM_STS_DCD_COMPL 0x80 |
||||
|
||||
#define AR9170_UART_REG_SCRATCH (AR9170_UART_REG_BASE + 0x024) |
||||
#define AR9170_UART_REG_DIVISOR_LSB (AR9170_UART_REG_BASE + 0x028) |
||||
#define AR9170_UART_REG_DIVISOR_MSB (AR9170_UART_REG_BASE + 0x02c) |
||||
#define AR9170_UART_REG_WORD_RX_BUFFER (AR9170_UART_REG_BASE + 0x034) |
||||
#define AR9170_UART_REG_WORD_TX_HOLDING (AR9170_UART_REG_BASE + 0x038) |
||||
#define AR9170_UART_REG_FIFO_COUNT (AR9170_UART_REG_BASE + 0x03c) |
||||
#define AR9170_UART_REG_REMAINDER (AR9170_UART_REG_BASE + 0x04c) |
||||
|
||||
/* Timer */ |
||||
#define AR9170_TIMER_REG_BASE 0x1c1000 |
||||
|
||||
#define AR9170_TIMER_REG_WATCH_DOG (AR9170_TIMER_REG_BASE + 0x000) |
||||
#define AR9170_TIMER_REG_TIMER0 (AR9170_TIMER_REG_BASE + 0x010) |
||||
#define AR9170_TIMER_REG_TIMER1 (AR9170_TIMER_REG_BASE + 0x014) |
||||
#define AR9170_TIMER_REG_TIMER2 (AR9170_TIMER_REG_BASE + 0x018) |
||||
#define AR9170_TIMER_REG_TIMER3 (AR9170_TIMER_REG_BASE + 0x01c) |
||||
#define AR9170_TIMER_REG_TIMER4 (AR9170_TIMER_REG_BASE + 0x020) |
||||
#define AR9170_TIMER_REG_CONTROL (AR9170_TIMER_REG_BASE + 0x024) |
||||
#define AR9170_TIMER_CTRL_DISABLE_CLOCK 0x100 |
||||
|
||||
#define AR9170_TIMER_REG_INTERRUPT (AR9170_TIMER_REG_BASE + 0x028) |
||||
#define AR9170_TIMER_INT_TIMER0 0x001 |
||||
#define AR9170_TIMER_INT_TIMER1 0x002 |
||||
#define AR9170_TIMER_INT_TIMER2 0x004 |
||||
#define AR9170_TIMER_INT_TIMER3 0x008 |
||||
#define AR9170_TIMER_INT_TIMER4 0x010 |
||||
#define AR9170_TIMER_INT_TICK_TIMER 0x100 |
||||
|
||||
#define AR9170_TIMER_REG_TICK_TIMER (AR9170_TIMER_REG_BASE + 0x030) |
||||
#define AR9170_TIMER_REG_CLOCK_LOW (AR9170_TIMER_REG_BASE + 0x040) |
||||
#define AR9170_TIMER_REG_CLOCK_HIGH (AR9170_TIMER_REG_BASE + 0x044) |
||||
|
||||
#define AR9170_MAC_REG_BASE 0x1c3000 |
||||
|
||||
#define AR9170_MAC_REG_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x500) |
||||
#define AR9170_MAC_POWER_STATE_CTRL_RESET 0x20 |
||||
|
||||
#define AR9170_MAC_REG_MAC_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x50c) |
||||
|
||||
#define AR9170_MAC_REG_INT_CTRL (AR9170_MAC_REG_BASE + 0x510) |
||||
#define AR9170_MAC_INT_TXC BIT(0) |
||||
#define AR9170_MAC_INT_RXC BIT(1) |
||||
#define AR9170_MAC_INT_RETRY_FAIL BIT(2) |
||||
#define AR9170_MAC_INT_WAKEUP BIT(3) |
||||
#define AR9170_MAC_INT_ATIM BIT(4) |
||||
#define AR9170_MAC_INT_DTIM BIT(5) |
||||
#define AR9170_MAC_INT_CFG_BCN BIT(6) |
||||
#define AR9170_MAC_INT_ABORT BIT(7) |
||||
#define AR9170_MAC_INT_QOS BIT(8) |
||||
#define AR9170_MAC_INT_MIMO_PS BIT(9) |
||||
#define AR9170_MAC_INT_KEY_GEN BIT(10) |
||||
#define AR9170_MAC_INT_DECRY_NOUSER BIT(11) |
||||
#define AR9170_MAC_INT_RADAR BIT(12) |
||||
#define AR9170_MAC_INT_QUIET_FRAME BIT(13) |
||||
#define AR9170_MAC_INT_PRETBTT BIT(14) |
||||
|
||||
#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514) |
||||
#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518) |
||||
|
||||
#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51c) |
||||
#define AR9170_MAC_ATIM_PERIOD_S 0 |
||||
#define AR9170_MAC_ATIM_PERIOD 0x0000ffff |
||||
|
||||
#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520) |
||||
#define AR9170_MAC_BCN_PERIOD_S 0 |
||||
#define AR9170_MAC_BCN_PERIOD 0x0000ffff |
||||
#define AR9170_MAC_BCN_DTIM_S 16 |
||||
#define AR9170_MAC_BCN_DTIM 0x00ff0000 |
||||
#define AR9170_MAC_BCN_AP_MODE BIT(24) |
||||
#define AR9170_MAC_BCN_IBSS_MODE BIT(25) |
||||
#define AR9170_MAC_BCN_PWR_MGT BIT(26) |
||||
#define AR9170_MAC_BCN_STA_PS BIT(27) |
||||
|
||||
#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524) |
||||
#define AR9170_MAC_PRETBTT_S 0 |
||||
#define AR9170_MAC_PRETBTT 0x0000ffff |
||||
#define AR9170_MAC_PRETBTT2_S 16 |
||||
#define AR9170_MAC_PRETBTT2 0xffff0000 |
||||
|
||||
#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610) |
||||
#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614) |
||||
#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618) |
||||
#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c) |
||||
|
||||
#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624) |
||||
#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628) |
||||
|
||||
#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62c) |
||||
|
||||
#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630) |
||||
#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634) |
||||
#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638) |
||||
#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c) |
||||
#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640) |
||||
#define AR9170_MAC_REG_AFTER_PNP (AR9170_MAC_REG_BASE + 0x648) |
||||
#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64c) |
||||
|
||||
#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658) |
||||
#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674) |
||||
#define AR9170_MAC_SNIFFER_ENABLE_PROMISC BIT(0) |
||||
#define AR9170_MAC_SNIFFER_DEFAULTS 0x02000000 |
||||
#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678) |
||||
#define AR9170_MAC_ENCRYPTION_MGMT_RX_SOFTWARE BIT(2) |
||||
#define AR9170_MAC_ENCRYPTION_RX_SOFTWARE BIT(3) |
||||
#define AR9170_MAC_ENCRYPTION_DEFAULTS 0x70 |
||||
|
||||
#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680) |
||||
#define AR9170_MAC_REG_MISC_684 (AR9170_MAC_REG_BASE + 0x684) |
||||
#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688) |
||||
|
||||
#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c) |
||||
#define AR9170_MAC_FTF_ASSOC_REQ BIT(0) |
||||
#define AR9170_MAC_FTF_ASSOC_RESP BIT(1) |
||||
#define AR9170_MAC_FTF_REASSOC_REQ BIT(2) |
||||
#define AR9170_MAC_FTF_REASSOC_RESP BIT(3) |
||||
#define AR9170_MAC_FTF_PRB_REQ BIT(4) |
||||
#define AR9170_MAC_FTF_PRB_RESP BIT(5) |
||||
#define AR9170_MAC_FTF_BIT6 BIT(6) |
||||
#define AR9170_MAC_FTF_BIT7 BIT(7) |
||||
#define AR9170_MAC_FTF_BEACON BIT(8) |
||||
#define AR9170_MAC_FTF_ATIM BIT(9) |
||||
#define AR9170_MAC_FTF_DEASSOC BIT(10) |
||||
#define AR9170_MAC_FTF_AUTH BIT(11) |
||||
#define AR9170_MAC_FTF_DEAUTH BIT(12) |
||||
#define AR9170_MAC_FTF_BIT13 BIT(13) |
||||
#define AR9170_MAC_FTF_BIT14 BIT(14) |
||||
#define AR9170_MAC_FTF_BIT15 BIT(15) |
||||
#define AR9170_MAC_FTF_BAR BIT(24) |
||||
#define AR9170_MAC_FTF_BA BIT(25) |
||||
#define AR9170_MAC_FTF_PSPOLL BIT(26) |
||||
#define AR9170_MAC_FTF_RTS BIT(27) |
||||
#define AR9170_MAC_FTF_CTS BIT(28) |
||||
#define AR9170_MAC_FTF_ACK BIT(29) |
||||
#define AR9170_MAC_FTF_CFE BIT(30) |
||||
#define AR9170_MAC_FTF_CFE_ACK BIT(31) |
||||
#define AR9170_MAC_FTF_DEFAULTS 0x0500ffff |
||||
#define AR9170_MAC_FTF_MONITOR 0xff00ffff |
||||
|
||||
#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690) |
||||
#define AR9170_MAC_REG_ACK_TPC (AR9170_MAC_REG_BASE + 0x694) |
||||
#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698) |
||||
#define AR9170_MAC_REG_RX_TIMEOUT_COUNT (AR9170_MAC_REG_BASE + 0x69c) |
||||
#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6a0) |
||||
#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6a4) |
||||
#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6a8) |
||||
#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6ac) |
||||
#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6b0) |
||||
#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6bc) |
||||
#define AR9170_MAC_REG_TX_BLOCKACKS (AR9170_MAC_REG_BASE + 0x6c0) |
||||
#define AR9170_MAC_REG_NAV_COUNT (AR9170_MAC_REG_BASE + 0x6c4) |
||||
#define AR9170_MAC_REG_BACKOFF_STATUS (AR9170_MAC_REG_BASE + 0x6c8) |
||||
#define AR9170_MAC_BACKOFF_CCA BIT(24) |
||||
#define AR9170_MAC_BACKOFF_TX_PEX BIT(25) |
||||
#define AR9170_MAC_BACKOFF_RX_PE BIT(26) |
||||
#define AR9170_MAC_BACKOFF_MD_READY BIT(27) |
||||
#define AR9170_MAC_BACKOFF_TX_PE BIT(28) |
||||
|
||||
#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6cc) |
||||
|
||||
#define AR9170_MAC_REG_TX_COMPLETE (AR9170_MAC_REG_BASE + 0x6d4) |
||||
|
||||
#define AR9170_MAC_REG_CHANNEL_BUSY (AR9170_MAC_REG_BASE + 0x6e8) |
||||
#define AR9170_MAC_REG_EXT_BUSY (AR9170_MAC_REG_BASE + 0x6ec) |
||||
|
||||
#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6f0) |
||||
#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6f4) |
||||
#define AR9170_MAC_REG_ACK_FC (AR9170_MAC_REG_BASE + 0x6f8) |
||||
|
||||
#define AR9170_MAC_REG_CAM_MODE (AR9170_MAC_REG_BASE + 0x700) |
||||
#define AR9170_MAC_CAM_IBSS 0xe0 |
||||
#define AR9170_MAC_CAM_AP 0xa1 |
||||
#define AR9170_MAC_CAM_STA 0x2 |
||||
#define AR9170_MAC_CAM_AP_WDS 0x3 |
||||
#define AR9170_MAC_CAM_DEFAULTS (0xf << 24) |
||||
#define AR9170_MAC_CAM_HOST_PENDING 0x80000000 |
||||
|
||||
#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704) |
||||
#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708) |
||||
|
||||
#define AR9170_MAC_REG_CAM_ADDR (AR9170_MAC_REG_BASE + 0x70c) |
||||
#define AR9170_MAC_CAM_ADDR_WRITE 0x80000000 |
||||
#define AR9170_MAC_REG_CAM_DATA0 (AR9170_MAC_REG_BASE + 0x720) |
||||
#define AR9170_MAC_REG_CAM_DATA1 (AR9170_MAC_REG_BASE + 0x724) |
||||
#define AR9170_MAC_REG_CAM_DATA2 (AR9170_MAC_REG_BASE + 0x728) |
||||
#define AR9170_MAC_REG_CAM_DATA3 (AR9170_MAC_REG_BASE + 0x72c) |
||||
|
||||
#define AR9170_MAC_REG_CAM_DBG0 (AR9170_MAC_REG_BASE + 0x730) |
||||
#define AR9170_MAC_REG_CAM_DBG1 (AR9170_MAC_REG_BASE + 0x734) |
||||
#define AR9170_MAC_REG_CAM_DBG2 (AR9170_MAC_REG_BASE + 0x738) |
||||
#define AR9170_MAC_REG_CAM_STATE (AR9170_MAC_REG_BASE + 0x73c) |
||||
#define AR9170_MAC_CAM_STATE_READ_PENDING 0x40000000 |
||||
#define AR9170_MAC_CAM_STATE_WRITE_PENDING 0x80000000 |
||||
|
||||
#define AR9170_MAC_REG_CAM_TXKEY (AR9170_MAC_REG_BASE + 0x740) |
||||
#define AR9170_MAC_REG_CAM_RXKEY (AR9170_MAC_REG_BASE + 0x750) |
||||
|
||||
#define AR9170_MAC_REG_CAM_TX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x760) |
||||
#define AR9170_MAC_REG_CAM_RX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x770) |
||||
#define AR9170_MAC_REG_CAM_TX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x780) |
||||
#define AR9170_MAC_REG_CAM_RX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x790) |
||||
|
||||
#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xb00) |
||||
#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xb04) |
||||
#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xb08) |
||||
#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xb0c) |
||||
#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xb10) |
||||
#define AR9170_MAC_REG_AC2_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xb14) |
||||
#define AR9170_MAC_REG_AC4_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xb18) |
||||
#define AR9170_MAC_REG_TXOP_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0xb1c) |
||||
#define AR9170_MAC_REG_TXOP_ACK_INTERVAL (AR9170_MAC_REG_BASE + 0xb20) |
||||
#define AR9170_MAC_REG_CONTENTION_POINT (AR9170_MAC_REG_BASE + 0xb24) |
||||
#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xb28) |
||||
#define AR9170_MAC_REG_TID_CFACK_CFEND_RATE (AR9170_MAC_REG_BASE + 0xb2c) |
||||
#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xb30) |
||||
#define AR9170_MAC_REG_TKIP_TSC (AR9170_MAC_REG_BASE + 0xb34) |
||||
#define AR9170_MAC_REG_TXOP_DURATION (AR9170_MAC_REG_BASE + 0xb38) |
||||
#define AR9170_MAC_REG_TX_QOS_THRESHOLD (AR9170_MAC_REG_BASE + 0xb3c) |
||||
#define AR9170_MAC_REG_QOS_PRIORITY_VIRTUAL_CCA (AR9170_MAC_REG_BASE + 0xb40) |
||||
#define AR9170_MAC_VIRTUAL_CCA_Q0 BIT(15) |
||||
#define AR9170_MAC_VIRTUAL_CCA_Q1 BIT(16) |
||||
#define AR9170_MAC_VIRTUAL_CCA_Q2 BIT(17) |
||||
#define AR9170_MAC_VIRTUAL_CCA_Q3 BIT(18) |
||||
#define AR9170_MAC_VIRTUAL_CCA_Q4 BIT(19) |
||||
#define AR9170_MAC_VIRTUAL_CCA_ALL (0xf8000) |
||||
|
||||
#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xb44) |
||||
#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xb48) |
||||
|
||||
#define AR9170_MAC_REG_AMPDU_COUNT (AR9170_MAC_REG_BASE + 0xb88) |
||||
#define AR9170_MAC_REG_MPDU_COUNT (AR9170_MAC_REG_BASE + 0xb8c) |
||||
|
||||
#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xb9c) |
||||
#define AR9170_MAC_AMPDU_FACTOR 0x7f0000 |
||||
#define AR9170_MAC_AMPDU_FACTOR_S 16 |
||||
#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xba0) |
||||
#define AR9170_MAC_AMPDU_DENSITY 0x7 |
||||
#define AR9170_MAC_AMPDU_DENSITY_S 0 |
||||
|
||||
#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xbb0) |
||||
#define AR9170_MAC_FCS_SWFCS 0x1 |
||||
#define AR9170_MAC_FCS_FIFO_PROT 0x4 |
||||
|
||||
#define AR9170_MAC_REG_RTS_CTS_TPC (AR9170_MAC_REG_BASE + 0xbb4) |
||||
#define AR9170_MAC_REG_CFEND_QOSNULL_TPC (AR9170_MAC_REG_BASE + 0xbb8) |
||||
|
||||
#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xc00) |
||||
#define AR9170_MAC_REG_RX_CONTROL (AR9170_MAC_REG_BASE + 0xc40) |
||||
#define AR9170_MAC_RX_CTRL_DEAGG 0x1 |
||||
#define AR9170_MAC_RX_CTRL_SHORT_FILTER 0x2 |
||||
#define AR9170_MAC_RX_CTRL_SA_DA_SEARCH 0x20 |
||||
#define AR9170_MAC_RX_CTRL_PASS_TO_HOST BIT(28) |
||||
#define AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER BIT(30) |
||||
|
||||
#define AR9170_MAC_REG_RX_CONTROL_1 (AR9170_MAC_REG_BASE + 0xc44) |
||||
|
||||
#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xc50) |
||||
|
||||
#define AR9170_MAC_REG_RX_MPDU (AR9170_MAC_REG_BASE + 0xca0) |
||||
#define AR9170_MAC_REG_RX_DROPPED_MPDU (AR9170_MAC_REG_BASE + 0xca4) |
||||
#define AR9170_MAC_REG_RX_DEL_MPDU (AR9170_MAC_REG_BASE + 0xca8) |
||||
#define AR9170_MAC_REG_RX_PHY_MISC_ERROR (AR9170_MAC_REG_BASE + 0xcac) |
||||
#define AR9170_MAC_REG_RX_PHY_XR_ERROR (AR9170_MAC_REG_BASE + 0xcb0) |
||||
#define AR9170_MAC_REG_RX_PHY_OFDM_ERROR (AR9170_MAC_REG_BASE + 0xcb4) |
||||
#define AR9170_MAC_REG_RX_PHY_CCK_ERROR (AR9170_MAC_REG_BASE + 0xcb8) |
||||
#define AR9170_MAC_REG_RX_PHY_HT_ERROR (AR9170_MAC_REG_BASE + 0xcbc) |
||||
#define AR9170_MAC_REG_RX_PHY_TOTAL (AR9170_MAC_REG_BASE + 0xcc0) |
||||
|
||||
#define AR9170_MAC_REG_DMA_TXQ_ADDR (AR9170_MAC_REG_BASE + 0xd00) |
||||
#define AR9170_MAC_REG_DMA_TXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04) |
||||
#define AR9170_MAC_REG_DMA_TXQ0_ADDR (AR9170_MAC_REG_BASE + 0xd00) |
||||
#define AR9170_MAC_REG_DMA_TXQ0_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04) |
||||
#define AR9170_MAC_REG_DMA_TXQ1_ADDR (AR9170_MAC_REG_BASE + 0xd08) |
||||
#define AR9170_MAC_REG_DMA_TXQ1_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd0c) |
||||
#define AR9170_MAC_REG_DMA_TXQ2_ADDR (AR9170_MAC_REG_BASE + 0xd10) |
||||
#define AR9170_MAC_REG_DMA_TXQ2_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd14) |
||||
#define AR9170_MAC_REG_DMA_TXQ3_ADDR (AR9170_MAC_REG_BASE + 0xd18) |
||||
#define AR9170_MAC_REG_DMA_TXQ3_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd1c) |
||||
#define AR9170_MAC_REG_DMA_TXQ4_ADDR (AR9170_MAC_REG_BASE + 0xd20) |
||||
#define AR9170_MAC_REG_DMA_TXQ4_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd24) |
||||
#define AR9170_MAC_REG_DMA_RXQ_ADDR (AR9170_MAC_REG_BASE + 0xd28) |
||||
#define AR9170_MAC_REG_DMA_RXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd2c) |
||||
|
||||
#define AR9170_MAC_REG_DMA_TRIGGER (AR9170_MAC_REG_BASE + 0xd30) |
||||
#define AR9170_DMA_TRIGGER_TXQ0 BIT(0) |
||||
#define AR9170_DMA_TRIGGER_TXQ1 BIT(1) |
||||
#define AR9170_DMA_TRIGGER_TXQ2 BIT(2) |
||||
#define AR9170_DMA_TRIGGER_TXQ3 BIT(3) |
||||
#define AR9170_DMA_TRIGGER_TXQ4 BIT(4) |
||||
#define AR9170_DMA_TRIGGER_RXQ BIT(8) |
||||
|
||||
#define AR9170_MAC_REG_DMA_WLAN_STATUS (AR9170_MAC_REG_BASE + 0xd38) |
||||
#define AR9170_MAC_REG_DMA_STATUS (AR9170_MAC_REG_BASE + 0xd3c) |
||||
#define AR9170_MAC_REG_DMA_TXQ_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd40) |
||||
#define AR9170_MAC_REG_DMA_TXQ0_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd40) |
||||
#define AR9170_MAC_REG_DMA_TXQ1_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd44) |
||||
#define AR9170_MAC_REG_DMA_TXQ2_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd48) |
||||
#define AR9170_MAC_REG_DMA_TXQ3_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd4c) |
||||
#define AR9170_MAC_REG_DMA_TXQ4_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd50) |
||||
#define AR9170_MAC_REG_DMA_TXQ0Q1_LEN (AR9170_MAC_REG_BASE + 0xd54) |
||||
#define AR9170_MAC_REG_DMA_TXQ2Q3_LEN (AR9170_MAC_REG_BASE + 0xd58) |
||||
#define AR9170_MAC_REG_DMA_TXQ4_LEN (AR9170_MAC_REG_BASE + 0xd5c) |
||||
|
||||
#define AR9170_MAC_REG_DMA_TXQX_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd74) |
||||
#define AR9170_MAC_REG_DMA_TXQX_FAIL_ADDR (AR9170_MAC_REG_BASE + 0xd78) |
||||
#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xd7c) |
||||
#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f |
||||
#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0 |
||||
#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000 |
||||
#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000 |
||||
|
||||
#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xd84) |
||||
#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xd88) |
||||
#define AR9170_MAC_BCN_LENGTH_MAX 256 |
||||
|
||||
#define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c) |
||||
|
||||
#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xd90) |
||||
#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xd94) |
||||
#define AR9170_BCN_CTRL_READY 0x01 |
||||
#define AR9170_BCN_CTRL_LOCK 0x02 |
||||
|
||||
#define AR9170_MAC_REG_BCN_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd98) |
||||
#define AR9170_MAC_REG_BCN_COUNT (AR9170_MAC_REG_BASE + 0xd9c) |
||||
#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xda0) |
||||
#define AR9170_MAC_BCN_HT1_HT_EN BIT(0) |
||||
#define AR9170_MAC_BCN_HT1_GF_PMB BIT(1) |
||||
#define AR9170_MAC_BCN_HT1_SP_EXP BIT(2) |
||||
#define AR9170_MAC_BCN_HT1_TX_BF BIT(3) |
||||
#define AR9170_MAC_BCN_HT1_PWR_CTRL_S 4 |
||||
#define AR9170_MAC_BCN_HT1_PWR_CTRL 0x70 |
||||
#define AR9170_MAC_BCN_HT1_TX_ANT1 BIT(7) |
||||
#define AR9170_MAC_BCN_HT1_TX_ANT0 BIT(8) |
||||
#define AR9170_MAC_BCN_HT1_NUM_LFT_S 9 |
||||
#define AR9170_MAC_BCN_HT1_NUM_LFT 0x600 |
||||
#define AR9170_MAC_BCN_HT1_BWC_20M_EXT BIT(16) |
||||
#define AR9170_MAC_BCN_HT1_BWC_40M_SHARED BIT(17) |
||||
#define AR9170_MAC_BCN_HT1_BWC_40M_DUP (BIT(16) | BIT(17)) |
||||
#define AR9170_MAC_BCN_HT1_BF_MCS_S 18 |
||||
#define AR9170_MAC_BCN_HT1_BF_MCS 0x1c0000 |
||||
#define AR9170_MAC_BCN_HT1_TPC_S 21 |
||||
#define AR9170_MAC_BCN_HT1_TPC 0x7e00000 |
||||
#define AR9170_MAC_BCN_HT1_CHAIN_MASK_S 27 |
||||
#define AR9170_MAC_BCN_HT1_CHAIN_MASK 0x38000000 |
||||
|
||||
#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xda4) |
||||
#define AR9170_MAC_BCN_HT2_MCS_S 0 |
||||
#define AR9170_MAC_BCN_HT2_MCS 0x7f |
||||
#define AR9170_MAC_BCN_HT2_BW40 BIT(8) |
||||
#define AR9170_MAC_BCN_HT2_SMOOTHING BIT(9) |
||||
#define AR9170_MAC_BCN_HT2_SS BIT(10) |
||||
#define AR9170_MAC_BCN_HT2_NSS BIT(11) |
||||
#define AR9170_MAC_BCN_HT2_STBC_S 12 |
||||
#define AR9170_MAC_BCN_HT2_STBC 0x3000 |
||||
#define AR9170_MAC_BCN_HT2_ADV_COD BIT(14) |
||||
#define AR9170_MAC_BCN_HT2_SGI BIT(15) |
||||
#define AR9170_MAC_BCN_HT2_LEN_S 16 |
||||
#define AR9170_MAC_BCN_HT2_LEN 0xffff0000 |
||||
|
||||
#define AR9170_MAC_REG_DMA_TXQX_ADDR_CURR (AR9170_MAC_REG_BASE + 0xdc0) |
||||
|
||||
/* Random number generator */ |
||||
#define AR9170_RAND_REG_BASE 0x1d0000 |
||||
|
||||
#define AR9170_RAND_REG_NUM (AR9170_RAND_REG_BASE + 0x000) |
||||
#define AR9170_RAND_REG_MODE (AR9170_RAND_REG_BASE + 0x004) |
||||
#define AR9170_RAND_MODE_MANUAL 0x000 |
||||
#define AR9170_RAND_MODE_FREE 0x001 |
||||
|
||||
/* GPIO */ |
||||
#define AR9170_GPIO_REG_BASE 0x1d0100 |
||||
#define AR9170_GPIO_REG_PORT_TYPE (AR9170_GPIO_REG_BASE + 0x000) |
||||
#define AR9170_GPIO_REG_PORT_DATA (AR9170_GPIO_REG_BASE + 0x004) |
||||
#define AR9170_GPIO_PORT_LED_0 1 |
||||
#define AR9170_GPIO_PORT_LED_1 2 |
||||
/* WPS Button GPIO for TP-Link TL-WN821N */ |
||||
#define AR9170_GPIO_PORT_WPS_BUTTON_PRESSED 4 |
||||
|
||||
/* Memory Controller */ |
||||
#define AR9170_MC_REG_BASE 0x1d1000 |
||||
|
||||
#define AR9170_MC_REG_FLASH_WAIT_STATE (AR9170_MC_REG_BASE + 0x000) |
||||
#define AR9170_MC_REG_SEEPROM_WP0 (AR9170_MC_REG_BASE + 0x400) |
||||
#define AR9170_MC_REG_SEEPROM_WP1 (AR9170_MC_REG_BASE + 0x404) |
||||
#define AR9170_MC_REG_SEEPROM_WP2 (AR9170_MC_REG_BASE + 0x408) |
||||
|
||||
/* Interrupt Controller */ |
||||
#define AR9170_MAX_INT_SRC 9 |
||||
#define AR9170_INT_REG_BASE 0x1d2000 |
||||
|
||||
#define AR9170_INT_REG_FLAG (AR9170_INT_REG_BASE + 0x000) |
||||
#define AR9170_INT_REG_FIQ_MASK (AR9170_INT_REG_BASE + 0x004) |
||||
#define AR9170_INT_REG_IRQ_MASK (AR9170_INT_REG_BASE + 0x008) |
||||
/* INT_REG_FLAG, INT_REG_FIQ_MASK and INT_REG_IRQ_MASK */ |
||||
#define AR9170_INT_FLAG_WLAN 0x001 |
||||
#define AR9170_INT_FLAG_PTAB_BIT 0x002 |
||||
#define AR9170_INT_FLAG_SE_BIT 0x004 |
||||
#define AR9170_INT_FLAG_UART_BIT 0x008 |
||||
#define AR9170_INT_FLAG_TIMER_BIT 0x010 |
||||
#define AR9170_INT_FLAG_EXT_BIT 0x020 |
||||
#define AR9170_INT_FLAG_SW_BIT 0x040 |
||||
#define AR9170_INT_FLAG_USB_BIT 0x080 |
||||
#define AR9170_INT_FLAG_ETHERNET_BIT 0x100 |
||||
|
||||
#define AR9170_INT_REG_PRIORITY1 (AR9170_INT_REG_BASE + 0x00c) |
||||
#define AR9170_INT_REG_PRIORITY2 (AR9170_INT_REG_BASE + 0x010) |
||||
#define AR9170_INT_REG_PRIORITY3 (AR9170_INT_REG_BASE + 0x014) |
||||
#define AR9170_INT_REG_EXT_INT_CONTROL (AR9170_INT_REG_BASE + 0x018) |
||||
#define AR9170_INT_REG_SW_INT_CONTROL (AR9170_INT_REG_BASE + 0x01c) |
||||
#define AR9170_INT_SW_INT_ENABLE 0x1 |
||||
|
||||
#define AR9170_INT_REG_FIQ_ENCODE (AR9170_INT_REG_BASE + 0x020) |
||||
#define AR9170_INT_INT_IRQ_ENCODE (AR9170_INT_REG_BASE + 0x024) |
||||
|
||||
/* Power Management */ |
||||
#define AR9170_PWR_REG_BASE 0x1d4000 |
||||
|
||||
#define AR9170_PWR_REG_POWER_STATE (AR9170_PWR_REG_BASE + 0x000) |
||||
|
||||
#define AR9170_PWR_REG_RESET (AR9170_PWR_REG_BASE + 0x004) |
||||
#define AR9170_PWR_RESET_COMMIT_RESET_MASK BIT(0) |
||||
#define AR9170_PWR_RESET_WLAN_MASK BIT(1) |
||||
#define AR9170_PWR_RESET_DMA_MASK BIT(2) |
||||
#define AR9170_PWR_RESET_BRIDGE_MASK BIT(3) |
||||
#define AR9170_PWR_RESET_AHB_MASK BIT(9) |
||||
#define AR9170_PWR_RESET_BB_WARM_RESET BIT(10) |
||||
#define AR9170_PWR_RESET_BB_COLD_RESET BIT(11) |
||||
#define AR9170_PWR_RESET_ADDA_CLK_COLD_RESET BIT(12) |
||||
#define AR9170_PWR_RESET_PLL BIT(13) |
||||
#define AR9170_PWR_RESET_USB_PLL BIT(14) |
||||
|
||||
#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008) |
||||
#define AR9170_PWR_CLK_AHB_40MHZ 0 |
||||
#define AR9170_PWR_CLK_AHB_20_22MHZ 1 |
||||
#define AR9170_PWR_CLK_AHB_40_44MHZ 2 |
||||
#define AR9170_PWR_CLK_AHB_80_88MHZ 3 |
||||
#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70 |
||||
|
||||
#define AR9170_PWR_REG_CHIP_REVISION (AR9170_PWR_REG_BASE + 0x010) |
||||
#define AR9170_PWR_REG_PLL_ADDAC (AR9170_PWR_REG_BASE + 0x014) |
||||
#define AR9170_PWR_PLL_ADDAC_DIV_S 2 |
||||
#define AR9170_PWR_PLL_ADDAC_DIV 0xffc |
||||
#define AR9170_PWR_REG_WATCH_DOG_MAGIC (AR9170_PWR_REG_BASE + 0x020) |
||||
|
||||
/* Faraday USB Controller */ |
||||
#define AR9170_USB_REG_BASE 0x1e1000 |
||||
|
||||
#define AR9170_USB_REG_MAIN_CTRL (AR9170_USB_REG_BASE + 0x000) |
||||
#define AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP BIT(0) |
||||
#define AR9170_USB_MAIN_CTRL_ENABLE_GLOBAL_INT BIT(2) |
||||
#define AR9170_USB_MAIN_CTRL_GO_TO_SUSPEND BIT(3) |
||||
#define AR9170_USB_MAIN_CTRL_RESET BIT(4) |
||||
#define AR9170_USB_MAIN_CTRL_CHIP_ENABLE BIT(5) |
||||
#define AR9170_USB_MAIN_CTRL_HIGHSPEED BIT(6) |
||||
|
||||
#define AR9170_USB_REG_DEVICE_ADDRESS (AR9170_USB_REG_BASE + 0x001) |
||||
#define AR9170_USB_DEVICE_ADDRESS_CONFIGURE BIT(7) |
||||
|
||||
#define AR9170_USB_REG_TEST (AR9170_USB_REG_BASE + 0x002) |
||||
#define AR9170_USB_REG_PHY_TEST_SELECT (AR9170_USB_REG_BASE + 0x008) |
||||
#define AR9170_USB_REG_CX_CONFIG_STATUS (AR9170_USB_REG_BASE + 0x00b) |
||||
#define AR9170_USB_REG_EP0_DATA (AR9170_USB_REG_BASE + 0x00c) |
||||
#define AR9170_USB_REG_EP0_DATA1 (AR9170_USB_REG_BASE + 0x00c) |
||||
#define AR9170_USB_REG_EP0_DATA2 (AR9170_USB_REG_BASE + 0x00d) |
||||
|
||||
#define AR9170_USB_REG_INTR_MASK_BYTE_0 (AR9170_USB_REG_BASE + 0x011) |
||||
#define AR9170_USB_REG_INTR_MASK_BYTE_1 (AR9170_USB_REG_BASE + 0x012) |
||||
#define AR9170_USB_REG_INTR_MASK_BYTE_2 (AR9170_USB_REG_BASE + 0x013) |
||||
#define AR9170_USB_REG_INTR_MASK_BYTE_3 (AR9170_USB_REG_BASE + 0x014) |
||||
#define AR9170_USB_REG_INTR_MASK_BYTE_4 (AR9170_USB_REG_BASE + 0x015) |
||||
#define AR9170_USB_INTR_DISABLE_OUT_INT (BIT(7) | BIT(6)) |
||||
|
||||
#define AR9170_USB_REG_INTR_MASK_BYTE_5 (AR9170_USB_REG_BASE + 0x016) |
||||
#define AR9170_USB_REG_INTR_MASK_BYTE_6 (AR9170_USB_REG_BASE + 0x017) |
||||
#define AR9170_USB_INTR_DISABLE_IN_INT BIT(6) |
||||
|
||||
#define AR9170_USB_REG_INTR_MASK_BYTE_7 (AR9170_USB_REG_BASE + 0x018) |
||||
|
||||
#define AR9170_USB_REG_INTR_GROUP (AR9170_USB_REG_BASE + 0x020) |
||||
|
||||
#define AR9170_USB_REG_INTR_SOURCE_0 (AR9170_USB_REG_BASE + 0x021) |
||||
#define AR9170_USB_INTR_SRC0_SETUP BIT(0) |
||||
#define AR9170_USB_INTR_SRC0_IN BIT(1) |
||||
#define AR9170_USB_INTR_SRC0_OUT BIT(2) |
||||
#define AR9170_USB_INTR_SRC0_FAIL BIT(3) /* ??? */ |
||||
#define AR9170_USB_INTR_SRC0_END BIT(4) /* ??? */ |
||||
#define AR9170_USB_INTR_SRC0_ABORT BIT(7) |
||||
|
||||
#define AR9170_USB_REG_INTR_SOURCE_1 (AR9170_USB_REG_BASE + 0x022) |
||||
#define AR9170_USB_REG_INTR_SOURCE_2 (AR9170_USB_REG_BASE + 0x023) |
||||
#define AR9170_USB_REG_INTR_SOURCE_3 (AR9170_USB_REG_BASE + 0x024) |
||||
#define AR9170_USB_REG_INTR_SOURCE_4 (AR9170_USB_REG_BASE + 0x025) |
||||
#define AR9170_USB_REG_INTR_SOURCE_5 (AR9170_USB_REG_BASE + 0x026) |
||||
#define AR9170_USB_REG_INTR_SOURCE_6 (AR9170_USB_REG_BASE + 0x027) |
||||
#define AR9170_USB_REG_INTR_SOURCE_7 (AR9170_USB_REG_BASE + 0x028) |
||||
#define AR9170_USB_INTR_SRC7_USB_RESET BIT(1) |
||||
#define AR9170_USB_INTR_SRC7_USB_SUSPEND BIT(2) |
||||
#define AR9170_USB_INTR_SRC7_USB_RESUME BIT(3) |
||||
#define AR9170_USB_INTR_SRC7_ISO_SEQ_ERR BIT(4) |
||||
#define AR9170_USB_INTR_SRC7_ISO_SEQ_ABORT BIT(5) |
||||
#define AR9170_USB_INTR_SRC7_TX0BYTE BIT(6) |
||||
#define AR9170_USB_INTR_SRC7_RX0BYTE BIT(7) |
||||
|
||||
#define AR9170_USB_REG_IDLE_COUNT (AR9170_USB_REG_BASE + 0x02f) |
||||
|
||||
#define AR9170_USB_REG_EP_MAP (AR9170_USB_REG_BASE + 0x030) |
||||
#define AR9170_USB_REG_EP1_MAP (AR9170_USB_REG_BASE + 0x030) |
||||
#define AR9170_USB_REG_EP2_MAP (AR9170_USB_REG_BASE + 0x031) |
||||
#define AR9170_USB_REG_EP3_MAP (AR9170_USB_REG_BASE + 0x032) |
||||
#define AR9170_USB_REG_EP4_MAP (AR9170_USB_REG_BASE + 0x033) |
||||
#define AR9170_USB_REG_EP5_MAP (AR9170_USB_REG_BASE + 0x034) |
||||
#define AR9170_USB_REG_EP6_MAP (AR9170_USB_REG_BASE + 0x035) |
||||
#define AR9170_USB_REG_EP7_MAP (AR9170_USB_REG_BASE + 0x036) |
||||
#define AR9170_USB_REG_EP8_MAP (AR9170_USB_REG_BASE + 0x037) |
||||
#define AR9170_USB_REG_EP9_MAP (AR9170_USB_REG_BASE + 0x038) |
||||
#define AR9170_USB_REG_EP10_MAP (AR9170_USB_REG_BASE + 0x039) |
||||
|
||||
#define AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x03f) |
||||
#define AR9170_USB_EP_IN_TOGGLE 0x10 |
||||
|
||||
#define AR9170_USB_REG_EP_IN_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x03e) |
||||
|
||||
#define AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x05f) |
||||
#define AR9170_USB_EP_OUT_TOGGLE 0x10 |
||||
|
||||
#define AR9170_USB_REG_EP_OUT_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x05e) |
||||
|
||||
#define AR9170_USB_REG_EP3_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0ae) |
||||
#define AR9170_USB_REG_EP3_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0be) |
||||
#define AR9170_USB_REG_EP4_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0af) |
||||
#define AR9170_USB_REG_EP4_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0bf) |
||||
|
||||
#define AR9170_USB_REG_FIFO_MAP (AR9170_USB_REG_BASE + 0x080) |
||||
#define AR9170_USB_REG_FIFO0_MAP (AR9170_USB_REG_BASE + 0x080) |
||||
#define AR9170_USB_REG_FIFO1_MAP (AR9170_USB_REG_BASE + 0x081) |
||||
#define AR9170_USB_REG_FIFO2_MAP (AR9170_USB_REG_BASE + 0x082) |
||||
#define AR9170_USB_REG_FIFO3_MAP (AR9170_USB_REG_BASE + 0x083) |
||||
#define AR9170_USB_REG_FIFO4_MAP (AR9170_USB_REG_BASE + 0x084) |
||||
#define AR9170_USB_REG_FIFO5_MAP (AR9170_USB_REG_BASE + 0x085) |
||||
#define AR9170_USB_REG_FIFO6_MAP (AR9170_USB_REG_BASE + 0x086) |
||||
#define AR9170_USB_REG_FIFO7_MAP (AR9170_USB_REG_BASE + 0x087) |
||||
#define AR9170_USB_REG_FIFO8_MAP (AR9170_USB_REG_BASE + 0x088) |
||||
#define AR9170_USB_REG_FIFO9_MAP (AR9170_USB_REG_BASE + 0x089) |
||||
|
||||
#define AR9170_USB_REG_FIFO_CONFIG (AR9170_USB_REG_BASE + 0x090) |
||||
#define AR9170_USB_REG_FIFO0_CONFIG (AR9170_USB_REG_BASE + 0x090) |
||||
#define AR9170_USB_REG_FIFO1_CONFIG (AR9170_USB_REG_BASE + 0x091) |
||||
#define AR9170_USB_REG_FIFO2_CONFIG (AR9170_USB_REG_BASE + 0x092) |
||||
#define AR9170_USB_REG_FIFO3_CONFIG (AR9170_USB_REG_BASE + 0x093) |
||||
#define AR9170_USB_REG_FIFO4_CONFIG (AR9170_USB_REG_BASE + 0x094) |
||||
#define AR9170_USB_REG_FIFO5_CONFIG (AR9170_USB_REG_BASE + 0x095) |
||||
#define AR9170_USB_REG_FIFO6_CONFIG (AR9170_USB_REG_BASE + 0x096) |
||||
#define AR9170_USB_REG_FIFO7_CONFIG (AR9170_USB_REG_BASE + 0x097) |
||||
#define AR9170_USB_REG_FIFO8_CONFIG (AR9170_USB_REG_BASE + 0x098) |
||||
#define AR9170_USB_REG_FIFO9_CONFIG (AR9170_USB_REG_BASE + 0x099) |
||||
|
||||
#define AR9170_USB_REG_EP3_DATA (AR9170_USB_REG_BASE + 0x0f8) |
||||
#define AR9170_USB_REG_EP4_DATA (AR9170_USB_REG_BASE + 0x0fc) |
||||
|
||||
#define AR9170_USB_REG_FIFO_SIZE (AR9170_USB_REG_BASE + 0x100) |
||||
#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108) |
||||
#define AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE BIT(0) |
||||
#define AR9170_USB_DMA_CTL_ENABLE_FROM_DEVICE BIT(1) |
||||
#define AR9170_USB_DMA_CTL_HIGH_SPEED BIT(2) |
||||
#define AR9170_USB_DMA_CTL_UP_PACKET_MODE BIT(3) |
||||
#define AR9170_USB_DMA_CTL_UP_STREAM_S 4 |
||||
#define AR9170_USB_DMA_CTL_UP_STREAM (BIT(4) | BIT(5)) |
||||
#define AR9170_USB_DMA_CTL_UP_STREAM_4K (0) |
||||
#define AR9170_USB_DMA_CTL_UP_STREAM_8K BIT(4) |
||||
#define AR9170_USB_DMA_CTL_UP_STREAM_16K BIT(5) |
||||
#define AR9170_USB_DMA_CTL_UP_STREAM_32K (BIT(4) | BIT(5)) |
||||
#define AR9170_USB_DMA_CTL_DOWN_STREAM BIT(6) |
||||
|
||||
#define AR9170_USB_REG_DMA_STATUS (AR9170_USB_REG_BASE + 0x10c) |
||||
#define AR9170_USB_DMA_STATUS_UP_IDLE BIT(8) |
||||
#define AR9170_USB_DMA_STATUS_DN_IDLE BIT(16) |
||||
|
||||
#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110) |
||||
#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114) |
||||
|
||||
#define AR9170_USB_REG_WAKE_UP (AR9170_USB_REG_BASE + 0x120) |
||||
#define AR9170_USB_WAKE_UP_WAKE BIT(0) |
||||
|
||||
#define AR9170_USB_REG_CBUS_CTRL (AR9170_USB_REG_BASE + 0x1f0) |
||||
#define AR9170_USB_CBUS_CTRL_BUFFER_END (BIT(1)) |
||||
|
||||
/* PCI/USB to AHB Bridge */ |
||||
#define AR9170_PTA_REG_BASE 0x1e2000 |
||||
|
||||
#define AR9170_PTA_REG_CMD (AR9170_PTA_REG_BASE + 0x000) |
||||
#define AR9170_PTA_REG_PARAM1 (AR9170_PTA_REG_BASE + 0x004) |
||||
#define AR9170_PTA_REG_PARAM2 (AR9170_PTA_REG_BASE + 0x008) |
||||
#define AR9170_PTA_REG_PARAM3 (AR9170_PTA_REG_BASE + 0x00c) |
||||
#define AR9170_PTA_REG_RSP (AR9170_PTA_REG_BASE + 0x010) |
||||
#define AR9170_PTA_REG_STATUS1 (AR9170_PTA_REG_BASE + 0x014) |
||||
#define AR9170_PTA_REG_STATUS2 (AR9170_PTA_REG_BASE + 0x018) |
||||
#define AR9170_PTA_REG_STATUS3 (AR9170_PTA_REG_BASE + 0x01c) |
||||
#define AR9170_PTA_REG_AHB_INT_FLAG (AR9170_PTA_REG_BASE + 0x020) |
||||
#define AR9170_PTA_REG_AHB_INT_MASK (AR9170_PTA_REG_BASE + 0x024) |
||||
#define AR9170_PTA_REG_AHB_INT_ACK (AR9170_PTA_REG_BASE + 0x028) |
||||
#define AR9170_PTA_REG_AHB_SCRATCH1 (AR9170_PTA_REG_BASE + 0x030) |
||||
#define AR9170_PTA_REG_AHB_SCRATCH2 (AR9170_PTA_REG_BASE + 0x034) |
||||
#define AR9170_PTA_REG_AHB_SCRATCH3 (AR9170_PTA_REG_BASE + 0x038) |
||||
#define AR9170_PTA_REG_AHB_SCRATCH4 (AR9170_PTA_REG_BASE + 0x03c) |
||||
|
||||
#define AR9170_PTA_REG_SHARE_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124) |
||||
|
||||
/* |
||||
* PCI to AHB Bridge |
||||
*/ |
||||
|
||||
#define AR9170_PTA_REG_INT_FLAG (AR9170_PTA_REG_BASE + 0x100) |
||||
#define AR9170_PTA_INT_FLAG_DN 0x01 |
||||
#define AR9170_PTA_INT_FLAG_UP 0x02 |
||||
#define AR9170_PTA_INT_FLAG_CMD 0x04 |
||||
|
||||
#define AR9170_PTA_REG_INT_MASK (AR9170_PTA_REG_BASE + 0x104) |
||||
#define AR9170_PTA_REG_DN_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x108) |
||||
#define AR9170_PTA_REG_DN_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x10c) |
||||
#define AR9170_PTA_REG_UP_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x110) |
||||
#define AR9170_PTA_REG_UP_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x114) |
||||
#define AR9170_PTA_REG_DN_PEND_TIME (AR9170_PTA_REG_BASE + 0x118) |
||||
#define AR9170_PTA_REG_UP_PEND_TIME (AR9170_PTA_REG_BASE + 0x11c) |
||||
#define AR9170_PTA_REG_CONTROL (AR9170_PTA_REG_BASE + 0x120) |
||||
#define AR9170_PTA_CTRL_4_BEAT_BURST 0x00 |
||||
#define AR9170_PTA_CTRL_8_BEAT_BURST 0x01 |
||||
#define AR9170_PTA_CTRL_16_BEAT_BURST 0x02 |
||||
#define AR9170_PTA_CTRL_LOOPBACK_MODE 0x10 |
||||
|
||||
#define AR9170_PTA_REG_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124) |
||||
#define AR9170_PTA_REG_MEM_ADDR (AR9170_PTA_REG_BASE + 0x128) |
||||
#define AR9170_PTA_REG_DN_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x12c) |
||||
#define AR9170_PTA_REG_UP_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x130) |
||||
#define AR9170_PTA_REG_DMA_STATUS (AR9170_PTA_REG_BASE + 0x134) |
||||
#define AR9170_PTA_REG_DN_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x138) |
||||
#define AR9170_PTA_REG_DN_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x13c) |
||||
#define AR9170_PTA_REG_UP_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x140) |
||||
#define AR9170_PTA_REG_UP_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x144) |
||||
#define AR9170_PTA_REG_DMA_MODE_CTRL (AR9170_PTA_REG_BASE + 0x148) |
||||
#define AR9170_PTA_DMA_MODE_CTRL_RESET BIT(0) |
||||
#define AR9170_PTA_DMA_MODE_CTRL_DISABLE_USB BIT(1) |
||||
|
||||
/* Protocol Controller Module */ |
||||
#define AR9170_MAC_REG_PC_REG_BASE (AR9170_MAC_REG_BASE + 0xe00) |
||||
|
||||
|
||||
#define AR9170_NUM_LEDS 2 |
||||
|
||||
/* CAM */ |
||||
#define AR9170_CAM_MAX_USER 64 |
||||
#define AR9170_CAM_MAX_KEY_LENGTH 16 |
||||
|
||||
#define AR9170_SRAM_OFFSET 0x100000 |
||||
#define AR9170_SRAM_SIZE 0x18000 |
||||
|
||||
#define AR9170_PRAM_OFFSET 0x200000 |
||||
#define AR9170_PRAM_SIZE 0x8000 |
||||
|
||||
enum cpu_clock { |
||||
AHB_STATIC_40MHZ = 0, |
||||
AHB_GMODE_22MHZ = 1, |
||||
AHB_AMODE_20MHZ = 1, |
||||
AHB_GMODE_44MHZ = 2, |
||||
AHB_AMODE_40MHZ = 2, |
||||
AHB_GMODE_88MHZ = 3, |
||||
AHB_AMODE_80MHZ = 3 |
||||
}; |
||||
|
||||
/* USB endpoints */ |
||||
enum ar9170_usb_ep { |
||||
/* |
||||
* Control EP is always EP 0 (USB SPEC) |
||||
* |
||||
* The weird thing is: the original firmware has a few |
||||
* comments that suggest that the actual EP numbers |
||||
* are in the 1 to 10 range?! |
||||
*/ |
||||
AR9170_USB_EP_CTRL = 0, |
||||
|
||||
AR9170_USB_EP_TX, |
||||
AR9170_USB_EP_RX, |
||||
AR9170_USB_EP_IRQ, |
||||
AR9170_USB_EP_CMD, |
||||
AR9170_USB_NUM_EXTRA_EP = 4, |
||||
|
||||
__AR9170_USB_NUM_EP, |
||||
|
||||
__AR9170_USB_NUM_MAX_EP = 10 |
||||
}; |
||||
|
||||
enum ar9170_usb_fifo { |
||||
__AR9170_USB_NUM_MAX_FIFO = 10 |
||||
}; |
||||
|
||||
enum ar9170_tx_queues { |
||||
AR9170_TXQ0 = 0, |
||||
AR9170_TXQ1, |
||||
AR9170_TXQ2, |
||||
AR9170_TXQ3, |
||||
AR9170_TXQ_SPECIAL, |
||||
|
||||
/* keep last */ |
||||
__AR9170_NUM_TX_QUEUES = 5 |
||||
}; |
||||
|
||||
#define AR9170_TX_STREAM_TAG 0x697e |
||||
#define AR9170_RX_STREAM_TAG 0x4e00 |
||||
#define AR9170_RX_STREAM_MAX_SIZE 0xffff |
||||
|
||||
struct ar9170_stream { |
||||
__le16 length; |
||||
__le16 tag; |
||||
|
||||
u8 payload[0]; |
||||
} __packed __aligned(4); |
||||
#define AR9170_STREAM_LEN 4 |
||||
|
||||
#define AR9170_MAX_ACKTABLE_ENTRIES 8 |
||||
#define AR9170_MAX_VIRTUAL_MAC 7 |
||||
|
||||
#define AR9170_USB_EP_CTRL_MAX 64 |
||||
#define AR9170_USB_EP_TX_MAX 512 |
||||
#define AR9170_USB_EP_RX_MAX 512 |
||||
#define AR9170_USB_EP_IRQ_MAX 64 |
||||
#define AR9170_USB_EP_CMD_MAX 64 |
||||
|
||||
/* Trigger PRETBTT interrupt 6 Kus earlier */ |
||||
#define CARL9170_PRETBTT_KUS 6 |
||||
|
||||
#define AR5416_MAX_RATE_POWER 63 |
||||
|
||||
#define SET_VAL(reg, value, newvalue) \ |
||||
(value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg)) |
||||
|
||||
#define SET_CONSTVAL(reg, newvalue) \ |
||||
(((newvalue) << reg##_S) & reg) |
||||
|
||||
#define MOD_VAL(reg, value, newvalue) \ |
||||
(((value) & ~reg) | (((newvalue) << reg##_S) & reg)) |
||||
|
||||
#define GET_VAL(reg, value) \ |
||||
(((value) & reg) >> reg##_S) |
||||
|
||||
#endif /* __CARL9170_SHARED_HW_H */ |
@ -0,0 +1,564 @@
@@ -0,0 +1,564 @@
|
||||
/* |
||||
* Shared Atheros AR9170 Header |
||||
* |
||||
* PHY register map |
||||
* |
||||
* Copyright (c) 2008-2009 Atheros Communications Inc. |
||||
* |
||||
* Permission to use, copy, modify, and/or distribute this software for any |
||||
* purpose with or without fee is hereby granted, provided that the above |
||||
* copyright notice and this permission notice appear in all copies. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170_SHARED_PHY_H |
||||
#define __CARL9170_SHARED_PHY_H |
||||
|
||||
#define AR9170_PHY_REG_BASE (0x1bc000 + 0x9800) |
||||
#define AR9170_PHY_REG(_n) (AR9170_PHY_REG_BASE + \ |
||||
((_n) << 2)) |
||||
|
||||
#define AR9170_PHY_REG_TEST (AR9170_PHY_REG_BASE + 0x0000) |
||||
#define AR9170_PHY_TEST_AGC_CLR 0x10000000 |
||||
#define AR9170_PHY_TEST_RFSILENT_BB 0x00002000 |
||||
|
||||
#define AR9170_PHY_REG_TURBO (AR9170_PHY_REG_BASE + 0x0004) |
||||
#define AR9170_PHY_TURBO_FC_TURBO_MODE 0x00000001 |
||||
#define AR9170_PHY_TURBO_FC_TURBO_SHORT 0x00000002 |
||||
#define AR9170_PHY_TURBO_FC_DYN2040_EN 0x00000004 |
||||
#define AR9170_PHY_TURBO_FC_DYN2040_PRI_ONLY 0x00000008 |
||||
#define AR9170_PHY_TURBO_FC_DYN2040_PRI_CH 0x00000010 |
||||
/* For 25 MHz channel spacing -- not used but supported by hw */ |
||||
#define AR9170_PHY_TURBO_FC_DYN2040_EXT_CH 0x00000020 |
||||
#define AR9170_PHY_TURBO_FC_HT_EN 0x00000040 |
||||
#define AR9170_PHY_TURBO_FC_SHORT_GI_40 0x00000080 |
||||
#define AR9170_PHY_TURBO_FC_WALSH 0x00000100 |
||||
#define AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 0x00000200 |
||||
#define AR9170_PHY_TURBO_FC_ENABLE_DAC_FIFO 0x00000800 |
||||
|
||||
#define AR9170_PHY_REG_TEST2 (AR9170_PHY_REG_BASE + 0x0008) |
||||
|
||||
#define AR9170_PHY_REG_TIMING2 (AR9170_PHY_REG_BASE + 0x0010) |
||||
#define AR9170_PHY_TIMING2_USE_FORCE 0x00001000 |
||||
#define AR9170_PHY_TIMING2_FORCE 0x00000fff |
||||
#define AR9170_PHY_TIMING2_FORCE_S 0 |
||||
|
||||
#define AR9170_PHY_REG_TIMING3 (AR9170_PHY_REG_BASE + 0x0014) |
||||
#define AR9170_PHY_TIMING3_DSC_EXP 0x0001e000 |
||||
#define AR9170_PHY_TIMING3_DSC_EXP_S 13 |
||||
#define AR9170_PHY_TIMING3_DSC_MAN 0xfffe0000 |
||||
#define AR9170_PHY_TIMING3_DSC_MAN_S 17 |
||||
|
||||
#define AR9170_PHY_REG_CHIP_ID (AR9170_PHY_REG_BASE + 0x0018) |
||||
#define AR9170_PHY_CHIP_ID_REV_0 0x80 |
||||
#define AR9170_PHY_CHIP_ID_REV_1 0x81 |
||||
#define AR9170_PHY_CHIP_ID_9160_REV_0 0xb0 |
||||
|
||||
#define AR9170_PHY_REG_ACTIVE (AR9170_PHY_REG_BASE + 0x001c) |
||||
#define AR9170_PHY_ACTIVE_EN 0x00000001 |
||||
#define AR9170_PHY_ACTIVE_DIS 0x00000000 |
||||
|
||||
#define AR9170_PHY_REG_RF_CTL2 (AR9170_PHY_REG_BASE + 0x0024) |
||||
#define AR9170_PHY_RF_CTL2_TX_END_DATA_START 0x000000ff |
||||
#define AR9170_PHY_RF_CTL2_TX_END_DATA_START_S 0 |
||||
#define AR9170_PHY_RF_CTL2_TX_END_PA_ON 0x0000ff00 |
||||
#define AR9170_PHY_RF_CTL2_TX_END_PA_ON_S 8 |
||||
|
||||
#define AR9170_PHY_REG_RF_CTL3 (AR9170_PHY_REG_BASE + 0x0028) |
||||
#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON 0x00ff0000 |
||||
#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON_S 16 |
||||
|
||||
#define AR9170_PHY_REG_ADC_CTL (AR9170_PHY_REG_BASE + 0x002c) |
||||
#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 |
||||
#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN_S 0 |
||||
#define AR9170_PHY_ADC_CTL_OFF_PWDDAC 0x00002000 |
||||
#define AR9170_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000 |
||||
#define AR9170_PHY_ADC_CTL_OFF_PWDADC 0x00008000 |
||||
#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000 |
||||
#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN_S 16 |
||||
|
||||
#define AR9170_PHY_REG_ADC_SERIAL_CTL (AR9170_PHY_REG_BASE + 0x0030) |
||||
#define AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC 0x00000000 |
||||
#define AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO 0x00000001 |
||||
|
||||
#define AR9170_PHY_REG_RF_CTL4 (AR9170_PHY_REG_BASE + 0x0034) |
||||
#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF 0xff000000 |
||||
#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24 |
||||
#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00ff0000 |
||||
#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16 |
||||
#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000ff00 |
||||
#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON_S 8 |
||||
#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000ff |
||||
#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 |
||||
|
||||
#define AR9170_PHY_REG_TSTDAC_CONST (AR9170_PHY_REG_BASE + 0x003c) |
||||
|
||||
#define AR9170_PHY_REG_SETTLING (AR9170_PHY_REG_BASE + 0x0044) |
||||
#define AR9170_PHY_SETTLING_SWITCH 0x00003f80 |
||||
#define AR9170_PHY_SETTLING_SWITCH_S 7 |
||||
|
||||
#define AR9170_PHY_REG_RXGAIN (AR9170_PHY_REG_BASE + 0x0048) |
||||
#define AR9170_PHY_REG_RXGAIN_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2048) |
||||
#define AR9170_PHY_RXGAIN_TXRX_ATTEN 0x0003f000 |
||||
#define AR9170_PHY_RXGAIN_TXRX_ATTEN_S 12 |
||||
#define AR9170_PHY_RXGAIN_TXRX_RF_MAX 0x007c0000 |
||||
#define AR9170_PHY_RXGAIN_TXRX_RF_MAX_S 18 |
||||
|
||||
#define AR9170_PHY_REG_DESIRED_SZ (AR9170_PHY_REG_BASE + 0x0050) |
||||
#define AR9170_PHY_DESIRED_SZ_ADC 0x000000ff |
||||
#define AR9170_PHY_DESIRED_SZ_ADC_S 0 |
||||
#define AR9170_PHY_DESIRED_SZ_PGA 0x0000ff00 |
||||
#define AR9170_PHY_DESIRED_SZ_PGA_S 8 |
||||
#define AR9170_PHY_DESIRED_SZ_TOT_DES 0x0ff00000 |
||||
#define AR9170_PHY_DESIRED_SZ_TOT_DES_S 20 |
||||
|
||||
#define AR9170_PHY_REG_FIND_SIG (AR9170_PHY_REG_BASE + 0x0058) |
||||
#define AR9170_PHY_FIND_SIG_FIRSTEP 0x0003f000 |
||||
#define AR9170_PHY_FIND_SIG_FIRSTEP_S 12 |
||||
#define AR9170_PHY_FIND_SIG_FIRPWR 0x03fc0000 |
||||
#define AR9170_PHY_FIND_SIG_FIRPWR_S 18 |
||||
|
||||
#define AR9170_PHY_REG_AGC_CTL1 (AR9170_PHY_REG_BASE + 0x005c) |
||||
#define AR9170_PHY_AGC_CTL1_COARSE_LOW 0x00007f80 |
||||
#define AR9170_PHY_AGC_CTL1_COARSE_LOW_S 7 |
||||
#define AR9170_PHY_AGC_CTL1_COARSE_HIGH 0x003f8000 |
||||
#define AR9170_PHY_AGC_CTL1_COARSE_HIGH_S 15 |
||||
|
||||
#define AR9170_PHY_REG_AGC_CONTROL (AR9170_PHY_REG_BASE + 0x0060) |
||||
#define AR9170_PHY_AGC_CONTROL_CAL 0x00000001 |
||||
#define AR9170_PHY_AGC_CONTROL_NF 0x00000002 |
||||
#define AR9170_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 |
||||
#define AR9170_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 |
||||
#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 |
||||
|
||||
#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064) |
||||
#define AR9170_PHY_CCA_MIN_PWR 0x0ff80000 |
||||
#define AR9170_PHY_CCA_MIN_PWR_S 19 |
||||
#define AR9170_PHY_CCA_THRESH62 0x0007f000 |
||||
#define AR9170_PHY_CCA_THRESH62_S 12 |
||||
|
||||
#define AR9170_PHY_REG_SFCORR (AR9170_PHY_REG_BASE + 0x0068) |
||||
#define AR9170_PHY_SFCORR_M2COUNT_THR 0x0000001f |
||||
#define AR9170_PHY_SFCORR_M2COUNT_THR_S 0 |
||||
#define AR9170_PHY_SFCORR_M1_THRESH 0x00fe0000 |
||||
#define AR9170_PHY_SFCORR_M1_THRESH_S 17 |
||||
#define AR9170_PHY_SFCORR_M2_THRESH 0x7f000000 |
||||
#define AR9170_PHY_SFCORR_M2_THRESH_S 24 |
||||
|
||||
#define AR9170_PHY_REG_SFCORR_LOW (AR9170_PHY_REG_BASE + 0x006c) |
||||
#define AR9170_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 |
||||
#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003f00 |
||||
#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 |
||||
#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001fc000 |
||||
#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 |
||||
#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0fe00000 |
||||
#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 |
||||
|
||||
#define AR9170_PHY_REG_SLEEP_CTR_CONTROL (AR9170_PHY_REG_BASE + 0x0070) |
||||
#define AR9170_PHY_REG_SLEEP_CTR_LIMIT (AR9170_PHY_REG_BASE + 0x0074) |
||||
#define AR9170_PHY_REG_SLEEP_SCAL (AR9170_PHY_REG_BASE + 0x0078) |
||||
|
||||
#define AR9170_PHY_REG_PLL_CTL (AR9170_PHY_REG_BASE + 0x007c) |
||||
#define AR9170_PHY_PLL_CTL_40 0xaa |
||||
#define AR9170_PHY_PLL_CTL_40_5413 0x04 |
||||
#define AR9170_PHY_PLL_CTL_44 0xab |
||||
#define AR9170_PHY_PLL_CTL_44_2133 0xeb |
||||
#define AR9170_PHY_PLL_CTL_40_2133 0xea |
||||
|
||||
#define AR9170_PHY_REG_BIN_MASK_1 (AR9170_PHY_REG_BASE + 0x0100) |
||||
#define AR9170_PHY_REG_BIN_MASK_2 (AR9170_PHY_REG_BASE + 0x0104) |
||||
#define AR9170_PHY_REG_BIN_MASK_3 (AR9170_PHY_REG_BASE + 0x0108) |
||||
#define AR9170_PHY_REG_MASK_CTL (AR9170_PHY_REG_BASE + 0x010c) |
||||
|
||||
/* analogue power on time (100ns) */ |
||||
#define AR9170_PHY_REG_RX_DELAY (AR9170_PHY_REG_BASE + 0x0114) |
||||
#define AR9170_PHY_REG_SEARCH_START_DELAY (AR9170_PHY_REG_BASE + 0x0118) |
||||
#define AR9170_PHY_RX_DELAY_DELAY 0x00003fff |
||||
|
||||
#define AR9170_PHY_REG_TIMING_CTRL4(_i) (AR9170_PHY_REG_BASE + \ |
||||
(0x0120 + ((_i) << 12))) |
||||
#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01f |
||||
#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0 |
||||
#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7e0 |
||||
#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5 |
||||
#define AR9170_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800 |
||||
#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xf000 |
||||
#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12 |
||||
#define AR9170_PHY_TIMING_CTRL4_DO_IQCAL 0x10000 |
||||
#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000 |
||||
#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000 |
||||
#define AR9170_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000 |
||||
#define AR9170_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000 |
||||
|
||||
#define AR9170_PHY_REG_TIMING5 (AR9170_PHY_REG_BASE + 0x0124) |
||||
#define AR9170_PHY_TIMING5_CYCPWR_THR1 0x000000fe |
||||
#define AR9170_PHY_TIMING5_CYCPWR_THR1_S 1 |
||||
|
||||
#define AR9170_PHY_REG_POWER_TX_RATE1 (AR9170_PHY_REG_BASE + 0x0134) |
||||
#define AR9170_PHY_REG_POWER_TX_RATE2 (AR9170_PHY_REG_BASE + 0x0138) |
||||
#define AR9170_PHY_REG_POWER_TX_RATE_MAX (AR9170_PHY_REG_BASE + 0x013c) |
||||
#define AR9170_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 |
||||
|
||||
#define AR9170_PHY_REG_FRAME_CTL (AR9170_PHY_REG_BASE + 0x0144) |
||||
#define AR9170_PHY_FRAME_CTL_TX_CLIP 0x00000038 |
||||
#define AR9170_PHY_FRAME_CTL_TX_CLIP_S 3 |
||||
|
||||
#define AR9170_PHY_REG_SPUR_REG (AR9170_PHY_REG_BASE + 0x014c) |
||||
#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL (0xff << 18) |
||||
#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL_S 18 |
||||
#define AR9170_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 |
||||
#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT (0xff << 9) |
||||
#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT_S 9 |
||||
#define AR9170_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100 |
||||
#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7f |
||||
#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0 |
||||
|
||||
#define AR9170_PHY_REG_RADAR_EXT (AR9170_PHY_REG_BASE + 0x0140) |
||||
#define AR9170_PHY_RADAR_EXT_ENA 0x00004000 |
||||
|
||||
#define AR9170_PHY_REG_RADAR_0 (AR9170_PHY_REG_BASE + 0x0154) |
||||
#define AR9170_PHY_RADAR_0_ENA 0x00000001 |
||||
#define AR9170_PHY_RADAR_0_FFT_ENA 0x80000000 |
||||
/* inband pulse threshold */ |
||||
#define AR9170_PHY_RADAR_0_INBAND 0x0000003e |
||||
#define AR9170_PHY_RADAR_0_INBAND_S 1 |
||||
/* pulse RSSI threshold */ |
||||
#define AR9170_PHY_RADAR_0_PRSSI 0x00000fc0 |
||||
#define AR9170_PHY_RADAR_0_PRSSI_S 6 |
||||
/* pulse height threshold */ |
||||
#define AR9170_PHY_RADAR_0_HEIGHT 0x0003f000 |
||||
#define AR9170_PHY_RADAR_0_HEIGHT_S 12 |
||||
/* radar RSSI threshold */ |
||||
#define AR9170_PHY_RADAR_0_RRSSI 0x00fc0000 |
||||
#define AR9170_PHY_RADAR_0_RRSSI_S 18 |
||||
/* radar firepower threshold */ |
||||
#define AR9170_PHY_RADAR_0_FIRPWR 0x7f000000 |
||||
#define AR9170_PHY_RADAR_0_FIRPWR_S 24 |
||||
|
||||
#define AR9170_PHY_REG_RADAR_1 (AR9170_PHY_REG_BASE + 0x0158) |
||||
#define AR9170_PHY_RADAR_1_RELPWR_ENA 0x00800000 |
||||
#define AR9170_PHY_RADAR_1_USE_FIR128 0x00400000 |
||||
#define AR9170_PHY_RADAR_1_RELPWR_THRESH 0x003f0000 |
||||
#define AR9170_PHY_RADAR_1_RELPWR_THRESH_S 16 |
||||
#define AR9170_PHY_RADAR_1_BLOCK_CHECK 0x00008000 |
||||
#define AR9170_PHY_RADAR_1_MAX_RRSSI 0x00004000 |
||||
#define AR9170_PHY_RADAR_1_RELSTEP_CHECK 0x00002000 |
||||
#define AR9170_PHY_RADAR_1_RELSTEP_THRESH 0x00001f00 |
||||
#define AR9170_PHY_RADAR_1_RELSTEP_THRESH_S 8 |
||||
#define AR9170_PHY_RADAR_1_MAXLEN 0x000000ff |
||||
#define AR9170_PHY_RADAR_1_MAXLEN_S 0 |
||||
|
||||
#define AR9170_PHY_REG_SWITCH_CHAIN_0 (AR9170_PHY_REG_BASE + 0x0160) |
||||
#define AR9170_PHY_REG_SWITCH_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2160) |
||||
|
||||
#define AR9170_PHY_REG_SWITCH_COM (AR9170_PHY_REG_BASE + 0x0164) |
||||
|
||||
#define AR9170_PHY_REG_CCA_THRESHOLD (AR9170_PHY_REG_BASE + 0x0168) |
||||
|
||||
#define AR9170_PHY_REG_SIGMA_DELTA (AR9170_PHY_REG_BASE + 0x016c) |
||||
#define AR9170_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 |
||||
#define AR9170_PHY_SIGMA_DELTA_ADC_SEL_S 0 |
||||
#define AR9170_PHY_SIGMA_DELTA_FILT2 0x000000f8 |
||||
#define AR9170_PHY_SIGMA_DELTA_FILT2_S 3 |
||||
#define AR9170_PHY_SIGMA_DELTA_FILT1 0x00001f00 |
||||
#define AR9170_PHY_SIGMA_DELTA_FILT1_S 8 |
||||
#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000 |
||||
#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP_S 13 |
||||
|
||||
#define AR9170_PHY_REG_RESTART (AR9170_PHY_REG_BASE + 0x0170) |
||||
#define AR9170_PHY_RESTART_DIV_GC 0x001c0000 |
||||
#define AR9170_PHY_RESTART_DIV_GC_S 18 |
||||
|
||||
#define AR9170_PHY_REG_RFBUS_REQ (AR9170_PHY_REG_BASE + 0x017c) |
||||
#define AR9170_PHY_RFBUS_REQ_EN 0x00000001 |
||||
|
||||
#define AR9170_PHY_REG_TIMING7 (AR9170_PHY_REG_BASE + 0x0180) |
||||
#define AR9170_PHY_REG_TIMING8 (AR9170_PHY_REG_BASE + 0x0184) |
||||
#define AR9170_PHY_TIMING8_PILOT_MASK_2 0x000fffff |
||||
#define AR9170_PHY_TIMING8_PILOT_MASK_2_S 0 |
||||
|
||||
#define AR9170_PHY_REG_BIN_MASK2_1 (AR9170_PHY_REG_BASE + 0x0188) |
||||
#define AR9170_PHY_REG_BIN_MASK2_2 (AR9170_PHY_REG_BASE + 0x018c) |
||||
#define AR9170_PHY_REG_BIN_MASK2_3 (AR9170_PHY_REG_BASE + 0x0190) |
||||
#define AR9170_PHY_REG_BIN_MASK2_4 (AR9170_PHY_REG_BASE + 0x0194) |
||||
#define AR9170_PHY_BIN_MASK2_4_MASK_4 0x00003fff |
||||
#define AR9170_PHY_BIN_MASK2_4_MASK_4_S 0 |
||||
|
||||
#define AR9170_PHY_REG_TIMING9 (AR9170_PHY_REG_BASE + 0x0198) |
||||
#define AR9170_PHY_REG_TIMING10 (AR9170_PHY_REG_BASE + 0x019c) |
||||
#define AR9170_PHY_TIMING10_PILOT_MASK_2 0x000fffff |
||||
#define AR9170_PHY_TIMING10_PILOT_MASK_2_S 0 |
||||
|
||||
#define AR9170_PHY_REG_TIMING11 (AR9170_PHY_REG_BASE + 0x01a0) |
||||
#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE 0x000fffff |
||||
#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE_S 0 |
||||
#define AR9170_PHY_TIMING11_SPUR_FREQ_SD 0x3ff00000 |
||||
#define AR9170_PHY_TIMING11_SPUR_FREQ_SD_S 20 |
||||
#define AR9170_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000 |
||||
#define AR9170_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000 |
||||
|
||||
#define AR9170_PHY_REG_RX_CHAINMASK (AR9170_PHY_REG_BASE + 0x01a4) |
||||
#define AR9170_PHY_REG_NEW_ADC_DC_GAIN_CORR(_i) (AR9170_PHY_REG_BASE + \ |
||||
0x01b4 + ((_i) << 12)) |
||||
#define AR9170_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 |
||||
#define AR9170_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 |
||||
|
||||
#define AR9170_PHY_REG_MULTICHAIN_GAIN_CTL (AR9170_PHY_REG_BASE + 0x01ac) |
||||
#define AR9170_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000 |
||||
#define AR9170_PHY_9285_ANT_DIV_CTL 0x01000000 |
||||
#define AR9170_PHY_9285_ANT_DIV_CTL_S 24 |
||||
#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000 |
||||
#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF_S 25 |
||||
#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000 |
||||
#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27 |
||||
#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000 |
||||
#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB_S 29 |
||||
#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000 |
||||
#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30 |
||||
#define AR9170_PHY_9285_ANT_DIV_LNA1 2 |
||||
#define AR9170_PHY_9285_ANT_DIV_LNA2 1 |
||||
#define AR9170_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3 |
||||
#define AR9170_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0 |
||||
#define AR9170_PHY_9285_ANT_DIV_GAINTB_0 0 |
||||
#define AR9170_PHY_9285_ANT_DIV_GAINTB_1 1 |
||||
|
||||
#define AR9170_PHY_REG_EXT_CCA0 (AR9170_PHY_REG_BASE + 0x01b8) |
||||
#define AR9170_PHY_REG_EXT_CCA0_THRESH62 0x000000ff |
||||
#define AR9170_PHY_REG_EXT_CCA0_THRESH62_S 0 |
||||
|
||||
#define AR9170_PHY_REG_EXT_CCA (AR9170_PHY_REG_BASE + 0x01bc) |
||||
#define AR9170_PHY_EXT_CCA_CYCPWR_THR1 0x0000fe00 |
||||
#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9 |
||||
#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000 |
||||
#define AR9170_PHY_EXT_CCA_THRESH62_S 16 |
||||
#define AR9170_PHY_EXT_CCA_MIN_PWR 0xff800000 |
||||
#define AR9170_PHY_EXT_CCA_MIN_PWR_S 23 |
||||
|
||||
#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0) |
||||
#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f |
||||
#define AR9170_PHY_SFCORR_EXT_M1_THRESH_S 0 |
||||
#define AR9170_PHY_SFCORR_EXT_M2_THRESH 0x00003f80 |
||||
#define AR9170_PHY_SFCORR_EXT_M2_THRESH_S 7 |
||||
#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001fc000 |
||||
#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 |
||||
#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0fe00000 |
||||
#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 |
||||
#define AR9170_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 |
||||
|
||||
#define AR9170_PHY_REG_HALFGI (AR9170_PHY_REG_BASE + 0x01d0) |
||||
#define AR9170_PHY_HALFGI_DSC_MAN 0x0007fff0 |
||||
#define AR9170_PHY_HALFGI_DSC_MAN_S 4 |
||||
#define AR9170_PHY_HALFGI_DSC_EXP 0x0000000f |
||||
#define AR9170_PHY_HALFGI_DSC_EXP_S 0 |
||||
|
||||
#define AR9170_PHY_REG_CHANNEL_MASK_01_30 (AR9170_PHY_REG_BASE + 0x01d4) |
||||
#define AR9170_PHY_REG_CHANNEL_MASK_31_60 (AR9170_PHY_REG_BASE + 0x01d8) |
||||
|
||||
#define AR9170_PHY_REG_CHAN_INFO_MEMORY (AR9170_PHY_REG_BASE + 0x01dc) |
||||
#define AR9170_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 |
||||
|
||||
#define AR9170_PHY_REG_HEAVY_CLIP_ENABLE (AR9170_PHY_REG_BASE + 0x01e0) |
||||
#define AR9170_PHY_REG_HEAVY_CLIP_FACTOR_RIFS (AR9170_PHY_REG_BASE + 0x01ec) |
||||
#define AR9170_PHY_RIFS_INIT_DELAY 0x03ff0000 |
||||
|
||||
#define AR9170_PHY_REG_CALMODE (AR9170_PHY_REG_BASE + 0x01f0) |
||||
#define AR9170_PHY_CALMODE_IQ 0x00000000 |
||||
#define AR9170_PHY_CALMODE_ADC_GAIN 0x00000001 |
||||
#define AR9170_PHY_CALMODE_ADC_DC_PER 0x00000002 |
||||
#define AR9170_PHY_CALMODE_ADC_DC_INIT 0x00000003 |
||||
|
||||
#define AR9170_PHY_REG_REFCLKDLY (AR9170_PHY_REG_BASE + 0x01f4) |
||||
#define AR9170_PHY_REG_REFCLKPD (AR9170_PHY_REG_BASE + 0x01f8) |
||||
|
||||
|
||||
#define AR9170_PHY_REG_CAL_MEAS_0(_i) (AR9170_PHY_REG_BASE + \ |
||||
0x0410 + ((_i) << 12)) |
||||
#define AR9170_PHY_REG_CAL_MEAS_1(_i) (AR9170_PHY_REG_BASE + \ |
||||
0x0414 \ + ((_i) << 12)) |
||||
#define AR9170_PHY_REG_CAL_MEAS_2(_i) (AR9170_PHY_REG_BASE + \ |
||||
0x0418 + ((_i) << 12)) |
||||
#define AR9170_PHY_REG_CAL_MEAS_3(_i) (AR9170_PHY_REG_BASE + \ |
||||
0x041c + ((_i) << 12)) |
||||
|
||||
#define AR9170_PHY_REG_CURRENT_RSSI (AR9170_PHY_REG_BASE + 0x041c) |
||||
|
||||
#define AR9170_PHY_REG_RFBUS_GRANT (AR9170_PHY_REG_BASE + 0x0420) |
||||
#define AR9170_PHY_RFBUS_GRANT_EN 0x00000001 |
||||
|
||||
#define AR9170_PHY_REG_CHAN_INFO_GAIN_DIFF (AR9170_PHY_REG_BASE + 0x04f4) |
||||
#define AR9170_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 |
||||
|
||||
#define AR9170_PHY_REG_CHAN_INFO_GAIN (AR9170_PHY_REG_BASE + 0x04fc) |
||||
|
||||
#define AR9170_PHY_REG_MODE (AR9170_PHY_REG_BASE + 0x0a00) |
||||
#define AR9170_PHY_MODE_ASYNCFIFO 0x80 |
||||
#define AR9170_PHY_MODE_AR2133 0x08 |
||||
#define AR9170_PHY_MODE_AR5111 0x00 |
||||
#define AR9170_PHY_MODE_AR5112 0x08 |
||||
#define AR9170_PHY_MODE_DYNAMIC 0x04 |
||||
#define AR9170_PHY_MODE_RF2GHZ 0x02 |
||||
#define AR9170_PHY_MODE_RF5GHZ 0x00 |
||||
#define AR9170_PHY_MODE_CCK 0x01 |
||||
#define AR9170_PHY_MODE_OFDM 0x00 |
||||
#define AR9170_PHY_MODE_DYN_CCK_DISABLE 0x100 |
||||
|
||||
#define AR9170_PHY_REG_CCK_TX_CTRL (AR9170_PHY_REG_BASE + 0x0a04) |
||||
#define AR9170_PHY_CCK_TX_CTRL_JAPAN 0x00000010 |
||||
#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000c |
||||
#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2 |
||||
|
||||
#define AR9170_PHY_REG_CCK_DETECT (AR9170_PHY_REG_BASE + 0x0a08) |
||||
#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003f |
||||
#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 |
||||
/* [12:6] settling time for antenna switch */ |
||||
#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001fc0 |
||||
#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 |
||||
#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 |
||||
#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13 |
||||
|
||||
#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c) |
||||
#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c) |
||||
#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000 |
||||
#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 |
||||
#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00 |
||||
#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN_S 10 |
||||
#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001f |
||||
#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN_S 0 |
||||
#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003e0000 |
||||
#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17 |
||||
#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001f000 |
||||
#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12 |
||||
#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000fc0 |
||||
#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB_S 6 |
||||
#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003f |
||||
#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB_S 0 |
||||
|
||||
#define AR9170_PHY_REG_CCK_RXCTRL4 (AR9170_PHY_REG_BASE + 0x0a1c) |
||||
#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01f80000 |
||||
#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19 |
||||
|
||||
#define AR9170_PHY_REG_DAG_CTRLCCK (AR9170_PHY_REG_BASE + 0x0a28) |
||||
#define AR9170_REG_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 |
||||
#define AR9170_REG_DAG_CTRLCCK_RSSI_THR 0x0001fc00 |
||||
#define AR9170_REG_DAG_CTRLCCK_RSSI_THR_S 10 |
||||
|
||||
#define AR9170_PHY_REG_FORCE_CLKEN_CCK (AR9170_PHY_REG_BASE + 0x0a2c) |
||||
#define AR9170_FORCE_CLKEN_CCK_MRC_MUX 0x00000040 |
||||
|
||||
#define AR9170_PHY_REG_POWER_TX_RATE3 (AR9170_PHY_REG_BASE + 0x0a34) |
||||
#define AR9170_PHY_REG_POWER_TX_RATE4 (AR9170_PHY_REG_BASE + 0x0a38) |
||||
|
||||
#define AR9170_PHY_REG_SCRM_SEQ_XR (AR9170_PHY_REG_BASE + 0x0a3c) |
||||
#define AR9170_PHY_REG_HEADER_DETECT_XR (AR9170_PHY_REG_BASE + 0x0a40) |
||||
#define AR9170_PHY_REG_CHIRP_DETECTED_XR (AR9170_PHY_REG_BASE + 0x0a44) |
||||
#define AR9170_PHY_REG_BLUETOOTH (AR9170_PHY_REG_BASE + 0x0a54) |
||||
|
||||
#define AR9170_PHY_REG_TPCRG1 (AR9170_PHY_REG_BASE + 0x0a58) |
||||
#define AR9170_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000 |
||||
#define AR9170_PHY_TPCRG1_NUM_PD_GAIN_S 14 |
||||
#define AR9170_PHY_TPCRG1_PD_GAIN_1 0x00030000 |
||||
#define AR9170_PHY_TPCRG1_PD_GAIN_1_S 16 |
||||
#define AR9170_PHY_TPCRG1_PD_GAIN_2 0x000c0000 |
||||
#define AR9170_PHY_TPCRG1_PD_GAIN_2_S 18 |
||||
#define AR9170_PHY_TPCRG1_PD_GAIN_3 0x00300000 |
||||
#define AR9170_PHY_TPCRG1_PD_GAIN_3_S 20 |
||||
#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000 |
||||
#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE_S 22 |
||||
|
||||
#define AR9170_PHY_REG_TX_PWRCTRL4 (AR9170_PHY_REG_BASE + 0x0a64) |
||||
#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001 |
||||
#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0 |
||||
#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001fe |
||||
#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1 |
||||
|
||||
#define AR9170_PHY_REG_ANALOG_SWAP (AR9170_PHY_REG_BASE + 0x0a68) |
||||
#define AR9170_PHY_ANALOG_SWAP_AB 0x0001 |
||||
#define AR9170_PHY_ANALOG_SWAP_ALT_CHAIN 0x00000040 |
||||
|
||||
#define AR9170_PHY_REG_TPCRG5 (AR9170_PHY_REG_BASE + 0x0a6c) |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000f |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003f0 |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000fc00 |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003f0000 |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0fc00000 |
||||
#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 |
||||
|
||||
#define AR9170_PHY_REG_TX_PWRCTRL6_0 (AR9170_PHY_REG_BASE + 0x0a70) |
||||
#define AR9170_PHY_REG_TX_PWRCTRL6_1 (AR9170_PHY_REG_BASE + 0x1a70) |
||||
#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000 |
||||
#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24 |
||||
|
||||
#define AR9170_PHY_REG_TX_PWRCTRL7 (AR9170_PHY_REG_BASE + 0x0a74) |
||||
#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01f80000 |
||||
#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 |
||||
|
||||
#define AR9170_PHY_REG_TX_PWRCTRL9 (AR9170_PHY_REG_BASE + 0x0a7c) |
||||
#define AR9170_PHY_TX_DESIRED_SCALE_CCK 0x00007c00 |
||||
#define AR9170_PHY_TX_DESIRED_SCALE_CCK_S 10 |
||||
#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 |
||||
#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31 |
||||
|
||||
#define AR9170_PHY_REG_TX_GAIN_TBL1 (AR9170_PHY_REG_BASE + 0x0b00) |
||||
#define AR9170_PHY_TX_GAIN 0x0007f000 |
||||
#define AR9170_PHY_TX_GAIN_S 12 |
||||
|
||||
/* Carrier leak calibration control, do it after AGC calibration */ |
||||
#define AR9170_PHY_REG_CL_CAL_CTL (AR9170_PHY_REG_BASE + 0x0b58) |
||||
#define AR9170_PHY_CL_CAL_ENABLE 0x00000002 |
||||
#define AR9170_PHY_CL_CAL_PARALLEL_CAL_ENABLE 0x00000001 |
||||
|
||||
#define AR9170_PHY_REG_POWER_TX_RATE5 (AR9170_PHY_REG_BASE + 0x0b8c) |
||||
#define AR9170_PHY_REG_POWER_TX_RATE6 (AR9170_PHY_REG_BASE + 0x0b90) |
||||
|
||||
#define AR9170_PHY_REG_CH0_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x0b98) |
||||
#define AR9170_PHY_REG_CH1_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x1b98) |
||||
#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP 0x0000fc00 |
||||
#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP_S 10 |
||||
|
||||
#define AR9170_PHY_REG_CAL_CHAINMASK (AR9170_PHY_REG_BASE + 0x0b9c) |
||||
#define AR9170_PHY_REG_VIT_MASK2_M_46_61 (AR9170_PHY_REG_BASE + 0x0ba0) |
||||
#define AR9170_PHY_REG_MASK2_M_31_45 (AR9170_PHY_REG_BASE + 0x0ba4) |
||||
#define AR9170_PHY_REG_MASK2_M_16_30 (AR9170_PHY_REG_BASE + 0x0ba8) |
||||
#define AR9170_PHY_REG_MASK2_M_00_15 (AR9170_PHY_REG_BASE + 0x0bac) |
||||
#define AR9170_PHY_REG_PILOT_MASK_01_30 (AR9170_PHY_REG_BASE + 0x0bb0) |
||||
#define AR9170_PHY_REG_PILOT_MASK_31_60 (AR9170_PHY_REG_BASE + 0x0bb4) |
||||
#define AR9170_PHY_REG_MASK2_P_15_01 (AR9170_PHY_REG_BASE + 0x0bb8) |
||||
#define AR9170_PHY_REG_MASK2_P_30_16 (AR9170_PHY_REG_BASE + 0x0bbc) |
||||
#define AR9170_PHY_REG_MASK2_P_45_31 (AR9170_PHY_REG_BASE + 0x0bc0) |
||||
#define AR9170_PHY_REG_MASK2_P_61_45 (AR9170_PHY_REG_BASE + 0x0bc4) |
||||
#define AR9170_PHY_REG_POWER_TX_SUB (AR9170_PHY_REG_BASE + 0x0bc8) |
||||
#define AR9170_PHY_REG_POWER_TX_RATE7 (AR9170_PHY_REG_BASE + 0x0bcc) |
||||
#define AR9170_PHY_REG_POWER_TX_RATE8 (AR9170_PHY_REG_BASE + 0x0bd0) |
||||
#define AR9170_PHY_REG_POWER_TX_RATE9 (AR9170_PHY_REG_BASE + 0x0bd4) |
||||
#define AR9170_PHY_REG_XPA_CFG (AR9170_PHY_REG_BASE + 0x0bd8) |
||||
#define AR9170_PHY_FORCE_XPA_CFG 0x000000001 |
||||
#define AR9170_PHY_FORCE_XPA_CFG_S 0 |
||||
|
||||
#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064) |
||||
#define AR9170_PHY_CH1_CCA_MIN_PWR 0x0ff80000 |
||||
#define AR9170_PHY_CH1_CCA_MIN_PWR_S 19 |
||||
|
||||
#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064) |
||||
#define AR9170_PHY_CH2_CCA_MIN_PWR 0x0ff80000 |
||||
#define AR9170_PHY_CH2_CCA_MIN_PWR_S 19 |
||||
|
||||
#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc) |
||||
#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR 0xff800000 |
||||
#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR_S 23 |
||||
|
||||
#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc) |
||||
#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR 0xff800000 |
||||
#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR_S 23 |
||||
|
||||
#endif /* __CARL9170_SHARED_PHY_H */ |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
#ifndef __CARL9170_SHARED_VERSION_H |
||||
#define __CARL9170_SHARED_VERSION_H |
||||
#define CARL9170FW_VERSION_YEAR 12 |
||||
#define CARL9170FW_VERSION_MONTH 7 |
||||
#define CARL9170FW_VERSION_DAY 7 |
||||
#define CARL9170FW_VERSION_GIT "1.9.6" |
||||
#endif /* __CARL9170_SHARED_VERSION_H */ |
@ -0,0 +1,435 @@
@@ -0,0 +1,435 @@
|
||||
/* |
||||
* Shared Atheros AR9170 Header |
||||
* |
||||
* RX/TX meta descriptor format |
||||
* |
||||
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net> |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
* |
||||
* 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; see the file COPYING. If not, see |
||||
* http://www.gnu.org/licenses/. |
||||
* |
||||
* This file incorporates work covered by the following copyright and |
||||
* permission notice: |
||||
* Copyright (c) 2007-2008 Atheros Communications, Inc. |
||||
* |
||||
* Permission to use, copy, modify, and/or distribute this software for any |
||||
* purpose with or without fee is hereby granted, provided that the above |
||||
* copyright notice and this permission notice appear in all copies. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170_SHARED_WLAN_H |
||||
#define __CARL9170_SHARED_WLAN_H |
||||
|
||||
#include "fwcmd.h" |
||||
|
||||
#define AR9170_RX_PHY_RATE_CCK_1M 0x0a |
||||
#define AR9170_RX_PHY_RATE_CCK_2M 0x14 |
||||
#define AR9170_RX_PHY_RATE_CCK_5M 0x37 |
||||
#define AR9170_RX_PHY_RATE_CCK_11M 0x6e |
||||
|
||||
#define AR9170_ENC_ALG_NONE 0x0 |
||||
#define AR9170_ENC_ALG_WEP64 0x1 |
||||
#define AR9170_ENC_ALG_TKIP 0x2 |
||||
#define AR9170_ENC_ALG_AESCCMP 0x4 |
||||
#define AR9170_ENC_ALG_WEP128 0x5 |
||||
#define AR9170_ENC_ALG_WEP256 0x6 |
||||
#define AR9170_ENC_ALG_CENC 0x7 |
||||
|
||||
#define AR9170_RX_ENC_SOFTWARE 0x8 |
||||
|
||||
#define AR9170_RX_STATUS_MODULATION 0x03 |
||||
#define AR9170_RX_STATUS_MODULATION_S 0 |
||||
#define AR9170_RX_STATUS_MODULATION_CCK 0x00 |
||||
#define AR9170_RX_STATUS_MODULATION_OFDM 0x01 |
||||
#define AR9170_RX_STATUS_MODULATION_HT 0x02 |
||||
#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03 |
||||
|
||||
/* depends on modulation */ |
||||
#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08 |
||||
#define AR9170_RX_STATUS_GREENFIELD 0x08 |
||||
|
||||
#define AR9170_RX_STATUS_MPDU 0x30 |
||||
#define AR9170_RX_STATUS_MPDU_S 4 |
||||
#define AR9170_RX_STATUS_MPDU_SINGLE 0x00 |
||||
#define AR9170_RX_STATUS_MPDU_FIRST 0x20 |
||||
#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 |
||||
#define AR9170_RX_STATUS_MPDU_LAST 0x10 |
||||
|
||||
#define AR9170_RX_STATUS_CONT_AGGR 0x40 |
||||
#define AR9170_RX_STATUS_TOTAL_ERROR 0x80 |
||||
|
||||
#define AR9170_RX_ERROR_RXTO 0x01 |
||||
#define AR9170_RX_ERROR_OVERRUN 0x02 |
||||
#define AR9170_RX_ERROR_DECRYPT 0x04 |
||||
#define AR9170_RX_ERROR_FCS 0x08 |
||||
#define AR9170_RX_ERROR_WRONG_RA 0x10 |
||||
#define AR9170_RX_ERROR_PLCP 0x20 |
||||
#define AR9170_RX_ERROR_MMIC 0x40 |
||||
|
||||
/* these are either-or */ |
||||
#define AR9170_TX_MAC_PROT_RTS 0x0001 |
||||
#define AR9170_TX_MAC_PROT_CTS 0x0002 |
||||
#define AR9170_TX_MAC_PROT 0x0003 |
||||
|
||||
#define AR9170_TX_MAC_NO_ACK 0x0004 |
||||
/* if unset, MAC will only do SIFS space before frame */ |
||||
#define AR9170_TX_MAC_BACKOFF 0x0008 |
||||
#define AR9170_TX_MAC_BURST 0x0010 |
||||
#define AR9170_TX_MAC_AGGR 0x0020 |
||||
|
||||
/* encryption is a two-bit field */ |
||||
#define AR9170_TX_MAC_ENCR_NONE 0x0000 |
||||
#define AR9170_TX_MAC_ENCR_RC4 0x0040 |
||||
#define AR9170_TX_MAC_ENCR_CENC 0x0080 |
||||
#define AR9170_TX_MAC_ENCR_AES 0x00c0 |
||||
|
||||
#define AR9170_TX_MAC_MMIC 0x0100 |
||||
#define AR9170_TX_MAC_HW_DURATION 0x0200 |
||||
#define AR9170_TX_MAC_QOS_S 10 |
||||
#define AR9170_TX_MAC_QOS 0x0c00 |
||||
#define AR9170_TX_MAC_DISABLE_TXOP 0x1000 |
||||
#define AR9170_TX_MAC_TXOP_RIFS 0x2000 |
||||
#define AR9170_TX_MAC_IMM_BA 0x4000 |
||||
|
||||
/* either-or */ |
||||
#define AR9170_TX_PHY_MOD_CCK 0x00000000 |
||||
#define AR9170_TX_PHY_MOD_OFDM 0x00000001 |
||||
#define AR9170_TX_PHY_MOD_HT 0x00000002 |
||||
|
||||
/* depends on modulation */ |
||||
#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004 |
||||
#define AR9170_TX_PHY_GREENFIELD 0x00000004 |
||||
|
||||
#define AR9170_TX_PHY_BW_S 3 |
||||
#define AR9170_TX_PHY_BW (3 << AR9170_TX_PHY_BW_SHIFT) |
||||
#define AR9170_TX_PHY_BW_20MHZ 0 |
||||
#define AR9170_TX_PHY_BW_40MHZ 2 |
||||
#define AR9170_TX_PHY_BW_40MHZ_DUP 3 |
||||
|
||||
#define AR9170_TX_PHY_TX_HEAVY_CLIP_S 6 |
||||
#define AR9170_TX_PHY_TX_HEAVY_CLIP (7 << \ |
||||
AR9170_TX_PHY_TX_HEAVY_CLIP_S) |
||||
|
||||
#define AR9170_TX_PHY_TX_PWR_S 9 |
||||
#define AR9170_TX_PHY_TX_PWR (0x3f << \ |
||||
AR9170_TX_PHY_TX_PWR_S) |
||||
|
||||
#define AR9170_TX_PHY_TXCHAIN_S 15 |
||||
#define AR9170_TX_PHY_TXCHAIN (7 << \ |
||||
AR9170_TX_PHY_TXCHAIN_S) |
||||
#define AR9170_TX_PHY_TXCHAIN_1 1 |
||||
/* use for cck, ofdm 6/9/12/18/24 and HT if capable */ |
||||
#define AR9170_TX_PHY_TXCHAIN_2 5 |
||||
|
||||
#define AR9170_TX_PHY_MCS_S 18 |
||||
#define AR9170_TX_PHY_MCS (0x7f << \ |
||||
AR9170_TX_PHY_MCS_S) |
||||
|
||||
#define AR9170_TX_PHY_RATE_CCK_1M 0x0 |
||||
#define AR9170_TX_PHY_RATE_CCK_2M 0x1 |
||||
#define AR9170_TX_PHY_RATE_CCK_5M 0x2 |
||||
#define AR9170_TX_PHY_RATE_CCK_11M 0x3 |
||||
|
||||
/* same as AR9170_RX_PHY_RATE */ |
||||
#define AR9170_TXRX_PHY_RATE_OFDM_6M 0xb |
||||
#define AR9170_TXRX_PHY_RATE_OFDM_9M 0xf |
||||
#define AR9170_TXRX_PHY_RATE_OFDM_12M 0xa |
||||
#define AR9170_TXRX_PHY_RATE_OFDM_18M 0xe |
||||
#define AR9170_TXRX_PHY_RATE_OFDM_24M 0x9 |
||||
#define AR9170_TXRX_PHY_RATE_OFDM_36M 0xd |
||||
#define AR9170_TXRX_PHY_RATE_OFDM_48M 0x8 |
||||
#define AR9170_TXRX_PHY_RATE_OFDM_54M 0xc |
||||
|
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS0 0x0 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS1 0x1 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS2 0x2 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS3 0x3 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS4 0x4 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS5 0x5 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS6 0x6 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS7 0x7 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS8 0x8 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS9 0x9 |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS10 0xa |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS11 0xb |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS12 0xc |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS13 0xd |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS14 0xe |
||||
#define AR9170_TXRX_PHY_RATE_HT_MCS15 0xf |
||||
|
||||
#define AR9170_TX_PHY_SHORT_GI 0x80000000 |
||||
|
||||
#ifdef __CARL9170FW__ |
||||
struct ar9170_tx_hw_mac_control { |
||||
union { |
||||
struct { |
||||
/* |
||||
* Beware of compiler bugs in all gcc pre 4.4! |
||||
*/ |
||||
|
||||
u8 erp_prot:2; |
||||
u8 no_ack:1; |
||||
u8 backoff:1; |
||||
u8 burst:1; |
||||
u8 ampdu:1; |
||||
|
||||
u8 enc_mode:2; |
||||
|
||||
u8 hw_mmic:1; |
||||
u8 hw_duration:1; |
||||
|
||||
u8 qos_queue:2; |
||||
|
||||
u8 disable_txop:1; |
||||
u8 txop_rifs:1; |
||||
|
||||
u8 ba_end:1; |
||||
u8 probe:1; |
||||
} __packed; |
||||
|
||||
__le16 set; |
||||
} __packed; |
||||
} __packed; |
||||
|
||||
struct ar9170_tx_hw_phy_control { |
||||
union { |
||||
struct { |
||||
/* |
||||
* Beware of compiler bugs in all gcc pre 4.4! |
||||
*/ |
||||
|
||||
u8 modulation:2; |
||||
u8 preamble:1; |
||||
u8 bandwidth:2; |
||||
u8:1; |
||||
u8 heavy_clip:3; |
||||
u8 tx_power:6; |
||||
u8 chains:3; |
||||
u8 mcs:7; |
||||
u8:6; |
||||
u8 short_gi:1; |
||||
} __packed; |
||||
|
||||
__le32 set; |
||||
} __packed; |
||||
} __packed; |
||||
|
||||
struct ar9170_tx_rate_info { |
||||
u8 tries:3; |
||||
u8 erp_prot:2; |
||||
u8 ampdu:1; |
||||
u8 free:2; /* free for use (e.g.:RIFS/TXOP/AMPDU) */ |
||||
} __packed; |
||||
|
||||
struct carl9170_tx_superdesc { |
||||
__le16 len; |
||||
u8 rix; |
||||
u8 cnt; |
||||
u8 cookie; |
||||
u8 ampdu_density:3; |
||||
u8 ampdu_factor:2; |
||||
u8 ampdu_commit_density:1; |
||||
u8 ampdu_commit_factor:1; |
||||
u8 ampdu_unused_bit:1; |
||||
u8 queue:2; |
||||
u8 assign_seq:1; |
||||
u8 vif_id:3; |
||||
u8 fill_in_tsf:1; |
||||
u8 cab:1; |
||||
u8 padding2; |
||||
struct ar9170_tx_rate_info ri[CARL9170_TX_MAX_RATES]; |
||||
struct ar9170_tx_hw_phy_control rr[CARL9170_TX_MAX_RETRY_RATES]; |
||||
} __packed; |
||||
|
||||
struct ar9170_tx_hwdesc { |
||||
__le16 length; |
||||
struct ar9170_tx_hw_mac_control mac; |
||||
struct ar9170_tx_hw_phy_control phy; |
||||
} __packed; |
||||
|
||||
struct ar9170_tx_frame { |
||||
struct ar9170_tx_hwdesc hdr; |
||||
|
||||
union { |
||||
struct ieee80211_hdr i3e; |
||||
u8 payload[0]; |
||||
} data; |
||||
} __packed; |
||||
|
||||
struct carl9170_tx_superframe { |
||||
struct carl9170_tx_superdesc s; |
||||
struct ar9170_tx_frame f; |
||||
} __packed __aligned(4); |
||||
|
||||
#endif /* __CARL9170FW__ */ |
||||
|
||||
struct _ar9170_tx_hwdesc { |
||||
__le16 length; |
||||
__le16 mac_control; |
||||
__le32 phy_control; |
||||
} __packed; |
||||
|
||||
#define CARL9170_TX_SUPER_AMPDU_DENSITY_S 0 |
||||
#define CARL9170_TX_SUPER_AMPDU_DENSITY 0x7 |
||||
#define CARL9170_TX_SUPER_AMPDU_FACTOR 0x18 |
||||
#define CARL9170_TX_SUPER_AMPDU_FACTOR_S 3 |
||||
#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY 0x20 |
||||
#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY_S 5 |
||||
#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR 0x40 |
||||
#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR_S 6 |
||||
|
||||
#define CARL9170_TX_SUPER_MISC_QUEUE 0x3 |
||||
#define CARL9170_TX_SUPER_MISC_QUEUE_S 0 |
||||
#define CARL9170_TX_SUPER_MISC_ASSIGN_SEQ 0x4 |
||||
#define CARL9170_TX_SUPER_MISC_VIF_ID 0x38 |
||||
#define CARL9170_TX_SUPER_MISC_VIF_ID_S 3 |
||||
#define CARL9170_TX_SUPER_MISC_FILL_IN_TSF 0x40 |
||||
#define CARL9170_TX_SUPER_MISC_CAB 0x80 |
||||
|
||||
#define CARL9170_TX_SUPER_RI_TRIES 0x7 |
||||
#define CARL9170_TX_SUPER_RI_TRIES_S 0 |
||||
#define CARL9170_TX_SUPER_RI_ERP_PROT 0x18 |
||||
#define CARL9170_TX_SUPER_RI_ERP_PROT_S 3 |
||||
#define CARL9170_TX_SUPER_RI_AMPDU 0x20 |
||||
#define CARL9170_TX_SUPER_RI_AMPDU_S 5 |
||||
|
||||
struct _carl9170_tx_superdesc { |
||||
__le16 len; |
||||
u8 rix; |
||||
u8 cnt; |
||||
u8 cookie; |
||||
u8 ampdu_settings; |
||||
u8 misc; |
||||
u8 padding; |
||||
u8 ri[CARL9170_TX_MAX_RATES]; |
||||
__le32 rr[CARL9170_TX_MAX_RETRY_RATES]; |
||||
} __packed; |
||||
|
||||
struct _carl9170_tx_superframe { |
||||
struct _carl9170_tx_superdesc s; |
||||
struct _ar9170_tx_hwdesc f; |
||||
u8 frame_data[0]; |
||||
} __packed __aligned(4); |
||||
|
||||
#define CARL9170_TX_SUPERDESC_LEN 24 |
||||
#define AR9170_TX_HWDESC_LEN 8 |
||||
#define CARL9170_TX_SUPERFRAME_LEN (CARL9170_TX_SUPERDESC_LEN + \ |
||||
AR9170_TX_HWDESC_LEN) |
||||
|
||||
struct ar9170_rx_head { |
||||
u8 plcp[12]; |
||||
} __packed; |
||||
|
||||
#define AR9170_RX_HEAD_LEN 12 |
||||
|
||||
struct ar9170_rx_phystatus { |
||||
union { |
||||
struct { |
||||
u8 rssi_ant0, rssi_ant1, rssi_ant2, |
||||
rssi_ant0x, rssi_ant1x, rssi_ant2x, |
||||
rssi_combined; |
||||
} __packed; |
||||
u8 rssi[7]; |
||||
} __packed; |
||||
|
||||
u8 evm_stream0[6], evm_stream1[6]; |
||||
u8 phy_err; |
||||
} __packed; |
||||
|
||||
#define AR9170_RX_PHYSTATUS_LEN 20 |
||||
|
||||
struct ar9170_rx_macstatus { |
||||
u8 SAidx, DAidx; |
||||
u8 error; |
||||
u8 status; |
||||
} __packed; |
||||
|
||||
#define AR9170_RX_MACSTATUS_LEN 4 |
||||
|
||||
struct ar9170_rx_frame_single { |
||||
struct ar9170_rx_head phy_head; |
||||
struct ieee80211_hdr i3e; |
||||
struct ar9170_rx_phystatus phy_tail; |
||||
struct ar9170_rx_macstatus macstatus; |
||||
} __packed; |
||||
|
||||
struct ar9170_rx_frame_head { |
||||
struct ar9170_rx_head phy_head; |
||||
struct ieee80211_hdr i3e; |
||||
struct ar9170_rx_macstatus macstatus; |
||||
} __packed; |
||||
|
||||
struct ar9170_rx_frame_middle { |
||||
struct ieee80211_hdr i3e; |
||||
struct ar9170_rx_macstatus macstatus; |
||||
} __packed; |
||||
|
||||
struct ar9170_rx_frame_tail { |
||||
struct ieee80211_hdr i3e; |
||||
struct ar9170_rx_phystatus phy_tail; |
||||
struct ar9170_rx_macstatus macstatus; |
||||
} __packed; |
||||
|
||||
struct ar9170_rx_frame { |
||||
union { |
||||
struct ar9170_rx_frame_single single; |
||||
struct ar9170_rx_frame_head head; |
||||
struct ar9170_rx_frame_middle middle; |
||||
struct ar9170_rx_frame_tail tail; |
||||
} __packed; |
||||
} __packed; |
||||
|
||||
static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) |
||||
{ |
||||
return (t->SAidx & 0xc0) >> 4 | |
||||
(t->DAidx & 0xc0) >> 6; |
||||
} |
||||
|
||||
/* |
||||
* This is an workaround for several undocumented bugs. |
||||
* Don't mess with the QoS/AC <-> HW Queue map, if you don't |
||||
* know what you are doing. |
||||
* |
||||
* Known problems [hardware]: |
||||
* * The MAC does not aggregate frames on anything other |
||||
* than the first HW queue. |
||||
* * when an AMPDU is placed [in the first hw queue] and |
||||
* additional frames are already queued on a different |
||||
* hw queue, the MAC will ALWAYS freeze. |
||||
* |
||||
* In a nutshell: The hardware can either do QoS or |
||||
* Aggregation but not both at the same time. As a |
||||
* result, this makes the device pretty much useless |
||||
* for any serious 802.11n setup. |
||||
*/ |
||||
enum ar9170_txq { |
||||
AR9170_TXQ_BK = 0, /* TXQ0 */ |
||||
AR9170_TXQ_BE, /* TXQ1 */ |
||||
AR9170_TXQ_VI, /* TXQ2 */ |
||||
AR9170_TXQ_VO, /* TXQ3 */ |
||||
|
||||
__AR9170_NUM_TXQ, |
||||
}; |
||||
|
||||
#define AR9170_TXQ_DEPTH 32 |
||||
|
||||
#endif /* __CARL9170_SHARED_WLAN_H */ |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 2.8) |
||||
|
||||
project(miniboot.fw) |
||||
|
||||
include("../extra/sh-elf-linux.cmake") |
||||
include("../config.cmake") |
||||
|
||||
set(miniboot_src miniboot.S) |
||||
set_source_files_properties(miniboot.S PROPERTIES LANGUAGE C) |
||||
|
||||
add_executable(miniboot.elf miniboot.S) |
||||
|
||||
set_target_properties(miniboot.elf PROPERTIES LINKER_LANGUAGE C) |
||||
|
||||
set_target_properties(miniboot.elf PROPERTIES LINK_FLAGS "-Tminiboot.lds") |
||||
|
||||
add_custom_target( |
||||
miniboot.fw ALL |
||||
${OBJCOPY} --strip-unneeded -O binary -R .sram -R .eeprom -R .fwdsc miniboot.elf miniboot.fw |
||||
DEPENDS miniboot.elf) |
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
config CARL9170FW_BUILD_MINIBOOT |
||||
def_bool y |
||||
prompt "Build MiniBoot Firmware Header" |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
.globl _start |
||||
.type _start, @function |
||||
.section ".boot", "ax" |
||||
_start: |
||||
mov.l startcode, r0 |
||||
jmp @r0 |
||||
startcode: .long 0x00000008 |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
ENTRY(_start); |
||||
|
||||
MEMORY |
||||
{ |
||||
pram : ORIGIN = 0x200000, LENGTH = 16k |
||||
} |
||||
|
||||
SECTIONS |
||||
{ |
||||
.padding : { |
||||
/* NOP NOP just in case */ |
||||
LONG(0x00090009) |
||||
} > pram |
||||
|
||||
.boot : { *(.boot) } > pram |
||||
.text : { *(.text*) } > pram |
||||
.rodata : { *(.rodata*) } > pram |
||||
.bss : { *(.bss) } > pram |
||||
.data : { *(.data*) } > pram |
||||
} |
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
BINUTILS_VER=2.22 |
||||
BINUTILS_URL=http://mirrors.kernel.org/gnu/binutils/binutils-$(BINUTILS_VER).tar.bz2 |
||||
BINUTILS_TAR=binutils-$(BINUTILS_VER).tar.bz2 |
||||
|
||||
NEWLIB_VER=1.20.0 |
||||
NEWLIB_URL=ftp://sources.redhat.com/pub/newlib/newlib-$(NEWLIB_VER).tar.gz |
||||
NEWLIB_TAR=newlib-$(NEWLIB_VER).tar.gz |
||||
|
||||
GCC_VER=4.7.1 |
||||
GCC_URL=http://mirrors.kernel.org/gnu/gcc/gcc-$(GCC_VER)/gcc-$(GCC_VER).tar.bz2 |
||||
GCC_TAR=gcc-$(GCC_VER).tar.bz2 |
||||
|
||||
BASEDIR=$(shell pwd) |
||||
|
||||
all: gcc |
||||
|
||||
src/$(BINUTILS_TAR): |
||||
wget -P src $(BINUTILS_URL) |
||||
|
||||
src/$(NEWLIB_TAR): |
||||
wget -P src $(NEWLIB_URL) |
||||
|
||||
src/$(GCC_TAR): |
||||
wget -P src $(GCC_URL) |
||||
|
||||
src/binutils-$(BINUTILS_VER): src/$(BINUTILS_TAR) |
||||
tar -C src -xjf $< |
||||
|
||||
src/newlib-$(NEWLIB_VER): src/$(NEWLIB_TAR) |
||||
tar -C src -xzf $< |
||||
|
||||
src/gcc-$(GCC_VER): src/$(GCC_TAR) src/newlib-$(NEWLIB_VER) |
||||
tar -C src -xjf $< |
||||
ln -s $(BASEDIR)/src/newlib-$(NEWLIB_VER)/newlib $@ |
||||
ln -s $(BASEDIR)/src/newlib-$(NEWLIB_VER)/libgloss $@ |
||||
|
||||
binutils: src/binutils-$(BINUTILS_VER) |
||||
mkdir -p build/binutils |
||||
cd build/binutils; \ |
||||
$(BASEDIR)/$</configure --target=sh-elf --prefix=$(BASEDIR)/inst; \ |
||||
$(MAKE) -j3; \ |
||||
$(MAKE) install |
||||
|
||||
gcc: src/gcc-$(GCC_VER) binutils |
||||
mkdir -p build/gcc |
||||
cd build/gcc; \ |
||||
$(BASEDIR)/$</configure --target=sh-elf --prefix=$(BASEDIR)/inst -enable-languages=c --without-pkgversion --with-newlib; \ |
||||
$(MAKE) -j3; \ |
||||
$(MAKE) install |
||||
|
||||
clean: |
||||
rm -rf build inst |
||||
|
||||
distclean: clean |
||||
rm -rf src |
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
cmake_minimum_required(VERSION 2.8) |
||||
|
||||
project(tools) |
||||
|
||||
if (CONFIG_CARL9170FW_MAKE_RELEASE) |
||||
set(CMAKE_BUILD_TYPE Release) |
||||
endif (CONFIG_CARL9170FW_MAKE_RELEASE) |
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/extra) |
||||
|
||||
include(GCCVersion) |
||||
include("../config.cmake") |
||||
|
||||
_COMPILER_DUMPVERSION(_COMPILER_VERSION) |
||||
|
||||
if (("${_COMPILER_VERSION}" VERSION_GREATER 44) OR |
||||
("${_COMPILER_VERSION}" VERSION_EQUAL 44)) |
||||
|
||||
include_directories (../include/linux ../include/shared ../include lib include) |
||||
add_subdirectory(lib) |
||||
add_subdirectory(src) |
||||
|
||||
if (CONFIG_CARL9170FW_BUILD_TOOLS_CARLU) |
||||
find_package(SDL QUIET) |
||||
find_package(USB-1.0 QUIET) |
||||
|
||||
if ("${USB-1.0_FOUND}" AND "${SDL_FOUND}") |
||||
add_subdirectory(carlu) |
||||
else() |
||||
if ("${USB-1.0_FOUND}") |
||||
MESSAGE(ERROR "LibUSB not found\n") |
||||
endif ("${USB-1.0_FOUND}") |
||||
if ("${SDL_FOUND}") |
||||
MESSAGE(ERROR "SDL not found\n") |
||||
endif ("${SDL_FOUND}") |
||||
endif () |
||||
endif (CONFIG_CARL9170FW_BUILD_TOOLS_CARLU) |
||||
endif () |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
menu "Firmware Tools" |
||||
|
||||
config CARL9170FW_BUILD_TOOLS |
||||
def_bool y |
||||
prompt "Build Firmware Tools" |
||||
|
||||
config CARL9170FW_BUILD_TOOLS_CARLU |
||||
def_bool n |
||||
prompt "Build CARLU testbench" |
||||
depends on CARL9170FW_BUILD_TOOLS |
||||
|
||||
endmenu |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
cmake_minimum_required(VERSION 2.8) |
||||
|
||||
project(carlu) |
||||
|
||||
find_package(SDL REQUIRED) |
||||
find_package(USB-1.0 REQUIRED) |
||||
|
||||
set(carlu_src src/debug.c src/cmd.c src/usb.c src/rx.c src/tx.c src/fw.c |
||||
src/test.c src/main.c) |
||||
|
||||
add_definitions(-D_GNU_SOURCE ${USB-1.0_DEFINITIONS}) |
||||
add_definitions(-DCARLU_PATH="${CMAKE_CURRENT_SOURCE_DIR}") |
||||
|
||||
include_directories(${SDL_INCLUDE_DIR} ${USB-1.0_INCLUDE_DIRS}) |
||||
|
||||
add_executable(carlu ${carlu_src}) |
||||
|
||||
target_link_libraries (carlu ${SDL_LIBRARY} ${USB-1.0_LIBRARIES} SDLmain carlfw) |
@ -0,0 +1,147 @@
@@ -0,0 +1,147 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* common API declaration |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170USER_H |
||||
#define __CARL9170USER_H |
||||
|
||||
#include "SDL.h" |
||||
#include "SDL_thread.h" |
||||
|
||||
#include "carlfw.h" |
||||
|
||||
#include "debug.h" |
||||
#include "hw.h" |
||||
#include "fwcmd.h" |
||||
#include "frame.h" |
||||
#include "eeprom.h" |
||||
#include "ieee80211.h" |
||||
#include "wlan.h" |
||||
#include "usb.h" |
||||
|
||||
struct carlu { |
||||
libusb_device_handle *dev; |
||||
libusb_context *ctx; |
||||
|
||||
SDL_Thread *event_thread; |
||||
bool stop_event_polling; |
||||
|
||||
struct libusb_transfer *rx_ring[AR9170_RX_BULK_BUFS]; |
||||
|
||||
struct libusb_transfer *rx_interrupt; |
||||
unsigned char irq_buf[AR9170_RX_BULK_IRQ_SIZE]; |
||||
|
||||
union { |
||||
unsigned char buf[CARL9170_MAX_CMD_LEN]; |
||||
uint32_t buf4[CARL9170_MAX_CMD_LEN / sizeof(uint32_t)]; |
||||
struct carl9170_cmd cmd; |
||||
struct carl9170_rsp rsp; |
||||
} cmd; |
||||
|
||||
struct list_head tx_queue; |
||||
SDL_mutex *tx_queue_lock; |
||||
unsigned int tx_queue_len; |
||||
|
||||
struct list_head dev_list; |
||||
unsigned int idx; |
||||
|
||||
unsigned int miniboot_size; |
||||
unsigned int rx_max; |
||||
|
||||
int event_pipe[2]; |
||||
|
||||
SDL_cond *resp_pend; |
||||
SDL_mutex *resp_lock; |
||||
uint8_t *resp_buf; |
||||
size_t resp_len; |
||||
|
||||
int tx_pending; |
||||
uint8_t cookie; |
||||
|
||||
void (*tx_cb)(struct carlu *, struct frame *); |
||||
void (*tx_fb_cb)(struct carlu *, struct frame *); |
||||
void (*rx_cb)(struct carlu *, void *, unsigned int); |
||||
int (*cmd_cb)(struct carlu *, struct carl9170_rsp *, |
||||
void *, unsigned int); |
||||
|
||||
struct carlfw *fw; |
||||
|
||||
struct ar9170_eeprom eeprom; |
||||
|
||||
struct frame_queue tx_sent_queue[__AR9170_NUM_TXQ]; |
||||
|
||||
SDL_mutex *mem_lock; |
||||
unsigned int dma_chunks; |
||||
unsigned int dma_chunk_size; |
||||
unsigned int used_dma_chunks; |
||||
|
||||
unsigned int extra_headroom; |
||||
bool tx_stream; |
||||
bool rx_stream; |
||||
|
||||
/* statistics */ |
||||
unsigned int rxed; |
||||
unsigned int txed; |
||||
|
||||
unsigned long tx_octets; |
||||
unsigned long rx_octets; |
||||
}; |
||||
|
||||
struct carlu_rate { |
||||
int8_t rix; |
||||
int8_t cnt; |
||||
uint8_t flags; |
||||
}; |
||||
|
||||
struct carlu_tx_info_tx { |
||||
unsigned int key; |
||||
}; |
||||
|
||||
struct carlu_tx_info { |
||||
uint32_t flags; |
||||
|
||||
struct carlu_rate rates[CARL9170_TX_MAX_RATES]; |
||||
|
||||
union { |
||||
struct carlu_tx_info_tx tx; |
||||
}; |
||||
}; |
||||
|
||||
static inline struct carlu_tx_info *get_tx_info(struct frame *frame) |
||||
{ |
||||
return (void *) frame->cb; |
||||
} |
||||
|
||||
void *carlu_alloc_driver(size_t size); |
||||
void carlu_free_driver(struct carlu *ar); |
||||
|
||||
int carlu_fw_check(struct carlu *ar); |
||||
void carlu_fw_info(struct carlu *ar); |
||||
|
||||
void carlu_rx(struct carlu *ar, struct frame *frame); |
||||
int carlu_tx(struct carlu *ar, struct frame *frame); |
||||
void carlu_tx_feedback(struct carlu *ar, |
||||
struct carl9170_rsp *cmd); |
||||
void carlu_handle_command(struct carlu *ar, void *buf, unsigned int len); |
||||
|
||||
struct frame *carlu_alloc_frame(struct carlu *ar, unsigned int size); |
||||
void carlu_free_frame(struct carlu *ar, struct frame *frame); |
||||
#endif /* __CARL9170USER_H */ |
@ -0,0 +1,189 @@
@@ -0,0 +1,189 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* Abstraction Layer for FW/HW command interface |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
#include <config.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdbool.h> |
||||
#include <stdlib.h> |
||||
#include <errno.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include "libusb.h" |
||||
#include <sys/types.h> |
||||
#include <sys/stat.h> |
||||
#include <unistd.h> |
||||
|
||||
#include "carlu.h" |
||||
#include "usb.h" |
||||
#include "debug.h" |
||||
#include "fwcmd.h" |
||||
#include "eeprom.h" |
||||
#include "cmd.h" |
||||
|
||||
int carlu_cmd_echo(struct carlu *ar, const uint32_t message) |
||||
{ |
||||
uint32_t _message; |
||||
int ret; |
||||
|
||||
ret = carlusb_cmd(ar, CARL9170_CMD_ECHO, |
||||
(uint8_t *)&message, sizeof(message), |
||||
(uint8_t *)&_message, sizeof(_message)); |
||||
|
||||
if (ret == 0) |
||||
ret = (message == _message) ? 0 : -EIO; |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
struct carl9170_cmd *carlu_cmd_buf(struct carlu *ar, |
||||
const enum carl9170_cmd_oids cmd, const unsigned int len) |
||||
{ |
||||
struct carl9170_cmd *tmp; |
||||
|
||||
if (len % 4 || (sizeof(struct carl9170_cmd_head) + len > 64)) |
||||
return ERR_PTR(-EINVAL); |
||||
|
||||
tmp = malloc(sizeof(struct carl9170_cmd_head) + len); |
||||
if (tmp) { |
||||
tmp->hdr.cmd = cmd; |
||||
tmp->hdr.len = len; |
||||
} |
||||
return tmp; |
||||
} |
||||
|
||||
int carlu_cmd_reboot(struct carlu *ar) |
||||
{ |
||||
struct carl9170_cmd *reboot; |
||||
int err; |
||||
|
||||
/* sure, we could put the struct on the stack too. */ |
||||
reboot = carlu_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0); |
||||
if (IS_ERR_OR_NULL(reboot)) |
||||
return reboot ? PTR_ERR(reboot) : -ENOMEM; |
||||
|
||||
err = carlusb_cmd_async(ar, reboot, true); |
||||
return err; |
||||
} |
||||
|
||||
int carlu_cmd_mem_dump(struct carlu *ar, const uint32_t start, |
||||
const unsigned int len, void *_buf) |
||||
{ |
||||
#define RW 8 /* number of words to read at once */ |
||||
#define RB (sizeof(uint32_t) * RW) |
||||
uint8_t *buf = _buf; |
||||
unsigned int i, j, block; |
||||
int err; |
||||
__le32 offsets[RW]; |
||||
|
||||
for (i = 0; i < (len + RB - 1) / RB; i++) { |
||||
block = min_t(unsigned int, (len - RB * i) / sizeof(uint32_t), RW); |
||||
for (j = 0; j < block; j++) |
||||
offsets[j] = cpu_to_le32(start + RB * i + 4 * j); |
||||
|
||||
err = carlusb_cmd(ar, CARL9170_CMD_RREG, |
||||
(void *) &offsets, block * sizeof(uint32_t), |
||||
(void *) buf + RB * i, RB); |
||||
|
||||
if (err) |
||||
return err; |
||||
} |
||||
|
||||
#undef RW |
||||
#undef RB |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int carlu_cmd_mem_watch(struct carlu *ar, const uint32_t mem, |
||||
const unsigned int len, void *_buf) |
||||
{ |
||||
#define RW 8 /* number of words to read at once */ |
||||
#define RB (sizeof(uint32_t) * RW) |
||||
uint8_t *buf = _buf; |
||||
unsigned int i, j, block; |
||||
int err; |
||||
__le32 offsets[RW]; |
||||
|
||||
for (i = 0; i < (len + RB - 1) / RB; i++) { |
||||
block = min_t(unsigned int, (len - RB * i) / sizeof(uint32_t), RW); |
||||
for (j = 0; j < block; j++) |
||||
offsets[j] = cpu_to_le32(mem); |
||||
|
||||
err = carlusb_cmd(ar, CARL9170_CMD_RREG, |
||||
(void *) &offsets, block * sizeof(uint32_t), |
||||
(void *) buf + RB * i, RB); |
||||
|
||||
if (err) |
||||
return err; |
||||
} |
||||
|
||||
#undef RW |
||||
#undef RB |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int carlu_cmd_write_mem(struct carlu *ar, const uint32_t addr, |
||||
const uint32_t val) |
||||
{ |
||||
int err; |
||||
__le32 msg, block[2] = { cpu_to_le32(addr), cpu_to_le32(val) }; |
||||
|
||||
err = carlusb_cmd(ar, CARL9170_CMD_WREG, |
||||
(void *) &block, sizeof(block), |
||||
(void *) &msg, sizeof(msg)); |
||||
return err; |
||||
} |
||||
|
||||
int carlu_cmd_read_mem(struct carlu *ar, const uint32_t _addr, |
||||
uint32_t *val) |
||||
{ |
||||
int err; |
||||
__le32 msg, addr = { cpu_to_le32(_addr) }; |
||||
err = carlusb_cmd(ar, CARL9170_CMD_RREG, (void *) &addr, sizeof(addr), |
||||
(void *) &msg, sizeof(msg)); |
||||
|
||||
*val = le32_to_cpu(msg); |
||||
return err; |
||||
} |
||||
|
||||
int carlu_cmd_read_eeprom(struct carlu *ar) |
||||
{ |
||||
|
||||
int err; |
||||
|
||||
err = carlu_cmd_mem_dump(ar, AR9170_EEPROM_START, sizeof(ar->eeprom), |
||||
&ar->eeprom); |
||||
|
||||
#ifndef __CHECKER__ |
||||
/* don't want to handle trailing remains */ |
||||
BUILD_BUG_ON(sizeof(ar->eeprom) % 8); |
||||
#endif |
||||
|
||||
if (ar->eeprom.length == cpu_to_le16(0xffff)) |
||||
return -ENODATA; |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,135 @@
@@ -0,0 +1,135 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* register/memory/command access functions |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170USER_CMD_H |
||||
#define __CARL9170USER_CMD_H |
||||
|
||||
#include "carlu.h" |
||||
|
||||
int carlu_cmd_echo(struct carlu *ar, const uint32_t message); |
||||
int carlu_cmd_reboot(struct carlu *ar); |
||||
int carlu_cmd_read_eeprom(struct carlu *ar); |
||||
int carlu_cmd_mem_dump(struct carlu *ar, const uint32_t start, |
||||
const unsigned int len, void *_buf); |
||||
int carlu_cmd_write_mem(struct carlu *ar, const uint32_t addr, |
||||
const uint32_t val); |
||||
int carlu_cmd_mem_watch(struct carlu *ar, const uint32_t mem, |
||||
const unsigned int len, void *_buf); |
||||
|
||||
struct carl9170_cmd *carlu_cmd_buf(struct carlu *ar, |
||||
const enum carl9170_cmd_oids cmd, const unsigned int len); |
||||
|
||||
#define PAYLOAD_MAX (CARL9170_MAX_CMD_LEN / 4 - 1) |
||||
/* |
||||
* Macros to facilitate writing multiple registers in a single |
||||
* write-combining USB command. Note that when the first group |
||||
* fails the whole thing will fail without any others attempted, |
||||
* but you won't know which write in the group failed. |
||||
*/ |
||||
#define carlu_regwrite_begin(ar) \ |
||||
do { \ |
||||
struct carlu *__ar = ar; \ |
||||
unsigned int __nreg = 0; \ |
||||
int __err = 0; \ |
||||
uint32_t __dummy; |
||||
|
||||
#define carlu_regwrite_flush() \ |
||||
if (__nreg) { \ |
||||
__err = carlusb_cmd(__ar, CARL9170_CMD_WREG, \ |
||||
(u8 *)&__ar->cmd.cmd.data, 8 * __nreg, \ |
||||
(u8 *)&__dummy, sizeof(__dummy)); \ |
||||
__nreg = 0; \ |
||||
if (__err) \ |
||||
goto __regwrite_out; \ |
||||
} |
||||
|
||||
#define carlu_regwrite(r, v) do { \ |
||||
__ar->cmd.buf4[2 * __nreg + 1] = cpu_to_le32(r); \ |
||||
__ar->cmd.buf4[2 * __nreg + 2] = cpu_to_le32(v); \ |
||||
__nreg++; \ |
||||
if ((__nreg >= PAYLOAD_MAX / 2)) { \ |
||||
__err = carlusb_cmd(__ar, CARL9170_CMD_WREG, \ |
||||
(u8 *)&__ar->cmd.cmd.data, 8 * __nreg, \ |
||||
(u8 *)&__dummy, sizeof(__dummy)); \ |
||||
\ |
||||
__nreg = 0; \ |
||||
if (__err) \ |
||||
goto __regwrite_out; \ |
||||
} \ |
||||
} while (0) |
||||
|
||||
#define carlu_regwrite_finish() \ |
||||
__regwrite_out : \ |
||||
if (__err == 0 && __nreg) \ |
||||
carlu_regwrite_flush(); |
||||
|
||||
#define carlu_regwrite_result() \ |
||||
__err; \ |
||||
} while (0); |
||||
|
||||
|
||||
#define carlu_async_get_buf() \ |
||||
do { \ |
||||
__cmd = carlu_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC, \ |
||||
CARL9170_MAX_CMD_PAYLOAD_LEN); \ |
||||
if (IS_ERR_OR_NULL(__cmd)) { \ |
||||
__err = __cmd ? PTR_ERR(__cmd) : -ENOMEM; \ |
||||
goto __async_regwrite_out; \ |
||||
} \ |
||||
} while (0); |
||||
|
||||
#define carlu_async_regwrite_begin(carl) \ |
||||
do { \ |
||||
int __nreg = 0, __err = 0; \ |
||||
struct carlu *__carl = carl; \ |
||||
struct carl9170_cmd *__cmd; \ |
||||
carlu_async_get_buf(); \ |
||||
|
||||
#define carlu_async_regwrite_flush() \ |
||||
if (__nreg) { \ |
||||
__cmd->hdr.len = 8 * __nreg; \ |
||||
__err = carlusb_cmd_async(__carl, __cmd, true); \ |
||||
__nreg = 0; \ |
||||
if (__err) \ |
||||
goto __async_regwrite_out; \ |
||||
__cmd = NULL; \ |
||||
carlu_async_get_buf(); \ |
||||
} |
||||
|
||||
#define carlu_async_regwrite(r, v) do { \ |
||||
__cmd->wreg.regs[__nreg].addr = cpu_to_le32(r); \ |
||||
__cmd->wreg.regs[__nreg].val = cpu_to_le32(v); \ |
||||
__nreg++; \ |
||||
if ((__nreg >= PAYLOAD_MAX / 2)) \ |
||||
carlu_async_regwrite_flush(); \ |
||||
} while (0) |
||||
|
||||
#define carlu_async_regwrite_finish() \ |
||||
__async_regwrite_out : \ |
||||
if (__err == 0 && __nreg) \ |
||||
carlu_async_regwrite_flush(); |
||||
|
||||
#define carlu_async_regwrite_result() \ |
||||
__err; \ |
||||
} while (0); |
||||
|
||||
#endif /* __CARL9170USER_CMD_H */ |
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* Random assortment of debug stuff |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
#include <config.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdbool.h> |
||||
#include <stdlib.h> |
||||
#include <errno.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include <ctype.h> |
||||
|
||||
#include "debug.h" |
||||
|
||||
bool print_message_debug_level; |
||||
enum debug_level_t debug_level; |
||||
FILE *_stdout; |
||||
FILE *_stddbg; |
||||
FILE *_stderr; |
||||
|
||||
void init_debug() |
||||
{ |
||||
debug_level = VERBOSE; |
||||
debug_level = INFO; |
||||
print_message_debug_level = false; |
||||
|
||||
_stdout = stdout; |
||||
_stddbg = stdout; |
||||
_stderr = stderr; |
||||
} |
||||
|
||||
FILE *dbg_lvl_to_fh(const enum debug_level_t lvl) |
||||
{ |
||||
switch (lvl) { |
||||
case ERROR: |
||||
case WARNING: |
||||
return _stderr; |
||||
case INFO: |
||||
return _stdout; |
||||
case VERBOSE: |
||||
return _stddbg; |
||||
default: |
||||
BUG_ON(1); |
||||
} |
||||
} |
||||
|
||||
void print_hex_dump_bytes(const enum debug_level_t lvl, const char *pre, |
||||
const void *buf, size_t len) |
||||
{ |
||||
char line[58]; |
||||
char str[17] = { 0 }; |
||||
const unsigned char *tmp = (void *) buf; |
||||
char *pbuf = line; |
||||
size_t i, j; |
||||
|
||||
for (i = 0; i < len; i++) { |
||||
if (i % 16 == 0) { |
||||
if (pbuf != line) { |
||||
__fprintf(lvl, "%s%s: %s\n", pre, line, str); |
||||
pbuf = line; |
||||
} |
||||
|
||||
pbuf += sprintf(pbuf, "0x%04lx: ", (unsigned long)i); |
||||
} |
||||
|
||||
pbuf += sprintf(pbuf, "%.2x ", tmp[i]); |
||||
str[i % 16] = (isprint(tmp[i]) && isascii(tmp[i])) ? tmp[i] : '.'; |
||||
} |
||||
if (pbuf != line) { |
||||
if ((i % 16)) { |
||||
str[i % 16] = '\0'; |
||||
|
||||
for (j = 0; j < (16 - (i % 16)); j++) |
||||
pbuf += sprintf(pbuf, " "); |
||||
} |
||||
|
||||
__fprintf(lvl, "%s%s: %s\n", pre, line, str); |
||||
} |
||||
} |
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* Debug API definition |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170USER_DEBUG_H |
||||
#define __CARL9170USER_DEBUG_H |
||||
|
||||
#include <stdio.h> |
||||
#include "compiler.h" |
||||
|
||||
enum debug_level_t { |
||||
SILENT, |
||||
ERROR, |
||||
WARNING, |
||||
INFO, |
||||
VERBOSE, |
||||
|
||||
/* KEEP LAST */ |
||||
ALL, |
||||
}; |
||||
|
||||
extern bool print_message_debug_level; |
||||
extern enum debug_level_t debug_level; |
||||
|
||||
#define __fprintf(lvl, fmt, args...) do { \ |
||||
if (lvl <= debug_level) { \ |
||||
if (print_message_debug_level) \ |
||||
fprintf(dbg_lvl_to_fh(lvl), "<%d>:" fmt, lvl, ##args); \ |
||||
else \ |
||||
fprintf(dbg_lvl_to_fh(lvl), fmt, ##args); \ |
||||
} \ |
||||
} while (0); |
||||
|
||||
#define dbg(fmt, args...) __fprintf(VERBOSE, fmt, ##args) |
||||
#define info(fmt, args...) __fprintf(INFO, fmt, ##args) |
||||
#define warn(fmt, args...) __fprintf(WARNING, fmt, ##args) |
||||
#define err(fmt, args...) __fprintf(ERROR, fmt, ##args) |
||||
|
||||
#define BUG_ON(a) \ |
||||
do { \ |
||||
if (a) { \ |
||||
__fprintf(ERROR, "!!!=>BUG IN function \"%s\" at line %d<=!!! %s\n", \ |
||||
__func__, __LINE__, #a); \ |
||||
fflush(stderr); \ |
||||
abort(); \ |
||||
} \ |
||||
} while (0) |
||||
|
||||
FILE *dbg_lvl_to_fh(const enum debug_level_t lvl); |
||||
void init_debug(void); |
||||
void print_hex_dump_bytes(const enum debug_level_t lvl, const char *prefix, |
||||
const void *buf, size_t len); |
||||
|
||||
#endif /* __CARL9170USER_DEBUG_H */ |
@ -0,0 +1,131 @@
@@ -0,0 +1,131 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* Firmware parsers |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
#include <config.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdbool.h> |
||||
#include <stdlib.h> |
||||
#include <errno.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include "libusb.h" |
||||
#include <sys/types.h> |
||||
#include <sys/stat.h> |
||||
#include <unistd.h> |
||||
|
||||
#include "carlu.h" |
||||
#include "usb.h" |
||||
#include "debug.h" |
||||
|
||||
int carlu_fw_check(struct carlu *ar) |
||||
{ |
||||
struct carl9170fw_otus_desc *otus_desc; |
||||
|
||||
otus_desc = carlfw_find_desc(ar->fw, (uint8_t *) OTUS_MAGIC, |
||||
sizeof(*otus_desc), |
||||
CARL9170FW_OTUS_DESC_CUR_VER); |
||||
|
||||
if (!otus_desc) { |
||||
err("No valid OTUS descriptor found.\n"); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_DUMMY_FEATURE)) { |
||||
err("Invalid Firmware Descriptor.\n"); |
||||
return -EIO; |
||||
} |
||||
|
||||
if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_UNUSABLE)) |
||||
dbg("Firmware is marked as unuseable.\n"); |
||||
|
||||
info("Firmware Version: %d.\n", otus_desc->api_ver); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int carlusb_fw_check(struct carlu *ar) |
||||
{ |
||||
struct carl9170fw_otus_desc *otus_desc; |
||||
|
||||
otus_desc = carlfw_find_desc(ar->fw, (uint8_t *) OTUS_MAGIC, |
||||
sizeof(*otus_desc), |
||||
CARL9170FW_OTUS_DESC_CUR_VER); |
||||
|
||||
if (!otus_desc) { |
||||
err("No valid USB descriptor found.\n"); |
||||
return -ENODATA; |
||||
} |
||||
|
||||
if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_DUMMY_FEATURE)) { |
||||
err("Invalid Firmware Descriptor.\n"); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_USB_INIT_FIRMWARE)) { |
||||
err("Firmware does not know how to initialize USB core.\n"); |
||||
return -EOPNOTSUPP; |
||||
} |
||||
|
||||
if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_USB_DOWN_STREAM)) { |
||||
dbg("Enabled tx stream mode.\n"); |
||||
ar->tx_stream = true; |
||||
ar->extra_headroom = sizeof(struct ar9170_stream); |
||||
} |
||||
|
||||
if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_USB_UP_STREAM)) { |
||||
dbg("Enabled rx stream mode.\n"); |
||||
ar->rx_stream = true; |
||||
} |
||||
|
||||
if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_USB_RESP_EP2)) |
||||
dbg("Firmware sends traps over EP2.\n"); |
||||
|
||||
ar->dma_chunk_size = le16_to_cpu(otus_desc->tx_frag_len); |
||||
ar->dma_chunks = otus_desc->tx_descs; |
||||
ar->rx_max = le16_to_cpu(otus_desc->rx_max_frame_len); |
||||
|
||||
if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_MINIBOOT)) |
||||
ar->miniboot_size = le16_to_cpu(otus_desc->miniboot_size); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void carlu_fw_info(struct carlu *ar) |
||||
{ |
||||
struct carl9170fw_motd_desc *motd_desc; |
||||
unsigned int fw_date; |
||||
|
||||
motd_desc = carlfw_find_desc(ar->fw, (uint8_t *) MOTD_MAGIC, |
||||
sizeof(*motd_desc), |
||||
CARL9170FW_MOTD_DESC_CUR_VER); |
||||
|
||||
if (motd_desc) { |
||||
fw_date = le32_to_cpu(motd_desc->fw_year_month_day); |
||||
|
||||
info("Firmware Date: 2%.3d-%.2d-%.2d\n", |
||||
CARL9170FW_GET_YEAR(fw_date), CARL9170FW_GET_MONTH(fw_date), |
||||
CARL9170FW_GET_DAY(fw_date)); |
||||
} |
||||
} |
@ -0,0 +1,307 @@
@@ -0,0 +1,307 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* main program routine |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
#include <config.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdbool.h> |
||||
#include <stdlib.h> |
||||
#include <errno.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include "SDL.h" |
||||
#include <SDL_version.h> |
||||
|
||||
#include "debug.h" |
||||
#include "carlu.h" |
||||
#include "usb.h" |
||||
#include "frame.h" |
||||
#include "test.h" |
||||
#include "cmd.h" |
||||
|
||||
void *carlu_alloc_driver(size_t size) |
||||
{ |
||||
unsigned int i; |
||||
struct carlu *ar; |
||||
|
||||
if (size < sizeof(*ar)) { |
||||
err("bogus driver context request."); |
||||
return NULL; |
||||
} |
||||
|
||||
ar = malloc(size); |
||||
if (ar == NULL) { |
||||
err("failed to alloc driver context."); |
||||
return NULL; |
||||
} |
||||
memset(ar, 0, size); |
||||
|
||||
for (i = 0; i < __AR9170_NUM_TXQ; i++) |
||||
frame_queue_init(&ar->tx_sent_queue[i]); |
||||
ar->resp_lock = SDL_CreateMutex(); |
||||
ar->mem_lock = SDL_CreateMutex(); |
||||
ar->resp_pend = SDL_CreateCond(); |
||||
ar->tx_pending = 0; |
||||
return ar; |
||||
} |
||||
|
||||
void carlu_free_driver(struct carlu *ar) |
||||
{ |
||||
unsigned int i; |
||||
|
||||
dbg("destroy driver struct.\n"); |
||||
SDL_DestroyMutex(ar->resp_lock); |
||||
SDL_DestroyMutex(ar->mem_lock); |
||||
SDL_DestroyCond(ar->resp_pend); |
||||
|
||||
for (i = 0; i < __AR9170_NUM_TXQ; i++) |
||||
frame_queue_kill(&ar->tx_sent_queue[i]); |
||||
|
||||
free(ar); |
||||
} |
||||
|
||||
static int carlu_init() |
||||
{ |
||||
struct SDL_version compiled; |
||||
int ret; |
||||
|
||||
SDL_VERSION(&compiled); |
||||
dbg("=== SDL %d.%d.%d ===\n", compiled.major, compiled.minor, compiled.patch); |
||||
|
||||
ret = SDL_Init(SDL_INIT_TIMER); |
||||
if (ret != 0) { |
||||
err("Unable to initialize SDL: (%s)\n", SDL_GetError()); |
||||
return EXIT_FAILURE; |
||||
} |
||||
|
||||
return usb_init(); |
||||
} |
||||
|
||||
static void carlu_exit() |
||||
{ |
||||
SDL_Quit(); |
||||
usb_exit(); |
||||
} |
||||
|
||||
static int carlu_dump_eeprom(void) |
||||
{ |
||||
struct carlu *carl = NULL; |
||||
uint8_t data[8192] = { 0 }; |
||||
int err; |
||||
|
||||
err = carlu_init(); |
||||
if (err) |
||||
goto out; |
||||
|
||||
carl = carlusb_probe(); |
||||
if (IS_ERR_OR_NULL(carl)) { |
||||
err = PTR_ERR(carl); |
||||
goto out; |
||||
} |
||||
|
||||
err = carlu_cmd_mem_dump(carl, 0, sizeof(data), &data); |
||||
if (err) |
||||
goto out_close; |
||||
|
||||
print_hex_dump_bytes(INFO, "EEPROM:", data, sizeof(data)); |
||||
|
||||
out_close: |
||||
carlusb_close(carl); |
||||
|
||||
out: |
||||
carlu_exit(); |
||||
return err ? EXIT_FAILURE : EXIT_SUCCESS; |
||||
} |
||||
|
||||
static int carlu_run_gpio_test(void) |
||||
{ |
||||
struct carlu *carl = NULL; |
||||
int err; |
||||
|
||||
err = carlu_init(); |
||||
if (err) |
||||
goto out; |
||||
|
||||
carl = carlusb_probe(); |
||||
if (IS_ERR_OR_NULL(carl)) { |
||||
err = PTR_ERR(carl); |
||||
goto out; |
||||
} |
||||
|
||||
err = carlu_gpio_test(carl); |
||||
if (err) |
||||
goto out_close; |
||||
|
||||
out_close: |
||||
carlusb_close(carl); |
||||
|
||||
out: |
||||
carlu_exit(); |
||||
return err ? EXIT_FAILURE : EXIT_SUCCESS; |
||||
} |
||||
|
||||
static int carlu_run_random_test(void) |
||||
{ |
||||
struct carlu *carl = NULL; |
||||
int err; |
||||
|
||||
err = carlu_init(); |
||||
if (err) |
||||
goto out; |
||||
|
||||
carl = carlusb_probe(); |
||||
if (IS_ERR_OR_NULL(carl)) { |
||||
err = PTR_ERR(carl); |
||||
goto out; |
||||
} |
||||
|
||||
err = carlu_random_test(carl); |
||||
if (err) |
||||
goto out_close; |
||||
|
||||
out_close: |
||||
carlusb_close(carl); |
||||
|
||||
out: |
||||
carlu_exit(); |
||||
return err ? EXIT_FAILURE : EXIT_SUCCESS; |
||||
} |
||||
|
||||
static int carlu_run_loop_test(void) |
||||
{ |
||||
struct carlu *carl; |
||||
int err; |
||||
|
||||
err = carlu_init(); |
||||
if (err) |
||||
return EXIT_FAILURE; |
||||
|
||||
carl = carlusb_probe(); |
||||
if (IS_ERR_OR_NULL(carl)) { |
||||
err = PTR_ERR(carl); |
||||
goto out; |
||||
} |
||||
|
||||
carlu_cmd_write_mem(carl, AR9170_MAC_REG_BCN_PERIOD, 0xFFFFFFFF); |
||||
carlu_cmd_write_mem(carl, AR9170_MAC_REG_PRETBTT, 0xFFFFFFFF); |
||||
|
||||
/* different payload test */ |
||||
carlu_loopback_test(carl, 9000, 1000, 1566, 1566); |
||||
carlusb_close(carl); |
||||
|
||||
out: |
||||
return err ? EXIT_FAILURE : EXIT_SUCCESS; |
||||
} |
||||
|
||||
static int carlu_probe_all(void) |
||||
{ |
||||
struct carlu *carl[32] = { 0 }; |
||||
unsigned int devs; |
||||
int ret; |
||||
|
||||
ret = carlu_init(); |
||||
if (ret) |
||||
return EXIT_FAILURE; |
||||
|
||||
for (devs = 0; devs < ARRAY_SIZE(carl); devs++) { |
||||
carl[devs] = carlusb_probe(); |
||||
if (IS_ERR_OR_NULL(carl[devs])) |
||||
break; |
||||
} |
||||
|
||||
info("Found %d devices\n", devs); |
||||
|
||||
for (; devs > 0; devs--) |
||||
carlusb_close(carl[devs - 1]); |
||||
|
||||
carlu_exit(); |
||||
return EXIT_SUCCESS; |
||||
} |
||||
|
||||
struct menu_struct { |
||||
char option; |
||||
unsigned int parameters; |
||||
int (*function)(void); |
||||
char help_text[80]; |
||||
}; |
||||
|
||||
#define MENU_ITEM(op, func, helpme) \ |
||||
{ \ |
||||
.option = op, \ |
||||
.parameters = 0, \ |
||||
.function = func, \ |
||||
.help_text = helpme, \ |
||||
} |
||||
|
||||
static int show_help(void); |
||||
|
||||
static const struct menu_struct menu[] = { |
||||
[0] = MENU_ITEM('h', show_help, "shows this useless help message text."), /* keep this entry at 0! */ |
||||
MENU_ITEM('e', carlu_dump_eeprom, "hexdumps eeprom content to stdout."), |
||||
MENU_ITEM('l', carlusb_print_known_devices, "list of all known ar9170 usb devices."), |
||||
MENU_ITEM('p', carlu_probe_all, "probe all possible devices."), |
||||
MENU_ITEM('t', carlu_run_loop_test, "run tx/rx test."), |
||||
MENU_ITEM('g', carlu_run_gpio_test, "flash the leds."), |
||||
MENU_ITEM('r', carlu_run_random_test, "get random numbers."), |
||||
}; |
||||
|
||||
static int show_help(void) |
||||
{ |
||||
unsigned int i; |
||||
char parameters[ARRAY_SIZE(menu) + 1]; |
||||
|
||||
for (i = 0; i < ARRAY_SIZE(menu); i++) |
||||
parameters[i] = menu[i].option; |
||||
|
||||
parameters[ARRAY_SIZE(menu)] = '\0'; |
||||
|
||||
info("usage: ar9170user -[%s]\n", parameters); |
||||
|
||||
for (i = 0; i < ARRAY_SIZE(menu); i++) |
||||
info("\t-%c\t%s\n", menu[i].option, menu[i].help_text); |
||||
|
||||
return EXIT_FAILURE; |
||||
} |
||||
|
||||
static int select_menu_item(const char arg) |
||||
{ |
||||
unsigned int i; |
||||
|
||||
for (i = ARRAY_SIZE(menu) - 1; i != 0; i--) { |
||||
if (arg == menu[i].option) |
||||
break; |
||||
} |
||||
|
||||
return menu[i].function(); |
||||
} |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
init_debug(); |
||||
|
||||
if (argc != 2 || strlen(argv[1]) != 2 || argv[1][0] != '-') |
||||
return show_help(); |
||||
|
||||
return select_menu_item(argv[1][1]); |
||||
} |
@ -0,0 +1,181 @@
@@ -0,0 +1,181 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* RX data processing |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
#include <config.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdbool.h> |
||||
#include <stdlib.h> |
||||
#include <errno.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include "libusb.h" |
||||
|
||||
#include "carlu.h" |
||||
#include "debug.h" |
||||
#include "frame.h" |
||||
#include "ieee80211.h" |
||||
#include "wlan.h" |
||||
|
||||
static void carlu_handle_data(struct carlu *ar, void *buf, |
||||
unsigned int len) |
||||
{ |
||||
if (ar->rx_cb) { |
||||
ar->rx_cb(ar, buf, len); |
||||
} else { |
||||
dbg("unhandled data:\n"); |
||||
print_hex_dump_bytes(VERBOSE, "DATA:", buf, len); |
||||
} |
||||
} |
||||
|
||||
void carlu_handle_command(struct carlu *ar, void *buf, |
||||
unsigned int len) |
||||
{ |
||||
struct carl9170_rsp *cmd; |
||||
int ret = 0; |
||||
|
||||
cmd = (void *) buf; |
||||
|
||||
if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) { |
||||
if ((cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG)) |
||||
return; |
||||
|
||||
SDL_mutexP(ar->resp_lock); |
||||
if (ar->resp_buf && ar->resp_len && ar->resp_len >= (len - 4)) { |
||||
memcpy(ar->resp_buf, buf + 4, len - 4); |
||||
ar->resp_buf = NULL; |
||||
} else { |
||||
warn("spurious command response (%d / %d)\n", |
||||
(int) len - 4, (int) ar->resp_len); |
||||
print_hex_dump_bytes(WARNING, "RSP:", buf, len); |
||||
} |
||||
SDL_mutexV(ar->resp_lock); |
||||
|
||||
SDL_CondSignal(ar->resp_pend); |
||||
return; |
||||
} |
||||
|
||||
if (ar->cmd_cb) |
||||
ret = ar->cmd_cb(ar, cmd, buf, len); |
||||
|
||||
if (ret) { |
||||
switch (cmd->hdr.cmd) { |
||||
case CARL9170_RSP_TXCOMP: |
||||
carlu_tx_feedback(ar, cmd); |
||||
break; |
||||
|
||||
case CARL9170_RSP_TEXT: |
||||
info("carl9170 FW: %.*s\n", (int)len - 4, (char *)buf + 4); |
||||
break; |
||||
|
||||
case CARL9170_RSP_HEXDUMP: |
||||
info("carl9170 FW: hexdump\n"); |
||||
print_hex_dump_bytes(INFO, "HEX:", (char *)buf + 4, len - 4); |
||||
break; |
||||
|
||||
case CARL9170_RSP_WATCHDOG: |
||||
err("Woof Woof! Watchdog notification.\n"); |
||||
break; |
||||
|
||||
case CARL9170_RSP_GPIO: |
||||
info("GPIO Interrupt => GPIO state %.8x\n", |
||||
le32_to_cpu(cmd->gpio.gpio)); |
||||
break; |
||||
|
||||
case CARL9170_RSP_RADAR: |
||||
info("RADAR Interrupt"); |
||||
break; |
||||
|
||||
default: |
||||
warn("received unhandled event 0x%x\n", cmd->hdr.cmd); |
||||
print_hex_dump_bytes(WARNING, "RSP:", (char *)buf + 4, len - 4); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void __carlu_rx(struct carlu *ar, uint8_t *buf, unsigned int len) |
||||
{ |
||||
unsigned int i; |
||||
|
||||
i = 0; |
||||
|
||||
/* weird thing, but this is the same in the original driver */ |
||||
while (len > 2 && i < 12 && buf[0] == 0xff && buf[1] == 0xff) { |
||||
i += 2; |
||||
len -= 2; |
||||
buf += 2; |
||||
} |
||||
|
||||
if (i == 12) { |
||||
struct carl9170_rsp *cmd; |
||||
i = 0; |
||||
|
||||
while (i < len) { |
||||
cmd = (void *) &buf[i]; |
||||
|
||||
carlu_handle_command(ar, cmd, cmd->hdr.len + 4); |
||||
i += cmd->hdr.len + 4; |
||||
} |
||||
} else { |
||||
carlu_handle_data(ar, buf, len); |
||||
} |
||||
} |
||||
|
||||
static void carlu_rx_stream(struct carlu *ar, struct frame *frame) |
||||
{ |
||||
void *buf = frame->data; |
||||
unsigned int len = frame->len; |
||||
|
||||
while (len >= 4) { |
||||
struct ar9170_stream *rx_stream; |
||||
unsigned int resplen, elen; |
||||
|
||||
rx_stream = (void *) buf; |
||||
resplen = le16_to_cpu(rx_stream->length); |
||||
elen = roundup(resplen + 4, 4); |
||||
|
||||
if (rx_stream->tag != cpu_to_le16(0x4e00)) { |
||||
warn("frame has no tag %p %u %x.\n", |
||||
buf, (int) len, rx_stream->tag); |
||||
print_hex_dump_bytes(WARNING, "FRAME:", frame->data, frame->len); |
||||
|
||||
__carlu_rx(ar, buf, len); |
||||
return; |
||||
} |
||||
|
||||
__carlu_rx(ar, rx_stream->payload, resplen); |
||||
|
||||
len -= elen; |
||||
buf += elen; |
||||
} |
||||
} |
||||
|
||||
void carlu_rx(struct carlu *ar, struct frame *frame) |
||||
{ |
||||
if (ar->rx_stream) |
||||
carlu_rx_stream(ar, frame); |
||||
else |
||||
__carlu_rx(ar, frame->data, frame->len); |
||||
} |
@ -0,0 +1,237 @@
@@ -0,0 +1,237 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* Various tests |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
#include <config.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdbool.h> |
||||
#include <stdlib.h> |
||||
#include <errno.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include "libusb.h" |
||||
#include "SDL.h" |
||||
|
||||
#include "carlu.h" |
||||
#include "debug.h" |
||||
#include "frame.h" |
||||
#include "usb.h" |
||||
#include "cmd.h" |
||||
|
||||
void debug_test(void) |
||||
{ |
||||
err("This is an error.\n"); |
||||
warn("This is a warnig.\n"); |
||||
info("This is an informative message.\n"); |
||||
dbg("This is just utter useless babble.\n"); |
||||
} |
||||
|
||||
void carlu_frame_test(struct carlu *ar) |
||||
{ |
||||
struct frame *frame; |
||||
|
||||
frame = carlu_alloc_frame(ar, 0x40); |
||||
frame_reserve(frame, 0x10); |
||||
|
||||
memset(frame_put(frame, 0x10), 0x11, 0x10); |
||||
memset(frame_put(frame, 0x10), 0x22, 0x10); |
||||
memset(frame_push(frame, 0x10), 0x33, 0x10); |
||||
memset(frame_put(frame, 0x10), 0x44, 0x10); |
||||
|
||||
print_hex_dump_bytes(INFO, "DATA:", frame->data, frame->len); |
||||
|
||||
print_hex_dump_bytes(INFO, "PAYLOAD:", frame->payload, frame->alloced); |
||||
|
||||
frame_free(frame); |
||||
} |
||||
|
||||
static void carlu_loopback_tx_cb(struct carlu *ar __unused, |
||||
struct frame *frame __unused) |
||||
{ |
||||
} |
||||
|
||||
static int carlu_loopback_cmd(struct carlu *ar __unused, |
||||
struct carl9170_rsp *cmd, void *buf __unused, |
||||
unsigned int len __unused) |
||||
{ |
||||
unsigned int i, n; |
||||
|
||||
switch (cmd->hdr.cmd) { |
||||
case CARL9170_RSP_TXCOMP: |
||||
n = cmd->hdr.ext; |
||||
dbg("received tx feedback (%d).\n", n); |
||||
|
||||
for (i = 0; i < n; i++) { |
||||
dbg("cookie:%x info:%x\n", |
||||
cmd->_tx_status[i].cookie, |
||||
cmd->_tx_status[i].info); |
||||
} |
||||
return -1; |
||||
|
||||
default: |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
static void carlu_loopback_rx(struct carlu *ar, |
||||
void *buf __unused, unsigned int len) |
||||
{ |
||||
ar->rxed++; |
||||
ar->rx_octets += len; |
||||
} |
||||
|
||||
static void carlu_loopback_mark_tx_frames(struct frame *frame) |
||||
{ |
||||
unsigned int i; |
||||
|
||||
for (i = 0; i < frame->len; i++) |
||||
frame->data[i] = (uint8_t) i; |
||||
} |
||||
|
||||
void carlu_loopback_test(struct carlu *ar, const unsigned int total_runs, |
||||
const unsigned int interval, const unsigned int min_len, const unsigned int max_len) |
||||
{ |
||||
struct frame *frame; |
||||
uint32_t start_time, total_time = 0; |
||||
float moctets, dtime; |
||||
unsigned int runs = 0, i = 0, j = 0, len; |
||||
int ret; |
||||
|
||||
if (min_len > max_len) { |
||||
err("stresstest: invalid parameters => min_len:%d > max_len:%d", |
||||
min_len, max_len); |
||||
return; |
||||
} |
||||
|
||||
if (min_len < 4) { |
||||
err("stresstest: invalid parameters => min_len is smaller than 4"); |
||||
return; |
||||
} |
||||
|
||||
len = min_len; |
||||
frame = carlu_alloc_frame(ar, len); |
||||
frame_put(frame, len); |
||||
|
||||
carlu_loopback_mark_tx_frames(frame); |
||||
|
||||
ar->rx_cb = carlu_loopback_rx; |
||||
ar->cmd_cb = carlu_loopback_cmd; |
||||
ar->tx_cb = carlu_loopback_tx_cb; |
||||
|
||||
start_time = SDL_GetTicks(); |
||||
while (runs <= total_runs) { |
||||
if (frame && carlu_tx(ar, frame) == 0) { |
||||
len = min_len; |
||||
i++; |
||||
} else { |
||||
frame_free(frame); |
||||
} |
||||
|
||||
frame = NULL; |
||||
|
||||
frame = carlu_alloc_frame(ar, len); |
||||
frame_put(frame, len); |
||||
|
||||
carlu_loopback_mark_tx_frames(frame); |
||||
j++; |
||||
|
||||
total_time = SDL_GetTicks() - start_time; |
||||
|
||||
if (total_time >= interval) { |
||||
moctets = ((float)ar->tx_octets) / (1024.0f * 1024.0f); |
||||
dtime = ((float)total_time) / 1000; |
||||
info("%d: tx %d of %d => %.2f MiB in %.2f secs => %.4f MBits/s\n", |
||||
runs, i, j, moctets, dtime, (moctets * 8.0f) / dtime); |
||||
|
||||
moctets = ((float)ar->rx_octets) / (1024.0f * 1024.0f); |
||||
info("%d: rx %d of %d => %.2f MiB in %.2f secs => %.4f MBits/s\n", |
||||
runs, ar->rxed, i, moctets, dtime, (moctets * 8.0f) / dtime); |
||||
|
||||
if ((ar->rxed == 0 && i) || !i) { |
||||
ret = carlu_cmd_echo(ar, 0xdeadbeef); |
||||
if (ret) |
||||
warn("firmware crashed... echo_cmd: (%d)\n", ret); |
||||
} |
||||
|
||||
total_time = 0; |
||||
i = 0; |
||||
j = 0; |
||||
ar->rxed = 0; |
||||
ar->txed = 0; |
||||
ar->rx_octets = 0; |
||||
ar->tx_octets = 0; |
||||
runs++; |
||||
start_time = SDL_GetTicks(); |
||||
} |
||||
} |
||||
|
||||
ar->rx_cb = NULL; |
||||
ar->cmd_cb = NULL; |
||||
ar->tx_cb = NULL; |
||||
} |
||||
|
||||
int carlu_gpio_test(struct carlu *ar) |
||||
{ |
||||
uint32_t gpio; |
||||
|
||||
#define CHK(cmd) \ |
||||
do { \ |
||||
int __err = cmd; \ |
||||
if ((__err)) \ |
||||
return __err; \ |
||||
} while (0) |
||||
|
||||
CHK(carlu_cmd_read_mem(ar, AR9170_GPIO_REG_PORT_DATA, &gpio)); |
||||
info("GPIO state:%x\n", gpio); |
||||
|
||||
/* turn both LEDs on */ |
||||
CHK(carlu_cmd_write_mem(ar, AR9170_GPIO_REG_PORT_DATA, |
||||
AR9170_GPIO_PORT_LED_0 | AR9170_GPIO_PORT_LED_1)); |
||||
|
||||
SDL_Delay(700); |
||||
|
||||
CHK(carlu_cmd_read_mem(ar, AR9170_GPIO_REG_PORT_DATA, &gpio)); |
||||
info("GPIO state:%x\n", gpio); |
||||
|
||||
/* turn LEDs off everything */ |
||||
CHK(carlu_cmd_write_mem(ar, AR9170_GPIO_REG_PORT_DATA, 0)); |
||||
|
||||
CHK(carlu_cmd_read_mem(ar, AR9170_GPIO_REG_PORT_DATA, &gpio)); |
||||
info("GPIO state:%x\n", gpio); |
||||
} |
||||
|
||||
int carlu_random_test(struct carlu *ar) |
||||
{ |
||||
uint32_t buf[4096]; |
||||
int err, i; |
||||
|
||||
err = carlu_cmd_mem_watch(ar, AR9170_RAND_REG_NUM, sizeof(buf), buf); |
||||
if (err) |
||||
return err; |
||||
|
||||
for (i = 0; i < ARRAY_SIZE(buf); i++) |
||||
info("%.2x %.2x ", buf[i] & 0xff, buf[i] >> 8); |
||||
|
||||
info("\n"); |
||||
} |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* test.c header |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef __CARL9170USER_TEST_H |
||||
#define __CARL9170USER_TEST_H |
||||
|
||||
#include "carlu.h" |
||||
|
||||
void carlu_loopback_test(struct carlu *ar, const unsigned int total_runs, |
||||
const unsigned int interval, const unsigned int min_len, |
||||
const unsigned int max_len); |
||||
|
||||
int carlu_gpio_test(struct carlu *ar); |
||||
int carlu_random_test(struct carlu *ar); |
||||
|
||||
#endif /* __CARL9170USER_TEST_H */ |
@ -0,0 +1,213 @@
@@ -0,0 +1,213 @@
|
||||
/* |
||||
* carlu - userspace testing utility for ar9170 devices |
||||
* |
||||
* xmit - related functions |
||||
* |
||||
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
#include <config.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdbool.h> |
||||
#include <stdlib.h> |
||||
#include <errno.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include "libusb.h" |
||||
|
||||
#include "carlu.h" |
||||
#include "debug.h" |
||||
#include "frame.h" |
||||
#include "usb.h" |
||||
#include "ieee80211.h" |
||||
#include "wlan.h" |
||||
|
||||
struct frame *carlu_alloc_frame(struct carlu *ar, unsigned int size) |
||||
{ |
||||
struct frame *tmp; |
||||
unsigned int total_len; |
||||
|
||||
total_len = ar->extra_headroom + sizeof(struct _carl9170_tx_superframe) + size; |
||||
|
||||
tmp = frame_alloc(total_len); |
||||
if (!tmp) |
||||
return NULL; |
||||
|
||||
frame_reserve(tmp, sizeof(struct _carl9170_tx_superframe) + ar->extra_headroom); |
||||
|
||||
tmp->queue = 2; |
||||
|
||||
return tmp; |
||||
} |
||||
|
||||
static int carlu_alloc_dev_mem(struct carlu *ar, |
||||
struct frame *frame) |
||||
{ |
||||
struct _carl9170_tx_superframe *txp = (void *)frame->data; |
||||
unsigned int len, chunks; |
||||
|
||||
len = roundup(frame->len, ar->dma_chunk_size); |
||||
chunks = len / ar->dma_chunk_size; |
||||
|
||||
SDL_mutexP(ar->mem_lock); |
||||
if (ar->tx_pending >= ar->dma_chunks || |
||||
ar->used_dma_chunks + chunks >= ar->dma_chunks) { |
||||
SDL_mutexV(ar->mem_lock); |
||||
return -ENOSPC; |
||||
} |
||||
|
||||
ar->used_dma_chunks += chunks; |
||||
ar->tx_pending++; |
||||
txp->s.cookie = ar->cookie++; |
||||
SDL_mutexV(ar->mem_lock); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static void carlu_free_dev_mem(struct carlu *ar, |
||||
struct frame *frame) |
||||
{ |
||||
struct _carl9170_tx_superframe *txp = (void *)frame->data; |
||||
unsigned int len, chunks; |
||||
|
||||
len = roundup(frame->len, ar->dma_chunk_size); |
||||
chunks = len / ar->dma_chunk_size; |
||||
|
||||
SDL_mutexP(ar->mem_lock); |
||||
ar->used_dma_chunks -= chunks; |
||||
ar->tx_pending--; |
||||
SDL_mutexV(ar->mem_lock); |
||||
} |
||||
|
||||
void carlu_free_frame(struct carlu *ar __unused, |
||||
struct frame *frame) |
||||
{ |
||||
frame_free(frame); |
||||
} |
||||
|
||||
static struct frame *carlu_find_frame(struct carlu *ar, |
||||
unsigned int queue, uint8_t cookie) |
||||
{ |
||||
struct frame *frame = NULL; |
||||
|
||||
BUG_ON(queue >= __AR9170_NUM_TXQ); |
||||
BUG_ON(SDL_mutexP(ar->tx_sent_queue[queue].lock) != 0); |
||||
FRAME_WALK(frame, &ar->tx_sent_queue[queue]) { |
||||
struct _carl9170_tx_superframe *super; |
||||
|
||||
super = (void *) frame->data; |
||||
if (super->s.cookie == cookie) { |
||||
__frame_unlink(&ar->tx_sent_queue[queue], frame); |
||||
SDL_mutexV(ar->tx_sent_queue[queue].lock); |
||||
return frame; |
||||
} |
||||
} |
||||
SDL_mutexV(ar->tx_sent_queue[queue].lock); |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
static void carlu_tx_fb_cb(struct carlu *ar, |
||||
struct frame *frame) |
||||
{ |
||||
if (ar->tx_fb_cb) |
||||
ar->tx_fb_cb(ar, frame); |
||||
else |
||||
carlu_free_frame(ar, frame); |
||||
|
||||
} |
||||
|
||||
void carlu_tx_feedback(struct carlu *ar, |
||||
struct carl9170_rsp *cmd) |
||||
{ |
||||
unsigned int i, n, k, q; |
||||
struct frame *frame; |
||||
struct carlu_tx_info *tx_info; |
||||
|
||||
n = cmd->hdr.ext; |
||||
|
||||
for (i = 0; i < n; i++) { |
||||
q = (cmd->_tx_status[i].info >> CARL9170_TX_STATUS_QUEUE_S) & |
||||
CARL9170_TX_STATUS_QUEUE; |
||||
frame = carlu_find_frame(ar, q, cmd->_tx_status[i].cookie); |
||||
if (frame) { |
||||
carlu_free_dev_mem(ar, frame); |
||||
tx_info = get_tx_info(frame); |
||||
|
||||
k = (cmd->_tx_status[i].info >> CARL9170_TX_STATUS_RIX) |
||||
& CARL9170_TX_STATUS_RIX_S; |
||||
tx_info->rates[k].cnt = (cmd->_tx_status[i].info >> |
||||
CARL9170_TX_STATUS_TRIES_S) & |
||||
CARL9170_TX_STATUS_TRIES; |
||||
for (k++; k < CARL9170_TX_MAX_RATES; k++) { |
||||
tx_info->rates[k].rix = -1; |
||||
tx_info->rates[k].cnt = -1; |
||||
} |
||||
|
||||
carlu_tx_fb_cb(ar, frame); |
||||
} else { |
||||
err("Found no frame for cookie %d.\n", |
||||
cmd->_tx_status[i].cookie); |
||||
} |
||||
} |
||||
} |
||||
|
||||
int carlu_tx(struct carlu *ar, struct frame *frame) |
||||
{ |
||||
struct _carl9170_tx_superframe *txp; |
||||
unsigned int len, queue; |
||||
int cookie, err; |
||||
|
||||
len = frame->len; |
||||
|
||||
txp = (void *) frame_push(frame, sizeof(struct _carl9170_tx_superframe)); |
||||
|
||||
if (txp->s.rix) |
||||
goto err_out; |
||||
|
||||
err = carlu_alloc_dev_mem(ar, frame); |
||||
if (err) |
||||
goto err_out; |
||||
|
||||
txp->s.len = cpu_to_le16(frame->len); |
||||
|
||||
queue = (frame->queue % __AR9170_NUM_TXQ); |
||||
|
||||
SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txp->s.misc, queue); |
||||
|
||||
txp->f.length = len + FCS_LEN; /* + I(C)V_LEN */ |
||||
|
||||
txp->f.mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | |
||||
AR9170_TX_MAC_BACKOFF); |
||||
txp->f.mac_control |= cpu_to_le16(queue << AR9170_TX_MAC_QOS_S); |
||||
|
||||
txp->f.phy_control = cpu_to_le32(AR9170_TX_PHY_MOD_CCK | AR9170_TX_PHY_BW_20MHZ | |
||||
((17 * 2) << AR9170_TX_PHY_TX_PWR_S) | |
||||
(AR9170_TX_PHY_TXCHAIN_1 << AR9170_TX_PHY_TXCHAIN_S) | |
||||
(11 << AR9170_TX_PHY_MCS_S)); |
||||
|
||||
frame_queue_tail(&ar->tx_sent_queue[queue], frame); |
||||
carlusb_tx(ar, frame); |
||||
return 0; |
||||
|
||||
err_out: |
||||
frame_pull(frame, sizeof(struct _carl9170_tx_superframe)); |
||||
return err; |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue