linux-firmware: add carl9170 firmware
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>
This commit is contained in:
parent
8cf14f0aca
commit
32eb7c7307
12
WHENCE
12
WHENCE
|
@ -2034,3 +2034,15 @@ useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Driver: carl9170 -- Atheros AR9170 802.11 draft-n USB driver
|
||||||
|
|
||||||
|
File: carl9170-1.fw
|
||||||
|
Version: 1.9.6
|
||||||
|
Source: carl9170fw/
|
||||||
|
|
||||||
|
Downloaded from http://linuxwireless.org/en/users/Drivers/carl9170
|
||||||
|
|
||||||
|
Licence: GPLv2
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
Binary file not shown.
|
@ -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 @@
|
||||||
|
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 @@
|
||||||
|
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 @@
|
||||||
|
mainmenu "CARL9170 Firmware Configuration"
|
||||||
|
|
||||||
|
source "carlfw/Kconfig"
|
||||||
|
source "minifw/Kconfig"
|
||||||
|
source "tools/Kconfig"
|
|
@ -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 @@
|
||||||
|
#!/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 @@
|
||||||
|
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 @@
|
||||||
|
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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/* $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 @@
|
||||||
|
/* $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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
.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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/* 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
|
File diff suppressed because it is too large
Load Diff
|
@ -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 @@
|
||||||
|
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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
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 @@
|
||||||
|
/*
|
||||||
|
* 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");
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
#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 @@
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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 @@
|
||||||
|
%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 @@
|
||||||
|
%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 @@
|
||||||
|
%{
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
# - 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 @@
|
||||||
|
# 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 @@
|
||||||
|
# - 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 @@
|
||||||
|
#=============================================================================
|
||||||
|
# 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 @@
|
||||||
|
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 @@
|
||||||
|
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 @@
|
||||||
|
#!/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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
#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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
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 @@
|
||||||
|
config CARL9170FW_BUILD_MINIBOOT
|
||||||
|
def_bool y
|
||||||
|
prompt "Build MiniBoot Firmware Header"
|
|
@ -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 @@
|
||||||
|
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 @@
|
||||||
|
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 @@
|
||||||
|
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 @@
|
||||||
|
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 @@
|
||||||
|
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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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 @@
|
||||||
|
/*
|
||||||
|
* 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