[kernel] r19729 - in dists/trunk/firmware-free: debian linux-free linux-free/carl9170fw linux-free/carl9170fw/carlfw linux-free/carl9170fw/carlfw/include linux-free/carl9170fw/carlfw/src linux-free/carl9170fw/carlfw/usb linux-free/carl9170fw/config linux-free/carl9170fw/extra linux-free/carl9170fw/include linux-free/carl9170fw/include/linux linux-free/carl9170fw/include/shared linux-free/carl9170fw/minifw linux-free/carl9170fw/toolchain linux-free/carl9170fw/tools linux-free/carl9170fw/tools/carlu linux-free/carl9170fw/tools/carlu/src linux-free/carl9170fw/tools/include linux-free/carl9170fw/tools/lib linux-free/carl9170fw/tools/src

Ben Hutchings benh at alioth.debian.org
Mon Jan 14 11:38:49 UTC 2013


Author: benh
Date: Mon Jan 14 11:38:44 2013
New Revision: 19729

Log:
Add Atheros AR9170 free firmware for use with carl9170 (Closes: #635840)

Added:
   dists/trunk/firmware-free/linux-free/carl9170-1.fw   (contents, props changed)
   dists/trunk/firmware-free/linux-free/carl9170fw/
   dists/trunk/firmware-free/linux-free/carl9170fw/CMakeLists.txt
   dists/trunk/firmware-free/linux-free/carl9170fw/COPYRIGHT
   dists/trunk/firmware-free/linux-free/carl9170fw/GPL
   dists/trunk/firmware-free/linux-free/carl9170fw/Kconfig
   dists/trunk/firmware-free/linux-free/carl9170fw/README
   dists/trunk/firmware-free/linux-free/carl9170fw/autogen.sh   (contents, props changed)
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/CMakeLists.txt
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/Kconfig
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/carl9170.lds
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/cam.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/carl9170.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/cmd.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/config.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/dma.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/fwdsc.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/gpio.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/hostif.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/io.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/printf.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/rf.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/rom.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/timer.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/uart.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/usb.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/usb_fifo.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/wl.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/wol.h
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/ashlsi3.S
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/cam.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/cmd.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/dma.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/fw.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/gpio.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/hostif.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/main.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/memcpy.S
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/memset.S
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/printf.c   (contents, props changed)
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/reboot.S
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/rf.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/uart.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/udivsi3_i4i-Os.S
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/wlan.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/wol.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/Kconfig
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/fifo.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/main.c
   dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/usb.c
   dists/trunk/firmware-free/linux-free/carl9170fw/config/
   dists/trunk/firmware-free/linux-free/carl9170fw/config/CMakeLists.txt
   dists/trunk/firmware-free/linux-free/carl9170fw/config/conf.c
   dists/trunk/firmware-free/linux-free/carl9170fw/config/confdata.c
   dists/trunk/firmware-free/linux-free/carl9170fw/config/expr.c
   dists/trunk/firmware-free/linux-free/carl9170fw/config/expr.h
   dists/trunk/firmware-free/linux-free/carl9170fw/config/lkc.h
   dists/trunk/firmware-free/linux-free/carl9170fw/config/lkc_proto.h
   dists/trunk/firmware-free/linux-free/carl9170fw/config/menu.c
   dists/trunk/firmware-free/linux-free/carl9170fw/config/symbol.c
   dists/trunk/firmware-free/linux-free/carl9170fw/config/util.c
   dists/trunk/firmware-free/linux-free/carl9170fw/config/zconf.gperf
   dists/trunk/firmware-free/linux-free/carl9170fw/config/zconf.l
   dists/trunk/firmware-free/linux-free/carl9170fw/config/zconf.y
   dists/trunk/firmware-free/linux-free/carl9170fw/extra/
   dists/trunk/firmware-free/linux-free/carl9170fw/extra/FindGPERF.cmake
   dists/trunk/firmware-free/linux-free/carl9170fw/extra/FindPackageHandleStandardArgs.cmake
   dists/trunk/firmware-free/linux-free/carl9170fw/extra/FindUSB-1.0.cmake
   dists/trunk/firmware-free/linux-free/carl9170fw/extra/GCCVersion.cmake
   dists/trunk/firmware-free/linux-free/carl9170fw/extra/libusb-zeropacket.diff
   dists/trunk/firmware-free/linux-free/carl9170fw/extra/sh-elf-linux.cmake
   dists/trunk/firmware-free/linux-free/carl9170fw/genapi.sh   (contents, props changed)
   dists/trunk/firmware-free/linux-free/carl9170fw/include/
   dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/
   dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/ch9.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/compiler.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/ieee80211.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/types.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/
   dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/eeprom.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/fwcmd.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/fwdesc.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/hw.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/phy.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/version.h
   dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/wlan.h
   dists/trunk/firmware-free/linux-free/carl9170fw/minifw/
   dists/trunk/firmware-free/linux-free/carl9170fw/minifw/CMakeLists.txt
   dists/trunk/firmware-free/linux-free/carl9170fw/minifw/Kconfig
   dists/trunk/firmware-free/linux-free/carl9170fw/minifw/miniboot.S
   dists/trunk/firmware-free/linux-free/carl9170fw/minifw/miniboot.lds
   dists/trunk/firmware-free/linux-free/carl9170fw/toolchain/
   dists/trunk/firmware-free/linux-free/carl9170fw/toolchain/Makefile
   dists/trunk/firmware-free/linux-free/carl9170fw/toolchain/SHA256SUMS
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/CMakeLists.txt
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/Kconfig
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/CMakeLists.txt
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/carlu.h
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/cmd.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/cmd.h
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/debug.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/debug.h
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/fw.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/main.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/rx.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/test.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/test.h
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/tx.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/usb.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/usb.h
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/include/
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/include/frame.h
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/include/list.h
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/CMakeLists.txt
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/carlfw.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/carlfw.h
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/CMakeLists.txt
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/checksum.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/eeprom_fix.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/fwinfo.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/miniboot.c
   dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/wol.c
Modified:
   dists/trunk/firmware-free/debian/changelog
   dists/trunk/firmware-free/linux-free/LICENSE
   dists/trunk/firmware-free/linux-free/defines

Modified: dists/trunk/firmware-free/debian/changelog
==============================================================================
--- dists/trunk/firmware-free/debian/changelog	Mon Jan 14 11:32:23 2013	(r19728)
+++ dists/trunk/firmware-free/debian/changelog	Mon Jan 14 11:38:44 2013	(r19729)
@@ -1,6 +1,7 @@
 firmware-free (3.2) UNRELEASED; urgency=low
 
   * Update to linux-support 3.2.0-4
+  * Add Atheros AR9170 free firmware for use with carl9170 (Closes: #635840)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Mon, 14 Jan 2013 11:31:51 +0000
 

Modified: dists/trunk/firmware-free/linux-free/LICENSE
==============================================================================
--- dists/trunk/firmware-free/linux-free/LICENSE	Mon Jan 14 11:32:23 2013	(r19728)
+++ dists/trunk/firmware-free/linux-free/LICENSE	Mon Jan 14 11:38:44 2013	(r19729)
@@ -149,6 +149,18 @@
 
 --------------------------------------------------------------------------
 
+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. Some build scripts use the New BSD (3-clause) licence.
+
+--------------------------------------------------------------------------
+
 On Debian systems the text of the GPL version 2 can be found in
 /usr/share/common-licenses/GPL-2, and the text of the GPL version 3
 can be found in /usr/share/common-licenses/GPL-3.

Added: dists/trunk/firmware-free/linux-free/carl9170-1.fw
==============================================================================
Binary file. No diff available.

Added: dists/trunk/firmware-free/linux-free/carl9170fw/CMakeLists.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/CMakeLists.txt	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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)
+

Added: dists/trunk/firmware-free/linux-free/carl9170fw/COPYRIGHT
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/COPYRIGHT	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at 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.

Added: dists/trunk/firmware-free/linux-free/carl9170fw/GPL
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/GPL	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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.

Added: dists/trunk/firmware-free/linux-free/carl9170fw/Kconfig
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/Kconfig	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,5 @@
+mainmenu "CARL9170 Firmware Configuration"
+
+source "carlfw/Kconfig"
+source "minifw/Kconfig"
+source "tools/Kconfig"

Added: dists/trunk/firmware-free/linux-free/carl9170fw/README
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/README	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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].
+

Added: dists/trunk/firmware-free/linux-free/carl9170fw/autogen.sh
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/autogen.sh	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,49 @@
+#!/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
+			echo -n "Add checksum..."
+			tools/src/checksum carlfw/carl9170.fw
+		fi
+
+		install -m 644 carlfw/carl9170.fw \
+			../carl9170-$CONFIG_CARL9170FW_RELEASE_VERSION.fw
+		echo "done."
+	;;
+
+	*)
+		$0 config
+		$0 compile
+	;;
+
+
+esac

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/CMakeLists.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/CMakeLists.txt	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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")

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/Kconfig
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/Kconfig	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/carl9170.lds
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/carl9170.lds	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/cam.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/cam.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/carl9170.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/carl9170.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,222 @@
+/*
+ * carl9170 firmware - used by the ar9170 wireless device
+ *
+ * Firmware context definition
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/cmd.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/cmd.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/config.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/config.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/dma.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/dma.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011  Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/fwdsc.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/fwdsc.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,50 @@
+/*
+ * carl9170 firmware - used by the ar9170 wireless device
+ *
+ * Firmware definition
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/gpio.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/gpio.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,45 @@
+/*
+ * carl9170 firmware - used by the ar9170 wireless device
+ *
+ * GPIO definitions
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/hostif.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/hostif.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/io.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/io.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/printf.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/printf.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */
+

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/rf.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/rf.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/rom.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/rom.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/timer.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/timer.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/uart.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/uart.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/usb.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/usb.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/usb_fifo.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/usb_fifo.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/wl.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/wl.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/wol.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/include/wol.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/ashlsi3.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/ashlsi3.S	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at cygnus.com
+
+!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
+!! recoded in assembly by Toshiyasu Morita
+!! tm at netcom.com
+
+/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
+   ELF local label prefixes by J"orn Rennecke
+   amylaar at 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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/cam.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/cam.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/cmd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/cmd.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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;
+	}
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/dma.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/dma.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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;
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/fw.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/fw.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,116 @@
+/*
+ * carl9170 firmware - used by the ar9170 wireless device
+ *
+ * Firmware descriptor
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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;

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/gpio.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/gpio.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/hostif.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/hostif.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/main.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/main.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 at 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();
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/memcpy.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/memcpy.S	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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, at -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, at -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, at -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, at -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, at -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, at -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, at -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, at -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, at -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, at -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, at -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, at -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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/memset.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/memset.S	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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, at -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, at -r4		! set 8-byte at once
+	bf/s	3b
+	 mov.l	r5, at -r4
+	!
+	mov	#7,r0
+	and	r0,r6
+	tst	r6,r6
+	bt	5f
+	! fill bytes
+4:
+	dt	r6
+	bf/s	4b
+	 mov.b	r5, at -r4
+5:
+	rts
+	 mov	r4,r0

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/printf.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/printf.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/reboot.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/reboot.S	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/rf.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/rf.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/uart.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/uart.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/udivsi3_i4i-Os.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/udivsi3_i4i-Os.S	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at 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, at -r15
+	extu.w r5,r0
+	cmp/eq r5,r0
+	swap.w r4,r0
+	shlr16 r4
+	bf/s large_divisor
+	div0u
+	mov.l r5, at -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, at -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, at -r15
+	cmp/pz r5
+	mov.l r5, at -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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/wlan.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/wlan.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,1211 @@
+/*
+ * carl9170 firmware - used by the ar9170 wireless device
+ *
+ * Interface to the WLAN part of the chip
+ *
+ * Copyright (c) 2000-2005 ZyDAS Technology Corporation
+ * Copyright (c) 2007-2009 Atheros Communications, Inc.
+ * Copyright	2009	Johannes Berg <johannes at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 "timer.h"
+#include "wl.h"
+#include "printf.h"
+#include "rf.h"
+#include "linux/ieee80211.h"
+#include "wol.h"
+
+static void wlan_txunstuck(unsigned int queue)
+{
+	set_wlan_txq_dma_addr(queue, ((uint32_t) fw.wlan.tx_queue[queue].head) | 1);
+}
+
+#ifdef CONFIG_CARL9170FW_DMA_QUEUE_BUMP
+static void wlan_txupdate(unsigned int queue)
+{
+	set_wlan_txq_dma_addr(queue, ((uint32_t) fw.wlan.tx_queue[queue].head));
+}
+
+static void wlan_dma_bump(unsigned int qidx)
+{
+	unsigned int offset = qidx;
+	uint32_t status, trigger;
+
+	status = get(AR9170_MAC_REG_DMA_STATUS) >> 12;
+	trigger = get(AR9170_MAC_REG_DMA_TRIGGER) >> 12;
+
+	while (offset != 0) {
+		status >>= 4;
+		trigger >>= 4;
+		offset--;
+	}
+
+	status &= 0xf;
+	trigger &= 0xf;
+
+	if ((trigger == 0xa) && (status == 0x8)) {
+		DBG("UNSTUCK");
+		wlan_txunstuck(qidx);
+	} else {
+		DBG("UPDATE");
+		wlan_txupdate(qidx);
+	}
+}
+#endif /* CONFIG_CARL9170FW_DMA_QUEUE_BUMP */
+
+#ifdef CONFIG_CARL9170FW_DEBUG
+static void wlan_dump_queue(unsigned int qidx)
+{
+
+	struct dma_desc *desc;
+	struct carl9170_tx_superframe *super;
+	int entries = 0;
+
+	__for_each_desc(desc, &fw.wlan.tx_queue[qidx]) {
+		super = get_super(desc);
+		DBG("%d: %p s:%x c:%x tl:%x ds:%x n:%p l:%p ", entries, desc,
+		    desc->status, desc->ctrl, desc->totalLen,
+		    desc->dataSize, desc->nextAddr, desc->lastAddr);
+
+		DBG("c:%x tr:%d ri:%d l:%x m:%x p:%x fc:%x",
+		    super->s.cookie, super->s.cnt, super->s.rix,
+		    super->f.hdr.length, super->f.hdr.mac.set,
+		    (unsigned int) le32_to_cpu(super->f.hdr.phy.set),
+		    super->f.data.i3e.frame_control);
+
+		entries++;
+	}
+
+	desc = get_wlan_txq_addr(qidx);
+
+	DBG("Queue: %d: te:%d td:%d h:%p c:%p t:%p",
+	    qidx, entries, queue_len(&fw.wlan.tx_queue[qidx]),
+	    fw.wlan.tx_queue[qidx].head,
+	    desc, fw.wlan.tx_queue[qidx].terminator);
+
+	DBG("HW: t:%x s:%x ac:%x c:%x",
+	    (unsigned int) get(AR9170_MAC_REG_DMA_TRIGGER),
+	    (unsigned int) get(AR9170_MAC_REG_DMA_STATUS),
+	    (unsigned int) get(AR9170_MAC_REG_AMPDU_COUNT),
+	    (unsigned int) get(AR9170_MAC_REG_DMA_TXQX_ADDR_CURR));
+}
+#endif /* CONFIG_CARL9170FW_DEBUG */
+
+static void wlan_send_buffered_tx_status(void)
+{
+	unsigned int len;
+
+	while (fw.wlan.tx_status_pending) {
+		len = min((unsigned int)fw.wlan.tx_status_pending,
+			  CARL9170_RSP_TX_STATUS_NUM);
+		len = min(len, CARL9170_TX_STATUS_NUM -	fw.wlan.tx_status_head_idx);
+
+		/*
+		 * rather than memcpy each individual request into a large buffer,
+		 * we _splice_ them all together.
+		 *
+		 * The only downside is however that we have to be careful around
+		 * the edges of the tx_status_cache.
+		 *
+		 * Note:
+		 * Each tx_status is about 2 bytes. However every command package
+		 * must have a size which is a multiple of 4.
+		 */
+
+		send_cmd_to_host((len * sizeof(struct carl9170_tx_status) + 3) & ~3,
+				 CARL9170_RSP_TXCOMP, len, (void *)
+				 &fw.wlan.tx_status_cache[fw.wlan.tx_status_head_idx]);
+
+		fw.wlan.tx_status_pending -= len;
+		fw.wlan.tx_status_head_idx += len;
+		fw.wlan.tx_status_head_idx %= CARL9170_TX_STATUS_NUM;
+	}
+}
+
+static struct carl9170_tx_status *wlan_get_tx_status_buffer(void)
+{
+	struct carl9170_tx_status *tmp;
+
+	tmp = &fw.wlan.tx_status_cache[fw.wlan.tx_status_tail_idx++];
+	fw.wlan.tx_status_tail_idx %= CARL9170_TX_STATUS_NUM;
+
+	if (fw.wlan.tx_status_pending == CARL9170_TX_STATUS_NUM)
+		wlan_send_buffered_tx_status();
+
+	fw.wlan.tx_status_pending++;
+
+	return tmp;
+}
+
+/* generate _aggregated_ tx_status for the host */
+void wlan_tx_complete(struct carl9170_tx_superframe *super,
+		      bool txs)
+{
+	struct carl9170_tx_status *status;
+
+	status = wlan_get_tx_status_buffer();
+
+	/*
+	 * The *unique* cookie and AC_ID is used by the driver for
+	 * frame lookup.
+	 */
+	status->cookie = super->s.cookie;
+	status->queue = super->s.queue;
+	super->s.cookie = 0;
+
+	/*
+	 * This field holds the number of tries of the rate in
+	 * the rate index field (rix).
+	 */
+	status->rix = super->s.rix;
+	status->tries = super->s.cnt;
+	status->success = (txs) ? 1 : 0;
+}
+
+static bool wlan_tx_consume_retry(struct carl9170_tx_superframe *super)
+{
+	/* check if this was the last possible retry with this rate */
+	if (unlikely(super->s.cnt >= super->s.ri[super->s.rix].tries)) {
+		/* end of the road - indicate tx failure */
+		if (unlikely(super->s.rix == CARL9170_TX_MAX_RETRY_RATES))
+			return false;
+
+		/* check if there are alternative rates available */
+		if (!super->s.rr[super->s.rix].set)
+			return false;
+
+		/* try next retry rate */
+		super->f.hdr.phy.set = super->s.rr[super->s.rix].set;
+
+		/* finally - mark the old rate as USED */
+		super->s.rix++;
+
+		/* update MAC flags */
+		super->f.hdr.mac.erp_prot = super->s.ri[super->s.rix].erp_prot;
+		super->f.hdr.mac.ampdu = super->s.ri[super->s.rix].ampdu;
+
+		/* reinitialize try counter */
+		super->s.cnt = 1;
+	} else {
+		/* just increase retry counter */
+		super->s.cnt++;
+	}
+
+	return true;
+}
+
+static inline u16 get_tid(struct ieee80211_hdr *hdr)
+{
+	return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+}
+
+/* This function will only work on uint32_t-aligned pointers! */
+static bool same_hdr(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]) |			/* FC + DU */
+		 (d0[1] ^ d1[1]) |			/* addr1 */
+		 (d0[2] ^ d1[2]) | (d0[3] ^ d1[3]) |	/* addr2 + addr3 */
+		 (d0[4] ^ d1[4]));			/* addr3 */
+}
+
+static inline bool same_aggr(struct ieee80211_hdr *a, struct ieee80211_hdr *b)
+{
+	return (get_tid(a) == get_tid(b)) || same_hdr(a, b);
+}
+
+static void wlan_tx_ampdu_reset(unsigned int qidx)
+{
+	fw.wlan.ampdu_prev[qidx] = NULL;
+}
+
+static void wlan_tx_ampdu_end(unsigned int qidx)
+{
+	struct carl9170_tx_superframe *ht_prev = fw.wlan.ampdu_prev[qidx];
+
+	if (ht_prev)
+		ht_prev->f.hdr.mac.ba_end = 1;
+
+	wlan_tx_ampdu_reset(qidx);
+}
+
+static void wlan_tx_ampdu(struct carl9170_tx_superframe *super)
+{
+	unsigned int qidx = super->s.queue;
+	struct carl9170_tx_superframe *ht_prev = fw.wlan.ampdu_prev[qidx];
+
+	if (super->f.hdr.mac.ampdu) {
+		if (ht_prev &&
+		    !same_aggr(&super->f.data.i3e, &ht_prev->f.data.i3e))
+			ht_prev->f.hdr.mac.ba_end = 1;
+		else
+			super->f.hdr.mac.ba_end = 0;
+
+		fw.wlan.ampdu_prev[qidx] = super;
+	} else {
+		wlan_tx_ampdu_end(qidx);
+	}
+}
+
+/* for all tries */
+static void __wlan_tx(struct dma_desc *desc)
+{
+	struct carl9170_tx_superframe *super = get_super(desc);
+
+	if (unlikely(super->s.fill_in_tsf)) {
+		struct ieee80211_mgmt *mgmt = (void *) &super->f.data.i3e;
+		uint32_t *tsf = (uint32_t *) &mgmt->u.probe_resp.timestamp;
+
+		/*
+		 * Truth be told: this is a hack.
+		 *
+		 * The *real* TSF is definitely going to be higher/older.
+		 * But this hardware emulation code is head and shoulders
+		 * above anything a driver can possibly do.
+		 *
+		 * (even, if it's got an accurate atomic clock source).
+		 */
+
+		read_tsf(tsf);
+	}
+
+	wlan_tx_ampdu(super);
+
+#ifdef CONFIG_CARL9170FW_DEBUG
+	BUG_ON(fw.phy.psm.state != CARL9170_PSM_WAKE);
+#endif /* CONFIG_CARL9170FW_DEBUG */
+
+	/* insert desc into the right queue */
+	dma_put(&fw.wlan.tx_queue[super->s.queue], desc);
+}
+
+static void wlan_assign_seq(struct ieee80211_hdr *hdr, unsigned int vif)
+{
+	hdr->seq_ctrl &= cpu_to_le16(~IEEE80211_SCTL_SEQ);
+	hdr->seq_ctrl |= cpu_to_le16(fw.wlan.sequence[vif]);
+
+	if (ieee80211_is_first_frag(hdr->seq_ctrl))
+		fw.wlan.sequence[vif] += 0x10;
+}
+
+/* prepares frame for the first transmission */
+static void _wlan_tx(struct dma_desc *desc)
+{
+	struct carl9170_tx_superframe *super = get_super(desc);
+
+	if (unlikely(super->s.assign_seq))
+		wlan_assign_seq(&super->f.data.i3e, super->s.vif_id);
+
+	if (unlikely(super->s.ampdu_commit_density)) {
+		set(AR9170_MAC_REG_AMPDU_DENSITY,
+		    MOD_VAL(AR9170_MAC_AMPDU_DENSITY,
+			    get(AR9170_MAC_REG_AMPDU_DENSITY),
+			    super->s.ampdu_density));
+	}
+
+	if (unlikely(super->s.ampdu_commit_factor)) {
+		set(AR9170_MAC_REG_AMPDU_FACTOR,
+		    MOD_VAL(AR9170_MAC_AMPDU_FACTOR,
+			    get(AR9170_MAC_REG_AMPDU_FACTOR),
+			    8 << super->s.ampdu_factor));
+	}
+}
+
+/* propagate transmission status back to the driver */
+static bool wlan_tx_status(struct dma_queue *queue,
+			   struct dma_desc *desc)
+{
+	struct carl9170_tx_superframe *super = get_super(desc);
+	unsigned int qidx = super->s.queue;
+	bool txfail = false, success;
+
+	success = true;
+
+	/* update hangcheck */
+	fw.wlan.last_super_num[qidx] = 0;
+
+	/*
+	 * Note:
+	 * There could be a corner case when the TXFAIL is set
+	 * even though the frame was properly ACKed by the peer:
+	 *   a BlockAckReq with the immediate policy will cause
+	 *   the receiving peer to produce a BlockACK unfortunately
+	 *   the MAC in this chip seems to be expecting a legacy
+	 *   ACK and marks the BAR as failed!
+	 */
+
+	if (!!(desc->ctrl & AR9170_CTRL_FAIL)) {
+		txfail = !!(desc->ctrl & AR9170_CTRL_TXFAIL);
+
+		/* reset retry indicator flags */
+		desc->ctrl &= ~(AR9170_CTRL_TXFAIL | AR9170_CTRL_BAFAIL);
+
+		/*
+		 * Note: wlan_tx_consume_retry will override the old
+		 * phy [CCK,OFDM, HT, BW20/40, MCS...] and mac vectors
+		 * [AMPDU,RTS/CTS,...] therefore be careful when they
+		 * are used.
+		 */
+		if (wlan_tx_consume_retry(super)) {
+			/*
+			 * retry for simple and aggregated 802.11 frames.
+			 *
+			 * Note: We must not mess up the original frame
+			 * order.
+			 */
+
+			if (!super->f.hdr.mac.ampdu) {
+				/*
+				 * 802.11 - 7.1.3.1.5.
+				 * set "Retry Field" for consecutive attempts
+				 *
+				 * Note: For AMPDU see:
+				 * 802.11n 9.9.1.6 "Retransmit Procedures"
+				 */
+				super->f.data.i3e.frame_control |=
+					cpu_to_le16(IEEE80211_FCTL_RETRY);
+			}
+
+			if (txfail) {
+				/* Normal TX Failure */
+
+				/* demise descriptor ownership back to the hardware */
+				dma_rearm(desc);
+
+				/*
+				 * And this will get the queue going again.
+				 * To understand why: you have to get the HW
+				 * specs... But sadly I never saw them.
+				 */
+				wlan_txunstuck(qidx);
+
+				/* abort cycle - this is necessary due to HW design */
+				return false;
+			} else {
+				/* (HT-) BlockACK failure */
+
+				/*
+				 * Unlink the failed attempt and put it into
+				 * the retry queue. The caller routine must
+				 * be aware of this so the frames don't get lost.
+				 */
+
+#ifndef CONFIG_CARL9170FW_DEBUG
+				dma_unlink_head(queue);
+#else /* CONFIG_CARL9170FW_DEBUG */
+				BUG_ON(dma_unlink_head(queue) != desc);
+#endif /* CONFIG_CARL9170FW_DEBUG */
+				dma_put(&fw.wlan.tx_retry, desc);
+				return true;
+			}
+		} else {
+			/* out of frame attempts - discard frame */
+			success = false;
+		}
+	}
+
+#ifndef CONFIG_CARL9170FW_DEBUG
+	dma_unlink_head(queue);
+#else /* CONFIG_CARL9170FW_DEBUG */
+	BUG_ON(dma_unlink_head(queue) != desc);
+#endif /* CONFIG_CARL9170FW_DEBUG */
+	if (txfail) {
+		/*
+		 * Issue the queue bump,
+		 * We need to do this in case this was the frame's last
+		 * possible retry attempt and it unfortunately: it failed.
+		 */
+
+		wlan_txunstuck(qidx);
+	}
+
+	unhide_super(desc);
+
+	if (unlikely(super == fw.wlan.fw_desc_data)) {
+		fw.wlan.fw_desc = desc;
+		fw.wlan.fw_desc_available = 1;
+
+		if (fw.wlan.fw_desc_callback)
+			fw.wlan.fw_desc_callback(super, success);
+
+		return true;
+	}
+
+#ifdef CONFIG_CARL9170FW_CAB_QUEUE
+	if (unlikely(super->s.cab))
+		fw.wlan.cab_queue_len[super->s.vif_id]--;
+#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
+
+	wlan_tx_complete(super, success);
+
+	if (ieee80211_is_back_req(super->f.data.i3e.frame_control)) {
+		fw.wlan.queued_bar--;
+	}
+
+	/* recycle freed descriptors */
+	dma_reclaim(&fw.pta.down_queue, desc);
+	down_trigger();
+	return true;
+}
+
+static void handle_tx_completion(void)
+{
+	struct dma_desc *desc;
+	int i;
+
+	for (i = AR9170_TXQ_SPECIAL; i >= AR9170_TXQ0; i--) {
+		__while_desc_bits(desc, &fw.wlan.tx_queue[i], AR9170_OWN_BITS_SW) {
+			if (!wlan_tx_status(&fw.wlan.tx_queue[i], desc)) {
+				/* termination requested. */
+				break;
+			}
+		}
+
+		wlan_tx_ampdu_reset(i);
+
+		for_each_desc(desc, &fw.wlan.tx_retry)
+			__wlan_tx(desc);
+
+		wlan_tx_ampdu_end(i);
+		if (!queue_empty(&fw.wlan.tx_queue[i]))
+			wlan_trigger(BIT(i));
+	}
+}
+
+void __hot wlan_tx(struct dma_desc *desc)
+{
+	struct carl9170_tx_superframe *super = DESC_PAYLOAD(desc);
+
+	if (ieee80211_is_back_req(super->f.data.i3e.frame_control)) {
+		fw.wlan.queued_bar++;
+	}
+
+	/* initialize rate control struct */
+	super->s.rix = 0;
+	super->s.cnt = 1;
+	hide_super(desc);
+
+#ifdef CONFIG_CARL9170FW_CAB_QUEUE
+	if (unlikely(super->s.cab)) {
+		fw.wlan.cab_queue_len[super->s.vif_id]++;
+		dma_put(&fw.wlan.cab_queue[super->s.vif_id], desc);
+		return;
+	}
+#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
+
+	_wlan_tx(desc);
+	__wlan_tx(desc);
+	wlan_trigger(BIT(super->s.queue));
+}
+
+void wlan_tx_fw(struct carl9170_tx_superdesc *super, fw_desc_callback_t cb)
+{
+	if (!fw.wlan.fw_desc_available)
+		return;
+
+	fw.wlan.fw_desc_available = 0;
+
+	/* Format BlockAck */
+	fw.wlan.fw_desc->ctrl = AR9170_CTRL_FS_BIT | AR9170_CTRL_LS_BIT;
+	fw.wlan.fw_desc->status = AR9170_OWN_BITS_SW;
+
+	fw.wlan.fw_desc->totalLen = fw.wlan.fw_desc->dataSize = super->len;
+	fw.wlan.fw_desc_data = fw.wlan.fw_desc->dataAddr = super;
+	fw.wlan.fw_desc->nextAddr = fw.wlan.fw_desc->lastAddr =
+		fw.wlan.fw_desc;
+	fw.wlan.fw_desc_callback = cb;
+	wlan_tx(fw.wlan.fw_desc);
+}
+
+static void wlan_send_buffered_ba(void)
+{
+	struct carl9170_tx_ba_superframe *baf = &dma_mem.reserved.ba.ba;
+	struct ieee80211_ba *ba = (struct ieee80211_ba *) &baf->f.ba;
+	struct carl9170_bar_ctx *ctx;
+
+	if (likely(!fw.wlan.queued_ba))
+		return;
+
+	/* there's no point to continue when the ba_desc is not available. */
+	if (!fw.wlan.fw_desc_available)
+		return;
+
+	ctx = &fw.wlan.ba_cache[fw.wlan.ba_head_idx];
+	fw.wlan.ba_head_idx++;
+	fw.wlan.ba_head_idx %= CONFIG_CARL9170FW_BACK_REQS_NUM;
+	fw.wlan.queued_ba--;
+
+	baf->s.len = sizeof(struct carl9170_tx_superdesc) +
+		     sizeof(struct ar9170_tx_hwdesc) +
+		     sizeof(struct ieee80211_ba);
+	baf->s.ri[0].tries = 1;
+	baf->s.cookie = 0;
+	baf->s.queue = AR9170_TXQ_VO;
+	baf->f.hdr.length = sizeof(struct ieee80211_ba) + FCS_LEN;
+
+	baf->f.hdr.mac.no_ack = 1;
+
+	baf->f.hdr.phy.modulation = 1; /* OFDM */
+	baf->f.hdr.phy.tx_power = 34; /* 17 dBm */
+	baf->f.hdr.phy.chains = 1;
+	baf->f.hdr.phy.mcs = AR9170_TXRX_PHY_RATE_OFDM_6M;
+
+	/* format outgoing BA */
+	ba->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK);
+	ba->duration = cpu_to_le16(0);
+
+	/* the BAR contains all necessary MACs. All we need is to swap them */
+	memcpy(ba->ra, ctx->ta, 6);
+	memcpy(ba->ta, ctx->ra, 6);
+
+	/*
+	 * Unfortunately, we cannot look into the hardware's scoreboard.
+	 * Therefore we have to proceed as described in 802.11n 9.10.7.5
+	 * and send a null BlockAck.
+	 */
+	memset(ba->bitmap, 0x0, sizeof(ba->bitmap));
+
+	/*
+	 * Both, the original firmare and ath9k set the NO ACK flag in
+	 * the BA Ack Policy subfield.
+	 */
+	ba->control = ctx->control | cpu_to_le16(1);
+	ba->start_seq_num = ctx->start_seq_num;
+	wlan_tx_fw(&baf->s, NULL);
+}
+
+static struct carl9170_bar_ctx *wlan_get_bar_cache_buffer(void)
+{
+	struct carl9170_bar_ctx *tmp;
+
+	tmp = &fw.wlan.ba_cache[fw.wlan.ba_tail_idx];
+	fw.wlan.ba_tail_idx++;
+	fw.wlan.ba_tail_idx %= CONFIG_CARL9170FW_BACK_REQS_NUM;
+	if (fw.wlan.queued_ba < CONFIG_CARL9170FW_BACK_REQS_NUM)
+		fw.wlan.queued_ba++;
+
+	return tmp;
+}
+
+static void handle_bar(struct dma_desc *desc __unused, struct ieee80211_hdr *hdr,
+		       unsigned int len, unsigned int mac_err)
+{
+	struct ieee80211_bar *bar;
+	struct carl9170_bar_ctx *ctx;
+
+	if (unlikely(mac_err)) {
+		/*
+		 * This check does a number of things:
+		 * 1. checks if the frame is in good nick
+		 * 2. checks if the RA (MAC) matches
+		 */
+		return ;
+	}
+
+	if (unlikely(len < (sizeof(struct ieee80211_bar) + FCS_LEN))) {
+		/*
+		 * Sneaky, corrupted BARs... but not with us!
+		 */
+
+		return ;
+	}
+
+	bar = (void *) hdr;
+
+	if ((bar->control & cpu_to_le16(IEEE80211_BAR_CTRL_MULTI_TID)) ||
+	    !(bar->control & cpu_to_le16(IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA))) {
+		/* not implemented yet */
+
+		return ;
+	}
+
+	ctx = wlan_get_bar_cache_buffer();
+
+	memcpy(ctx->ra, bar->ra, 6);
+	memcpy(ctx->ta, bar->ta, 6);
+	ctx->control = bar->control;
+	ctx->start_seq_num = bar->start_seq_num;
+}
+
+static void wlan_check_rx_overrun(void)
+{
+	uint32_t overruns, total;
+
+	fw.tally.rx_total += total = get(AR9170_MAC_REG_RX_TOTAL);
+	fw.tally.rx_overrun += overruns = get(AR9170_MAC_REG_RX_OVERRUN);
+	if (unlikely(overruns)) {
+		if (overruns == total) {
+			DBG("RX Overrun");
+			fw.wlan.mac_reset++;
+		}
+
+		wlan_trigger(AR9170_DMA_TRIGGER_RXQ);
+	}
+}
+
+static unsigned int wlan_rx_filter(struct dma_desc *desc)
+{
+	struct ieee80211_hdr *hdr;
+	unsigned int data_len;
+	unsigned int rx_filter;
+	unsigned int mac_err;
+
+	data_len = ar9170_get_rx_mpdu_len(desc);
+	mac_err = ar9170_get_rx_macstatus_error(desc);
+
+#define AR9170_RX_ERROR_BAD (AR9170_RX_ERROR_FCS | AR9170_RX_ERROR_PLCP)
+
+	if (unlikely(data_len < (4 + 6 + FCS_LEN) ||
+	    desc->totalLen > CONFIG_CARL9170FW_RX_FRAME_LEN) ||
+	    mac_err & AR9170_RX_ERROR_BAD) {
+		/*
+		 * This frame is too damaged to do anything
+		 * useful with it.
+		 */
+
+		return CARL9170_RX_FILTER_BAD;
+	}
+
+	rx_filter = 0;
+	if (mac_err & AR9170_RX_ERROR_WRONG_RA)
+		rx_filter |= CARL9170_RX_FILTER_OTHER_RA;
+
+	if (mac_err & AR9170_RX_ERROR_DECRYPT)
+		rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL;
+
+	hdr = ar9170_get_rx_i3e(desc);
+	if (likely(ieee80211_is_data(hdr->frame_control))) {
+		rx_filter |= CARL9170_RX_FILTER_DATA;
+	} else if (ieee80211_is_ctl(hdr->frame_control)) {
+		switch (le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE) {
+		case IEEE80211_STYPE_BACK_REQ:
+			handle_bar(desc, hdr, data_len, mac_err);
+			rx_filter |= CARL9170_RX_FILTER_CTL_BACKR;
+			break;
+		case IEEE80211_STYPE_PSPOLL:
+			rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL;
+			break;
+		case IEEE80211_STYPE_BACK:
+			if (fw.wlan.queued_bar) {
+				/*
+				 * Don't filter block acks when the application
+				 * has queued BARs. This is because the firmware
+				 * can't do the accouting and the application
+				 * has to sort out if the BA belongs to any BARs.
+				 */
+				break;
+			}
+			/* otherwise fall through */
+		default:
+			rx_filter |= CARL9170_RX_FILTER_CTL_OTHER;
+			break;
+		}
+	} else {
+		/* ieee80211_is_mgmt */
+		rx_filter |= CARL9170_RX_FILTER_MGMT;
+	}
+
+	if (unlikely(fw.suspend_mode == CARL9170_HOST_SUSPENDED)) {
+		wol_rx(rx_filter, hdr, min(data_len,
+			(unsigned int)AR9170_BLOCK_SIZE));
+	}
+
+#undef AR9170_RX_ERROR_BAD
+
+	return rx_filter;
+}
+
+static void handle_rx(void)
+{
+	struct dma_desc *desc;
+
+	for_each_desc_not_bits(desc, &fw.wlan.rx_queue, AR9170_OWN_BITS_HW) {
+		if (!(wlan_rx_filter(desc) & fw.wlan.rx_filter)) {
+			dma_put(&fw.pta.up_queue, desc);
+			up_trigger();
+		} else {
+			dma_reclaim(&fw.wlan.rx_queue, desc);
+			wlan_trigger(AR9170_DMA_TRIGGER_RXQ);
+		}
+	}
+}
+
+#ifdef CONFIG_CARL9170FW_CAB_QUEUE
+void wlan_cab_flush_queue(const unsigned int vif)
+{
+	struct dma_queue *cab_queue = &fw.wlan.cab_queue[vif];
+	struct dma_desc *desc;
+
+	/* move queued frames into the main tx queues */
+	for_each_desc(desc, cab_queue) {
+		struct carl9170_tx_superframe *super = get_super(desc);
+		if (!queue_empty(cab_queue)) {
+			/*
+			 * Set MOREDATA flag for all,
+			 * but the last queued frame.
+			 * see: 802.11-2007 11.2.1.5 f)
+			 *
+			 * This is actually the reason to why
+			 * we need to prevent the reentry.
+			 */
+
+			super->f.data.i3e.frame_control |=
+				cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+		} else {
+			super->f.data.i3e.frame_control &=
+				cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
+		}
+
+		/* ready to roll! */
+		_wlan_tx(desc);
+		__wlan_tx(desc);
+		wlan_trigger(BIT(super->s.queue));
+	}
+}
+
+static uint8_t *beacon_find_ie(uint8_t ie, void *addr,
+			       const unsigned int len)
+{
+	struct ieee80211_mgmt *mgmt = addr;
+	uint8_t *pos, *end;
+
+	pos = mgmt->u.beacon.variable;
+	end = (uint8_t *) ((unsigned long)mgmt + (len - FCS_LEN));
+	while (pos < end) {
+		if (pos + 2 + pos[1] > end)
+			return NULL;
+
+		if (pos[0] == ie)
+			return pos;
+
+		pos += pos[1] + 2;
+	}
+
+	return NULL;
+}
+
+void wlan_modify_beacon(const unsigned int vif,
+	const unsigned int addr, const unsigned int len)
+{
+	uint8_t *_ie;
+	struct ieee80211_tim_ie *ie;
+
+	_ie = beacon_find_ie(WLAN_EID_TIM, (void *)addr, len);
+	if (likely(_ie)) {
+		ie = (struct ieee80211_tim_ie *) &_ie[2];
+
+		if (!queue_empty(&fw.wlan.cab_queue[vif]) && (ie->dtim_count == 0)) {
+			/* schedule DTIM transfer */
+			fw.wlan.cab_flush_trigger[vif] = CARL9170_CAB_TRIGGER_ARMED;
+		} else if ((fw.wlan.cab_queue_len[vif] == 0) && (fw.wlan.cab_flush_trigger[vif])) {
+			/* undo all chances to the beacon structure */
+			ie->bitmap_ctrl &= ~0x1;
+			fw.wlan.cab_flush_trigger[vif] = CARL9170_CAB_TRIGGER_EMPTY;
+		}
+
+		/* Triggered by CARL9170_CAB_TRIGGER_ARMED || CARL9170_CAB_TRIGGER_DEFER */
+		if (fw.wlan.cab_flush_trigger[vif]) {
+			/* Set the almighty Multicast Traffic Indication Bit. */
+			ie->bitmap_ctrl |= 0x1;
+		}
+	}
+
+	/*
+	 * Ideally, the sequence number should be assigned by the TX arbiter
+	 * hardware. But AFAIK that's not possible, so we have to go for the
+	 * next best thing and write it into the beacon fifo during the open
+	 * beacon update window.
+	 */
+
+	wlan_assign_seq((struct ieee80211_hdr *)addr, vif);
+}
+
+static void wlan_send_buffered_cab(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < CARL9170_INTF_NUM; i++) {
+		if (unlikely(fw.wlan.cab_flush_trigger[i] == CARL9170_CAB_TRIGGER_ARMED)) {
+			/*
+			 * This is hardcoded into carl9170usb driver.
+			 *
+			 * The driver must set the PRETBTT event to beacon_interval -
+			 * CARL9170_PRETBTT_KUS (usually 6) Kus.
+			 *
+			 * But still, we can only do so much about 802.11-2007 9.3.2.1 &
+			 * 11.2.1.6. Let's hope the current solution is adequate enough.
+			 */
+
+			if (is_after_msecs(fw.wlan.cab_flush_time, (CARL9170_TBTT_DELTA))) {
+				wlan_cab_flush_queue(i);
+
+				/*
+				 * This prevents the code from sending new BC/MC frames
+				 * which were queued after the previous buffered traffic
+				 * has been sent out... They will have to wait until the
+				 * next DTIM beacon comes along.
+				 */
+				fw.wlan.cab_flush_trigger[i] = CARL9170_CAB_TRIGGER_DEFER;
+			}
+		}
+
+	}
+}
+#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
+
+static void handle_beacon_config(void)
+{
+	uint32_t bcn_count;
+
+	bcn_count = get(AR9170_MAC_REG_BCN_COUNT);
+	send_cmd_to_host(4, CARL9170_RSP_BEACON_CONFIG, 0x00,
+			 (uint8_t *) &bcn_count);
+}
+
+static void handle_pretbtt(void)
+{
+#ifdef CONFIG_CARL9170FW_CAB_QUEUE
+	fw.wlan.cab_flush_time = get_clock_counter();
+#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
+
+#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
+	rf_psm();
+
+	send_cmd_to_host(4, CARL9170_RSP_PRETBTT, 0x00,
+			 (uint8_t *) &fw.phy.psm.state);
+#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
+}
+
+static void handle_atim(void)
+{
+	send_cmd_to_host(0, CARL9170_RSP_ATIM, 0x00, NULL);
+}
+
+#ifdef CONFIG_CARL9170FW_DEBUG
+static void handle_qos(void)
+{
+	/*
+	 * What is the QoS Bit used for?
+	 * Is it only an indicator for TXOP & Burst, or
+	 * should we do something here?
+	 */
+}
+
+static void handle_radar(void)
+{
+	send_cmd_to_host(0, CARL9170_RSP_RADAR, 0x00, NULL);
+}
+#endif /* CONFIG_CARL9170FW_DEBUG */
+
+static void wlan_janitor(void)
+{
+#ifdef CONFIG_CARL9170FW_CAB_QUEUE
+	wlan_send_buffered_cab();
+#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
+
+	wlan_send_buffered_tx_status();
+
+	wlan_send_buffered_ba();
+
+	wol_janitor();
+}
+
+void handle_wlan(void)
+{
+	uint32_t intr;
+
+	intr = get(AR9170_MAC_REG_INT_CTRL);
+	/* ACK Interrupt */
+	set(AR9170_MAC_REG_INT_CTRL, intr);
+
+#define HANDLER(intr, flag, func)			\
+	do {						\
+		if ((intr & flag) != 0) {		\
+			func();				\
+		}					\
+	} while (0)
+
+	intr |= fw.wlan.soft_int;
+	fw.wlan.soft_int = 0;
+
+	HANDLER(intr, AR9170_MAC_INT_PRETBTT, handle_pretbtt);
+
+	HANDLER(intr, AR9170_MAC_INT_ATIM, handle_atim);
+
+	HANDLER(intr, AR9170_MAC_INT_RXC, handle_rx);
+
+	HANDLER(intr, (AR9170_MAC_INT_TXC | AR9170_MAC_INT_RETRY_FAIL),
+		handle_tx_completion);
+
+#ifdef CONFIG_CARL9170FW_DEBUG
+	HANDLER(intr, AR9170_MAC_INT_QOS, handle_qos);
+
+	HANDLER(intr, AR9170_MAC_INT_RADAR, handle_radar);
+#endif /* CONFIG_CARL9170FW_DEBUG */
+
+	HANDLER(intr, AR9170_MAC_INT_CFG_BCN, handle_beacon_config);
+
+	if (unlikely(intr))
+		DBG("Unhandled Interrupt %x\n", (unsigned int) intr);
+
+	wlan_janitor();
+
+#undef HANDLER
+}
+
+enum {
+	CARL9170FW_TX_MAC_BUMP = 4,
+	CARL9170FW_TX_MAC_DEBUG = 6,
+	CARL9170FW_TX_MAC_RESET = 7,
+};
+
+static void wlan_check_hang(void)
+{
+	struct dma_desc *desc;
+	int i;
+
+	for (i = AR9170_TXQ_SPECIAL; i >= AR9170_TXQ0; i--) {
+		if (queue_empty(&fw.wlan.tx_queue[i])) {
+			/* Nothing to do here... move along */
+			continue;
+		}
+
+		/* fetch the current DMA queue position */
+		desc = (struct dma_desc *)get_wlan_txq_addr(i);
+
+		/* Stuck frame detection */
+		if (unlikely(DESC_PAYLOAD(desc) == fw.wlan.last_super[i])) {
+			fw.wlan.last_super_num[i]++;
+
+			if (unlikely(fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_RESET)) {
+				/*
+				 * schedule MAC reset (aka OFF/ON => dead)
+				 *
+				 * This will almost certainly kill
+				 * the device for good, but it's the
+				 * recommended thing to do...
+				 */
+
+				fw.wlan.mac_reset++;
+			}
+
+#ifdef CONFIG_CARL9170FW_DEBUG
+			if (unlikely(fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_DEBUG)) {
+				/*
+				 * Sigh, the queue is almost certainly
+				 * dead. Dump the queue content to the
+				 * user, maybe we find out why it got
+				 * so stuck.
+				 */
+
+				wlan_dump_queue(i);
+			}
+#endif /* CONFIG_CARL9170FW_DEBUG */
+
+#ifdef CONFIG_CARL9170FW_DMA_QUEUE_BUMP
+			if (unlikely(fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_BUMP)) {
+				/*
+				 * Hrrm, bump the queue a bit.
+				 * maybe this will get it going again.
+				 */
+
+				wlan_dma_bump(i);
+				wlan_trigger(BIT(i));
+			}
+#endif /* CONFIG_CARL9170FW_DMA_QUEUE_BUMP */
+		} else {
+			/* Nothing stuck */
+			fw.wlan.last_super[i] = DESC_PAYLOAD(desc);
+			fw.wlan.last_super_num[i] = 0;
+		}
+	}
+}
+
+#ifdef CONFIG_CARL9170FW_FW_MAC_RESET
+/*
+ * NB: Resetting the MAC is a two-edged sword.
+ * On most occasions, it does what it is supposed to do.
+ * But there is a chance that this will make it
+ * even worse and the radio dies silently.
+ */
+static void wlan_mac_reset(void)
+{
+	uint32_t val;
+	uint32_t agg_wait_counter;
+	uint32_t agg_density;
+	uint32_t bcn_start_addr;
+	uint32_t rctl, rcth;
+	uint32_t cam_mode;
+	uint32_t ack_power;
+	uint32_t rts_cts_tpc;
+	uint32_t rts_cts_rate;
+	int i;
+
+#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
+	uint32_t rx_BB;
+#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
+
+#ifdef CONFIG_CARL9170FW_NOISY_MAC_RESET
+	INFO("MAC RESET");
+#endif /* CONFIG_CARL9170FW_NOISY_MAC_RESET */
+
+	/* Save aggregation parameters */
+	agg_wait_counter = get(AR9170_MAC_REG_AMPDU_FACTOR);
+	agg_density = get(AR9170_MAC_REG_AMPDU_DENSITY);
+
+	bcn_start_addr = get(AR9170_MAC_REG_BCN_ADDR);
+
+	cam_mode = get(AR9170_MAC_REG_CAM_MODE);
+	rctl = get(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L);
+	rcth = get(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H);
+
+	ack_power = get(AR9170_MAC_REG_ACK_TPC);
+	rts_cts_tpc = get(AR9170_MAC_REG_RTS_CTS_TPC);
+	rts_cts_rate = get(AR9170_MAC_REG_RTS_CTS_RATE);
+
+#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
+	/* 0x1c8960 write only */
+	rx_BB = get(AR9170_PHY_REG_SWITCH_CHAIN_0);
+#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
+
+	/* TX/RX must be stopped by now */
+	val = get(AR9170_MAC_REG_POWER_STATE_CTRL);
+
+	val |= AR9170_MAC_POWER_STATE_CTRL_RESET;
+
+	/*
+	 * Manipulate CCA threshold to stop transmission
+	 *
+	 * set(AR9170_PHY_REG_CCA_THRESHOLD, 0x300);
+	 */
+
+	/*
+	 * check Rx state in 0(idle) 9(disable)
+	 *
+	 * chState = (get(AR9170_MAC_REG_MISC_684) >> 16) & 0xf;
+	 * while( (chState != 0) && (chState != 9)) {
+	 *	chState = (get(AR9170_MAC_REG_MISC_684) >> 16) & 0xf;
+	 * }
+	 */
+
+	set(AR9170_MAC_REG_POWER_STATE_CTRL, val);
+
+	delay(2);
+
+	/* Restore aggregation parameters */
+	set(AR9170_MAC_REG_AMPDU_FACTOR, agg_wait_counter);
+	set(AR9170_MAC_REG_AMPDU_DENSITY, agg_density);
+
+	set(AR9170_MAC_REG_BCN_ADDR, bcn_start_addr);
+	set(AR9170_MAC_REG_CAM_MODE, cam_mode);
+	set(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L, rctl);
+	set(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H, rcth);
+
+	set(AR9170_MAC_REG_RTS_CTS_TPC, rts_cts_tpc);
+	set(AR9170_MAC_REG_ACK_TPC, ack_power);
+	set(AR9170_MAC_REG_RTS_CTS_RATE, rts_cts_rate);
+
+#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
+	set(AR9170_PHY_REG_SWITCH_CHAIN_2, rx_BB);
+#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
+
+	/*
+	 * Manipulate CCA threshold to resume transmission
+	 *
+	 * set(AR9170_PHY_REG_CCA_THRESHOLD, 0x0);
+	 */
+
+	val = AR9170_DMA_TRIGGER_RXQ;
+	/* Reinitialize all WLAN TX DMA queues. */
+	for (i = AR9170_TXQ_SPECIAL; i >= AR9170_TXQ0; i--) {
+		struct dma_desc *iter;
+
+		__for_each_desc_bits(iter, &fw.wlan.tx_queue[i], AR9170_OWN_BITS_SW);
+
+		/* kill the stuck frame */
+		if (!is_terminator(&fw.wlan.tx_queue[i], iter) &&
+		    fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_RESET &&
+		    fw.wlan.last_super[i] == DESC_PAYLOAD(iter)) {
+			struct carl9170_tx_superframe *super = get_super(iter);
+
+			iter->status = AR9170_OWN_BITS_SW;
+			/*
+			 * Mark the frame as failed.
+			 * The BAFAIL flag allows the frame to sail through
+			 * wlan_tx_status without much "unstuck" trouble.
+			 */
+			iter->ctrl &= ~(AR9170_CTRL_FAIL);
+			iter->ctrl |= AR9170_CTRL_BAFAIL;
+
+			super->s.cnt = CARL9170_TX_MAX_RATE_TRIES;
+			super->s.rix = CARL9170_TX_MAX_RETRY_RATES;
+
+			fw.wlan.last_super_num[i] = 0;
+			fw.wlan.last_super[i] = NULL;
+			iter = iter->lastAddr->nextAddr;
+		}
+
+		set_wlan_txq_dma_addr(i, (uint32_t) iter);
+		if (!is_terminator(&fw.wlan.tx_queue[i], iter))
+			val |= BIT(i);
+
+		DBG("Q:%d l:%d h:%p t:%p cu:%p it:%p ct:%x st:%x\n", i, queue_len(&fw.wlan.tx_queue[i]),
+		     fw.wlan.tx_queue[i].head, fw.wlan.tx_queue[i].terminator,
+		     get_wlan_txq_addr(i), iter, iter->ctrl, iter->status);
+	}
+
+	fw.wlan.soft_int |= AR9170_MAC_INT_RXC | AR9170_MAC_INT_TXC |
+			    AR9170_MAC_INT_RETRY_FAIL;
+
+	set(AR9170_MAC_REG_DMA_RXQ_ADDR, (uint32_t) fw.wlan.rx_queue.head);
+	wlan_trigger(val);
+}
+#else
+static void wlan_mac_reset(void)
+{
+	/* The driver takes care of reinitializing the device */
+	BUG("MAC RESET");
+}
+#endif /* CONFIG_CARL9170FW_FW_MAC_RESET */
+
+void __cold wlan_timer(void)
+{
+	unsigned int cached_mac_reset;
+
+	cached_mac_reset = fw.wlan.mac_reset;
+
+	/* TX Queue Hang check */
+	wlan_check_hang();
+
+	/* RX Overrun check */
+	wlan_check_rx_overrun();
+
+	if (unlikely(fw.wlan.mac_reset >= CARL9170_MAC_RESET_RESET)) {
+		wlan_mac_reset();
+		fw.wlan.mac_reset = CARL9170_MAC_RESET_OFF;
+	} else {
+		if (fw.wlan.mac_reset && cached_mac_reset == fw.wlan.mac_reset)
+			fw.wlan.mac_reset--;
+	}
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/wol.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/src/wol.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,287 @@
+/*
+ * carl9170 firmware - used by the ar9170 wireless device
+ *
+ * WakeUp on WLAN functions
+ *
+ * Copyright 2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/Kconfig
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/Kconfig	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/fifo.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/fifo.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/main.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/main.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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)
+{
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/usb.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/carlfw/usb/usb.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at sipsolutions.net>
+ * Copyright 2009-2011	Christian Lamparter <chunkeey at 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;
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/CMakeLists.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/CMakeLists.txt	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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})

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/conf.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/conf.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,646 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel at 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");
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/confdata.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/confdata.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,1170 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel at linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <sys/stat.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "lkc.h"
+
+static void conf_warning(const char *fmt, ...)
+	__attribute__ ((format (printf, 1, 2)));
+
+static void conf_message(const char *fmt, ...)
+	__attribute__ ((format (printf, 1, 2)));
+
+static const char *conf_filename;
+static int conf_lineno, conf_warnings, conf_unsaved;
+
+const char conf_defname[] = "include/generated/defconfig";
+
+static void conf_warning(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
+	vfprintf(stderr, fmt, ap);
+	fprintf(stderr, "\n");
+	va_end(ap);
+	conf_warnings++;
+}
+
+static void conf_default_message_callback(const char *fmt, va_list ap)
+{
+	printf("#\n# ");
+	vprintf(fmt, ap);
+	printf("\n#\n");
+}
+
+static void (*conf_message_callback) (const char *fmt, va_list ap) =
+	conf_default_message_callback;
+void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
+{
+	conf_message_callback = fn;
+}
+
+static void conf_message(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	if (conf_message_callback)
+		conf_message_callback(fmt, ap);
+}
+
+const char *conf_get_configname(void)
+{
+	char *name = getenv("KCONFIG_CONFIG");
+
+	return name ? name : ".config";
+}
+
+const char *conf_get_autoconfig_name(void)
+{
+	char *name = getenv("KCONFIG_AUTOCONFIG");
+
+	return name ? name : "include/generated/auto.conf";
+}
+
+static char *conf_expand_value(const char *in)
+{
+	struct symbol *sym;
+	const char *src;
+	static char res_value[SYMBOL_MAXLENGTH];
+	char *dst, name[SYMBOL_MAXLENGTH];
+
+	res_value[0] = 0;
+	dst = name;
+	while ((src = strchr(in, '$'))) {
+		strncat(res_value, in, src - in);
+		src++;
+		dst = name;
+		while (isalnum(*src) || *src == '_')
+			*dst++ = *src++;
+		*dst = 0;
+		sym = sym_lookup(name, 0);
+		sym_calc_value(sym);
+		strcat(res_value, sym_get_string_value(sym));
+		in = src;
+	}
+	strcat(res_value, in);
+
+	return res_value;
+}
+
+char *conf_get_default_confname(void)
+{
+	struct stat buf;
+	static char fullname[PATH_MAX+1];
+	char *env, *name;
+
+	name = conf_expand_value(conf_defname);
+	env = getenv(SRCTREE);
+	if (env) {
+		sprintf(fullname, "%s/%s", env, name);
+		if (!stat(fullname, &buf))
+			return fullname;
+	}
+	return name;
+}
+
+static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
+{
+	char *p2;
+
+	switch (sym->type) {
+	case S_TRISTATE:
+		if (p[0] == 'm') {
+			sym->def[def].tri = mod;
+			sym->flags |= def_flags;
+			break;
+		}
+		/* fall through */
+	case S_BOOLEAN:
+		if (p[0] == 'y') {
+			sym->def[def].tri = yes;
+			sym->flags |= def_flags;
+			break;
+		}
+		if (p[0] == 'n') {
+			sym->def[def].tri = no;
+			sym->flags |= def_flags;
+			break;
+		}
+		conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+		return 1;
+	case S_OTHER:
+		if (*p != '"') {
+			for (p2 = p; *p2 && !isspace(*p2); p2++)
+				;
+			sym->type = S_STRING;
+			goto done;
+		}
+		/* fall through */
+	case S_STRING:
+		if (*p++ != '"')
+			break;
+		for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+			if (*p2 == '"') {
+				*p2 = 0;
+				break;
+			}
+			memmove(p2, p2 + 1, strlen(p2));
+		}
+		if (!p2) {
+			conf_warning("invalid string found");
+			return 1;
+		}
+		/* fall through */
+	case S_INT:
+	case S_HEX:
+	done:
+		if (sym_string_valid(sym, p)) {
+			sym->def[def].val = strdup(p);
+			sym->flags |= def_flags;
+		} else {
+			conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+			return 1;
+		}
+		break;
+	default:
+		;
+	}
+	return 0;
+}
+
+int conf_read_simple(const char *name, int def)
+{
+	FILE *in = NULL;
+	char line[1024];
+	char *p, *p2;
+	struct symbol *sym;
+	int i, def_flags;
+
+	if (name) {
+		in = zconf_fopen(name);
+	} else {
+		struct property *prop;
+
+		name = conf_get_configname();
+		in = zconf_fopen(name);
+		if (in)
+			goto load;
+		sym_add_change_count(1);
+		if (!sym_defconfig_list) {
+			if (modules_sym)
+				sym_calc_value(modules_sym);
+			return 1;
+		}
+
+		for_all_defaults(sym_defconfig_list, prop) {
+			if (expr_calc_value(prop->visible.expr) == no ||
+			    prop->expr->type != E_SYMBOL)
+				continue;
+			name = conf_expand_value(prop->expr->left.sym->name);
+			in = zconf_fopen(name);
+			if (in) {
+				conf_message(_("using defaults found in %s"),
+					 name);
+				goto load;
+			}
+		}
+	}
+	if (!in)
+		return 1;
+
+load:
+	conf_filename = name;
+	conf_lineno = 0;
+	conf_warnings = 0;
+	conf_unsaved = 0;
+
+	def_flags = SYMBOL_DEF << def;
+	for_all_symbols(i, sym) {
+		sym->flags |= SYMBOL_CHANGED;
+		sym->flags &= ~(def_flags|SYMBOL_VALID);
+		if (sym_is_choice(sym))
+			sym->flags |= def_flags;
+		switch (sym->type) {
+		case S_INT:
+		case S_HEX:
+		case S_STRING:
+			if (sym->def[def].val)
+				free(sym->def[def].val);
+			/* fall through */
+		default:
+			sym->def[def].val = NULL;
+			sym->def[def].tri = no;
+		}
+	}
+
+	while (fgets(line, sizeof(line), in)) {
+		conf_lineno++;
+		sym = NULL;
+		if (line[0] == '#') {
+			if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
+				continue;
+			p = strchr(line + 2 + strlen(CONFIG_), ' ');
+			if (!p)
+				continue;
+			*p++ = 0;
+			if (strncmp(p, "is not set", 10))
+				continue;
+			if (def == S_DEF_USER) {
+				sym = sym_find(line + 2 + strlen(CONFIG_));
+				if (!sym) {
+					sym_add_change_count(1);
+					goto setsym;
+				}
+			} else {
+				sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
+				if (sym->type == S_UNKNOWN)
+					sym->type = S_BOOLEAN;
+			}
+			if (sym->flags & def_flags) {
+				conf_warning("override: reassigning to symbol %s", sym->name);
+			}
+			switch (sym->type) {
+			case S_BOOLEAN:
+			case S_TRISTATE:
+				sym->def[def].tri = no;
+				sym->flags |= def_flags;
+				break;
+			default:
+				;
+			}
+		} else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
+			p = strchr(line + strlen(CONFIG_), '=');
+			if (!p)
+				continue;
+			*p++ = 0;
+			p2 = strchr(p, '\n');
+			if (p2) {
+				*p2-- = 0;
+				if (*p2 == '\r')
+					*p2 = 0;
+			}
+			if (def == S_DEF_USER) {
+				sym = sym_find(line + strlen(CONFIG_));
+				if (!sym) {
+					sym_add_change_count(1);
+					goto setsym;
+				}
+			} else {
+				sym = sym_lookup(line + strlen(CONFIG_), 0);
+				if (sym->type == S_UNKNOWN)
+					sym->type = S_OTHER;
+			}
+			if (sym->flags & def_flags) {
+				conf_warning("override: reassigning to symbol %s", sym->name);
+			}
+			if (conf_set_sym_val(sym, def, def_flags, p))
+				continue;
+		} else {
+			if (line[0] != '\r' && line[0] != '\n')
+				conf_warning("unexpected data");
+			continue;
+		}
+setsym:
+		if (sym && sym_is_choice_value(sym)) {
+			struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+			switch (sym->def[def].tri) {
+			case no:
+				break;
+			case mod:
+				if (cs->def[def].tri == yes) {
+					conf_warning("%s creates inconsistent choice state", sym->name);
+					cs->flags &= ~def_flags;
+				}
+				break;
+			case yes:
+				if (cs->def[def].tri != no)
+					conf_warning("override: %s changes choice state", sym->name);
+				cs->def[def].val = sym;
+				break;
+			}
+			cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
+		}
+	}
+	fclose(in);
+
+	if (modules_sym)
+		sym_calc_value(modules_sym);
+	return 0;
+}
+
+int conf_read(const char *name)
+{
+	struct symbol *sym;
+	int i;
+
+	sym_set_change_count(0);
+
+	if (conf_read_simple(name, S_DEF_USER))
+		return 1;
+
+	for_all_symbols(i, sym) {
+		sym_calc_value(sym);
+		if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
+			continue;
+		if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
+			/* check that calculated value agrees with saved value */
+			switch (sym->type) {
+			case S_BOOLEAN:
+			case S_TRISTATE:
+				if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
+					break;
+				if (!sym_is_choice(sym))
+					continue;
+				/* fall through */
+			default:
+				if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
+					continue;
+				break;
+			}
+		} else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
+			/* no previous value and not saved */
+			continue;
+		conf_unsaved++;
+		/* maybe print value in verbose mode... */
+	}
+
+	for_all_symbols(i, sym) {
+		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
+			/* Reset values of generates values, so they'll appear
+			 * as new, if they should become visible, but that
+			 * doesn't quite work if the Kconfig and the saved
+			 * configuration disagree.
+			 */
+			if (sym->visible == no && !conf_unsaved)
+				sym->flags &= ~SYMBOL_DEF_USER;
+			switch (sym->type) {
+			case S_STRING:
+			case S_INT:
+			case S_HEX:
+				/* Reset a string value if it's out of range */
+				if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
+					break;
+				sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+				conf_unsaved++;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	sym_add_change_count(conf_warnings || conf_unsaved);
+
+	return 0;
+}
+
+/*
+ * Kconfig configuration printer
+ *
+ * This printer is used when generating the resulting configuration after
+ * kconfig invocation and `defconfig' files. Unset symbol might be omitted by
+ * passing a non-NULL argument to the printer.
+ *
+ */
+static void
+kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
+{
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		if (*value == 'n') {
+			bool skip_unset = (arg != NULL);
+
+			if (!skip_unset)
+				fprintf(fp, "# %s%s is not set\n",
+				    CONFIG_, sym->name);
+			return;
+		}
+		break;
+	default:
+		break;
+	}
+
+	fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value);
+}
+
+static void
+kconfig_print_cmake_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
+{
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		if (*value == 'n') {
+			bool skip_unset = (arg != NULL);
+
+			if (!skip_unset)
+				fprintf(fp, "set(%s%s false)\n",
+					CONFIG_, sym->name, value);
+			return;
+		} else if (*value == 'm') {
+			abort();
+		} else {
+			fprintf(fp, "set(%s%s true)\n", CONFIG_, sym->name, value);
+		}
+		break;
+	case S_HEX: {
+		const char *prefix = "";
+
+		if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X'))
+			prefix = "0x";
+		fprintf(fp, "set(%s%s %s%s)\n",
+		    CONFIG_, sym->name, prefix, value);
+		break;
+	}
+	case S_STRING:
+	case S_INT:
+		fprintf(fp, "set(%s%s %s)\n",
+		    CONFIG_, sym->name, value);
+		break;
+	default:
+		break;
+	}
+
+}
+
+static void
+kconfig_print_comment(FILE *fp, const char *value, void *arg)
+{
+	const char *p = value;
+	size_t l;
+
+	for (;;) {
+		l = strcspn(p, "\n");
+		fprintf(fp, "#");
+		if (l) {
+			fprintf(fp, " ");
+			xfwrite(p, l, 1, fp);
+			p += l;
+		}
+		fprintf(fp, "\n");
+		if (*p++ == '\0')
+			break;
+	}
+}
+
+static struct conf_printer kconfig_printer_cb =
+{
+	.print_symbol = kconfig_print_symbol,
+	.print_comment = kconfig_print_comment,
+};
+
+static struct conf_printer kconfig_printer_cmake_cb =
+{
+	.print_symbol = kconfig_print_cmake_symbol,
+	.print_comment = kconfig_print_comment,
+};
+
+/*
+ * Header printer
+ *
+ * This printer is used when generating the `include/generated/autoconf.h' file.
+ */
+static void
+header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
+{
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE: {
+		const char *suffix = "";
+
+		switch (*value) {
+		case 'n':
+			break;
+		case 'm':
+			suffix = "_MODULE";
+			/* fall through */
+		default:
+			fprintf(fp, "#define %s%s%s 1\n",
+			    CONFIG_, sym->name, suffix);
+		}
+		break;
+	}
+	case S_HEX: {
+		const char *prefix = "";
+
+		if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X'))
+			prefix = "0x";
+		fprintf(fp, "#define %s%s %s%s\n",
+		    CONFIG_, sym->name, prefix, value);
+		break;
+	}
+	case S_STRING:
+	case S_INT:
+		fprintf(fp, "#define %s%s %s\n",
+		    CONFIG_, sym->name, value);
+		break;
+	default:
+		break;
+	}
+
+}
+
+static void
+header_print_comment(FILE *fp, const char *value, void *arg)
+{
+	const char *p = value;
+	size_t l;
+
+	fprintf(fp, "/*\n");
+	for (;;) {
+		l = strcspn(p, "\n");
+		fprintf(fp, " *");
+		if (l) {
+			fprintf(fp, " ");
+			xfwrite(p, l, 1, fp);
+			p += l;
+		}
+		fprintf(fp, "\n");
+		if (*p++ == '\0')
+			break;
+	}
+	fprintf(fp, " */\n");
+}
+
+static struct conf_printer header_printer_cb =
+{
+	.print_symbol = header_print_symbol,
+	.print_comment = header_print_comment,
+};
+
+/*
+ * Tristate printer
+ *
+ * This printer is used when generating the `include/generated/tristate.conf' file.
+ */
+static void
+tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
+{
+
+	if (sym->type == S_TRISTATE && *value != 'n')
+		fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value));
+}
+
+static struct conf_printer tristate_printer_cb =
+{
+	.print_symbol = tristate_print_symbol,
+	.print_comment = kconfig_print_comment,
+};
+
+static void conf_write_symbol(FILE *fp, struct symbol *sym,
+			      struct conf_printer *printer, void *printer_arg)
+{
+	const char *str;
+
+	switch (sym->type) {
+	case S_OTHER:
+	case S_UNKNOWN:
+		break;
+	case S_STRING:
+		str = sym_get_string_value(sym);
+		str = sym_escape_string_value(str);
+		printer->print_symbol(fp, sym, str, printer_arg);
+		free((void *)str);
+		break;
+	default:
+		str = sym_get_string_value(sym);
+		printer->print_symbol(fp, sym, str, printer_arg);
+	}
+}
+
+static void
+conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg)
+{
+	char buf[256];
+
+	snprintf(buf, sizeof(buf),
+	    "\n"
+	    "Automatically generated file; DO NOT EDIT.\n"
+	    "%s\n",
+	    rootmenu.prompt->text);
+
+	printer->print_comment(fp, buf, printer_arg);
+}
+
+/*
+ * Write out a minimal config.
+ * All values that has default values are skipped as this is redundant.
+ */
+int conf_write_defconfig(const char *filename)
+{
+	struct symbol *sym;
+	struct menu *menu;
+	FILE *out;
+
+	out = fopen(filename, "w");
+	if (!out)
+		return 1;
+
+	sym_clear_all_valid();
+
+	/* Traverse all menus to find all relevant symbols */
+	menu = rootmenu.list;
+
+	while (menu != NULL)
+	{
+		sym = menu->sym;
+		if (sym == NULL) {
+			if (!menu_is_visible(menu))
+				goto next_menu;
+		} else if (!sym_is_choice(sym)) {
+			sym_calc_value(sym);
+			if (!(sym->flags & SYMBOL_WRITE))
+				goto next_menu;
+			sym->flags &= ~SYMBOL_WRITE;
+			/* If we cannot change the symbol - skip */
+			if (!sym_is_changable(sym))
+				goto next_menu;
+			/* If symbol equals to default value - skip */
+			if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
+				goto next_menu;
+
+			/*
+			 * If symbol is a choice value and equals to the
+			 * default for a choice - skip.
+			 * But only if value is bool and equal to "y" and
+			 * choice is not "optional".
+			 * (If choice is "optional" then all values can be "n")
+			 */
+			if (sym_is_choice_value(sym)) {
+				struct symbol *cs;
+				struct symbol *ds;
+
+				cs = prop_get_symbol(sym_get_choice_prop(sym));
+				ds = sym_choice_default(cs);
+				if (!sym_is_optional(cs) && sym == ds) {
+					if ((sym->type == S_BOOLEAN) &&
+					    sym_get_tristate_value(sym) == yes)
+						goto next_menu;
+				}
+			}
+			conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
+		}
+next_menu:
+		if (menu->list != NULL) {
+			menu = menu->list;
+		}
+		else if (menu->next != NULL) {
+			menu = menu->next;
+		} else {
+			while ((menu = menu->parent)) {
+				if (menu->next != NULL) {
+					menu = menu->next;
+					break;
+				}
+			}
+		}
+	}
+	fclose(out);
+	return 0;
+}
+
+int conf_write(const char *name)
+{
+	FILE *out;
+	struct symbol *sym;
+	struct menu *menu;
+	const char *basename;
+	const char *str;
+	char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
+	char *env;
+
+	dirname[0] = 0;
+	if (name && name[0]) {
+		struct stat st;
+		char *slash;
+
+		if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
+			strcpy(dirname, name);
+			strcat(dirname, "/");
+			basename = conf_get_configname();
+		} else if ((slash = strrchr(name, '/'))) {
+			int size = slash - name + 1;
+			memcpy(dirname, name, size);
+			dirname[size] = 0;
+			if (slash[1])
+				basename = slash + 1;
+			else
+				basename = conf_get_configname();
+		} else
+			basename = name;
+	} else
+		basename = conf_get_configname();
+
+	sprintf(newname, "%s%s", dirname, basename);
+	env = getenv("KCONFIG_OVERWRITECONFIG");
+	if (!env || !*env) {
+		sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
+		out = fopen(tmpname, "w");
+	} else {
+		*tmpname = 0;
+		out = fopen(newname, "w");
+	}
+	if (!out)
+		return 1;
+
+	conf_write_heading(out, &kconfig_printer_cb, NULL);
+
+	if (!conf_get_changed())
+		sym_clear_all_valid();
+
+	menu = rootmenu.list;
+	while (menu) {
+		sym = menu->sym;
+		if (!sym) {
+			if (!menu_is_visible(menu))
+				goto next;
+			str = menu_get_prompt(menu);
+			fprintf(out, "\n"
+				     "#\n"
+				     "# %s\n"
+				     "#\n", str);
+		} else if (!(sym->flags & SYMBOL_CHOICE)) {
+			sym_calc_value(sym);
+			if (!(sym->flags & SYMBOL_WRITE))
+				goto next;
+			sym->flags &= ~SYMBOL_WRITE;
+
+			conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
+		}
+
+next:
+		if (menu->list) {
+			menu = menu->list;
+			continue;
+		}
+		if (menu->next)
+			menu = menu->next;
+		else while ((menu = menu->parent)) {
+			if (menu->next) {
+				menu = menu->next;
+				break;
+			}
+		}
+	}
+	fclose(out);
+
+	if (*tmpname) {
+		strcat(dirname, basename);
+		strcat(dirname, ".old");
+		rename(newname, dirname);
+		if (rename(tmpname, newname))
+			return 1;
+	}
+
+	conf_message(_("configuration written to %s"), newname);
+
+	sym_set_change_count(0);
+
+	return 0;
+}
+
+static int conf_split_config(void)
+{
+	const char *name;
+	char path[PATH_MAX+1];
+	char *s, *d, c;
+	struct symbol *sym;
+	struct stat sb;
+	int res, i, fd;
+
+	name = conf_get_autoconfig_name();
+	conf_read_simple(name, S_DEF_AUTO);
+
+	if (chdir("include/generated"))
+		return 1;
+
+	res = 0;
+	for_all_symbols(i, sym) {
+		sym_calc_value(sym);
+		if ((sym->flags & SYMBOL_AUTO) || !sym->name)
+			continue;
+		if (sym->flags & SYMBOL_WRITE) {
+			if (sym->flags & SYMBOL_DEF_AUTO) {
+				/*
+				 * symbol has old and new value,
+				 * so compare them...
+				 */
+				switch (sym->type) {
+				case S_BOOLEAN:
+				case S_TRISTATE:
+					if (sym_get_tristate_value(sym) ==
+					    sym->def[S_DEF_AUTO].tri)
+						continue;
+					break;
+				case S_STRING:
+				case S_HEX:
+				case S_INT:
+					if (!strcmp(sym_get_string_value(sym),
+						    sym->def[S_DEF_AUTO].val))
+						continue;
+					break;
+				default:
+					break;
+				}
+			} else {
+				/*
+				 * If there is no old value, only 'no' (unset)
+				 * is allowed as new value.
+				 */
+				switch (sym->type) {
+				case S_BOOLEAN:
+				case S_TRISTATE:
+					if (sym_get_tristate_value(sym) == no)
+						continue;
+					break;
+				default:
+					break;
+				}
+			}
+		} else if (!(sym->flags & SYMBOL_DEF_AUTO))
+			/* There is neither an old nor a new value. */
+			continue;
+		/* else
+		 *	There is an old value, but no new value ('no' (unset)
+		 *	isn't saved in auto.conf, so the old value is always
+		 *	different from 'no').
+		 */
+
+		/* Replace all '_' and append ".h" */
+		s = sym->name;
+		d = path;
+		while ((c = *s++)) {
+			c = tolower(c);
+			*d++ = (c == '_') ? '/' : c;
+		}
+		strcpy(d, ".h");
+
+		/* Assume directory path already exists. */
+		fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+		if (fd == -1) {
+			if (errno != ENOENT) {
+				res = 1;
+				break;
+			}
+			/*
+			 * Create directory components,
+			 * unless they exist already.
+			 */
+			d = path;
+			while ((d = strchr(d, '/'))) {
+				*d = 0;
+				if (stat(path, &sb) && mkdir(path, 0755)) {
+					res = 1;
+					goto out;
+				}
+				*d++ = '/';
+			}
+			/* Try it again. */
+			fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+			if (fd == -1) {
+				res = 1;
+				break;
+			}
+		}
+		close(fd);
+	}
+out:
+	if (chdir("../.."))
+		return 1;
+
+	return res;
+}
+
+int conf_write_autoconf(void)
+{
+	struct symbol *sym;
+	const char *name;
+	FILE *out, *tristate, *out_h, *out_c;
+	int i;
+
+	sym_clear_all_valid();
+
+	file_write_dep("include/generated/auto.conf.cmd");
+
+	if (conf_split_config())
+		return 1;
+
+	out = fopen(".tmpconfig", "w");
+	if (!out)
+		return 1;
+
+	tristate = fopen(".tmpconfig_tristate", "w");
+	if (!tristate) {
+		fclose(out);
+		return 1;
+	}
+
+	out_h = fopen(".tmpconfig.h", "w");
+	if (!out_h) {
+		fclose(out);
+		fclose(tristate);
+		return 1;
+	}
+
+	out_c = fopen(".tmpconfig.cmake", "w");
+	if (!out_c) {
+		fclose(out);
+		fclose(tristate);
+		fclose(out_h);
+	}
+
+	conf_write_heading(out, &kconfig_printer_cb, NULL);
+
+	conf_write_heading(tristate, &tristate_printer_cb, NULL);
+
+	conf_write_heading(out_h, &header_printer_cb, NULL);
+
+	conf_write_heading(out_c, &kconfig_printer_cmake_cb, NULL);
+
+	for_all_symbols(i, sym) {
+		sym_calc_value(sym);
+		if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
+			continue;
+
+		/* write symbol to auto.conf, tristate and header files */
+		conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
+
+		conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
+
+		conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
+
+		conf_write_symbol(out_c, sym, &kconfig_printer_cmake_cb, NULL);
+	}
+	fclose(out);
+	fclose(tristate);
+	fclose(out_h);
+	fclose(out_c);
+
+	name = getenv("KCONFIG_AUTOHEADER");
+	if (!name)
+		name = "include/generated/autoconf.h";
+	if (rename(".tmpconfig.h", name))
+		return 1;
+	name = getenv("KCONFIG_TRISTATE");
+	if (!name)
+		name = "include/generated/tristate.conf";
+	if (rename(".tmpconfig_tristate", name))
+		return 1;
+	name = getenv("KCONFIG_CMAKE");
+	if (!name)
+		name = "config.cmake";
+	if (rename(".tmpconfig.cmake", name))
+		return 1;
+	name = conf_get_autoconfig_name();
+	/*
+	 * This must be the last step, kbuild has a dependency on auto.conf
+	 * and this marks the successful completion of the previous steps.
+	 */
+	if (rename(".tmpconfig", name))
+		return 1;
+
+	return 0;
+}
+
+static int sym_change_count;
+static void (*conf_changed_callback)(void);
+
+void sym_set_change_count(int count)
+{
+	int _sym_change_count = sym_change_count;
+	sym_change_count = count;
+	if (conf_changed_callback &&
+	    (bool)_sym_change_count != (bool)count)
+		conf_changed_callback();
+}
+
+void sym_add_change_count(int count)
+{
+	sym_set_change_count(count + sym_change_count);
+}
+
+bool conf_get_changed(void)
+{
+	return sym_change_count;
+}
+
+void conf_set_changed_callback(void (*fn)(void))
+{
+	conf_changed_callback = fn;
+}
+
+static void randomize_choice_values(struct symbol *csym)
+{
+	struct property *prop;
+	struct symbol *sym;
+	struct expr *e;
+	int cnt, def;
+
+	/*
+	 * If choice is mod then we may have more items selected
+	 * and if no then no-one.
+	 * In both cases stop.
+	 */
+	if (csym->curr.tri != yes)
+		return;
+
+	prop = sym_get_choice_prop(csym);
+
+	/* count entries in choice block */
+	cnt = 0;
+	expr_list_for_each_sym(prop->expr, e, sym)
+		cnt++;
+
+	/*
+	 * find a random value and set it to yes,
+	 * set the rest to no so we have only one set
+	 */
+	def = (rand() % cnt);
+
+	cnt = 0;
+	expr_list_for_each_sym(prop->expr, e, sym) {
+		if (def == cnt++) {
+			sym->def[S_DEF_USER].tri = yes;
+			csym->def[S_DEF_USER].val = sym;
+		}
+		else {
+			sym->def[S_DEF_USER].tri = no;
+		}
+	}
+	csym->flags |= SYMBOL_DEF_USER;
+	/* clear VALID to get value calculated */
+	csym->flags &= ~(SYMBOL_VALID);
+}
+
+static void set_all_choice_values(struct symbol *csym)
+{
+	struct property *prop;
+	struct symbol *sym;
+	struct expr *e;
+
+	prop = sym_get_choice_prop(csym);
+
+	/*
+	 * Set all non-assinged choice values to no
+	 */
+	expr_list_for_each_sym(prop->expr, e, sym) {
+		if (!sym_has_value(sym))
+			sym->def[S_DEF_USER].tri = no;
+	}
+	csym->flags |= SYMBOL_DEF_USER;
+	/* clear VALID to get value calculated */
+	csym->flags &= ~(SYMBOL_VALID);
+}
+
+void conf_set_all_new_symbols(enum conf_def_mode mode)
+{
+	struct symbol *sym, *csym;
+	int i, cnt;
+
+	for_all_symbols(i, sym) {
+		if (sym_has_value(sym))
+			continue;
+		switch (sym_get_type(sym)) {
+		case S_BOOLEAN:
+		case S_TRISTATE:
+			switch (mode) {
+			case def_yes:
+				sym->def[S_DEF_USER].tri = yes;
+				break;
+			case def_mod:
+				sym->def[S_DEF_USER].tri = mod;
+				break;
+			case def_no:
+				sym->def[S_DEF_USER].tri = no;
+				break;
+			case def_random:
+				cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
+				sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
+				break;
+			default:
+				continue;
+			}
+			if (!(sym_is_choice(sym) && mode == def_random))
+				sym->flags |= SYMBOL_DEF_USER;
+			break;
+		default:
+			break;
+		}
+
+	}
+
+	sym_clear_all_valid();
+
+	/*
+	 * We have different type of choice blocks.
+	 * If curr.tri equals to mod then we can select several
+	 * choice symbols in one block.
+	 * In this case we do nothing.
+	 * If curr.tri equals yes then only one symbol can be
+	 * selected in a choice block and we set it to yes,
+	 * and the rest to no.
+	 */
+	for_all_symbols(i, csym) {
+		if (sym_has_value(csym) || !sym_is_choice(csym))
+			continue;
+
+		sym_calc_value(csym);
+		if (mode == def_random)
+			randomize_choice_values(csym);
+		else
+			set_all_choice_values(csym);
+	}
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/expr.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/expr.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,1168 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel at linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lkc.h"
+
+#define DEBUG_EXPR	0
+
+struct expr *expr_alloc_symbol(struct symbol *sym)
+{
+	struct expr *e = calloc(1, sizeof(*e));
+	e->type = E_SYMBOL;
+	e->left.sym = sym;
+	return e;
+}
+
+struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
+{
+	struct expr *e = calloc(1, sizeof(*e));
+	e->type = type;
+	e->left.expr = ce;
+	return e;
+}
+
+struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
+{
+	struct expr *e = calloc(1, sizeof(*e));
+	e->type = type;
+	e->left.expr = e1;
+	e->right.expr = e2;
+	return e;
+}
+
+struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
+{
+	struct expr *e = calloc(1, sizeof(*e));
+	e->type = type;
+	e->left.sym = s1;
+	e->right.sym = s2;
+	return e;
+}
+
+struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
+{
+	if (!e1)
+		return e2;
+	return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
+}
+
+struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
+{
+	if (!e1)
+		return e2;
+	return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
+}
+
+struct expr *expr_copy(const struct expr *org)
+{
+	struct expr *e;
+
+	if (!org)
+		return NULL;
+
+	e = malloc(sizeof(*org));
+	memcpy(e, org, sizeof(*org));
+	switch (org->type) {
+	case E_SYMBOL:
+		e->left = org->left;
+		break;
+	case E_NOT:
+		e->left.expr = expr_copy(org->left.expr);
+		break;
+	case E_EQUAL:
+	case E_UNEQUAL:
+		e->left.sym = org->left.sym;
+		e->right.sym = org->right.sym;
+		break;
+	case E_AND:
+	case E_OR:
+	case E_LIST:
+		e->left.expr = expr_copy(org->left.expr);
+		e->right.expr = expr_copy(org->right.expr);
+		break;
+	default:
+		printf("can't copy type %d\n", e->type);
+		free(e);
+		e = NULL;
+		break;
+	}
+
+	return e;
+}
+
+void expr_free(struct expr *e)
+{
+	if (!e)
+		return;
+
+	switch (e->type) {
+	case E_SYMBOL:
+		break;
+	case E_NOT:
+		expr_free(e->left.expr);
+		return;
+	case E_EQUAL:
+	case E_UNEQUAL:
+		break;
+	case E_OR:
+	case E_AND:
+		expr_free(e->left.expr);
+		expr_free(e->right.expr);
+		break;
+	default:
+		printf("how to free type %d?\n", e->type);
+		break;
+	}
+	free(e);
+}
+
+static int trans_count;
+
+#define e1 (*ep1)
+#define e2 (*ep2)
+
+static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+	if (e1->type == type) {
+		__expr_eliminate_eq(type, &e1->left.expr, &e2);
+		__expr_eliminate_eq(type, &e1->right.expr, &e2);
+		return;
+	}
+	if (e2->type == type) {
+		__expr_eliminate_eq(type, &e1, &e2->left.expr);
+		__expr_eliminate_eq(type, &e1, &e2->right.expr);
+		return;
+	}
+	if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
+	    e1->left.sym == e2->left.sym &&
+	    (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
+		return;
+	if (!expr_eq(e1, e2))
+		return;
+	trans_count++;
+	expr_free(e1); expr_free(e2);
+	switch (type) {
+	case E_OR:
+		e1 = expr_alloc_symbol(&symbol_no);
+		e2 = expr_alloc_symbol(&symbol_no);
+		break;
+	case E_AND:
+		e1 = expr_alloc_symbol(&symbol_yes);
+		e2 = expr_alloc_symbol(&symbol_yes);
+		break;
+	default:
+		;
+	}
+}
+
+void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
+{
+	if (!e1 || !e2)
+		return;
+	switch (e1->type) {
+	case E_OR:
+	case E_AND:
+		__expr_eliminate_eq(e1->type, ep1, ep2);
+	default:
+		;
+	}
+	if (e1->type != e2->type) switch (e2->type) {
+	case E_OR:
+	case E_AND:
+		__expr_eliminate_eq(e2->type, ep1, ep2);
+	default:
+		;
+	}
+	e1 = expr_eliminate_yn(e1);
+	e2 = expr_eliminate_yn(e2);
+}
+
+#undef e1
+#undef e2
+
+int expr_eq(struct expr *e1, struct expr *e2)
+{
+	int res, old_count;
+
+	if (e1->type != e2->type)
+		return 0;
+	switch (e1->type) {
+	case E_EQUAL:
+	case E_UNEQUAL:
+		return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
+	case E_SYMBOL:
+		return e1->left.sym == e2->left.sym;
+	case E_NOT:
+		return expr_eq(e1->left.expr, e2->left.expr);
+	case E_AND:
+	case E_OR:
+		e1 = expr_copy(e1);
+		e2 = expr_copy(e2);
+		old_count = trans_count;
+		expr_eliminate_eq(&e1, &e2);
+		res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
+		       e1->left.sym == e2->left.sym);
+		expr_free(e1);
+		expr_free(e2);
+		trans_count = old_count;
+		return res;
+	case E_LIST:
+	case E_RANGE:
+	case E_NONE:
+		/* panic */;
+	}
+
+	if (DEBUG_EXPR) {
+		expr_fprint(e1, stdout);
+		printf(" = ");
+		expr_fprint(e2, stdout);
+		printf(" ?\n");
+	}
+
+	return 0;
+}
+
+struct expr *expr_eliminate_yn(struct expr *e)
+{
+	struct expr *tmp;
+
+	if (e) switch (e->type) {
+	case E_AND:
+		e->left.expr = expr_eliminate_yn(e->left.expr);
+		e->right.expr = expr_eliminate_yn(e->right.expr);
+		if (e->left.expr->type == E_SYMBOL) {
+			if (e->left.expr->left.sym == &symbol_no) {
+				expr_free(e->left.expr);
+				expr_free(e->right.expr);
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_no;
+				e->right.expr = NULL;
+				return e;
+			} else if (e->left.expr->left.sym == &symbol_yes) {
+				free(e->left.expr);
+				tmp = e->right.expr;
+				*e = *(e->right.expr);
+				free(tmp);
+				return e;
+			}
+		}
+		if (e->right.expr->type == E_SYMBOL) {
+			if (e->right.expr->left.sym == &symbol_no) {
+				expr_free(e->left.expr);
+				expr_free(e->right.expr);
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_no;
+				e->right.expr = NULL;
+				return e;
+			} else if (e->right.expr->left.sym == &symbol_yes) {
+				free(e->right.expr);
+				tmp = e->left.expr;
+				*e = *(e->left.expr);
+				free(tmp);
+				return e;
+			}
+		}
+		break;
+	case E_OR:
+		e->left.expr = expr_eliminate_yn(e->left.expr);
+		e->right.expr = expr_eliminate_yn(e->right.expr);
+		if (e->left.expr->type == E_SYMBOL) {
+			if (e->left.expr->left.sym == &symbol_no) {
+				free(e->left.expr);
+				tmp = e->right.expr;
+				*e = *(e->right.expr);
+				free(tmp);
+				return e;
+			} else if (e->left.expr->left.sym == &symbol_yes) {
+				expr_free(e->left.expr);
+				expr_free(e->right.expr);
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_yes;
+				e->right.expr = NULL;
+				return e;
+			}
+		}
+		if (e->right.expr->type == E_SYMBOL) {
+			if (e->right.expr->left.sym == &symbol_no) {
+				free(e->right.expr);
+				tmp = e->left.expr;
+				*e = *(e->left.expr);
+				free(tmp);
+				return e;
+			} else if (e->right.expr->left.sym == &symbol_yes) {
+				expr_free(e->left.expr);
+				expr_free(e->right.expr);
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_yes;
+				e->right.expr = NULL;
+				return e;
+			}
+		}
+		break;
+	default:
+		;
+	}
+	return e;
+}
+
+/*
+ * bool FOO!=n => FOO
+ */
+struct expr *expr_trans_bool(struct expr *e)
+{
+	if (!e)
+		return NULL;
+	switch (e->type) {
+	case E_AND:
+	case E_OR:
+	case E_NOT:
+		e->left.expr = expr_trans_bool(e->left.expr);
+		e->right.expr = expr_trans_bool(e->right.expr);
+		break;
+	case E_UNEQUAL:
+		// FOO!=n -> FOO
+		if (e->left.sym->type == S_TRISTATE) {
+			if (e->right.sym == &symbol_no) {
+				e->type = E_SYMBOL;
+				e->right.sym = NULL;
+			}
+		}
+		break;
+	default:
+		;
+	}
+	return e;
+}
+
+/*
+ * e1 || e2 -> ?
+ */
+static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
+{
+	struct expr *tmp;
+	struct symbol *sym1, *sym2;
+
+	if (expr_eq(e1, e2))
+		return expr_copy(e1);
+	if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
+		return NULL;
+	if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
+		return NULL;
+	if (e1->type == E_NOT) {
+		tmp = e1->left.expr;
+		if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
+			return NULL;
+		sym1 = tmp->left.sym;
+	} else
+		sym1 = e1->left.sym;
+	if (e2->type == E_NOT) {
+		if (e2->left.expr->type != E_SYMBOL)
+			return NULL;
+		sym2 = e2->left.expr->left.sym;
+	} else
+		sym2 = e2->left.sym;
+	if (sym1 != sym2)
+		return NULL;
+	if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
+		return NULL;
+	if (sym1->type == S_TRISTATE) {
+		if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+		    ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
+		     (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
+			// (a='y') || (a='m') -> (a!='n')
+			return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
+		}
+		if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+		    ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
+		     (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
+			// (a='y') || (a='n') -> (a!='m')
+			return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
+		}
+		if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+		    ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
+		     (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
+			// (a='m') || (a='n') -> (a!='y')
+			return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
+		}
+	}
+	if (sym1->type == S_BOOLEAN && sym1 == sym2) {
+		if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
+		    (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
+			return expr_alloc_symbol(&symbol_yes);
+	}
+
+	if (DEBUG_EXPR) {
+		printf("optimize (");
+		expr_fprint(e1, stdout);
+		printf(") || (");
+		expr_fprint(e2, stdout);
+		printf(")?\n");
+	}
+	return NULL;
+}
+
+static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
+{
+	struct expr *tmp;
+	struct symbol *sym1, *sym2;
+
+	if (expr_eq(e1, e2))
+		return expr_copy(e1);
+	if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
+		return NULL;
+	if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
+		return NULL;
+	if (e1->type == E_NOT) {
+		tmp = e1->left.expr;
+		if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
+			return NULL;
+		sym1 = tmp->left.sym;
+	} else
+		sym1 = e1->left.sym;
+	if (e2->type == E_NOT) {
+		if (e2->left.expr->type != E_SYMBOL)
+			return NULL;
+		sym2 = e2->left.expr->left.sym;
+	} else
+		sym2 = e2->left.sym;
+	if (sym1 != sym2)
+		return NULL;
+	if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
+		return NULL;
+
+	if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
+	    (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
+		// (a) && (a='y') -> (a='y')
+		return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+	if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
+	    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
+		// (a) && (a!='n') -> (a)
+		return expr_alloc_symbol(sym1);
+
+	if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
+	    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
+		// (a) && (a!='m') -> (a='y')
+		return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+	if (sym1->type == S_TRISTATE) {
+		if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
+			// (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
+			sym2 = e1->right.sym;
+			if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
+				return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
+							     : expr_alloc_symbol(&symbol_no);
+		}
+		if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
+			// (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
+			sym2 = e2->right.sym;
+			if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
+				return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
+							     : expr_alloc_symbol(&symbol_no);
+		}
+		if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+			   ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
+			    (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
+			// (a!='y') && (a!='n') -> (a='m')
+			return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
+
+		if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+			   ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
+			    (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
+			// (a!='y') && (a!='m') -> (a='n')
+			return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
+
+		if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+			   ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
+			    (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
+			// (a!='m') && (a!='n') -> (a='m')
+			return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+		if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
+		    (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
+		    (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
+		    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
+			return NULL;
+	}
+
+	if (DEBUG_EXPR) {
+		printf("optimize (");
+		expr_fprint(e1, stdout);
+		printf(") && (");
+		expr_fprint(e2, stdout);
+		printf(")?\n");
+	}
+	return NULL;
+}
+
+static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+	struct expr *tmp;
+
+	if (e1->type == type) {
+		expr_eliminate_dups1(type, &e1->left.expr, &e2);
+		expr_eliminate_dups1(type, &e1->right.expr, &e2);
+		return;
+	}
+	if (e2->type == type) {
+		expr_eliminate_dups1(type, &e1, &e2->left.expr);
+		expr_eliminate_dups1(type, &e1, &e2->right.expr);
+		return;
+	}
+	if (e1 == e2)
+		return;
+
+	switch (e1->type) {
+	case E_OR: case E_AND:
+		expr_eliminate_dups1(e1->type, &e1, &e1);
+	default:
+		;
+	}
+
+	switch (type) {
+	case E_OR:
+		tmp = expr_join_or(e1, e2);
+		if (tmp) {
+			expr_free(e1); expr_free(e2);
+			e1 = expr_alloc_symbol(&symbol_no);
+			e2 = tmp;
+			trans_count++;
+		}
+		break;
+	case E_AND:
+		tmp = expr_join_and(e1, e2);
+		if (tmp) {
+			expr_free(e1); expr_free(e2);
+			e1 = expr_alloc_symbol(&symbol_yes);
+			e2 = tmp;
+			trans_count++;
+		}
+		break;
+	default:
+		;
+	}
+#undef e1
+#undef e2
+}
+
+static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+	struct expr *tmp, *tmp1, *tmp2;
+
+	if (e1->type == type) {
+		expr_eliminate_dups2(type, &e1->left.expr, &e2);
+		expr_eliminate_dups2(type, &e1->right.expr, &e2);
+		return;
+	}
+	if (e2->type == type) {
+		expr_eliminate_dups2(type, &e1, &e2->left.expr);
+		expr_eliminate_dups2(type, &e1, &e2->right.expr);
+	}
+	if (e1 == e2)
+		return;
+
+	switch (e1->type) {
+	case E_OR:
+		expr_eliminate_dups2(e1->type, &e1, &e1);
+		// (FOO || BAR) && (!FOO && !BAR) -> n
+		tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
+		tmp2 = expr_copy(e2);
+		tmp = expr_extract_eq_and(&tmp1, &tmp2);
+		if (expr_is_yes(tmp1)) {
+			expr_free(e1);
+			e1 = expr_alloc_symbol(&symbol_no);
+			trans_count++;
+		}
+		expr_free(tmp2);
+		expr_free(tmp1);
+		expr_free(tmp);
+		break;
+	case E_AND:
+		expr_eliminate_dups2(e1->type, &e1, &e1);
+		// (FOO && BAR) || (!FOO || !BAR) -> y
+		tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
+		tmp2 = expr_copy(e2);
+		tmp = expr_extract_eq_or(&tmp1, &tmp2);
+		if (expr_is_no(tmp1)) {
+			expr_free(e1);
+			e1 = expr_alloc_symbol(&symbol_yes);
+			trans_count++;
+		}
+		expr_free(tmp2);
+		expr_free(tmp1);
+		expr_free(tmp);
+		break;
+	default:
+		;
+	}
+#undef e1
+#undef e2
+}
+
+struct expr *expr_eliminate_dups(struct expr *e)
+{
+	int oldcount;
+	if (!e)
+		return e;
+
+	oldcount = trans_count;
+	while (1) {
+		trans_count = 0;
+		switch (e->type) {
+		case E_OR: case E_AND:
+			expr_eliminate_dups1(e->type, &e, &e);
+			expr_eliminate_dups2(e->type, &e, &e);
+		default:
+			;
+		}
+		if (!trans_count)
+			break;
+		e = expr_eliminate_yn(e);
+	}
+	trans_count = oldcount;
+	return e;
+}
+
+struct expr *expr_transform(struct expr *e)
+{
+	struct expr *tmp;
+
+	if (!e)
+		return NULL;
+	switch (e->type) {
+	case E_EQUAL:
+	case E_UNEQUAL:
+	case E_SYMBOL:
+	case E_LIST:
+		break;
+	default:
+		e->left.expr = expr_transform(e->left.expr);
+		e->right.expr = expr_transform(e->right.expr);
+	}
+
+	switch (e->type) {
+	case E_EQUAL:
+		if (e->left.sym->type != S_BOOLEAN)
+			break;
+		if (e->right.sym == &symbol_no) {
+			e->type = E_NOT;
+			e->left.expr = expr_alloc_symbol(e->left.sym);
+			e->right.sym = NULL;
+			break;
+		}
+		if (e->right.sym == &symbol_mod) {
+			printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
+			e->type = E_SYMBOL;
+			e->left.sym = &symbol_no;
+			e->right.sym = NULL;
+			break;
+		}
+		if (e->right.sym == &symbol_yes) {
+			e->type = E_SYMBOL;
+			e->right.sym = NULL;
+			break;
+		}
+		break;
+	case E_UNEQUAL:
+		if (e->left.sym->type != S_BOOLEAN)
+			break;
+		if (e->right.sym == &symbol_no) {
+			e->type = E_SYMBOL;
+			e->right.sym = NULL;
+			break;
+		}
+		if (e->right.sym == &symbol_mod) {
+			printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
+			e->type = E_SYMBOL;
+			e->left.sym = &symbol_yes;
+			e->right.sym = NULL;
+			break;
+		}
+		if (e->right.sym == &symbol_yes) {
+			e->type = E_NOT;
+			e->left.expr = expr_alloc_symbol(e->left.sym);
+			e->right.sym = NULL;
+			break;
+		}
+		break;
+	case E_NOT:
+		switch (e->left.expr->type) {
+		case E_NOT:
+			// !!a -> a
+			tmp = e->left.expr->left.expr;
+			free(e->left.expr);
+			free(e);
+			e = tmp;
+			e = expr_transform(e);
+			break;
+		case E_EQUAL:
+		case E_UNEQUAL:
+			// !a='x' -> a!='x'
+			tmp = e->left.expr;
+			free(e);
+			e = tmp;
+			e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
+			break;
+		case E_OR:
+			// !(a || b) -> !a && !b
+			tmp = e->left.expr;
+			e->type = E_AND;
+			e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
+			tmp->type = E_NOT;
+			tmp->right.expr = NULL;
+			e = expr_transform(e);
+			break;
+		case E_AND:
+			// !(a && b) -> !a || !b
+			tmp = e->left.expr;
+			e->type = E_OR;
+			e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
+			tmp->type = E_NOT;
+			tmp->right.expr = NULL;
+			e = expr_transform(e);
+			break;
+		case E_SYMBOL:
+			if (e->left.expr->left.sym == &symbol_yes) {
+				// !'y' -> 'n'
+				tmp = e->left.expr;
+				free(e);
+				e = tmp;
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_no;
+				break;
+			}
+			if (e->left.expr->left.sym == &symbol_mod) {
+				// !'m' -> 'm'
+				tmp = e->left.expr;
+				free(e);
+				e = tmp;
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_mod;
+				break;
+			}
+			if (e->left.expr->left.sym == &symbol_no) {
+				// !'n' -> 'y'
+				tmp = e->left.expr;
+				free(e);
+				e = tmp;
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_yes;
+				break;
+			}
+			break;
+		default:
+			;
+		}
+		break;
+	default:
+		;
+	}
+	return e;
+}
+
+int expr_contains_symbol(struct expr *dep, struct symbol *sym)
+{
+	if (!dep)
+		return 0;
+
+	switch (dep->type) {
+	case E_AND:
+	case E_OR:
+		return expr_contains_symbol(dep->left.expr, sym) ||
+		       expr_contains_symbol(dep->right.expr, sym);
+	case E_SYMBOL:
+		return dep->left.sym == sym;
+	case E_EQUAL:
+	case E_UNEQUAL:
+		return dep->left.sym == sym ||
+		       dep->right.sym == sym;
+	case E_NOT:
+		return expr_contains_symbol(dep->left.expr, sym);
+	default:
+		;
+	}
+	return 0;
+}
+
+bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
+{
+	if (!dep)
+		return false;
+
+	switch (dep->type) {
+	case E_AND:
+		return expr_depends_symbol(dep->left.expr, sym) ||
+		       expr_depends_symbol(dep->right.expr, sym);
+	case E_SYMBOL:
+		return dep->left.sym == sym;
+	case E_EQUAL:
+		if (dep->left.sym == sym) {
+			if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
+				return true;
+		}
+		break;
+	case E_UNEQUAL:
+		if (dep->left.sym == sym) {
+			if (dep->right.sym == &symbol_no)
+				return true;
+		}
+		break;
+	default:
+		;
+	}
+ 	return false;
+}
+
+struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
+{
+	struct expr *tmp = NULL;
+	expr_extract_eq(E_AND, &tmp, ep1, ep2);
+	if (tmp) {
+		*ep1 = expr_eliminate_yn(*ep1);
+		*ep2 = expr_eliminate_yn(*ep2);
+	}
+	return tmp;
+}
+
+struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
+{
+	struct expr *tmp = NULL;
+	expr_extract_eq(E_OR, &tmp, ep1, ep2);
+	if (tmp) {
+		*ep1 = expr_eliminate_yn(*ep1);
+		*ep2 = expr_eliminate_yn(*ep2);
+	}
+	return tmp;
+}
+
+void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+	if (e1->type == type) {
+		expr_extract_eq(type, ep, &e1->left.expr, &e2);
+		expr_extract_eq(type, ep, &e1->right.expr, &e2);
+		return;
+	}
+	if (e2->type == type) {
+		expr_extract_eq(type, ep, ep1, &e2->left.expr);
+		expr_extract_eq(type, ep, ep1, &e2->right.expr);
+		return;
+	}
+	if (expr_eq(e1, e2)) {
+		*ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
+		expr_free(e2);
+		if (type == E_AND) {
+			e1 = expr_alloc_symbol(&symbol_yes);
+			e2 = expr_alloc_symbol(&symbol_yes);
+		} else if (type == E_OR) {
+			e1 = expr_alloc_symbol(&symbol_no);
+			e2 = expr_alloc_symbol(&symbol_no);
+		}
+	}
+#undef e1
+#undef e2
+}
+
+struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
+{
+	struct expr *e1, *e2;
+
+	if (!e) {
+		e = expr_alloc_symbol(sym);
+		if (type == E_UNEQUAL)
+			e = expr_alloc_one(E_NOT, e);
+		return e;
+	}
+	switch (e->type) {
+	case E_AND:
+		e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
+		e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
+		if (sym == &symbol_yes)
+			e = expr_alloc_two(E_AND, e1, e2);
+		if (sym == &symbol_no)
+			e = expr_alloc_two(E_OR, e1, e2);
+		if (type == E_UNEQUAL)
+			e = expr_alloc_one(E_NOT, e);
+		return e;
+	case E_OR:
+		e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
+		e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
+		if (sym == &symbol_yes)
+			e = expr_alloc_two(E_OR, e1, e2);
+		if (sym == &symbol_no)
+			e = expr_alloc_two(E_AND, e1, e2);
+		if (type == E_UNEQUAL)
+			e = expr_alloc_one(E_NOT, e);
+		return e;
+	case E_NOT:
+		return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
+	case E_UNEQUAL:
+	case E_EQUAL:
+		if (type == E_EQUAL) {
+			if (sym == &symbol_yes)
+				return expr_copy(e);
+			if (sym == &symbol_mod)
+				return expr_alloc_symbol(&symbol_no);
+			if (sym == &symbol_no)
+				return expr_alloc_one(E_NOT, expr_copy(e));
+		} else {
+			if (sym == &symbol_yes)
+				return expr_alloc_one(E_NOT, expr_copy(e));
+			if (sym == &symbol_mod)
+				return expr_alloc_symbol(&symbol_yes);
+			if (sym == &symbol_no)
+				return expr_copy(e);
+		}
+		break;
+	case E_SYMBOL:
+		return expr_alloc_comp(type, e->left.sym, sym);
+	case E_LIST:
+	case E_RANGE:
+	case E_NONE:
+		/* panic */;
+	}
+	return NULL;
+}
+
+tristate expr_calc_value(struct expr *e)
+{
+	tristate val1, val2;
+	const char *str1, *str2;
+
+	if (!e)
+		return yes;
+
+	switch (e->type) {
+	case E_SYMBOL:
+		sym_calc_value(e->left.sym);
+		return e->left.sym->curr.tri;
+	case E_AND:
+		val1 = expr_calc_value(e->left.expr);
+		val2 = expr_calc_value(e->right.expr);
+		return EXPR_AND(val1, val2);
+	case E_OR:
+		val1 = expr_calc_value(e->left.expr);
+		val2 = expr_calc_value(e->right.expr);
+		return EXPR_OR(val1, val2);
+	case E_NOT:
+		val1 = expr_calc_value(e->left.expr);
+		return EXPR_NOT(val1);
+	case E_EQUAL:
+		sym_calc_value(e->left.sym);
+		sym_calc_value(e->right.sym);
+		str1 = sym_get_string_value(e->left.sym);
+		str2 = sym_get_string_value(e->right.sym);
+		return !strcmp(str1, str2) ? yes : no;
+	case E_UNEQUAL:
+		sym_calc_value(e->left.sym);
+		sym_calc_value(e->right.sym);
+		str1 = sym_get_string_value(e->left.sym);
+		str2 = sym_get_string_value(e->right.sym);
+		return !strcmp(str1, str2) ? no : yes;
+	default:
+		printf("expr_calc_value: %d?\n", e->type);
+		return no;
+	}
+}
+
+int expr_compare_type(enum expr_type t1, enum expr_type t2)
+{
+#if 0
+	return 1;
+#else
+	if (t1 == t2)
+		return 0;
+	switch (t1) {
+	case E_EQUAL:
+	case E_UNEQUAL:
+		if (t2 == E_NOT)
+			return 1;
+	case E_NOT:
+		if (t2 == E_AND)
+			return 1;
+	case E_AND:
+		if (t2 == E_OR)
+			return 1;
+	case E_OR:
+		if (t2 == E_LIST)
+			return 1;
+	case E_LIST:
+		if (t2 == 0)
+			return 1;
+	default:
+		return -1;
+	}
+	printf("[%dgt%d?]", t1, t2);
+	return 0;
+#endif
+}
+
+static inline struct expr *
+expr_get_leftmost_symbol(const struct expr *e)
+{
+
+	if (e == NULL)
+		return NULL;
+
+	while (e->type != E_SYMBOL)
+		e = e->left.expr;
+
+	return expr_copy(e);
+}
+
+/*
+ * Given expression `e1' and `e2', returns the leaf of the longest
+ * sub-expression of `e1' not containing 'e2.
+ */
+struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
+{
+	struct expr *ret;
+
+	switch (e1->type) {
+	case E_OR:
+		return expr_alloc_and(
+		    expr_simplify_unmet_dep(e1->left.expr, e2),
+		    expr_simplify_unmet_dep(e1->right.expr, e2));
+	case E_AND: {
+		struct expr *e;
+		e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
+		e = expr_eliminate_dups(e);
+		ret = (!expr_eq(e, e1)) ? e1 : NULL;
+		expr_free(e);
+		break;
+		}
+	default:
+		ret = e1;
+		break;
+	}
+
+	return expr_get_leftmost_symbol(ret);
+}
+
+void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
+{
+	if (!e) {
+		fn(data, NULL, "y");
+		return;
+	}
+
+	if (expr_compare_type(prevtoken, e->type) > 0)
+		fn(data, NULL, "(");
+	switch (e->type) {
+	case E_SYMBOL:
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
+		break;
+	case E_NOT:
+		fn(data, NULL, "!");
+		expr_print(e->left.expr, fn, data, E_NOT);
+		break;
+	case E_EQUAL:
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
+		fn(data, NULL, "=");
+		fn(data, e->right.sym, e->right.sym->name);
+		break;
+	case E_UNEQUAL:
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
+		fn(data, NULL, "!=");
+		fn(data, e->right.sym, e->right.sym->name);
+		break;
+	case E_OR:
+		expr_print(e->left.expr, fn, data, E_OR);
+		fn(data, NULL, " || ");
+		expr_print(e->right.expr, fn, data, E_OR);
+		break;
+	case E_AND:
+		expr_print(e->left.expr, fn, data, E_AND);
+		fn(data, NULL, " && ");
+		expr_print(e->right.expr, fn, data, E_AND);
+		break;
+	case E_LIST:
+		fn(data, e->right.sym, e->right.sym->name);
+		if (e->left.expr) {
+			fn(data, NULL, " ^ ");
+			expr_print(e->left.expr, fn, data, E_LIST);
+		}
+		break;
+	case E_RANGE:
+		fn(data, NULL, "[");
+		fn(data, e->left.sym, e->left.sym->name);
+		fn(data, NULL, " ");
+		fn(data, e->right.sym, e->right.sym->name);
+		fn(data, NULL, "]");
+		break;
+	default:
+	  {
+		char buf[32];
+		sprintf(buf, "<unknown type %d>", e->type);
+		fn(data, NULL, buf);
+		break;
+	  }
+	}
+	if (expr_compare_type(prevtoken, e->type) > 0)
+		fn(data, NULL, ")");
+}
+
+static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
+{
+	xfwrite(str, strlen(str), 1, data);
+}
+
+void expr_fprint(struct expr *e, FILE *out)
+{
+	expr_print(e, expr_print_file_helper, out, E_NONE);
+}
+
+static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
+{
+	struct gstr *gs = (struct gstr*)data;
+	const char *sym_str = NULL;
+
+	if (sym)
+		sym_str = sym_get_string_value(sym);
+
+	if (gs->max_width) {
+		unsigned extra_length = strlen(str);
+		const char *last_cr = strrchr(gs->s, '\n');
+		unsigned last_line_length;
+
+		if (sym_str)
+			extra_length += 4 + strlen(sym_str);
+
+		if (!last_cr)
+			last_cr = gs->s;
+
+		last_line_length = strlen(gs->s) - (last_cr - gs->s);
+
+		if ((last_line_length + extra_length) > gs->max_width)
+			str_append(gs, "\\\n");
+	}
+
+	str_append(gs, str);
+	if (sym && sym->type != S_UNKNOWN)
+		str_printf(gs, " [=%s]", sym_str);
+}
+
+void expr_gstr_print(struct expr *e, struct gstr *gs)
+{
+	expr_print(e, expr_print_gstr_helper, gs, E_NONE);
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/expr.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/expr.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/lkc.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/lkc.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/lkc_proto.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/lkc_proto.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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));

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/menu.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/menu.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel at 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 = &current_entry->list;
+	return current_menu = current_entry;
+}
+
+void menu_end_menu(void)
+{
+	last_entry_ptr = &current_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);
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/symbol.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/symbol.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,1310 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel at linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <regex.h>
+#include <sys/utsname.h>
+
+#include "lkc.h"
+
+struct symbol symbol_yes = {
+	.name = "y",
+	.curr = { "y", yes },
+	.flags = SYMBOL_CONST|SYMBOL_VALID,
+}, symbol_mod = {
+	.name = "m",
+	.curr = { "m", mod },
+	.flags = SYMBOL_CONST|SYMBOL_VALID,
+}, symbol_no = {
+	.name = "n",
+	.curr = { "n", no },
+	.flags = SYMBOL_CONST|SYMBOL_VALID,
+}, symbol_empty = {
+	.name = "",
+	.curr = { "", no },
+	.flags = SYMBOL_VALID,
+};
+
+struct symbol *sym_defconfig_list;
+struct symbol *modules_sym;
+tristate modules_val;
+
+struct expr *sym_env_list;
+
+static void sym_add_default(struct symbol *sym, const char *def)
+{
+	struct property *prop = prop_alloc(P_DEFAULT, sym);
+
+	prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
+}
+
+void sym_init(void)
+{
+	struct symbol *sym;
+	struct utsname uts;
+	static bool inited = false;
+
+	if (inited)
+		return;
+	inited = true;
+
+	uname(&uts);
+
+	sym = sym_lookup("UNAME_RELEASE", 0);
+	sym->type = S_STRING;
+	sym->flags |= SYMBOL_AUTO;
+	sym_add_default(sym, uts.release);
+}
+
+enum symbol_type sym_get_type(struct symbol *sym)
+{
+	enum symbol_type type = sym->type;
+
+	if (type == S_TRISTATE) {
+		if (sym_is_choice_value(sym) && sym->visible == yes)
+			type = S_BOOLEAN;
+		else if (modules_val == no)
+			type = S_BOOLEAN;
+	}
+	return type;
+}
+
+const char *sym_type_name(enum symbol_type type)
+{
+	switch (type) {
+	case S_BOOLEAN:
+		return "boolean";
+	case S_TRISTATE:
+		return "tristate";
+	case S_INT:
+		return "integer";
+	case S_HEX:
+		return "hex";
+	case S_STRING:
+		return "string";
+	case S_UNKNOWN:
+		return "unknown";
+	case S_OTHER:
+		break;
+	}
+	return "???";
+}
+
+struct property *sym_get_choice_prop(struct symbol *sym)
+{
+	struct property *prop;
+
+	for_all_choices(sym, prop)
+		return prop;
+	return NULL;
+}
+
+struct property *sym_get_env_prop(struct symbol *sym)
+{
+	struct property *prop;
+
+	for_all_properties(sym, prop, P_ENV)
+		return prop;
+	return NULL;
+}
+
+struct property *sym_get_default_prop(struct symbol *sym)
+{
+	struct property *prop;
+
+	for_all_defaults(sym, prop) {
+		prop->visible.tri = expr_calc_value(prop->visible.expr);
+		if (prop->visible.tri != no)
+			return prop;
+	}
+	return NULL;
+}
+
+static struct property *sym_get_range_prop(struct symbol *sym)
+{
+	struct property *prop;
+
+	for_all_properties(sym, prop, P_RANGE) {
+		prop->visible.tri = expr_calc_value(prop->visible.expr);
+		if (prop->visible.tri != no)
+			return prop;
+	}
+	return NULL;
+}
+
+static int sym_get_range_val(struct symbol *sym, int base)
+{
+	sym_calc_value(sym);
+	switch (sym->type) {
+	case S_INT:
+		base = 10;
+		break;
+	case S_HEX:
+		base = 16;
+		break;
+	default:
+		break;
+	}
+	return strtol(sym->curr.val, NULL, base);
+}
+
+static void sym_validate_range(struct symbol *sym)
+{
+	struct property *prop;
+	int base, val, val2;
+	char str[64];
+
+	switch (sym->type) {
+	case S_INT:
+		base = 10;
+		break;
+	case S_HEX:
+		base = 16;
+		break;
+	default:
+		return;
+	}
+	prop = sym_get_range_prop(sym);
+	if (!prop)
+		return;
+	val = strtol(sym->curr.val, NULL, base);
+	val2 = sym_get_range_val(prop->expr->left.sym, base);
+	if (val >= val2) {
+		val2 = sym_get_range_val(prop->expr->right.sym, base);
+		if (val <= val2)
+			return;
+	}
+	if (sym->type == S_INT)
+		sprintf(str, "%d", val2);
+	else
+		sprintf(str, "0x%x", val2);
+	sym->curr.val = strdup(str);
+}
+
+static void sym_calc_visibility(struct symbol *sym)
+{
+	struct property *prop;
+	tristate tri;
+
+	/* any prompt visible? */
+	tri = no;
+	for_all_prompts(sym, prop) {
+		prop->visible.tri = expr_calc_value(prop->visible.expr);
+		tri = EXPR_OR(tri, prop->visible.tri);
+	}
+	if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
+		tri = yes;
+	if (sym->visible != tri) {
+		sym->visible = tri;
+		sym_set_changed(sym);
+	}
+	if (sym_is_choice_value(sym))
+		return;
+	/* defaulting to "yes" if no explicit "depends on" are given */
+	tri = yes;
+	if (sym->dir_dep.expr)
+		tri = expr_calc_value(sym->dir_dep.expr);
+	if (tri == mod)
+		tri = yes;
+	if (sym->dir_dep.tri != tri) {
+		sym->dir_dep.tri = tri;
+		sym_set_changed(sym);
+	}
+	tri = no;
+	if (sym->rev_dep.expr)
+		tri = expr_calc_value(sym->rev_dep.expr);
+	if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
+		tri = yes;
+	if (sym->rev_dep.tri != tri) {
+		sym->rev_dep.tri = tri;
+		sym_set_changed(sym);
+	}
+}
+
+/*
+ * Find the default symbol for a choice.
+ * First try the default values for the choice symbol
+ * Next locate the first visible choice value
+ * Return NULL if none was found
+ */
+struct symbol *sym_choice_default(struct symbol *sym)
+{
+	struct symbol *def_sym;
+	struct property *prop;
+	struct expr *e;
+
+	/* any of the defaults visible? */
+	for_all_defaults(sym, prop) {
+		prop->visible.tri = expr_calc_value(prop->visible.expr);
+		if (prop->visible.tri == no)
+			continue;
+		def_sym = prop_get_symbol(prop);
+		if (def_sym->visible != no)
+			return def_sym;
+	}
+
+	/* just get the first visible value */
+	prop = sym_get_choice_prop(sym);
+	expr_list_for_each_sym(prop->expr, e, def_sym)
+		if (def_sym->visible != no)
+			return def_sym;
+
+	/* failed to locate any defaults */
+	return NULL;
+}
+
+static struct symbol *sym_calc_choice(struct symbol *sym)
+{
+	struct symbol *def_sym;
+	struct property *prop;
+	struct expr *e;
+	int flags;
+
+	/* first calculate all choice values' visibilities */
+	flags = sym->flags;
+	prop = sym_get_choice_prop(sym);
+	expr_list_for_each_sym(prop->expr, e, def_sym) {
+		sym_calc_visibility(def_sym);
+		if (def_sym->visible != no)
+			flags &= def_sym->flags;
+	}
+
+	sym->flags &= flags | ~SYMBOL_DEF_USER;
+
+	/* is the user choice visible? */
+	def_sym = sym->def[S_DEF_USER].val;
+	if (def_sym && def_sym->visible != no)
+		return def_sym;
+
+	def_sym = sym_choice_default(sym);
+
+	if (def_sym == NULL)
+		/* no choice? reset tristate value */
+		sym->curr.tri = no;
+
+	return def_sym;
+}
+
+void sym_calc_value(struct symbol *sym)
+{
+	struct symbol_value newval, oldval;
+	struct property *prop;
+	struct expr *e;
+
+	if (!sym)
+		return;
+
+	if (sym->flags & SYMBOL_VALID)
+		return;
+	sym->flags |= SYMBOL_VALID;
+
+	oldval = sym->curr;
+
+	switch (sym->type) {
+	case S_INT:
+	case S_HEX:
+	case S_STRING:
+		newval = symbol_empty.curr;
+		break;
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		newval = symbol_no.curr;
+		break;
+	default:
+		sym->curr.val = sym->name;
+		sym->curr.tri = no;
+		return;
+	}
+	if (!sym_is_choice_value(sym))
+		sym->flags &= ~SYMBOL_WRITE;
+
+	sym_calc_visibility(sym);
+
+	/* set default if recursively called */
+	sym->curr = newval;
+
+	switch (sym_get_type(sym)) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		if (sym_is_choice_value(sym) && sym->visible == yes) {
+			prop = sym_get_choice_prop(sym);
+			newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
+		} else {
+			if (sym->visible != no) {
+				/* if the symbol is visible use the user value
+				 * if available, otherwise try the default value
+				 */
+				sym->flags |= SYMBOL_WRITE;
+				if (sym_has_value(sym)) {
+					newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
+							      sym->visible);
+					goto calc_newval;
+				}
+			}
+			if (sym->rev_dep.tri != no)
+				sym->flags |= SYMBOL_WRITE;
+			if (!sym_is_choice(sym)) {
+				prop = sym_get_default_prop(sym);
+				if (prop) {
+					sym->flags |= SYMBOL_WRITE;
+					newval.tri = EXPR_AND(expr_calc_value(prop->expr),
+							      prop->visible.tri);
+				}
+			}
+		calc_newval:
+			if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
+				struct expr *e;
+				e = expr_simplify_unmet_dep(sym->rev_dep.expr,
+				    sym->dir_dep.expr);
+				fprintf(stderr, "warning: (");
+				expr_fprint(e, stderr);
+				fprintf(stderr, ") selects %s which has unmet direct dependencies (",
+					sym->name);
+				expr_fprint(sym->dir_dep.expr, stderr);
+				fprintf(stderr, ")\n");
+				expr_free(e);
+			}
+			newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
+		}
+		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
+			newval.tri = yes;
+		break;
+	case S_STRING:
+	case S_HEX:
+	case S_INT:
+		if (sym->visible != no) {
+			sym->flags |= SYMBOL_WRITE;
+			if (sym_has_value(sym)) {
+				newval.val = sym->def[S_DEF_USER].val;
+				break;
+			}
+		}
+		prop = sym_get_default_prop(sym);
+		if (prop) {
+			struct symbol *ds = prop_get_symbol(prop);
+			if (ds) {
+				sym->flags |= SYMBOL_WRITE;
+				sym_calc_value(ds);
+				newval.val = ds->curr.val;
+			}
+		}
+		break;
+	default:
+		;
+	}
+
+	sym->curr = newval;
+	if (sym_is_choice(sym) && newval.tri == yes)
+		sym->curr.val = sym_calc_choice(sym);
+	sym_validate_range(sym);
+
+	if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
+		sym_set_changed(sym);
+		if (modules_sym == sym) {
+			sym_set_all_changed();
+			modules_val = modules_sym->curr.tri;
+		}
+	}
+
+	if (sym_is_choice(sym)) {
+		struct symbol *choice_sym;
+
+		prop = sym_get_choice_prop(sym);
+		expr_list_for_each_sym(prop->expr, e, choice_sym) {
+			if ((sym->flags & SYMBOL_WRITE) &&
+			    choice_sym->visible != no)
+				choice_sym->flags |= SYMBOL_WRITE;
+			if (sym->flags & SYMBOL_CHANGED)
+				sym_set_changed(choice_sym);
+		}
+	}
+
+	if (sym->flags & SYMBOL_AUTO)
+		sym->flags &= ~SYMBOL_WRITE;
+}
+
+void sym_clear_all_valid(void)
+{
+	struct symbol *sym;
+	int i;
+
+	for_all_symbols(i, sym)
+		sym->flags &= ~SYMBOL_VALID;
+	sym_add_change_count(1);
+	if (modules_sym)
+		sym_calc_value(modules_sym);
+}
+
+void sym_set_changed(struct symbol *sym)
+{
+	struct property *prop;
+
+	sym->flags |= SYMBOL_CHANGED;
+	for (prop = sym->prop; prop; prop = prop->next) {
+		if (prop->menu)
+			prop->menu->flags |= MENU_CHANGED;
+	}
+}
+
+void sym_set_all_changed(void)
+{
+	struct symbol *sym;
+	int i;
+
+	for_all_symbols(i, sym)
+		sym_set_changed(sym);
+}
+
+bool sym_tristate_within_range(struct symbol *sym, tristate val)
+{
+	int type = sym_get_type(sym);
+
+	if (sym->visible == no)
+		return false;
+
+	if (type != S_BOOLEAN && type != S_TRISTATE)
+		return false;
+
+	if (type == S_BOOLEAN && val == mod)
+		return false;
+	if (sym->visible <= sym->rev_dep.tri)
+		return false;
+	if (sym_is_choice_value(sym) && sym->visible == yes)
+		return val == yes;
+	return val >= sym->rev_dep.tri && val <= sym->visible;
+}
+
+bool sym_set_tristate_value(struct symbol *sym, tristate val)
+{
+	tristate oldval = sym_get_tristate_value(sym);
+
+	if (oldval != val && !sym_tristate_within_range(sym, val))
+		return false;
+
+	if (!(sym->flags & SYMBOL_DEF_USER)) {
+		sym->flags |= SYMBOL_DEF_USER;
+		sym_set_changed(sym);
+	}
+	/*
+	 * setting a choice value also resets the new flag of the choice
+	 * symbol and all other choice values.
+	 */
+	if (sym_is_choice_value(sym) && val == yes) {
+		struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+		struct property *prop;
+		struct expr *e;
+
+		cs->def[S_DEF_USER].val = sym;
+		cs->flags |= SYMBOL_DEF_USER;
+		prop = sym_get_choice_prop(cs);
+		for (e = prop->expr; e; e = e->left.expr) {
+			if (e->right.sym->visible != no)
+				e->right.sym->flags |= SYMBOL_DEF_USER;
+		}
+	}
+
+	sym->def[S_DEF_USER].tri = val;
+	if (oldval != val)
+		sym_clear_all_valid();
+
+	return true;
+}
+
+tristate sym_toggle_tristate_value(struct symbol *sym)
+{
+	tristate oldval, newval;
+
+	oldval = newval = sym_get_tristate_value(sym);
+	do {
+		switch (newval) {
+		case no:
+			newval = mod;
+			break;
+		case mod:
+			newval = yes;
+			break;
+		case yes:
+			newval = no;
+			break;
+		}
+		if (sym_set_tristate_value(sym, newval))
+			break;
+	} while (oldval != newval);
+	return newval;
+}
+
+bool sym_string_valid(struct symbol *sym, const char *str)
+{
+	signed char ch;
+
+	switch (sym->type) {
+	case S_STRING:
+		return true;
+	case S_INT:
+		ch = *str++;
+		if (ch == '-')
+			ch = *str++;
+		if (!isdigit(ch))
+			return false;
+		if (ch == '0' && *str != 0)
+			return false;
+		while ((ch = *str++)) {
+			if (!isdigit(ch))
+				return false;
+		}
+		return true;
+	case S_HEX:
+		if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+			str += 2;
+		ch = *str++;
+		do {
+			if (!isxdigit(ch))
+				return false;
+		} while ((ch = *str++));
+		return true;
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		switch (str[0]) {
+		case 'y': case 'Y':
+		case 'm': case 'M':
+		case 'n': case 'N':
+			return true;
+		}
+		return false;
+	default:
+		return false;
+	}
+}
+
+bool sym_string_within_range(struct symbol *sym, const char *str)
+{
+	struct property *prop;
+	int val;
+
+	switch (sym->type) {
+	case S_STRING:
+		return sym_string_valid(sym, str);
+	case S_INT:
+		if (!sym_string_valid(sym, str))
+			return false;
+		prop = sym_get_range_prop(sym);
+		if (!prop)
+			return true;
+		val = strtol(str, NULL, 10);
+		return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
+		       val <= sym_get_range_val(prop->expr->right.sym, 10);
+	case S_HEX:
+		if (!sym_string_valid(sym, str))
+			return false;
+		prop = sym_get_range_prop(sym);
+		if (!prop)
+			return true;
+		val = strtol(str, NULL, 16);
+		return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
+		       val <= sym_get_range_val(prop->expr->right.sym, 16);
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		switch (str[0]) {
+		case 'y': case 'Y':
+			return sym_tristate_within_range(sym, yes);
+		case 'm': case 'M':
+			return sym_tristate_within_range(sym, mod);
+		case 'n': case 'N':
+			return sym_tristate_within_range(sym, no);
+		}
+		return false;
+	default:
+		return false;
+	}
+}
+
+bool sym_set_string_value(struct symbol *sym, const char *newval)
+{
+	const char *oldval;
+	char *val;
+	int size;
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		switch (newval[0]) {
+		case 'y': case 'Y':
+			return sym_set_tristate_value(sym, yes);
+		case 'm': case 'M':
+			return sym_set_tristate_value(sym, mod);
+		case 'n': case 'N':
+			return sym_set_tristate_value(sym, no);
+		}
+		return false;
+	default:
+		;
+	}
+
+	if (!sym_string_within_range(sym, newval))
+		return false;
+
+	if (!(sym->flags & SYMBOL_DEF_USER)) {
+		sym->flags |= SYMBOL_DEF_USER;
+		sym_set_changed(sym);
+	}
+
+	oldval = sym->def[S_DEF_USER].val;
+	size = strlen(newval) + 1;
+	if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
+		size += 2;
+		sym->def[S_DEF_USER].val = val = malloc(size);
+		*val++ = '0';
+		*val++ = 'x';
+	} else if (!oldval || strcmp(oldval, newval))
+		sym->def[S_DEF_USER].val = val = malloc(size);
+	else
+		return true;
+
+	strcpy(val, newval);
+	free((void *)oldval);
+	sym_clear_all_valid();
+
+	return true;
+}
+
+/*
+ * Find the default value associated to a symbol.
+ * For tristate symbol handle the modules=n case
+ * in which case "m" becomes "y".
+ * If the symbol does not have any default then fallback
+ * to the fixed default values.
+ */
+const char *sym_get_string_default(struct symbol *sym)
+{
+	struct property *prop;
+	struct symbol *ds;
+	const char *str;
+	tristate val;
+
+	sym_calc_visibility(sym);
+	sym_calc_value(modules_sym);
+	val = symbol_no.curr.tri;
+	str = symbol_empty.curr.val;
+
+	/* If symbol has a default value look it up */
+	prop = sym_get_default_prop(sym);
+	if (prop != NULL) {
+		switch (sym->type) {
+		case S_BOOLEAN:
+		case S_TRISTATE:
+			/* The visibility may limit the value from yes => mod */
+			val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
+			break;
+		default:
+			/*
+			 * The following fails to handle the situation
+			 * where a default value is further limited by
+			 * the valid range.
+			 */
+			ds = prop_get_symbol(prop);
+			if (ds != NULL) {
+				sym_calc_value(ds);
+				str = (const char *)ds->curr.val;
+			}
+		}
+	}
+
+	/* Handle select statements */
+	val = EXPR_OR(val, sym->rev_dep.tri);
+
+	/* transpose mod to yes if modules are not enabled */
+	if (val == mod)
+		if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
+			val = yes;
+
+	/* transpose mod to yes if type is bool */
+	if (sym->type == S_BOOLEAN && val == mod)
+		val = yes;
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		switch (val) {
+		case no: return "n";
+		case mod: return "m";
+		case yes: return "y";
+		}
+	case S_INT:
+	case S_HEX:
+		return str;
+	case S_STRING:
+		return str;
+	case S_OTHER:
+	case S_UNKNOWN:
+		break;
+	}
+	return "";
+}
+
+const char *sym_get_string_value(struct symbol *sym)
+{
+	tristate val;
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		val = sym_get_tristate_value(sym);
+		switch (val) {
+		case no:
+			return "n";
+		case mod:
+			sym_calc_value(modules_sym);
+			return (modules_sym->curr.tri == no) ? "n" : "m";
+		case yes:
+			return "y";
+		}
+		break;
+	default:
+		;
+	}
+	return (const char *)sym->curr.val;
+}
+
+bool sym_is_changable(struct symbol *sym)
+{
+	return sym->visible > sym->rev_dep.tri;
+}
+
+static unsigned strhash(const char *s)
+{
+	/* fnv32 hash */
+	unsigned hash = 2166136261U;
+	for (; *s; s++)
+		hash = (hash ^ *s) * 0x01000193;
+	return hash;
+}
+
+struct symbol *sym_lookup(const char *name, int flags)
+{
+	struct symbol *symbol;
+	char *new_name;
+	int hash;
+
+	if (name) {
+		if (name[0] && !name[1]) {
+			switch (name[0]) {
+			case 'y': return &symbol_yes;
+			case 'm': return &symbol_mod;
+			case 'n': return &symbol_no;
+			}
+		}
+		hash = strhash(name) % SYMBOL_HASHSIZE;
+
+		for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+			if (symbol->name &&
+			    !strcmp(symbol->name, name) &&
+			    (flags ? symbol->flags & flags
+				   : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
+				return symbol;
+		}
+		new_name = strdup(name);
+	} else {
+		new_name = NULL;
+		hash = 0;
+	}
+
+	symbol = malloc(sizeof(*symbol));
+	memset(symbol, 0, sizeof(*symbol));
+	symbol->name = new_name;
+	symbol->type = S_UNKNOWN;
+	symbol->flags |= flags;
+
+	symbol->next = symbol_hash[hash];
+	symbol_hash[hash] = symbol;
+
+	return symbol;
+}
+
+struct symbol *sym_find(const char *name)
+{
+	struct symbol *symbol = NULL;
+	int hash = 0;
+
+	if (!name)
+		return NULL;
+
+	if (name[0] && !name[1]) {
+		switch (name[0]) {
+		case 'y': return &symbol_yes;
+		case 'm': return &symbol_mod;
+		case 'n': return &symbol_no;
+		}
+	}
+	hash = strhash(name) % SYMBOL_HASHSIZE;
+
+	for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+		if (symbol->name &&
+		    !strcmp(symbol->name, name) &&
+		    !(symbol->flags & SYMBOL_CONST))
+				break;
+	}
+
+	return symbol;
+}
+
+/*
+ * Expand symbol's names embedded in the string given in argument. Symbols'
+ * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
+ * the empty string.
+ */
+const char *sym_expand_string_value(const char *in)
+{
+	const char *src;
+	char *res;
+	size_t reslen;
+
+	reslen = strlen(in) + 1;
+	res = malloc(reslen);
+	res[0] = '\0';
+
+	while ((src = strchr(in, '$'))) {
+		char *p, name[SYMBOL_MAXLENGTH];
+		const char *symval = "";
+		struct symbol *sym;
+		size_t newlen;
+
+		strncat(res, in, src - in);
+		src++;
+
+		p = name;
+		while (isalnum(*src) || *src == '_')
+			*p++ = *src++;
+		*p = '\0';
+
+		sym = sym_find(name);
+		if (sym != NULL) {
+			sym_calc_value(sym);
+			symval = sym_get_string_value(sym);
+		}
+
+		newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
+		if (newlen > reslen) {
+			reslen = newlen;
+			res = realloc(res, reslen);
+		}
+
+		strcat(res, symval);
+		in = src;
+	}
+	strcat(res, in);
+
+	return res;
+}
+
+const char *sym_escape_string_value(const char *in)
+{
+	const char *p;
+	size_t reslen;
+	char *res;
+	size_t l;
+
+	reslen = strlen(in) + strlen("\"\"") + 1;
+
+	p = in;
+	for (;;) {
+		l = strcspn(p, "\"\\");
+		p += l;
+
+		if (p[0] == '\0')
+			break;
+
+		reslen++;
+		p++;
+	}
+
+	res = malloc(reslen);
+	res[0] = '\0';
+
+	strcat(res, "\"");
+
+	p = in;
+	for (;;) {
+		l = strcspn(p, "\"\\");
+		strncat(res, p, l);
+		p += l;
+
+		if (p[0] == '\0')
+			break;
+
+		strcat(res, "\\");
+		strncat(res, p++, 1);
+	}
+
+	strcat(res, "\"");
+	return res;
+}
+
+struct symbol **sym_re_search(const char *pattern)
+{
+	struct symbol *sym, **sym_arr = NULL;
+	int i, cnt, size;
+	regex_t re;
+
+	cnt = size = 0;
+	/* Skip if empty */
+	if (strlen(pattern) == 0)
+		return NULL;
+	if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
+		return NULL;
+
+	for_all_symbols(i, sym) {
+		if (sym->flags & SYMBOL_CONST || !sym->name)
+			continue;
+		if (regexec(&re, sym->name, 0, NULL, 0))
+			continue;
+		if (cnt + 1 >= size) {
+			void *tmp = sym_arr;
+			size += 16;
+			sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
+			if (!sym_arr) {
+				free(tmp);
+				return NULL;
+			}
+		}
+		sym_calc_value(sym);
+		sym_arr[cnt++] = sym;
+	}
+	if (sym_arr)
+		sym_arr[cnt] = NULL;
+	regfree(&re);
+
+	return sym_arr;
+}
+
+/*
+ * When we check for recursive dependencies we use a stack to save
+ * current state so we can print out relevant info to user.
+ * The entries are located on the call stack so no need to free memory.
+ * Note inser() remove() must always match to properly clear the stack.
+ */
+static struct dep_stack {
+	struct dep_stack *prev, *next;
+	struct symbol *sym;
+	struct property *prop;
+	struct expr *expr;
+} *check_top;
+
+static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
+{
+	memset(stack, 0, sizeof(*stack));
+	if (check_top)
+		check_top->next = stack;
+	stack->prev = check_top;
+	stack->sym = sym;
+	check_top = stack;
+}
+
+static void dep_stack_remove(void)
+{
+	check_top = check_top->prev;
+	if (check_top)
+		check_top->next = NULL;
+}
+
+/*
+ * Called when we have detected a recursive dependency.
+ * check_top point to the top of the stact so we use
+ * the ->prev pointer to locate the bottom of the stack.
+ */
+static void sym_check_print_recursive(struct symbol *last_sym)
+{
+	struct dep_stack *stack;
+	struct symbol *sym, *next_sym;
+	struct menu *menu = NULL;
+	struct property *prop;
+	struct dep_stack cv_stack;
+
+	if (sym_is_choice_value(last_sym)) {
+		dep_stack_insert(&cv_stack, last_sym);
+		last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
+	}
+
+	for (stack = check_top; stack != NULL; stack = stack->prev)
+		if (stack->sym == last_sym)
+			break;
+	if (!stack) {
+		fprintf(stderr, "unexpected recursive dependency error\n");
+		return;
+	}
+
+	for (; stack; stack = stack->next) {
+		sym = stack->sym;
+		next_sym = stack->next ? stack->next->sym : last_sym;
+		prop = stack->prop;
+		if (prop == NULL)
+			prop = stack->sym->prop;
+
+		/* for choice values find the menu entry (used below) */
+		if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
+			for (prop = sym->prop; prop; prop = prop->next) {
+				menu = prop->menu;
+				if (prop->menu)
+					break;
+			}
+		}
+		if (stack->sym == last_sym)
+			fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
+				prop->file->name, prop->lineno);
+		if (stack->expr) {
+			fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
+				prop->file->name, prop->lineno,
+				sym->name ? sym->name : "<choice>",
+				prop_get_type_name(prop->type),
+				next_sym->name ? next_sym->name : "<choice>");
+		} else if (stack->prop) {
+			fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
+				prop->file->name, prop->lineno,
+				sym->name ? sym->name : "<choice>",
+				next_sym->name ? next_sym->name : "<choice>");
+		} else if (sym_is_choice(sym)) {
+			fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
+				menu->file->name, menu->lineno,
+				sym->name ? sym->name : "<choice>",
+				next_sym->name ? next_sym->name : "<choice>");
+		} else if (sym_is_choice_value(sym)) {
+			fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
+				menu->file->name, menu->lineno,
+				sym->name ? sym->name : "<choice>",
+				next_sym->name ? next_sym->name : "<choice>");
+		} else {
+			fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
+				prop->file->name, prop->lineno,
+				sym->name ? sym->name : "<choice>",
+				next_sym->name ? next_sym->name : "<choice>");
+		}
+	}
+
+	if (check_top == &cv_stack)
+		dep_stack_remove();
+}
+
+static struct symbol *sym_check_expr_deps(struct expr *e)
+{
+	struct symbol *sym;
+
+	if (!e)
+		return NULL;
+	switch (e->type) {
+	case E_OR:
+	case E_AND:
+		sym = sym_check_expr_deps(e->left.expr);
+		if (sym)
+			return sym;
+		return sym_check_expr_deps(e->right.expr);
+	case E_NOT:
+		return sym_check_expr_deps(e->left.expr);
+	case E_EQUAL:
+	case E_UNEQUAL:
+		sym = sym_check_deps(e->left.sym);
+		if (sym)
+			return sym;
+		return sym_check_deps(e->right.sym);
+	case E_SYMBOL:
+		return sym_check_deps(e->left.sym);
+	default:
+		break;
+	}
+	printf("Oops! How to check %d?\n", e->type);
+	return NULL;
+}
+
+/* return NULL when dependencies are OK */
+static struct symbol *sym_check_sym_deps(struct symbol *sym)
+{
+	struct symbol *sym2;
+	struct property *prop;
+	struct dep_stack stack;
+
+	dep_stack_insert(&stack, sym);
+
+	sym2 = sym_check_expr_deps(sym->rev_dep.expr);
+	if (sym2)
+		goto out;
+
+	for (prop = sym->prop; prop; prop = prop->next) {
+		if (prop->type == P_CHOICE || prop->type == P_SELECT)
+			continue;
+		stack.prop = prop;
+		sym2 = sym_check_expr_deps(prop->visible.expr);
+		if (sym2)
+			break;
+		if (prop->type != P_DEFAULT || sym_is_choice(sym))
+			continue;
+		stack.expr = prop->expr;
+		sym2 = sym_check_expr_deps(prop->expr);
+		if (sym2)
+			break;
+		stack.expr = NULL;
+	}
+
+out:
+	dep_stack_remove();
+
+	return sym2;
+}
+
+static struct symbol *sym_check_choice_deps(struct symbol *choice)
+{
+	struct symbol *sym, *sym2;
+	struct property *prop;
+	struct expr *e;
+	struct dep_stack stack;
+
+	dep_stack_insert(&stack, choice);
+
+	prop = sym_get_choice_prop(choice);
+	expr_list_for_each_sym(prop->expr, e, sym)
+		sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+
+	choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+	sym2 = sym_check_sym_deps(choice);
+	choice->flags &= ~SYMBOL_CHECK;
+	if (sym2)
+		goto out;
+
+	expr_list_for_each_sym(prop->expr, e, sym) {
+		sym2 = sym_check_sym_deps(sym);
+		if (sym2)
+			break;
+	}
+out:
+	expr_list_for_each_sym(prop->expr, e, sym)
+		sym->flags &= ~SYMBOL_CHECK;
+
+	if (sym2 && sym_is_choice_value(sym2) &&
+	    prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
+		sym2 = choice;
+
+	dep_stack_remove();
+
+	return sym2;
+}
+
+struct symbol *sym_check_deps(struct symbol *sym)
+{
+	struct symbol *sym2;
+	struct property *prop;
+
+	if (sym->flags & SYMBOL_CHECK) {
+		sym_check_print_recursive(sym);
+		return sym;
+	}
+	if (sym->flags & SYMBOL_CHECKED)
+		return NULL;
+
+	if (sym_is_choice_value(sym)) {
+		struct dep_stack stack;
+
+		/* for choice groups start the check with main choice symbol */
+		dep_stack_insert(&stack, sym);
+		prop = sym_get_choice_prop(sym);
+		sym2 = sym_check_deps(prop_get_symbol(prop));
+		dep_stack_remove();
+	} else if (sym_is_choice(sym)) {
+		sym2 = sym_check_choice_deps(sym);
+	} else {
+		sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+		sym2 = sym_check_sym_deps(sym);
+		sym->flags &= ~SYMBOL_CHECK;
+	}
+
+	if (sym2 && sym2 == sym)
+		sym2 = NULL;
+
+	return sym2;
+}
+
+struct property *prop_alloc(enum prop_type type, struct symbol *sym)
+{
+	struct property *prop;
+	struct property **propp;
+
+	prop = malloc(sizeof(*prop));
+	memset(prop, 0, sizeof(*prop));
+	prop->type = type;
+	prop->sym = sym;
+	prop->file = current_file;
+	prop->lineno = zconf_lineno();
+
+	/* append property to the prop list of symbol */
+	if (sym) {
+		for (propp = &sym->prop; *propp; propp = &(*propp)->next)
+			;
+		*propp = prop;
+	}
+
+	return prop;
+}
+
+struct symbol *prop_get_symbol(struct property *prop)
+{
+	if (prop->expr && (prop->expr->type == E_SYMBOL ||
+			   prop->expr->type == E_LIST))
+		return prop->expr->left.sym;
+	return NULL;
+}
+
+const char *prop_get_type_name(enum prop_type type)
+{
+	switch (type) {
+	case P_PROMPT:
+		return "prompt";
+	case P_ENV:
+		return "env";
+	case P_COMMENT:
+		return "comment";
+	case P_MENU:
+		return "menu";
+	case P_DEFAULT:
+		return "default";
+	case P_CHOICE:
+		return "choice";
+	case P_SELECT:
+		return "select";
+	case P_RANGE:
+		return "range";
+	case P_SYMBOL:
+		return "symbol";
+	case P_UNKNOWN:
+		break;
+	}
+	return "unknown";
+}
+
+static void prop_add_env(const char *env)
+{
+	struct symbol *sym, *sym2;
+	struct property *prop;
+	char *p;
+
+	sym = current_entry->sym;
+	sym->flags |= SYMBOL_AUTO;
+	for_all_properties(sym, prop, P_ENV) {
+		sym2 = prop_get_symbol(prop);
+		if (strcmp(sym2->name, env))
+			menu_warn(current_entry, "redefining environment symbol from %s",
+				  sym2->name);
+		return;
+	}
+
+	prop = prop_alloc(P_ENV, sym);
+	prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
+
+	sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
+	sym_env_list->right.sym = sym;
+
+	p = getenv(env);
+	if (p)
+		sym_add_default(sym, p);
+	else
+		menu_warn(current_entry, "environment variable %s undefined", env);
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/util.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/util.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2002-2005 Roman Zippel <zippel at linux-m68k.org>
+ * Copyright (C) 2002-2005 Sam Ravnborg <sam at 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;
+}
+

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/zconf.gperf
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/zconf.gperf	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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
+%%

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/zconf.l
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/zconf.l	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 at 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>";
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/config/zconf.y
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/config/zconf.y	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,740 @@
+%{
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel at 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"

Added: dists/trunk/firmware-free/linux-free/carl9170fw/extra/FindGPERF.cmake
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/extra/FindGPERF.cmake	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,160 @@
+# - 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
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+#
+# * Neither the names of Kitware, Inc., the Insight Software Consortium,
+#   nor the names of their contributors may be used to endorse or promote
+#   products derived from this software without specific prior written
+#   permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+cmake_minimum_required(VERSION 2.8.4)
+
+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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/extra/FindPackageHandleStandardArgs.cmake
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/extra/FindPackageHandleStandardArgs.cmake	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,278 @@
+# 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.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+#
+# * Neither the names of Kitware, Inc., the Insight Software Consortium,
+#   nor the names of their contributors may be used to endorse or promote
+#   products derived from this software without specific prior written
+#   permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+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)

Added: dists/trunk/firmware-free/linux-free/carl9170fw/extra/FindUSB-1.0.cmake
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/extra/FindUSB-1.0.cmake	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,112 @@
+# - 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 at cynapses.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+
+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)
+

Added: dists/trunk/firmware-free/linux-free/carl9170fw/extra/GCCVersion.cmake
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/extra/GCCVersion.cmake	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,60 @@
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006-2008 Andreas Schneider <mail at cynapses.org>
+# Copyright 2007      Wengo
+# Copyright 2007      Mike Jackson
+# Copyright 2008      Andreas Pakulat <apaku at gmx.de>
+# Copyright 2008-2009 Philip Lowman <philip at yhbt.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+#
+# * Neither the names of Kitware, Inc., the Insight Software Consortium,
+#   nor the names of their contributors may be used to endorse or promote
+#   products derived from this software without specific prior written
+#   permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#-------------------------------------------------------------------------------
+
+#
+# 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
+#
+#-------------------------------------------------------------------------------
+
+

Added: dists/trunk/firmware-free/linux-free/carl9170fw/extra/libusb-zeropacket.diff
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/extra/libusb-zeropacket.diff	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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,

Added: dists/trunk/firmware-free/linux-free/carl9170fw/extra/sh-elf-linux.cmake
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/extra/sh-elf-linux.cmake	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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)

Added: dists/trunk/firmware-free/linux-free/carl9170fw/genapi.sh
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/genapi.sh	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/ch9.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/ch9.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/compiler.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/compiler.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/ieee80211.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/ieee80211.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,1918 @@
+/*
+ * IEEE 802.11 defines
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <jkmaline at cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline at cc.hut.fi>
+ * Copyright (c) 2005, Devicescape Software, Inc.
+ * Copyright (c) 2006, Michael Wu <flamingice at sourmilk.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_IEEE80211_H
+#define __LINUX_IEEE80211_H
+
+/*
+ * DS bit usage
+ *
+ * TA = transmitter address
+ * RA = receiver address
+ * DA = destination address
+ * SA = source address
+ *
+ * ToDS    FromDS  A1(RA)  A2(TA)  A3      A4      Use
+ * -----------------------------------------------------------------
+ *  0       0       DA      SA      BSSID   -       IBSS/DLS
+ *  0       1       DA      BSSID   SA      -       AP -> STA
+ *  1       0       BSSID   SA      DA      -       AP <- STA
+ *  1       1       RA      TA      DA      SA      unspecified (WDS)
+ */
+
+#define FCS_LEN 4
+
+#define IEEE80211_FCTL_VERS		0x0003
+#define IEEE80211_FCTL_FTYPE		0x000c
+#define IEEE80211_FCTL_STYPE		0x00f0
+#define IEEE80211_FCTL_TODS		0x0100
+#define IEEE80211_FCTL_FROMDS		0x0200
+#define IEEE80211_FCTL_MOREFRAGS	0x0400
+#define IEEE80211_FCTL_RETRY		0x0800
+#define IEEE80211_FCTL_PM		0x1000
+#define IEEE80211_FCTL_MOREDATA		0x2000
+#define IEEE80211_FCTL_PROTECTED	0x4000
+#define IEEE80211_FCTL_ORDER		0x8000
+
+#define IEEE80211_SCTL_FRAG		0x000F
+#define IEEE80211_SCTL_SEQ		0xFFF0
+
+#define IEEE80211_FTYPE_MGMT		0x0000
+#define IEEE80211_FTYPE_CTL		0x0004
+#define IEEE80211_FTYPE_DATA		0x0008
+
+/* management */
+#define IEEE80211_STYPE_ASSOC_REQ	0x0000
+#define IEEE80211_STYPE_ASSOC_RESP	0x0010
+#define IEEE80211_STYPE_REASSOC_REQ	0x0020
+#define IEEE80211_STYPE_REASSOC_RESP	0x0030
+#define IEEE80211_STYPE_PROBE_REQ	0x0040
+#define IEEE80211_STYPE_PROBE_RESP	0x0050
+#define IEEE80211_STYPE_BEACON		0x0080
+#define IEEE80211_STYPE_ATIM		0x0090
+#define IEEE80211_STYPE_DISASSOC	0x00A0
+#define IEEE80211_STYPE_AUTH		0x00B0
+#define IEEE80211_STYPE_DEAUTH		0x00C0
+#define IEEE80211_STYPE_ACTION		0x00D0
+
+/* control */
+#define IEEE80211_STYPE_BACK_REQ	0x0080
+#define IEEE80211_STYPE_BACK		0x0090
+#define IEEE80211_STYPE_PSPOLL		0x00A0
+#define IEEE80211_STYPE_RTS		0x00B0
+#define IEEE80211_STYPE_CTS		0x00C0
+#define IEEE80211_STYPE_ACK		0x00D0
+#define IEEE80211_STYPE_CFEND		0x00E0
+#define IEEE80211_STYPE_CFENDACK	0x00F0
+
+/* data */
+#define IEEE80211_STYPE_DATA			0x0000
+#define IEEE80211_STYPE_DATA_CFACK		0x0010
+#define IEEE80211_STYPE_DATA_CFPOLL		0x0020
+#define IEEE80211_STYPE_DATA_CFACKPOLL		0x0030
+#define IEEE80211_STYPE_NULLFUNC		0x0040
+#define IEEE80211_STYPE_CFACK			0x0050
+#define IEEE80211_STYPE_CFPOLL			0x0060
+#define IEEE80211_STYPE_CFACKPOLL		0x0070
+#define IEEE80211_STYPE_QOS_DATA		0x0080
+#define IEEE80211_STYPE_QOS_DATA_CFACK		0x0090
+#define IEEE80211_STYPE_QOS_DATA_CFPOLL		0x00A0
+#define IEEE80211_STYPE_QOS_DATA_CFACKPOLL	0x00B0
+#define IEEE80211_STYPE_QOS_NULLFUNC		0x00C0
+#define IEEE80211_STYPE_QOS_CFACK		0x00D0
+#define IEEE80211_STYPE_QOS_CFPOLL		0x00E0
+#define IEEE80211_STYPE_QOS_CFACKPOLL		0x00F0
+
+
+/* miscellaneous IEEE 802.11 constants */
+#define IEEE80211_MAX_FRAG_THRESHOLD	2352
+#define IEEE80211_MAX_RTS_THRESHOLD	2353
+#define IEEE80211_MAX_AID		2007
+#define IEEE80211_MAX_TIM_LEN		251
+/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+   6.2.1.1.2.
+
+   802.11e clarifies the figure in section 7.1.2. The frame body is
+   up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */
+#define IEEE80211_MAX_DATA_LEN		2304
+/* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */
+#define IEEE80211_MAX_FRAME_LEN		2352
+
+#define IEEE80211_MAX_SSID_LEN		32
+
+#define IEEE80211_MAX_MESH_ID_LEN	32
+
+#define IEEE80211_QOS_CTL_LEN		2
+/* 1d tag mask */
+#define IEEE80211_QOS_CTL_TAG1D_MASK		0x0007
+/* TID mask */
+#define IEEE80211_QOS_CTL_TID_MASK		0x000f
+/* EOSP */
+#define IEEE80211_QOS_CTL_EOSP			0x0010
+/* ACK policy */
+#define IEEE80211_QOS_CTL_ACK_POLICY_NORMAL	0x0000
+#define IEEE80211_QOS_CTL_ACK_POLICY_NOACK	0x0020
+#define IEEE80211_QOS_CTL_ACK_POLICY_NO_EXPL	0x0040
+#define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK	0x0060
+#define IEEE80211_QOS_CTL_ACK_POLICY_MASK	0x0060
+/* A-MSDU 802.11n */
+#define IEEE80211_QOS_CTL_A_MSDU_PRESENT	0x0080
+/* Mesh Control 802.11s */
+#define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT  0x0100
+
+/* U-APSD queue for WMM IEs sent by AP */
+#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD	(1<<7)
+#define IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK	0x0f
+
+/* U-APSD queues for WMM IEs sent by STA */
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO	(1<<0)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VI	(1<<1)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BK	(1<<2)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BE	(1<<3)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK	0x0f
+
+/* U-APSD max SP length for WMM IEs sent by STA */
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL	0x00
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_2	0x01
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_4	0x02
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_6	0x03
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK	0x03
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT	5
+
+#define IEEE80211_HT_CTL_LEN		4
+
+struct ieee80211_hdr {
+	__le16 frame_control;
+	__le16 duration_id;
+	u8 addr1[6];
+	u8 addr2[6];
+	u8 addr3[6];
+	__le16 seq_ctrl;
+	u8 addr4[6];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+	__le16 frame_control;
+	__le16 duration_id;
+	u8 addr1[6];
+	u8 addr2[6];
+	u8 addr3[6];
+	__le16 seq_ctrl;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_hdr {
+	__le16 frame_control;
+	__le16 duration_id;
+	u8 addr1[6];
+	u8 addr2[6];
+	u8 addr3[6];
+	__le16 seq_ctrl;
+	__le16 qos_ctrl;
+} __attribute__ ((packed));
+
+/**
+ * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_has_tods(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0;
+}
+
+/**
+ * ieee80211_has_fromds - check if IEEE80211_FCTL_FROMDS is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_has_fromds(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0;
+}
+
+/**
+ * ieee80211_has_a4 - check if IEEE80211_FCTL_TODS and IEEE80211_FCTL_FROMDS are set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_has_a4(__le16 fc)
+{
+	__le16 tmp = cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
+	return (fc & tmp) == tmp;
+}
+
+/**
+ * ieee80211_has_morefrags - check if IEEE80211_FCTL_MOREFRAGS is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_has_morefrags(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0;
+}
+
+/**
+ * ieee80211_has_retry - check if IEEE80211_FCTL_RETRY is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_has_retry(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0;
+}
+
+/**
+ * ieee80211_has_pm - check if IEEE80211_FCTL_PM is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_has_pm(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_PM)) != 0;
+}
+
+/**
+ * ieee80211_has_moredata - check if IEEE80211_FCTL_MOREDATA is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_has_moredata(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0;
+}
+
+/**
+ * ieee80211_has_protected - check if IEEE80211_FCTL_PROTECTED is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_has_protected(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0;
+}
+
+/**
+ * ieee80211_has_order - check if IEEE80211_FCTL_ORDER is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_has_order(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0;
+}
+
+/**
+ * ieee80211_is_mgmt - check if type is IEEE80211_FTYPE_MGMT
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_mgmt(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT);
+}
+
+/**
+ * ieee80211_is_ctl - check if type is IEEE80211_FTYPE_CTL
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_ctl(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_CTL);
+}
+
+/**
+ * ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_data(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_DATA);
+}
+
+/**
+ * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_data_qos(__le16 fc)
+{
+	/*
+	 * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need
+	 * to check the one bit
+	 */
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_STYPE_QOS_DATA)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA);
+}
+
+/**
+ * ieee80211_is_data_present - check if type is IEEE80211_FTYPE_DATA and has data
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_data_present(__le16 fc)
+{
+	/*
+	 * mask with 0x40 and test that that bit is clear to only return true
+	 * for the data-containing substypes.
+	 */
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 0x40)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_DATA);
+}
+
+/**
+ * ieee80211_is_assoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_REQ
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_assoc_req(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ);
+}
+
+/**
+ * ieee80211_is_assoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_RESP
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_assoc_resp(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP);
+}
+
+/**
+ * ieee80211_is_reassoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_REQ
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_reassoc_req(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ);
+}
+
+/**
+ * ieee80211_is_reassoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_RESP
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_reassoc_resp(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP);
+}
+
+/**
+ * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_probe_req(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ);
+}
+
+/**
+ * ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_RESP
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_probe_resp(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
+}
+
+/**
+ * ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_BEACON
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_beacon(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
+}
+
+/**
+ * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_atim(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ATIM);
+}
+
+/**
+ * ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DISASSOC
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_disassoc(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC);
+}
+
+/**
+ * ieee80211_is_auth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_AUTH
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_auth(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
+}
+
+/**
+ * ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DEAUTH
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_deauth(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
+}
+
+/**
+ * ieee80211_is_action - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ACTION
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_action(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
+}
+
+/**
+ * ieee80211_is_back_req - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK_REQ
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_back_req(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ);
+}
+
+/**
+ * ieee80211_is_back - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_back(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK);
+}
+
+/**
+ * ieee80211_is_pspoll - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_PSPOLL
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_pspoll(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
+}
+
+/**
+ * ieee80211_is_rts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_RTS
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_rts(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
+}
+
+/**
+ * ieee80211_is_cts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CTS
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_cts(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
+}
+
+/**
+ * ieee80211_is_ack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_ACK
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_ack(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK);
+}
+
+/**
+ * ieee80211_is_cfend - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFEND
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_cfend(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFEND);
+}
+
+/**
+ * ieee80211_is_cfendack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFENDACK
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_cfendack(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFENDACK);
+}
+
+/**
+ * ieee80211_is_nullfunc - check if frame is a regular (non-QoS) nullfunc frame
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_nullfunc(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC);
+}
+
+/**
+ * ieee80211_is_qos_nullfunc - check if frame is a QoS nullfunc frame
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_qos_nullfunc(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+	       cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);
+}
+
+static inline unsigned int ieee80211_hdrlen(__le16 fc)
+{
+	unsigned int hdrlen = 24;
+
+	if (ieee80211_has_a4(fc))
+		hdrlen = 30;
+
+	if (ieee80211_is_data_qos(fc)) {
+		hdrlen += IEEE80211_QOS_CTL_LEN;
+		if (ieee80211_has_order(fc))
+			hdrlen += IEEE80211_HT_CTL_LEN;
+	}
+
+        return hdrlen;
+}
+
+/**
+ * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set
+ * @seq_ctrl: frame sequence control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_first_frag(__le16 seq_ctrl)
+{
+	return (seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0;
+}
+
+struct ieee80211s_hdr {
+	u8 flags;
+	u8 ttl;
+	__le32 seqnum;
+	u8 eaddr1[6];
+	u8 eaddr2[6];
+} __attribute__ ((packed));
+
+/* Mesh flags */
+#define MESH_FLAGS_AE_A4	0x1
+#define MESH_FLAGS_AE_A5_A6	0x2
+#define MESH_FLAGS_AE		0x3
+#define MESH_FLAGS_PS_DEEP	0x4
+
+/**
+ * struct ieee80211_quiet_ie
+ *
+ * This structure refers to "Quiet information element"
+ */
+struct ieee80211_quiet_ie {
+	u8 count;
+	u8 period;
+	__le16 duration;
+	__le16 offset;
+} __attribute__ ((packed));
+
+/**
+ * struct ieee80211_msrment_ie
+ *
+ * This structure refers to "Measurement Request/Report information element"
+ */
+struct ieee80211_msrment_ie {
+	u8 token;
+	u8 mode;
+	u8 type;
+	u8 request[0];
+} __attribute__ ((packed));
+
+/**
+ * struct ieee80211_channel_sw_ie
+ *
+ * This structure refers to "Channel Switch Announcement information element"
+ */
+struct ieee80211_channel_sw_ie {
+	u8 mode;
+	u8 new_ch_num;
+	u8 count;
+} __attribute__ ((packed));
+
+/**
+ * struct ieee80211_tim
+ *
+ * This structure refers to "Traffic Indication Map information element"
+ */
+struct ieee80211_tim_ie {
+	u8 dtim_count;
+	u8 dtim_period;
+	u8 bitmap_ctrl;
+	/* variable size: 1 - 251 bytes */
+	u8 virtual_map[1];
+} __attribute__ ((packed));
+
+/**
+ * struct ieee80211_meshconf_ie
+ *
+ * This structure refers to "Mesh Configuration information element"
+ */
+struct ieee80211_meshconf_ie {
+	u8 meshconf_psel;
+	u8 meshconf_pmetric;
+	u8 meshconf_congest;
+	u8 meshconf_synch;
+	u8 meshconf_auth;
+	u8 meshconf_form;
+	u8 meshconf_cap;
+} __attribute__ ((packed));
+
+/**
+ * struct ieee80211_rann_ie
+ *
+ * This structure refers to "Root Announcement information element"
+ */
+struct ieee80211_rann_ie {
+	u8 rann_flags;
+	u8 rann_hopcount;
+	u8 rann_ttl;
+	u8 rann_addr[6];
+	__le32 rann_seq;
+	__le32 rann_interval;
+	__le32 rann_metric;
+} __attribute__ ((packed));
+
+enum ieee80211_rann_flags {
+	RANN_FLAG_IS_GATE = 1 << 0,
+};
+
+#define WLAN_SA_QUERY_TR_ID_LEN 2
+
+struct ieee80211_mgmt {
+	__le16 frame_control;
+	__le16 duration;
+	u8 da[6];
+	u8 sa[6];
+	u8 bssid[6];
+	__le16 seq_ctrl;
+	union {
+		struct {
+			__le16 auth_alg;
+			__le16 auth_transaction;
+			__le16 status_code;
+			/* possibly followed by Challenge text */
+			u8 variable[0];
+		} __attribute__ ((packed)) auth;
+		struct {
+			__le16 reason_code;
+		} __attribute__ ((packed)) deauth;
+		struct {
+			__le16 capab_info;
+			__le16 listen_interval;
+			/* followed by SSID and Supported rates */
+			u8 variable[0];
+		} __attribute__ ((packed)) assoc_req;
+		struct {
+			__le16 capab_info;
+			__le16 status_code;
+			__le16 aid;
+			/* followed by Supported rates */
+			u8 variable[0];
+		} __attribute__ ((packed)) assoc_resp, reassoc_resp;
+		struct {
+			__le16 capab_info;
+			__le16 listen_interval;
+			u8 current_ap[6];
+			/* followed by SSID and Supported rates */
+			u8 variable[0];
+		} __attribute__ ((packed)) reassoc_req;
+		struct {
+			__le16 reason_code;
+		} __attribute__ ((packed)) disassoc;
+		struct {
+			__le64 timestamp;
+			__le16 beacon_int;
+			__le16 capab_info;
+			/* followed by some of SSID, Supported rates,
+			 * FH Params, DS Params, CF Params, IBSS Params, TIM */
+			u8 variable[0];
+		} __attribute__ ((packed)) beacon;
+		struct {
+			/* only variable items: SSID, Supported rates */
+			u8 variable[0];
+		} __attribute__ ((packed)) probe_req;
+		struct {
+			__le64 timestamp;
+			__le16 beacon_int;
+			__le16 capab_info;
+			/* followed by some of SSID, Supported rates,
+			 * FH Params, DS Params, CF Params, IBSS Params */
+			u8 variable[0];
+		} __attribute__ ((packed)) probe_resp;
+		struct {
+			u8 category;
+			union {
+				struct {
+					u8 action_code;
+					u8 dialog_token;
+					u8 status_code;
+					u8 variable[0];
+				} __attribute__ ((packed)) wme_action;
+				struct{
+					u8 action_code;
+					u8 element_id;
+					u8 length;
+					struct ieee80211_channel_sw_ie sw_elem;
+				} __attribute__((packed)) chan_switch;
+				struct{
+					u8 action_code;
+					u8 dialog_token;
+					u8 element_id;
+					u8 length;
+					struct ieee80211_msrment_ie msr_elem;
+				} __attribute__((packed)) measurement;
+				struct{
+					u8 action_code;
+					u8 dialog_token;
+					__le16 capab;
+					__le16 timeout;
+					__le16 start_seq_num;
+				} __attribute__((packed)) addba_req;
+				struct{
+					u8 action_code;
+					u8 dialog_token;
+					__le16 status;
+					__le16 capab;
+					__le16 timeout;
+				} __attribute__((packed)) addba_resp;
+				struct{
+					u8 action_code;
+					__le16 params;
+					__le16 reason_code;
+				} __attribute__((packed)) delba;
+				struct {
+					u8 action_code;
+					u8 variable[0];
+				} __attribute__((packed)) self_prot;
+				struct{
+					u8 action_code;
+					u8 variable[0];
+				} __attribute__((packed)) mesh_action;
+				struct {
+					u8 action;
+					u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+				} __attribute__ ((packed)) sa_query;
+				struct {
+					u8 action;
+					u8 smps_control;
+				} __attribute__ ((packed)) ht_smps;
+				struct {
+					u8 action_code;
+					u8 dialog_token;
+					__le16 capability;
+					u8 variable[0];
+				} __packed tdls_discover_resp;
+			} u;
+		} __attribute__ ((packed)) action;
+	} u;
+} __attribute__ ((packed));
+
+/* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */
+#define BSS_MEMBERSHIP_SELECTOR_HT_PHY	127
+
+/* mgmt header + 1 byte category code */
+#define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
+
+
+/* Management MIC information element (IEEE 802.11w) */
+struct ieee80211_mmie {
+	u8 element_id;
+	u8 length;
+	__le16 key_id;
+	u8 sequence_number[6];
+	u8 mic[8];
+} __attribute__ ((packed));
+
+struct ieee80211_vendor_ie {
+	u8 element_id;
+	u8 len;
+	u8 oui[3];
+	u8 oui_type;
+} __packed;
+
+/* Control frames */
+struct ieee80211_rts {
+	__le16 frame_control;
+	__le16 duration;
+	u8 ra[6];
+	u8 ta[6];
+} __attribute__ ((packed));
+
+struct ieee80211_cts {
+	__le16 frame_control;
+	__le16 duration;
+	u8 ra[6];
+} __attribute__ ((packed));
+
+struct ieee80211_pspoll {
+	__le16 frame_control;
+	__le16 aid;
+	u8 bssid[6];
+	u8 ta[6];
+} __attribute__ ((packed));
+
+/* TDLS */
+
+/* Link-id information element */
+struct ieee80211_tdls_lnkie {
+	u8 ie_type; /* Link Identifier IE */
+	u8 ie_len;
+	u8 bssid[6];
+	u8 init_sta[6];
+	u8 resp_sta[6];
+} __packed;
+
+struct ieee80211_tdls_data {
+	u8 da[6];
+	u8 sa[6];
+	__be16 ether_type;
+	u8 payload_type;
+	u8 category;
+	u8 action_code;
+	union {
+		struct {
+			u8 dialog_token;
+			__le16 capability;
+			u8 variable[0];
+		} __packed setup_req;
+		struct {
+			__le16 status_code;
+			u8 dialog_token;
+			__le16 capability;
+			u8 variable[0];
+		} __packed setup_resp;
+		struct {
+			__le16 status_code;
+			u8 dialog_token;
+			u8 variable[0];
+		} __packed setup_cfm;
+		struct {
+			__le16 reason_code;
+			u8 variable[0];
+		} __packed teardown;
+		struct {
+			u8 dialog_token;
+			u8 variable[0];
+		} __packed discover_req;
+	} u;
+} __packed;
+
+/**
+ * struct ieee80211_bar - HT Block Ack Request
+ *
+ * This structure refers to "HT BlockAckReq" as
+ * described in 802.11n draft section 7.2.1.7.1
+ */
+struct ieee80211_bar {
+	__le16 frame_control;
+	__le16 duration;
+	__u8 ra[6];
+	__u8 ta[6];
+	__le16 control;
+	__le16 start_seq_num;
+} __attribute__((packed)) __aligned(4);
+
+/* 802.11 BA(R) control masks */
+#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL	0x0000
+#define IEEE80211_BAR_CTRL_MULTI_TID		0x0002
+#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA	0x0004
+#define IEEE80211_BAR_CTRL_TID_INFO_MASK	0xf000
+#define IEEE80211_BAR_CTRL_TID_INFO_SHIFT	12
+
+/**
+ * struct ieee80211_ba - HT Block Ack
+ *
+ * This structure refers to "HT BlockAck" as
+ * described in 802.11n draft section 7.2.1.8.1
+ */
+struct ieee80211_ba {
+	__le16 frame_control;
+	__le16 duration;
+	u8 ra[6];
+	u8 ta[6];
+	__le16 control;
+
+	__le16 start_seq_num;
+	u8 bitmap[8];
+} __attribute__((packed));
+
+#define IEEE80211_HT_MCS_MASK_LEN		10
+
+/**
+ * struct ieee80211_mcs_info - MCS information
+ * @rx_mask: RX mask
+ * @rx_highest: highest supported RX rate. If set represents
+ *	the highest supported RX data rate in units of 1 Mbps.
+ *	If this field is 0 this value should not be used to
+ *	consider the highest RX data rate supported.
+ * @tx_params: TX parameters
+ */
+struct ieee80211_mcs_info {
+	u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN];
+	__le16 rx_highest;
+	u8 tx_params;
+	u8 reserved[3];
+} __attribute__((packed));
+
+/* 802.11n HT capability MSC set */
+#define IEEE80211_HT_MCS_RX_HIGHEST_MASK	0x3ff
+#define IEEE80211_HT_MCS_TX_DEFINED		0x01
+#define IEEE80211_HT_MCS_TX_RX_DIFF		0x02
+/* value 0 == 1 stream etc */
+#define IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK	0x0C
+#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT	2
+#define		IEEE80211_HT_MCS_TX_MAX_STREAMS	4
+#define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION	0x10
+
+/*
+ * 802.11n D5.0 20.3.5 / 20.6 says:
+ * - indices 0 to 7 and 32 are single spatial stream
+ * - 8 to 31 are multiple spatial streams using equal modulation
+ *   [8..15 for two streams, 16..23 for three and 24..31 for four]
+ * - remainder are multiple spatial streams using unequal modulation
+ */
+#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START 33
+#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE \
+	(IEEE80211_HT_MCS_UNEQUAL_MODULATION_START / 8)
+
+/**
+ * struct ieee80211_ht_cap - HT capabilities
+ *
+ * This structure is the "HT capabilities element" as
+ * described in 802.11n D5.0 7.3.2.57
+ */
+struct ieee80211_ht_cap {
+	__le16 cap_info;
+	u8 ampdu_params_info;
+
+	/* 16 bytes MCS information */
+	struct ieee80211_mcs_info mcs;
+
+	__le16 extended_ht_cap_info;
+	__le32 tx_BF_cap_info;
+	u8 antenna_selection_info;
+} __attribute__ ((packed));
+
+/* 802.11n HT capabilities masks (for cap_info) */
+#define IEEE80211_HT_CAP_LDPC_CODING		0x0001
+#define IEEE80211_HT_CAP_SUP_WIDTH_20_40	0x0002
+#define IEEE80211_HT_CAP_SM_PS			0x000C
+#define		IEEE80211_HT_CAP_SM_PS_SHIFT	2
+#define IEEE80211_HT_CAP_GRN_FLD		0x0010
+#define IEEE80211_HT_CAP_SGI_20			0x0020
+#define IEEE80211_HT_CAP_SGI_40			0x0040
+#define IEEE80211_HT_CAP_TX_STBC		0x0080
+#define IEEE80211_HT_CAP_RX_STBC		0x0300
+#define		IEEE80211_HT_CAP_RX_STBC_SHIFT	8
+#define IEEE80211_HT_CAP_DELAY_BA		0x0400
+#define IEEE80211_HT_CAP_MAX_AMSDU		0x0800
+#define IEEE80211_HT_CAP_DSSSCCK40		0x1000
+#define IEEE80211_HT_CAP_RESERVED		0x2000
+#define IEEE80211_HT_CAP_40MHZ_INTOLERANT	0x4000
+#define IEEE80211_HT_CAP_LSIG_TXOP_PROT		0x8000
+
+/* 802.11n HT extended capabilities masks (for extended_ht_cap_info) */
+#define IEEE80211_HT_EXT_CAP_PCO		0x0001
+#define IEEE80211_HT_EXT_CAP_PCO_TIME		0x0006
+#define		IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT	1
+#define IEEE80211_HT_EXT_CAP_MCS_FB		0x0300
+#define		IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT	8
+#define IEEE80211_HT_EXT_CAP_HTC_SUP		0x0400
+#define IEEE80211_HT_EXT_CAP_RD_RESPONDER	0x0800
+
+/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
+#define IEEE80211_HT_AMPDU_PARM_FACTOR		0x03
+#define IEEE80211_HT_AMPDU_PARM_DENSITY		0x1C
+#define		IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT	2
+
+/*
+ * Maximum length of AMPDU that the STA can receive.
+ * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
+ */
+enum ieee80211_max_ampdu_length_exp {
+	IEEE80211_HT_MAX_AMPDU_8K = 0,
+	IEEE80211_HT_MAX_AMPDU_16K = 1,
+	IEEE80211_HT_MAX_AMPDU_32K = 2,
+	IEEE80211_HT_MAX_AMPDU_64K = 3
+};
+
+#define IEEE80211_HT_MAX_AMPDU_FACTOR 13
+
+/* Minimum MPDU start spacing */
+enum ieee80211_min_mpdu_spacing {
+	IEEE80211_HT_MPDU_DENSITY_NONE = 0,	/* No restriction */
+	IEEE80211_HT_MPDU_DENSITY_0_25 = 1,	/* 1/4 usec */
+	IEEE80211_HT_MPDU_DENSITY_0_5 = 2,	/* 1/2 usec */
+	IEEE80211_HT_MPDU_DENSITY_1 = 3,	/* 1 usec */
+	IEEE80211_HT_MPDU_DENSITY_2 = 4,	/* 2 usec */
+	IEEE80211_HT_MPDU_DENSITY_4 = 5,	/* 4 usec */
+	IEEE80211_HT_MPDU_DENSITY_8 = 6,	/* 8 usec */
+	IEEE80211_HT_MPDU_DENSITY_16 = 7	/* 16 usec */
+};
+
+/**
+ * struct ieee80211_ht_operation - HT operation IE
+ *
+ * This structure is the "HT operation element" as
+ * described in 802.11n-2009 7.3.2.57
+ */
+struct ieee80211_ht_operation {
+	u8 primary_chan;
+	u8 ht_param;
+	__le16 operation_mode;
+	__le16 stbc_param;
+	u8 basic_set[16];
+} __attribute__ ((packed));
+
+/* for ht_param */
+#define IEEE80211_HT_PARAM_CHA_SEC_OFFSET		0x03
+#define		IEEE80211_HT_PARAM_CHA_SEC_NONE		0x00
+#define		IEEE80211_HT_PARAM_CHA_SEC_ABOVE	0x01
+#define		IEEE80211_HT_PARAM_CHA_SEC_BELOW	0x03
+#define IEEE80211_HT_PARAM_CHAN_WIDTH_ANY		0x04
+#define IEEE80211_HT_PARAM_RIFS_MODE			0x08
+
+/* for operation_mode */
+#define IEEE80211_HT_OP_MODE_PROTECTION			0x0003
+#define		IEEE80211_HT_OP_MODE_PROTECTION_NONE		0
+#define		IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER	1
+#define		IEEE80211_HT_OP_MODE_PROTECTION_20MHZ		2
+#define		IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED	3
+#define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT		0x0004
+#define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT		0x0010
+
+/* for stbc_param */
+#define IEEE80211_HT_STBC_PARAM_DUAL_BEACON		0x0040
+#define IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT		0x0080
+#define IEEE80211_HT_STBC_PARAM_STBC_BEACON		0x0100
+#define IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT	0x0200
+#define IEEE80211_HT_STBC_PARAM_PCO_ACTIVE		0x0400
+#define IEEE80211_HT_STBC_PARAM_PCO_PHASE		0x0800
+
+
+/* block-ack parameters */
+#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
+#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
+#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0
+#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
+#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
+
+/*
+ * A-PMDU buffer sizes
+ * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2)
+ */
+#define IEEE80211_MIN_AMPDU_BUF 0x8
+#define IEEE80211_MAX_AMPDU_BUF 0x40
+
+
+/* Spatial Multiplexing Power Save Modes (for capability) */
+#define WLAN_HT_CAP_SM_PS_STATIC	0
+#define WLAN_HT_CAP_SM_PS_DYNAMIC	1
+#define WLAN_HT_CAP_SM_PS_INVALID	2
+#define WLAN_HT_CAP_SM_PS_DISABLED	3
+
+/* for SM power control field lower two bits */
+#define WLAN_HT_SMPS_CONTROL_DISABLED	0
+#define WLAN_HT_SMPS_CONTROL_STATIC	1
+#define WLAN_HT_SMPS_CONTROL_DYNAMIC	3
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+#define WLAN_AUTH_FT 2
+#define WLAN_AUTH_SAE 3
+#define WLAN_AUTH_LEAP 128
+
+#define WLAN_AUTH_CHALLENGE_LEN 128
+
+#define WLAN_CAPABILITY_ESS		(1<<0)
+#define WLAN_CAPABILITY_IBSS		(1<<1)
+
+/*
+ * A mesh STA sets the ESS and IBSS capability bits to zero.
+ * however, this holds true for p2p probe responses (in the p2p_find
+ * phase) as well.
+ */
+#define WLAN_CAPABILITY_IS_STA_BSS(cap)	\
+	(!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)))
+
+#define WLAN_CAPABILITY_CF_POLLABLE	(1<<2)
+#define WLAN_CAPABILITY_CF_POLL_REQUEST	(1<<3)
+#define WLAN_CAPABILITY_PRIVACY		(1<<4)
+#define WLAN_CAPABILITY_SHORT_PREAMBLE	(1<<5)
+#define WLAN_CAPABILITY_PBCC		(1<<6)
+#define WLAN_CAPABILITY_CHANNEL_AGILITY	(1<<7)
+
+/* 802.11h */
+#define WLAN_CAPABILITY_SPECTRUM_MGMT	(1<<8)
+#define WLAN_CAPABILITY_QOS		(1<<9)
+#define WLAN_CAPABILITY_SHORT_SLOT_TIME	(1<<10)
+#define WLAN_CAPABILITY_DSSS_OFDM	(1<<13)
+/* measurement */
+#define IEEE80211_SPCT_MSR_RPRT_MODE_LATE	(1<<0)
+#define IEEE80211_SPCT_MSR_RPRT_MODE_INCAPABLE	(1<<1)
+#define IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED	(1<<2)
+
+#define IEEE80211_SPCT_MSR_RPRT_TYPE_BASIC	0
+#define IEEE80211_SPCT_MSR_RPRT_TYPE_CCA	1
+#define IEEE80211_SPCT_MSR_RPRT_TYPE_RPI	2
+
+
+/* 802.11g ERP information element */
+#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
+#define WLAN_ERP_USE_PROTECTION (1<<1)
+#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
+
+/* WLAN_ERP_BARKER_PREAMBLE values */
+enum {
+	WLAN_ERP_PREAMBLE_SHORT = 0,
+	WLAN_ERP_PREAMBLE_LONG = 1,
+};
+
+/* Status codes */
+enum ieee80211_statuscode {
+	WLAN_STATUS_SUCCESS = 0,
+	WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
+	WLAN_STATUS_CAPS_UNSUPPORTED = 10,
+	WLAN_STATUS_REASSOC_NO_ASSOC = 11,
+	WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
+	WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
+	WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
+	WLAN_STATUS_CHALLENGE_FAIL = 15,
+	WLAN_STATUS_AUTH_TIMEOUT = 16,
+	WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+	WLAN_STATUS_ASSOC_DENIED_RATES = 18,
+	/* 802.11b */
+	WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
+	WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
+	WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
+	/* 802.11h */
+	WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
+	WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
+	WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
+	/* 802.11g */
+	WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
+	WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+	/* 802.11w */
+	WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY = 30,
+	WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
+	/* 802.11i */
+	WLAN_STATUS_INVALID_IE = 40,
+	WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
+	WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
+	WLAN_STATUS_INVALID_AKMP = 43,
+	WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
+	WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
+	WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+	/* 802.11e */
+	WLAN_STATUS_UNSPECIFIED_QOS = 32,
+	WLAN_STATUS_ASSOC_DENIED_NOBANDWIDTH = 33,
+	WLAN_STATUS_ASSOC_DENIED_LOWACK = 34,
+	WLAN_STATUS_ASSOC_DENIED_UNSUPP_QOS = 35,
+	WLAN_STATUS_REQUEST_DECLINED = 37,
+	WLAN_STATUS_INVALID_QOS_PARAM = 38,
+	WLAN_STATUS_CHANGE_TSPEC = 39,
+	WLAN_STATUS_WAIT_TS_DELAY = 47,
+	WLAN_STATUS_NO_DIRECT_LINK = 48,
+	WLAN_STATUS_STA_NOT_PRESENT = 49,
+	WLAN_STATUS_STA_NOT_QSTA = 50,
+	/* 802.11s */
+	WLAN_STATUS_ANTI_CLOG_REQUIRED = 76,
+	WLAN_STATUS_FCG_NOT_SUPP = 78,
+	WLAN_STATUS_STA_NO_TBTT = 78,
+};
+
+
+/* Reason codes */
+enum ieee80211_reasoncode {
+	WLAN_REASON_UNSPECIFIED = 1,
+	WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+	WLAN_REASON_DEAUTH_LEAVING = 3,
+	WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
+	WLAN_REASON_DISASSOC_AP_BUSY = 5,
+	WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+	WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+	WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
+	WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+	/* 802.11h */
+	WLAN_REASON_DISASSOC_BAD_POWER = 10,
+	WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
+	/* 802.11i */
+	WLAN_REASON_INVALID_IE = 13,
+	WLAN_REASON_MIC_FAILURE = 14,
+	WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
+	WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
+	WLAN_REASON_IE_DIFFERENT = 17,
+	WLAN_REASON_INVALID_GROUP_CIPHER = 18,
+	WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
+	WLAN_REASON_INVALID_AKMP = 20,
+	WLAN_REASON_UNSUPP_RSN_VERSION = 21,
+	WLAN_REASON_INVALID_RSN_IE_CAP = 22,
+	WLAN_REASON_IEEE8021X_FAILED = 23,
+	WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+	/* 802.11e */
+	WLAN_REASON_DISASSOC_UNSPECIFIED_QOS = 32,
+	WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH = 33,
+	WLAN_REASON_DISASSOC_LOW_ACK = 34,
+	WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP = 35,
+	WLAN_REASON_QSTA_LEAVE_QBSS = 36,
+	WLAN_REASON_QSTA_NOT_USE = 37,
+	WLAN_REASON_QSTA_REQUIRE_SETUP = 38,
+	WLAN_REASON_QSTA_TIMEOUT = 39,
+	WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45,
+	/* 802.11s */
+	WLAN_REASON_MESH_PEER_CANCELED = 52,
+	WLAN_REASON_MESH_MAX_PEERS = 53,
+	WLAN_REASON_MESH_CONFIG = 54,
+	WLAN_REASON_MESH_CLOSE = 55,
+	WLAN_REASON_MESH_MAX_RETRIES = 56,
+	WLAN_REASON_MESH_CONFIRM_TIMEOUT = 57,
+	WLAN_REASON_MESH_INVALID_GTK = 58,
+	WLAN_REASON_MESH_INCONSISTENT_PARAM = 59,
+	WLAN_REASON_MESH_INVALID_SECURITY = 60,
+	WLAN_REASON_MESH_PATH_ERROR = 61,
+	WLAN_REASON_MESH_PATH_NOFORWARD = 62,
+	WLAN_REASON_MESH_PATH_DEST_UNREACHABLE = 63,
+	WLAN_REASON_MAC_EXISTS_IN_MBSS = 64,
+	WLAN_REASON_MESH_CHAN_REGULATORY = 65,
+	WLAN_REASON_MESH_CHAN = 66,
+};
+
+
+/* Information Element IDs */
+enum ieee80211_eid {
+	WLAN_EID_SSID = 0,
+	WLAN_EID_SUPP_RATES = 1,
+	WLAN_EID_FH_PARAMS = 2,
+	WLAN_EID_DS_PARAMS = 3,
+	WLAN_EID_CF_PARAMS = 4,
+	WLAN_EID_TIM = 5,
+	WLAN_EID_IBSS_PARAMS = 6,
+	WLAN_EID_CHALLENGE = 16,
+
+	WLAN_EID_COUNTRY = 7,
+	WLAN_EID_HP_PARAMS = 8,
+	WLAN_EID_HP_TABLE = 9,
+	WLAN_EID_REQUEST = 10,
+
+	WLAN_EID_QBSS_LOAD = 11,
+	WLAN_EID_EDCA_PARAM_SET = 12,
+	WLAN_EID_TSPEC = 13,
+	WLAN_EID_TCLAS = 14,
+	WLAN_EID_SCHEDULE = 15,
+	WLAN_EID_TS_DELAY = 43,
+	WLAN_EID_TCLAS_PROCESSING = 44,
+	WLAN_EID_QOS_CAPA = 46,
+	/* 802.11z */
+	WLAN_EID_LINK_ID = 101,
+	/* 802.11s */
+	WLAN_EID_MESH_CONFIG = 113,
+	WLAN_EID_MESH_ID = 114,
+	WLAN_EID_LINK_METRIC_REPORT = 115,
+	WLAN_EID_CONGESTION_NOTIFICATION = 116,
+	WLAN_EID_PEER_MGMT = 117,
+	WLAN_EID_CHAN_SWITCH_PARAM = 118,
+	WLAN_EID_MESH_AWAKE_WINDOW = 119,
+	WLAN_EID_BEACON_TIMING = 120,
+	WLAN_EID_MCCAOP_SETUP_REQ = 121,
+	WLAN_EID_MCCAOP_SETUP_RESP = 122,
+	WLAN_EID_MCCAOP_ADVERT = 123,
+	WLAN_EID_MCCAOP_TEARDOWN = 124,
+	WLAN_EID_GANN = 125,
+	WLAN_EID_RANN = 126,
+	WLAN_EID_PREQ = 130,
+	WLAN_EID_PREP = 131,
+	WLAN_EID_PERR = 132,
+	WLAN_EID_PXU = 137,
+	WLAN_EID_PXUC = 138,
+	WLAN_EID_AUTH_MESH_PEER_EXCH = 139,
+	WLAN_EID_MIC = 140,
+
+	WLAN_EID_PWR_CONSTRAINT = 32,
+	WLAN_EID_PWR_CAPABILITY = 33,
+	WLAN_EID_TPC_REQUEST = 34,
+	WLAN_EID_TPC_REPORT = 35,
+	WLAN_EID_SUPPORTED_CHANNELS = 36,
+	WLAN_EID_CHANNEL_SWITCH = 37,
+	WLAN_EID_MEASURE_REQUEST = 38,
+	WLAN_EID_MEASURE_REPORT = 39,
+	WLAN_EID_QUIET = 40,
+	WLAN_EID_IBSS_DFS = 41,
+
+	WLAN_EID_ERP_INFO = 42,
+	WLAN_EID_EXT_SUPP_RATES = 50,
+
+	WLAN_EID_HT_CAPABILITY = 45,
+	WLAN_EID_HT_OPERATION = 61,
+
+	WLAN_EID_RSN = 48,
+	WLAN_EID_MMIE = 76,
+	WLAN_EID_WPA = 221,
+	WLAN_EID_GENERIC = 221,
+	WLAN_EID_VENDOR_SPECIFIC = 221,
+	WLAN_EID_QOS_PARAMETER = 222,
+
+	WLAN_EID_AP_CHAN_REPORT = 51,
+	WLAN_EID_NEIGHBOR_REPORT = 52,
+	WLAN_EID_RCPI = 53,
+	WLAN_EID_BSS_AVG_ACCESS_DELAY = 63,
+	WLAN_EID_ANTENNA_INFO = 64,
+	WLAN_EID_RSNI = 65,
+	WLAN_EID_MEASUREMENT_PILOT_TX_INFO = 66,
+	WLAN_EID_BSS_AVAILABLE_CAPACITY = 67,
+	WLAN_EID_BSS_AC_ACCESS_DELAY = 68,
+	WLAN_EID_RRM_ENABLED_CAPABILITIES = 70,
+	WLAN_EID_MULTIPLE_BSSID = 71,
+	WLAN_EID_BSS_COEX_2040 = 72,
+	WLAN_EID_OVERLAP_BSS_SCAN_PARAM = 74,
+	WLAN_EID_EXT_CAPABILITY = 127,
+
+	WLAN_EID_MOBILITY_DOMAIN = 54,
+	WLAN_EID_FAST_BSS_TRANSITION = 55,
+	WLAN_EID_TIMEOUT_INTERVAL = 56,
+	WLAN_EID_RIC_DATA = 57,
+	WLAN_EID_RIC_DESCRIPTOR = 75,
+
+	WLAN_EID_DSE_REGISTERED_LOCATION = 58,
+	WLAN_EID_SUPPORTED_REGULATORY_CLASSES = 59,
+	WLAN_EID_EXT_CHANSWITCH_ANN = 60,
+};
+
+/* Action category code */
+enum ieee80211_category {
+	WLAN_CATEGORY_SPECTRUM_MGMT = 0,
+	WLAN_CATEGORY_QOS = 1,
+	WLAN_CATEGORY_DLS = 2,
+	WLAN_CATEGORY_BACK = 3,
+	WLAN_CATEGORY_PUBLIC = 4,
+	WLAN_CATEGORY_HT = 7,
+	WLAN_CATEGORY_SA_QUERY = 8,
+	WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
+	WLAN_CATEGORY_TDLS = 12,
+	WLAN_CATEGORY_MESH_ACTION = 13,
+	WLAN_CATEGORY_MULTIHOP_ACTION = 14,
+	WLAN_CATEGORY_SELF_PROTECTED = 15,
+	WLAN_CATEGORY_WMM = 17,
+	WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
+	WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
+};
+
+/* SPECTRUM_MGMT action code */
+enum ieee80211_spectrum_mgmt_actioncode {
+	WLAN_ACTION_SPCT_MSR_REQ = 0,
+	WLAN_ACTION_SPCT_MSR_RPRT = 1,
+	WLAN_ACTION_SPCT_TPC_REQ = 2,
+	WLAN_ACTION_SPCT_TPC_RPRT = 3,
+	WLAN_ACTION_SPCT_CHL_SWITCH = 4,
+};
+
+/* HT action codes */
+enum ieee80211_ht_actioncode {
+	WLAN_HT_ACTION_NOTIFY_CHANWIDTH = 0,
+	WLAN_HT_ACTION_SMPS = 1,
+	WLAN_HT_ACTION_PSMP = 2,
+	WLAN_HT_ACTION_PCO_PHASE = 3,
+	WLAN_HT_ACTION_CSI = 4,
+	WLAN_HT_ACTION_NONCOMPRESSED_BF = 5,
+	WLAN_HT_ACTION_COMPRESSED_BF = 6,
+	WLAN_HT_ACTION_ASEL_IDX_FEEDBACK = 7,
+};
+
+/* Self Protected Action codes */
+enum ieee80211_self_protected_actioncode {
+	WLAN_SP_RESERVED = 0,
+	WLAN_SP_MESH_PEERING_OPEN = 1,
+	WLAN_SP_MESH_PEERING_CONFIRM = 2,
+	WLAN_SP_MESH_PEERING_CLOSE = 3,
+	WLAN_SP_MGK_INFORM = 4,
+	WLAN_SP_MGK_ACK = 5,
+};
+
+/* Mesh action codes */
+enum ieee80211_mesh_actioncode {
+	WLAN_MESH_ACTION_LINK_METRIC_REPORT,
+	WLAN_MESH_ACTION_HWMP_PATH_SELECTION,
+	WLAN_MESH_ACTION_GATE_ANNOUNCEMENT,
+	WLAN_MESH_ACTION_CONGESTION_CONTROL_NOTIFICATION,
+	WLAN_MESH_ACTION_MCCA_SETUP_REQUEST,
+	WLAN_MESH_ACTION_MCCA_SETUP_REPLY,
+	WLAN_MESH_ACTION_MCCA_ADVERTISEMENT_REQUEST,
+	WLAN_MESH_ACTION_MCCA_ADVERTISEMENT,
+	WLAN_MESH_ACTION_MCCA_TEARDOWN,
+	WLAN_MESH_ACTION_TBTT_ADJUSTMENT_REQUEST,
+	WLAN_MESH_ACTION_TBTT_ADJUSTMENT_RESPONSE,
+};
+
+/* Security key length */
+enum ieee80211_key_len {
+	WLAN_KEY_LEN_WEP40 = 5,
+	WLAN_KEY_LEN_WEP104 = 13,
+	WLAN_KEY_LEN_CCMP = 16,
+	WLAN_KEY_LEN_TKIP = 32,
+	WLAN_KEY_LEN_AES_CMAC = 16,
+};
+
+/* Public action codes */
+enum ieee80211_pub_actioncode {
+	WLAN_PUB_ACTION_TDLS_DISCOVER_RES = 14,
+};
+
+/* TDLS action codes */
+enum ieee80211_tdls_actioncode {
+	WLAN_TDLS_SETUP_REQUEST = 0,
+	WLAN_TDLS_SETUP_RESPONSE = 1,
+	WLAN_TDLS_SETUP_CONFIRM = 2,
+	WLAN_TDLS_TEARDOWN = 3,
+	WLAN_TDLS_PEER_TRAFFIC_INDICATION = 4,
+	WLAN_TDLS_CHANNEL_SWITCH_REQUEST = 5,
+	WLAN_TDLS_CHANNEL_SWITCH_RESPONSE = 6,
+	WLAN_TDLS_PEER_PSM_REQUEST = 7,
+	WLAN_TDLS_PEER_PSM_RESPONSE = 8,
+	WLAN_TDLS_PEER_TRAFFIC_RESPONSE = 9,
+	WLAN_TDLS_DISCOVERY_REQUEST = 10,
+};
+
+/*
+ * TDLS capabililites to be enabled in the 5th byte of the
+ * @WLAN_EID_EXT_CAPABILITY information element
+ */
+#define WLAN_EXT_CAPA5_TDLS_ENABLED	BIT(5)
+#define WLAN_EXT_CAPA5_TDLS_PROHIBITED	BIT(6)
+
+/* TDLS specific payload type in the LLC/SNAP header */
+#define WLAN_TDLS_SNAP_RFTYPE	0x2
+
+/**
+ * enum - mesh synchronization method identifier
+ *
+ * @IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET: the default synchronization method
+ * @IEEE80211_SYNC_METHOD_VENDOR: a vendor specific synchronization method
+ * that will be specified in a vendor specific information element
+ */
+enum {
+	IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET = 1,
+	IEEE80211_SYNC_METHOD_VENDOR = 255,
+};
+
+/**
+ * enum - mesh path selection protocol identifier
+ *
+ * @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol
+ * @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will
+ * be specified in a vendor specific information element
+ */
+enum {
+	IEEE80211_PATH_PROTOCOL_HWMP = 1,
+	IEEE80211_PATH_PROTOCOL_VENDOR = 255,
+};
+
+/**
+ * enum - mesh path selection metric identifier
+ *
+ * @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric
+ * @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be
+ * specified in a vendor specific information element
+ */
+enum {
+	IEEE80211_PATH_METRIC_AIRTIME = 1,
+	IEEE80211_PATH_METRIC_VENDOR = 255,
+};
+
+
+/*
+ * IEEE 802.11-2007 7.3.2.9 Country information element
+ *
+ * Minimum length is 8 octets, ie len must be evenly
+ * divisible by 2
+ */
+
+/* Although the spec says 8 I'm seeing 6 in practice */
+#define IEEE80211_COUNTRY_IE_MIN_LEN	6
+
+/* The Country String field of the element shall be 3 octets in length */
+#define IEEE80211_COUNTRY_STRING_LEN	3
+
+/*
+ * For regulatory extension stuff see IEEE 802.11-2007
+ * Annex I (page 1141) and Annex J (page 1147). Also
+ * review 7.3.2.9.
+ *
+ * When dot11RegulatoryClassesRequired is true and the
+ * first_channel/reg_extension_id is >= 201 then the IE
+ * compromises of the 'ext' struct represented below:
+ *
+ *  - Regulatory extension ID - when generating IE this just needs
+ *    to be monotonically increasing for each triplet passed in
+ *    the IE
+ *  - Regulatory class - index into set of rules
+ *  - Coverage class - index into air propagation time (Table 7-27),
+ *    in microseconds, you can compute the air propagation time from
+ *    the index by multiplying by 3, so index 10 yields a propagation
+ *    of 10 us. Valid values are 0-31, values 32-255 are not defined
+ *    yet. A value of 0 inicates air propagation of <= 1 us.
+ *
+ *  See also Table I.2 for Emission limit sets and table
+ *  I.3 for Behavior limit sets. Table J.1 indicates how to map
+ *  a reg_class to an emission limit set and behavior limit set.
+ */
+#define IEEE80211_COUNTRY_EXTENSION_ID 201
+
+/*
+ *  Channels numbers in the IE must be monotonically increasing
+ *  if dot11RegulatoryClassesRequired is not true.
+ *
+ *  If dot11RegulatoryClassesRequired is true consecutive
+ *  subband triplets following a regulatory triplet shall
+ *  have monotonically increasing first_channel number fields.
+ *
+ *  Channel numbers shall not overlap.
+ *
+ *  Note that max_power is signed.
+ */
+struct ieee80211_country_ie_triplet {
+	union {
+		struct {
+			u8 first_channel;
+			u8 num_channels;
+			s8 max_power;
+		} __attribute__ ((packed)) chans;
+		struct {
+			u8 reg_extension_id;
+			u8 reg_class;
+			u8 coverage_class;
+		} __attribute__ ((packed)) ext;
+	};
+} __attribute__ ((packed));
+
+enum ieee80211_timeout_interval_type {
+	WLAN_TIMEOUT_REASSOC_DEADLINE = 1 /* 802.11r */,
+	WLAN_TIMEOUT_KEY_LIFETIME = 2 /* 802.11r */,
+	WLAN_TIMEOUT_ASSOC_COMEBACK = 3 /* 802.11w */,
+};
+
+/* BACK action code */
+enum ieee80211_back_actioncode {
+	WLAN_ACTION_ADDBA_REQ = 0,
+	WLAN_ACTION_ADDBA_RESP = 1,
+	WLAN_ACTION_DELBA = 2,
+};
+
+/* BACK (block-ack) parties */
+enum ieee80211_back_parties {
+	WLAN_BACK_RECIPIENT = 0,
+	WLAN_BACK_INITIATOR = 1,
+};
+
+/* SA Query action */
+enum ieee80211_sa_query_action {
+	WLAN_ACTION_SA_QUERY_REQUEST = 0,
+	WLAN_ACTION_SA_QUERY_RESPONSE = 1,
+};
+
+
+/* cipher suite selectors */
+#define WLAN_CIPHER_SUITE_USE_GROUP	0x000FAC00
+#define WLAN_CIPHER_SUITE_WEP40		0x000FAC01
+#define WLAN_CIPHER_SUITE_TKIP		0x000FAC02
+/* reserved:				0x000FAC03 */
+#define WLAN_CIPHER_SUITE_CCMP		0x000FAC04
+#define WLAN_CIPHER_SUITE_WEP104	0x000FAC05
+#define WLAN_CIPHER_SUITE_AES_CMAC	0x000FAC06
+
+#define WLAN_CIPHER_SUITE_SMS4		0x00147201
+
+/* AKM suite selectors */
+#define WLAN_AKM_SUITE_8021X		0x000FAC01
+#define WLAN_AKM_SUITE_PSK		0x000FAC02
+#define WLAN_AKM_SUITE_SAE			0x000FAC08
+#define WLAN_AKM_SUITE_FT_OVER_SAE	0x000FAC09
+
+#define WLAN_MAX_KEY_LEN		32
+
+#define WLAN_PMKID_LEN			16
+
+#define WLAN_OUI_WFA			0x506f9a
+#define WLAN_OUI_TYPE_WFA_P2P		9
+
+/*
+ * WMM/802.11e Tspec Element
+ */
+#define IEEE80211_WMM_IE_TSPEC_TID_MASK		0x0F
+#define IEEE80211_WMM_IE_TSPEC_TID_SHIFT	1
+
+enum ieee80211_tspec_status_code {
+	IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED = 0,
+	IEEE80211_TSPEC_STATUS_ADDTS_INVAL_PARAMS = 0x1,
+};
+
+struct ieee80211_tspec_ie {
+	u8 element_id;
+	u8 len;
+	u8 oui[3];
+	u8 oui_type;
+	u8 oui_subtype;
+	u8 version;
+	__le16 tsinfo;
+	u8 tsinfo_resvd;
+	__le16 nominal_msdu;
+	__le16 max_msdu;
+	__le32 min_service_int;
+	__le32 max_service_int;
+	__le32 inactivity_int;
+	__le32 suspension_int;
+	__le32 service_start_time;
+	__le32 min_data_rate;
+	__le32 mean_data_rate;
+	__le32 peak_data_rate;
+	__le32 max_burst_size;
+	__le32 delay_bound;
+	__le32 min_phy_rate;
+	__le16 sba;
+	__le16 medium_time;
+} __packed;
+
+/**
+ * ieee80211_get_qos_ctl - get pointer to qos control bytes
+ * @hdr: the frame
+ *
+ * The qos ctrl bytes come after the frame_control, duration, seq_num
+ * and 3 or 4 addresses of length ETH_ALEN.
+ * 3 addr: 2 + 2 + 2 + 3*6 = 24
+ * 4 addr: 2 + 2 + 2 + 4*6 = 30
+ */
+static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)
+{
+	if (ieee80211_has_a4(hdr->frame_control))
+		return (u8 *)hdr + 30;
+	else
+		return (u8 *)hdr + 24;
+}
+
+/**
+ * ieee80211_get_SA - get pointer to SA
+ * @hdr: the frame
+ *
+ * Given an 802.11 frame, this function returns the offset
+ * to the source address (SA). It does not verify that the
+ * header is long enough to contain the address, and the
+ * header must be long enough to contain the frame control
+ * field.
+ */
+static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr)
+{
+	if (ieee80211_has_a4(hdr->frame_control))
+		return hdr->addr4;
+	if (ieee80211_has_fromds(hdr->frame_control))
+		return hdr->addr3;
+	return hdr->addr2;
+}
+
+/**
+ * ieee80211_get_DA - get pointer to DA
+ * @hdr: the frame
+ *
+ * Given an 802.11 frame, this function returns the offset
+ * to the destination address (DA). It does not verify that
+ * the header is long enough to contain the address, and the
+ * header must be long enough to contain the frame control
+ * field.
+ */
+static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr)
+{
+	if (ieee80211_has_tods(hdr->frame_control))
+		return hdr->addr3;
+	else
+		return hdr->addr1;
+}
+
+/**
+ * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame
+ * @hdr: the frame (buffer must include at least the first octet of payload)
+ */
+static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
+{
+	if (ieee80211_is_disassoc(hdr->frame_control) ||
+	    ieee80211_is_deauth(hdr->frame_control))
+		return true;
+
+	if (ieee80211_is_action(hdr->frame_control)) {
+		u8 *category;
+
+		/*
+		 * Action frames, excluding Public Action frames, are Robust
+		 * Management Frames. However, if we are looking at a Protected
+		 * frame, skip the check since the data may be encrypted and
+		 * the frame has already been found to be a Robust Management
+		 * Frame (by the other end).
+		 */
+		if (ieee80211_has_protected(hdr->frame_control))
+			return true;
+		category = ((u8 *) hdr) + 24;
+		return *category != WLAN_CATEGORY_PUBLIC &&
+			*category != WLAN_CATEGORY_HT &&
+			*category != WLAN_CATEGORY_SELF_PROTECTED &&
+			*category != WLAN_CATEGORY_VENDOR_SPECIFIC;
+	}
+
+	return false;
+}
+
+/**
+ * ieee80211_is_public_action - check if frame is a public action frame
+ * @hdr: the frame
+ * @len: length of the frame
+ */
+static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr,
+					      size_t len)
+{
+	struct ieee80211_mgmt *mgmt = (void *)hdr;
+
+	if (len < IEEE80211_MIN_ACTION_SIZE)
+		return false;
+	if (!ieee80211_is_action(hdr->frame_control))
+		return false;
+	return mgmt->u.action.category == WLAN_CATEGORY_PUBLIC;
+}
+
+/**
+ * ieee80211_fhss_chan_to_freq - get channel frequency
+ * @channel: the FHSS channel
+ *
+ * Convert IEEE802.11 FHSS channel to frequency (MHz)
+ * Ref IEEE 802.11-2007 section 14.6
+ */
+static inline int ieee80211_fhss_chan_to_freq(int channel)
+{
+	if ((channel > 1) && (channel < 96))
+		return channel + 2400;
+	else
+		return -1;
+}
+
+/**
+ * ieee80211_freq_to_fhss_chan - get channel
+ * @freq: the channels frequency
+ *
+ * Convert frequency (MHz) to IEEE802.11 FHSS channel
+ * Ref IEEE 802.11-2007 section 14.6
+ */
+static inline int ieee80211_freq_to_fhss_chan(int freq)
+{
+	if ((freq > 2401) && (freq < 2496))
+		return freq - 2400;
+	else
+		return -1;
+}
+
+/**
+ * ieee80211_dsss_chan_to_freq - get channel center frequency
+ * @channel: the DSSS channel
+ *
+ * Convert IEEE802.11 DSSS channel to the center frequency (MHz).
+ * Ref IEEE 802.11-2007 section 15.6
+ */
+static inline int ieee80211_dsss_chan_to_freq(int channel)
+{
+	if ((channel > 0) && (channel < 14))
+		return 2407 + (channel * 5);
+	else if (channel == 14)
+		return 2484;
+	else
+		return -1;
+}
+
+/**
+ * ieee80211_freq_to_dsss_chan - get channel
+ * @freq: the frequency
+ *
+ * Convert frequency (MHz) to IEEE802.11 DSSS channel
+ * Ref IEEE 802.11-2007 section 15.6
+ *
+ * This routine selects the channel with the closest center frequency.
+ */
+static inline int ieee80211_freq_to_dsss_chan(int freq)
+{
+	if ((freq >= 2410) && (freq < 2475))
+		return (freq - 2405) / 5;
+	else if ((freq >= 2482) && (freq < 2487))
+		return 14;
+	else
+		return -1;
+}
+
+/* Convert IEEE802.11 HR DSSS channel to frequency (MHz) and back
+ * Ref IEEE 802.11-2007 section 18.4.6.2
+ *
+ * The channels and frequencies are the same as those defined for DSSS
+ */
+#define ieee80211_hr_chan_to_freq(chan) ieee80211_dsss_chan_to_freq(chan)
+#define ieee80211_freq_to_hr_chan(freq) ieee80211_freq_to_dsss_chan(freq)
+
+/* Convert IEEE802.11 ERP channel to frequency (MHz) and back
+ * Ref IEEE 802.11-2007 section 19.4.2
+ */
+#define ieee80211_erp_chan_to_freq(chan) ieee80211_hr_chan_to_freq(chan)
+#define ieee80211_freq_to_erp_chan(freq) ieee80211_freq_to_hr_chan(freq)
+
+/**
+ * ieee80211_ofdm_chan_to_freq - get channel center frequency
+ * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz
+ * @channel: the OFDM channel
+ *
+ * Convert IEEE802.11 OFDM channel to center frequency (MHz)
+ * Ref IEEE 802.11-2007 section 17.3.8.3.2
+ */
+static inline int ieee80211_ofdm_chan_to_freq(int s_freq, int channel)
+{
+	if ((channel > 0) && (channel <= 200) &&
+	    (s_freq >= 4000))
+		return s_freq + (channel * 5);
+	else
+		return -1;
+}
+
+/**
+ * ieee80211_freq_to_ofdm_channel - get channel
+ * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz
+ * @freq: the frequency
+ *
+ * Convert frequency (MHz) to IEEE802.11 OFDM channel
+ * Ref IEEE 802.11-2007 section 17.3.8.3.2
+ *
+ * This routine selects the channel with the closest center frequency.
+ */
+static inline int ieee80211_freq_to_ofdm_chan(int s_freq, int freq)
+{
+	if ((freq > (s_freq + 2)) && (freq <= (s_freq + 1202)) &&
+	    (s_freq >= 4000))
+		return (freq + 2 - s_freq) / 5;
+	else
+		return -1;
+}
+
+/**
+ * ieee80211_tu_to_usec - convert time units (TU) to microseconds
+ * @tu: the TUs
+ */
+static inline unsigned long ieee80211_tu_to_usec(unsigned long tu)
+{
+	return 1024 * tu;
+}
+
+/**
+ * ieee80211_check_tim - check if AID bit is set in TIM
+ * @tim: the TIM IE
+ * @tim_len: length of the TIM IE
+ * @aid: the AID to look for
+ */
+static inline bool ieee80211_check_tim(struct ieee80211_tim_ie *tim,
+				       u8 tim_len, u16 aid)
+{
+	u8 mask;
+	u8 indexn0, indexn1, indexn2;
+
+	if (unlikely(!tim || tim_len < sizeof(*tim)))
+		return false;
+
+	aid &= 0x3fff;
+	indexn0 = aid / 8;
+	mask  = 1 << (aid & 7);
+
+	indexn1 = tim->bitmap_ctrl & 0xfe;
+	indexn2 = tim_len + indexn1 - 4;
+
+	if (indexn0 < indexn1 || indexn0 > indexn2)
+		return false;
+
+	indexn0 -= indexn1;
+
+	return !!(tim->virtual_map[indexn0] & mask);
+}
+
+#endif /* __LINUX_IEEE80211_H */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/types.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/linux/types.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/eeprom.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/eeprom.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,216 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * EEPROM layout
+ *
+ * Copyright 2008, Johannes Berg <johannes at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/fwcmd.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/fwcmd.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,318 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * Firmware command interface definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes at sipsolutions.net>
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/fwdesc.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/fwdesc.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,277 @@
+/*
+ * Shared CARL9170 Header
+ *
+ * Firmware descriptor format
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/hw.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/hw.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,817 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * Register map, hardware-specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes at sipsolutions.net>
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/phy.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/phy.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/version.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/version.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/wlan.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/include/shared/wlan.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,435 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * RX/TX meta descriptor format
+ *
+ * Copyright 2008, Johannes Berg <johannes at sipsolutions.net>
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/minifw/CMakeLists.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/minifw/CMakeLists.txt	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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)

Added: dists/trunk/firmware-free/linux-free/carl9170fw/minifw/Kconfig
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/minifw/Kconfig	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,3 @@
+config CARL9170FW_BUILD_MINIBOOT
+	def_bool y
+	prompt "Build MiniBoot Firmware Header"

Added: dists/trunk/firmware-free/linux-free/carl9170fw/minifw/miniboot.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/minifw/miniboot.S	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,7 @@
+	.globl _start
+	.type  _start, @function
+	.section ".boot", "ax"
+	_start:
+		mov.l startcode, r0
+		jmp @r0
+startcode:	.long 0x00000008

Added: dists/trunk/firmware-free/linux-free/carl9170fw/minifw/miniboot.lds
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/minifw/miniboot.lds	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/toolchain/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/toolchain/Makefile	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,66 @@
+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)
+
+define checksum
+ at if grep -q '  $(subst .,\.,$(1))$$' SHA256SUMS; then			\
+	grep '  $(subst .,\.,$(1))$$' SHA256SUMS | sha256sum -c;	\
+else									\
+	echo "WARNING: no checksum defined for $(1)";			\
+fi
+endef
+
+all: gcc
+
+src/$(BINUTILS_TAR):
+	wget -P src $(BINUTILS_URL)
+	$(call checksum,$@)
+
+src/$(NEWLIB_TAR):
+	wget -P src $(NEWLIB_URL)
+	$(call checksum,$@)
+
+src/$(GCC_TAR):
+	wget -P src $(GCC_URL)
+	$(call checksum,$@)
+
+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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/toolchain/SHA256SUMS
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/toolchain/SHA256SUMS	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,3 @@
+6c7af8ed1c8cf9b4b9d6e6fe09a3e1d3d479fe63984ba8b9b26bf356b6313ca9  src/binutils-2.22.tar.bz2
+16093f6fa01732adf378d97fe338f113c933bdf56da22bf87c76beff13da406f  src/gcc-4.7.1.tar.bz2
+c644b2847244278c57bec2ddda69d8fab5a7c767f3b9af69aa7aa3da823ff692  src/newlib-1.20.0.tar.gz

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/CMakeLists.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/CMakeLists.txt	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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 ()

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/Kconfig
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/Kconfig	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/CMakeLists.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/CMakeLists.txt	Mon Jan 14 11:38:44 2013	(r19729)
@@ -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)

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/carlu.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/carlu.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,147 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * common API declaration
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/cmd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/cmd.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,189 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * Abstraction Layer for FW/HW command interface
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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;
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/cmd.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/cmd.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,135 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * register/memory/command access functions
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/debug.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/debug.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,101 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * Random assortment of debug stuff
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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);
+	}
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/debug.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/debug.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,72 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * Debug API definition
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/fw.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/fw.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,131 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * Firmware parsers
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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));
+	}
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/main.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/main.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,307 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * main program routine
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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]);
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/rx.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/rx.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,181 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * RX data processing
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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);
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/test.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/test.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,237 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * Various tests
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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");
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/test.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/test.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,35 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * test.c header
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/tx.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/tx.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,213 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * xmit - related functions
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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;
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/usb.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/usb.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,793 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * USB back-end driver
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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 <stdlib.h>
+#include "libusb.h"
+
+#include "carlu.h"
+#include "usb.h"
+#include "debug.h"
+#include "list.h"
+#include "cmd.h"
+
+#define ADD_DEV(_vid, _pid, _vs, _ps)	{		\
+	.idVendor = _vid,				\
+	.idProduct = _pid,				\
+	.vendor_name = _vs,				\
+	.product_name = _ps				\
+}
+
+static const struct {
+	uint16_t idVendor;
+	uint16_t idProduct;
+	char *vendor_name;
+	char *product_name;
+} dev_list[] = {
+	ADD_DEV(0x0cf3, 0x9170, "Atheros", "9170"),
+	ADD_DEV(0x0cf3, 0x1001, "Atheros", "TG121N"),
+	ADD_DEV(0x0cf3, 0x1002, "TP-Link", "TL-WN821N v2"),
+	ADD_DEV(0xcace, 0x0300, "Cace", "Airpcap NX"),
+	ADD_DEV(0x07d1, 0x3c10, "D-Link", "DWA 160 A1"),
+	ADD_DEV(0x07d1, 0x3a09, "D-Link", "DWA 160 A2"),
+	ADD_DEV(0x0846, 0x9010, "Netgear", "WNDA3100"),
+	ADD_DEV(0x0846, 0x9001, "Netgear", "WN111 v2"),
+	ADD_DEV(0x0ace, 0x1221, "Zydas", "ZD1221"),
+	ADD_DEV(0x0586, 0x3417, "ZyXEL", "NWD271N"),
+	ADD_DEV(0x0cde, 0x0023, "Z-Com", "UB81 BG"),
+	ADD_DEV(0x0cde, 0x0026, "Z-Com", "UB82 ABG"),
+	ADD_DEV(0x0cde, 0x0027, "Sphairon", "Homelink 1202"),
+	ADD_DEV(0x083a, 0xf522, "Arcadyan", "WN7512"),
+	ADD_DEV(0x2019, 0x5304, "Planex", "GWUS300"),
+	ADD_DEV(0x04bb, 0x093f, "IO-Data", "WNGDNUS2"),
+	ADD_DEV(0x057C, 0x8401, "AVM", "FRITZ!WLAN USB Stick N"),
+	ADD_DEV(0x057C, 0x8402, "AVM", "FRITZ!WLAN USB Stick N 2.4"),
+};
+
+static libusb_context *usb_ctx;
+static LIST_HEAD(active_dev_list);
+
+static int carlusb_event_thread(void *_ar)
+{
+	struct carlu *ar = (void *)_ar;
+	dbg("event thread active and polling.\n");
+
+	while (!ar->stop_event_polling)
+		libusb_handle_events(ar->ctx);
+
+	dbg("==> event thread desixed.\n");
+	return 0;
+}
+
+static int carlusb_is_ar9170(struct libusb_device_descriptor *desc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
+		if ((desc->idVendor == dev_list[i].idVendor) &&
+		    (desc->idProduct == dev_list[i].idProduct)) {
+			dbg("== found device \"%s %s\" [0x%04x:0x%04x]\n",
+				dev_list[i].vendor_name, dev_list[i].product_name,
+				desc->idVendor, desc->idProduct);
+
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+static bool carlusb_is_dev(struct carlu *iter,
+			       struct libusb_device *dev)
+{
+	libusb_device *list_dev;
+
+	if (!iter->dev)
+		return false;
+
+	list_dev = libusb_get_device(iter->dev);
+
+	if (libusb_get_bus_number(list_dev) == libusb_get_bus_number(dev) &&
+	    libusb_get_device_address(list_dev) == libusb_get_device_address(dev))
+		return true;
+
+	return false;
+}
+
+int carlusb_show_devinfo(struct carlu *ar)
+{
+	struct libusb_device_descriptor desc;
+	libusb_device *dev;
+	int err;
+
+	dev = libusb_get_device(ar->dev);
+
+	err = libusb_get_device_descriptor(dev, &desc);
+	if (err)
+		return err;
+
+	info("USB Device Information:\n");
+	info("\tUSB VendorID:%.4x(%s), ProductID:%.4x(%s)\n",
+	     dev_list[ar->idx].idVendor, dev_list[ar->idx].vendor_name,
+	     dev_list[ar->idx].idProduct, dev_list[ar->idx].product_name);
+	info("\tBus:%d Address:%d\n", libusb_get_bus_number(dev),
+	     libusb_get_device_address(dev));
+
+	return 0;
+}
+
+static int carlusb_get_dev(struct carlu *ar, bool reset)
+{
+	struct carlu *iter;
+	libusb_device_handle *dev;
+	libusb_device **list;
+	int ret, err, i, idx = -1;
+
+	ret = libusb_get_device_list(usb_ctx, &list);
+	if (ret < 0) {
+		err("usb device enum failed (%d)\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < ret; i++) {
+		struct libusb_device_descriptor desc;
+
+		memset(&desc, 0, sizeof(desc));
+		err = libusb_get_device_descriptor(list[i], &desc);
+		if (err != 0)
+			continue;
+
+		idx = carlusb_is_ar9170(&desc);
+		if (idx < 0)
+			continue;
+
+		list_for_each_entry(iter, &active_dev_list, dev_list) {
+			if (carlusb_is_dev(iter, list[i])) {
+				err = -EALREADY;
+				break;
+			}
+		}
+
+		if (err)
+			continue;
+
+		err = libusb_open(list[i], &dev);
+		if (err != 0) {
+			err("failed to open device (%d)\n", err);
+			continue;
+		}
+
+		err = libusb_kernel_driver_active(dev, 0);
+		switch (err) {
+		case 0:
+			break;
+		default:
+			err("failed to aquire exculusive access (%d).\n", err);
+			goto skip;
+		}
+
+		if (reset) {
+			err = libusb_reset_device(dev);
+			if (err != 0) {
+				err("failed to reset device (%d)\n", err);
+				goto skip;
+			}
+		}
+
+		err = libusb_claim_interface(dev, 0);
+		if (err == 0) {
+			dbg(">device is now under our control.\n");
+			break;
+		} else {
+			err("failed to claim device (%d)\n", err);
+			goto skip;
+		}
+
+skip:
+		libusb_close(dev);
+	}
+
+	if (i != ret) {
+		ar->idx = idx;
+		ar->ctx = usb_ctx;
+		ar->dev = dev;
+		list_add_tail(&ar->dev_list, &active_dev_list);
+		ret = 0;
+	} else {
+		ret = -ENODEV;
+	}
+
+	libusb_free_device_list(list, 1);
+	return ret;
+}
+
+static void carlusb_tx_cb(struct carlu *ar,
+			      struct frame *frame)
+{
+	if (ar->tx_cb)
+		ar->tx_cb(ar, frame);
+
+	ar->tx_octets += frame->len;
+
+	carlu_free_frame(ar, frame);
+}
+
+static void carlusb_zap_queues(struct carlu *ar)
+{
+	struct frame *frame;
+
+	BUG_ON(SDL_mutexP(ar->tx_queue_lock) != 0);
+	while (!list_empty(&ar->tx_queue)) {
+		frame = list_first_entry(&ar->tx_queue, struct frame, dcb.list);
+		list_del(&frame->dcb.list);
+		carlusb_tx_cb(ar, frame);
+	}
+	SDL_mutexV(ar->tx_queue_lock);
+}
+
+static void carlusb_free_driver(struct carlu *ar)
+{
+	if (!IS_ERR_OR_NULL(ar)) {
+		if (ar->event_pipe[0] > -1)
+			close(ar->event_pipe[0]);
+
+		if (ar->event_pipe[1] > -1)
+			close(ar->event_pipe[1]);
+
+		carlusb_zap_queues(ar);
+		carlfw_release(ar->fw);
+		ar->fw = NULL;
+
+		if (ar->dev) {
+			libusb_release_interface(ar->dev, 0);
+			libusb_close(ar->dev);
+			ar->dev = NULL;
+		}
+		carlu_free_driver(ar);
+	}
+}
+
+static int carlusb_init(struct carlu *ar)
+{
+	init_list_head(&ar->tx_queue);
+	ar->tx_queue_lock = SDL_CreateMutex();
+	ar->event_pipe[0] = ar->event_pipe[1] = -1;
+
+	return 0;
+}
+
+static struct carlu *carlusb_open(void)
+{
+	struct carlu *tmp;
+	int err;
+
+	tmp = carlu_alloc_driver(sizeof(*tmp));
+	if (tmp == NULL)
+		return NULL;
+
+	err = carlusb_init(tmp);
+	if (err < 0)
+		goto err_out;
+
+	err = carlusb_get_dev(tmp, true);
+	if (err < 0)
+		goto err_out;
+
+	return tmp;
+
+err_out:
+	carlusb_free_driver(tmp);
+	return ERR_PTR(err);
+}
+
+static void carlusb_cancel_rings(struct carlu *ar)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(ar->rx_ring); i++)
+		libusb_cancel_transfer(ar->rx_ring[i]);
+
+	libusb_cancel_transfer(ar->rx_interrupt);
+}
+
+static void carlusb_free_rings(struct carlu *ar)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(ar->rx_ring); i++)
+		libusb_free_transfer(ar->rx_ring[i]);
+
+	libusb_free_transfer(ar->rx_interrupt);
+}
+
+static void carlusb_destroy(struct carlu *ar)
+{
+	int event_thread_status;
+
+	dbg("==>release device.\n");
+
+	ar->stop_event_polling = true;
+
+	carlusb_cancel_rings(ar);
+
+	SDL_WaitThread(ar->event_thread, &event_thread_status);
+
+	carlusb_free_rings(ar);
+	list_del(&ar->dev_list);
+}
+
+static void carlusb_tx_bulk_cb(struct libusb_transfer *transfer);
+
+static void carlusb_tx_pending(struct carlu *ar)
+{
+	struct frame *frame;
+	struct libusb_transfer *urb;
+	int err;
+
+	BUG_ON(SDL_mutexP(ar->tx_queue_lock) != 0);
+	if (ar->tx_queue_len >= (AR9170_TX_MAX_ACTIVE_URBS) ||
+	    list_empty(&ar->tx_queue))
+		goto out;
+
+	ar->tx_queue_len++;
+
+	urb = libusb_alloc_transfer(0);
+	if (urb == NULL)
+		goto out;
+
+	frame = list_first_entry(&ar->tx_queue, struct frame, dcb.list);
+	list_del(&frame->dcb.list);
+
+	if (ar->tx_stream) {
+		struct ar9170_stream *tx_stream;
+
+		tx_stream = frame_push(frame, sizeof(*tx_stream));
+		tx_stream->length = cpu_to_le16(frame->len);
+		tx_stream->tag = cpu_to_le16(0x697e);
+	}
+
+	libusb_fill_bulk_transfer(urb, ar->dev, AR9170_EP_TX, (unsigned char *)
+		frame->data, frame->len, carlusb_tx_bulk_cb, (void *)frame, 0);
+
+	/* FIXME: ZERO_PACKET support! */
+	urb->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
+/*	urb->flags |= LIBUSB_TRANSFER_ZERO_PACKET; */
+	frame->dev = (void *) ar;
+	frame_get(frame);
+
+	err = libusb_submit_transfer(urb);
+	if (err != 0) {
+		err("->usb bulk tx submit failed (%d).\n", err);
+		libusb_free_transfer(urb);
+	}
+
+out:
+	SDL_mutexV(ar->tx_queue_lock);
+	return;
+}
+
+void carlusb_tx(struct carlu *ar, struct frame *frame)
+{
+	BUG_ON(SDL_mutexP(ar->tx_queue_lock) != 0);
+
+	list_add_tail(&frame->dcb.list, &ar->tx_queue);
+	SDL_mutexV(ar->tx_queue_lock);
+
+	carlusb_tx_pending(ar);
+}
+
+static void carlusb_tx_bulk_cb(struct libusb_transfer *transfer)
+{
+	struct frame *frame = (void *) transfer->user_data;
+	struct carlu *ar = (void *) frame->dev;
+
+	BUG_ON(SDL_mutexP(ar->tx_queue_lock) != 0);
+	ar->tx_queue_len--;
+	SDL_mutexV(ar->tx_queue_lock);
+
+	if (ar->tx_stream)
+		frame_pull(frame, 4);
+
+	carlusb_tx_cb(ar, frame);
+	carlusb_tx_pending(ar);
+}
+
+static void carlusb_rx_interrupt_cb(struct libusb_transfer *transfer)
+{
+	struct carlu *ar = (void *) transfer->user_data;
+	int err;
+
+	switch (transfer->status) {
+	case LIBUSB_TRANSFER_COMPLETED:
+		carlu_handle_command(ar, transfer->buffer, transfer->actual_length);
+		break;
+
+	case LIBUSB_TRANSFER_CANCELLED:
+		return;
+
+	default:
+		err("==>rx_irq urb died (%d)\n", transfer->status);
+		break;
+	}
+
+	err = libusb_submit_transfer(transfer);
+	if (err != 0)
+		err("==>rx_irq urb resubmit failed (%d)\n", err);
+}
+
+static void carlusb_rx_bulk_cb(struct libusb_transfer *transfer)
+{
+	struct frame *frame = (void *) transfer->user_data;
+	struct carlu *ar = (void *) frame->dev;
+	int err;
+
+	switch (transfer->status) {
+	case LIBUSB_TRANSFER_COMPLETED:
+		frame_put(frame, transfer->actual_length);
+
+		carlu_rx(ar, frame);
+
+		frame_trim(frame, 0);
+		break;
+
+	case LIBUSB_TRANSFER_CANCELLED:
+		return;
+
+	default:
+		err("==>rx_bulk urb died (%d)\n", transfer->status);
+		break;
+	}
+
+	err = libusb_submit_transfer(transfer);
+	if (err != 0)
+		err("->rx_bulk urb resubmit failed (%d)\n", err);
+}
+
+static int carlusb_initialize_rxirq(struct carlu *ar)
+{
+	int err;
+
+	ar->rx_interrupt = libusb_alloc_transfer(0);
+	if (ar->rx_interrupt == NULL) {
+		err("==>cannot alloc rx interrupt urb\n");
+		return -1;
+	}
+
+	libusb_fill_interrupt_transfer(ar->rx_interrupt, ar->dev, AR9170_EP_IRQ,
+				       (unsigned char *)&ar->irq_buf, sizeof(ar->irq_buf),
+				       carlusb_rx_interrupt_cb, (void *) ar, 0);
+
+	err = libusb_submit_transfer(ar->rx_interrupt);
+	if (err != 0) {
+		err("==>failed to submit rx interrupt (%d)\n", err);
+		return err;
+	}
+
+	dbg("rx interrupt is now operational.\n");
+	return 0;
+}
+
+static int carlusb_initialize_rxrings(struct carlu *ar)
+{
+	struct frame *tmp;
+	unsigned int i;
+	int err;
+
+	for (i = 0; i < ARRAY_SIZE(ar->rx_ring); i++) {
+		tmp = frame_alloc(ar->rx_max);
+		if (tmp == NULL)
+			return -ENOMEM;
+
+		tmp->dev = (void *) ar;
+
+		ar->rx_ring[i] = libusb_alloc_transfer(0);
+		if (ar->rx_ring[i] == NULL) {
+			frame_free(tmp);
+			return -ENOMEM;
+		}
+
+		libusb_fill_bulk_transfer(ar->rx_ring[i], ar->dev,
+			AR9170_EP_RX, (unsigned char *)tmp->data,
+			ar->rx_max, carlusb_rx_bulk_cb, (void *)tmp, 0);
+
+		err = libusb_submit_transfer(ar->rx_ring[i]);
+		if (err != 0) {
+			err("==>failed to submit rx buld urb (%d)\n", err);
+			return EXIT_FAILURE;
+		}
+	}
+
+	dbg("rx ring is now ready to receive.\n");
+	return 0;
+}
+
+static int carlusb_load_firmware(struct carlu *ar)
+{
+	int ret = 0;
+
+	dbg("loading firmware...\n");
+
+	ar->fw = carlfw_load(CARL9170_FIRMWARE_FILE);
+	if (IS_ERR_OR_NULL(ar->fw))
+		return PTR_ERR(ar->fw);
+
+	ret = carlu_fw_check(ar);
+	if (ret)
+		return ret;
+
+	ret = carlusb_fw_check(ar);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int carlusb_upload_firmware(struct carlu *ar, bool boot)
+{
+	uint32_t addr = 0x200000;
+	size_t len;
+	void *buf;
+	int ret = 0;
+
+	dbg("initiating firmware image upload procedure.\n");
+
+	buf = carlfw_get_fw(ar->fw, &len);
+	if (IS_ERR_OR_NULL(buf))
+		return PTR_ERR(buf);
+
+	if (ar->miniboot_size) {
+		dbg("Miniboot firmware size:%d\n", ar->miniboot_size);
+		len -= ar->miniboot_size;
+		buf += ar->miniboot_size;
+	}
+
+	while (len) {
+		int blocklen = len > 4096 ? 4096 : len;
+
+		ret = libusb_control_transfer(ar->dev, 0x40, 0x30, addr >> 8, 0, buf, blocklen, 1000);
+		if (ret != blocklen && ret != LIBUSB_ERROR_TIMEOUT) {
+			err("==>firmware upload failed (%d)\n", ret);
+			return -EXIT_FAILURE;
+		}
+
+		dbg("uploaded %d bytes to start address 0x%04x.\n", blocklen, addr);
+
+		buf += blocklen;
+		addr += blocklen;
+		len -= blocklen;
+	}
+
+	if (boot) {
+		ret = libusb_control_transfer(ar->dev, 0x40, 0x31, 0, 0, NULL, 0, 5000);
+		if (ret < 0) {
+			err("unable to boot firmware (%d)\n", ret);
+			return -EXIT_FAILURE;
+		}
+
+		/* give the firmware some time to reset & reboot */
+		SDL_Delay(100);
+
+		/*
+		 * since the device did a full usb reset,
+		 * we have to get a new "dev".
+		 */
+		libusb_release_interface(ar->dev, 0);
+		libusb_close(ar->dev);
+		ar->dev = NULL;
+		list_del(&ar->dev_list);
+
+		ret = carlusb_get_dev(ar, false);
+	}
+
+	return 0;
+}
+
+int carlusb_cmd_async(struct carlu *ar, struct carl9170_cmd *cmd,
+		      const bool free_buf)
+{
+	struct libusb_transfer *urb;
+	int ret, send;
+
+	if (cmd->hdr.len > (CARL9170_MAX_CMD_LEN - 4)) {
+		err("|-> too much payload\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (cmd->hdr.len % 4) {
+		err("|-> invalid command length\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = libusb_interrupt_transfer(ar->dev, AR9170_EP_CMD, (void *) cmd, cmd->hdr.len + 4, &send, 32);
+	if (ret != 0) {
+		err("OID:0x%.2x failed due to (%d) (%d).\n", cmd->hdr.cmd, ret, send);
+		print_hex_dump_bytes(ERROR, "CMD:", cmd, cmd->hdr.len);
+	}
+
+out:
+	if (free_buf)
+		free((void *)cmd);
+
+	return ret;
+}
+
+int carlusb_cmd(struct carlu *ar, uint8_t oid,
+		      uint8_t *cmd, size_t clen,
+		      uint8_t *rsp, size_t rlen)
+{
+	int ret, send;
+
+	if (clen > (CARL9170_MAX_CMD_LEN - 4)) {
+		err("|-> OID:0x%.2x has too much payload (%d octs)\n", oid, (int)clen);
+		return -EINVAL;
+	}
+
+	ret = SDL_mutexP(ar->resp_lock);
+	if (ret != 0) {
+		err("failed to acquire resp_lock.\n");
+		print_hex_dump_bytes(ERROR, "CMD:", ar->cmd.buf, clen);
+		return -1;
+	}
+
+	ar->cmd.cmd.hdr.len = clen;
+	ar->cmd.cmd.hdr.cmd = oid;
+	/* buf[2] & buf[3] are padding */
+	if (clen && cmd != (uint8_t *)(&ar->cmd.cmd.data))
+		memcpy(&ar->cmd.cmd.data, cmd, clen);
+
+	ar->resp_buf = (uint8_t *)rsp;
+	ar->resp_len = rlen;
+
+	ret = carlusb_cmd_async(ar, &ar->cmd.cmd, false);
+	if (ret != 0) {
+		err("OID:0x%.2x failed due to (%d) (%d).\n", oid, ret, send);
+		print_hex_dump_bytes(ERROR, "CMD:", ar->cmd.buf, clen);
+		SDL_mutexV(ar->resp_lock);
+		return ret;
+	}
+
+	ret = SDL_CondWaitTimeout(ar->resp_pend, ar->resp_lock, 100);
+	if (ret != 0) {
+		err("|-> OID:0x%.2x timed out %d.\n", oid, ret);
+		ar->resp_buf = NULL;
+		ar->resp_len = 0;
+		ret = -ETIMEDOUT;
+	}
+
+	SDL_mutexV(ar->resp_lock);
+	return ret;
+}
+
+struct carlu *carlusb_probe(void)
+{
+	struct carlu *ar;
+	int ret = -ENOMEM;
+
+	ar = carlusb_open();
+	if (IS_ERR_OR_NULL(ar)) {
+		if (IS_ERR(ar))
+			ret = PTR_ERR(ar);
+		goto err_out;
+	}
+
+	ret = carlusb_show_devinfo(ar);
+	if (ret)
+		goto err_out;
+
+	ret = carlusb_load_firmware(ar);
+	if (ret)
+		goto err_out;
+
+	ret = pipe(ar->event_pipe);
+	if (ret)
+		goto err_out;
+
+	ar->stop_event_polling = false;
+	ar->event_thread = SDL_CreateThread(carlusb_event_thread, ar);
+
+	ret = carlusb_upload_firmware(ar, true);
+	if (ret)
+		goto err_kill;
+
+	ret = carlusb_initialize_rxirq(ar);
+	if (ret)
+		goto err_kill;
+
+	ret = carlusb_initialize_rxrings(ar);
+	if (ret)
+		goto err_kill;
+
+	ret = carlu_cmd_echo(ar, 0x44110dee);
+	if (ret) {
+		err("echo test failed...\n");
+		goto err_kill;
+	}
+
+	info("firmware is active and running.\n");
+
+	carlu_fw_info(ar);
+
+	return ar;
+
+err_kill:
+	carlusb_destroy(ar);
+
+err_out:
+	carlusb_free_driver(ar);
+	err("usb device rendezvous failed (%d).\n", ret);
+	return ERR_PTR(ret);
+}
+
+void carlusb_close(struct carlu *ar)
+{
+	carlu_cmd_reboot(ar);
+
+	carlusb_destroy(ar);
+	carlusb_free_driver(ar);
+}
+
+int carlusb_print_known_devices(void)
+{
+	unsigned int i;
+
+	debug_level = INFO;
+
+	info("==> dumping known device list <==\n");
+	for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
+		info("Vendor:\"%-9s\" Product:\"%-26s\" => USBID:[0x%04x:0x%04x]\n",
+		     dev_list[i].vendor_name, dev_list[i].product_name,
+		     dev_list[i].idVendor, dev_list[i].idProduct);
+	}
+	info("==> end of device list <==\n");
+
+	return EXIT_SUCCESS;
+}
+
+int usb_init(void)
+{
+	int ret;
+
+	ret = libusb_init(&usb_ctx);
+	if (ret != 0) {
+		err("failed to initialize usb subsystem (%d)\n", ret);
+		return ret;
+	}
+
+	/* like a silent chatterbox! */
+	libusb_set_debug(usb_ctx, 2);
+
+	return 0;
+}
+
+void usb_exit(void)
+{
+	libusb_exit(usb_ctx);
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/usb.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/carlu/src/usb.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,68 @@
+/*
+ * carlu - userspace testing utility for ar9170 devices
+ *
+ * USB back-end API declaration
+ *
+ * Copyright 2009-2011 Christian Lamparter <chunkeey at 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_USB_H
+#define __CARL9170USER_USB_H
+
+#include "SDL.h"
+#include "SDL_thread.h"
+#include "libusb.h"
+#include "frame.h"
+#include "list.h"
+
+#include "fwcmd.h"
+#include <unistd.h>
+#include "carlu.h"
+
+#define AR9170_RX_BULK_BUFS		16
+#define AR9170_RX_BULK_BUF_SIZE		8192
+#define AR9170_RX_BULK_IRQ_SIZE		64
+
+/* endpoints */
+#define AR9170_EP_TX				(LIBUSB_ENDPOINT_OUT | AR9170_USB_EP_TX)
+#define AR9170_EP_RX				(LIBUSB_ENDPOINT_IN  | AR9170_USB_EP_RX)
+#define AR9170_EP_IRQ				(LIBUSB_ENDPOINT_IN  | AR9170_USB_EP_IRQ)
+#define AR9170_EP_CMD				(LIBUSB_ENDPOINT_OUT | AR9170_USB_EP_CMD)
+
+#define AR9170_TX_MAX_ACTIVE_URBS		8
+
+#define CARL9170_FIRMWARE_FILE (CARLU_PATH "/../../carlfw/carl9170.fw")
+
+struct carlu;
+
+void carlusb_reset_txep(struct carlu *ar);
+
+int usb_init(void);
+void usb_exit(void);
+
+struct carlu *carlusb_probe(void);
+void carlusb_close(struct carlu *ar);
+
+void carlusb_tx(struct carlu *ar, struct frame *frame);
+int carlusb_fw_check(struct carlu *ar);
+
+int carlusb_cmd(struct carlu *_ar, uint8_t oid, uint8_t *cmd, size_t clen,
+		uint8_t *rsp, size_t rlen);
+
+int carlusb_print_known_devices(void);
+
+#endif /* __CARL9170USER_USB_H */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/include/frame.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/include/frame.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,401 @@
+/*
+ * 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 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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Most ideas and some code are copied from the linux' kernels
+ *	include/linux/skbuff.h
+ */
+
+#ifndef __TOOLS_FRAME_H
+#define __TOOLS_FRAME_H
+
+#include "SDL.h"
+#include "list.h"
+
+/**
+ * struct frame_queue - sk_buff_head like frame queue
+ *
+ * @list: pointer to head and tail
+ * @lock: mutex lock for serialize access
+ * @len: exact number of queued frames
+ */
+
+struct frame_queue {
+	struct list_head list;
+	SDL_mutex *lock;
+	size_t len;
+};
+
+/**
+ * struct frame - frame data structure (like sk_buff)
+ *
+ * @list: storage for double-linked &struct frame_queue list
+ * @dev: pointer to private device/driver structure
+ * @timestamp: space for the current timestamp
+ * @cb: private driver data
+ * @dcb: more reserved space for low-level / backend driver
+ * @queue: selected frame queue / priority
+ * @ref: reference counter
+ * @alloced: maximum available space
+ * @total_len: currently consumed and reserved memory
+ * @len: current frame length
+ * @head: points to the buffer head
+ * @data: current frame data pointer
+ * @tail: frame data tail pointer
+ * @payload: frame data storage container
+ */
+
+struct frame {
+	struct list_head list;
+	void *dev;
+	unsigned long timestamp;
+	uint8_t cb[64];
+	union {
+		struct list_head list;
+		uint8_t raw_data[32];
+	} dcb;
+
+	unsigned int queue;
+	unsigned int ref;
+	unsigned int alloced;
+	unsigned int total_len;
+	unsigned int len;
+	uint8_t *head;
+	uint8_t *data;
+	uint8_t *tail;
+
+	/* payload must be the last entry */
+	uint8_t payload[0];
+};
+
+/**
+ * frame_put - append more data to &struct frame
+ *
+ * Allocate @size bytes from &struct frame tail and
+ * returns a pointer to the requested location.
+ *
+ * @frame: frame to alter
+ * @size: extra size
+ */
+static inline void *frame_put(struct frame *frame, unsigned int size)
+{
+	void *tmp;
+
+	BUG_ON(frame->total_len + size > frame->alloced);
+
+	frame->len += size;
+	frame->total_len += size;
+
+	tmp = (void *) frame->tail;
+	frame->tail += size;
+
+	BUG_ON(frame->tail > (frame->payload + frame->alloced));
+
+	return tmp;
+}
+
+/**
+ * frame_push - allocate head
+ *
+ * returns a pointer to a newly allocate area at &struct frame head.
+ *
+ * @frame: frame to modify
+ * @size: requested extra size
+ */
+static inline void *frame_push(struct frame *frame, unsigned int size)
+{
+	frame->len += size;
+	frame->data -= size;
+
+	BUG_ON(frame->data < frame->payload);
+	return frame->data;
+}
+
+/**
+ * frame_get - reference frame buffer
+ *
+ * grab a reference from the frame buffer, in order to
+ * prevent it from being freed prematurely by a different user.
+ *
+ * @frame: frame pointer
+ */
+static inline struct frame *frame_get(struct frame *frame)
+{
+	frame->ref++;
+	return frame;
+}
+
+/**
+ * frame_pull - remove space from &struct frame head
+ *
+ * Does the opposite of frame_push() and removes freed-up
+ * space at the frames's head.
+ *
+ * @frame: pointer to frame structure
+ * @size: bytes to remove from head
+ */
+static inline void *frame_pull(struct frame *frame, unsigned int size)
+{
+	BUG_ON(frame->len < size);
+
+	frame->len -= size;
+	frame->total_len -= size;
+	frame->data += size;
+
+	return frame->data;
+}
+
+/**
+ * frame_reserve - reserve frame headroom
+ *
+ * Reserve a certain amount of space to allow headroom manipulations
+ * in the future.
+ *
+ * @frame: frame to adjust
+ * @size: bytes to reserve
+ */
+static inline void frame_reserve(struct frame *frame, unsigned int size)
+{
+	BUG_ON(frame->total_len + size > frame->alloced);
+	BUG_ON(frame->len != 0);
+
+	frame->total_len += size;
+	frame->data += size;
+	frame->tail += size;
+}
+
+/**
+ * frame_trim - set frame length
+ *
+ * cut the frame to @size length.
+ *
+ * @frame: frame to be trimmed
+ * @size: new length
+ */
+static inline void frame_trim(struct frame *frame, unsigned int size)
+{
+	BUG_ON(size > frame->total_len);
+
+	frame->len = size;
+	frame->total_len = size;
+	frame->data = frame->head;
+	frame->tail = frame->head + size;
+}
+
+/**
+ * frame_alloc - alloc and initialize new frame
+ *
+ * returns a newly created &struct frame object.
+ *
+ * @size: maximum frame size of the new frame
+ */
+static inline struct frame *frame_alloc(unsigned int size)
+{
+	struct frame *tmp;
+
+	tmp = malloc(size + sizeof(*tmp));
+	if (tmp != NULL) {
+		memset(tmp, 0, sizeof(*tmp));
+		init_list_head(&tmp->list);
+		init_list_head(&tmp->dcb.list);
+		tmp->len = 0;
+		tmp->total_len = 0;
+		tmp->alloced = size;
+
+		tmp->head = tmp->payload;
+		tmp->data = tmp->payload;
+		tmp->tail = tmp->payload;
+		tmp->ref = 1;
+	}
+	return tmp;
+}
+
+/**
+ * frame_free - unref and free frame
+ *
+ * Unreference frame and free it up, if all users are gone.
+ *
+ * @frame: frame to be freed
+ */
+static inline void frame_free(struct frame *frame)
+{
+	if (!--frame->ref)
+		free(frame);
+}
+
+/**
+ * FRAME_WALK - MACRO walker
+ *
+ * Walks over all queued elements in &struct frame_queue
+ *
+ * NOTE: This function is vulnerable in concurrent access
+ *	 scenarios without proper locking.
+ *
+ * @pos: current position inside the queue
+ * @head: &struct frame_queue head
+ */
+#define FRAME_WALK(pos, head)					\
+	list_for_each_entry((pos), &(head)->list, list)
+
+static inline void __frame_queue_init(struct frame_queue *queue)
+{
+	queue->len = 0;
+	init_list_head(&queue->list);
+}
+
+/**
+ * frame_queue_init - initialize frame_queue
+ *
+ * Initialize the given &struct frame_queue object.
+ *
+ * @queue: frame_queue to be initialized
+ */
+static inline void frame_queue_init(struct frame_queue *queue)
+{
+	queue->lock = SDL_CreateMutex();
+	__frame_queue_init(queue);
+}
+
+/**
+ * frame_queue_len - returns number of queue elements
+ *
+ * @queue: frame_queue object
+ */
+static inline unsigned int frame_queue_len(struct frame_queue *queue)
+{
+	return queue->len;
+}
+
+/**
+ * frame_queue_empty - returns %TRUE whenever queue is empty
+ *
+ * @queue: frame_queue object
+ */
+static inline bool frame_queue_empty(struct frame_queue *queue)
+{
+	return list_empty(&queue->list);
+}
+
+static inline void __frame_queue_head(struct frame_queue *queue, struct frame *frame)
+{
+	list_add_head(&frame->list, &queue->list);
+	queue->len++;
+}
+
+/**
+ * frame_queue_head - queue a frame at the queues head
+ * @queue: queue to use
+ */
+static inline void frame_queue_head(struct frame_queue *queue, struct frame *frame)
+{
+	BUG_ON((SDL_mutexP(queue->lock) != 0));
+	__frame_queue_head(queue, frame);
+	SDL_mutexV(queue->lock);
+}
+
+static inline void __frame_queue_tail(struct frame_queue *queue, struct frame *frame)
+{
+	list_add_tail(&frame->list, &queue->list);
+	queue->len++;
+}
+
+/**
+ * frame_queue_head - queue a frame at the queues tail
+ * @queue: queue to use
+ */
+static inline void frame_queue_tail(struct frame_queue *queue, struct frame *frame)
+{
+	BUG_ON((SDL_mutexP(queue->lock) != 0));
+	__frame_queue_tail(queue, frame);
+	SDL_mutexV(queue->lock);
+}
+
+static inline void __frame_unlink(struct frame_queue *queue, struct frame *frame)
+{
+	list_del(&frame->list);
+	queue->len--;
+}
+
+/**
+ * frame_queue_unlink - remove a frame from the queue
+ * @queue: queue to use
+ * @frame: frame to remove
+ */
+static inline void frame_unlink(struct frame_queue *queue, struct frame *frame)
+{
+	BUG_ON((SDL_mutexP(queue->lock) != 0));
+	__frame_unlink(queue, frame);
+	SDL_mutexV(queue->lock);
+}
+
+
+static inline struct frame *__frame_dequeue(struct frame_queue *queue)
+{
+	struct frame *tmp = NULL;
+
+	if (!frame_queue_empty(queue)) {
+		tmp = list_entry(queue->list.next, struct frame, list);
+		__frame_unlink(queue, tmp);
+	}
+
+	return tmp;
+}
+
+/**
+ * frame_dequeue - remove frame from the head of the queue
+ *
+ * @queue: queue to dequeue from
+ */
+static inline struct frame *frame_dequeue(struct frame_queue *queue)
+{
+	struct frame *tmp;
+
+	BUG_ON((SDL_mutexP(queue->lock) != 0));
+
+	tmp = __frame_dequeue(queue);
+	SDL_mutexV(queue->lock);
+	return tmp;
+}
+
+static inline void __frame_queue_purge(struct frame_queue *queue)
+{
+	while (list_empty(&queue->list) == false)
+		frame_free(__frame_dequeue(queue));
+}
+
+/**
+ * frame_queue_purge - frees all queued &struct frame objects
+ *
+ * @queue: queue to be freed
+ */
+static inline void frame_queue_purge(struct frame_queue *queue)
+{
+	BUG_ON((SDL_mutexP(queue->lock) != 0));
+	__frame_queue_purge(queue);
+	SDL_mutexV(queue->lock);
+}
+
+/**
+ * frame_queue_kill - destroys frame_queue object
+ *
+ * Destroy object and frees up all remaining elements
+ *
+ * @queue: frame_queue victim
+ */
+static inline void frame_queue_kill(struct frame_queue *queue)
+{
+	SDL_DestroyMutex(queue->lock);
+	__frame_queue_purge(queue);
+}
+
+#endif /* __TOOLS_FRAME_H */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/include/list.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/include/list.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,92 @@
+/*
+ * list.h List Utilities
+ *
+ *	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 version 2.1
+ *	of the License.
+ *
+ * Copyright (c) 2003-2006 Thomas Graf <tgraf at suug.ch>
+ */
+
+#ifndef __LIST_H
+#define __LIST_H
+
+struct list_head {
+	struct list_head *next;
+	struct list_head *prev;
+};
+
+static inline void list_add(struct list_head *obj,
+			    struct list_head *prev,
+			    struct list_head *next)
+{
+	prev->next = obj;
+	obj->prev = prev;
+	next->prev = obj;
+	obj->next = next;
+}
+
+static inline void list_add_tail(struct list_head *obj,
+				 struct list_head *head)
+{
+	list_add(obj, head->prev, head);
+}
+
+static inline void list_add_head(struct list_head *obj,
+				 struct list_head *head)
+{
+	list_add(obj, head, head->next);
+}
+
+static inline void list_del(struct list_head *obj)
+{
+	obj->prev->next = obj->next;
+	obj->next->prev = obj->prev;
+	obj->next = obj->prev = obj;
+}
+
+static inline void list_replace(struct list_head *old,
+				struct list_head *obj)
+{
+	obj->next = old->next;
+	obj->next->prev = obj;
+	obj->prev = old->prev;
+	obj->prev->next = obj;
+}
+
+static inline int list_empty(struct list_head *head)
+{
+	return head->next == head;
+}
+
+#define list_entry(ptr, type, member) \
+	container_of(ptr, type, member)
+
+#define list_first_entry(ptr, type, member) \
+	container_of((ptr)->next, type, member)
+
+#define list_at_tail(pos, head, member) \
+	((pos)->member.next == (head))
+
+#define list_at_head(pos, head, member) \
+	((pos)->member.prev == (head))
+
+#define LIST_HEAD(name) \
+	struct list_head name = { &(name), &(name) }
+
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     &(pos)->member != (head);					\
+	     (pos) = list_entry((pos)->member.next, typeof(*(pos)), member))
+
+#define list_for_each_entry_safe(pos, n, head, member)			\
+	for (pos = list_entry((head)->next, typeof(*pos), member),	\
+	     n = list_entry(pos->member.next, typeof(*pos), member);	\
+	     &(pos)->member != (head);					\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+#define init_list_head(head) \
+	do { (head)->next = (head); (head)->prev = (head); } while (0)
+
+#endif /* __LIST_H */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/CMakeLists.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/CMakeLists.txt	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(libcarlfw)
+
+set(carlfw_src carlfw.c)
+
+add_library( carlfw STATIC ${carlfw_src})

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/carlfw.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/carlfw.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,630 @@
+/*
+ * Copyright 2010-2011 Christian Lamparter <chunkeey at 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 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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "carlfw.h"
+
+struct carlfw_file {
+	char *name;
+	size_t len;
+	char *data;
+};
+
+struct carlfw {
+	struct carlfw_file fw;
+	struct carlfw_file hdr;
+
+	struct list_head desc_list;
+	unsigned int desc_list_entries,
+		     desc_list_len;
+};
+
+#define carlfw_walk_descs(iter, fw)					\
+	list_for_each_entry(iter, &fw->desc_list, h.list)
+
+struct carlfw_list_entry_head {
+	struct list_head list;
+};
+
+struct carlfw_list_entry {
+	struct carlfw_list_entry_head h;
+	union {
+		struct carl9170fw_desc_head head;
+		uint32_t data[0];
+		char text[0];
+	};
+};
+
+static inline struct carlfw_list_entry *carlfw_desc_to_entry(struct carl9170fw_desc_head *head)
+{
+	return container_of(head, struct carlfw_list_entry, head);
+}
+
+static inline struct carl9170fw_desc_head *carlfw_entry_to_desc(struct carlfw_list_entry *entry)
+{
+	return &entry->head;
+}
+
+static void carlfw_entry_unlink(struct carlfw *fw,
+	struct carlfw_list_entry *entry)
+{
+	fw->desc_list_entries--;
+	fw->desc_list_len -= le16_to_cpu(entry->head.length);
+	list_del(&entry->h.list);
+}
+
+static void carlfw_entry_del(struct carlfw *fw,
+	struct carlfw_list_entry *entry)
+{
+	carlfw_entry_unlink(fw, entry);
+	free(entry);
+}
+
+static struct carlfw_list_entry *carlfw_find_entry(struct carlfw *fw,
+						   const uint8_t descid[4],
+						   unsigned int len,
+						   uint8_t compatible_revision)
+{
+	struct carlfw_list_entry *iter;
+
+	carlfw_walk_descs(iter, fw) {
+		if (carl9170fw_desc_cmp(&iter->head, descid, len,
+					 compatible_revision))
+			return (void *)iter;
+	}
+
+	return NULL;
+}
+
+static struct carlfw_list_entry *__carlfw_entry_add_prepare(struct carlfw *fw,
+	const struct carl9170fw_desc_head *desc)
+{
+	struct carlfw_list_entry *tmp;
+	unsigned int len;
+
+	len = le16_to_cpu(desc->length);
+
+	if (len < sizeof(struct carl9170fw_desc_head))
+		return ERR_PTR(-EINVAL);
+
+	tmp = malloc(sizeof(*tmp) + len);
+	if (!tmp)
+		return ERR_PTR(-ENOMEM);
+
+	fw->desc_list_entries++;
+	fw->desc_list_len += len;
+
+	memcpy(tmp->data, desc, len);
+	return tmp;
+}
+
+static void __carlfw_release(struct carlfw_file *f)
+{
+	f->len = 0;
+	if (f->name)
+		free(f->name);
+	f->name = NULL;
+
+	if (f->data)
+		free(f->data);
+	f->data = NULL;
+}
+
+void carlfw_release(struct carlfw *fw)
+{
+	struct carlfw_list_entry *entry;
+
+	if (!IS_ERR_OR_NULL(fw)) {
+		while (!list_empty(&fw->desc_list)) {
+			entry = list_entry(fw->desc_list.next,
+					   struct carlfw_list_entry, h.list);
+			carlfw_entry_del(fw, entry);
+		}
+
+		__carlfw_release(&fw->fw);
+		__carlfw_release(&fw->hdr);
+		free(fw);
+	}
+}
+
+static int __carlfw_load(struct carlfw_file *file, const char *name, const char *mode)
+{
+	struct stat file_stat;
+	FILE *fh;
+	int err;
+
+	fh = fopen(name, mode);
+	if (fh == NULL)
+		return errno ? -errno : -1;
+
+	err = fstat(fileno(fh), &file_stat);
+	if (err)
+		return errno ? -errno : -1;
+
+	file->len = file_stat.st_size;
+	file->data = malloc(file->len);
+	if (file->data == NULL)
+		return -ENOMEM;
+
+	err = fread(file->data, file->len, 1, fh);
+	if (err != 1)
+		return -ferror(fh);
+
+	file->name = strdup(name);
+	fclose(fh);
+
+	if (!file->name)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void *__carlfw_find_desc(struct carlfw_file *file,
+				uint8_t descid[4],
+				unsigned int len,
+				uint8_t compatible_revision)
+{
+	int scan = file->len, found = 0;
+	struct carl9170fw_desc_head *tmp = NULL;
+
+	while (scan >= 0) {
+		if (file->data[scan] == descid[CARL9170FW_MAGIC_SIZE - found - 1])
+			found++;
+		else
+			found = 0;
+
+		if (found == CARL9170FW_MAGIC_SIZE)
+			break;
+
+		scan--;
+	}
+
+	if (found == CARL9170FW_MAGIC_SIZE) {
+		tmp = (void *) &file->data[scan];
+
+		if (!CHECK_HDR_VERSION(tmp, compatible_revision) &&
+		    (le16_to_cpu(tmp->length) >= len))
+			return tmp;
+	}
+
+	return NULL;
+}
+
+void *carlfw_find_desc(struct carlfw *fw,
+		       const uint8_t descid[4],
+		       const unsigned int len,
+		       const uint8_t compatible_revision)
+{
+	struct carlfw_list_entry *tmp;
+
+	tmp = carlfw_find_entry(fw, descid, len, compatible_revision);
+
+	return tmp ? carlfw_entry_to_desc(tmp) : NULL;
+}
+
+int carlfw_desc_add_tail(struct carlfw *fw,
+	const struct carl9170fw_desc_head *desc)
+{
+	struct carlfw_list_entry *tmp;
+
+	tmp = __carlfw_entry_add_prepare(fw, desc);
+	if (IS_ERR(tmp))
+		return PTR_ERR(tmp);
+
+	list_add_tail(&tmp->h.list, &fw->desc_list);
+	return 0;
+}
+
+int carlfw_desc_add(struct carlfw *fw,
+		    const struct carl9170fw_desc_head *desc,
+		    struct carl9170fw_desc_head *prev,
+		    struct carl9170fw_desc_head *next)
+{
+	struct carlfw_list_entry *tmp;
+
+	tmp = __carlfw_entry_add_prepare(fw, desc);
+	if (IS_ERR(tmp))
+		return PTR_ERR(tmp);
+
+	list_add(&tmp->h.list, &((carlfw_desc_to_entry(prev))->h.list),
+		 &((carlfw_desc_to_entry(next))->h.list));
+	return 0;
+}
+
+int carlfw_desc_add_before(struct carlfw *fw,
+			   const struct carl9170fw_desc_head *desc,
+			   struct carl9170fw_desc_head *pos)
+{
+	struct carl9170fw_desc_head *prev;
+	struct carlfw_list_entry *prev_entry;
+
+	prev_entry = carlfw_desc_to_entry(pos);
+
+	prev = carlfw_entry_to_desc((struct carlfw_list_entry *) prev_entry->h.list.prev);
+
+	return carlfw_desc_add(fw, desc, prev, pos);
+}
+
+void carlfw_desc_unlink(struct carlfw *fw,
+	struct carl9170fw_desc_head *desc)
+{
+	carlfw_entry_unlink(fw, carlfw_desc_to_entry(desc));
+}
+
+void carlfw_desc_del(struct carlfw *fw,
+	struct carl9170fw_desc_head *desc)
+{
+	carlfw_entry_del(fw, carlfw_desc_to_entry(desc));
+}
+
+void *carlfw_desc_mod_len(struct carlfw *fw __unused,
+	struct carl9170fw_desc_head *desc, size_t len)
+{
+	struct carlfw_list_entry *obj, tmp;
+	int new_len = le16_to_cpu(desc->length) + len;
+
+	if (new_len < (int)sizeof(*desc))
+		return ERR_PTR(-EINVAL);
+
+	if (new_len > CARL9170FW_DESC_MAX_LENGTH)
+		return ERR_PTR(-E2BIG);
+
+	obj = carlfw_desc_to_entry(desc);
+
+	memcpy(&tmp, obj, sizeof(tmp));
+	obj = realloc(obj, new_len + sizeof(struct carlfw_list_entry_head));
+	if (obj == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	list_replace(&tmp.h.list, &obj->h.list);
+
+	desc = carlfw_entry_to_desc(obj);
+	desc->length = le16_to_cpu(new_len);
+	fw->desc_list_len += len;
+
+	return desc;
+}
+
+void *carlfw_desc_next(struct carlfw *fw,
+		       struct carl9170fw_desc_head *pos)
+{
+	struct carlfw_list_entry *entry;
+
+	if (!pos)
+		entry = (struct carlfw_list_entry *) &fw->desc_list;
+	else
+		entry = carlfw_desc_to_entry(pos);
+
+	if (list_at_tail(entry, &fw->desc_list, h.list))
+		return NULL;
+
+	entry = (struct carlfw_list_entry *) entry->h.list.next;
+
+	return carlfw_entry_to_desc(entry);
+}
+
+static int carlfw_parse_descs(struct carlfw *fw,
+			      struct carl9170fw_otus_desc *otus_desc)
+{
+	const struct carl9170fw_desc_head *iter = NULL;
+	int err;
+
+	carl9170fw_for_each_hdr(iter, &otus_desc->head) {
+		err = carlfw_desc_add_tail(fw, iter);
+		if (err)
+			return err;
+	}
+	/* LAST is added automatically by carlfw_store */
+
+	return err;
+}
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define CRCPOLY_LE 0xedb88320
+
+/* copied from the linux kernel  */
+static uint32_t crc32_le(uint32_t crc, unsigned char const *p, size_t len)
+{
+	int i;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+	}
+	return crc;
+}
+#else
+#error "this tool does not work with a big endian host yet!"
+#endif
+
+static int carlfw_check_crc32s(struct carlfw *fw)
+{
+	struct carl9170fw_chk_desc *chk_desc;
+	struct carlfw_list_entry *iter;
+	unsigned int elen;
+	uint32_t crc32;
+
+	chk_desc = carlfw_find_desc(fw, (uint8_t *) CHK_MAGIC,
+				    sizeof(*chk_desc),
+				    CARL9170FW_CHK_DESC_CUR_VER);
+	if (!chk_desc)
+		return -ENODATA;
+
+	crc32 = crc32_le(~0, (void *) fw->fw.data, fw->fw.len);
+	if (crc32 != le32_to_cpu(chk_desc->fw_crc32))
+		return -EINVAL;
+
+	carlfw_walk_descs(iter, fw) {
+		elen = le16_to_cpu(iter->head.length);
+
+		if (carl9170fw_desc_cmp(&iter->head, (uint8_t *) CHK_MAGIC,
+					sizeof(*chk_desc),
+					CARL9170FW_CHK_DESC_CUR_VER))
+			continue;
+
+		crc32 = crc32_le(crc32, (void *) &iter->head, elen);
+	}
+
+	if (crc32 != le32_to_cpu(chk_desc->hdr_crc32))
+		return -EINVAL;
+
+	return 0;
+}
+
+struct carlfw *carlfw_load(const char *basename)
+{
+	char filename[256];
+	struct carlfw *fw;
+	struct carl9170fw_otus_desc *otus_desc;
+	struct carl9170fw_last_desc *last_desc;
+	struct carlfw_file *hdr_file;
+	unsigned long fin, diff, off, rem;
+	int err;
+
+	fw = calloc(1, sizeof(*fw));
+	if (!fw)
+		return ERR_PTR(-ENOMEM);
+
+	init_list_head(&fw->desc_list);
+
+	err = __carlfw_load(&fw->fw, basename, "r");
+	if (err)
+		goto err_out;
+
+	if (fw->hdr.name)
+		hdr_file = &fw->hdr;
+	else
+		hdr_file = &fw->fw;
+
+	otus_desc = __carlfw_find_desc(hdr_file, (uint8_t *) OTUS_MAGIC,
+				       sizeof(*otus_desc),
+				       CARL9170FW_OTUS_DESC_CUR_VER);
+	last_desc = __carlfw_find_desc(hdr_file, (uint8_t *) LAST_MAGIC,
+				       sizeof(*last_desc),
+				       CARL9170FW_LAST_DESC_CUR_VER);
+
+	if (!otus_desc || !last_desc ||
+	    (unsigned long) otus_desc > (unsigned long) last_desc) {
+		err = -ENODATA;
+		goto err_out;
+	}
+
+	err = carlfw_parse_descs(fw, otus_desc);
+	if (err)
+		goto err_out;
+
+	fin = (unsigned long)last_desc + sizeof(*last_desc);
+	diff = fin - (unsigned long)otus_desc;
+	rem = hdr_file->len - (fin - (unsigned long) hdr_file->data);
+
+	if (rem) {
+		off = (unsigned long)otus_desc - (unsigned long)hdr_file->data;
+		memmove(&hdr_file->data[off],
+			((uint8_t *)last_desc) + sizeof(*last_desc), rem);
+	}
+
+	hdr_file->len -= diff;
+	hdr_file->data = realloc(hdr_file->data, hdr_file->len);
+	if (!hdr_file->data && hdr_file->len) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	err = carlfw_check_crc32s(fw);
+	if (err && err != -ENODATA)
+		goto err_out;
+
+	return fw;
+
+err_out:
+	carlfw_release(fw);
+	return ERR_PTR(err);
+}
+
+static int carlfw_apply_checksums(struct carlfw *fw)
+{
+	struct carlfw_list_entry *iter;
+	struct carl9170fw_chk_desc tmp = {
+		CARL9170FW_FILL_DESC(CHK_MAGIC, sizeof(tmp),
+				      CARL9170FW_CHK_DESC_MIN_VER,
+				      CARL9170FW_CHK_DESC_CUR_VER) };
+	struct carl9170fw_chk_desc *chk_desc = NULL;
+	int err = 0;
+	unsigned int len = 0, elen, max_len;
+	uint32_t crc32;
+
+	chk_desc = carlfw_find_desc(fw, (uint8_t *) CHK_MAGIC,
+				    sizeof(*chk_desc),
+				    CARL9170FW_CHK_DESC_CUR_VER);
+	if (chk_desc) {
+		carlfw_desc_del(fw, &chk_desc->head);
+		chk_desc = NULL;
+	}
+
+	max_len = fw->desc_list_len;
+
+	crc32 = crc32_le(~0, (void *) fw->fw.data, fw->fw.len);
+	tmp.fw_crc32 = cpu_to_le32(crc32);
+
+	/*
+	 * NOTE:
+	 *
+	 * The descriptor checksum is seeded with the firmware's crc32.
+	 * This neat trick ensures that the driver can check whenever
+	 * descriptor actually belongs to the firmware, or not.
+	 */
+
+	carlfw_walk_descs(iter, fw) {
+		elen = le16_to_cpu(iter->head.length);
+
+		if (max_len < len + elen)
+			return -EMSGSIZE;
+
+		crc32 = crc32_le(crc32, (void *) &iter->head, elen);
+		len += elen;
+	}
+
+	tmp.hdr_crc32 = cpu_to_le32(crc32);
+
+	err = carlfw_desc_add_tail(fw, &tmp.head);
+
+	return err;
+}
+
+int carlfw_store(struct carlfw *fw)
+{
+	struct carl9170fw_last_desc last_desc = {
+		CARL9170FW_FILL_DESC(LAST_MAGIC, sizeof(last_desc),
+			CARL9170FW_LAST_DESC_MIN_VER,
+			CARL9170FW_LAST_DESC_CUR_VER) };
+
+	struct carlfw_list_entry *iter;
+	FILE *fh;
+	int err, elen;
+
+	err = carlfw_apply_checksums(fw);
+	if (err)
+		return err;
+
+	fh = fopen(fw->fw.name, "w");
+	if (!fh)
+		return -errno;
+
+	err = fwrite(fw->fw.data, fw->fw.len, 1, fh);
+	if (err != 1) {
+		err = -errno;
+		goto close_out;
+	}
+
+	if (fw->hdr.name) {
+		fclose(fh);
+
+		fh = fopen(fw->hdr.name, "w");
+	}
+
+	carlfw_walk_descs(iter, fw) {
+		elen = le16_to_cpu(iter->head.length);
+
+		if (elen > CARL9170FW_DESC_MAX_LENGTH) {
+			err = -E2BIG;
+			goto close_out;
+		}
+
+		err = fwrite(iter->data, elen, 1, fh);
+		if (err != 1) {
+			err = -ferror(fh);
+			goto close_out;
+		}
+	}
+
+	err = fwrite(&last_desc, sizeof(last_desc), 1, fh);
+	if (err != 1) {
+		err = -ferror(fh);
+		goto close_out;
+	}
+
+	err = 0;
+
+close_out:
+	fclose(fh);
+	return err;
+}
+
+void *carlfw_mod_tailroom(struct carlfw *fw, ssize_t len)
+{
+	size_t new_len;
+	void *buf;
+
+	new_len = fw->fw.len + len;
+
+	if (!carl9170fw_size_check(new_len))
+		return ERR_PTR(-EINVAL);
+
+	buf = realloc(fw->fw.data, new_len);
+	if (buf == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	fw->fw.len = new_len;
+	fw->fw.data = buf;
+	return &fw->fw.data[new_len - len];
+}
+
+void *carlfw_mod_headroom(struct carlfw *fw, ssize_t len)
+{
+	size_t new_len;
+	void *ptr;
+
+	new_len = fw->fw.len + len;
+	if (!carl9170fw_size_check(new_len))
+		return ERR_PTR(-EINVAL);
+
+	if (len < 0)
+		memmove(fw->fw.data, &fw->fw.data[len], new_len);
+
+	ptr = carlfw_mod_tailroom(fw, len);
+	if (IS_ERR_OR_NULL(ptr))
+		return ptr;
+
+	if (len > 0)
+		memmove(&fw->fw.data[len], &fw->fw.data[0], new_len - len);
+
+	return fw->fw.data;
+}
+
+void *carlfw_get_fw(struct carlfw *fw, size_t *len)
+{
+	*len = fw->fw.len;
+	return fw->fw.data;
+}
+
+unsigned int carlfw_get_descs_num(struct carlfw *fw)
+{
+	return fw->desc_list_entries;
+}
+
+unsigned int carlfw_get_descs_size(struct carlfw *fw)
+{
+	return fw->desc_list_len;
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/carlfw.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/lib/carlfw.h	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010-2011 Christian Lamparter <chunkeey at 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 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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __CARLFW_H
+#define __CARLFW_H
+
+#include <linux/types.h>
+#include "compiler.h"
+#include "fwdesc.h"
+#include "list.h"
+
+struct carlfw;
+
+void carlfw_release(struct carlfw *fw);
+struct carlfw *carlfw_load(const char *basename);
+int carlfw_store(struct carlfw *fw);
+void *carlfw_find_desc(struct carlfw *fw,
+	const uint8_t descid[4], const unsigned int len,
+	const uint8_t compatible_revision);
+
+int carlfw_desc_add_tail(struct carlfw *fw,
+			 const struct carl9170fw_desc_head *desc);
+
+int carlfw_desc_add(struct carlfw *fw,
+		    const struct carl9170fw_desc_head *desc,
+		    struct carl9170fw_desc_head *prev,
+		    struct carl9170fw_desc_head *next);
+
+void *carlfw_desc_mod_len(struct carlfw *fw,
+			  struct carl9170fw_desc_head *desc,
+			  size_t len);
+
+int carlfw_desc_add_before(struct carlfw *fw,
+			   const struct carl9170fw_desc_head *desc,
+			   struct carl9170fw_desc_head *pos);
+
+void carlfw_desc_unlink(struct carlfw *fw,
+			struct carl9170fw_desc_head *desc);
+
+void carlfw_desc_del(struct carlfw *fw,
+		     struct carl9170fw_desc_head *entry);
+
+void *carlfw_desc_next(struct carlfw *fw,
+		       struct carl9170fw_desc_head *pos);
+
+void *carlfw_mod_tailroom(struct carlfw *fw, ssize_t len);
+void *carlfw_mod_headroom(struct carlfw *fw, ssize_t len);
+
+void *carlfw_get_fw(struct carlfw *fw, size_t *len);
+
+unsigned int carlfw_get_descs_num(struct carlfw *fw);
+unsigned int carlfw_get_descs_size(struct carlfw *fw);
+#endif /* __CARLFW_H */

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/CMakeLists.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/CMakeLists.txt	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(tools)
+
+add_custom_target(wol ALL COMMAND gcc wol.c -o wol)
+
+set(tools fwinfo miniboot checksum eeprom_fix)
+
+foreach(tool ${tools})
+	add_executable( ${tool} ${tool}.c )
+	add_definitions("-std=gnu99 -Wall -Wextra -Wshadow")
+	target_link_libraries( ${tool} carlfw )
+endforeach()

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/checksum.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/checksum.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010-2011 Christian Lamparter <chunkeey at 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 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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "carlfw.h"
+
+#include "compiler.h"
+
+static void checksum_help(void)
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\tchecksum FW-FILE\n");
+
+	fprintf(stderr, "\nDescription:\n");
+	fprintf(stderr, "\tThis simple utility adds/updates various "
+			"checksums.\n");
+
+	fprintf(stderr, "\nParameteres:\n");
+	fprintf(stderr, "\t 'FW-FILE'	= firmware name\n");
+	fprintf(stderr, "\n");
+}
+
+int main(int argc, char *args[])
+{
+	struct carlfw *fw = NULL;
+	int err = 0;
+
+	if (argc != 2) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	fw = carlfw_load(args[1]);
+	if (IS_ERR_OR_NULL(fw)) {
+		err = PTR_ERR(fw);
+		fprintf(stderr, "Failed to open file \"%s\" (%d).\n",
+			args[1], err);
+		goto out;
+	}
+
+	/*
+	 * No magic here, The checksum descriptor is added/update
+	 * automatically in a subroutine of carlfw_store().
+	 *
+	 * This tools serves as a skeleton/example.
+	 */
+	err = carlfw_store(fw);
+	if (err) {
+		fprintf(stderr, "Failed to apply checksum (%d).\n", err);
+		goto out;
+	}
+
+out:
+	switch (err) {
+	case 0:
+		fprintf(stdout, "checksum applied.\n");
+		break;
+	case -EINVAL:
+		checksum_help();
+		break;
+	default:
+		break;
+	}
+
+	carlfw_release(fw);
+	return err ? EXIT_FAILURE : EXIT_SUCCESS;
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/eeprom_fix.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/eeprom_fix.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2010-2011 Christian Lamparter <chunkeey at 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 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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "carlfw.h"
+
+#include "compiler.h"
+
+static int get_val(char *str, unsigned int *val)
+{
+	int err;
+
+	err = sscanf(str, "%8x", val);
+	if (err != 1)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int get_addr(char *str, unsigned int *val)
+{
+	int err;
+
+	err = get_val(str, val);
+	if (*val & 3) {
+		fprintf(stderr, "Address 0x%.8x is not a multiple of 4.\n",
+			*val);
+
+		return -EINVAL;
+	}
+
+	return err;
+}
+
+static int
+new_fix_entry(struct carlfw *fw, struct carl9170fw_fix_entry *fix_entry)
+{
+	struct carl9170fw_fix_desc *fix;
+	unsigned int len;
+
+	len = sizeof(*fix) + sizeof(*fix_entry);
+	fix = malloc(len);
+	if (!fix)
+		return -ENOMEM;
+
+	carl9170fw_fill_desc(&fix->head, (uint8_t *) FIX_MAGIC,
+			      cpu_to_le16(len),
+			      CARL9170FW_FIX_DESC_MIN_VER,
+			      CARL9170FW_FIX_DESC_CUR_VER);
+
+	memcpy(&fix->data[0], fix_entry, sizeof(*fix_entry));
+
+	return carlfw_desc_add_tail(fw, &fix->head);
+}
+
+static struct carl9170fw_fix_entry *
+scan_for_similar_fix(struct carl9170fw_fix_desc *fix, __le32 address)
+{
+	unsigned int i, entries;
+
+	entries = (le16_to_cpu(fix->head.length) - sizeof(*fix)) /
+		   sizeof(struct carl9170fw_fix_entry);
+
+	for (i = 0; i < entries; i++) {
+		if (address == fix->data[i].address)
+			return &fix->data[i];
+	}
+
+	return NULL;
+}
+
+static int
+add_another_fix_entry(struct carlfw *fw, struct carl9170fw_fix_desc *fix,
+		 struct carl9170fw_fix_entry *fix_entry)
+{
+	unsigned int entry;
+
+	fix = carlfw_desc_mod_len(fw, &fix->head, sizeof(*fix_entry));
+	if (IS_ERR_OR_NULL(fix))
+		return (int) PTR_ERR(fix);
+
+	entry = (le16_to_cpu(fix->head.length) - sizeof(*fix)) /
+		sizeof(*fix_entry) - 1;
+
+	memcpy(&fix->data[entry], fix_entry, sizeof(*fix_entry));
+	return 0;
+}
+
+static int
+update_entry(char option, struct carl9170fw_fix_entry *entry,
+	     struct carl9170fw_fix_entry *fix)
+{
+	switch (option) {
+	case '=':
+		entry->mask = fix->mask;
+		entry->value = fix->value;
+		break;
+
+	case 'O':
+		entry->mask |= fix->mask;
+		entry->value |= fix->value;
+		break;
+
+	case 'A':
+		entry->mask &= fix->mask;
+		entry->value &= fix->value;
+		break;
+
+	default:
+		fprintf(stderr, "Unknown option: '%c'\n", option);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void user_education(void)
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\teeprom_fix FW-FILE SWITCH [ADDRESS [VALUE MASK]]\n");
+
+	fprintf(stderr, "\nDescription:\n");
+	fprintf(stderr, "\tThis utility manage a set of overrides which "
+			"commands the driver\n\tto load customized EEPROM' "
+			"data for all specified addresses.\n");
+
+	fprintf(stderr, "\nParameters:\n");
+	fprintf(stderr, "\t'FW-FILE'  = firmware file [basename]\n");
+	fprintf(stderr, "\t'SWITCH'   = [=|d|D]\n");
+	fprintf(stderr, "\t | '='       => add/set value for address\n");
+	fprintf(stderr, "\t | 'D'       => removes all EEPROM overrides\n");
+	fprintf(stderr, "\t * 'd'       => removed override for 'address'\n");
+	fprintf(stderr, "\n\t'ADDRESS'  = location of the EEPROM override\n");
+	fprintf(stderr, "\t\t     NB: must be a multiple of 4.\n");
+	fprintf(stderr, "\t\t     an address map can be found in eeprom.h.\n");
+	fprintf(stderr, "\n\t'VALUE'    = replacement value\n");
+	fprintf(stderr, "\t'MASK'     = mask for the value placement.\n\n");
+
+	exit(EXIT_FAILURE);
+}
+
+static int
+set_fix(struct carlfw *fw, struct carl9170fw_fix_desc *fix,
+	char __unused option, int __unused argc, char *args[])
+{
+	struct carl9170fw_fix_entry fix_entry, *entry = NULL;
+	unsigned int address, value, mask;
+	int err;
+
+	err = get_addr(args[3], &address);
+	if (err)
+		return err;
+
+	err = get_val(args[4], &value);
+	if (err)
+		return err;
+
+	err = get_val(args[5], &mask);
+	if (err)
+		return err;
+
+	fix_entry.address = cpu_to_le32(address);
+	fix_entry.value = cpu_to_le32(value);
+	fix_entry.mask = cpu_to_le32(mask);
+
+	if (!fix) {
+		err = new_fix_entry(fw, &fix_entry);
+	} else {
+		entry = scan_for_similar_fix(fix, fix_entry.address);
+		if (entry) {
+			err = update_entry(option, entry, &fix_entry);
+			if (err)
+				fprintf(stdout, "Overwrite old entry.\n");
+		} else {
+			err = add_another_fix_entry(fw, fix, &fix_entry);
+		}
+	}
+
+	return err;
+}
+
+static int
+del_fix(struct carlfw *fw, struct carl9170fw_fix_desc *fix,
+	char __unused option, int __unused argc, char *args[])
+{
+	struct carl9170fw_fix_entry *entry = NULL;
+	unsigned int address;
+	unsigned long off;
+	unsigned int rem_len;
+	int err;
+
+	err = get_addr(args[3], &address);
+	if (err)
+		return err;
+
+	if (fix)
+		entry = scan_for_similar_fix(fix, cpu_to_le32(address));
+
+	if (!entry) {
+		fprintf(stderr, "Entry for 0x%.8x not found\n", address);
+		return -EINVAL;
+	}
+
+	off = (unsigned long) entry - (unsigned long) fix->data;
+	rem_len = le16_to_cpu(fix->head.length) - off;
+
+	if (rem_len) {
+		unsigned long cont;
+		cont = (unsigned long) entry + sizeof(*entry);
+		memmove(entry, (void *)cont, rem_len);
+	}
+
+	fix = carlfw_desc_mod_len(fw, &fix->head, -sizeof(*entry));
+	err = IS_ERR_OR_NULL(fix);
+	return err;
+}
+
+static int del_all(struct carlfw *fw, struct carl9170fw_fix_desc *fix,
+	char __unused option, int __unused argc, char __unused *args[])
+{
+	if (!fix)
+		return 0;
+
+	carlfw_desc_del(fw, &fix->head);
+	return 0;
+}
+
+static const struct {
+	char option;
+	int argc;
+	int (*func)(struct carlfw *, struct carl9170fw_fix_desc *,
+		    char, int, char **);
+} programm_function[] = {
+	{ '=', 6, set_fix },
+	{ 'O', 6, set_fix },
+	{ 'A', 6, set_fix },
+	{ 'd', 4, del_fix },
+	{ 'D', 3, del_all },
+};
+
+int main(int argc, char *args[])
+{
+	struct carl9170fw_fix_desc *fix;
+	struct carlfw *fw = NULL;
+	unsigned int i;
+	int err = 0;
+	char option;
+
+	if (argc < 3 || argc > 6) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	fw = carlfw_load(args[1]);
+	if (IS_ERR_OR_NULL(fw)) {
+		err = PTR_ERR(fw);
+		fprintf(stderr, "Failed to open file \"%s\" (%d).\n",
+			args[1], err);
+		goto out;
+	}
+
+	fix = carlfw_find_desc(fw, (uint8_t *)FIX_MAGIC, sizeof(*fix),
+			       CARL9170FW_FIX_DESC_CUR_VER);
+
+	option = args[2][0];
+	for (i = 0; i < ARRAY_SIZE(programm_function); i++) {
+		if (programm_function[i].option != option)
+			continue;
+
+		if (argc != programm_function[i].argc) {
+			err = -EINVAL;
+			goto out;
+		}
+
+		err = programm_function[i].func(fw, fix, option, argc, args);
+		if (err)
+			goto out;
+
+		break;
+	}
+	if (i == ARRAY_SIZE(programm_function)) {
+		fprintf(stderr, "Unknown option: '%c'\n",
+			args[2][0]);
+		goto out;
+	}
+
+	err = carlfw_store(fw);
+	if (err) {
+		fprintf(stderr, "Failed to apply changes (%d).\n", err);
+		goto out;
+	}
+
+out:
+	carlfw_release(fw);
+
+	if (err) {
+		if (err == -EINVAL)
+			user_education();
+		else
+			fprintf(stderr, "%s\n", strerror(err));
+	}
+
+	return err ? EXIT_FAILURE : EXIT_SUCCESS;
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/fwinfo.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/fwinfo.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2010-2011 Christian Lamparter <chunkeey at 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 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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "carlfw.h"
+
+#include "fwcmd.h"
+#include "compiler.h"
+
+struct feature_list {
+	unsigned int id;
+	char name[64];
+	void (*func)(const struct carl9170fw_desc_head *, struct carlfw *fw);
+};
+
+#define CHECK_FOR_FEATURE(feature_enum)					\
+	{ .id = feature_enum, .name = #feature_enum, .func = NULL }
+
+#define CHECK_FOR_FEATURE_FUNC(feature_enum, _func)			\
+	{ .id = feature_enum, .name = #feature_enum, .func = _func }
+
+static void show_miniboot_info(const struct carl9170fw_desc_head *head,
+			       struct carlfw *fw __unused)
+{
+	const struct carl9170fw_otus_desc *otus = (const void *) head;
+
+	fprintf(stdout, "\t\t\tminiboot size: %d Bytes\n", otus->miniboot_size);
+}
+
+static const struct feature_list known_otus_features_v1[] = {
+	CHECK_FOR_FEATURE(CARL9170FW_DUMMY_FEATURE),
+	CHECK_FOR_FEATURE_FUNC(CARL9170FW_MINIBOOT, show_miniboot_info),
+	CHECK_FOR_FEATURE(CARL9170FW_USB_INIT_FIRMWARE),
+	CHECK_FOR_FEATURE(CARL9170FW_USB_RESP_EP2),
+	CHECK_FOR_FEATURE(CARL9170FW_USB_DOWN_STREAM),
+	CHECK_FOR_FEATURE(CARL9170FW_USB_UP_STREAM),
+	CHECK_FOR_FEATURE(CARL9170FW_UNUSABLE),
+	CHECK_FOR_FEATURE(CARL9170FW_COMMAND_PHY),
+	CHECK_FOR_FEATURE(CARL9170FW_COMMAND_CAM),
+	CHECK_FOR_FEATURE(CARL9170FW_WLANTX_CAB),
+	CHECK_FOR_FEATURE(CARL9170FW_HANDLE_BACK_REQ),
+	CHECK_FOR_FEATURE(CARL9170FW_GPIO_INTERRUPT),
+	CHECK_FOR_FEATURE(CARL9170FW_PSM),
+	CHECK_FOR_FEATURE(CARL9170FW_RX_FILTER),
+	CHECK_FOR_FEATURE(CARL9170FW_WOL),
+	CHECK_FOR_FEATURE(CARL9170FW_FIXED_5GHZ_PSM),
+	CHECK_FOR_FEATURE(CARL9170FW_HW_COUNTERS),
+	CHECK_FOR_FEATURE(CARL9170FW_RX_BA_FILTER),
+};
+
+static void check_feature_list(const struct carl9170fw_desc_head *head,
+			       const __le32 bitmap,
+			       const struct feature_list *list,
+			       const unsigned int entries,
+			       struct carlfw *fw)
+{
+	unsigned int i;
+
+	for (i = 0; i < entries; i++) {
+		if (!carl9170fw_supports(bitmap, list[i].id))
+			continue;
+
+		fprintf(stdout, "\t\t%2d = %s\n", list[i].id, list[i].name);
+		if (list[i].func)
+			list[i].func(head, fw);
+	}
+}
+
+static void show_otus_desc(const struct carl9170fw_desc_head *head,
+			   struct carlfw *fw)
+{
+	const struct carl9170fw_otus_desc *otus = (const void *) head;
+
+	BUILD_BUG_ON(ARRAY_SIZE(known_otus_features_v1) != __CARL9170FW_FEATURE_NUM);
+
+	fprintf(stdout, "\tFirmware upload pointer: 0x%x\n",
+		otus->fw_address);
+	fprintf(stdout, "\tBeacon Address: %x, (reserved:%d Bytes)\n",
+		le32_to_cpu(otus->bcn_addr), le16_to_cpu(otus->bcn_len));
+	fprintf(stdout, "\tTX DMA chunk size:%d Bytes, TX DMA chunks:%d\n",
+		otus->tx_frag_len, otus->tx_descs);
+	fprintf(stdout, "\t=> %d Bytes are reserved for the TX queues\n",
+		otus->tx_frag_len * otus->tx_descs);
+	fprintf(stdout, "\tCommand response buffers:%d\n", otus->cmd_bufs);
+	fprintf(stdout, "\tMax. RX stream block size:%d Bytes\n",
+		otus->rx_max_frame_len);
+	fprintf(stdout, "\tSupported Firmware Interfaces: %d\n", otus->vif_num);
+	fprintf(stdout, "\tFirmware API Version: %d\n", otus->api_ver);
+	fprintf(stdout, "\tSupported Features: (raw:%.08x)\n",
+		le32_to_cpu(otus->feature_set));
+
+	check_feature_list(head, otus->feature_set, known_otus_features_v1,
+			   ARRAY_SIZE(known_otus_features_v1), fw);
+}
+
+static void show_motd_desc(const struct carl9170fw_desc_head *head,
+			   struct carlfw *fw __unused)
+{
+	const struct carl9170fw_motd_desc *motd = (const void *) head;
+	char buf[CARL9170FW_MOTD_STRING_LEN];
+	unsigned int fw_date;
+
+	fw_date = motd->fw_year_month_day;
+	fprintf(stdout, "\tFirmware Build Date (YYYY-MM-DD): 2%03d-%02d-%02d\n",
+		CARL9170FW_GET_YEAR(fw_date), CARL9170FW_GET_MONTH(fw_date),
+		CARL9170FW_GET_DAY(fw_date));
+
+	strncpy(buf, motd->desc, CARL9170FW_MOTD_STRING_LEN);
+	fprintf(stdout, "\tFirmware Text:\"%s\"\n", buf);
+
+	strncpy(buf, motd->release, CARL9170FW_MOTD_STRING_LEN);
+	fprintf(stdout, "\tFirmware Release:\"%s\"\n", buf);
+}
+
+static void show_fix_desc(const struct carl9170fw_desc_head *head,
+			  struct carlfw *fw __unused)
+{
+	const struct carl9170fw_fix_desc *fix = (const void *) head;
+	const struct carl9170fw_fix_entry *iter;
+	unsigned int i;
+
+	for (i = 0; i < (head->length - sizeof(*head)) / sizeof(*iter); i++) {
+		iter = &fix->data[i];
+		fprintf(stdout, "\t\t%d: 0x%.8x := 0x%.8x (0x%.8x)\n", i,
+			le32_to_cpu(iter->address), le32_to_cpu(iter->value),
+			le32_to_cpu(iter->mask));
+	}
+}
+
+static void show_dbg_desc(const struct carl9170fw_desc_head *head,
+			    struct carlfw *fw __unused)
+{
+	const struct carl9170fw_dbg_desc *dbg = (const void *) head;
+
+#define DBG_ADDR(_name, _reg) do {					\
+	unsigned int __tmp = le32_to_cpu(dbg->_reg);			\
+	if (__tmp)							\
+		fprintf(stdout, "\t\t" _name " = 0x%.8x\n", __tmp);	\
+	} while (0);
+
+	fprintf(stdout, "\tFirmware Debug Registers/Counters\n");
+	DBG_ADDR("bogoclock    ", bogoclock_addr);
+	DBG_ADDR("counter      ", counter_addr);
+	DBG_ADDR("rx total     ", rx_total_addr);
+	DBG_ADDR("rx overrun   ", rx_overrun_addr);
+	DBG_ADDR("rx filer     ", rx_filter);
+}
+
+static void show_txsq_desc(const struct carl9170fw_desc_head *head,
+			   struct carlfw *fw __unused)
+{
+	const struct carl9170fw_txsq_desc *txsq = (const void *) head;
+
+	fprintf(stdout, "\t\ttx-seq table addr: 0x%x\n",
+		le32_to_cpu(txsq->seq_table_addr));
+}
+
+
+static const struct feature_list wol_triggers_v1[] = {
+	CHECK_FOR_FEATURE(CARL9170_WOL_DISCONNECT),
+	CHECK_FOR_FEATURE(CARL9170_WOL_MAGIC_PKT),
+};
+
+static void show_wol_desc(const struct carl9170fw_desc_head *head,
+			  struct carlfw *fw __unused)
+{
+	const struct carl9170fw_wol_desc *wol = (const void *) head;
+
+	fprintf(stdout, "\tSupported WOWLAN triggers: (raw:%.08x)\n",
+		le32_to_cpu(wol->supported_triggers));
+
+	check_feature_list(head, wol->supported_triggers, wol_triggers_v1,
+			   ARRAY_SIZE(wol_triggers_v1), fw);
+}
+
+static void show_chk_desc(const struct carl9170fw_desc_head *head,
+			  struct carlfw *fw __unused)
+{
+	const struct carl9170fw_chk_desc *chk = (const void *) head;
+
+	fprintf(stdout, "\tFirmware Descriptor CRC32: %08x\n",
+		le32_to_cpu(chk->hdr_crc32));
+	fprintf(stdout, "\tFirmware Image CRC32: %08x\n",
+		le32_to_cpu(chk->fw_crc32));
+}
+
+static void show_last_desc(const struct carl9170fw_desc_head *head,
+			   struct carlfw *fw __unused)
+
+{
+	const struct carl9170fw_last_desc *last __unused = (const void *) head;
+
+	/* Nothing here */
+}
+
+#define ADD_HANDLER(_magic, _func)				\
+	{							\
+	  .magic = _magic##_MAGIC,				\
+	  .min_ver = CARL9170FW_## _magic##_DESC_CUR_VER,	\
+	  .func = _func,					\
+	  .size = CARL9170FW_## _magic##_DESC_SIZE,		\
+	}
+
+static const struct {
+	uint8_t magic[4];
+	uint8_t min_ver;
+	void (*func)(const struct carl9170fw_desc_head *, struct carlfw *);
+	uint16_t size;
+} known_magics[] = {
+	ADD_HANDLER(OTUS, show_otus_desc),
+	ADD_HANDLER(TXSQ, show_txsq_desc),
+	ADD_HANDLER(MOTD, show_motd_desc),
+	ADD_HANDLER(DBG, show_dbg_desc),
+	ADD_HANDLER(FIX, show_fix_desc),
+	ADD_HANDLER(CHK, show_chk_desc),
+	ADD_HANDLER(WOL, show_wol_desc),
+	ADD_HANDLER(LAST, show_last_desc),
+};
+
+static const uint8_t otus_magic[4] = { OTUS_MAGIC };
+
+static void show_desc_head(struct carl9170fw_desc_head *head)
+{
+#define P(c) (isprint(c) ? c :  ' ')
+
+	fprintf(stdout, ">\t%c%c%c%c Descriptor: size:%d, compatible:%d, "
+			"version:%d\n",
+		P(head->magic[0]), P(head->magic[1]), P(head->magic[2]),
+		P(head->magic[3]), le16_to_cpu(head->length), head->min_ver,
+		head->cur_ver);
+}
+
+static void fwinfo_info(void)
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\tfwinfo FW-FILE\n");
+
+	fprintf(stderr, "\nDescription:\n");
+	fprintf(stderr, "\tDisplay firmware descriptors information in "
+			"a human readable form.\n");
+
+	fprintf(stderr, "\nParameteres:\n");
+	fprintf(stderr, "\t 'FW-FILE'	= firmware file/base-name\n\n");
+}
+
+int main(int argc, char *args[])
+{
+	struct carlfw *fw = NULL;
+	struct carl9170fw_desc_head *fw_desc;
+	unsigned int i;
+	int err = 0;
+	size_t len;
+
+	if (argc != 2) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	fw = carlfw_load(args[1]);
+	if (IS_ERR_OR_NULL(fw)) {
+		err = PTR_ERR(fw);
+		fprintf(stderr, "Failed to open firmware \"%s\" (%d).\n",
+			args[1], err);
+		goto out;
+	}
+
+	carlfw_get_fw(fw, &len);
+	fprintf(stdout, "General Firmware Statistics:\n");
+	fprintf(stdout, "\tFirmware file size: %u Bytes\n", (unsigned int)len);
+	fprintf(stdout, "\t%d Descriptors in %d Bytes\n",
+		carlfw_get_descs_num(fw), carlfw_get_descs_size(fw));
+
+	fw_desc = NULL;
+	fprintf(stdout, "\nDetailed Descriptor Description:\n");
+	while ((fw_desc = carlfw_desc_next(fw, fw_desc))) {
+		show_desc_head(fw_desc);
+
+		for (i = 0; i < ARRAY_SIZE(known_magics); i++) {
+			if (carl9170fw_desc_cmp(fw_desc, known_magics[i].magic,
+			    known_magics[i].size, known_magics[i].min_ver)) {
+				known_magics[i].func(fw_desc, fw);
+				break;
+			}
+		}
+
+		if (i == ARRAY_SIZE(known_magics))
+			fprintf(stderr, "Unknown Descriptor.\n");
+
+		fprintf(stdout, "\n");
+	}
+
+out:
+	switch (err) {
+	case 0:
+		break;
+
+	case -EINVAL:
+		fwinfo_info();
+		break;
+
+	default:
+		fprintf(stderr, "%s\n", strerror(-err));
+		break;
+	}
+
+	carlfw_release(fw);
+	return err ? EXIT_FAILURE : EXIT_SUCCESS;
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/miniboot.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/miniboot.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2010-2011 Christian Lamparter <chunkeey at 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 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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "carlfw.h"
+
+#include "compiler.h"
+
+static void mini_help(void)
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\tminiboot ACTION FW-FILE [MB-FILE]\n");
+
+	fprintf(stderr, "\nDescription:\n");
+	fprintf(stderr, "\tFirmware concatenation utility.\n");
+
+	fprintf(stderr, "\nParameteres:\n");
+	fprintf(stderr, "\t'ACTION'	= [a|d]\n");
+	fprintf(stderr, "\t | 'a'	= Add miniboot firmware.\n");
+	fprintf(stderr, "\t * 'd'	= remove miniboot firmware.\n");
+	fprintf(stderr, "\t'FW-FILE'	= destination for the package.\n");
+	fprintf(stderr, "\t'MB-FILE'	= extra firmware image.\n");
+}
+
+static int add_mini(struct carlfw *fw, const char *mini)
+{
+	struct stat file_stat;
+	struct carl9170fw_otus_desc *otus_desc = NULL;
+	FILE *m = NULL;
+	char *buf = NULL;
+	size_t extra;
+	int err;
+
+	m = fopen(mini, "r");
+	if (m == NULL) {
+		fprintf(stderr, "Failed to open file %s (%d).\n",
+			mini, errno);
+		err = -errno;
+		goto fail;
+	}
+
+	err = fstat(fileno(m), &file_stat);
+	if (err) {
+		fprintf(stderr, "Failed to query file infos from "
+				"\"%s\" (%d).\n", mini, errno);
+		err = -errno;
+		goto fail;
+	}
+	extra = file_stat.st_size;
+
+	otus_desc = carlfw_find_desc(fw, (uint8_t *) OTUS_MAGIC,
+				     sizeof(*otus_desc),
+				     CARL9170FW_OTUS_DESC_CUR_VER);
+	if (!otus_desc) {
+		fprintf(stderr, "No OTUS descriptor found\n");
+		goto fail;
+	}
+
+	if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_MINIBOOT)) {
+		fprintf(stderr, "Firmware has already a miniboot image.\n");
+		goto fail;
+	}
+
+	otus_desc->feature_set |= cpu_to_le32(BIT(CARL9170FW_MINIBOOT));
+	otus_desc->miniboot_size = cpu_to_le16(extra);
+
+	buf = carlfw_mod_headroom(fw, extra);
+	if (IS_ERR_OR_NULL(buf)) {
+		fprintf(stderr, "Unable to add miniboot image.\n");
+		goto fail;
+	}
+
+	err = fread(buf, extra, 1, m);
+	if (err != 1) {
+		fprintf(stderr, "Unable to load miniboot.\n");
+		goto fail;
+	}
+
+	carlfw_store(fw);
+	fclose(m);
+
+	return 0;
+
+fail:
+	if (m)
+		fclose(m);
+
+	return err;
+}
+
+static int del_mini(struct carlfw *fw)
+{
+	struct carl9170fw_otus_desc *otus_desc = NULL;
+	void *buf;
+	int cut;
+
+	otus_desc = carlfw_find_desc(fw, (uint8_t *) OTUS_MAGIC,
+				     sizeof(*otus_desc),
+				     CARL9170FW_OTUS_DESC_CUR_VER);
+	if (!otus_desc) {
+		fprintf(stderr, "Firmware is not for USB devices.\n");
+		return -ENODATA;
+	}
+
+	if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_MINIBOOT)) {
+		fprintf(stderr, "Firmware has no miniboot image.\n");
+		return -EINVAL;
+	}
+
+	cut = le16_to_cpu(otus_desc->miniboot_size);
+
+	buf = carlfw_mod_headroom(fw, -cut);
+	if (IS_ERR_OR_NULL(buf)) {
+		fprintf(stderr, "Unable to remove miniboot.\n");
+		return PTR_ERR(buf);
+	}
+
+	otus_desc->feature_set &= cpu_to_le32(~BIT(CARL9170FW_MINIBOOT));
+	otus_desc->miniboot_size = cpu_to_le16(0);
+
+	carlfw_store(fw);
+	return 0;
+}
+
+int main(int argc, char *args[])
+{
+	struct carlfw *fw = NULL;
+	int err;
+
+	if (argc < 3 || argc > 4) {
+		err = -EINVAL;
+		goto err_param;
+	}
+
+	switch (args[1][0]) {
+	case 'a':
+		if (argc != 4)
+			goto err_param;
+
+		fw = carlfw_load(args[2]);
+		if (IS_ERR_OR_NULL(fw)) {
+			err = PTR_ERR(fw);
+			goto err_out;
+		}
+
+		err = add_mini(fw, args[3]);
+		break;
+	case 'd':
+		if (argc != 3)
+			goto err_param;
+
+		fw = carlfw_load(args[2]);
+		if (IS_ERR_OR_NULL(fw)) {
+			err = PTR_ERR(fw);
+			goto err_out;
+		}
+
+		err = del_mini(fw);
+		break;
+
+	default:
+		goto err_param;
+		break;
+	}
+
+	carlfw_release(fw);
+	return EXIT_SUCCESS;
+
+err_out:
+	carlfw_release(fw);
+	fprintf(stderr, "miniboot action failed (%d).\n", err);
+	return EXIT_FAILURE;
+
+err_param:
+	carlfw_release(fw);
+	mini_help();
+	return EXIT_FAILURE;
+}

Added: dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/wol.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/firmware-free/linux-free/carl9170fw/tools/src/wol.c	Mon Jan 14 11:38:44 2013	(r19729)
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2011, Christian Lamparter <chunkeey at 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 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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <linux/types.h>
+#include <linux/if_ether.h>	/* ETH_P_ALL */
+#include <linux/if_packet.h>	/* sockaddr_ll */
+#include <linux/if.h>		/* IFNAMSIZ */
+
+static int monitor_init(const char *ifname)
+{
+	struct sockaddr_ll ll;
+	int monitor_sock;
+
+	memset(&ll, 0, sizeof(ll));
+	ll.sll_family = AF_PACKET;
+	ll.sll_ifindex = if_nametoindex(ifname);
+	if (ll.sll_ifindex == 0) {
+		fprintf(stderr, "Monitor interface '%s' does not exist\n", ifname);
+		return -1;
+	}
+
+	monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+	if (monitor_sock < 0) {
+		fprintf(stderr, "socket(PF_PACKET,SOCK_RAW): %s\n", strerror(errno));
+		return -1;
+	}
+
+	if (bind(monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
+		fprintf(stderr, "bind(PACKET): %s\n", strerror(errno));
+		close(monitor_sock);
+		return -1;
+	}
+
+	return monitor_sock;
+}
+
+static int inject_frame(int s, const void *data, size_t len)
+{
+#define IEEE80211_RADIOTAP_F_FRAG       0x08
+	unsigned char rtap_hdr[] = {
+		0x00, 0x00, /* radiotap version */
+		0x0e, 0x00, /* radiotap length */
+		0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
+		IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
+		0x00,       /* padding */
+		0x00, 0x00, /* RX and TX flags to indicate that */
+		0x00, 0x00, /* this is the injected frame directly */
+	};
+	struct iovec iov[2] = {
+		{
+			.iov_base = &rtap_hdr,
+			.iov_len = sizeof(rtap_hdr),
+		},
+		{
+			.iov_base = (void *) data,
+			.iov_len = len,
+		}
+	};
+	struct msghdr msg = {
+		.msg_name = NULL,
+		.msg_namelen = 0,
+		.msg_iov = iov,
+		.msg_iovlen = 2,
+		.msg_control = NULL,
+		.msg_controllen = 0,
+		.msg_flags = 0,
+	};
+	int ret;
+
+	ret = sendmsg(s, &msg, 0);
+	if (ret < 0)
+		perror("sendmsg");
+	return ret;
+}
+
+static unsigned char wol_magic_tmpl[30 + 6 + 16 * 6] = {
+	0x08, 0x00, 0x00, 0x00,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* RA */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* TA */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* SA */
+	0x00, 0x00,
+
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+static void prepare_wol(unsigned char *wol_magic, unsigned char *mac)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		memcpy(&wol_magic[30 + i * 6], mac, 6);
+}
+
+void usage(void)
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "\twol -i monitor_dev -m DE:VI:CE:MA:CW:OL -n #num -v\n");
+
+	fprintf(stderr, "\nDescription:\n");
+	fprintf(stderr, "\tThis utility generates a WOL packet for the"
+			"given [MAC] address and tries to injects"
+			"it into [monitor_dev]\n");
+
+	exit(EXIT_FAILURE);
+}
+
+#define MAC_STR "%2X:%2X:%2X:%2X:%2X:%2X"
+
+#define M(a, i) ((unsigned int *)&a[i])
+#define MAC_ARG(a) M(a, 0), M(a, 1), M(a, 2), M(a, 3), M(a, 4), M(a, 5)
+
+#define M2(a, i) (a[i])
+#define MAC_ARG2(a) M2(a, 0), M2(a, 1), M2(a, 2), M2(a, 3), M2(a, 4), M2(a, 5)
+
+int main(int argc, char **args)
+{
+	int sock, err = 0, opt, num = 10;
+	unsigned char mac[ETH_ALEN];
+	char dev_name[IFNAMSIZ + 1] = { 0 };
+	bool has_mac = false, has_dev = false, verbose = false;
+
+	while ((opt = getopt(argc, args, "m:i:n:v")) != -EXIT_FAILURE) {
+		switch (opt) {
+		case 'i':
+			has_dev = true;
+			strncpy(dev_name, optarg, IFNAMSIZ);
+			break;
+		case 'm':
+			has_mac = true;
+			err = sscanf(optarg, MAC_STR, MAC_ARG(mac)) != 6;
+			if (err)
+				fprintf(stderr, "invalid MAC: \"%s\"\n", optarg);
+			break;
+
+		case 'n':
+			err = sscanf(optarg, "%d", &num) != 1;
+			err |= num < 1 | num > 1000;
+			if (err)
+				fprintf(stderr, "invalid tries: \"%s\"\n", optarg);
+			break;
+
+		case 'v':
+			verbose = true;
+			break;
+
+		default:
+			err = -EINVAL;
+			break;
+		}
+
+		if (err)
+			break;
+	}
+
+	if (!has_mac || !has_dev || err)
+		usage();
+
+	if (verbose)
+		fprintf(stdout, "Opening monitor injection interface [%s].\n", dev_name);
+
+	sock = monitor_init(dev_name);
+	if (sock < 0)
+		return EXIT_FAILURE;
+
+	if (verbose)
+		fprintf(stdout, "Generating %d WOL packet for ["MAC_STR"].\n", num, MAC_ARG2(mac));
+
+	prepare_wol(wol_magic_tmpl, mac);
+
+	while (num--) {
+		err = inject_frame(sock, wol_magic_tmpl, sizeof(wol_magic_tmpl));
+		if (err < 0) {
+			fprintf(stderr, "failed to send WOL packet.\n");
+			break;
+		} else if (verbose) {
+			fprintf(stdout, "WOL packet sent.\n");
+		}
+	}
+
+	close(sock);
+	if (err < 0)
+		return EXIT_FAILURE;
+
+	return 0;
+}

Modified: dists/trunk/firmware-free/linux-free/defines
==============================================================================
--- dists/trunk/firmware-free/linux-free/defines	Mon Jan 14 11:32:23 2013	(r19728)
+++ dists/trunk/firmware-free/linux-free/defines	Mon Jan 14 11:38:44 2013	(r19729)
@@ -9,6 +9,7 @@
  and has been moved to the firmware-linux-nonfree package.
 files:
  av7110/bootcode.bin
+ carl9170-1.fw
  cis/3CCFEM556.cis
  cis/3CXEM556.cis
  cis/COMpad2.cis
@@ -38,6 +39,9 @@
 [av7110/bootcode.bin_base]
 desc: AV7110 DVB card firmware
 
+[carl9170-1.fw_base]
+desc: Atheros AR9170 free firmware for use with carl9170 (Closes: #635840)
+
 [cis/3CCFEM556.cis_base]
 desc: 3Com Megahertz 3CCFEM556 CIS fix
 



More information about the Kernel-svn-changes mailing list