]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
Staging: add wlan-ng prism2 usb driver
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 2 Oct 2008 18:29:28 +0000 (11:29 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 10 Oct 2008 22:31:10 +0000 (15:31 -0700)
This adds the wlan-ng prism2 USB driver to the drivers/staging tree.

The code was originally written by the linux-wlan-ng team, patched by
some Novell engineers to properly work on newer kernels, and then hacked
into place in order to get it to build properly in a single subdirectory
within the kernel tree by me.

It supports a wide range of older USB prism2 devices, and contains a
80211 stack to support this single driver.

Cc: Christian Zoz <zoz@suse.de>
Cc: Andreas Gruenbacher <agruen@suse.de>
Cc: linux-wireless <linux-wireless@vger.kernel.org>
Cc: John Linville <linville@tuxdriver.com>
Cc: Helmut Schaa <helmut.schaa@googlemail.com>
Cc: linux-wlan-ng <solomon@linux-wlan.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
37 files changed:
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/wlan-ng/Kconfig [new file with mode: 0644]
drivers/staging/wlan-ng/Makefile [new file with mode: 0644]
drivers/staging/wlan-ng/README [new file with mode: 0644]
drivers/staging/wlan-ng/hfa384x.c [new file with mode: 0644]
drivers/staging/wlan-ng/hfa384x.h [new file with mode: 0644]
drivers/staging/wlan-ng/hfa384x_usb.c [new file with mode: 0644]
drivers/staging/wlan-ng/p80211conv.c [new file with mode: 0644]
drivers/staging/wlan-ng/p80211conv.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211hdr.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211ioctl.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211meta.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211metadef.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211metamib.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211metamsg.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211metastruct.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211mgmt.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211mod.c [new file with mode: 0644]
drivers/staging/wlan-ng/p80211msg.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211netdev.c [new file with mode: 0644]
drivers/staging/wlan-ng/p80211netdev.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211req.c [new file with mode: 0644]
drivers/staging/wlan-ng/p80211req.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211types.h [new file with mode: 0644]
drivers/staging/wlan-ng/p80211wep.c [new file with mode: 0644]
drivers/staging/wlan-ng/p80211wext.c [new file with mode: 0644]
drivers/staging/wlan-ng/prism2_cs.c [new file with mode: 0644]
drivers/staging/wlan-ng/prism2_pci.c [new file with mode: 0644]
drivers/staging/wlan-ng/prism2_plx.c [new file with mode: 0644]
drivers/staging/wlan-ng/prism2_usb.c [new file with mode: 0644]
drivers/staging/wlan-ng/prism2mgmt.c [new file with mode: 0644]
drivers/staging/wlan-ng/prism2mgmt.h [new file with mode: 0644]
drivers/staging/wlan-ng/prism2mib.c [new file with mode: 0644]
drivers/staging/wlan-ng/prism2sta.c [new file with mode: 0644]
drivers/staging/wlan-ng/version.h [new file with mode: 0644]
drivers/staging/wlan-ng/wlan_compat.h [new file with mode: 0644]

index fdbdf84e3077971e9afa96200ee13c933e58e30a..762b471fdeda3d4f52fbd4f7df1799c6c8223fb4 100644 (file)
@@ -37,4 +37,6 @@ source "drivers/staging/usbip/Kconfig"
 
 source "drivers/staging/winbond/Kconfig"
 
+source "drivers/staging/wlan-ng/Kconfig"
+
 endif # STAGING
index 9b576c91b15ef17736e024a323c9fa6cfa103c1c..574198479d665f6cc0804058c2a2facf305b4ea0 100644 (file)
@@ -7,3 +7,4 @@ obj-$(CONFIG_ME4000)            += me4000/
 obj-$(CONFIG_VIDEO_GO7007)     += go7007/
 obj-$(CONFIG_USB_IP_COMMON)    += usbip/
 obj-$(CONFIG_W35UND)           += winbond/
+obj-$(CONFIG_PRISM2_USB)       += wlan-ng/
diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig
new file mode 100644 (file)
index 0000000..10b1f0f
--- /dev/null
@@ -0,0 +1,10 @@
+config PRISM2_USB
+       tristate "Prism2.5 USB driver"
+       depends on USB
+       default n
+       ---help---
+         This is the wlan-ng prism 2.5 USB driver for a wide range of
+         old USB wireless devices.
+
+         To compile this driver as a module, choose M here: the module
+         will be called prism2_usb.
diff --git a/drivers/staging/wlan-ng/Makefile b/drivers/staging/wlan-ng/Makefile
new file mode 100644 (file)
index 0000000..777b511
--- /dev/null
@@ -0,0 +1,9 @@
+obj-$(CONFIG_PRISM2_USB) += prism2_usb.o
+obj-$(CONFIG_PRISM2_USB) += p80211.o
+
+p80211-objs := p80211mod.o \
+               p80211conv.o \
+               p80211req.o \
+               p80211wep.o \
+               p80211wext.o \
+               p80211netdev.o
diff --git a/drivers/staging/wlan-ng/README b/drivers/staging/wlan-ng/README
new file mode 100644 (file)
index 0000000..f50e4eb
--- /dev/null
@@ -0,0 +1,8 @@
+TODO:
+       - checkpatch.pl cleanups
+       - sparse warnings
+       - Lindent cleanups
+       - move to use the in-kernel wireless stack
+       - possible enable the pcmcia and pci portions of the driver
+
+Please send all patches to Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/wlan-ng/hfa384x.c b/drivers/staging/wlan-ng/hfa384x.c
new file mode 100644 (file)
index 0000000..04df3fd
--- /dev/null
@@ -0,0 +1,4018 @@
+/* src/prism2/driver/hfa384x.c
+*
+* Implements the functions of the Intersil hfa384x MAC
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file implements functions that correspond to the prism2/hfa384x
+* 802.11 MAC hardware and firmware host interface.
+*
+* The functions can be considered to represent several levels of
+* abstraction.  The lowest level functions are simply C-callable wrappers
+* around the register accesses.  The next higher level represents C-callable
+* prism2 API functions that match the Intersil documentation as closely
+* as is reasonable.  The next higher layer implements common sequences
+* of invokations of the API layer (e.g. write to bap, followed by cmd).
+*
+* Common sequences:
+* hfa384x_drvr_xxx     Highest level abstractions provided by the
+*                      hfa384x code.  They are driver defined wrappers
+*                      for common sequences.  These functions generally
+*                      use the services of the lower levels.
+*
+* hfa384x_drvr_xxxconfig  An example of the drvr level abstraction. These
+*                      functions are wrappers for the RID get/set
+*                      sequence. They  call copy_[to|from]_bap() and
+*                      cmd_access().   These functions operate on the
+*                      RIDs and buffers without validation.  The caller
+*                      is responsible for that.
+*
+* API wrapper functions:
+* hfa384x_cmd_xxx      functions that provide access to the f/w commands.
+*                      The function arguments correspond to each command
+*                      argument, even command arguments that get packed
+*                      into single registers.  These functions _just_
+*                      issue the command by setting the cmd/parm regs
+*                      & reading the status/resp regs.  Additional
+*                      activities required to fully use a command
+*                      (read/write from/to bap, get/set int status etc.)
+*                      are implemented separately.  Think of these as
+*                      C-callable prism2 commands.
+*
+* Lowest Layer Functions:
+* hfa384x_docmd_xxx    These functions implement the sequence required
+*                      to issue any prism2 command.  Primarily used by the
+*                      hfa384x_cmd_xxx functions.
+*
+* hfa384x_bap_xxx      BAP read/write access functions.
+*                      Note: we usually use BAP0 for non-interrupt context
+*                       and BAP1 for interrupt context.
+*
+* hfa384x_dl_xxx       download related functions.
+*
+* Driver State Issues:
+* Note that there are two pairs of functions that manage the
+* 'initialized' and 'running' states of the hw/MAC combo.  The four
+* functions are create(), destroy(), start(), and stop().  create()
+* sets up the data structures required to support the hfa384x_*
+* functions and destroy() cleans them up.  The start() function gets
+* the actual hardware running and enables the interrupts.  The stop()
+* function shuts the hardware down.  The sequence should be:
+* create()
+*  .
+*  .  Self contained test routines can run here, particularly
+*  .  corereset() and test_hostif().
+*  .
+* start()
+*  .
+*  .  Do interesting things w/ the hardware
+*  .
+* stop()
+* destroy()
+*
+* Note that destroy() can be called without calling stop() first.
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+
+/* System Includes */
+#define WLAN_DBVAR     prism2_debug
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/timer.h>
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <linux/list.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include <linux/tqueue.h>
+#else
+#include <linux/workqueue.h>
+#endif
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
+#include <pcmcia/version.h>
+#endif
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/cisreg.h>
+#endif
+
+#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI))
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#endif
+
+#include "wlan_compat.h"
+
+// XXXX #define CMD_IRQ
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211req.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+static const UINT16 crc16tab[256] =
+{
+       0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
+       0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
+       0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
+       0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
+       0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
+       0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
+       0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
+       0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
+       0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+       0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
+       0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
+       0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
+       0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
+       0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
+       0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
+       0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
+       0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
+       0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+       0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
+       0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
+       0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
+       0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
+       0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
+       0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
+       0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
+       0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
+       0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+       0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
+       0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
+       0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
+       0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
+       0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
+};
+
+/*================================================================*/
+/* Local Macros */
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+extern int prism2_debug;
+
+/*================================================================*/
+/* Local Function Declarations */
+
+static void    hfa384x_int_dtim(wlandevice_t *wlandev);
+static void    hfa384x_int_infdrop(wlandevice_t *wlandev);
+
+static void     hfa384x_bap_tasklet(unsigned long data);
+
+static void    hfa384x_int_info(wlandevice_t *wlandev);
+static void    hfa384x_int_txexc(wlandevice_t *wlandev);
+static void    hfa384x_int_tx(wlandevice_t *wlandev);
+static void    hfa384x_int_rx(wlandevice_t *wlandev);
+
+#ifdef CMD_IRQ
+static void    hfa384x_int_cmd(wlandevice_t *wlandev);
+#endif
+static void    hfa384x_int_rxmonitor( wlandevice_t *wlandev,
+                       UINT16 rxfid, hfa384x_rx_frame_t *rxdesc);
+static void    hfa384x_int_alloc(wlandevice_t *wlandev);
+
+static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd);
+
+static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd);
+
+static UINT16
+hfa384x_mkcrc16(UINT8 *p, int len);
+
+int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
+                        void *buf, UINT len, void* buf2, UINT len2,
+                        void *buf3, UINT len3, void* buf4, UINT len4);
+
+/*================================================================*/
+/* Function Definitions */
+
+static UINT16
+txfid_queue_empty(hfa384x_t *hw)
+{
+       return (hw->txfid_head == hw->txfid_tail) ? 1 : 0;
+}
+
+static UINT16
+txfid_queue_remove(hfa384x_t *hw)
+{
+       UINT16 result= 0;
+
+       if (txfid_queue_empty(hw)) {
+               WLAN_LOG_DEBUG(3,"queue empty.\n");
+       } else {
+               result = hw->txfid_queue[hw->txfid_head];
+               hw->txfid_head = (hw->txfid_head + 1) % hw->txfid_N;
+       }
+
+       return (UINT16)result;
+}
+
+static INT16
+txfid_queue_add(hfa384x_t *hw, UINT16 val)
+{
+       INT16 result = 0;
+
+       if (hw->txfid_head == ((hw->txfid_tail + 1) % hw->txfid_N)) {
+               result = -1;
+               WLAN_LOG_DEBUG(3,"queue full.\n");
+       } else {
+               hw->txfid_queue[hw->txfid_tail] = val;
+               result = hw->txfid_tail;
+               hw->txfid_tail = (hw->txfid_tail + 1) % hw->txfid_N;
+       }
+
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_create
+*
+* Initializes the hfa384x_t data structure for use.  Note this
+* does _not_ intialize the actual hardware, just the data structures
+* we use to keep track of its state.
+*
+* Arguments:
+*      hw              device structure
+*      irq             device irq number
+*      iobase          [pcmcia] i/o base address for register access
+*                      [pci] zero
+*                      [plx] i/o base address for register access
+*      membase         [pcmcia] pcmcia_cs "link" pointer
+*                      [pci] memory base address for register access
+*                      [plx] memory base address for card attribute memory
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+void hfa384x_create(hfa384x_t *hw, UINT irq, UINT32 iobase,
+                   UINT8 __iomem *membase)
+{
+       DBFENTER;
+       memset(hw, 0, sizeof(hfa384x_t));
+       hw->irq = irq;
+       hw->iobase = iobase;
+       hw->membase = membase;
+       spin_lock_init(&(hw->cmdlock));
+
+       /* BAP setup */
+       spin_lock_init(&(hw->baplock));
+       tasklet_init(&hw->bap_tasklet,
+                    hfa384x_bap_tasklet,
+                    (unsigned long) hw);
+
+       init_waitqueue_head(&hw->cmdq);
+       sema_init(&hw->infofid_sem, 1);
+
+        hw->txfid_head = 0;
+        hw->txfid_tail = 0;
+        hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX;
+        memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue));
+
+       hw->isram16 = 1;
+
+       /* Init the auth queue head */
+       skb_queue_head_init(&hw->authq);
+
+       INIT_WORK2(&hw->link_bh, prism2sta_processing_defer);
+
+        INIT_WORK2(&hw->commsqual_bh, prism2sta_commsqual_defer);
+
+       init_timer(&hw->commsqual_timer);
+       hw->commsqual_timer.data = (unsigned long) hw;
+       hw->commsqual_timer.function = prism2sta_commsqual_timer;
+
+       hw->link_status = HFA384x_LINK_NOTCONNECTED;
+       hw->state = HFA384x_STATE_INIT;
+
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_destroy
+*
+* Partner to hfa384x_create().  This function cleans up the hw
+* structure so that it can be freed by the caller using a simple
+* kfree.  Currently, this function is just a placeholder.  If, at some
+* point in the future, an hw in the 'shutdown' state requires a 'deep'
+* kfree, this is where it should be done.  Note that if this function
+* is called on a _running_ hw structure, the drvr_stop() function is
+* called.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      nothing, this function is not allowed to fail.
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+void
+hfa384x_destroy( hfa384x_t *hw)
+{
+       struct sk_buff *skb;
+
+       DBFENTER;
+
+       if ( hw->state == HFA384x_STATE_RUNNING ) {
+               hfa384x_drvr_stop(hw);
+       }
+       hw->state = HFA384x_STATE_PREINIT;
+
+       if (hw->scanresults) {
+               kfree(hw->scanresults);
+               hw->scanresults = NULL;
+       }
+
+        /* Now to clean out the auth queue */
+        while ( (skb = skb_dequeue(&hw->authq)) ) {
+                dev_kfree_skb(skb);
+        }
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_getconfig
+*
+* Performs the sequence necessary to read a config/info item.
+*
+* Arguments:
+*      hw              device structure
+*      rid             config/info record id (host order)
+*      buf             host side record buffer.  Upon return it will
+*                      contain the body portion of the record (minus the
+*                      RID and len).
+*      len             buffer length (in bytes, should match record length)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*      -ENODATA        length mismatch between argument and retrieved
+*                      record.
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
+{
+       int             result = 0;
+       DBFENTER;
+
+       result = hfa384x_cmd_access( hw, 0, rid, buf, len);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_setconfig
+*
+* Performs the sequence necessary to write a config/info item.
+*
+* Arguments:
+*      hw              device structure
+*      rid             config/info record id (in host order)
+*      buf             host side record buffer
+*      len             buffer length (in bytes)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
+{
+       int             result = 0;
+       DBFENTER;
+
+       result = hfa384x_cmd_access( hw, 1, rid, buf, len);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_readpda
+*
+* Performs the sequence to read the PDA space.  Note there is no
+* drvr_writepda() function.  Writing a PDA is
+* generally implemented by a calling component via calls to
+* cmd_download and writing to the flash download buffer via the
+* aux regs.
+*
+* Arguments:
+*      hw              device structure
+*      buf             buffer to store PDA in
+*      len             buffer length
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*      -ETIMEOUT       timout waiting for the cmd regs to become
+*                      available, or waiting for the control reg
+*                      to indicate the Aux port is enabled.
+*      -ENODATA        the buffer does NOT contain a valid PDA.
+*                      Either the card PDA is bad, or the auxdata
+*                      reads are giving us garbage.
+
+*
+* Side effects:
+*
+* Call context:
+*      process thread or non-card interrupt.
+----------------------------------------------------------------*/
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len)
+{
+       int             result = 0;
+       UINT16          *pda = buf;
+       int             pdaok = 0;
+       int             morepdrs = 1;
+       int             currpdr = 0;    /* word offset of the current pdr */
+       int             i;
+       UINT16          pdrlen;         /* pdr length in bytes, host order */
+       UINT16          pdrcode;        /* pdr code, host order */
+       UINT16          crc;
+       UINT16          pdacrc;
+       struct pdaloc {
+               UINT32  cardaddr;
+               UINT16  auxctl;
+       } pdaloc[] =
+       {
+               { HFA3842_PDA_BASE,             HFA384x_AUX_CTL_NV},
+               { HFA3842_PDA_BASE,             HFA384x_AUX_CTL_EXTDS},
+               { HFA3841_PDA_BASE,             HFA384x_AUX_CTL_NV},
+               { HFA3841_PDA_BASE,             HFA384x_AUX_CTL_EXTDS},
+               { HFA3841_PDA_BOGUS_BASE,       HFA384x_AUX_CTL_NV}
+       };
+
+       DBFENTER;
+       /* Check for aux available */
+       result = hfa384x_cmd_aux_enable(hw, 0);
+       if ( result ) {
+               WLAN_LOG_DEBUG(1,"aux_enable() failed. result=%d\n", result);
+               goto failed;
+       }
+
+       /* Read the pda from each known address.  */
+       for ( i = 0; i < (sizeof(pdaloc)/sizeof(pdaloc[0])); i++) {
+               WLAN_LOG_DEBUG( 3, "Checking PDA@(0x%08x,%s)\n",
+                       pdaloc[i].cardaddr,
+                       pdaloc[i].auxctl == HFA384x_AUX_CTL_NV ?
+                       "CTL_NV" : "CTL_EXTDS");
+
+               /* Copy bufsize bytes from our current pdaloc */
+               hfa384x_copy_from_aux(hw,
+                       pdaloc[i].cardaddr,
+                       pdaloc[i].auxctl,
+                       buf,
+                       len);
+
+               /* Test for garbage */
+               /* Traverse the PDR list Looking for PDA-END */
+               pdaok = 1;      /* intially assume good */
+               morepdrs = 1;
+               currpdr = 0;
+               while ( pdaok && morepdrs ) {
+                       pdrlen = hfa384x2host_16(pda[currpdr]) * 2;
+                       pdrcode = hfa384x2host_16(pda[currpdr+1]);
+
+                       /* Test for completion at END record */
+                       if ( pdrcode == HFA384x_PDR_END_OF_PDA ) {
+                               if ( pdrlen == 4 ) {
+                                       morepdrs = 0;
+                                       /* Calculate CRC-16 and compare to PDA
+                                        * value.  Note the addition of 2 words
+                                        * for ENDREC.len and ENDREC.code
+                                        * fields.
+                                        */
+                                       crc = hfa384x_mkcrc16( (UINT8*)pda,
+                                               (currpdr + 2) * sizeof(UINT16));
+                                       pdacrc =hfa384x2host_16(pda[currpdr+2]);
+                                       if ( crc != pdacrc ) {
+                                               WLAN_LOG_DEBUG(3,
+                                               "PDA crc failed:"
+                                               "calc_crc=0x%04x,"
+                                               "pdr_crc=0x%04x.\n",
+                                               crc, pdacrc);
+                                               pdaok = 0;
+                                       }
+                               } else {
+                                       WLAN_LOG_DEBUG(3,
+                                       "END record detected w/ "
+                                       "len(%d) != 2, assuming bad PDA\n",
+                                       pdrlen);
+                                       pdaok = 0;
+
+                               }
+                               break;
+                       }
+
+                       /* Test the record length */
+                       if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
+                               WLAN_LOG_DEBUG(3,
+                                       "pdrlen for address #%d "
+                                       "at %#x:%#x:%d\n",
+                                       i, pdaloc[i].cardaddr,
+                                       pdaloc[i].auxctl, pdrlen);
+                               WLAN_LOG_DEBUG(3,"pdrlen invalid=%d\n",
+                                       pdrlen);
+                               pdaok = 0;
+                               break;
+                       }
+
+                       /* Move to the next pdr */
+                       if ( morepdrs ) {
+                               /* note the access to pda[], we need words */
+                               currpdr += hfa384x2host_16(pda[currpdr]) + 1;
+                               if (currpdr*sizeof(UINT16) > len) {
+                                       WLAN_LOG_DEBUG(3,
+                                       "Didn't find PDA_END in buffer, "
+                                       "trying next location.\n");
+                                       pdaok = 0;
+                                       break;
+                               }
+                       }
+               }
+               if ( pdaok ) {
+                       WLAN_LOG_INFO(
+                               "PDA Read from 0x%08x in %s space.\n",
+                               pdaloc[i].cardaddr,
+                               pdaloc[i].auxctl == 0 ? "EXTDS" :
+                               pdaloc[i].auxctl == 1 ? "NV" :
+                               pdaloc[i].auxctl == 2 ? "PHY" :
+                               pdaloc[i].auxctl == 3 ? "ICSRAM" :
+                               "<bogus auxctl>");
+                       break;
+               }
+       }
+       result = pdaok ? 0 : -ENODATA;
+
+       if ( result ) {
+               WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n");
+       }
+
+       hfa384x_cmd_aux_disable(hw);
+failed:
+       DBFEXIT;
+       return result;
+}
+
+
+
+/*----------------------------------------------------------------
+* mkpda_crc
+*
+* Calculates the CRC16 for the given PDA and inserts the value
+* into the end record.
+*
+* Arguments:
+*      pda     ptr to the PDA data structure.
+*
+* Returns:
+*      0       - success
+*      ~0      - failure (probably an errno)
+----------------------------------------------------------------*/
+static UINT16
+hfa384x_mkcrc16(UINT8 *p, int len)
+{
+       UINT16  crc = 0;
+       UINT8   *lim = p + len;
+
+       while (p < lim) {
+               crc = (crc >> 8 ) ^ crc16tab[(crc & 0xff) ^ *p++];
+       }
+
+       return crc;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_enable
+*
+* Begins the ram download state.  Checks to see that we're not
+* already in a download state and that a port isn't enabled.
+* Sets the download state and calls cmd_download with the
+* ENABLE_VOLATILE subcommand and the exeaddr argument.
+*
+* Arguments:
+*      hw              device structure
+*      exeaddr         the card execution address that will be
+*                       jumped to when ramdl_disable() is called
+*                      (host order).
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr)
+{
+       int             result = 0;
+       UINT16          lowaddr;
+       UINT16          hiaddr;
+       int             i;
+       DBFENTER;
+       /* Check that a port isn't active */
+       for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
+               if ( hw->port_enabled[i] ) {
+                       WLAN_LOG_DEBUG(1,"Can't download with a port enabled.\n");
+                       result = -EINVAL;
+                       goto done;
+               }
+       }
+
+       /* Check that we're not already in a download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+               WLAN_LOG_DEBUG(1,"Download state not disabled.\n");
+               result = -EINVAL;
+               goto done;
+       }
+
+       /* Are we supposed to go into genesis mode? */
+       if (exeaddr == 0x3f0000) {
+               UINT16 initseq[2] = { 0xe100, 0xffa1 };
+               UINT16 readbuf[2];
+               UINT8 hcr = 0x0f; /* Default to x16 SRAM */
+               hw->isram16 = 1;
+
+               WLAN_LOG_DEBUG(1, "Dropping into Genesis mode\n");
+
+               /* Issue card reset and enable aux port */
+               hfa384x_corereset(hw, prism2_reset_holdtime,
+                                 prism2_reset_settletime, 0);
+               hfa384x_cmd_aux_enable(hw, 1);
+
+               /* Genesis set */
+               hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+                                   initseq, sizeof(initseq));
+
+               hfa384x_corereset(hw, prism2_reset_holdtime,
+                                 prism2_reset_settletime, hcr);
+
+               /* Validate memory config */
+               hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+                                   initseq, sizeof(initseq));
+               hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+                                   readbuf, sizeof(initseq));
+               WLAN_HEX_DUMP(3, "readback", readbuf, sizeof(readbuf));
+
+               if (memcmp(initseq, readbuf, sizeof(readbuf))) {
+                       hcr = 0x1f; /* x8 SRAM */
+                       hw->isram16 = 0;
+
+                       hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+                                           initseq, sizeof(initseq));
+                       hfa384x_corereset(hw, prism2_reset_holdtime,
+                                         prism2_reset_settletime, hcr);
+
+                       hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+                                           initseq, sizeof(initseq));
+                       hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+                                           readbuf, sizeof(initseq));
+                       WLAN_HEX_DUMP(2, "readback", readbuf, sizeof(readbuf));
+
+                       if (memcmp(initseq, readbuf, sizeof(readbuf))) {
+                               WLAN_LOG_ERROR("Genesis mode failed\n");
+                               result = -1;
+                               goto done;
+                       }
+               }
+
+               /* Now we're in genesis mode */
+               hw->dlstate = HFA384x_DLSTATE_GENESIS;
+               goto done;
+       }
+
+       /* Retrieve the buffer loc&size and timeout */
+       if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+                               &(hw->bufinfo), sizeof(hw->bufinfo))) ) {
+               goto done;
+       }
+       hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
+       hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
+       hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
+       if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+                               &(hw->dltimeout))) ) {
+               goto done;
+       }
+       hw->dltimeout = hfa384x2host_16(hw->dltimeout);
+
+       /* Enable the aux port */
+       if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {
+               WLAN_LOG_DEBUG(1,"Aux enable failed, result=%d.\n", result);
+               goto done;
+       }
+
+       /* Call the download(1,addr) function */
+       lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);
+       hiaddr =  HFA384x_ADDR_CMD_MKPAGE(exeaddr);
+
+       result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
+                       lowaddr, hiaddr, 0);
+       if ( result == 0) {
+               /* Set the download state */
+               hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
+       } else {
+               WLAN_LOG_DEBUG(1,"cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
+                               lowaddr,hiaddr, result);
+               /* Disable  the aux port */
+               hfa384x_cmd_aux_disable(hw);
+       }
+
+ done:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_disable
+*
+* Ends the ram download state.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
+{
+       DBFENTER;
+       /* Check that we're already in the download state */
+       if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) &&
+            ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) {
+               return -EINVAL;
+       }
+
+       if (hw->dlstate == HFA384x_DLSTATE_GENESIS) {
+               hfa384x_corereset(hw, prism2_reset_holdtime,
+                                 prism2_reset_settletime,
+                                 hw->isram16 ? 0x07: 0x17);
+               goto done;
+       }
+
+       /* Disable the aux port */
+       hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+
+ done:
+       hw->dlstate = HFA384x_DLSTATE_DISABLED;
+       hfa384x_cmd_aux_disable(hw);
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_write
+*
+* Performs a RAM download of a chunk of data. First checks to see
+* that we're in the RAM download state, then uses the aux functions
+* to 1) copy the data, 2) readback and compare.  The download
+* state is unaffected.  When all data has been written using
+* this function, call drvr_ramdl_disable() to end the download state
+* and restart the MAC.
+*
+* Arguments:
+*      hw              device structure
+*      daddr           Card address to write to. (host order)
+*      buf             Ptr to data to write.
+*      len             Length of data (host order).
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
+{
+       int             result = 0;
+       UINT8           *verbuf;
+       DBFENTER;
+       /* Check that we're in the ram download state */
+       if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) &&
+            ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) {
+               return -EINVAL;
+       }
+
+       WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr);
+#if 0
+WLAN_HEX_DUMP(1, "dldata", buf, len);
+#endif
+       /* Copy the data via the aux port */
+       hfa384x_copy_to_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, buf, len);
+
+       /* Create a buffer for the verify */
+       verbuf = kmalloc(len, GFP_KERNEL);
+       if (verbuf == NULL ) return 1;
+
+       /* Read back and compare */
+       hfa384x_copy_from_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, verbuf, len);
+
+       if ( memcmp(buf, verbuf, len) ) {
+               WLAN_LOG_DEBUG(1,"ramdl verify failed!\n");
+               result = -EINVAL;
+       }
+
+       kfree_s(verbuf, len);
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_enable
+*
+* Begins the flash download state.  Checks to see that we're not
+* already in a download state and that a port isn't enabled.
+* Sets the download state and retrieves the flash download
+* buffer location, buffer size, and timeout length.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
+{
+       int             result = 0;
+       int             i;
+
+       DBFENTER;
+       /* Check that a port isn't active */
+       for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
+               if ( hw->port_enabled[i] ) {
+                       WLAN_LOG_DEBUG(1,"called when port enabled.\n");
+                       return -EINVAL;
+               }
+       }
+
+       /* Check that we're not already in a download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+               return -EINVAL;
+       }
+
+       /* Retrieve the buffer loc&size and timeout */
+       if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+                               &(hw->bufinfo), sizeof(hw->bufinfo))) ) {
+               return result;
+       }
+       hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
+       hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
+       hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
+       if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+                               &(hw->dltimeout))) ) {
+               return result;
+       }
+       hw->dltimeout = hfa384x2host_16(hw->dltimeout);
+
+       /* Enable the aux port */
+       if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {
+               return result;
+       }
+
+       hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_disable
+*
+* Ends the flash download state.  Note that this will cause the MAC
+* firmware to restart.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
+{
+       DBFENTER;
+       /* Check that we're already in the download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+               return -EINVAL;
+       }
+
+       /* There isn't much we can do at this point, so I don't */
+       /*  bother  w/ the return value */
+       hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+       hw->dlstate = HFA384x_DLSTATE_DISABLED;
+
+       /* Disable the aux port */
+       hfa384x_cmd_aux_disable(hw);
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_write
+*
+* Performs a FLASH download of a chunk of data. First checks to see
+* that we're in the FLASH download state, then sets the download
+* mode, uses the aux functions to 1) copy the data to the flash
+* buffer, 2) sets the download 'write flash' mode, 3) readback and
+* compare.  Lather rinse, repeat as many times an necessary to get
+* all the given data into flash.
+* When all data has been written using this function (possibly
+* repeatedly), call drvr_flashdl_disable() to end the download state
+* and restart the MAC.
+*
+* Arguments:
+*      hw              device structure
+*      daddr           Card address to write to. (host order)
+*      buf             Ptr to data to write.
+*      len             Length of data (host order).
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
+{
+       int             result = 0;
+       UINT8           *verbuf;
+       UINT32          dlbufaddr;
+       UINT32          currlen;
+       UINT32          currdaddr;
+       UINT16          destlo;
+       UINT16          desthi;
+       int             nwrites;
+       int             i;
+
+       DBFENTER;
+       /* Check that we're in the flash download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+               return -EINVAL;
+       }
+
+       WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr);
+
+       /* Need a flat address for arithmetic */
+       dlbufaddr = HFA384x_ADDR_AUX_MKFLAT(
+                       hw->bufinfo.page,
+                       hw->bufinfo.offset);
+       verbuf = kmalloc(hw->bufinfo.len, GFP_KERNEL);
+
+#if 0
+WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);
+#endif
+       /* Figure out how many times to to the flash prog */
+       nwrites = len / hw->bufinfo.len;
+       nwrites += (len % hw->bufinfo.len) ? 1 : 0;
+
+       if ( verbuf == NULL ) {
+               WLAN_LOG_ERROR("Failed to allocate flash verify buffer\n");
+               return 1;
+       }
+       /* For each */
+       for ( i = 0; i < nwrites; i++) {
+               /* Get the dest address and len */
+               currlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
+                               hw->bufinfo.len :
+                               (len - (hw->bufinfo.len * i));
+               currdaddr = daddr + (hw->bufinfo.len * i);
+               destlo = HFA384x_ADDR_CMD_MKOFF(currdaddr);
+               desthi = HFA384x_ADDR_CMD_MKPAGE(currdaddr);
+               WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n", currlen, currdaddr);
+#if 0
+WLAN_HEX_DUMP(1, "dldata", buf+(hw->bufinfo.len*i), currlen);
+#endif
+               /* Set the download mode */
+               result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
+                               destlo, desthi, currlen);
+               if ( result ) {
+                       WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) "
+                               "cmd failed, result=%d. Aborting d/l\n",
+                               destlo, desthi, currlen, result);
+                       goto exit_proc;
+               }
+               /* copy the data to the flash buffer */
+               hfa384x_copy_to_aux(hw, dlbufaddr, HFA384x_AUX_CTL_EXTDS,
+                                       buf+(hw->bufinfo.len*i), currlen);
+               /* set the download 'write flash' mode */
+               result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NVWRITE, 0,0,0);
+               if ( result ) {
+                       WLAN_LOG_ERROR(
+                               "download(NVWRITE,lo=%x,hi=%x,len=%x) "
+                               "cmd failed, result=%d. Aborting d/l\n",
+                               destlo, desthi, currlen, result);
+                       goto exit_proc;
+               }
+               /* readback and compare, if fail...bail */
+               hfa384x_copy_from_aux(hw,
+                               currdaddr, HFA384x_AUX_CTL_NV,
+                               verbuf, currlen);
+
+               if ( memcmp(buf+(hw->bufinfo.len*i), verbuf, currlen) ) {
+                       return -EINVAL;
+               }
+       }
+
+exit_proc:
+         /* DOH! This kfree's for you Mark :-) My forehead hurts... */
+         kfree(verbuf);
+
+       /* Leave the firmware in the 'post-prog' mode.  flashdl_disable will */
+       /*  actually disable programming mode.  Remember, that will cause the */
+       /*  the firmware to effectively reset itself. */
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_initialize
+*
+* Issues the initialize command and sets the hw->state based
+* on the result.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_initialize(hfa384x_t *hw)
+{
+       int result = 0;
+       int i;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       /* we don't want to be interrupted during the reset */
+       hfa384x_setreg(hw, 0, HFA384x_INTEN);
+       hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
+
+       cmd.cmd = HFA384x_CMDCODE_INIT;
+       cmd.parm0 = 0;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       if ( result == 0 ) {
+               for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+                       hw->port_enabled[i] = 0;
+               }
+       }
+
+        hw->link_status = HFA384x_LINK_NOTCONNECTED;
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_commtallies
+*
+* Send a commtallies inquiry to the MAC.  Note that this is an async
+* call that will result in an info frame arriving sometime later.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      zero            success.
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_commtallies( hfa384x_t *hw )
+{
+       hfa384x_metacmd_t cmd;
+       int result;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMDCODE_INQ;
+       cmd.parm0 = HFA384x_IT_COMMTALLIES;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_enable
+*
+* Issues the enable command to enable communications on one of
+* the MACs 'ports'.  Only macport 0 is valid  for stations.
+* APs may also enable macports 1-6.  Only ports that are currently
+* disabled may be enabled.
+*
+* Arguments:
+*      hw              device structure
+*      macport         MAC port number
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport)
+{
+       int     result = 0;
+
+       DBFENTER;
+       if ((!hw->isap && macport != 0) ||
+           (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
+           (hw->port_enabled[macport]) ){
+               result = -EINVAL;
+       } else {
+               result = hfa384x_cmd_enable(hw, macport);
+               if ( result == 0 ) {
+                       hw->port_enabled[macport] = 1;
+               }
+       }
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_enable
+*
+* Issues the the enable command to enable communications on one of the
+* MACs 'ports'.
+*
+* Arguments:
+*      hw              device structure
+*      macport         MAC port number
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
+                 HFA384x_CMD_MACPORT_SET(macport);
+       cmd.parm0 = 0;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_disable
+*
+* Issues the disable command to stop communications on one of
+* the MACs 'ports'.  Only macport 0 is valid  for stations.
+* APs may also disable macports 1-6.  Only ports that have been
+* previously enabled may be disabled.
+*
+* Arguments:
+*      hw              device structure
+*      macport         MAC port number (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport)
+{
+       int     result = 0;
+
+       DBFENTER;
+       if ((!hw->isap && macport != 0) ||
+           (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
+           !(hw->port_enabled[macport]) ){
+               result = -EINVAL;
+       } else {
+               result = hfa384x_cmd_disable(hw, macport);
+               if ( result == 0 ) {
+                       hw->port_enabled[macport] = 0;
+               }
+       }
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_disable
+*
+* Issues the command to disable a port.
+*
+* Arguments:
+*      hw              device structure
+*      macport         MAC port number (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
+                 HFA384x_CMD_MACPORT_SET(macport);
+       cmd.parm0 = 0;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_diagnose
+*
+* Issues the diagnose command to test the: register interface,
+* MAC controller (including loopback), External RAM, Non-volatile
+* memory integrity, and synthesizers.  Following execution of this
+* command, MAC/firmware are in the 'initial state'.  Therefore,
+* the Initialize command should be issued after successful
+* completion of this command.  This function may only be called
+* when the MAC is in the 'communication disabled' state.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+#define DIAG_PATTERNA ((UINT16)0xaaaa)
+#define DIAG_PATTERNB ((UINT16)0x5555)
+
+int hfa384x_cmd_diagnose(hfa384x_t *hw)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DIAG);
+       cmd.parm0 = DIAG_PATTERNA;
+       cmd.parm1 = DIAG_PATTERNB;
+       cmd.parm2 = 0;
+
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_allocate
+*
+* Issues the allocate command instructing the firmware to allocate
+* a 'frame structure buffer' in MAC controller RAM.  This command
+* does not provide the result, it only initiates one of the f/w's
+* asynchronous processes to construct the buffer.  When the
+* allocation is complete, it will be indicated via the Alloc
+* bit in the EvStat register and the FID identifying the allocated
+* space will be available from the AllocFID register.  Some care
+* should be taken when waiting for the Alloc event.  If a Tx or
+* Notify command w/ Reclaim has been previously executed, it's
+* possible the first Alloc event after execution of this command
+* will be for the reclaimed buffer and not the one you asked for.
+* This case must be handled in the Alloc event handler.
+*
+* Arguments:
+*      hw              device structure
+*      len             allocation length, must be an even value
+*                      in the range [4-2400]. (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       if ( (len % 2) ||
+            len < HFA384x_CMD_ALLOC_LEN_MIN ||
+            len > HFA384x_CMD_ALLOC_LEN_MAX ) {
+               result = -EINVAL;
+       } else {
+               cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC);
+               cmd.parm0 = len;
+               cmd.parm1 = 0;
+               cmd.parm2 = 0;
+
+               spin_lock_bh(&hw->cmdlock);
+               result = hfa384x_docmd_wait(hw, &cmd);
+               spin_unlock_bh(&hw->cmdlock);
+       }
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_transmit
+*
+* Instructs the firmware to transmit a frame previously copied
+* to a given buffer.  This function returns immediately, the Tx
+* results are available via the Tx or TxExc events (if the frame
+* control bits are set).  The reclaim argument specifies if the
+* FID passed will be used by the f/w tx process or returned for
+* use w/ another transmit command.  If reclaim is set, expect an
+* Alloc event signalling the availibility of the FID for reuse.
+*
+* NOTE: hw->cmdlock MUST BE HELD before calling this function!
+*
+* Arguments:
+*      hw              device structure
+*      reclaim         [0|1] indicates whether the given FID will
+*                      be handed back (via Alloc event) for reuse.
+*                      (host order)
+*      qos             [0-3] Value to put in the QoS field of the
+*                      tx command, identifies a queue to place the
+*                      outgoing frame in.
+*                      (host order)
+*      fid             FID of buffer containing the frame that was
+*                      previously copied to MAC memory via the bap.
+*                      (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*      hw->resp0 will contain the FID being used by async tx
+*      process.  If reclaim==0, resp0 will be the same as the fid
+*      argument.  If reclaim==1, resp0 will be the different and
+*      is the value to watch for in the Tx|TxExc to indicate completion
+*      of the frame passed in fid.
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX) |
+               HFA384x_CMD_RECL_SET(reclaim) |
+               HFA384x_CMD_QOS_SET(qos);
+       cmd.parm0 = fid;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       result = hfa384x_docmd_wait(hw, &cmd);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_clearpersist
+*
+* Instructs the firmware to clear the persistence bit in a given
+* FID.  This has the effect of telling the firmware to drop the
+* persistent frame.  The FID must be one that was previously used
+* to transmit a PRST frame.
+*
+* Arguments:
+*      hw              device structure
+*      fid             FID of the persistent frame (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_CLRPRST);
+       cmd.parm0 = fid;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_notify
+*
+* Sends an info frame to the firmware to alter the behavior
+* of the f/w asynch processes.  Can only be called when the MAC
+* is in the enabled state.
+*
+* Arguments:
+*      hw              device structure
+*      reclaim         [0|1] indicates whether the given FID will
+*                      be handed back (via Alloc event) for reuse.
+*                      (host order)
+*      fid             FID of buffer containing the frame that was
+*                      previously copied to MAC memory via the bap.
+*                      (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*      hw->resp0 will contain the FID being used by async notify
+*      process.  If reclaim==0, resp0 will be the same as the fid
+*      argument.  If reclaim==1, resp0 will be the different.
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid,
+                      void *buf, UINT16 len)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) |
+               HFA384x_CMD_RECL_SET(reclaim);
+       cmd.parm0 = fid;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       spin_lock_bh(&hw->cmdlock);
+
+        /* Copy the record to FID */
+        result = hfa384x_copy_to_bap(hw, HFA384x_BAP_PROC, hw->infofid, 0, buf, len);
+        if ( result ) {
+                WLAN_LOG_DEBUG(1,
+                       "copy_to_bap(%04x, 0, %d) failed, result=0x%x\n",
+                        hw->infofid, len, result);
+               result = -EIO;
+                goto failed;
+        }
+
+       result = hfa384x_docmd_wait(hw, &cmd);
+
+ failed:
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+
+#if 0
+/*----------------------------------------------------------------
+* hfa384x_cmd_inquiry
+*
+* Requests an info frame from the firmware.  The info frame will
+* be delivered asynchronously via the Info event.
+*
+* Arguments:
+*      hw              device structure
+*      fid             FID of the info frame requested. (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+static int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ);
+       cmd.parm0 = fid;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+#endif
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_access
+*
+* Requests that a given record be copied to/from the record
+* buffer.  If we're writing from the record buffer, the contents
+* must previously have been written to the record buffer via the
+* bap.  If we're reading into the record buffer, the record can
+* be read out of the record buffer after this call.
+*
+* Arguments:
+*      hw              device structure
+*      write           [0|1] copy the record buffer to the given
+*                      configuration record. (host order)
+*      rid             RID of the record to read/write. (host order)
+*      buf             host side record buffer.  Upon return it will
+*                      contain the body portion of the record (minus the
+*                      RID and len).
+*      len             buffer length (in bytes, should match record length)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid,
+                      void* buf, UINT16 len)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+       hfa384x_rec_t   rec;
+
+       DBFENTER;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
+       /* This should NOT be called in interrupt context! */
+       if (in_irq()) {
+               WLAN_LOG_ERROR("Krap, in Interrupt context!");
+#ifdef WLAN_INCLUDE_DEBUG
+               BUG();
+#endif
+       }
+#endif
+       spin_lock_bh(&hw->cmdlock);
+
+       if (write) {
+               rec.rid = host2hfa384x_16(rid);
+               rec.reclen = host2hfa384x_16((len/2) + 1); /* note conversion to words, +1 for rid field */
+               /* write the record */
+               result = hfa384x_copy_to_bap4( hw, HFA384x_BAP_PROC, rid, 0,
+                                              &rec, sizeof(rec),
+                                              buf, len,
+                                              NULL, 0, NULL, 0);
+               if ( result ) {
+                       WLAN_LOG_DEBUG(3,"Failure writing record header+data\n");
+                       goto fail;
+               }
+
+       }
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ACCESS) |
+               HFA384x_CMD_WRITE_SET(write);
+       cmd.parm0 = rid;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       result = hfa384x_docmd_wait(hw, &cmd);
+       if ( result ) {
+               WLAN_LOG_ERROR("Call to hfa384x_docmd_wait failed (%d %d)\n",
+                               result, cmd.result.resp0);
+               goto fail;
+       }
+
+       if (!write) {
+               result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, 0, &rec, sizeof(rec));
+               if ( result ) {
+                       WLAN_LOG_DEBUG(3,"Call to hfa384x_copy_from_bap failed\n");
+                       goto fail;
+               }
+
+               /* Validate the record length */
+               if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) {  /* note body len calculation in bytes */
+                       WLAN_LOG_DEBUG(1, "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
+                                       rid, len, (hfa384x2host_16(rec.reclen)-1)*2);
+                       result = -ENODATA;
+                       goto fail;
+               }
+
+               result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, sizeof(rec), buf, len);
+
+       }
+
+ fail:
+       spin_unlock_bh(&hw->cmdlock);
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_monitor
+*
+* Enables the 'monitor mode' of the MAC.  Here's the description of
+* monitor mode that I've received thus far:
+*
+*  "The "monitor mode" of operation is that the MAC passes all
+*  frames for which the PLCP checks are correct. All received
+*  MPDUs are passed to the host with MAC Port = 7, with a
+*  receive status of good, FCS error, or undecryptable. Passing
+*  certain MPDUs is a violation of the 802.11 standard, but useful
+*  for a debugging tool."  Normal communication is not possible
+*  while monitor mode is enabled.
+*
+* Arguments:
+*      hw              device structure
+*      enable          a code (0x0b|0x0f) that enables/disables
+*                      monitor mode. (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
+               HFA384x_CMD_AINFO_SET(enable);
+       cmd.parm0 = 0;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_download
+*
+* Sets the controls for the MAC controller code/data download
+* process.  The arguments set the mode and address associated
+* with a download.  Note that the aux registers should be enabled
+* prior to setting one of the download enable modes.
+*
+* Arguments:
+*      hw              device structure
+*      mode            0 - Disable programming and begin code exec
+*                      1 - Enable volatile mem programming
+*                      2 - Enable non-volatile mem programming
+*                      3 - Program non-volatile section from NV download
+*                          buffer.
+*                      (host order)
+*      lowaddr
+*      highaddr        For mode 1, sets the high & low order bits of
+*                      the "destination address".  This address will be
+*                      the execution start address when download is
+*                      subsequently disabled.
+*                      For mode 2, sets the high & low order bits of
+*                      the destination in NV ram.
+*                      For modes 0 & 3, should be zero. (host order)
+*                      NOTE: these address args are in CMD format
+*      codelen         Length of the data to write in mode 2,
+*                      zero otherwise. (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr,
+                               UINT16 highaddr, UINT16 codelen)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) |
+               HFA384x_CMD_PROGMODE_SET(mode);
+       cmd.parm0 = lowaddr;
+       cmd.parm1 = highaddr;
+       cmd.parm2 = codelen;
+
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_dl_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_aux_enable
+*
+* Goes through the process of enabling the auxilary port.  This
+* is necessary prior to raw reads/writes to card data space.
+* Direct access to the card data space is only used for downloading
+* code and debugging.
+* Note that a call to this function is required before attempting
+* a download.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_aux_enable(hfa384x_t *hw, int force)
+{
+       int             result = -ETIMEDOUT;
+       unsigned long   flags;
+       UINT32          retries_remaining;
+       UINT16          reg;
+       UINT            auxen_mirror = hw->auxen;
+
+       DBFENTER;
+
+       /* Check for existing enable */
+       if ( hw->auxen ) {
+               hw->auxen++;
+               return 0;
+       }
+
+       /* acquire the lock */
+       spin_lock_irqsave( &(hw->cmdlock), flags);
+       /* wait for cmd register busy bit to clear */
+       retries_remaining = 100000;
+       do {
+               reg = hfa384x_getreg(hw, HFA384x_CMD);
+               udelay(10);
+       }
+       while (HFA384x_CMD_ISBUSY(reg) && --retries_remaining);
+       if (retries_remaining != 0) {
+               /* busy bit clear, it's OK to write to ParamX regs */
+               hfa384x_setreg(hw, HFA384x_AUXPW0,
+                       HFA384x_PARAM0);
+               hfa384x_setreg(hw, HFA384x_AUXPW1,
+                       HFA384x_PARAM1);
+               hfa384x_setreg(hw, HFA384x_AUXPW2,
+                       HFA384x_PARAM2);
+
+               /* Set the aux enable in the Control register */
+               hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DOENABLE,
+                       HFA384x_CONTROL);
+
+               /* Now wait for completion */
+               retries_remaining = 100000;
+               do {
+                       reg = hfa384x_getreg(hw, HFA384x_CONTROL);
+                       udelay(10);
+               }
+               while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISENABLED) &&
+                       --retries_remaining );
+               if (retries_remaining != 0) {
+                       result = 0;
+                       hw->auxen++;
+               }
+       }
+
+       /* Force it enabled even if the command failed, if told.. */
+       if ((hw->auxen == auxen_mirror) && force)
+               hw->auxen++;
+
+       spin_unlock_irqrestore( &(hw->cmdlock), flags);
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_aux_disable
+*
+* Goes through the process of disabling the auxilary port
+* enabled with aux_enable().
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_aux_disable(hfa384x_t *hw)
+{
+       int             result = -ETIMEDOUT;
+       unsigned long   timeout;
+       UINT16          reg = 0;
+
+       DBFENTER;
+
+       /* See if there's more than one enable */
+       if (hw->auxen) hw->auxen--;
+       if (hw->auxen) return 0;
+
+       /* Clear the aux enable in the Control register */
+       hfa384x_setreg(hw, 0, HFA384x_PARAM0);
+       hfa384x_setreg(hw, 0, HFA384x_PARAM1);
+       hfa384x_setreg(hw, 0, HFA384x_PARAM2);
+       hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DODISABLE,
+               HFA384x_CONTROL);
+
+       /* Now wait for completion */
+       timeout = jiffies + 1*HZ;
+       reg = hfa384x_getreg(hw, HFA384x_CONTROL);
+       while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISDISABLED) &&
+               time_before(jiffies,timeout) ){
+               udelay(10);
+               reg = hfa384x_getreg(hw, HFA384x_CONTROL);
+       }
+       if ((reg & (BIT14|BIT15)) == HFA384x_CONTROL_AUX_ISDISABLED ) {
+               result = 0;
+       }
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_low_level
+*
+* Write test commands to the card.  Some test commands don't make
+* sense without prior set-up.  For example, continous TX isn't very
+* useful until you set the channel.  That functionality should be
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+* -----------------------------------------------------------------*/
+int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+       int             result = 0;
+       DBFENTER;
+
+       /* Do i need a host2hfa... conversion ? */
+#if 0
+       printk(KERN_INFO "%#x %#x %#x %#x\n", cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2);
+#endif
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/* TODO: determine if these will ever be needed */
+#if 0
+int hfa384x_cmd_readmif(hfa384x_t *hw)
+{
+       DBFENTER;
+       DBFEXIT;
+       return 0;
+}
+
+
+int hfa384x_cmd_writemif(hfa384x_t *hw)
+{
+       DBFENTER;
+       DBFEXIT;
+       return 0;
+}
+#endif
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_mmi_read
+*
+* Read mmi registers.  mmi is intersil-speak for the baseband
+* processor registers.
+*
+* Arguments:
+*       hw              device structure
+*       register        The test register to be accessed (must be even #).
+*
+* Returns:
+*       0               success
+*       >0              f/w reported error - f/w status code
+*       <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*       process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr, UINT32 *resp)
+{
+        int             result = 0;
+       hfa384x_metacmd_t cmd;
+
+        DBFENTER;
+       cmd.cmd = (UINT16) 0x30;
+       cmd.parm0 = (UINT16) addr;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+        /* Do i need a host2hfa... conversion ? */
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+       *resp = (UINT32) cmd.result.resp0;
+
+        DBFEXIT;
+        return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_mmi_write
+*
+* Read mmi registers.  mmi is intersil-speak for the baseband
+* processor registers.
+*
+* Arguments:
+*       hw              device structure
+*       addr            The test register to be accessed (must be even #).
+*       data            The data value to write to the register.
+*
+* Returns:
+*       0               success
+*       >0              f/w reported error - f/w status code
+*       <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*       process thread
+----------------------------------------------------------------*/
+
+int
+hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data)
+{
+        int             result = 0;
+       hfa384x_metacmd_t cmd;
+
+        DBFENTER;
+       cmd.cmd = (UINT16) 0x31;
+       cmd.parm0 = (UINT16) addr;
+       cmd.parm1 = (UINT16) data;
+       cmd.parm2 = 0;
+
+        WLAN_LOG_DEBUG(1,"mmi write : addr = 0x%08x\n", addr);
+        WLAN_LOG_DEBUG(1,"mmi write : data = 0x%08x\n", data);
+
+        /* Do i need a host2hfa... conversion ? */
+       spin_lock_bh(&hw->cmdlock);
+       result = hfa384x_docmd_wait(hw, &cmd);
+       spin_unlock_bh(&hw->cmdlock);
+
+        DBFEXIT;
+        return result;
+}
+
+
+/* TODO: determine if these will ever be needed */
+#if 0
+int hfa384x_cmd_readmif(hfa384x_t *hw)
+{
+        DBFENTER;
+        DBFEXIT;
+        return 0;
+}
+
+
+int hfa384x_cmd_writemif(hfa384x_t *hw)
+{
+        DBFENTER;
+        DBFEXIT;
+        return 0;
+}
+#endif
+
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_from_bap
+*
+* Copies a collection of bytes from the MAC controller memory via
+* one set of BAP registers.
+*
+* Arguments:
+*      hw              device structure
+*      bap             [0|1] which BAP to use
+*      id              FID or RID, destined for the select register (host order)
+*      offset          An _even_ offset into the buffer for the given
+*                      FID/RID.  We haven't the means to validate this,
+*                      so be careful. (host order)
+*      buf             ptr to array of bytes
+*      len             length of data to transfer in bytes
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - value of offset reg.
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+*      interrupt
+----------------------------------------------------------------*/
+int hfa384x_copy_from_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
+                               void *buf, UINT len)
+{
+       int             result = 0;
+       unsigned long   flags = 0;
+       UINT8           *d = (UINT8*)buf;
+       UINT            selectreg;
+       UINT            offsetreg;
+       UINT            datareg;
+       UINT            i;
+       UINT16          reg = 0;
+
+       DBFENTER;
+
+       /* Validate bap, offset, buf, and len */
+       if ( (bap > 1) ||
+            (offset > HFA384x_BAP_OFFSET_MAX) ||
+            (offset % 2) ||
+            (buf == NULL) ||
+            (len > HFA384x_BAP_DATALEN_MAX) ){
+               result = -EINVAL;
+       } else {
+               selectreg = (bap == 1) ?  HFA384x_SELECT1 : HFA384x_SELECT0 ;
+               offsetreg = (bap == 1) ?  HFA384x_OFFSET1 : HFA384x_OFFSET0 ;
+               datareg =   (bap == 1) ?  HFA384x_DATA1 : HFA384x_DATA0 ;
+
+               /* Obtain lock */
+               spin_lock_irqsave( &(hw->baplock), flags);
+
+               /* Write id to select reg */
+               hfa384x_setreg(hw, id, selectreg);
+               /* Write offset to offset reg */
+               hfa384x_setreg(hw, offset, offsetreg);
+               /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */
+               i = 0;
+               do {
+                       reg = hfa384x_getreg(hw, offsetreg);
+                       if ( i > 0 ) udelay(10);
+                       i++;
+               } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg));
+#if (WLAN_HOSTIF != WLAN_PCI)
+               /* Release lock */
+               spin_unlock_irqrestore( &(hw->baplock), flags);
+#endif
+
+               if ( HFA384x_OFFSET_ISBUSY(reg) ){
+                       /* If timeout, return -ETIMEDOUT */
+                       result = reg;
+               } else if ( HFA384x_OFFSET_ISERR(reg) ){
+                       /* If offset[err] == 1, return -EINVAL */
+                       result = reg;
+               } else {
+                       /* Read even(len) buf contents from data reg */
+                       for ( i = 0; i < (len & 0xfffe); i+=2 ) {
+                               *(UINT16*)(&(d[i])) =
+                                       hfa384x_getreg_noswap(hw, datareg);
+                       }
+                       /* If len odd, handle last byte */
+                       if ( len % 2 ){
+                               reg = hfa384x_getreg_noswap(hw, datareg);
+                               d[len-1] = ((UINT8*)(&reg))[0];
+                       }
+               }
+
+               /* According to Intersil errata dated 9/16/02:
+
+               "In PRISM PCI MAC host interface, if both BAPs are concurrently
+                requesing memory access, both will accept the Ack.   There is no
+                firmware workaround possible.  To prevent BAP access failures or
+                hang conditions the host MUST NOT access both BAPs in sucession
+                unless at least 5us elapses between accesses.  The safest choice
+                is to USE ONLY ONE BAP for all data movement operations."
+
+                What this means:
+
+                We have to serialize ALL BAP accesses, and furthermore, add a 5us
+                delay after access if we're using a PCI platform.
+
+                Unfortunately, this means we have to lock out interrupts througout
+                the entire BAP copy.
+
+                It remains to be seen if "BAP access" means "BAP setup" or the more
+                literal definition of "copying data back and forth"  I'm erring for
+                the latter, safer definition.  -- SLP.
+
+               */
+
+#if (WLAN_HOSTIF == WLAN_PCI)
+               udelay(5);
+               /* Release lock */
+               spin_unlock_irqrestore( &(hw->baplock), flags);
+#endif
+
+       }
+
+       if (result) {
+         WLAN_LOG_DEBUG(1,
+                         "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+                         reg, len, result);
+       }
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_to_bap
+*
+* Copies a collection of bytes to the MAC controller memory via
+* one set of BAP registers.
+*
+* Arguments:
+*      hw              device structure
+*      bap             [0|1] which BAP to use
+*      id              FID or RID, destined for the select register (host order)
+*      offset          An _even_ offset into the buffer for the given
+*                      FID/RID.  We haven't the means to validate this,
+*                      so be careful. (host order)
+*      buf             ptr to array of bytes
+*      len             length of data to transfer (in bytes)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - value of offset reg.
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+*      interrupt
+----------------------------------------------------------------*/
+int hfa384x_copy_to_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
+                               void *buf, UINT len)
+{
+       return hfa384x_copy_to_bap4(hw, bap, id, offset, buf, len, NULL, 0, NULL, 0, NULL, 0);
+}
+
+int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
+                        void *buf, UINT len1, void* buf2, UINT len2,
+                        void *buf3, UINT len3, void *buf4, UINT len4)
+{
+       int             result = 0;
+       unsigned long   flags = 0;
+       UINT8           *d;
+       UINT            selectreg;
+       UINT            offsetreg;
+       UINT            datareg;
+       UINT            i;
+       UINT16          reg;
+
+       DBFENTER;
+
+//     printk(KERN_DEBUG "ctb1 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4);
+
+       /* Validate bap, offset, buf, and len */
+       if ( (bap > 1) ||
+            (offset > HFA384x_BAP_OFFSET_MAX) ||
+            (offset % 2) ||
+            (buf == NULL) ||
+            (len1+len2+len3+len4 > HFA384x_BAP_DATALEN_MAX) ){
+               result = -EINVAL;
+       } else {
+               selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0;
+               offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0;
+               datareg =   (bap == 1) ? HFA384x_DATA1   : HFA384x_DATA0;
+               /* Obtain lock */
+               spin_lock_irqsave( &(hw->baplock), flags);
+
+               /* Write id to select reg */
+               hfa384x_setreg(hw, id, selectreg);
+               udelay(10);
+               /* Write offset to offset reg */
+               hfa384x_setreg(hw, offset, offsetreg);
+               /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */
+               i = 0;
+               do {
+                       reg = hfa384x_getreg(hw, offsetreg);
+                       if ( i > 0 ) udelay(10);
+                       i++;
+               } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg));
+
+#if (WLAN_HOSTIF != WLAN_PCI)
+               /* Release lock */
+               spin_unlock_irqrestore( &(hw->baplock), flags);
+#endif
+
+               if ( HFA384x_OFFSET_ISBUSY(reg) ){
+                       /* If timeout, return reg */
+                       result = reg;
+               } else if ( HFA384x_OFFSET_ISERR(reg) ){
+                       /* If offset[err] == 1, return reg */
+                       result = reg;
+               } else {
+                       d = (UINT8*)buf;
+                       /* Write even(len1) buf contents to data reg */
+                       for ( i = 0; i < (len1 & 0xfffe); i+=2 ) {
+                               hfa384x_setreg_noswap(hw,
+                                       *(UINT16*)(&(d[i])), datareg);
+                       }
+                       if (len1 & 1) {
+                               UINT16 data;
+                               UINT8 *b = (UINT8 *) &data;
+                               b[0] = d[len1-1];
+                               if (buf2 != NULL) {
+                                       d = (UINT8*)buf2;
+                                       b[1] = d[0];
+                                       len2--;
+                                       buf2++;
+                               }
+                               hfa384x_setreg_noswap(hw, data, datareg);
+                       }
+                       if ((buf2 != NULL) && (len2 > 0)) {
+                               /* Write even(len2) buf contents to data reg */
+                               d = (UINT8*)buf2;
+                               for ( i = 0; i < (len2 & 0xfffe); i+=2 ) {
+                                       hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg);
+                               }
+                               if (len2 & 1) {
+                                       UINT16 data;
+                                       UINT8 *b = (UINT8 *) &data;
+                                       b[0] = d[len2-1];
+                                       if (buf3 != NULL) {
+                                               d = (UINT8*)buf3;
+                                               b[1] = d[0];
+                                               len3--;
+                                               buf3++;
+                                       }
+                                       hfa384x_setreg_noswap(hw, data, datareg);
+                               }
+                       }
+
+                       if ((buf3 != NULL) && (len3 > 0)) {
+                               /* Write even(len3) buf contents to data reg */
+                               d = (UINT8*)buf3;
+                               for ( i = 0; i < (len3 & 0xfffe); i+=2 ) {
+                                       hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg);
+                               }
+                               if (len3 & 1) {
+                                       UINT16 data;
+                                       UINT8 *b = (UINT8 *) &data;
+                                       b[0] = d[len3-1];
+                                       if (buf4 != NULL) {
+                                               d = (UINT8*)buf4;
+                                               b[1] = d[0];
+                                               len4--;
+                                               buf4++;
+                                       }
+                                       hfa384x_setreg_noswap(hw, data, datareg);
+                               }
+                       }
+                       if ((buf4 != NULL) && (len4 > 0)) {
+                               /* Write even(len4) buf contents to data reg */
+                               d = (UINT8*)buf4;
+                               for ( i = 0; i < (len4 & 0xfffe); i+=2 ) {
+                                       hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg);
+                               }
+                               if (len4 & 1) {
+                                       UINT16 data;
+                                       UINT8 *b = (UINT8 *) &data;
+                                       b[0] = d[len4-1];
+                                       b[1] = 0;
+
+                                       hfa384x_setreg_noswap(hw, data, datareg);
+                               }
+                       }
+//                     printk(KERN_DEBUG "ctb2 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4);
+
+               }
+
+#if (WLAN_HOSTIF == WLAN_PCI)
+               udelay(5);
+               /* Release lock */
+               spin_unlock_irqrestore( &(hw->baplock), flags);
+#endif
+
+       }
+
+       if (result)
+               WLAN_LOG_ERROR("copy_to_bap() failed.\n");
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_from_aux
+*
+* Copies a collection of bytes from the controller memory.  The
+* Auxiliary port MUST be enabled prior to calling this function.
+* We _might_ be in a download state.
+*
+* Arguments:
+*      hw              device structure
+*      cardaddr        address in hfa384x data space to read
+*      auxctl          address space select
+*      buf             ptr to destination host buffer
+*      len             length of data to transfer (in bytes)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      buf contains the data copied
+*
+* Call context:
+*      process thread
+*      interrupt
+----------------------------------------------------------------*/
+void
+hfa384x_copy_from_aux(
+       hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
+{
+       UINT16          currpage;
+       UINT16          curroffset;
+       UINT            i = 0;
+
+       DBFENTER;
+
+       if ( !(hw->auxen) ) {
+               WLAN_LOG_DEBUG(1,
+                       "Attempt to read 0x%04x when aux not enabled\n",
+                       cardaddr);
+               return;
+
+       }
+       /* Build appropriate aux page and offset */
+       currpage = HFA384x_AUX_MKPAGE(cardaddr);
+       curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl);
+       hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
+       hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
+       udelay(5);      /* beat */
+
+       /* read the data */
+       while ( i < len) {
+               *((UINT16*)(buf+i)) = hfa384x_getreg_noswap(hw, HFA384x_AUXDATA);
+               i+=2;
+               curroffset+=2;
+               if ( (curroffset&HFA384x_ADDR_AUX_OFF_MASK) >
+                       HFA384x_ADDR_AUX_OFF_MAX ) {
+                       currpage++;
+                       curroffset = 0;
+                       curroffset = HFA384x_AUX_MKOFF(curroffset, auxctl);
+                       hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
+                       hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
+                       udelay(5);      /* beat */
+               }
+       }
+       /* Make sure the auxctl bits are clear */
+       hfa384x_setreg(hw, 0, HFA384x_AUXOFFSET);
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_to_aux
+*
+* Copies a collection of bytes to the controller memory.  The
+* Auxiliary port MUST be enabled prior to calling this function.
+* We _might_ be in a download state.
+*
+* Arguments:
+*      hw              device structure
+*      cardaddr        address in hfa384x data space to read
+*      auxctl          address space select
+*      buf             ptr to destination host buffer
+*      len             length of data to transfer (in bytes)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      Controller memory now contains a copy of buf
+*
+* Call context:
+*      process thread
+*      interrupt
+----------------------------------------------------------------*/
+void
+hfa384x_copy_to_aux(
+       hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
+{
+       UINT16          currpage;
+       UINT16          curroffset;
+       UINT            i = 0;
+
+       DBFENTER;
+
+       if ( !(hw->auxen) ) {
+               WLAN_LOG_DEBUG(1,
+                       "Attempt to read 0x%04x when aux not enabled\n",
+                       cardaddr);
+               return;
+
+       }
+       /* Build appropriate aux page and offset */
+       currpage = HFA384x_AUX_MKPAGE(cardaddr);
+       curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl);
+       hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
+       hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
+       udelay(5);      /* beat */
+
+       /* write the data */
+       while ( i < len) {
+               hfa384x_setreg_noswap(hw,
+                       *((UINT16*)(buf+i)), HFA384x_AUXDATA);
+               i+=2;
+               curroffset+=2;
+               if ( curroffset > HFA384x_ADDR_AUX_OFF_MAX ) {
+                       currpage++;
+                       curroffset = 0;
+                       hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
+                       hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
+                       udelay(5);      /* beat */
+               }
+       }
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_wait
+*
+* Waits for availability of the Command register, then
+* issues the given command.  Then polls the Evstat register
+* waiting for command completion.  Timeouts shouldn't be
+* possible since we're preventing overlapping commands and all
+* commands should be cleared and acknowledged.
+*
+* Arguments:
+*      wlandev         device structure
+*       cmd             cmd structure.  Includes all arguments and result
+*                       data points.  All in host order.
+*
+* Returns:
+*      0               success
+*      -ETIMEDOUT      timed out waiting for register ready or
+*                      command completion
+*      >0              command indicated error, Status and Resp0-2 are
+*                      in hw structure.
+*
+* Side effects:
+*
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+       int             result = -ETIMEDOUT;
+       UINT16          reg = 0;
+       UINT16          counter;
+
+       DBFENTER;
+
+       hw->cmdflag = 0;
+       hw->cmddata = cmd;
+
+       /* wait for the busy bit to clear */
+       counter = 0;
+       reg = hfa384x_getreg(hw, HFA384x_CMD);
+       while ( HFA384x_CMD_ISBUSY(reg) &&
+               (counter < 10)) {
+               reg = hfa384x_getreg(hw, HFA384x_CMD);
+               counter++;
+               udelay(10);
+       }
+
+       if (HFA384x_CMD_ISBUSY(reg)) {
+               WLAN_LOG_ERROR("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg);
+               goto failed;
+       }
+       if (!HFA384x_CMD_ISBUSY(reg)) {
+               /* busy bit clear, write command */
+               hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0);
+               hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1);
+               hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2);
+               hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD);
+
+#ifdef CMD_IRQ
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0))
+               while (! hw->cmdflag)
+                       interruptible_sleep_on(&hw->cmdq);
+#else
+               wait_event_interruptible(hw->cmdq, hw->cmdflag);
+#endif
+               result = HFA384x_STATUS_RESULT_GET(cmd->status);
+#else // CMD_IRQ
+               /* Now wait for completion */
+               counter = 0;
+               reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+               /* Initialization is the problem.  It takes about
+                   100ms. "normal" commands are typically is about
+                   200-400 us (I've never seen less than 200).  Longer
+                   is better so that we're not hammering the bus. */
+               while ( !HFA384x_EVSTAT_ISCMD(reg) &&
+                       (counter < 5000)) {
+                       reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+                       counter++;
+                       udelay(200);
+               }
+
+               if ( HFA384x_EVSTAT_ISCMD(reg) ) {
+                       result = 0;
+                       cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS);
+                       cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
+                       cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
+                       cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
+                       hfa384x_setreg(hw, HFA384x_EVACK_CMD,
+                               HFA384x_EVACK);
+                       result = HFA384x_STATUS_RESULT_GET(cmd->result.status);
+               } else {
+                       WLAN_LOG_ERROR("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg);
+               }
+#endif  /* CMD_IRQ */
+       }
+
+ failed:
+       hw->cmdflag = 0;
+       hw->cmddata = NULL;
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_dl_docmd_wait
+*
+* Waits for availability of the Command register, then
+* issues the given command.  Then polls the Evstat register
+* waiting for command completion.  Timeouts shouldn't be
+* possible since we're preventing overlapping commands and all
+* commands should be cleared and acknowledged.
+*
+* This routine is only used for downloads.  Since it doesn't lock out
+* interrupts the system response is much better.
+*
+* Arguments:
+*      wlandev         device structure
+*       cmd             cmd structure.  Includes all arguments and result
+*                       data points.  All in host order.
+*
+* Returns:
+*      0               success
+*      -ETIMEDOUT      timed out waiting for register ready or
+*                      command completion
+*      >0              command indicated error, Status and Resp0-2 are
+*                      in hw structure.
+*
+* Side effects:
+*
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+       int             result = -ETIMEDOUT;
+       unsigned long   timeout;
+       UINT16          reg = 0;
+
+       DBFENTER;
+       /* wait for the busy bit to clear */
+       timeout = jiffies + 1*HZ;
+       reg = hfa384x_getreg(hw, HFA384x_CMD);
+       while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) {
+               reg = hfa384x_getreg(hw, HFA384x_CMD);
+               udelay(10);
+       }
+       if (HFA384x_CMD_ISBUSY(reg)) {
+               WLAN_LOG_WARNING("Timed out waiting for cmd register.\n");
+               goto failed;
+       }
+
+       if (!HFA384x_CMD_ISBUSY(reg)) {
+               /* busy bit clear, write command */
+               hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0);
+               hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1);
+               hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2);
+               hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD);
+
+               /* Now wait for completion */
+               if ( (HFA384x_CMD_CMDCODE_GET(cmd->cmd) == HFA384x_CMDCODE_DOWNLD) ) {
+                       /* dltimeout is in ms */
+                       timeout = (((UINT32)hw->dltimeout) / 1000UL) * HZ;
+                       if ( timeout > 0 ) {
+                               timeout += jiffies;
+                       } else {
+                               timeout = jiffies + 1*HZ;
+                       }
+               } else {
+                       timeout = jiffies + 1*HZ;
+               }
+               reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+               while ( !HFA384x_EVSTAT_ISCMD(reg) && time_before(jiffies,timeout) ) {
+                       udelay(100);
+                       reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+               }
+               if ( HFA384x_EVSTAT_ISCMD(reg) ) {
+                       result = 0;
+                       cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS);
+                       cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
+                       cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
+                       cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
+                       hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK);
+                       result = HFA384x_STATUS_RESULT_GET(cmd->result.status);
+               }
+       }
+
+failed:
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_start
+*
+* Issues the MAC initialize command, sets up some data structures,
+* and enables the interrupts.  After this function completes, the
+* low-level stuff should be ready for any/all commands.
+*
+* Arguments:
+*      hw              device structure
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_start(hfa384x_t *hw)
+{
+       int     result = 0;
+       UINT16                  reg;
+       int                     i;
+       int                     j;
+       DBFENTER;
+
+       /* call initialize */
+       result = hfa384x_cmd_initialize(hw);
+       if (result != 0) {
+               WLAN_LOG_ERROR("Initialize command failed.\n");
+               goto failed;
+       }
+
+       /* make sure interrupts are disabled and any layabout events cleared */
+       hfa384x_setreg(hw, 0, HFA384x_INTEN);
+       hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
+
+        hw->txfid_head = 0;
+        hw->txfid_tail = 0;
+        hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX;
+        memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue));
+
+       /* Allocate tx and notify FIDs */
+       /* First, tx */
+       for ( i = 0; i < HFA384x_DRVR_FIDSTACKLEN_MAX-1; i++) {
+               result = hfa384x_cmd_allocate(hw, HFA384x_DRVR_TXBUF_MAX);
+               if (result != 0) {
+                       WLAN_LOG_ERROR("Allocate(tx) command failed.\n");
+                       goto failed;
+               }
+               j = 0;
+               do {
+                       reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+                       udelay(10);
+                       j++;
+               } while ( !HFA384x_EVSTAT_ISALLOC(reg) && j < 50); /* 50 is timeout */
+               if ( j >= 50 ) {
+                       WLAN_LOG_ERROR("Timed out waiting for evalloc(tx).\n");
+                       result = -ETIMEDOUT;
+                       goto failed;
+               }
+               reg = hfa384x_getreg(hw, HFA384x_ALLOCFID);
+
+               txfid_queue_add(hw, reg);
+
+               WLAN_LOG_DEBUG(4,"hw->txfid_queue[%d]=0x%04x\n",i,reg);
+
+               reg = HFA384x_EVACK_ALLOC_SET(1);
+               hfa384x_setreg(hw, reg, HFA384x_EVACK);
+
+       }
+
+       /* Now, the info frame fid */
+       result = hfa384x_cmd_allocate(hw, HFA384x_INFOFRM_MAXLEN);
+       if (result != 0) {
+               WLAN_LOG_ERROR("Allocate(tx) command failed.\n");
+               goto failed;
+       }
+       i = 0;
+       do {
+               reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+               udelay(10);
+               i++;
+       } while ( !HFA384x_EVSTAT_ISALLOC(reg) && i < 50); /* 50 is timeout */
+       if ( i >= 50 ) {
+               WLAN_LOG_ERROR("Timed out waiting for evalloc(info).\n");
+               result = -ETIMEDOUT;
+               goto failed;
+       }
+       hw->infofid = hfa384x_getreg(hw, HFA384x_ALLOCFID);
+       reg = HFA384x_EVACK_ALLOC_SET(1);
+       hfa384x_setreg(hw, reg, HFA384x_EVACK);
+       WLAN_LOG_DEBUG(4,"hw->infofid=0x%04x\n", hw->infofid);
+
+       /* Set swsupport regs to magic # for card presence detection */
+       hfa384x_setreg(hw, HFA384x_DRVR_MAGIC, HFA384x_SWSUPPORT0);
+
+       /* Now enable the interrupts and set the running state */
+       hfa384x_setreg(hw, 0xffff, HFA384x_EVSTAT);
+       hfa384x_events_all(hw);
+
+       hw->state = HFA384x_STATE_RUNNING;
+
+       goto done;
+failed:
+       WLAN_LOG_ERROR("Failed, result=%d\n", result);
+done:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_stop
+*
+* Issues the initialize command to leave us in the 'reset' state.
+*
+* Arguments:
+*      hw              device structure
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_stop(hfa384x_t *hw)
+{
+       int     result = 0;
+       int i;
+       DBFENTER;
+
+       del_timer_sync(&hw->commsqual_timer);
+
+       if ( hw->wlandev->hwremoved ) {
+               /* only flush when we're shutting down for good */
+               flush_scheduled_work();
+       }
+
+       if (hw->state == HFA384x_STATE_RUNNING) {
+               /*
+                * Send the MAC initialize cmd.
+                */
+               hfa384x_cmd_initialize(hw);
+
+               /*
+                * Make absolutely sure interrupts are disabled and any
+                * layabout events cleared
+                */
+               hfa384x_setreg(hw, 0, HFA384x_INTEN);
+               hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
+       }
+
+       tasklet_kill(&hw->bap_tasklet);
+
+       hw->link_status = HFA384x_LINK_NOTCONNECTED;
+       hw->state = HFA384x_STATE_INIT;
+
+       /* Clear all the port status */
+       for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+               hw->port_enabled[i] = 0;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_txframe
+*
+* Takes a frame from prism2sta and queues it for transmission.
+*
+* Arguments:
+*      hw              device structure
+*      skb             packet buffer struct.  Contains an 802.11
+*                      data frame.
+*       p80211_hdr      points to the 802.11 header for the packet.
+* Returns:
+*      0               Success and more buffs available
+*      1               Success but no more buffs
+*      2               Allocation failure
+*      3               MAC Tx command failed
+*      4               Buffer full or queue busy
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
+{
+       hfa384x_tx_frame_t      txdesc;
+       UINT16                  macq = 0;
+       UINT16                  fid;
+       int                     result;
+
+       DBFENTER;
+
+       /* Build Tx frame structure */
+       /* Set up the control field */
+       memset(&txdesc, 0, sizeof(txdesc));
+
+/* Tx complete and Tx exception disable per dleach.  Might be causing
+ * buf depletion
+ */
+#define DOBOTH 1
+#if DOBOTH
+       txdesc.tx_control =
+               HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+               HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
+#elif DOEXC
+       txdesc.tx_control =
+               HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+               HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
+#else
+       txdesc.tx_control =
+               HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+               HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
+#endif
+
+       /* if we're using host WEP, increase size by IV+ICV */
+       if (p80211_wep->data) {
+               txdesc.data_len = host2hfa384x_16(skb->len+8);
+               //              txdesc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1);
+       } else {
+               txdesc.data_len =  host2hfa384x_16(skb->len);
+       }
+
+       txdesc.tx_control = host2hfa384x_16(txdesc.tx_control);
+       /* copy the header over to the txdesc */
+       memcpy(&(txdesc.frame_control), p80211_hdr, sizeof(p80211_hdr_t));
+
+       /* Since tbusy is set whenever the stack is empty, there should
+        * always be something on the stack if we get to this point.
+        * [MSM]: NOT TRUE!!!!! so I added the test of fid below.
+        */
+
+       /* Allocate FID */
+
+       fid = txfid_queue_remove(hw);
+
+       if ( fid == 0 ) { /* stack or queue was empty */
+               return 4;
+       }
+
+       /* now let's get the cmdlock */
+       spin_lock(&hw->cmdlock);
+
+       /* Copy descriptor+payload to FID */
+        if (p80211_wep->data) {
+               result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0,
+                                             &txdesc, sizeof(txdesc),
+                                             p80211_wep->iv, sizeof(p80211_wep->iv),
+                                             p80211_wep->data, skb->len,
+                                             p80211_wep->icv, sizeof(p80211_wep->icv));
+       } else {
+               result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0,
+                                             &txdesc, sizeof(txdesc),
+                                             skb->data, skb->len,
+                                             NULL, 0, NULL, 0);
+       }
+
+       if ( result ) {
+               WLAN_LOG_DEBUG(1,
+                       "copy_to_bap(%04x, %d, %d) failed, result=0x%x\n",
+                       fid,
+                       sizeof(txdesc),
+                       skb->len,
+                       result);
+
+               /* put the fid back in the queue */
+               txfid_queue_add(hw, fid);
+
+               result = 3;
+               goto failed;
+       }
+
+       /* Issue Tx command */
+       result = hfa384x_cmd_transmit(hw, HFA384x_TXCMD_RECL, macq, fid);
+
+       if ( result != 0 ) {
+               txfid_queue_add(hw, fid);
+
+               WLAN_LOG_DEBUG(1,"cmd_tx(%04x) failed, result=%d\n",
+                       fid, result);
+               result = 3;
+               goto failed;
+       }
+
+       /* indicate we haven't any buffers, int_alloc will clear */
+       result = txfid_queue_empty(hw);
+failed:
+
+       spin_unlock(&hw->cmdlock);
+
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_interrupt
+*
+* Driver interrupt handler.
+*
+* Arguments:
+*      irq             irq number
+*      dev_id          pointer to the device
+*      regs            registers
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      May result in a frame being passed up the stack or an info
+*      frame being handled.
+*
+* Call context:
+*      Ummm, could it be interrupt?
+----------------------------------------------------------------*/
+irqreturn_t hfa384x_interrupt(int irq, void *dev_id PT_REGS)
+{
+       int                     reg;
+       wlandevice_t            *wlandev = (wlandevice_t*)dev_id;
+       hfa384x_t               *hw = wlandev->priv;
+       int                     ev_read = 0;
+       DBFENTER;
+
+       if (!wlandev || wlandev->hwremoved)
+               return IRQ_NONE;  /* Not much we can do w/o hardware */
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+       if (hw->iobase == 0)  /* XXX FIXME Properly */
+               return IRQ_NONE;
+#endif
+
+       for (;;ev_read++) {
+               if (ev_read >= prism2_irq_evread_max)
+                       break;
+
+               /* Check swsupport reg magic # for card presence */
+               reg = hfa384x_getreg(hw, HFA384x_SWSUPPORT0);
+               if ( reg != HFA384x_DRVR_MAGIC) {
+                       WLAN_LOG_DEBUG(2, "irq=%d, no magic.  Card removed?.\n", irq);
+                       break;
+               }
+
+               /* read the EvStat register for interrupt enabled events */
+               reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+
+               /* AND with the enabled interrupts */
+               reg &= hfa384x_getreg(hw, HFA384x_INTEN);
+
+               /* Handle the events */
+               if ( HFA384x_EVSTAT_ISWTERR(reg) ){
+                       WLAN_LOG_ERROR(
+                       "Error: WTERR interrupt received (unhandled).\n");
+                       hfa384x_setreg(hw, HFA384x_EVACK_WTERR_SET(1),
+                               HFA384x_EVACK);
+               }
+
+               if ( HFA384x_EVSTAT_ISINFDROP(reg) ){
+                       hfa384x_int_infdrop(wlandev);
+                       hfa384x_setreg(hw, HFA384x_EVACK_INFDROP_SET(1),
+                               HFA384x_EVACK);
+               }
+
+               if (HFA384x_EVSTAT_ISBAP_OP(reg)) {
+                       /* Disable the BAP interrupts */
+                       hfa384x_events_nobap(hw);
+                       tasklet_schedule(&hw->bap_tasklet);
+               }
+
+               if ( HFA384x_EVSTAT_ISALLOC(reg) ){
+                       hfa384x_int_alloc(wlandev);
+                       hfa384x_setreg(hw, HFA384x_EVACK_ALLOC_SET(1),
+                               HFA384x_EVACK);
+               }
+
+               if ( HFA384x_EVSTAT_ISDTIM(reg) ){
+                       hfa384x_int_dtim(wlandev);
+                       hfa384x_setreg(hw, HFA384x_EVACK_DTIM_SET(1),
+                               HFA384x_EVACK);
+               }
+#ifdef CMD_IRQ
+               if ( HFA384x_EVSTAT_ISCMD(reg) ){
+                       hfa384x_int_cmd(wlandev);
+                       hfa384x_setreg(hw, HFA384x_EVACK_CMD_SET(1),
+                                      HFA384x_EVACK);
+               }
+#endif
+
+               /* allow the evstat to be updated after the evack */
+               udelay(20);
+       }
+
+       DBFEXIT;
+       return IRQ_HANDLED;
+}
+
+#ifdef CMD_IRQ
+/*----------------------------------------------------------------
+* hfa384x_int_cmd
+*
+* Handles command completion event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+void hfa384x_int_cmd(wlandevice_t *wlandev)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       DBFENTER;
+
+       // check to make sure it's the right command?
+       if (hw->cmddata) {
+               hw->cmddata->status = hfa384x_getreg(hw, HFA384x_STATUS);
+               hw->cmddata->resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
+               hw->cmddata->resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
+               hw->cmddata->resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
+       }
+       hw->cmdflag = 1;
+
+       printk(KERN_INFO "um. int_cmd\n");
+
+       wake_up_interruptible(&hw->cmdq);
+
+       // XXXX perform a bap copy too?
+
+       DBFEXIT;
+       return;
+}
+#endif
+
+/*----------------------------------------------------------------
+* hfa384x_int_dtim
+*
+* Handles the DTIM early warning event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_dtim(wlandevice_t *wlandev)
+{
+#if 0
+       hfa384x_t               *hw = wlandev->priv;
+#endif
+       DBFENTER;
+       prism2sta_ev_dtim(wlandev);
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_infdrop
+*
+* Handles the InfDrop event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_infdrop(wlandevice_t *wlandev)
+{
+#if 0
+       hfa384x_t               *hw = wlandev->priv;
+#endif
+       DBFENTER;
+       prism2sta_ev_infdrop(wlandev);
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_info
+*
+* Handles the Info event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      tasklet
+----------------------------------------------------------------*/
+static void hfa384x_int_info(wlandevice_t *wlandev)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       UINT16                  reg;
+       hfa384x_InfFrame_t      inf;
+       int                     result;
+       DBFENTER;
+       /* Retrieve the FID */
+       reg = hfa384x_getreg(hw, HFA384x_INFOFID);
+
+       /* Retrieve the length */
+       result = hfa384x_copy_from_bap( hw,
+               HFA384x_BAP_INT, reg, 0, &inf.framelen, sizeof(UINT16));
+       if ( result ) {
+               WLAN_LOG_DEBUG(1,
+                       "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+                       reg, sizeof(inf), result);
+               goto failed;
+       }
+       inf.framelen = hfa384x2host_16(inf.framelen);
+
+       /* Retrieve the rest */
+       result = hfa384x_copy_from_bap( hw,
+               HFA384x_BAP_INT, reg, sizeof(UINT16),
+               &(inf.infotype), inf.framelen * sizeof(UINT16));
+       if ( result ) {
+               WLAN_LOG_DEBUG(1,
+                       "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+                       reg, sizeof(inf), result);
+               goto failed;
+       }
+
+       prism2sta_ev_info(wlandev, &inf);
+failed:
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_txexc
+*
+* Handles the TxExc event.  A Transmit Exception event indicates
+* that the MAC's TX process was unsuccessful - so the packet did
+* not get transmitted.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      tasklet
+----------------------------------------------------------------*/
+static void hfa384x_int_txexc(wlandevice_t *wlandev)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       UINT16                  status;
+       UINT16                  fid;
+       int                     result = 0;
+       DBFENTER;
+       /* Collect the status and display */
+       fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID);
+       result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status));
+       if ( result ) {
+               WLAN_LOG_DEBUG(1,
+                       "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+                       fid, sizeof(status), result);
+               goto failed;
+       }
+       status = hfa384x2host_16(status);
+       prism2sta_ev_txexc(wlandev, status);
+failed:
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_tx
+*
+* Handles the Tx event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      tasklet
+----------------------------------------------------------------*/
+static void hfa384x_int_tx(wlandevice_t *wlandev)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       UINT16                  fid;
+       UINT16                  status;
+       int                     result = 0;
+       DBFENTER;
+       fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID);
+       result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status));
+       if ( result ) {
+               WLAN_LOG_DEBUG(1,
+                       "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+                       fid, sizeof(status), result);
+               goto failed;
+       }
+       status = hfa384x2host_16(status);
+       prism2sta_ev_tx(wlandev, status);
+failed:
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_int_rx
+*
+* Handles the Rx event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      tasklet
+----------------------------------------------------------------*/
+static void hfa384x_int_rx(wlandevice_t *wlandev)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       UINT16                  rxfid;
+       hfa384x_rx_frame_t      rxdesc;
+       int                     result;
+       int                     hdrlen;
+       UINT16                  fc;
+       p80211_rxmeta_t *rxmeta;
+       struct sk_buff          *skb = NULL;
+       UINT8 *datap;
+
+       DBFENTER;
+
+       /* Get the FID */
+       rxfid = hfa384x_getreg(hw, HFA384x_RXFID);
+       /* Get the descriptor (including headers) */
+       result = hfa384x_copy_from_bap(hw,
+                       HFA384x_BAP_INT,
+                       rxfid,
+                       0,
+                       &rxdesc,
+                       sizeof(rxdesc));
+       if ( result ) {
+               WLAN_LOG_DEBUG(1,
+                       "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n",
+                       rxfid,
+                       0,
+                       sizeof(rxdesc),
+                       result);
+               goto done;
+       }
+
+       /* Byte order convert once up front. */
+       rxdesc.status = hfa384x2host_16(rxdesc.status);
+       rxdesc.time =   hfa384x2host_32(rxdesc.time);
+
+       /* drop errors and whatnot in promisc mode */
+       if (( wlandev->netdev->flags & IFF_PROMISC ) &&
+           (HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) ||
+            HFA384x_RXSTATUS_ISUNDECR(rxdesc.status)))
+         goto done;
+
+       /* Now handle frame based on port# */
+       switch( HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) )
+       {
+       case 0:
+
+               fc = ieee2host16(rxdesc.frame_control);
+
+               /* If exclude and we receive an unencrypted, drop it */
+               if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
+                    !WLAN_GET_FC_ISWEP(fc)) {
+                       goto done;
+               }
+
+               hdrlen = p80211_headerlen(fc);
+
+               /* Allocate the buffer, note CRC (aka FCS). pballoc */
+               /* assumes there needs to be space for one */
+               skb = dev_alloc_skb(hfa384x2host_16(rxdesc.data_len) + hdrlen + WLAN_CRC_LEN + 2); /* a little extra */
+
+               if ( ! skb ) {
+                       WLAN_LOG_ERROR("alloc_skb failed.\n");
+                       goto done;
+                }
+
+               skb->dev = wlandev->netdev;
+
+               /* theoretically align the IP header on a 32-bit word. */
+               if ( hdrlen == WLAN_HDR_A4_LEN )
+                       skb_reserve(skb, 2);
+
+               /* Copy the 802.11 hdr to the buffer */
+               datap = skb_put(skb, WLAN_HDR_A3_LEN);
+               memcpy(datap, &rxdesc.frame_control, WLAN_HDR_A3_LEN);
+
+               /* Snag the A4 address if present */
+               if (hdrlen == WLAN_HDR_A4_LEN) {
+                       datap = skb_put(skb, WLAN_ADDR_LEN);
+                       memcpy(datap, &rxdesc.address4, WLAN_HDR_A3_LEN);
+               }
+
+               /* we can convert the data_len as we passed the original on */
+               rxdesc.data_len = hfa384x2host_16(rxdesc.data_len);
+
+               /* Copy the payload data to the buffer */
+               if ( rxdesc.data_len > 0 ) {
+                       datap = skb_put(skb, rxdesc.data_len);
+                       result = hfa384x_copy_from_bap(hw,
+                               HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF,
+                               datap, rxdesc.data_len);
+                       if ( result ) {
+                               WLAN_LOG_DEBUG(1,
+                                       "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n",
+                                       rxfid,
+                                       HFA384x_RX_DATA_OFF,
+                                       rxdesc.data_len,
+                                       result);
+                               goto failed;
+                       }
+               }
+               /* the prism2 cards don't return the FCS */
+               datap = skb_put(skb, WLAN_CRC_LEN);
+               memset (datap, 0xff, WLAN_CRC_LEN);
+               skb_reset_mac_header(skb);
+
+               /* Attach the rxmeta, set some stuff */
+               p80211skb_rxmeta_attach(wlandev, skb);
+               rxmeta = P80211SKB_RXMETA(skb);
+               rxmeta->mactime = rxdesc.time;
+               rxmeta->rxrate = rxdesc.rate;
+               rxmeta->signal = rxdesc.signal - hw->dbmadjust;
+               rxmeta->noise = rxdesc.silence - hw->dbmadjust;
+
+               prism2sta_ev_rx(wlandev, skb);
+               goto done;
+       case 7:
+
+               if ( ! HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) ) {
+                        hfa384x_int_rxmonitor( wlandev, rxfid, &rxdesc);
+                } else {
+                        WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n");
+                }
+               goto done;
+
+       default:
+
+               WLAN_LOG_WARNING("Received frame on unsupported port=%d\n",
+                       HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) );
+               goto done;
+       }
+
+ failed:
+       dev_kfree_skb(skb);
+
+ done:
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_rxmonitor
+*
+* Helper function for int_rx.  Handles monitor frames.
+* Note that this function allocates space for the FCS and sets it
+* to 0xffffffff.  The hfa384x doesn't give us the FCS value but the
+* higher layers expect it.  0xffffffff is used as a flag to indicate
+* the FCS is bogus.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      rxfid           received FID
+*      rxdesc          rx descriptor read from card in int_rx
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      Allocates an skb and passes it up via the PF_PACKET interface.
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, UINT16 rxfid,
+                                  hfa384x_rx_frame_t *rxdesc)
+{
+       hfa384x_t                       *hw = wlandev->priv;
+       UINT                            hdrlen = 0;
+       UINT                            datalen = 0;
+       UINT                            skblen = 0;
+       UINT                            truncated = 0;
+       UINT8                           *datap;
+       UINT16                          fc;
+       struct sk_buff                  *skb;
+
+       DBFENTER;
+       /* Don't forget the status, time, and data_len fields are in host order */
+       /* Figure out how big the frame is */
+       fc = ieee2host16(rxdesc->frame_control);
+       hdrlen = p80211_headerlen(fc);
+       datalen = hfa384x2host_16(rxdesc->data_len);
+
+       /* Allocate an ind message+framesize skb */
+       skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) +
+               hdrlen + datalen + WLAN_CRC_LEN;
+
+       /* sanity check the length */
+       if ( skblen >
+               (sizeof(p80211msg_lnxind_wlansniffrm_t) +
+               WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
+               WLAN_LOG_DEBUG(1, "overlen frm: len=%d\n",
+                       skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
+       }
+
+       if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
+               WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen);
+               return;
+       }
+
+       /* only prepend the prism header if in the right mode */
+       if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
+           (hw->sniffhdr == 0)) {
+               p80211msg_lnxind_wlansniffrm_t  *msg;
+               datap = skb_put(skb, sizeof(p80211msg_lnxind_wlansniffrm_t));
+               msg = (p80211msg_lnxind_wlansniffrm_t*) datap;
+
+               /* Initialize the message members */
+               msg->msgcode = DIDmsg_lnxind_wlansniffrm;
+               msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
+               strcpy(msg->devname, wlandev->name);
+
+               msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+               msg->hosttime.status = 0;
+               msg->hosttime.len = 4;
+               msg->hosttime.data = jiffies;
+
+               msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+               msg->mactime.status = 0;
+               msg->mactime.len = 4;
+               msg->mactime.data = rxdesc->time * 1000;
+
+               msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+               msg->channel.status = 0;
+               msg->channel.len = 4;
+               msg->channel.data = hw->sniff_channel;
+
+               msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+               msg->rssi.status = P80211ENUM_msgitem_status_no_value;
+               msg->rssi.len = 4;
+               msg->rssi.data = 0;
+
+               msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
+               msg->sq.status = P80211ENUM_msgitem_status_no_value;
+               msg->sq.len = 4;
+               msg->sq.data = 0;
+
+               msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+               msg->signal.status = 0;
+               msg->signal.len = 4;
+               msg->signal.data = rxdesc->signal;
+
+               msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+               msg->noise.status = 0;
+               msg->noise.len = 4;
+               msg->noise.data = rxdesc->silence;
+
+               msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+               msg->rate.status = 0;
+               msg->rate.len = 4;
+               msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
+
+               msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+               msg->istx.status = 0;
+               msg->istx.len = 4;
+               msg->istx.data = P80211ENUM_truth_false;
+
+               msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+               msg->frmlen.status = 0;
+               msg->frmlen.len = 4;
+               msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN;
+       } else if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
+                  (hw->sniffhdr != 0)) {
+               p80211_caphdr_t         *caphdr;
+               /* The NEW header format! */
+               datap = skb_put(skb, sizeof(p80211_caphdr_t));
+               caphdr = (p80211_caphdr_t*) datap;
+
+               caphdr->version =       htonl(P80211CAPTURE_VERSION);
+               caphdr->length =        htonl(sizeof(p80211_caphdr_t));
+               caphdr->mactime =       __cpu_to_be64(rxdesc->time);
+               caphdr->hosttime =      __cpu_to_be64(jiffies);
+               caphdr->phytype =       htonl(4); /* dss_dot11_b */
+               caphdr->channel =       htonl(hw->sniff_channel);
+               caphdr->datarate =      htonl(rxdesc->rate);
+               caphdr->antenna =       htonl(0); /* unknown */
+               caphdr->priority =      htonl(0); /* unknown */
+               caphdr->ssi_type =      htonl(3); /* rssi_raw */
+               caphdr->ssi_signal =    htonl(rxdesc->signal);
+               caphdr->ssi_noise =     htonl(rxdesc->silence);
+               caphdr->preamble =      htonl(0); /* unknown */
+               caphdr->encoding =      htonl(1); /* cck */
+       }
+       /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
+       datap = skb_put(skb, hdrlen);
+       memcpy( datap, &(rxdesc->frame_control), hdrlen);
+
+       /* If any, copy the data from the card to the skb */
+       if ( datalen > 0 )
+       {
+               /* Truncate the packet if the user wants us to */
+               UINT    dataread = datalen;
+               if(hw->sniff_truncate > 0 && dataread > hw->sniff_truncate) {
+                       dataread = hw->sniff_truncate;
+                       truncated = 1;
+               }
+
+               datap = skb_put(skb, dataread);
+               hfa384x_copy_from_bap(hw,
+                       HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF,
+                       datap, dataread);
+
+               /* check for unencrypted stuff if WEP bit set. */
+               if (*(datap - hdrlen + 1) & 0x40) // wep set
+                 if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa))
+                   *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header!
+       }
+
+       if (!truncated && hw->sniff_fcs) {
+               /* Set the FCS */
+               datap = skb_put(skb, WLAN_CRC_LEN);
+               memset( datap, 0xff, WLAN_CRC_LEN);
+       }
+
+       /* pass it back up */
+       prism2sta_ev_rx(wlandev, skb);
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_int_alloc
+*
+* Handles the Alloc event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_alloc(wlandevice_t *wlandev)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       UINT16                  fid;
+       INT16                   result;
+
+       DBFENTER;
+
+       /* Handle the reclaimed FID */
+       /*   collect the FID and push it onto the stack */
+       fid = hfa384x_getreg(hw, HFA384x_ALLOCFID);
+
+       if ( fid != hw->infofid ) { /* It's a transmit fid */
+               WLAN_LOG_DEBUG(5, "int_alloc(%#x)\n", fid);
+               result = txfid_queue_add(hw, fid);
+               if (result != -1) {
+                       prism2sta_ev_alloc(wlandev);
+                       WLAN_LOG_DEBUG(5, "q_add.\n");
+               } else {
+                       WLAN_LOG_DEBUG(5, "q_full.\n");
+               }
+       } else {
+               /* unlock the info fid */
+               up(&hw->infofid_sem);
+       }
+
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_handover
+*
+* Sends a handover notification to the MAC.
+*
+* Arguments:
+*      hw              device structure
+*      addr            address of station that's left
+*
+* Returns:
+*      zero            success.
+*      -ERESTARTSYS    received signal while waiting for semaphore.
+*      -EIO            failed to write to bap, or failed in cmd.
+*
+* Side effects:
+*
+* Call context:
+*      process thread, NOTE: this call may block on a semaphore!
+----------------------------------------------------------------*/
+int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr)
+{
+       int                     result = 0;
+        hfa384x_HandoverAddr_t  rec;
+        UINT                    len;
+        DBFENTER;
+
+       /* Acquire the infofid */
+       if ( down_interruptible(&hw->infofid_sem) ) {
+               result = -ERESTARTSYS;
+               goto failed;
+       }
+
+        /* Set up the record */
+        len = sizeof(hfa384x_HandoverAddr_t);
+        rec.framelen = host2hfa384x_16(len/2 - 1);
+        rec.infotype = host2hfa384x_16(HFA384x_IT_HANDOVERADDR);
+        memcpy(rec.handover_addr, addr, sizeof(rec.handover_addr));
+
+        /* Issue the command */
+        result = hfa384x_cmd_notify(hw, 1, hw->infofid, &rec, len);
+
+        if ( result != 0 ) {
+                WLAN_LOG_DEBUG(1,"cmd_notify(%04x) failed, result=%d",
+                        hw->infofid, result);
+               result = -EIO;
+                goto failed;
+        }
+
+failed:
+       DBFEXIT;
+       return result;
+}
+
+void hfa384x_tx_timeout(wlandevice_t *wlandev)
+{
+       DBFENTER;
+
+       WLAN_LOG_WARNING("Implement me.\n");
+
+       DBFEXIT;
+}
+
+/* Handles all "rx" BAP operations */
+static void     hfa384x_bap_tasklet(unsigned long data)
+{
+       hfa384x_t *hw = (hfa384x_t *) data;
+       wlandevice_t *wlandev = hw->wlandev;
+       int counter = prism2_irq_evread_max;
+       int                     reg;
+
+       DBFENTER;
+
+       while (counter-- > 0) {
+               /* Get interrupt register */
+               reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+
+               if ((reg == 0xffff) ||
+                   !(reg & HFA384x_INT_BAP_OP)) {
+                       break;
+               }
+
+               if ( HFA384x_EVSTAT_ISINFO(reg) ){
+                       hfa384x_int_info(wlandev);
+                       hfa384x_setreg(hw, HFA384x_EVACK_INFO_SET(1),
+                               HFA384x_EVACK);
+               }
+               if ( HFA384x_EVSTAT_ISTXEXC(reg) ){
+                       hfa384x_int_txexc(wlandev);
+                       hfa384x_setreg(hw, HFA384x_EVACK_TXEXC_SET(1),
+                               HFA384x_EVACK);
+               }
+               if ( HFA384x_EVSTAT_ISTX(reg) ){
+                       hfa384x_int_tx(wlandev);
+                       hfa384x_setreg(hw, HFA384x_EVACK_TX_SET(1),
+                               HFA384x_EVACK);
+               }
+               if ( HFA384x_EVSTAT_ISRX(reg) ){
+                       hfa384x_int_rx(wlandev);
+                       hfa384x_setreg(hw, HFA384x_EVACK_RX_SET(1),
+                               HFA384x_EVACK);
+               }
+       }
+
+       /* re-enable interrupts */
+       hfa384x_events_all(hw);
+
+       DBFEXIT;
+}
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
new file mode 100644 (file)
index 0000000..a205463
--- /dev/null
@@ -0,0 +1,3067 @@
+/* hfa384x.h
+*
+* Defines the constants and data structures for the hfa384x
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+*   [Implementation and usage notes]
+*
+*   [References]
+*      CW10 Programmer's Manual v1.5
+*      IEEE 802.11 D10.0
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _HFA384x_H
+#define _HFA384x_H
+
+/*=============================================================*/
+#define HFA384x_FIRMWARE_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+
+#define HFA384x_LEVEL_TO_dBm(v)   (0x100 + (v) * 100 / 255 - 100)
+
+/*------ Constants --------------------------------------------*/
+/*--- Mins & Maxs -----------------------------------*/
+#define                HFA384x_CMD_ALLOC_LEN_MIN       ((UINT16)4)
+#define                HFA384x_CMD_ALLOC_LEN_MAX       ((UINT16)2400)
+#define                HFA384x_BAP_DATALEN_MAX         ((UINT16)4096)
+#define                HFA384x_BAP_OFFSET_MAX          ((UINT16)4096)
+#define                HFA384x_PORTID_MAX              ((UINT16)7)
+#define                HFA384x_NUMPORTS_MAX            ((UINT16)(HFA384x_PORTID_MAX+1))
+#define                HFA384x_PDR_LEN_MAX             ((UINT16)512)   /* in bytes, from EK */
+#define                HFA384x_PDA_RECS_MAX            ((UINT16)200)   /* a guess */
+#define                HFA384x_PDA_LEN_MAX             ((UINT16)1024)  /* in bytes, from EK */
+#define                HFA384x_SCANRESULT_MAX          ((UINT16)31)
+#define                HFA384x_HSCANRESULT_MAX         ((UINT16)31)
+#define                HFA384x_CHINFORESULT_MAX        ((UINT16)16)
+#define                HFA384x_DRVR_FIDSTACKLEN_MAX    (10)
+#define                HFA384x_DRVR_TXBUF_MAX          (sizeof(hfa384x_tx_frame_t) + \
+                                               WLAN_DATA_MAXLEN - \
+                                               WLAN_WEP_IV_LEN - \
+                                               WLAN_WEP_ICV_LEN + 2)
+#define                HFA384x_DRVR_MAGIC              (0x4a2d)
+#define                HFA384x_INFODATA_MAXLEN         (sizeof(hfa384x_infodata_t))
+#define                HFA384x_INFOFRM_MAXLEN          (sizeof(hfa384x_InfFrame_t))
+#define                HFA384x_RID_GUESSING_MAXLEN     2048  /* I'm not really sure */
+#define                HFA384x_RIDDATA_MAXLEN          HFA384x_RID_GUESSING_MAXLEN
+#define                HFA384x_USB_RWMEM_MAXLEN        2048
+
+/*--- Support Constants -----------------------------*/
+#define                HFA384x_BAP_PROC                        ((UINT16)0)
+#define                HFA384x_BAP_INT                         ((UINT16)1)
+#define                HFA384x_PORTTYPE_IBSS                   ((UINT16)0)
+#define                HFA384x_PORTTYPE_BSS                    ((UINT16)1)
+#define                HFA384x_PORTTYPE_WDS                    ((UINT16)2)
+#define                HFA384x_PORTTYPE_PSUEDOIBSS             ((UINT16)3)
+#define                HFA384x_PORTTYPE_HOSTAP                 ((UINT16)6)
+#define                HFA384x_WEPFLAGS_PRIVINVOKED            ((UINT16)BIT0)
+#define                HFA384x_WEPFLAGS_EXCLUDE                ((UINT16)BIT1)
+#define                HFA384x_WEPFLAGS_DISABLE_TXCRYPT        ((UINT16)BIT4)
+#define                HFA384x_WEPFLAGS_DISABLE_RXCRYPT        ((UINT16)BIT7)
+#define                HFA384x_WEPFLAGS_DISALLOW_MIXED         ((UINT16)BIT11)
+#define                HFA384x_WEPFLAGS_IV_INTERVAL1           ((UINT16)0)
+#define                HFA384x_WEPFLAGS_IV_INTERVAL10          ((UINT16)BIT5)
+#define                HFA384x_WEPFLAGS_IV_INTERVAL50          ((UINT16)BIT6)
+#define                HFA384x_WEPFLAGS_IV_INTERVAL100         ((UINT16)(BIT5 | BIT6))
+#define                HFA384x_WEPFLAGS_FIRMWARE_WPA           ((UINT16)BIT8)
+#define                HFA384x_WEPFLAGS_HOST_MIC               ((UINT16)BIT9)
+#define        HFA384x_ROAMMODE_FWSCAN_FWROAM          ((UINT16)1)
+#define        HFA384x_ROAMMODE_FWSCAN_HOSTROAM        ((UINT16)2)
+#define        HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM      ((UINT16)3)
+#define        HFA384x_PORTSTATUS_DISABLED             ((UINT16)1)
+#define        HFA384x_PORTSTATUS_INITSRCH             ((UINT16)2)
+#define        HFA384x_PORTSTATUS_CONN_IBSS            ((UINT16)3)
+#define        HFA384x_PORTSTATUS_CONN_ESS             ((UINT16)4)
+#define        HFA384x_PORTSTATUS_OOR_ESS              ((UINT16)5)
+#define        HFA384x_PORTSTATUS_CONN_WDS             ((UINT16)6)
+#define        HFA384x_PORTSTATUS_HOSTAP               ((UINT16)8)
+#define                HFA384x_RATEBIT_1                       ((UINT16)1)
+#define                HFA384x_RATEBIT_2                       ((UINT16)2)
+#define                HFA384x_RATEBIT_5dot5                   ((UINT16)4)
+#define                HFA384x_RATEBIT_11                      ((UINT16)8)
+
+/*--- Just some symbolic names for legibility -------*/
+#define                HFA384x_TXCMD_NORECL            ((UINT16)0)
+#define                HFA384x_TXCMD_RECL              ((UINT16)1)
+
+/*--- MAC Internal memory constants and macros ------*/
+/* masks and macros used to manipulate MAC internal memory addresses. */
+/* MAC internal memory addresses are 23 bit quantities.  The MAC uses
+ * a paged address space where the upper 16 bits are the page number
+ * and the lower 7 bits are the offset.  There are various Host API
+ * elements that require two 16-bit quantities to specify a MAC
+ * internal memory address.  Unfortunately, some of the API's use a
+ * page/offset format where the offset value is JUST the lower seven
+ * bits and the page is  the remaining 16 bits.  Some of the API's
+ * assume that the 23 bit address has been split at the 16th bit.  We
+ * refer to these two formats as AUX format and CMD format.  The
+ * macros below help handle some of this.
+ */
+
+/* Handy constant */
+#define                HFA384x_ADDR_AUX_OFF_MAX        ((UINT16)0x007f)
+
+/* Mask bits for discarding unwanted pieces in a flat address */
+#define                HFA384x_ADDR_FLAT_AUX_PAGE_MASK (0x007fff80)
+#define                HFA384x_ADDR_FLAT_AUX_OFF_MASK  (0x0000007f)
+#define                HFA384x_ADDR_FLAT_CMD_PAGE_MASK (0xffff0000)
+#define                HFA384x_ADDR_FLAT_CMD_OFF_MASK  (0x0000ffff)
+
+/* Mask bits for discarding unwanted pieces in AUX format 16-bit address parts */
+#define                HFA384x_ADDR_AUX_PAGE_MASK      (0xffff)
+#define                HFA384x_ADDR_AUX_OFF_MASK       (0x007f)
+
+/* Mask bits for discarding unwanted pieces in CMD format 16-bit address parts */
+#define                HFA384x_ADDR_CMD_PAGE_MASK      (0x007f)
+#define                HFA384x_ADDR_CMD_OFF_MASK       (0xffff)
+
+/* Make a 32-bit flat address from AUX format 16-bit page and offset */
+#define                HFA384x_ADDR_AUX_MKFLAT(p,o)    \
+               (((UINT32)(((UINT16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) <<7) | \
+               ((UINT32)(((UINT16)(o))&HFA384x_ADDR_AUX_OFF_MASK))
+
+/* Make a 32-bit flat address from CMD format 16-bit page and offset */
+#define                HFA384x_ADDR_CMD_MKFLAT(p,o)    \
+               (((UINT32)(((UINT16)(p))&HFA384x_ADDR_CMD_PAGE_MASK)) <<16) | \
+               ((UINT32)(((UINT16)(o))&HFA384x_ADDR_CMD_OFF_MASK))
+
+/* Make AUX format offset and page from a 32-bit flat address */
+#define                HFA384x_ADDR_AUX_MKPAGE(f) \
+               ((UINT16)((((UINT32)(f))&HFA384x_ADDR_FLAT_AUX_PAGE_MASK)>>7))
+#define                HFA384x_ADDR_AUX_MKOFF(f) \
+               ((UINT16)(((UINT32)(f))&HFA384x_ADDR_FLAT_AUX_OFF_MASK))
+
+/* Make CMD format offset and page from a 32-bit flat address */
+#define                HFA384x_ADDR_CMD_MKPAGE(f) \
+               ((UINT16)((((UINT32)(f))&HFA384x_ADDR_FLAT_CMD_PAGE_MASK)>>16))
+#define                HFA384x_ADDR_CMD_MKOFF(f) \
+               ((UINT16)(((UINT32)(f))&HFA384x_ADDR_FLAT_CMD_OFF_MASK))
+
+/*--- Aux register masks/tests ----------------------*/
+/* Some of the upper bits of the AUX offset register are used to */
+/*  select address space. */
+#define                HFA384x_AUX_CTL_EXTDS   (0x00)
+#define                HFA384x_AUX_CTL_NV      (0x01)
+#define                HFA384x_AUX_CTL_PHY     (0x02)
+#define                HFA384x_AUX_CTL_ICSRAM  (0x03)
+
+/* Make AUX register offset and page values from a flat address */
+#define                HFA384x_AUX_MKOFF(f, c) \
+       (HFA384x_ADDR_AUX_MKOFF(f) | (((UINT16)(c))<<12))
+#define                HFA384x_AUX_MKPAGE(f)   HFA384x_ADDR_AUX_MKPAGE(f)
+
+
+/*--- Controller Memory addresses -------------------*/
+#define                HFA3842_PDA_BASE        (0x007f0000UL)
+#define                HFA3841_PDA_BASE        (0x003f0000UL)
+#define                HFA3841_PDA_BOGUS_BASE  (0x00390000UL)
+
+/*--- Driver Download states  -----------------------*/
+#define                HFA384x_DLSTATE_DISABLED                0
+#define                HFA384x_DLSTATE_RAMENABLED              1
+#define                HFA384x_DLSTATE_FLASHENABLED            2
+#define                HFA384x_DLSTATE_FLASHWRITTEN            3
+#define                HFA384x_DLSTATE_FLASHWRITEPENDING       4
+#define                HFA384x_DLSTATE_GENESIS                 5
+
+/*--- Register I/O offsets --------------------------*/
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+
+#define                HFA384x_CMD_OFF                 (0x00)
+#define                HFA384x_PARAM0_OFF              (0x02)
+#define                HFA384x_PARAM1_OFF              (0x04)
+#define                HFA384x_PARAM2_OFF              (0x06)
+#define                HFA384x_STATUS_OFF              (0x08)
+#define                HFA384x_RESP0_OFF               (0x0A)
+#define                HFA384x_RESP1_OFF               (0x0C)
+#define                HFA384x_RESP2_OFF               (0x0E)
+#define                HFA384x_INFOFID_OFF             (0x10)
+#define                HFA384x_RXFID_OFF               (0x20)
+#define                HFA384x_ALLOCFID_OFF            (0x22)
+#define                HFA384x_TXCOMPLFID_OFF          (0x24)
+#define                HFA384x_SELECT0_OFF             (0x18)
+#define                HFA384x_OFFSET0_OFF             (0x1C)
+#define                HFA384x_DATA0_OFF               (0x36)
+#define                HFA384x_SELECT1_OFF             (0x1A)
+#define                HFA384x_OFFSET1_OFF             (0x1E)
+#define                HFA384x_DATA1_OFF               (0x38)
+#define                HFA384x_EVSTAT_OFF              (0x30)
+#define                HFA384x_INTEN_OFF               (0x32)
+#define                HFA384x_EVACK_OFF               (0x34)
+#define                HFA384x_CONTROL_OFF             (0x14)
+#define                HFA384x_SWSUPPORT0_OFF          (0x28)
+#define                HFA384x_SWSUPPORT1_OFF          (0x2A)
+#define                HFA384x_SWSUPPORT2_OFF          (0x2C)
+#define                HFA384x_AUXPAGE_OFF             (0x3A)
+#define                HFA384x_AUXOFFSET_OFF           (0x3C)
+#define                HFA384x_AUXDATA_OFF             (0x3E)
+
+#elif (WLAN_HOSTIF == WLAN_PCI || WLAN_HOSTIF == WLAN_USB)
+
+#define                HFA384x_CMD_OFF                 (0x00)
+#define                HFA384x_PARAM0_OFF              (0x04)
+#define                HFA384x_PARAM1_OFF              (0x08)
+#define                HFA384x_PARAM2_OFF              (0x0c)
+#define                HFA384x_STATUS_OFF              (0x10)
+#define                HFA384x_RESP0_OFF               (0x14)
+#define                HFA384x_RESP1_OFF               (0x18)
+#define                HFA384x_RESP2_OFF               (0x1c)
+#define                HFA384x_INFOFID_OFF             (0x20)
+#define                HFA384x_RXFID_OFF               (0x40)
+#define                HFA384x_ALLOCFID_OFF            (0x44)
+#define                HFA384x_TXCOMPLFID_OFF          (0x48)
+#define                HFA384x_SELECT0_OFF             (0x30)
+#define                HFA384x_OFFSET0_OFF             (0x38)
+#define                HFA384x_DATA0_OFF               (0x6c)
+#define                HFA384x_SELECT1_OFF             (0x34)
+#define                HFA384x_OFFSET1_OFF             (0x3c)
+#define                HFA384x_DATA1_OFF               (0x70)
+#define                HFA384x_EVSTAT_OFF              (0x60)
+#define                HFA384x_INTEN_OFF               (0x64)
+#define                HFA384x_EVACK_OFF               (0x68)
+#define                HFA384x_CONTROL_OFF             (0x28)
+#define                HFA384x_SWSUPPORT0_OFF          (0x50)
+#define                HFA384x_SWSUPPORT1_OFF          (0x54)
+#define                HFA384x_SWSUPPORT2_OFF          (0x58)
+#define                HFA384x_AUXPAGE_OFF             (0x74)
+#define                HFA384x_AUXOFFSET_OFF           (0x78)
+#define                HFA384x_AUXDATA_OFF             (0x7c)
+#define                HFA384x_PCICOR_OFF              (0x4c)
+#define                HFA384x_PCIHCR_OFF              (0x5c)
+#define                HFA384x_PCI_M0_ADDRH_OFF        (0x80)
+#define                HFA384x_PCI_M0_ADDRL_OFF        (0x84)
+#define                HFA384x_PCI_M0_LEN_OFF          (0x88)
+#define                HFA384x_PCI_M0_CTL_OFF          (0x8c)
+#define                HFA384x_PCI_STATUS_OFF          (0x98)
+#define                HFA384x_PCI_M1_ADDRH_OFF        (0xa0)
+#define                HFA384x_PCI_M1_ADDRL_OFF        (0xa4)
+#define                HFA384x_PCI_M1_LEN_OFF          (0xa8)
+#define                HFA384x_PCI_M1_CTL_OFF          (0xac)
+
+#endif
+
+/*--- Register Field Masks --------------------------*/
+#define                HFA384x_CMD_BUSY                ((UINT16)BIT15)
+#define                HFA384x_CMD_AINFO               ((UINT16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
+#define                HFA384x_CMD_MACPORT             ((UINT16)(BIT10 | BIT9 | BIT8))
+#define                HFA384x_CMD_RECL                ((UINT16)BIT8)
+#define                HFA384x_CMD_WRITE               ((UINT16)BIT8)
+#define                HFA384x_CMD_PROGMODE            ((UINT16)(BIT9 | BIT8))
+#define                HFA384x_CMD_CMDCODE             ((UINT16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
+
+#define                HFA384x_STATUS_RESULT           ((UINT16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
+#define                HFA384x_STATUS_CMDCODE          ((UINT16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
+
+#define                HFA384x_OFFSET_BUSY             ((UINT16)BIT15)
+#define                HFA384x_OFFSET_ERR              ((UINT16)BIT14)
+#define                HFA384x_OFFSET_DATAOFF          ((UINT16)(BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1))
+
+#define                HFA384x_EVSTAT_TICK             ((UINT16)BIT15)
+#define                HFA384x_EVSTAT_WTERR            ((UINT16)BIT14)
+#define                HFA384x_EVSTAT_INFDROP          ((UINT16)BIT13)
+#define                HFA384x_EVSTAT_INFO             ((UINT16)BIT7)
+#define                HFA384x_EVSTAT_DTIM             ((UINT16)BIT5)
+#define                HFA384x_EVSTAT_CMD              ((UINT16)BIT4)
+#define                HFA384x_EVSTAT_ALLOC            ((UINT16)BIT3)
+#define                HFA384x_EVSTAT_TXEXC            ((UINT16)BIT2)
+#define                HFA384x_EVSTAT_TX               ((UINT16)BIT1)
+#define                HFA384x_EVSTAT_RX               ((UINT16)BIT0)
+
+#define         HFA384x_INT_BAP_OP           (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC)
+
+#define         HFA384x_INT_NORMAL           (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC|HFA384x_EVSTAT_INFDROP|HFA384x_EVSTAT_ALLOC|HFA384x_EVSTAT_DTIM)
+
+#define                HFA384x_INTEN_TICK              ((UINT16)BIT15)
+#define                HFA384x_INTEN_WTERR             ((UINT16)BIT14)
+#define                HFA384x_INTEN_INFDROP           ((UINT16)BIT13)
+#define                HFA384x_INTEN_INFO              ((UINT16)BIT7)
+#define                HFA384x_INTEN_DTIM              ((UINT16)BIT5)
+#define                HFA384x_INTEN_CMD               ((UINT16)BIT4)
+#define                HFA384x_INTEN_ALLOC             ((UINT16)BIT3)
+#define                HFA384x_INTEN_TXEXC             ((UINT16)BIT2)
+#define                HFA384x_INTEN_TX                ((UINT16)BIT1)
+#define                HFA384x_INTEN_RX                ((UINT16)BIT0)
+
+#define                HFA384x_EVACK_TICK              ((UINT16)BIT15)
+#define                HFA384x_EVACK_WTERR             ((UINT16)BIT14)
+#define                HFA384x_EVACK_INFDROP           ((UINT16)BIT13)
+#define                HFA384x_EVACK_INFO              ((UINT16)BIT7)
+#define                HFA384x_EVACK_DTIM              ((UINT16)BIT5)
+#define                HFA384x_EVACK_CMD               ((UINT16)BIT4)
+#define                HFA384x_EVACK_ALLOC             ((UINT16)BIT3)
+#define                HFA384x_EVACK_TXEXC             ((UINT16)BIT2)
+#define                HFA384x_EVACK_TX                ((UINT16)BIT1)
+#define                HFA384x_EVACK_RX                ((UINT16)BIT0)
+
+#define                HFA384x_CONTROL_AUXEN           ((UINT16)(BIT15 | BIT14))
+
+
+/*--- Command Code Constants --------------------------*/
+/*--- Controller Commands --------------------------*/
+#define                HFA384x_CMDCODE_INIT            ((UINT16)0x00)
+#define                HFA384x_CMDCODE_ENABLE          ((UINT16)0x01)
+#define                HFA384x_CMDCODE_DISABLE         ((UINT16)0x02)
+#define                HFA384x_CMDCODE_DIAG            ((UINT16)0x03)
+
+/*--- Buffer Mgmt Commands --------------------------*/
+#define                HFA384x_CMDCODE_ALLOC           ((UINT16)0x0A)
+#define                HFA384x_CMDCODE_TX              ((UINT16)0x0B)
+#define                HFA384x_CMDCODE_CLRPRST         ((UINT16)0x12)
+
+/*--- Regulate Commands --------------------------*/
+#define                HFA384x_CMDCODE_NOTIFY          ((UINT16)0x10)
+#define                HFA384x_CMDCODE_INQ             ((UINT16)0x11)
+
+/*--- Configure Commands --------------------------*/
+#define                HFA384x_CMDCODE_ACCESS          ((UINT16)0x21)
+#define                HFA384x_CMDCODE_DOWNLD          ((UINT16)0x22)
+
+/*--- Debugging Commands -----------------------------*/
+#define        HFA384x_CMDCODE_MONITOR         ((UINT16)(0x38))
+#define                HFA384x_MONITOR_ENABLE          ((UINT16)(0x0b))
+#define                HFA384x_MONITOR_DISABLE         ((UINT16)(0x0f))
+
+/*--- Result Codes --------------------------*/
+#define                HFA384x_SUCCESS                 ((UINT16)(0x00))
+#define                HFA384x_CARD_FAIL               ((UINT16)(0x01))
+#define                HFA384x_NO_BUFF                 ((UINT16)(0x05))
+#define                HFA384x_CMD_ERR                 ((UINT16)(0x7F))
+
+/*--- Programming Modes --------------------------
+       MODE 0: Disable programming
+       MODE 1: Enable volatile memory programming
+       MODE 2: Enable non-volatile memory programming
+       MODE 3: Program non-volatile memory section
+--------------------------------------------------*/
+#define                HFA384x_PROGMODE_DISABLE        ((UINT16)0x00)
+#define                HFA384x_PROGMODE_RAM            ((UINT16)0x01)
+#define                HFA384x_PROGMODE_NV             ((UINT16)0x02)
+#define                HFA384x_PROGMODE_NVWRITE        ((UINT16)0x03)
+
+/*--- AUX register enable --------------------------*/
+#define                HFA384x_AUXPW0                  ((UINT16)0xfe01)
+#define                HFA384x_AUXPW1                  ((UINT16)0xdc23)
+#define                HFA384x_AUXPW2                  ((UINT16)0xba45)
+
+#define                HFA384x_CONTROL_AUX_ISDISABLED  ((UINT16)0x0000)
+#define                HFA384x_CONTROL_AUX_ISENABLED   ((UINT16)0xc000)
+#define                HFA384x_CONTROL_AUX_DOENABLE    ((UINT16)0x8000)
+#define                HFA384x_CONTROL_AUX_DODISABLE   ((UINT16)0x4000)
+
+/*--- Record ID Constants --------------------------*/
+/*--------------------------------------------------------------------
+Configuration RIDs: Network Parameters, Static Configuration Entities
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_CNFPORTTYPE         ((UINT16)0xFC00)
+#define                HFA384x_RID_CNFOWNMACADDR       ((UINT16)0xFC01)
+#define                HFA384x_RID_CNFDESIREDSSID      ((UINT16)0xFC02)
+#define                HFA384x_RID_CNFOWNCHANNEL       ((UINT16)0xFC03)
+#define                HFA384x_RID_CNFOWNSSID          ((UINT16)0xFC04)
+#define                HFA384x_RID_CNFOWNATIMWIN       ((UINT16)0xFC05)
+#define                HFA384x_RID_CNFSYSSCALE         ((UINT16)0xFC06)
+#define                HFA384x_RID_CNFMAXDATALEN       ((UINT16)0xFC07)
+#define                HFA384x_RID_CNFWDSADDR          ((UINT16)0xFC08)
+#define                HFA384x_RID_CNFPMENABLED        ((UINT16)0xFC09)
+#define                HFA384x_RID_CNFPMEPS            ((UINT16)0xFC0A)
+#define                HFA384x_RID_CNFMULTICASTRX      ((UINT16)0xFC0B)
+#define                HFA384x_RID_CNFMAXSLEEPDUR      ((UINT16)0xFC0C)
+#define                HFA384x_RID_CNFPMHOLDDUR        ((UINT16)0xFC0D)
+#define                HFA384x_RID_CNFOWNNAME          ((UINT16)0xFC0E)
+#define                HFA384x_RID_CNFOWNDTIMPER       ((UINT16)0xFC10)
+#define                HFA384x_RID_CNFWDSADDR1         ((UINT16)0xFC11)
+#define                HFA384x_RID_CNFWDSADDR2         ((UINT16)0xFC12)
+#define                HFA384x_RID_CNFWDSADDR3         ((UINT16)0xFC13)
+#define                HFA384x_RID_CNFWDSADDR4         ((UINT16)0xFC14)
+#define                HFA384x_RID_CNFWDSADDR5         ((UINT16)0xFC15)
+#define                HFA384x_RID_CNFWDSADDR6         ((UINT16)0xFC16)
+#define                HFA384x_RID_CNFMCASTPMBUFF      ((UINT16)0xFC17)
+
+/*--------------------------------------------------------------------
+Configuration RID lengths: Network Params, Static Config Entities
+  This is the length of JUST the DATA part of the RID (does not
+  include the len or code fields)
+--------------------------------------------------------------------*/
+/* TODO: fill in the rest of these */
+#define                HFA384x_RID_CNFPORTTYPE_LEN     ((UINT16)2)
+#define                HFA384x_RID_CNFOWNMACADDR_LEN   ((UINT16)6)
+#define                HFA384x_RID_CNFDESIREDSSID_LEN  ((UINT16)34)
+#define                HFA384x_RID_CNFOWNCHANNEL_LEN   ((UINT16)2)
+#define                HFA384x_RID_CNFOWNSSID_LEN      ((UINT16)34)
+#define                HFA384x_RID_CNFOWNATIMWIN_LEN   ((UINT16)2)
+#define                HFA384x_RID_CNFSYSSCALE_LEN     ((UINT16)0)
+#define                HFA384x_RID_CNFMAXDATALEN_LEN   ((UINT16)0)
+#define                HFA384x_RID_CNFWDSADDR_LEN      ((UINT16)6)
+#define                HFA384x_RID_CNFPMENABLED_LEN    ((UINT16)0)
+#define                HFA384x_RID_CNFPMEPS_LEN        ((UINT16)0)
+#define                HFA384x_RID_CNFMULTICASTRX_LEN  ((UINT16)0)
+#define                HFA384x_RID_CNFMAXSLEEPDUR_LEN  ((UINT16)0)
+#define                HFA384x_RID_CNFPMHOLDDUR_LEN    ((UINT16)0)
+#define                HFA384x_RID_CNFOWNNAME_LEN      ((UINT16)34)
+#define                HFA384x_RID_CNFOWNDTIMPER_LEN   ((UINT16)0)
+#define                HFA384x_RID_CNFWDSADDR1_LEN     ((UINT16)6)
+#define                HFA384x_RID_CNFWDSADDR2_LEN     ((UINT16)6)
+#define                HFA384x_RID_CNFWDSADDR3_LEN     ((UINT16)6)
+#define                HFA384x_RID_CNFWDSADDR4_LEN     ((UINT16)6)
+#define                HFA384x_RID_CNFWDSADDR5_LEN     ((UINT16)6)
+#define                HFA384x_RID_CNFWDSADDR6_LEN     ((UINT16)6)
+#define                HFA384x_RID_CNFMCASTPMBUFF_LEN  ((UINT16)0)
+#define                HFA384x_RID_CNFAUTHENTICATION_LEN ((UINT16)sizeof(UINT16))
+#define                HFA384x_RID_CNFMAXSLEEPDUR_LEN  ((UINT16)0)
+
+/*--------------------------------------------------------------------
+Configuration RIDs: Network Parameters, Dynamic Configuration Entities
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_GROUPADDR           ((UINT16)0xFC80)
+#define                HFA384x_RID_CREATEIBSS          ((UINT16)0xFC81)
+#define                HFA384x_RID_FRAGTHRESH          ((UINT16)0xFC82)
+#define                HFA384x_RID_RTSTHRESH           ((UINT16)0xFC83)
+#define                HFA384x_RID_TXRATECNTL          ((UINT16)0xFC84)
+#define                HFA384x_RID_PROMISCMODE         ((UINT16)0xFC85)
+#define                HFA384x_RID_FRAGTHRESH0         ((UINT16)0xFC90)
+#define                HFA384x_RID_FRAGTHRESH1         ((UINT16)0xFC91)
+#define                HFA384x_RID_FRAGTHRESH2         ((UINT16)0xFC92)
+#define                HFA384x_RID_FRAGTHRESH3         ((UINT16)0xFC93)
+#define                HFA384x_RID_FRAGTHRESH4         ((UINT16)0xFC94)
+#define                HFA384x_RID_FRAGTHRESH5         ((UINT16)0xFC95)
+#define                HFA384x_RID_FRAGTHRESH6         ((UINT16)0xFC96)
+#define                HFA384x_RID_RTSTHRESH0          ((UINT16)0xFC97)
+#define                HFA384x_RID_RTSTHRESH1          ((UINT16)0xFC98)
+#define                HFA384x_RID_RTSTHRESH2          ((UINT16)0xFC99)
+#define                HFA384x_RID_RTSTHRESH3          ((UINT16)0xFC9A)
+#define                HFA384x_RID_RTSTHRESH4          ((UINT16)0xFC9B)
+#define                HFA384x_RID_RTSTHRESH5          ((UINT16)0xFC9C)
+#define                HFA384x_RID_RTSTHRESH6          ((UINT16)0xFC9D)
+#define                HFA384x_RID_TXRATECNTL0         ((UINT16)0xFC9E)
+#define                HFA384x_RID_TXRATECNTL1         ((UINT16)0xFC9F)
+#define                HFA384x_RID_TXRATECNTL2         ((UINT16)0xFCA0)
+#define                HFA384x_RID_TXRATECNTL3         ((UINT16)0xFCA1)
+#define                HFA384x_RID_TXRATECNTL4         ((UINT16)0xFCA2)
+#define                HFA384x_RID_TXRATECNTL5         ((UINT16)0xFCA3)
+#define                HFA384x_RID_TXRATECNTL6         ((UINT16)0xFCA4)
+
+/*--------------------------------------------------------------------
+Configuration RID Lengths: Network Param, Dynamic Config Entities
+  This is the length of JUST the DATA part of the RID (does not
+  include the len or code fields)
+--------------------------------------------------------------------*/
+/* TODO: fill in the rest of these */
+#define                HFA384x_RID_GROUPADDR_LEN       ((UINT16)16 * WLAN_ADDR_LEN)
+#define                HFA384x_RID_CREATEIBSS_LEN      ((UINT16)0)
+#define                HFA384x_RID_FRAGTHRESH_LEN      ((UINT16)0)
+#define                HFA384x_RID_RTSTHRESH_LEN       ((UINT16)0)
+#define                HFA384x_RID_TXRATECNTL_LEN      ((UINT16)4)
+#define                HFA384x_RID_PROMISCMODE_LEN     ((UINT16)2)
+#define                HFA384x_RID_FRAGTHRESH0_LEN     ((UINT16)0)
+#define                HFA384x_RID_FRAGTHRESH1_LEN     ((UINT16)0)
+#define                HFA384x_RID_FRAGTHRESH2_LEN     ((UINT16)0)
+#define                HFA384x_RID_FRAGTHRESH3_LEN     ((UINT16)0)
+#define                HFA384x_RID_FRAGTHRESH4_LEN     ((UINT16)0)
+#define                HFA384x_RID_FRAGTHRESH5_LEN     ((UINT16)0)
+#define                HFA384x_RID_FRAGTHRESH6_LEN     ((UINT16)0)
+#define                HFA384x_RID_RTSTHRESH0_LEN      ((UINT16)0)
+#define                HFA384x_RID_RTSTHRESH1_LEN      ((UINT16)0)
+#define                HFA384x_RID_RTSTHRESH2_LEN      ((UINT16)0)
+#define                HFA384x_RID_RTSTHRESH3_LEN      ((UINT16)0)
+#define                HFA384x_RID_RTSTHRESH4_LEN      ((UINT16)0)
+#define                HFA384x_RID_RTSTHRESH5_LEN      ((UINT16)0)
+#define                HFA384x_RID_RTSTHRESH6_LEN      ((UINT16)0)
+#define                HFA384x_RID_TXRATECNTL0_LEN     ((UINT16)0)
+#define                HFA384x_RID_TXRATECNTL1_LEN     ((UINT16)0)
+#define                HFA384x_RID_TXRATECNTL2_LEN     ((UINT16)0)
+#define                HFA384x_RID_TXRATECNTL3_LEN     ((UINT16)0)
+#define                HFA384x_RID_TXRATECNTL4_LEN     ((UINT16)0)
+#define                HFA384x_RID_TXRATECNTL5_LEN     ((UINT16)0)
+#define                HFA384x_RID_TXRATECNTL6_LEN     ((UINT16)0)
+
+/*--------------------------------------------------------------------
+Configuration RIDs: Behavior Parameters
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_ITICKTIME           ((UINT16)0xFCE0)
+
+/*--------------------------------------------------------------------
+Configuration RID Lengths: Behavior Parameters
+  This is the length of JUST the DATA part of the RID (does not
+  include the len or code fields)
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_ITICKTIME_LEN       ((UINT16)2)
+
+/*----------------------------------------------------------------------
+Information RIDs: NIC Information
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_MAXLOADTIME         ((UINT16)0xFD00)
+#define                HFA384x_RID_DOWNLOADBUFFER      ((UINT16)0xFD01)
+#define                HFA384x_RID_PRIIDENTITY         ((UINT16)0xFD02)
+#define                HFA384x_RID_PRISUPRANGE         ((UINT16)0xFD03)
+#define                HFA384x_RID_PRI_CFIACTRANGES    ((UINT16)0xFD04)
+#define                HFA384x_RID_NICSERIALNUMBER     ((UINT16)0xFD0A)
+#define                HFA384x_RID_NICIDENTITY         ((UINT16)0xFD0B)
+#define                HFA384x_RID_MFISUPRANGE         ((UINT16)0xFD0C)
+#define                HFA384x_RID_CFISUPRANGE         ((UINT16)0xFD0D)
+#define                HFA384x_RID_CHANNELLIST         ((UINT16)0xFD10)
+#define                HFA384x_RID_REGULATORYDOMAINS   ((UINT16)0xFD11)
+#define                HFA384x_RID_TEMPTYPE            ((UINT16)0xFD12)
+#define                HFA384x_RID_CIS                 ((UINT16)0xFD13)
+#define                HFA384x_RID_STAIDENTITY         ((UINT16)0xFD20)
+#define                HFA384x_RID_STASUPRANGE         ((UINT16)0xFD21)
+#define                HFA384x_RID_STA_MFIACTRANGES    ((UINT16)0xFD22)
+#define                HFA384x_RID_STA_CFIACTRANGES    ((UINT16)0xFD23)
+#define                HFA384x_RID_BUILDSEQ            ((UINT16)0xFFFE)
+#define                HFA384x_RID_FWID                ((UINT16)0xFFFF)
+
+/*----------------------------------------------------------------------
+Information RID Lengths: NIC Information
+  This is the length of JUST the DATA part of the RID (does not
+  include the len or code fields)
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_MAXLOADTIME_LEN             ((UINT16)0)
+#define                HFA384x_RID_DOWNLOADBUFFER_LEN          ((UINT16)sizeof(hfa384x_downloadbuffer_t))
+#define                HFA384x_RID_PRIIDENTITY_LEN             ((UINT16)8)
+#define                HFA384x_RID_PRISUPRANGE_LEN             ((UINT16)10)
+#define                HFA384x_RID_CFIACTRANGES_LEN            ((UINT16)10)
+#define                HFA384x_RID_NICSERIALNUMBER_LEN         ((UINT16)12)
+#define                HFA384x_RID_NICIDENTITY_LEN             ((UINT16)8)
+#define                HFA384x_RID_MFISUPRANGE_LEN             ((UINT16)10)
+#define                HFA384x_RID_CFISUPRANGE_LEN             ((UINT16)10)
+#define                HFA384x_RID_CHANNELLIST_LEN             ((UINT16)0)
+#define                HFA384x_RID_REGULATORYDOMAINS_LEN       ((UINT16)12)
+#define                HFA384x_RID_TEMPTYPE_LEN                ((UINT16)0)
+#define                HFA384x_RID_CIS_LEN                     ((UINT16)480)
+#define                HFA384x_RID_STAIDENTITY_LEN             ((UINT16)8)
+#define                HFA384x_RID_STASUPRANGE_LEN             ((UINT16)10)
+#define                HFA384x_RID_MFIACTRANGES_LEN            ((UINT16)10)
+#define                HFA384x_RID_CFIACTRANGES2_LEN           ((UINT16)10)
+#define                HFA384x_RID_BUILDSEQ_LEN                ((UINT16)sizeof(hfa384x_BuildSeq_t))
+#define                HFA384x_RID_FWID_LEN                    ((UINT16)sizeof(hfa384x_FWID_t))
+
+/*--------------------------------------------------------------------
+Information RIDs:  MAC Information
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_PORTSTATUS          ((UINT16)0xFD40)
+#define                HFA384x_RID_CURRENTSSID         ((UINT16)0xFD41)
+#define                HFA384x_RID_CURRENTBSSID        ((UINT16)0xFD42)
+#define                HFA384x_RID_COMMSQUALITY        ((UINT16)0xFD43)
+#define                HFA384x_RID_CURRENTTXRATE       ((UINT16)0xFD44)
+#define                HFA384x_RID_CURRENTBCNINT       ((UINT16)0xFD45)
+#define                HFA384x_RID_CURRENTSCALETHRESH  ((UINT16)0xFD46)
+#define                HFA384x_RID_PROTOCOLRSPTIME     ((UINT16)0xFD47)
+#define                HFA384x_RID_SHORTRETRYLIMIT     ((UINT16)0xFD48)
+#define                HFA384x_RID_LONGRETRYLIMIT      ((UINT16)0xFD49)
+#define                HFA384x_RID_MAXTXLIFETIME       ((UINT16)0xFD4A)
+#define                HFA384x_RID_MAXRXLIFETIME       ((UINT16)0xFD4B)
+#define                HFA384x_RID_CFPOLLABLE          ((UINT16)0xFD4C)
+#define                HFA384x_RID_AUTHALGORITHMS      ((UINT16)0xFD4D)
+#define                HFA384x_RID_PRIVACYOPTIMP       ((UINT16)0xFD4F)
+#define                HFA384x_RID_DBMCOMMSQUALITY     ((UINT16)0xFD51)
+#define                HFA384x_RID_CURRENTTXRATE1      ((UINT16)0xFD80)
+#define                HFA384x_RID_CURRENTTXRATE2      ((UINT16)0xFD81)
+#define                HFA384x_RID_CURRENTTXRATE3      ((UINT16)0xFD82)
+#define                HFA384x_RID_CURRENTTXRATE4      ((UINT16)0xFD83)
+#define                HFA384x_RID_CURRENTTXRATE5      ((UINT16)0xFD84)
+#define                HFA384x_RID_CURRENTTXRATE6      ((UINT16)0xFD85)
+#define                HFA384x_RID_OWNMACADDRESS       ((UINT16)0xFD86)
+// #define     HFA384x_RID_PCFINFO             ((UINT16)0xFD87)
+#define                HFA384x_RID_SCANRESULTS         ((UINT16)0xFD88) // NEW
+#define                HFA384x_RID_HOSTSCANRESULTS     ((UINT16)0xFD89) // NEW
+#define                HFA384x_RID_AUTHENTICATIONUSED  ((UINT16)0xFD8A) // NEW
+#define                HFA384x_RID_ASSOCIATEFAILURE    ((UINT16)0xFD8D) // 1.8.0
+
+/*--------------------------------------------------------------------
+Information RID Lengths:  MAC Information
+  This is the length of JUST the DATA part of the RID (does not
+  include the len or code fields)
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_PORTSTATUS_LEN              ((UINT16)0)
+#define                HFA384x_RID_CURRENTSSID_LEN             ((UINT16)34)
+#define                HFA384x_RID_CURRENTBSSID_LEN            ((UINT16)WLAN_BSSID_LEN)
+#define                HFA384x_RID_COMMSQUALITY_LEN            ((UINT16)sizeof(hfa384x_commsquality_t))
+#define                HFA384x_RID_DBMCOMMSQUALITY_LEN         ((UINT16)sizeof(hfa384x_dbmcommsquality_t))
+#define                HFA384x_RID_CURRENTTXRATE_LEN           ((UINT16)0)
+#define                HFA384x_RID_CURRENTBCNINT_LEN           ((UINT16)0)
+#define                HFA384x_RID_STACURSCALETHRESH_LEN       ((UINT16)12)
+#define                HFA384x_RID_APCURSCALETHRESH_LEN        ((UINT16)6)
+#define                HFA384x_RID_PROTOCOLRSPTIME_LEN         ((UINT16)0)
+#define                HFA384x_RID_SHORTRETRYLIMIT_LEN         ((UINT16)0)
+#define                HFA384x_RID_LONGRETRYLIMIT_LEN          ((UINT16)0)
+#define                HFA384x_RID_MAXTXLIFETIME_LEN           ((UINT16)0)
+#define                HFA384x_RID_MAXRXLIFETIME_LEN           ((UINT16)0)
+#define                HFA384x_RID_CFPOLLABLE_LEN              ((UINT16)0)
+#define                HFA384x_RID_AUTHALGORITHMS_LEN          ((UINT16)4)
+#define                HFA384x_RID_PRIVACYOPTIMP_LEN           ((UINT16)0)
+#define                HFA384x_RID_CURRENTTXRATE1_LEN          ((UINT16)0)
+#define                HFA384x_RID_CURRENTTXRATE2_LEN          ((UINT16)0)
+#define                HFA384x_RID_CURRENTTXRATE3_LEN          ((UINT16)0)
+#define                HFA384x_RID_CURRENTTXRATE4_LEN          ((UINT16)0)
+#define                HFA384x_RID_CURRENTTXRATE5_LEN          ((UINT16)0)
+#define                HFA384x_RID_CURRENTTXRATE6_LEN          ((UINT16)0)
+#define                HFA384x_RID_OWNMACADDRESS_LEN           ((UINT16)6)
+#define                HFA384x_RID_PCFINFO_LEN                 ((UINT16)6)
+#define                HFA384x_RID_CNFAPPCFINFO_LEN            ((UINT16)sizeof(hfa384x_PCFInfo_data_t))
+#define                HFA384x_RID_SCANREQUEST_LEN             ((UINT16)sizeof(hfa384x_ScanRequest_data_t))
+#define                HFA384x_RID_JOINREQUEST_LEN             ((UINT16)sizeof(hfa384x_JoinRequest_data_t))
+#define                HFA384x_RID_AUTHENTICATESTA_LEN         ((UINT16)sizeof(hfa384x_authenticateStation_data_t))
+#define                HFA384x_RID_CHANNELINFOREQUEST_LEN      ((UINT16)sizeof(hfa384x_ChannelInfoRequest_data_t))
+/*--------------------------------------------------------------------
+Information RIDs:  Modem Information
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_PHYTYPE             ((UINT16)0xFDC0)
+#define                HFA384x_RID_CURRENTCHANNEL      ((UINT16)0xFDC1)
+#define                HFA384x_RID_CURRENTPOWERSTATE   ((UINT16)0xFDC2)
+#define                HFA384x_RID_CCAMODE             ((UINT16)0xFDC3)
+#define                HFA384x_RID_SUPPORTEDDATARATES  ((UINT16)0xFDC6)
+#define                HFA384x_RID_LFOSTATUS           ((UINT16)0xFDC7) // 1.7.1
+
+/*--------------------------------------------------------------------
+Information RID Lengths:  Modem Information
+  This is the length of JUST the DATA part of the RID (does not
+  include the len or code fields)
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_PHYTYPE_LEN                 ((UINT16)0)
+#define                HFA384x_RID_CURRENTCHANNEL_LEN          ((UINT16)0)
+#define                HFA384x_RID_CURRENTPOWERSTATE_LEN       ((UINT16)0)
+#define                HFA384x_RID_CCAMODE_LEN                 ((UINT16)0)
+#define                HFA384x_RID_SUPPORTEDDATARATES_LEN      ((UINT16)10)
+
+/*--------------------------------------------------------------------
+API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
+--------------------------------------------------------------------*/
+#define                HFA384x_RID_CNFWEPDEFAULTKEYID  ((UINT16)0xFC23)
+#define                HFA384x_RID_CNFWEPDEFAULTKEY0   ((UINT16)0xFC24)
+#define                HFA384x_RID_CNFWEPDEFAULTKEY1   ((UINT16)0xFC25)
+#define                HFA384x_RID_CNFWEPDEFAULTKEY2   ((UINT16)0xFC26)
+#define                HFA384x_RID_CNFWEPDEFAULTKEY3   ((UINT16)0xFC27)
+#define                HFA384x_RID_CNFWEPFLAGS         ((UINT16)0xFC28)
+#define                HFA384x_RID_CNFWEPKEYMAPTABLE   ((UINT16)0xFC29)
+#define                HFA384x_RID_CNFAUTHENTICATION   ((UINT16)0xFC2A)
+#define                HFA384x_RID_CNFMAXASSOCSTATIONS ((UINT16)0xFC2B)
+#define                HFA384x_RID_CNFTXCONTROL        ((UINT16)0xFC2C)
+#define                HFA384x_RID_CNFROAMINGMODE      ((UINT16)0xFC2D)
+#define                HFA384x_RID_CNFHOSTAUTHASSOC    ((UINT16)0xFC2E)
+#define                HFA384x_RID_CNFRCVCRCERROR      ((UINT16)0xFC30)
+// #define             HFA384x_RID_CNFMMLIFE           ((UINT16)0xFC31)
+#define                HFA384x_RID_CNFALTRETRYCNT      ((UINT16)0xFC32)
+#define                HFA384x_RID_CNFAPBCNINT         ((UINT16)0xFC33)
+#define                HFA384x_RID_CNFAPPCFINFO        ((UINT16)0xFC34)
+#define                HFA384x_RID_CNFSTAPCFINFO       ((UINT16)0xFC35)
+#define                HFA384x_RID_CNFPRIORITYQUSAGE   ((UINT16)0xFC37)
+#define                HFA384x_RID_CNFTIMCTRL          ((UINT16)0xFC40)
+#define                HFA384x_RID_CNFTHIRTY2TALLY     ((UINT16)0xFC42)
+#define                HFA384x_RID_CNFENHSECURITY      ((UINT16)0xFC43)
+#define                HFA384x_RID_CNFDBMADJUST        ((UINT16)0xFC46) // NEW
+#define                HFA384x_RID_CNFWPADATA          ((UINT16)0xFC48) // 1.7.0
+#define                HFA384x_RID_CNFPROPOGATIONDELAY ((UINT16)0xFC49) // 1.7.6
+#define                HFA384x_RID_CNFSHORTPREAMBLE    ((UINT16)0xFCB0)
+#define                HFA384x_RID_CNFEXCLONGPREAMBLE  ((UINT16)0xFCB1)
+#define                HFA384x_RID_CNFAUTHRSPTIMEOUT   ((UINT16)0xFCB2)
+#define                HFA384x_RID_CNFBASICRATES       ((UINT16)0xFCB3)
+#define                HFA384x_RID_CNFSUPPRATES        ((UINT16)0xFCB4)
+#define                HFA384x_RID_CNFFALLBACKCTRL     ((UINT16)0xFCB5) // NEW
+#define                HFA384x_RID_WEPKEYSTATUS        ((UINT16)0xFCB6) // NEW
+#define                HFA384x_RID_WEPKEYMAPINDEX      ((UINT16)0xFCB7) // NEW
+#define                HFA384x_RID_BROADCASTKEYID      ((UINT16)0xFCB8) // NEW
+#define                HFA384x_RID_ENTSECFLAGEYID      ((UINT16)0xFCB9) // NEW
+#define                HFA384x_RID_CNFPASSIVESCANCTRL  ((UINT16)0xFCBA) // NEW STA
+#define                HFA384x_RID_CNFWPAHANDLING      ((UINT16)0xFCBB) // 1.7.0
+#define                HFA384x_RID_MDCCONTROL          ((UINT16)0xFCBC) // 1.7.0/1.4.0
+#define                HFA384x_RID_MDCCOUNTRY          ((UINT16)0xFCBD) // 1.7.0/1.4.0
+#define                HFA384x_RID_TXPOWERMAX          ((UINT16)0xFCBE) // 1.7.0/1.4.0
+#define                HFA384x_RID_CNFLFOENBLED        ((UINT16)0xFCBF) // 1.6.3
+#define         HFA384x_RID_CAPINFO             ((UINT16)0xFCC0) // 1.7.0/1.3.7
+#define         HFA384x_RID_LISTENINTERVAL      ((UINT16)0xFCC1) // 1.7.0/1.3.7
+#define         HFA384x_RID_DIVERSITYENABLED    ((UINT16)0xFCC2) // 1.7.0/1.3.7
+#define         HFA384x_RID_LED_CONTROL         ((UINT16)0xFCC4) // 1.7.6
+#define         HFA384x_RID_HFO_DELAY           ((UINT16)0xFCC5) // 1.7.6
+#define         HFA384x_RID_DISSALOWEDBSSID     ((UINT16)0xFCC6) // 1.8.0
+#define                HFA384x_RID_SCANREQUEST         ((UINT16)0xFCE1)
+#define                HFA384x_RID_JOINREQUEST         ((UINT16)0xFCE2)
+#define                HFA384x_RID_AUTHENTICATESTA     ((UINT16)0xFCE3)
+#define                HFA384x_RID_CHANNELINFOREQUEST  ((UINT16)0xFCE4)
+#define                HFA384x_RID_HOSTSCAN            ((UINT16)0xFCE5) // NEW STA
+#define                HFA384x_RID_ASSOCIATESTA        ((UINT16)0xFCE6)
+
+#define                HFA384x_RID_CNFWEPDEFAULTKEY_LEN        ((UINT16)6)
+#define                HFA384x_RID_CNFWEP128DEFAULTKEY_LEN     ((UINT16)14)
+#define                HFA384x_RID_CNFPRIOQUSAGE_LEN           ((UINT16)4)
+/*--------------------------------------------------------------------
+PD Record codes
+--------------------------------------------------------------------*/
+#define HFA384x_PDR_PCB_PARTNUM                ((UINT16)0x0001)
+#define HFA384x_PDR_PDAVER             ((UINT16)0x0002)
+#define HFA384x_PDR_NIC_SERIAL         ((UINT16)0x0003)
+#define HFA384x_PDR_MKK_MEASUREMENTS   ((UINT16)0x0004)
+#define HFA384x_PDR_NIC_RAMSIZE                ((UINT16)0x0005)
+#define HFA384x_PDR_MFISUPRANGE                ((UINT16)0x0006)
+#define HFA384x_PDR_CFISUPRANGE                ((UINT16)0x0007)
+#define HFA384x_PDR_NICID              ((UINT16)0x0008)
+//#define HFA384x_PDR_REFDAC_MEASUREMENTS      ((UINT16)0x0010)
+//#define HFA384x_PDR_VGDAC_MEASUREMENTS       ((UINT16)0x0020)
+//#define HFA384x_PDR_LEVEL_COMP_MEASUREMENTS  ((UINT16)0x0030)
+//#define HFA384x_PDR_MODEM_TRIMDAC_MEASUREMENTS       ((UINT16)0x0040)
+//#define HFA384x_PDR_COREGA_HACK              ((UINT16)0x00ff)
+#define HFA384x_PDR_MAC_ADDRESS                ((UINT16)0x0101)
+//#define HFA384x_PDR_MKK_CALLNAME     ((UINT16)0x0102)
+#define HFA384x_PDR_REGDOMAIN          ((UINT16)0x0103)
+#define HFA384x_PDR_ALLOWED_CHANNEL    ((UINT16)0x0104)
+#define HFA384x_PDR_DEFAULT_CHANNEL    ((UINT16)0x0105)
+//#define HFA384x_PDR_PRIVACY_OPTION   ((UINT16)0x0106)
+#define HFA384x_PDR_TEMPTYPE           ((UINT16)0x0107)
+//#define HFA384x_PDR_REFDAC_SETUP     ((UINT16)0x0110)
+//#define HFA384x_PDR_VGDAC_SETUP              ((UINT16)0x0120)
+//#define HFA384x_PDR_LEVEL_COMP_SETUP ((UINT16)0x0130)
+//#define HFA384x_PDR_TRIMDAC_SETUP    ((UINT16)0x0140)
+#define HFA384x_PDR_IFR_SETTING                ((UINT16)0x0200)
+#define HFA384x_PDR_RFR_SETTING                ((UINT16)0x0201)
+#define HFA384x_PDR_HFA3861_BASELINE   ((UINT16)0x0202)
+#define HFA384x_PDR_HFA3861_SHADOW     ((UINT16)0x0203)
+#define HFA384x_PDR_HFA3861_IFRF       ((UINT16)0x0204)
+#define HFA384x_PDR_HFA3861_CHCALSP    ((UINT16)0x0300)
+#define HFA384x_PDR_HFA3861_CHCALI     ((UINT16)0x0301)
+#define HFA384x_PDR_MAX_TX_POWER       ((UINT16)0x0302)
+#define HFA384x_PDR_MASTER_CHAN_LIST   ((UINT16)0x0303)
+#define HFA384x_PDR_3842_NIC_CONFIG    ((UINT16)0x0400)
+#define HFA384x_PDR_USB_ID             ((UINT16)0x0401)
+#define HFA384x_PDR_PCI_ID             ((UINT16)0x0402)
+#define HFA384x_PDR_PCI_IFCONF         ((UINT16)0x0403)
+#define HFA384x_PDR_PCI_PMCONF         ((UINT16)0x0404)
+#define HFA384x_PDR_RFENRGY            ((UINT16)0x0406)
+#define HFA384x_PDR_USB_POWER_TYPE      ((UINT16)0x0407)
+//#define HFA384x_PDR_UNKNOWN408               ((UINT16)0x0408)
+#define HFA384x_PDR_USB_MAX_POWER      ((UINT16)0x0409)
+#define HFA384x_PDR_USB_MANUFACTURER   ((UINT16)0x0410)
+#define HFA384x_PDR_USB_PRODUCT        ((UINT16)0x0411)
+#define HFA384x_PDR_ANT_DIVERSITY      ((UINT16)0x0412)
+#define HFA384x_PDR_HFO_DELAY          ((UINT16)0x0413)
+#define HFA384x_PDR_SCALE_THRESH       ((UINT16)0x0414)
+
+#define HFA384x_PDR_HFA3861_MANF_TESTSP        ((UINT16)0x0900)
+#define HFA384x_PDR_HFA3861_MANF_TESTI ((UINT16)0x0901)
+#define HFA384x_PDR_END_OF_PDA         ((UINT16)0x0000)
+
+
+/*=============================================================*/
+/*------ Macros -----------------------------------------------*/
+
+/*--- Register ID macros ------------------------*/
+
+#define                HFA384x_CMD             HFA384x_CMD_OFF
+#define                HFA384x_PARAM0          HFA384x_PARAM0_OFF
+#define                HFA384x_PARAM1          HFA384x_PARAM1_OFF
+#define                HFA384x_PARAM2          HFA384x_PARAM2_OFF
+#define                HFA384x_STATUS          HFA384x_STATUS_OFF
+#define                HFA384x_RESP0           HFA384x_RESP0_OFF
+#define                HFA384x_RESP1           HFA384x_RESP1_OFF
+#define                HFA384x_RESP2           HFA384x_RESP2_OFF
+#define                HFA384x_INFOFID         HFA384x_INFOFID_OFF
+#define                HFA384x_RXFID           HFA384x_RXFID_OFF
+#define                HFA384x_ALLOCFID        HFA384x_ALLOCFID_OFF
+#define                HFA384x_TXCOMPLFID      HFA384x_TXCOMPLFID_OFF
+#define                HFA384x_SELECT0         HFA384x_SELECT0_OFF
+#define                HFA384x_OFFSET0         HFA384x_OFFSET0_OFF
+#define                HFA384x_DATA0           HFA384x_DATA0_OFF
+#define                HFA384x_SELECT1         HFA384x_SELECT1_OFF
+#define                HFA384x_OFFSET1         HFA384x_OFFSET1_OFF
+#define                HFA384x_DATA1           HFA384x_DATA1_OFF
+#define                HFA384x_EVSTAT          HFA384x_EVSTAT_OFF
+#define                HFA384x_INTEN           HFA384x_INTEN_OFF
+#define                HFA384x_EVACK           HFA384x_EVACK_OFF
+#define                HFA384x_CONTROL         HFA384x_CONTROL_OFF
+#define                HFA384x_SWSUPPORT0      HFA384x_SWSUPPORT0_OFF
+#define                HFA384x_SWSUPPORT1      HFA384x_SWSUPPORT1_OFF
+#define                HFA384x_SWSUPPORT2      HFA384x_SWSUPPORT2_OFF
+#define                HFA384x_AUXPAGE         HFA384x_AUXPAGE_OFF
+#define                HFA384x_AUXOFFSET       HFA384x_AUXOFFSET_OFF
+#define                HFA384x_AUXDATA         HFA384x_AUXDATA_OFF
+#define                HFA384x_PCICOR          HFA384x_PCICOR_OFF
+#define                HFA384x_PCIHCR          HFA384x_PCIHCR_OFF
+
+
+/*--- Register Test/Get/Set Field macros ------------------------*/
+
+#define                HFA384x_CMD_ISBUSY(value)               ((UINT16)(((UINT16)value) & HFA384x_CMD_BUSY))
+#define                HFA384x_CMD_AINFO_GET(value)            ((UINT16)(((UINT16)(value) & HFA384x_CMD_AINFO) >> 8))
+#define                HFA384x_CMD_AINFO_SET(value)            ((UINT16)((UINT16)(value) << 8))
+#define                HFA384x_CMD_MACPORT_GET(value)          ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_MACPORT)))
+#define                HFA384x_CMD_MACPORT_SET(value)          ((UINT16)HFA384x_CMD_AINFO_SET(value))
+#define                HFA384x_CMD_ISRECL(value)               ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_RECL)))
+#define                HFA384x_CMD_RECL_SET(value)             ((UINT16)HFA384x_CMD_AINFO_SET(value))
+#define                HFA384x_CMD_QOS_GET(value)              ((UINT16((((UINT16)(value))&((UINT16)0x3000)) >> 12))
+#define                HFA384x_CMD_QOS_SET(value)              ((UINT16)((((UINT16)(value)) << 12) & 0x3000))
+#define                HFA384x_CMD_ISWRITE(value)              ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_WRITE)))
+#define                HFA384x_CMD_WRITE_SET(value)            ((UINT16)HFA384x_CMD_AINFO_SET((UINT16)value))
+#define                HFA384x_CMD_PROGMODE_GET(value)         ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_PROGMODE)))
+#define                HFA384x_CMD_PROGMODE_SET(value)         ((UINT16)HFA384x_CMD_AINFO_SET((UINT16)value))
+#define                HFA384x_CMD_CMDCODE_GET(value)          ((UINT16)(((UINT16)(value)) & HFA384x_CMD_CMDCODE))
+#define                HFA384x_CMD_CMDCODE_SET(value)          ((UINT16)(value))
+
+#define                HFA384x_STATUS_RESULT_GET(value)        ((UINT16)((((UINT16)(value)) & HFA384x_STATUS_RESULT) >> 8))
+#define                HFA384x_STATUS_RESULT_SET(value)        (((UINT16)(value)) << 8)
+#define                HFA384x_STATUS_CMDCODE_GET(value)       (((UINT16)(value)) & HFA384x_STATUS_CMDCODE)
+#define                HFA384x_STATUS_CMDCODE_SET(value)       ((UINT16)(value))
+
+#define                HFA384x_OFFSET_ISBUSY(value)            ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_BUSY))
+#define                HFA384x_OFFSET_ISERR(value)             ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_ERR))
+#define                HFA384x_OFFSET_DATAOFF_GET(value)       ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_DATAOFF))
+#define                HFA384x_OFFSET_DATAOFF_SET(value)       ((UINT16)(value))
+
+#define                HFA384x_EVSTAT_ISTICK(value)            ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TICK))
+#define                HFA384x_EVSTAT_ISWTERR(value)           ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_WTERR))
+#define                HFA384x_EVSTAT_ISINFDROP(value)         ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_INFDROP))
+#define                HFA384x_EVSTAT_ISINFO(value)            ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_INFO))
+#define                HFA384x_EVSTAT_ISDTIM(value)            ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_DTIM))
+#define                HFA384x_EVSTAT_ISCMD(value)             ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_CMD))
+#define                HFA384x_EVSTAT_ISALLOC(value)           ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_ALLOC))
+#define                HFA384x_EVSTAT_ISTXEXC(value)           ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TXEXC))
+#define                HFA384x_EVSTAT_ISTX(value)              ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TX))
+#define                HFA384x_EVSTAT_ISRX(value)              ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_RX))
+
+#define                HFA384x_EVSTAT_ISBAP_OP(value)          ((UINT16)(((UINT16)(value)) & HFA384x_INT_BAP_OP))
+
+#define                HFA384x_INTEN_ISTICK(value)             ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TICK))
+#define                HFA384x_INTEN_TICK_SET(value)           ((UINT16)(((UINT16)(value)) << 15))
+#define                HFA384x_INTEN_ISWTERR(value)            ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_WTERR))
+#define                HFA384x_INTEN_WTERR_SET(value)          ((UINT16)(((UINT16)(value)) << 14))
+#define                HFA384x_INTEN_ISINFDROP(value)          ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_INFDROP))
+#define                HFA384x_INTEN_INFDROP_SET(value)        ((UINT16)(((UINT16)(value)) << 13))
+#define                HFA384x_INTEN_ISINFO(value)             ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_INFO))
+#define                HFA384x_INTEN_INFO_SET(value)           ((UINT16)(((UINT16)(value)) << 7))
+#define                HFA384x_INTEN_ISDTIM(value)             ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_DTIM))
+#define                HFA384x_INTEN_DTIM_SET(value)           ((UINT16)(((UINT16)(value)) << 5))
+#define                HFA384x_INTEN_ISCMD(value)              ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_CMD))
+#define                HFA384x_INTEN_CMD_SET(value)            ((UINT16)(((UINT16)(value)) << 4))
+#define                HFA384x_INTEN_ISALLOC(value)            ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_ALLOC))
+#define                HFA384x_INTEN_ALLOC_SET(value)          ((UINT16)(((UINT16)(value)) << 3))
+#define                HFA384x_INTEN_ISTXEXC(value)            ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TXEXC))
+#define                HFA384x_INTEN_TXEXC_SET(value)          ((UINT16)(((UINT16)(value)) << 2))
+#define                HFA384x_INTEN_ISTX(value)               ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TX))
+#define                HFA384x_INTEN_TX_SET(value)             ((UINT16)(((UINT16)(value)) << 1))
+#define                HFA384x_INTEN_ISRX(value)               ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_RX))
+#define                HFA384x_INTEN_RX_SET(value)             ((UINT16)(((UINT16)(value)) << 0))
+
+#define                HFA384x_EVACK_ISTICK(value)             ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TICK))
+#define                HFA384x_EVACK_TICK_SET(value)           ((UINT16)(((UINT16)(value)) << 15))
+#define                HFA384x_EVACK_ISWTERR(value)            ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_WTERR))
+#define                HFA384x_EVACK_WTERR_SET(value)          ((UINT16)(((UINT16)(value)) << 14))
+#define                HFA384x_EVACK_ISINFDROP(value)          ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_INFDROP))
+#define                HFA384x_EVACK_INFDROP_SET(value)        ((UINT16)(((UINT16)(value)) << 13))
+#define                HFA384x_EVACK_ISINFO(value)             ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_INFO))
+#define                HFA384x_EVACK_INFO_SET(value)           ((UINT16)(((UINT16)(value)) << 7))
+#define                HFA384x_EVACK_ISDTIM(value)             ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_DTIM))
+#define                HFA384x_EVACK_DTIM_SET(value)           ((UINT16)(((UINT16)(value)) << 5))
+#define                HFA384x_EVACK_ISCMD(value)              ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_CMD))
+#define                HFA384x_EVACK_CMD_SET(value)            ((UINT16)(((UINT16)(value)) << 4))
+#define                HFA384x_EVACK_ISALLOC(value)            ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_ALLOC))
+#define                HFA384x_EVACK_ALLOC_SET(value)          ((UINT16)(((UINT16)(value)) << 3))
+#define                HFA384x_EVACK_ISTXEXC(value)            ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TXEXC))
+#define                HFA384x_EVACK_TXEXC_SET(value)          ((UINT16)(((UINT16)(value)) << 2))
+#define                HFA384x_EVACK_ISTX(value)               ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TX))
+#define                HFA384x_EVACK_TX_SET(value)             ((UINT16)(((UINT16)(value)) << 1))
+#define                HFA384x_EVACK_ISRX(value)               ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_RX))
+#define                HFA384x_EVACK_RX_SET(value)             ((UINT16)(((UINT16)(value)) << 0))
+
+#define                HFA384x_CONTROL_AUXEN_SET(value)        ((UINT16)(((UINT16)(value)) << 14))
+#define                HFA384x_CONTROL_AUXEN_GET(value)        ((UINT16)(((UINT16)(value)) >> 14))
+
+/* Byte Order */
+#ifdef __KERNEL__
+#define hfa384x2host_16(n)     (__le16_to_cpu((UINT16)(n)))
+#define hfa384x2host_32(n)     (__le32_to_cpu((UINT32)(n)))
+#define host2hfa384x_16(n)     (__cpu_to_le16((UINT16)(n)))
+#define host2hfa384x_32(n)     (__cpu_to_le32((UINT32)(n)))
+#endif
+
+/* Host Maintained State Info */
+#define HFA384x_STATE_PREINIT  0
+#define HFA384x_STATE_INIT     1
+#define HFA384x_STATE_RUNNING  2
+
+/*=============================================================*/
+/*------ Types and their related constants --------------------*/
+
+#define HFA384x_HOSTAUTHASSOC_HOSTAUTH   BIT0
+#define HFA384x_HOSTAUTHASSOC_HOSTASSOC  BIT1
+
+#define HFA384x_WHAHANDLING_DISABLED     0
+#define HFA384x_WHAHANDLING_PASSTHROUGH  BIT1
+
+/*-------------------------------------------------------------*/
+/* Commonly used basic types */
+typedef struct hfa384x_bytestr
+{
+       UINT16  len;
+       UINT8   data[0];
+} __WLAN_ATTRIB_PACK__ hfa384x_bytestr_t;
+
+typedef struct hfa384x_bytestr32
+{
+       UINT16  len;
+       UINT8   data[32];
+} __WLAN_ATTRIB_PACK__ hfa384x_bytestr32_t;
+
+/*--------------------------------------------------------------------
+Configuration Record Structures:
+       Network Parameters, Static Configuration Entities
+--------------------------------------------------------------------*/
+/* Prototype structure: all configuration record structures start with
+these members */
+
+typedef struct hfa384x_record
+{
+       UINT16  reclen;
+       UINT16  rid;
+} __WLAN_ATTRIB_PACK__ hfa384x_rec_t;
+
+typedef struct hfa384x_record16
+{
+       UINT16  reclen;
+       UINT16  rid;
+       UINT16  val;
+} __WLAN_ATTRIB_PACK__ hfa384x_rec16_t;
+
+typedef struct hfa384x_record32
+{
+       UINT16  reclen;
+       UINT16  rid;
+       UINT32  val;
+} __WLAN_ATTRIB_PACK__ hfa384x_rec32;
+
+/*-- Hardware/Firmware Component Information ----------*/
+typedef struct hfa384x_compident
+{
+       UINT16  id;
+       UINT16  variant;
+       UINT16  major;
+       UINT16  minor;
+} __WLAN_ATTRIB_PACK__ hfa384x_compident_t;
+
+typedef struct hfa384x_caplevel
+{
+       UINT16  role;
+       UINT16  id;
+       UINT16  variant;
+       UINT16  bottom;
+       UINT16  top;
+} __WLAN_ATTRIB_PACK__ hfa384x_caplevel_t;
+
+/*-- Configuration Record: cnfPortType --*/
+typedef struct hfa384x_cnfPortType
+{
+       UINT16  cnfPortType;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfPortType_t;
+
+/*-- Configuration Record: cnfOwnMACAddress --*/
+typedef struct hfa384x_cnfOwnMACAddress
+{
+       UINT8   cnfOwnMACAddress[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnMACAddress_t;
+
+/*-- Configuration Record: cnfDesiredSSID --*/
+typedef struct hfa384x_cnfDesiredSSID
+{
+       UINT8   cnfDesiredSSID[34];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfDesiredSSID_t;
+
+/*-- Configuration Record: cnfOwnChannel --*/
+typedef struct hfa384x_cnfOwnChannel
+{
+       UINT16  cnfOwnChannel;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnChannel_t;
+
+/*-- Configuration Record: cnfOwnSSID --*/
+typedef struct hfa384x_cnfOwnSSID
+{
+       UINT8   cnfOwnSSID[34];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnSSID_t;
+
+/*-- Configuration Record: cnfOwnATIMWindow --*/
+typedef struct hfa384x_cnfOwnATIMWindow
+{
+       UINT16  cnfOwnATIMWindow;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnATIMWindow_t;
+
+/*-- Configuration Record: cnfSystemScale --*/
+typedef struct hfa384x_cnfSystemScale
+{
+       UINT16  cnfSystemScale;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfSystemScale_t;
+
+/*-- Configuration Record: cnfMaxDataLength --*/
+typedef struct hfa384x_cnfMaxDataLength
+{
+       UINT16  cnfMaxDataLength;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxDataLength_t;
+
+/*-- Configuration Record: cnfWDSAddress --*/
+typedef struct hfa384x_cnfWDSAddress
+{
+       UINT8   cnfWDSAddress[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddress_t;
+
+/*-- Configuration Record: cnfPMEnabled --*/
+typedef struct hfa384x_cnfPMEnabled
+{
+       UINT16  cnfPMEnabled;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEnabled_t;
+
+/*-- Configuration Record: cnfPMEPS --*/
+typedef struct hfa384x_cnfPMEPS
+{
+       UINT16  cnfPMEPS;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEPS_t;
+
+/*-- Configuration Record: cnfMulticastReceive --*/
+typedef struct hfa384x_cnfMulticastReceive
+{
+       UINT16  cnfMulticastReceive;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastReceive_t;
+
+/*-- Configuration Record: cnfAuthentication --*/
+#define HFA384x_CNFAUTHENTICATION_OPENSYSTEM   0x0001
+#define HFA384x_CNFAUTHENTICATION_SHAREDKEY    0x0002
+#define HFA384x_CNFAUTHENTICATION_LEAP         0x0004
+
+/*-- Configuration Record: cnfMaxSleepDuration --*/
+typedef struct hfa384x_cnfMaxSleepDuration
+{
+       UINT16  cnfMaxSleepDuration;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxSleepDuration_t;
+
+/*-- Configuration Record: cnfPMHoldoverDuration --*/
+typedef struct hfa384x_cnfPMHoldoverDuration
+{
+       UINT16  cnfPMHoldoverDuration;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMHoldoverDuration_t;
+
+/*-- Configuration Record: cnfOwnName --*/
+typedef struct hfa384x_cnfOwnName
+{
+       UINT8   cnfOwnName[34];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnName_t;
+
+/*-- Configuration Record: cnfOwnDTIMPeriod --*/
+typedef struct hfa384x_cnfOwnDTIMPeriod
+{
+       UINT16  cnfOwnDTIMPeriod;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnDTIMPeriod_t;
+
+/*-- Configuration Record: cnfWDSAddress --*/
+typedef struct hfa384x_cnfWDSAddressN
+{
+       UINT8   cnfWDSAddress[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddressN_t;
+
+/*-- Configuration Record: cnfMulticastPMBuffering --*/
+typedef struct hfa384x_cnfMulticastPMBuffering
+{
+       UINT16  cnfMulticastPMBuffering;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastPMBuffering_t;
+
+/*--------------------------------------------------------------------
+Configuration Record Structures:
+       Network Parameters, Dynamic Configuration Entities
+--------------------------------------------------------------------*/
+
+/*-- Configuration Record: GroupAddresses --*/
+typedef struct hfa384x_GroupAddresses
+{
+       UINT8   MACAddress[16][6];
+} __WLAN_ATTRIB_PACK__ hfa384x_GroupAddresses_t;
+
+/*-- Configuration Record: CreateIBSS --*/
+typedef struct hfa384x_CreateIBSS
+{
+       UINT16  CreateIBSS;
+} __WLAN_ATTRIB_PACK__ hfa384x_CreateIBSS_t;
+
+#define HFA384x_CREATEIBSS_JOINCREATEIBSS          0
+#define HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS  1
+#define HFA384x_CREATEIBSS_JOINIBSS                2
+#define HFA384x_CREATEIBSS_JOINESS_JOINIBSS        3
+
+/*-- Configuration Record: FragmentationThreshold --*/
+typedef struct hfa384x_FragmentationThreshold
+{
+       UINT16  FragmentationThreshold;
+} __WLAN_ATTRIB_PACK__ hfa384x_FragmentationThreshold_t;
+
+/*-- Configuration Record: RTSThreshold --*/
+typedef struct hfa384x_RTSThreshold
+{
+       UINT16  RTSThreshold;
+} __WLAN_ATTRIB_PACK__ hfa384x_RTSThreshold_t;
+
+/*-- Configuration Record: TxRateControl --*/
+typedef struct hfa384x_TxRateControl
+{
+       UINT16  TxRateControl;
+} __WLAN_ATTRIB_PACK__ hfa384x_TxRateControl_t;
+
+/*-- Configuration Record: PromiscuousMode --*/
+typedef struct hfa384x_PromiscuousMode
+{
+       UINT16  PromiscuousMode;
+} __WLAN_ATTRIB_PACK__ hfa384x_PromiscuousMode_t;
+
+/*-- Configuration Record: ScanRequest (data portion only) --*/
+typedef struct hfa384x_ScanRequest_data
+{
+       UINT16  channelList;
+       UINT16  txRate;
+} __WLAN_ATTRIB_PACK__ hfa384x_ScanRequest_data_t;
+
+/*-- Configuration Record: HostScanRequest (data portion only) --*/
+typedef struct hfa384x_HostScanRequest_data
+{
+       UINT16  channelList;
+       UINT16  txRate;
+       hfa384x_bytestr32_t ssid;
+} __WLAN_ATTRIB_PACK__ hfa384x_HostScanRequest_data_t;
+
+/*-- Configuration Record: JoinRequest (data portion only) --*/
+typedef struct hfa384x_JoinRequest_data
+{
+       UINT8   bssid[WLAN_BSSID_LEN];
+       UINT16  channel;
+} __WLAN_ATTRIB_PACK__ hfa384x_JoinRequest_data_t;
+
+/*-- Configuration Record: authenticateStation (data portion only) --*/
+typedef struct hfa384x_authenticateStation_data
+{
+       UINT8   address[WLAN_ADDR_LEN];
+       UINT16  status;
+       UINT16  algorithm;
+} __WLAN_ATTRIB_PACK__ hfa384x_authenticateStation_data_t;
+
+/*-- Configuration Record: associateStation (data portion only) --*/
+typedef struct hfa384x_associateStation_data
+{
+       UINT8   address[WLAN_ADDR_LEN];
+       UINT16  status;
+       UINT16  type;
+} __WLAN_ATTRIB_PACK__ hfa384x_associateStation_data_t;
+
+/*-- Configuration Record: ChannelInfoRequest (data portion only) --*/
+typedef struct hfa384x_ChannelInfoRequest_data
+{
+       UINT16  channelList;
+       UINT16  channelDwellTime;
+} __WLAN_ATTRIB_PACK__ hfa384x_ChannelInfoRequest_data_t;
+
+/*-- Configuration Record: WEPKeyMapping (data portion only) --*/
+typedef struct hfa384x_WEPKeyMapping
+{
+       UINT8   address[WLAN_ADDR_LEN];
+       UINT16  key_index;
+       UINT8   key[16];
+       UINT8   mic_transmit_key[4];
+       UINT8   mic_receive_key[4];
+} __WLAN_ATTRIB_PACK__ hfa384x_WEPKeyMapping_t;
+
+/*-- Configuration Record: WPAData       (data portion only) --*/
+typedef struct hfa384x_WPAData
+{
+       UINT16  datalen;
+        UINT8  data[0]; // max 80
+} __WLAN_ATTRIB_PACK__ hfa384x_WPAData_t;
+
+/*--------------------------------------------------------------------
+Configuration Record Structures: Behavior Parameters
+--------------------------------------------------------------------*/
+
+/*-- Configuration Record: TickTime --*/
+typedef struct hfa384x_TickTime
+{
+       UINT16  TickTime;
+} __WLAN_ATTRIB_PACK__ hfa384x_TickTime_t;
+
+/*--------------------------------------------------------------------
+Information Record Structures: NIC Information
+--------------------------------------------------------------------*/
+
+/*-- Information Record: MaxLoadTime --*/
+typedef struct hfa384x_MaxLoadTime
+{
+       UINT16  MaxLoadTime;
+} __WLAN_ATTRIB_PACK__ hfa384x_MaxLoadTime_t;
+
+/*-- Information Record: DownLoadBuffer --*/
+/* NOTE: The page and offset are in AUX format */
+typedef struct hfa384x_downloadbuffer
+{
+       UINT16  page;
+       UINT16  offset;
+       UINT16  len;
+} __WLAN_ATTRIB_PACK__ hfa384x_downloadbuffer_t;
+
+/*-- Information Record: PRIIdentity --*/
+typedef struct hfa384x_PRIIdentity
+{
+       UINT16  PRICompID;
+       UINT16  PRIVariant;
+       UINT16  PRIMajorVersion;
+       UINT16  PRIMinorVersion;
+} __WLAN_ATTRIB_PACK__ hfa384x_PRIIdentity_t;
+
+/*-- Information Record: PRISupRange --*/
+typedef struct hfa384x_PRISupRange
+{
+       UINT16  PRIRole;
+       UINT16  PRIID;
+       UINT16  PRIVariant;
+       UINT16  PRIBottom;
+       UINT16  PRITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_PRISupRange_t;
+
+/*-- Information Record: CFIActRanges --*/
+typedef struct hfa384x_CFIActRanges
+{
+       UINT16  CFIRole;
+       UINT16  CFIID;
+       UINT16  CFIVariant;
+       UINT16  CFIBottom;
+       UINT16  CFITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_CFIActRanges_t;
+
+/*-- Information Record: NICSerialNumber --*/
+typedef struct hfa384x_NICSerialNumber
+{
+       UINT8   NICSerialNumber[12];
+} __WLAN_ATTRIB_PACK__ hfa384x_NICSerialNumber_t;
+
+/*-- Information Record: NICIdentity --*/
+typedef struct hfa384x_NICIdentity
+{
+       UINT16  NICCompID;
+       UINT16  NICVariant;
+       UINT16  NICMajorVersion;
+       UINT16  NICMinorVersion;
+} __WLAN_ATTRIB_PACK__ hfa384x_NICIdentity_t;
+
+/*-- Information Record: MFISupRange --*/
+typedef struct hfa384x_MFISupRange
+{
+       UINT16  MFIRole;
+       UINT16  MFIID;
+       UINT16  MFIVariant;
+       UINT16  MFIBottom;
+       UINT16  MFITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_MFISupRange_t;
+
+/*-- Information Record: CFISupRange --*/
+typedef struct hfa384x_CFISupRange
+{
+       UINT16  CFIRole;
+       UINT16  CFIID;
+       UINT16  CFIVariant;
+       UINT16  CFIBottom;
+       UINT16  CFITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_CFISupRange_t;
+
+/*-- Information Record: BUILDSEQ:BuildSeq --*/
+typedef struct hfa384x_BuildSeq {
+       UINT16  primary;
+       UINT16  secondary;
+} __WLAN_ATTRIB_PACK__ hfa384x_BuildSeq_t;
+
+/*-- Information Record: FWID --*/
+#define HFA384x_FWID_LEN       14
+typedef struct hfa384x_FWID {
+       UINT8   primary[HFA384x_FWID_LEN];
+       UINT8   secondary[HFA384x_FWID_LEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_FWID_t;
+
+/*-- Information Record: ChannelList --*/
+typedef struct hfa384x_ChannelList
+{
+       UINT16  ChannelList;
+} __WLAN_ATTRIB_PACK__ hfa384x_ChannelList_t;
+
+/*-- Information Record: RegulatoryDomains --*/
+typedef struct hfa384x_RegulatoryDomains
+{
+       UINT8   RegulatoryDomains[12];
+} __WLAN_ATTRIB_PACK__ hfa384x_RegulatoryDomains_t;
+
+/*-- Information Record: TempType --*/
+typedef struct hfa384x_TempType
+{
+       UINT16  TempType;
+} __WLAN_ATTRIB_PACK__ hfa384x_TempType_t;
+
+/*-- Information Record: CIS --*/
+typedef struct hfa384x_CIS
+{
+       UINT8   CIS[480];
+} __WLAN_ATTRIB_PACK__ hfa384x_CIS_t;
+
+/*-- Information Record: STAIdentity --*/
+typedef struct hfa384x_STAIdentity
+{
+       UINT16  STACompID;
+       UINT16  STAVariant;
+       UINT16  STAMajorVersion;
+       UINT16  STAMinorVersion;
+} __WLAN_ATTRIB_PACK__ hfa384x_STAIdentity_t;
+
+/*-- Information Record: STASupRange --*/
+typedef struct hfa384x_STASupRange
+{
+       UINT16  STARole;
+       UINT16  STAID;
+       UINT16  STAVariant;
+       UINT16  STABottom;
+       UINT16  STATop;
+} __WLAN_ATTRIB_PACK__ hfa384x_STASupRange_t;
+
+/*-- Information Record: MFIActRanges --*/
+typedef struct hfa384x_MFIActRanges
+{
+       UINT16  MFIRole;
+       UINT16  MFIID;
+       UINT16  MFIVariant;
+       UINT16  MFIBottom;
+       UINT16  MFITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_MFIActRanges_t;
+
+/*--------------------------------------------------------------------
+Information Record Structures: NIC Information
+--------------------------------------------------------------------*/
+
+/*-- Information Record: PortStatus --*/
+typedef struct hfa384x_PortStatus
+{
+       UINT16  PortStatus;
+} __WLAN_ATTRIB_PACK__ hfa384x_PortStatus_t;
+
+#define HFA384x_PSTATUS_DISABLED       ((UINT16)1)
+#define HFA384x_PSTATUS_SEARCHING      ((UINT16)2)
+#define HFA384x_PSTATUS_CONN_IBSS      ((UINT16)3)
+#define HFA384x_PSTATUS_CONN_ESS       ((UINT16)4)
+#define HFA384x_PSTATUS_OUTOFRANGE     ((UINT16)5)
+#define HFA384x_PSTATUS_CONN_WDS       ((UINT16)6)
+
+/*-- Information Record: CurrentSSID --*/
+typedef struct hfa384x_CurrentSSID
+{
+       UINT8   CurrentSSID[34];
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentSSID_t;
+
+/*-- Information Record: CurrentBSSID --*/
+typedef struct hfa384x_CurrentBSSID
+{
+       UINT8   CurrentBSSID[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBSSID_t;
+
+/*-- Information Record: commsquality --*/
+typedef struct hfa384x_commsquality
+{
+       UINT16  CQ_currBSS;
+       UINT16  ASL_currBSS;
+       UINT16  ANL_currFC;
+} __WLAN_ATTRIB_PACK__ hfa384x_commsquality_t;
+
+/*-- Information Record: dmbcommsquality --*/
+typedef struct hfa384x_dbmcommsquality
+{
+       UINT16  CQdbm_currBSS;
+       UINT16  ASLdbm_currBSS;
+       UINT16  ANLdbm_currFC;
+} __WLAN_ATTRIB_PACK__ hfa384x_dbmcommsquality_t;
+
+/*-- Information Record: CurrentTxRate --*/
+typedef struct hfa384x_CurrentTxRate
+{
+       UINT16  CurrentTxRate;
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentTxRate_t;
+
+/*-- Information Record: CurrentBeaconInterval --*/
+typedef struct hfa384x_CurrentBeaconInterval
+{
+       UINT16  CurrentBeaconInterval;
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBeaconInterval_t;
+
+/*-- Information Record: CurrentScaleThresholds --*/
+typedef struct hfa384x_CurrentScaleThresholds
+{
+       UINT16  EnergyDetectThreshold;
+       UINT16  CarrierDetectThreshold;
+       UINT16  DeferDetectThreshold;
+       UINT16  CellSearchThreshold; /* Stations only */
+       UINT16  DeadSpotThreshold; /* Stations only */
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentScaleThresholds_t;
+
+/*-- Information Record: ProtocolRspTime --*/
+typedef struct hfa384x_ProtocolRspTime
+{
+       UINT16  ProtocolRspTime;
+} __WLAN_ATTRIB_PACK__ hfa384x_ProtocolRspTime_t;
+
+/*-- Information Record: ShortRetryLimit --*/
+typedef struct hfa384x_ShortRetryLimit
+{
+       UINT16  ShortRetryLimit;
+} __WLAN_ATTRIB_PACK__ hfa384x_ShortRetryLimit_t;
+
+/*-- Information Record: LongRetryLimit --*/
+typedef struct hfa384x_LongRetryLimit
+{
+       UINT16  LongRetryLimit;
+} __WLAN_ATTRIB_PACK__ hfa384x_LongRetryLimit_t;
+
+/*-- Information Record: MaxTransmitLifetime --*/
+typedef struct hfa384x_MaxTransmitLifetime
+{
+       UINT16  MaxTransmitLifetime;
+} __WLAN_ATTRIB_PACK__ hfa384x_MaxTransmitLifetime_t;
+
+/*-- Information Record: MaxReceiveLifetime --*/
+typedef struct hfa384x_MaxReceiveLifetime
+{
+       UINT16  MaxReceiveLifetime;
+} __WLAN_ATTRIB_PACK__ hfa384x_MaxReceiveLifetime_t;
+
+/*-- Information Record: CFPollable --*/
+typedef struct hfa384x_CFPollable
+{
+       UINT16  CFPollable;
+} __WLAN_ATTRIB_PACK__ hfa384x_CFPollable_t;
+
+/*-- Information Record: AuthenticationAlgorithms --*/
+typedef struct hfa384x_AuthenticationAlgorithms
+{
+       UINT16  AuthenticationType;
+       UINT16  TypeEnabled;
+} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_t;
+
+/*-- Information Record: AuthenticationAlgorithms
+(data only --*/
+typedef struct hfa384x_AuthenticationAlgorithms_data
+{
+       UINT16  AuthenticationType;
+       UINT16  TypeEnabled;
+} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_data_t;
+
+/*-- Information Record: PrivacyOptionImplemented --*/
+typedef struct hfa384x_PrivacyOptionImplemented
+{
+       UINT16  PrivacyOptionImplemented;
+} __WLAN_ATTRIB_PACK__ hfa384x_PrivacyOptionImplemented_t;
+
+/*-- Information Record: OwnMACAddress --*/
+typedef struct hfa384x_OwnMACAddress
+{
+       UINT8   OwnMACAddress[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_OwnMACAddress_t;
+
+/*-- Information Record: PCFInfo --*/
+typedef struct hfa384x_PCFInfo
+{
+       UINT16  MediumOccupancyLimit;
+       UINT16  CFPPeriod;
+       UINT16  CFPMaxDuration;
+       UINT16  CFPFlags;
+} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_t;
+
+/*-- Information Record: PCFInfo (data portion only) --*/
+typedef struct hfa384x_PCFInfo_data
+{
+       UINT16  MediumOccupancyLimit;
+       UINT16  CFPPeriod;
+       UINT16  CFPMaxDuration;
+       UINT16  CFPFlags;
+} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_data_t;
+
+/*--------------------------------------------------------------------
+Information Record Structures: Modem Information Records
+--------------------------------------------------------------------*/
+
+/*-- Information Record: PHYType --*/
+typedef struct hfa384x_PHYType
+{
+       UINT16  PHYType;
+} __WLAN_ATTRIB_PACK__ hfa384x_PHYType_t;
+
+/*-- Information Record: CurrentChannel --*/
+typedef struct hfa384x_CurrentChannel
+{
+       UINT16  CurrentChannel;
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentChannel_t;
+
+/*-- Information Record: CurrentPowerState --*/
+typedef struct hfa384x_CurrentPowerState
+{
+       UINT16  CurrentPowerState;
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentPowerState_t;
+
+/*-- Information Record: CCAMode --*/
+typedef struct hfa384x_CCAMode
+{
+       UINT16  CCAMode;
+} __WLAN_ATTRIB_PACK__ hfa384x_CCAMode_t;
+
+/*-- Information Record: SupportedDataRates --*/
+typedef struct hfa384x_SupportedDataRates
+{
+       UINT8   SupportedDataRates[10];
+} __WLAN_ATTRIB_PACK__ hfa384x_SupportedDataRates_t;
+
+/*-- Information Record: LFOStatus --*/
+typedef struct hfa384x_LFOStatus
+{
+       UINT16  TestResults;
+       UINT16  LFOResult;
+       UINT16  VRHFOResult;
+} __WLAN_ATTRIB_PACK__ hfa384x_LFOStatus_t;
+
+#define HFA384x_TESTRESULT_ALLPASSED    BIT0
+#define HFA384x_TESTRESULT_LFO_FAIL     BIT1
+#define HFA384x_TESTRESULT_VR_HF0_FAIL  BIT2
+#define HFA384x_HOST_FIRM_COORDINATE    BIT7
+#define HFA384x_TESTRESULT_COORDINATE   BIT15
+
+/*-- Information Record: LEDControl --*/
+typedef struct hfa384x_LEDControl
+{
+       UINT16  searching_on;
+       UINT16  searching_off;
+       UINT16  assoc_on;
+       UINT16  assoc_off;
+       UINT16  activity;
+} __WLAN_ATTRIB_PACK__ hfa384x_LEDControl_t;
+
+/*--------------------------------------------------------------------
+                 FRAME DESCRIPTORS AND FRAME STRUCTURES
+
+FRAME DESCRIPTORS: Offsets
+
+----------------------------------------------------------------------
+Control Info (offset 44-51)
+--------------------------------------------------------------------*/
+#define                HFA384x_FD_STATUS_OFF                   ((UINT16)0x44)
+#define                HFA384x_FD_TIME_OFF                     ((UINT16)0x46)
+#define                HFA384x_FD_SWSUPPORT_OFF                ((UINT16)0x4A)
+#define                HFA384x_FD_SILENCE_OFF                  ((UINT16)0x4A)
+#define                HFA384x_FD_SIGNAL_OFF                   ((UINT16)0x4B)
+#define                HFA384x_FD_RATE_OFF                     ((UINT16)0x4C)
+#define                HFA384x_FD_RXFLOW_OFF                   ((UINT16)0x4D)
+#define                HFA384x_FD_RESERVED_OFF                 ((UINT16)0x4E)
+#define                HFA384x_FD_TXCONTROL_OFF                ((UINT16)0x50)
+/*--------------------------------------------------------------------
+802.11 Header (offset 52-6B)
+--------------------------------------------------------------------*/
+#define                HFA384x_FD_FRAMECONTROL_OFF             ((UINT16)0x52)
+#define                HFA384x_FD_DURATIONID_OFF               ((UINT16)0x54)
+#define                HFA384x_FD_ADDRESS1_OFF                 ((UINT16)0x56)
+#define                HFA384x_FD_ADDRESS2_OFF                 ((UINT16)0x5C)
+#define                HFA384x_FD_ADDRESS3_OFF                 ((UINT16)0x62)
+#define                HFA384x_FD_SEQCONTROL_OFF               ((UINT16)0x68)
+#define                HFA384x_FD_ADDRESS4_OFF                 ((UINT16)0x6A)
+#define                HFA384x_FD_DATALEN_OFF                  ((UINT16)0x70)
+/*--------------------------------------------------------------------
+802.3 Header (offset 72-7F)
+--------------------------------------------------------------------*/
+#define                HFA384x_FD_DESTADDRESS_OFF              ((UINT16)0x72)
+#define                HFA384x_FD_SRCADDRESS_OFF               ((UINT16)0x78)
+#define                HFA384x_FD_DATALENGTH_OFF               ((UINT16)0x7E)
+
+/*--------------------------------------------------------------------
+FRAME STRUCTURES: Communication Frames
+----------------------------------------------------------------------
+Communication Frames: Transmit Frames
+--------------------------------------------------------------------*/
+/*-- Communication Frame: Transmit Frame Structure --*/
+typedef struct hfa384x_tx_frame
+{
+       UINT16  status;
+       UINT16  reserved1;
+       UINT16  reserved2;
+       UINT32  sw_support;
+       UINT8   tx_retrycount;
+       UINT8   tx_rate;
+       UINT16  tx_control;
+
+       /*-- 802.11 Header Information --*/
+
+       UINT16  frame_control;
+       UINT16  duration_id;
+       UINT8   address1[6];
+       UINT8   address2[6];
+       UINT8   address3[6];
+       UINT16  sequence_control;
+       UINT8   address4[6];
+       UINT16  data_len; /* little endian format */
+
+       /*-- 802.3 Header Information --*/
+
+       UINT8   dest_addr[6];
+       UINT8   src_addr[6];
+       UINT16  data_length; /* big endian format */
+} __WLAN_ATTRIB_PACK__ hfa384x_tx_frame_t;
+/*--------------------------------------------------------------------
+Communication Frames: Field Masks for Transmit Frames
+--------------------------------------------------------------------*/
+/*-- Status Field --*/
+#define                HFA384x_TXSTATUS_ACKERR                 ((UINT16)BIT5)
+#define                HFA384x_TXSTATUS_FORMERR                ((UINT16)BIT3)
+#define                HFA384x_TXSTATUS_DISCON                 ((UINT16)BIT2)
+#define                HFA384x_TXSTATUS_AGEDERR                ((UINT16)BIT1)
+#define                HFA384x_TXSTATUS_RETRYERR               ((UINT16)BIT0)
+/*-- Transmit Control Field --*/
+#define                HFA384x_TX_CFPOLL                       ((UINT16)BIT12)
+#define                HFA384x_TX_PRST                         ((UINT16)BIT11)
+#define                HFA384x_TX_MACPORT                      ((UINT16)(BIT10 | BIT9 | BIT8))
+#define                HFA384x_TX_NOENCRYPT                    ((UINT16)BIT7)
+#define                HFA384x_TX_RETRYSTRAT                   ((UINT16)(BIT6 | BIT5))
+#define                HFA384x_TX_STRUCTYPE                    ((UINT16)(BIT4 | BIT3))
+#define                HFA384x_TX_TXEX                         ((UINT16)BIT2)
+#define                HFA384x_TX_TXOK                         ((UINT16)BIT1)
+/*--------------------------------------------------------------------
+Communication Frames: Test/Get/Set Field Values for Transmit Frames
+--------------------------------------------------------------------*/
+/*-- Status Field --*/
+#define HFA384x_TXSTATUS_ISERROR(v)    \
+       (((UINT16)(v))&\
+       (HFA384x_TXSTATUS_ACKERR|HFA384x_TXSTATUS_FORMERR|\
+       HFA384x_TXSTATUS_DISCON|HFA384x_TXSTATUS_AGEDERR|\
+       HFA384x_TXSTATUS_RETRYERR))
+
+#define        HFA384x_TXSTATUS_ISACKERR(v)    ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_ACKERR))
+#define        HFA384x_TXSTATUS_ISFORMERR(v)   ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_FORMERR))
+#define        HFA384x_TXSTATUS_ISDISCON(v)    ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_DISCON))
+#define        HFA384x_TXSTATUS_ISAGEDERR(v)   ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_AGEDERR))
+#define        HFA384x_TXSTATUS_ISRETRYERR(v)  ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_RETRYERR))
+
+#define        HFA384x_TX_GET(v,m,s)           ((((UINT16)(v))&((UINT16)(m)))>>((UINT16)(s)))
+#define        HFA384x_TX_SET(v,m,s)           ((((UINT16)(v))<<((UINT16)(s)))&((UINT16)(m)))
+
+#define        HFA384x_TX_CFPOLL_GET(v)        HFA384x_TX_GET(v, HFA384x_TX_CFPOLL,12)
+#define        HFA384x_TX_CFPOLL_SET(v)        HFA384x_TX_SET(v, HFA384x_TX_CFPOLL,12)
+#define        HFA384x_TX_PRST_GET(v)          HFA384x_TX_GET(v, HFA384x_TX_PRST,11)
+#define        HFA384x_TX_PRST_SET(v)          HFA384x_TX_SET(v, HFA384x_TX_PRST,11)
+#define        HFA384x_TX_MACPORT_GET(v)       HFA384x_TX_GET(v, HFA384x_TX_MACPORT, 8)
+#define        HFA384x_TX_MACPORT_SET(v)       HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8)
+#define        HFA384x_TX_NOENCRYPT_GET(v)     HFA384x_TX_GET(v, HFA384x_TX_NOENCRYPT, 7)
+#define        HFA384x_TX_NOENCRYPT_SET(v)     HFA384x_TX_SET(v, HFA384x_TX_NOENCRYPT, 7)
+#define        HFA384x_TX_RETRYSTRAT_GET(v)    HFA384x_TX_GET(v, HFA384x_TX_RETRYSTRAT, 5)
+#define        HFA384x_TX_RETRYSTRAT_SET(v)    HFA384x_TX_SET(v, HFA384x_TX_RETRYSTRAT, 5)
+#define        HFA384x_TX_STRUCTYPE_GET(v)     HFA384x_TX_GET(v, HFA384x_TX_STRUCTYPE, 3)
+#define        HFA384x_TX_STRUCTYPE_SET(v)     HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3)
+#define        HFA384x_TX_TXEX_GET(v)          HFA384x_TX_GET(v, HFA384x_TX_TXEX, 2)
+#define        HFA384x_TX_TXEX_SET(v)          HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2)
+#define        HFA384x_TX_TXOK_GET(v)          HFA384x_TX_GET(v, HFA384x_TX_TXOK, 1)
+#define        HFA384x_TX_TXOK_SET(v)          HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1)
+/*--------------------------------------------------------------------
+Communication Frames: Receive Frames
+--------------------------------------------------------------------*/
+/*-- Communication Frame: Receive Frame Structure --*/
+typedef struct hfa384x_rx_frame
+{
+       /*-- MAC rx descriptor (hfa384x byte order) --*/
+       UINT16  status;
+       UINT32  time;
+       UINT8   silence;
+       UINT8   signal;
+       UINT8   rate;
+       UINT8   rx_flow;
+       UINT16  reserved1;
+       UINT16  reserved2;
+
+       /*-- 802.11 Header Information (802.11 byte order) --*/
+       UINT16  frame_control;
+       UINT16  duration_id;
+       UINT8   address1[6];
+       UINT8   address2[6];
+       UINT8   address3[6];
+       UINT16  sequence_control;
+       UINT8   address4[6];
+       UINT16  data_len; /* hfa384x (little endian) format */
+
+       /*-- 802.3 Header Information --*/
+       UINT8   dest_addr[6];
+       UINT8   src_addr[6];
+       UINT16  data_length; /* IEEE? (big endian) format */
+} __WLAN_ATTRIB_PACK__ hfa384x_rx_frame_t;
+/*--------------------------------------------------------------------
+Communication Frames: Field Masks for Receive Frames
+--------------------------------------------------------------------*/
+/*-- Offsets --------*/
+#define                HFA384x_RX_DATA_LEN_OFF                 ((UINT16)44)
+#define                HFA384x_RX_80211HDR_OFF                 ((UINT16)14)
+#define                HFA384x_RX_DATA_OFF                     ((UINT16)60)
+
+/*-- Status Fields --*/
+#define                HFA384x_RXSTATUS_MSGTYPE                ((UINT16)(BIT15 | BIT14 | BIT13))
+#define                HFA384x_RXSTATUS_MACPORT                ((UINT16)(BIT10 | BIT9 | BIT8))
+#define                HFA384x_RXSTATUS_UNDECR                 ((UINT16)BIT1)
+#define                HFA384x_RXSTATUS_FCSERR                 ((UINT16)BIT0)
+/*--------------------------------------------------------------------
+Communication Frames: Test/Get/Set Field Values for Receive Frames
+--------------------------------------------------------------------*/
+#define                HFA384x_RXSTATUS_MSGTYPE_GET(value)     ((UINT16)((((UINT16)(value)) & HFA384x_RXSTATUS_MSGTYPE) >> 13))
+#define                HFA384x_RXSTATUS_MSGTYPE_SET(value)     ((UINT16)(((UINT16)(value)) << 13))
+#define                HFA384x_RXSTATUS_MACPORT_GET(value)     ((UINT16)((((UINT16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8))
+#define                HFA384x_RXSTATUS_MACPORT_SET(value)     ((UINT16)(((UINT16)(value)) << 8))
+#define                HFA384x_RXSTATUS_ISUNDECR(value)        ((UINT16)(((UINT16)(value)) & HFA384x_RXSTATUS_UNDECR))
+#define                HFA384x_RXSTATUS_ISFCSERR(value)        ((UINT16)(((UINT16)(value)) & HFA384x_RXSTATUS_FCSERR))
+/*--------------------------------------------------------------------
+ FRAME STRUCTURES: Information Types and Information Frame Structures
+----------------------------------------------------------------------
+Information Types
+--------------------------------------------------------------------*/
+#define                HFA384x_IT_HANDOVERADDR                 ((UINT16)0xF000UL)
+#define                HFA384x_IT_HANDOVERDEAUTHADDRESS        ((UINT16)0xF001UL)//AP 1.3.7
+#define                HFA384x_IT_COMMTALLIES                  ((UINT16)0xF100UL)
+#define                HFA384x_IT_SCANRESULTS                  ((UINT16)0xF101UL)
+#define                HFA384x_IT_CHINFORESULTS                ((UINT16)0xF102UL)
+#define                HFA384x_IT_HOSTSCANRESULTS              ((UINT16)0xF103UL)
+#define                HFA384x_IT_LINKSTATUS                   ((UINT16)0xF200UL)
+#define                HFA384x_IT_ASSOCSTATUS                  ((UINT16)0xF201UL)
+#define                HFA384x_IT_AUTHREQ                      ((UINT16)0xF202UL)
+#define                HFA384x_IT_PSUSERCNT                    ((UINT16)0xF203UL)
+#define                HFA384x_IT_KEYIDCHANGED                 ((UINT16)0xF204UL)
+#define                HFA384x_IT_ASSOCREQ                     ((UINT16)0xF205UL)
+#define                HFA384x_IT_MICFAILURE                   ((UINT16)0xF206UL)
+
+/*--------------------------------------------------------------------
+Information Frames Structures
+----------------------------------------------------------------------
+Information Frames: Notification Frame Structures
+--------------------------------------------------------------------*/
+/*--  Notification Frame,MAC Mgmt: Handover Address --*/
+typedef struct hfa384x_HandoverAddr
+{
+       UINT16  framelen;
+       UINT16  infotype;
+       UINT8   handover_addr[WLAN_BSSID_LEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_HandoverAddr_t;
+
+/*--  Inquiry Frame, Diagnose: Communication Tallies --*/
+typedef struct hfa384x_CommTallies16
+{
+       UINT16  txunicastframes;
+       UINT16  txmulticastframes;
+       UINT16  txfragments;
+       UINT16  txunicastoctets;
+       UINT16  txmulticastoctets;
+       UINT16  txdeferredtrans;
+       UINT16  txsingleretryframes;
+       UINT16  txmultipleretryframes;
+       UINT16  txretrylimitexceeded;
+       UINT16  txdiscards;
+       UINT16  rxunicastframes;
+       UINT16  rxmulticastframes;
+       UINT16  rxfragments;
+       UINT16  rxunicastoctets;
+       UINT16  rxmulticastoctets;
+       UINT16  rxfcserrors;
+       UINT16  rxdiscardsnobuffer;
+       UINT16  txdiscardswrongsa;
+       UINT16  rxdiscardswepundecr;
+       UINT16  rxmsginmsgfrag;
+       UINT16  rxmsginbadmsgfrag;
+} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies16_t;
+
+typedef struct hfa384x_CommTallies32
+{
+       UINT32  txunicastframes;
+       UINT32  txmulticastframes;
+       UINT32  txfragments;
+       UINT32  txunicastoctets;
+       UINT32  txmulticastoctets;
+       UINT32  txdeferredtrans;
+       UINT32  txsingleretryframes;
+       UINT32  txmultipleretryframes;
+       UINT32  txretrylimitexceeded;
+       UINT32  txdiscards;
+       UINT32  rxunicastframes;
+       UINT32  rxmulticastframes;
+       UINT32  rxfragments;
+       UINT32  rxunicastoctets;
+       UINT32  rxmulticastoctets;
+       UINT32  rxfcserrors;
+       UINT32  rxdiscardsnobuffer;
+       UINT32  txdiscardswrongsa;
+       UINT32  rxdiscardswepundecr;
+       UINT32  rxmsginmsgfrag;
+       UINT32  rxmsginbadmsgfrag;
+} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies32_t;
+
+/*--  Inquiry Frame, Diagnose: Scan Results & Subfields--*/
+typedef struct hfa384x_ScanResultSub
+{
+       UINT16  chid;
+       UINT16  anl;
+       UINT16  sl;
+       UINT8   bssid[WLAN_BSSID_LEN];
+       UINT16  bcnint;
+       UINT16  capinfo;
+       hfa384x_bytestr32_t     ssid;
+       UINT8   supprates[10]; /* 802.11 info element */
+       UINT16  proberesp_rate;
+} __WLAN_ATTRIB_PACK__ hfa384x_ScanResultSub_t;
+
+typedef struct hfa384x_ScanResult
+{
+       UINT16  rsvd;
+       UINT16  scanreason;
+       hfa384x_ScanResultSub_t
+               result[HFA384x_SCANRESULT_MAX];
+} __WLAN_ATTRIB_PACK__ hfa384x_ScanResult_t;
+
+/*--  Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/
+typedef struct hfa384x_ChInfoResultSub
+{
+       UINT16  chid;
+       UINT16  anl;
+       UINT16  pnl;
+       UINT16  active;
+} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResultSub_t;
+
+#define HFA384x_CHINFORESULT_BSSACTIVE BIT0
+#define HFA384x_CHINFORESULT_PCFACTIVE BIT1
+
+typedef struct hfa384x_ChInfoResult
+{
+       UINT16  scanchannels;
+       hfa384x_ChInfoResultSub_t
+               result[HFA384x_CHINFORESULT_MAX];
+} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResult_t;
+
+/*--  Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/
+typedef struct hfa384x_HScanResultSub
+{
+       UINT16  chid;
+       UINT16  anl;
+       UINT16  sl;
+       UINT8   bssid[WLAN_BSSID_LEN];
+       UINT16  bcnint;
+       UINT16  capinfo;
+       hfa384x_bytestr32_t     ssid;
+       UINT8   supprates[10]; /* 802.11 info element */
+       UINT16  proberesp_rate;
+       UINT16  atim;
+} __WLAN_ATTRIB_PACK__ hfa384x_HScanResultSub_t;
+
+typedef struct hfa384x_HScanResult
+{
+       UINT16  nresult;
+       UINT16  rsvd;
+       hfa384x_HScanResultSub_t
+               result[HFA384x_HSCANRESULT_MAX];
+} __WLAN_ATTRIB_PACK__ hfa384x_HScanResult_t;
+
+/*--  Unsolicited Frame, MAC Mgmt: LinkStatus --*/
+
+#define HFA384x_LINK_NOTCONNECTED      ((UINT16)0)
+#define HFA384x_LINK_CONNECTED         ((UINT16)1)
+#define HFA384x_LINK_DISCONNECTED      ((UINT16)2)
+#define HFA384x_LINK_AP_CHANGE         ((UINT16)3)
+#define HFA384x_LINK_AP_OUTOFRANGE     ((UINT16)4)
+#define HFA384x_LINK_AP_INRANGE                ((UINT16)5)
+#define HFA384x_LINK_ASSOCFAIL         ((UINT16)6)
+
+typedef struct hfa384x_LinkStatus
+{
+       UINT16  linkstatus;
+} __WLAN_ATTRIB_PACK__ hfa384x_LinkStatus_t;
+
+
+/*--  Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/
+
+#define HFA384x_ASSOCSTATUS_STAASSOC   ((UINT16)1)
+#define HFA384x_ASSOCSTATUS_REASSOC    ((UINT16)2)
+#define HFA384x_ASSOCSTATUS_DISASSOC   ((UINT16)3)
+#define HFA384x_ASSOCSTATUS_ASSOCFAIL  ((UINT16)4)
+#define HFA384x_ASSOCSTATUS_AUTHFAIL   ((UINT16)5)
+
+typedef struct hfa384x_AssocStatus
+{
+       UINT16  assocstatus;
+       UINT8   sta_addr[WLAN_ADDR_LEN];
+       /* old_ap_addr is only valid if assocstatus == 2 */
+       UINT8   old_ap_addr[WLAN_ADDR_LEN];
+       UINT16  reason;
+       UINT16  reserved;
+} __WLAN_ATTRIB_PACK__ hfa384x_AssocStatus_t;
+
+/*--  Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/
+
+typedef struct hfa384x_AuthRequest
+{
+       UINT8   sta_addr[WLAN_ADDR_LEN];
+       UINT16  algorithm;
+} __WLAN_ATTRIB_PACK__ hfa384x_AuthReq_t;
+
+/*--  Unsolicited Frame, MAC Mgmt: AssocRequest (AP Only) --*/
+
+typedef struct hfa384x_AssocRequest
+{
+       UINT8   sta_addr[WLAN_ADDR_LEN];
+       UINT16  type;
+       UINT8   wpa_data[80];
+} __WLAN_ATTRIB_PACK__ hfa384x_AssocReq_t;
+
+
+#define HFA384x_ASSOCREQ_TYPE_ASSOC     0
+#define HFA384x_ASSOCREQ_TYPE_REASSOC   1
+
+/*--  Unsolicited Frame, MAC Mgmt: MIC Failure  (AP Only) --*/
+
+typedef struct hfa384x_MicFailure
+{
+       UINT8   sender[WLAN_ADDR_LEN];
+       UINT8   dest[WLAN_ADDR_LEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_MicFailure_t;
+
+/*--  Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/
+
+typedef struct hfa384x_PSUserCount
+{
+       UINT16  usercnt;
+} __WLAN_ATTRIB_PACK__ hfa384x_PSUserCount_t;
+
+typedef struct hfa384x_KeyIDChanged
+{
+       UINT8   sta_addr[WLAN_ADDR_LEN];
+       UINT16  keyid;
+} __WLAN_ATTRIB_PACK__ hfa384x_KeyIDChanged_t;
+
+/*--  Collection of all Inf frames ---------------*/
+typedef union hfa384x_infodata {
+       hfa384x_CommTallies16_t commtallies16;
+       hfa384x_CommTallies32_t commtallies32;
+       hfa384x_ScanResult_t    scanresult;
+       hfa384x_ChInfoResult_t  chinforesult;
+       hfa384x_HScanResult_t   hscanresult;
+       hfa384x_LinkStatus_t    linkstatus;
+       hfa384x_AssocStatus_t   assocstatus;
+       hfa384x_AuthReq_t       authreq;
+       hfa384x_PSUserCount_t   psusercnt;
+       hfa384x_KeyIDChanged_t  keyidchanged;
+} __WLAN_ATTRIB_PACK__ hfa384x_infodata_t;
+
+typedef struct hfa384x_InfFrame
+{
+       UINT16                  framelen;
+       UINT16                  infotype;
+       hfa384x_infodata_t      info;
+} __WLAN_ATTRIB_PACK__ hfa384x_InfFrame_t;
+
+#if (WLAN_HOSTIF == WLAN_USB)
+/*--------------------------------------------------------------------
+USB Packet structures and constants.
+--------------------------------------------------------------------*/
+
+/* Should be sent to the ctrlout endpoint */
+#define HFA384x_USB_ENBULKIN   6
+
+/* Should be sent to the bulkout endpoint */
+#define HFA384x_USB_TXFRM      0
+#define HFA384x_USB_CMDREQ     1
+#define HFA384x_USB_WRIDREQ    2
+#define HFA384x_USB_RRIDREQ    3
+#define HFA384x_USB_WMEMREQ    4
+#define HFA384x_USB_RMEMREQ    5
+
+/* Received from the bulkin endpoint */
+#define HFA384x_USB_ISFRM(a)   (!((a) & 0x8000))
+#define HFA384x_USB_ISTXFRM(a) (((a) & 0x9000) == 0x1000)
+#define HFA384x_USB_ISRXFRM(a) (!((a) & 0x9000))
+#define HFA384x_USB_INFOFRM    0x8000
+#define HFA384x_USB_CMDRESP    0x8001
+#define HFA384x_USB_WRIDRESP   0x8002
+#define HFA384x_USB_RRIDRESP   0x8003
+#define HFA384x_USB_WMEMRESP   0x8004
+#define HFA384x_USB_RMEMRESP   0x8005
+#define HFA384x_USB_BUFAVAIL   0x8006
+#define HFA384x_USB_ERROR      0x8007
+
+/*------------------------------------*/
+/* Request (bulk OUT) packet contents */
+
+typedef struct hfa384x_usb_txfrm {
+       hfa384x_tx_frame_t      desc;
+       UINT8                   data[WLAN_DATA_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_txfrm_t;
+
+typedef struct hfa384x_usb_cmdreq {
+       UINT16          type;
+       UINT16          cmd;
+       UINT16          parm0;
+       UINT16          parm1;
+       UINT16          parm2;
+       UINT8           pad[54];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdreq_t;
+
+typedef struct hfa384x_usb_wridreq {
+       UINT16          type;
+       UINT16          frmlen;
+       UINT16          rid;
+       UINT8           data[HFA384x_RIDDATA_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_wridreq_t;
+
+typedef struct hfa384x_usb_rridreq {
+       UINT16          type;
+       UINT16          frmlen;
+       UINT16          rid;
+       UINT8           pad[58];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridreq_t;
+
+typedef struct hfa384x_usb_wmemreq {
+       UINT16          type;
+       UINT16          frmlen;
+       UINT16          offset;
+       UINT16          page;
+       UINT8           data[HFA384x_USB_RWMEM_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_wmemreq_t;
+
+typedef struct hfa384x_usb_rmemreq {
+       UINT16          type;
+       UINT16          frmlen;
+       UINT16          offset;
+       UINT16          page;
+       UINT8           pad[56];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemreq_t;
+
+/*------------------------------------*/
+/* Response (bulk IN) packet contents */
+
+typedef struct hfa384x_usb_rxfrm {
+       hfa384x_rx_frame_t      desc;
+       UINT8                   data[WLAN_DATA_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rxfrm_t;
+
+typedef struct hfa384x_usb_infofrm {
+       UINT16                  type;
+       hfa384x_InfFrame_t      info;
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_infofrm_t;
+
+typedef struct hfa384x_usb_statusresp {
+       UINT16          type;
+       UINT16          status;
+       UINT16          resp0;
+       UINT16          resp1;
+       UINT16          resp2;
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdresp_t;
+
+typedef hfa384x_usb_cmdresp_t hfa384x_usb_wridresp_t;
+
+typedef struct hfa384x_usb_rridresp {
+       UINT16          type;
+       UINT16          frmlen;
+       UINT16          rid;
+       UINT8           data[HFA384x_RIDDATA_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridresp_t;
+
+typedef hfa384x_usb_cmdresp_t hfa384x_usb_wmemresp_t;
+
+typedef struct hfa384x_usb_rmemresp {
+       UINT16          type;
+       UINT16          frmlen;
+       UINT8           data[HFA384x_USB_RWMEM_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemresp_t;
+
+typedef struct hfa384x_usb_bufavail {
+       UINT16          type;
+       UINT16          frmlen;
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_bufavail_t;
+
+typedef struct hfa384x_usb_error {
+       UINT16          type;
+       UINT16          errortype;
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_error_t;
+
+/*----------------------------------------------------------*/
+/* Unions for packaging all the known packet types together */
+
+typedef union hfa384x_usbout {
+       UINT16                  type;
+       hfa384x_usb_txfrm_t     txfrm;
+       hfa384x_usb_cmdreq_t    cmdreq;
+       hfa384x_usb_wridreq_t   wridreq;
+       hfa384x_usb_rridreq_t   rridreq;
+       hfa384x_usb_wmemreq_t   wmemreq;
+       hfa384x_usb_rmemreq_t   rmemreq;
+} __WLAN_ATTRIB_PACK__ hfa384x_usbout_t;
+
+typedef union hfa384x_usbin {
+       UINT16                  type;
+       hfa384x_usb_rxfrm_t     rxfrm;
+       hfa384x_usb_txfrm_t     txfrm;
+       hfa384x_usb_infofrm_t   infofrm;
+       hfa384x_usb_cmdresp_t   cmdresp;
+       hfa384x_usb_wridresp_t  wridresp;
+       hfa384x_usb_rridresp_t  rridresp;
+       hfa384x_usb_wmemresp_t  wmemresp;
+       hfa384x_usb_rmemresp_t  rmemresp;
+       hfa384x_usb_bufavail_t  bufavail;
+       hfa384x_usb_error_t     usberror;
+       UINT8                   boguspad[3000];
+} __WLAN_ATTRIB_PACK__ hfa384x_usbin_t;
+
+#endif /* WLAN_USB */
+
+/*--------------------------------------------------------------------
+PD record structures.
+--------------------------------------------------------------------*/
+
+typedef struct hfa384x_pdr_pcb_partnum
+{
+       UINT8   num[8];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_partnum_t;
+
+typedef struct hfa384x_pdr_pcb_tracenum
+{
+       UINT8   num[8];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_tracenum_t;
+
+typedef struct hfa384x_pdr_nic_serial
+{
+       UINT8   num[12];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_serial_t;
+
+typedef struct hfa384x_pdr_mkk_measurements
+{
+       double  carrier_freq;
+       double  occupied_band;
+       double  power_density;
+       double  tx_spur_f1;
+       double  tx_spur_f2;
+       double  tx_spur_f3;
+       double  tx_spur_f4;
+       double  tx_spur_l1;
+       double  tx_spur_l2;
+       double  tx_spur_l3;
+       double  tx_spur_l4;
+       double  rx_spur_f1;
+       double  rx_spur_f2;
+       double  rx_spur_l1;
+       double  rx_spur_l2;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_measurements_t;
+
+typedef struct hfa384x_pdr_nic_ramsize
+{
+       UINT8   size[12]; /* units of KB */
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_ramsize_t;
+
+typedef struct hfa384x_pdr_mfisuprange
+{
+       UINT16  id;
+       UINT16  variant;
+       UINT16  bottom;
+       UINT16  top;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mfisuprange_t;
+
+typedef struct hfa384x_pdr_cfisuprange
+{
+       UINT16  id;
+       UINT16  variant;
+       UINT16  bottom;
+       UINT16  top;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_cfisuprange_t;
+
+typedef struct hfa384x_pdr_nicid
+{
+       UINT16  id;
+       UINT16  variant;
+       UINT16  major;
+       UINT16  minor;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nicid_t;
+
+
+typedef struct hfa384x_pdr_refdac_measurements
+{
+       UINT16  value[0];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_measurements_t;
+
+typedef struct hfa384x_pdr_vgdac_measurements
+{
+       UINT16  value[0];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_measurements_t;
+
+typedef struct hfa384x_pdr_level_comp_measurements
+{
+       UINT16  value[0];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_compc_measurements_t;
+
+typedef struct hfa384x_pdr_mac_address
+{
+       UINT8   addr[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mac_address_t;
+
+typedef struct hfa384x_pdr_mkk_callname
+{
+       UINT8   callname[8];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_callname_t;
+
+typedef struct hfa384x_pdr_regdomain
+{
+       UINT16  numdomains;
+       UINT16  domain[5];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_regdomain_t;
+
+typedef struct hfa384x_pdr_allowed_channel
+{
+       UINT16  ch_bitmap;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_allowed_channel_t;
+
+typedef struct hfa384x_pdr_default_channel
+{
+       UINT16  channel;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_default_channel_t;
+
+typedef struct hfa384x_pdr_privacy_option
+{
+       UINT16  available;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_privacy_option_t;
+
+typedef struct hfa384x_pdr_temptype
+{
+       UINT16  type;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_temptype_t;
+
+typedef struct hfa384x_pdr_refdac_setup
+{
+       UINT16  ch_value[14];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_setup_t;
+
+typedef struct hfa384x_pdr_vgdac_setup
+{
+       UINT16  ch_value[14];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_setup_t;
+
+typedef struct hfa384x_pdr_level_comp_setup
+{
+       UINT16  ch_value[14];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_comp_setup_t;
+
+typedef struct hfa384x_pdr_trimdac_setup
+{
+       UINT16  trimidac;
+       UINT16  trimqdac;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_trimdac_setup_t;
+
+typedef struct hfa384x_pdr_ifr_setting
+{
+       UINT16  value[3];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_ifr_setting_t;
+
+typedef struct hfa384x_pdr_rfr_setting
+{
+       UINT16  value[3];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_rfr_setting_t;
+
+typedef struct hfa384x_pdr_hfa3861_baseline
+{
+       UINT16  value[50];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_baseline_t;
+
+typedef struct hfa384x_pdr_hfa3861_shadow
+{
+       UINT32  value[32];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_shadow_t;
+
+typedef struct hfa384x_pdr_hfa3861_ifrf
+{
+       UINT32  value[20];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_ifrf_t;
+
+typedef struct hfa384x_pdr_hfa3861_chcalsp
+{
+       UINT16  value[14];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcalsp_t;
+
+typedef struct hfa384x_pdr_hfa3861_chcali
+{
+       UINT16  value[17];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcali_t;
+
+typedef struct hfa384x_pdr_hfa3861_nic_config
+{
+       UINT16  config_bitmap;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_config_t;
+
+typedef struct hfa384x_pdr_hfo_delay
+{
+       UINT8   hfo_delay;
+} __WLAN_ATTRIB_PACK__ hfa384x_hfo_delay_t;
+
+typedef struct hfa384x_pdr_hfa3861_manf_testsp
+{
+       UINT16  value[30];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testsp_t;
+
+typedef struct hfa384x_pdr_hfa3861_manf_testi
+{
+       UINT16  value[30];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testi_t;
+
+typedef struct hfa384x_end_of_pda
+{
+       UINT16  crc;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_end_of_pda_t;
+
+typedef struct hfa384x_pdrec
+{
+       UINT16  len; /* in words */
+       UINT16  code;
+       union pdr {
+       hfa384x_pdr_pcb_partnum_t       pcb_partnum;
+       hfa384x_pdr_pcb_tracenum_t      pcb_tracenum;
+       hfa384x_pdr_nic_serial_t        nic_serial;
+       hfa384x_pdr_mkk_measurements_t  mkk_measurements;
+       hfa384x_pdr_nic_ramsize_t       nic_ramsize;
+       hfa384x_pdr_mfisuprange_t       mfisuprange;
+       hfa384x_pdr_cfisuprange_t       cfisuprange;
+       hfa384x_pdr_nicid_t             nicid;
+       hfa384x_pdr_refdac_measurements_t       refdac_measurements;
+       hfa384x_pdr_vgdac_measurements_t        vgdac_measurements;
+       hfa384x_pdr_level_compc_measurements_t  level_compc_measurements;
+       hfa384x_pdr_mac_address_t       mac_address;
+       hfa384x_pdr_mkk_callname_t      mkk_callname;
+       hfa384x_pdr_regdomain_t         regdomain;
+       hfa384x_pdr_allowed_channel_t   allowed_channel;
+       hfa384x_pdr_default_channel_t   default_channel;
+       hfa384x_pdr_privacy_option_t    privacy_option;
+       hfa384x_pdr_temptype_t          temptype;
+       hfa384x_pdr_refdac_setup_t      refdac_setup;
+       hfa384x_pdr_vgdac_setup_t       vgdac_setup;
+       hfa384x_pdr_level_comp_setup_t  level_comp_setup;
+       hfa384x_pdr_trimdac_setup_t     trimdac_setup;
+       hfa384x_pdr_ifr_setting_t       ifr_setting;
+       hfa384x_pdr_rfr_setting_t       rfr_setting;
+       hfa384x_pdr_hfa3861_baseline_t  hfa3861_baseline;
+       hfa384x_pdr_hfa3861_shadow_t    hfa3861_shadow;
+       hfa384x_pdr_hfa3861_ifrf_t      hfa3861_ifrf;
+       hfa384x_pdr_hfa3861_chcalsp_t   hfa3861_chcalsp;
+       hfa384x_pdr_hfa3861_chcali_t    hfa3861_chcali;
+       hfa384x_pdr_nic_config_t        nic_config;
+       hfa384x_hfo_delay_t             hfo_delay;
+       hfa384x_pdr_hfa3861_manf_testsp_t       hfa3861_manf_testsp;
+       hfa384x_pdr_hfa3861_manf_testi_t        hfa3861_manf_testi;
+       hfa384x_pdr_end_of_pda_t        end_of_pda;
+
+       } data;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdrec_t;
+
+
+#ifdef __KERNEL__
+/*--------------------------------------------------------------------
+---  MAC state structure, argument to all functions --
+---  Also, a collection of support types --
+--------------------------------------------------------------------*/
+typedef struct hfa384x_statusresult
+{
+       UINT16  status;
+       UINT16  resp0;
+       UINT16  resp1;
+       UINT16  resp2;
+} hfa384x_cmdresult_t;
+
+#if (WLAN_HOSTIF == WLAN_USB)
+
+/* USB Control Exchange (CTLX):
+ *  A queue of the structure below is maintained for all of the
+ *  Request/Response type USB packets supported by Prism2.
+ */
+/* The following hfa384x_* structures are arguments to
+ * the usercb() for the different CTLX types.
+ */
+typedef hfa384x_cmdresult_t hfa384x_wridresult_t;
+typedef hfa384x_cmdresult_t hfa384x_wmemresult_t;
+
+typedef struct hfa384x_rridresult
+{
+       UINT16          rid;
+       const void      *riddata;
+       UINT            riddata_len;
+} hfa384x_rridresult_t;
+
+enum ctlx_state {
+       CTLX_START = 0, /* Start state, not queued */
+
+       CTLX_COMPLETE,  /* CTLX successfully completed */
+       CTLX_REQ_FAILED,        /* OUT URB completed w/ error */
+
+       CTLX_PENDING,           /* Queued, data valid */
+       CTLX_REQ_SUBMITTED,     /* OUT URB submitted */
+       CTLX_REQ_COMPLETE,      /* OUT URB complete */
+       CTLX_RESP_COMPLETE      /* IN URB received */
+};
+typedef enum ctlx_state  CTLX_STATE;
+
+struct hfa384x_usbctlx;
+struct hfa384x;
+
+typedef void (*ctlx_cmdcb_t)( struct hfa384x*, const struct hfa384x_usbctlx* );
+
+typedef void (*ctlx_usercb_t)(
+       struct hfa384x  *hw,
+       void            *ctlxresult,
+       void            *usercb_data);
+
+typedef struct hfa384x_usbctlx
+{
+       struct list_head        list;
+
+       size_t                  outbufsize;
+       hfa384x_usbout_t        outbuf;         /* pkt buf for OUT */
+       hfa384x_usbin_t         inbuf;          /* pkt buf for IN(a copy) */
+
+       CTLX_STATE              state;          /* Tracks running state */
+
+       struct completion       done;
+       volatile int            reapable;       /* Food for the reaper task */
+
+       ctlx_cmdcb_t            cmdcb;          /* Async command callback */
+       ctlx_usercb_t           usercb;         /* Async user callback, */
+       void                    *usercb_data;   /*  at CTLX completion  */
+
+       int                     variant;        /* Identifies cmd variant */
+} hfa384x_usbctlx_t;
+
+typedef struct hfa384x_usbctlxq
+{
+       spinlock_t              lock;
+       struct list_head        pending;
+       struct list_head        active;
+       struct list_head        completing;
+       struct list_head        reapable;
+} hfa384x_usbctlxq_t;
+#endif
+
+typedef struct hfa484x_metacmd
+{
+       UINT16          cmd;
+
+       UINT16          parm0;
+       UINT16          parm1;
+       UINT16          parm2;
+
+#if 0 //XXX cmd irq stuff
+       UINT16          bulkid;         /* what RID/FID to copy down. */
+       int             bulklen;        /* how much to copy from BAP */
+        char            *bulkdata;      /* And to where? */
+#endif
+
+       hfa384x_cmdresult_t result;
+} hfa384x_metacmd_t;
+
+#define        MAX_PRISM2_GRP_ADDR     16
+#define        MAX_GRP_ADDR            32
+#define WLAN_COMMENT_MAX       80  /* Max. length of user comment string. */
+
+#define MM_SAT_PCF             (BIT14)
+#define MM_GCSD_PCF            (BIT15)
+#define MM_GCSD_PCF_EB         (BIT14 | BIT15)
+
+#define WLAN_STATE_STOPPED     0   /* Network is not active. */
+#define WLAN_STATE_STARTED     1   /* Network has been started. */
+
+#define WLAN_AUTH_MAX           60  /* Max. # of authenticated stations. */
+#define WLAN_ACCESS_MAX                60  /* Max. # of stations in an access list. */
+#define WLAN_ACCESS_NONE       0   /* No stations may be authenticated. */
+#define WLAN_ACCESS_ALL                1   /* All stations may be authenticated. */
+#define WLAN_ACCESS_ALLOW      2   /* Authenticate only "allowed" stations. */
+#define WLAN_ACCESS_DENY       3   /* Do not authenticate "denied" stations. */
+
+/* XXX These are going away ASAP */
+typedef struct prism2sta_authlist
+{
+       UINT    cnt;
+       UINT8   addr[WLAN_AUTH_MAX][WLAN_ADDR_LEN];
+       UINT8   assoc[WLAN_AUTH_MAX];
+} prism2sta_authlist_t;
+
+typedef struct prism2sta_accesslist
+{
+       UINT    modify;
+       UINT    cnt;
+       UINT8   addr[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
+       UINT    cnt1;
+       UINT8   addr1[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
+} prism2sta_accesslist_t;
+
+typedef struct hfa384x
+{
+#if (WLAN_HOSTIF != WLAN_USB)
+       /* Resource config */
+       UINT32                  iobase;
+       char                    __iomem *membase;
+       UINT32                  irq;
+#else
+       /* USB support data */
+       struct usb_device       *usb;
+       struct urb              rx_urb;
+       struct sk_buff          *rx_urb_skb;
+       struct urb              tx_urb;
+       struct urb              ctlx_urb;
+       hfa384x_usbout_t        txbuff;
+       hfa384x_usbctlxq_t      ctlxq;
+       struct timer_list       reqtimer;
+       struct timer_list       resptimer;
+
+       struct timer_list       throttle;
+
+       struct tasklet_struct   reaper_bh;
+       struct tasklet_struct   completion_bh;
+
+       struct work_struct      usb_work;
+
+       unsigned long           usb_flags;
+#define THROTTLE_RX    0
+#define THROTTLE_TX    1
+#define WORK_RX_HALT   2
+#define WORK_TX_HALT   3
+#define WORK_RX_RESUME 4
+#define WORK_TX_RESUME 5
+
+       unsigned short          req_timer_done:1;
+       unsigned short          resp_timer_done:1;
+
+       int                     endp_in;
+       int                     endp_out;
+#endif /* !USB */
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       struct pcmcia_device *pdev;
+#else
+       dev_link_t      *link;
+#endif
+       dev_node_t      node;
+#endif
+
+       int                     sniff_fcs;
+       int                     sniff_channel;
+       int                     sniff_truncate;
+       int                     sniffhdr;
+
+       wait_queue_head_t cmdq;         /* wait queue itself */
+
+       /* Controller state */
+       UINT32          state;
+       UINT32          isap;
+       UINT8           port_enabled[HFA384x_NUMPORTS_MAX];
+#if (WLAN_HOSTIF != WLAN_USB)
+       UINT            auxen;
+       UINT            isram16;
+#endif /* !USB */
+
+       /* Download support */
+       UINT                            dlstate;
+       hfa384x_downloadbuffer_t        bufinfo;
+       UINT16                          dltimeout;
+
+#if (WLAN_HOSTIF != WLAN_USB)
+       spinlock_t      cmdlock;
+       volatile int    cmdflag;        /* wait queue flag */
+       hfa384x_metacmd_t *cmddata;      /* for our async callback */
+
+       /* BAP support */
+       spinlock_t      baplock;
+       struct tasklet_struct   bap_tasklet;
+
+       /* MAC buffer ids */
+        UINT16          txfid_head;
+        UINT16          txfid_tail;
+        UINT            txfid_N;
+        UINT16          txfid_queue[HFA384x_DRVR_FIDSTACKLEN_MAX];
+       UINT16                  infofid;
+       struct semaphore        infofid_sem;
+#endif /* !USB */
+
+       int                          scanflag;    /* to signal scan comlete */
+       int                          join_ap;        /* are we joined to a specific ap */
+       int                          join_retries;   /* number of join retries till we fail */
+       hfa384x_JoinRequest_data_t   joinreq;        /* join request saved data */
+
+       wlandevice_t            *wlandev;
+       /* Timer to allow for the deferred processing of linkstatus messages */
+       struct work_struct      link_bh;
+
+        struct work_struct      commsqual_bh;
+       hfa384x_commsquality_t  qual;
+       struct timer_list       commsqual_timer;
+
+       UINT16 link_status;
+       UINT16 link_status_new;
+       struct sk_buff_head        authq;
+
+       /* And here we have stuff that used to be in priv */
+
+       /* State variables */
+       UINT            presniff_port_type;
+       UINT16          presniff_wepflags;
+       UINT32          dot11_desired_bss_type;
+       int             ap;     /* AP flag: 0 - Station, 1 - Access Point. */
+
+       int             dbmadjust;
+
+       /* Group Addresses - right now, there are up to a total
+       of MAX_GRP_ADDR group addresses */
+       UINT8           dot11_grp_addr[MAX_GRP_ADDR][WLAN_ADDR_LEN];
+       UINT            dot11_grpcnt;
+
+       /* Component Identities */
+       hfa384x_compident_t     ident_nic;
+       hfa384x_compident_t     ident_pri_fw;
+       hfa384x_compident_t     ident_sta_fw;
+       hfa384x_compident_t     ident_ap_fw;
+       UINT16                  mm_mods;
+
+       /* Supplier compatibility ranges */
+       hfa384x_caplevel_t      cap_sup_mfi;
+       hfa384x_caplevel_t      cap_sup_cfi;
+       hfa384x_caplevel_t      cap_sup_pri;
+       hfa384x_caplevel_t      cap_sup_sta;
+       hfa384x_caplevel_t      cap_sup_ap;
+
+       /* Actor compatibility ranges */
+       hfa384x_caplevel_t      cap_act_pri_cfi; /* pri f/w to controller interface */
+       hfa384x_caplevel_t      cap_act_sta_cfi; /* sta f/w to controller interface */
+       hfa384x_caplevel_t      cap_act_sta_mfi; /* sta f/w to modem interface */
+       hfa384x_caplevel_t      cap_act_ap_cfi;  /* ap f/w to controller interface */
+       hfa384x_caplevel_t      cap_act_ap_mfi;  /* ap f/w to modem interface */
+
+       UINT32                  psusercount;  /* Power save user count. */
+       hfa384x_CommTallies32_t tallies;      /* Communication tallies. */
+       UINT8                   comment[WLAN_COMMENT_MAX+1]; /* User comment */
+
+       /* Channel Info request results (AP only) */
+       struct {
+               atomic_t                done;
+               UINT8                   count;
+               hfa384x_ChInfoResult_t  results;
+       } channel_info;
+
+       hfa384x_InfFrame_t      *scanresults;
+
+
+        prism2sta_authlist_t   authlist;     /* Authenticated station list. */
+       UINT                    accessmode;   /* Access mode. */
+        prism2sta_accesslist_t allow;        /* Allowed station list. */
+        prism2sta_accesslist_t deny;         /* Denied station list. */
+
+} hfa384x_t;
+
+/*=============================================================*/
+/*--- Function Declarations -----------------------------------*/
+/*=============================================================*/
+#if (WLAN_HOSTIF == WLAN_USB)
+void
+hfa384x_create(
+       hfa384x_t *hw,
+       struct usb_device *usb);
+#else
+void
+hfa384x_create(
+       hfa384x_t *hw,
+       UINT irq,
+       UINT32 iobase,
+       UINT8 __iomem *membase);
+#endif
+
+void hfa384x_destroy(hfa384x_t *hw);
+
+irqreturn_t
+hfa384x_interrupt(int irq, void *dev_id PT_REGS);
+int
+hfa384x_corereset( hfa384x_t *hw, int holdtime, int settletime, int genesis);
+int
+hfa384x_drvr_chinforesults( hfa384x_t *hw);
+int
+hfa384x_drvr_commtallies( hfa384x_t *hw);
+int
+hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport);
+int
+hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport);
+int
+hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
+int
+hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
+int
+hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len);
+int
+hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len);
+int
+hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr);
+int
+hfa384x_drvr_hostscanresults( hfa384x_t *hw);
+int
+hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd);
+int
+hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 address, UINT32 *result);
+int
+hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 address, UINT32 data);
+int
+hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr);
+int
+hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
+int
+hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len);
+int
+hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len);
+int
+hfa384x_drvr_scanresults( hfa384x_t *hw);
+
+int
+hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len);
+
+static inline int
+hfa384x_drvr_getconfig16(hfa384x_t *hw, UINT16 rid, void *val)
+{
+       int             result = 0;
+       result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT16));
+       if ( result == 0 ) {
+               *((UINT16*)val) = hfa384x2host_16(*((UINT16*)val));
+       }
+       return result;
+}
+
+static inline int
+hfa384x_drvr_getconfig32(hfa384x_t *hw, UINT16 rid, void *val)
+{
+       int             result = 0;
+
+       result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT32));
+       if ( result == 0 ) {
+               *((UINT32*)val) = hfa384x2host_32(*((UINT32*)val));
+       }
+
+       return result;
+}
+
+static inline int
+hfa384x_drvr_setconfig16(hfa384x_t *hw, UINT16 rid, UINT16 val)
+{
+       UINT16 value = host2hfa384x_16(val);
+       return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
+}
+
+static inline int
+hfa384x_drvr_setconfig32(hfa384x_t *hw, UINT16 rid, UINT32 val)
+{
+       UINT32 value = host2hfa384x_32(val);
+       return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
+}
+
+#if (WLAN_HOSTIF == WLAN_USB)
+int
+hfa384x_drvr_getconfig_async(hfa384x_t     *hw,
+                              UINT16        rid,
+                              ctlx_usercb_t usercb,
+                              void          *usercb_data);
+
+int
+hfa384x_drvr_setconfig_async(hfa384x_t *hw,
+                              UINT16 rid,
+                              void *buf,
+                              UINT16 len,
+                              ctlx_usercb_t usercb,
+                              void *usercb_data);
+#else
+static inline int
+hfa384x_drvr_setconfig_async(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len,
+                            void *ptr1, void *ptr2)
+{
+         (void)ptr1;
+         (void)ptr2;
+         return hfa384x_drvr_setconfig(hw, rid, buf, len);
+}
+#endif
+
+static inline int
+hfa384x_drvr_setconfig16_async(hfa384x_t *hw, UINT16 rid, UINT16 val)
+{
+       UINT16 value = host2hfa384x_16(val);
+       return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
+                                           NULL , NULL);
+}
+
+static inline int
+hfa384x_drvr_setconfig32_async(hfa384x_t *hw, UINT16 rid, UINT32 val)
+{
+       UINT32 value = host2hfa384x_32(val);
+       return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
+                                           NULL , NULL);
+}
+
+
+int
+hfa384x_drvr_start(hfa384x_t *hw);
+int
+hfa384x_drvr_stop(hfa384x_t *hw);
+int
+hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+void
+hfa384x_tx_timeout(wlandevice_t *wlandev);
+
+int
+hfa384x_cmd_initialize(hfa384x_t *hw);
+int
+hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport);
+int
+hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport);
+int
+hfa384x_cmd_diagnose(hfa384x_t *hw);
+int
+hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len);
+int
+hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid);
+int
+hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid);
+int
+hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, void *buf, UINT16 len);
+int
+hfa384x_cmd_inquire(hfa384x_t *hw, UINT16 fid);
+int
+hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid, void *buf, UINT16 len);
+int
+hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable);
+int
+hfa384x_cmd_download(
+       hfa384x_t *hw,
+       UINT16 mode,
+       UINT16 lowaddr,
+       UINT16 highaddr,
+       UINT16 codelen);
+int
+hfa384x_cmd_aux_enable(hfa384x_t *hw, int force);
+int
+hfa384x_cmd_aux_disable(hfa384x_t *hw);
+int
+hfa384x_copy_from_bap(
+       hfa384x_t *hw,
+       UINT16  bap,
+       UINT16  id,
+       UINT16  offset,
+       void    *buf,
+       UINT    len);
+int
+hfa384x_copy_to_bap(
+       hfa384x_t *hw,
+       UINT16  bap,
+       UINT16  id,
+       UINT16  offset,
+       void    *buf,
+       UINT    len);
+void
+hfa384x_copy_from_aux(
+       hfa384x_t *hw,
+       UINT32  cardaddr,
+       UINT32  auxctl,
+       void    *buf,
+       UINT    len);
+void
+hfa384x_copy_to_aux(
+       hfa384x_t *hw,
+       UINT32  cardaddr,
+       UINT32  auxctl,
+       void    *buf,
+       UINT    len);
+
+#if (WLAN_HOSTIF != WLAN_USB)
+
+/*
+   HFA384x is a LITTLE ENDIAN part.
+
+   the get/setreg functions implicitly byte-swap the data to LE.
+   the _noswap variants do not perform a byte-swap on the data.
+*/
+
+static inline UINT16
+__hfa384x_getreg(hfa384x_t *hw, UINT reg);
+
+static inline void
+__hfa384x_setreg(hfa384x_t *hw, UINT16 val, UINT reg);
+
+static inline UINT16
+__hfa384x_getreg_noswap(hfa384x_t *hw, UINT reg);
+
+static inline void
+__hfa384x_setreg_noswap(hfa384x_t *hw, UINT16 val, UINT reg);
+
+#ifdef REVERSE_ENDIAN
+#define hfa384x_getreg __hfa384x_getreg_noswap
+#define hfa384x_setreg __hfa384x_setreg_noswap
+#define hfa384x_getreg_noswap __hfa384x_getreg
+#define hfa384x_setreg_noswap __hfa384x_setreg
+#else
+#define hfa384x_getreg __hfa384x_getreg
+#define hfa384x_setreg __hfa384x_setreg
+#define hfa384x_getreg_noswap __hfa384x_getreg_noswap
+#define hfa384x_setreg_noswap __hfa384x_setreg_noswap
+#endif
+
+/*----------------------------------------------------------------
+* hfa384x_getreg
+*
+* Retrieve the value of one of the MAC registers.  Done here
+* because different PRISM2 MAC parts use different buses and such.
+* NOTE: This function returns the value in HOST ORDER!!!!!!
+*
+* Arguments:
+*       hw         MAC part structure
+*       reg        Register identifier (offset for I/O based i/f)
+*
+* Returns:
+*       Value from the register in HOST ORDER!!!!
+----------------------------------------------------------------*/
+static inline UINT16
+__hfa384x_getreg(hfa384x_t *hw, UINT reg)
+{
+/*     printk(KERN_DEBUG "Reading from 0x%0x\n", hw->membase + reg); */
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+       return wlan_inw_le16_to_cpu(hw->iobase+reg);
+#elif (WLAN_HOSTIF == WLAN_PCI)
+       return __le16_to_cpu(readw(hw->membase + reg));
+#endif
+}
+
+/*----------------------------------------------------------------
+* hfa384x_setreg
+*
+* Set the value of one of the MAC registers.  Done here
+* because different PRISM2 MAC parts use different buses and such.
+* NOTE: This function assumes the value is in HOST ORDER!!!!!!
+*
+* Arguments:
+*       hw     MAC part structure
+*      val     Value, in HOST ORDER!!, to put in the register
+*       reg    Register identifier (offset for I/O based i/f)
+*
+* Returns:
+*       Nothing
+----------------------------------------------------------------*/
+static inline void
+__hfa384x_setreg(hfa384x_t *hw, UINT16 val, UINT reg)
+{
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+       wlan_outw_cpu_to_le16( val, hw->iobase + reg);
+       return;
+#elif (WLAN_HOSTIF == WLAN_PCI)
+       writew(__cpu_to_le16(val), hw->membase + reg);
+       return;
+#endif
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_getreg_noswap
+*
+* Retrieve the value of one of the MAC registers.  Done here
+* because different PRISM2 MAC parts use different buses and such.
+*
+* Arguments:
+*       hw         MAC part structure
+*       reg        Register identifier (offset for I/O based i/f)
+*
+* Returns:
+*       Value from the register.
+----------------------------------------------------------------*/
+static inline UINT16
+__hfa384x_getreg_noswap(hfa384x_t *hw, UINT reg)
+{
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+       return wlan_inw(hw->iobase+reg);
+#elif (WLAN_HOSTIF == WLAN_PCI)
+       return readw(hw->membase + reg);
+#endif
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_setreg_noswap
+*
+* Set the value of one of the MAC registers.  Done here
+* because different PRISM2 MAC parts use different buses and such.
+*
+* Arguments:
+*       hw     MAC part structure
+*      val     Value to put in the register
+*       reg    Register identifier (offset for I/O based i/f)
+*
+* Returns:
+*       Nothing
+----------------------------------------------------------------*/
+static inline void
+__hfa384x_setreg_noswap(hfa384x_t *hw, UINT16 val, UINT reg)
+{
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+       wlan_outw( val, hw->iobase + reg);
+       return;
+#elif (WLAN_HOSTIF == WLAN_PCI)
+       writew(val, hw->membase + reg);
+       return;
+#endif
+}
+
+
+static inline void hfa384x_events_all(hfa384x_t *hw)
+{
+       hfa384x_setreg(hw,
+                      HFA384x_INT_NORMAL
+#ifdef CMD_IRQ
+                      | HFA384x_INTEN_CMD_SET(1)
+#endif
+                      ,
+                      HFA384x_INTEN);
+
+}
+
+static inline void hfa384x_events_nobap(hfa384x_t *hw)
+{
+       hfa384x_setreg(hw,
+                       (HFA384x_INT_NORMAL & ~HFA384x_INT_BAP_OP)
+#ifdef CMD_IRQ
+                      | HFA384x_INTEN_CMD_SET(1)
+#endif
+                      ,
+                      HFA384x_INTEN);
+
+}
+
+#endif /* WLAN_HOSTIF != WLAN_USB */
+#endif /* __KERNEL__ */
+
+#endif  /* _HFA384x_H */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
new file mode 100644 (file)
index 0000000..db0c502
--- /dev/null
@@ -0,0 +1,5027 @@
+/* src/prism2/driver/hfa384x_usb.c
+*
+* Functions that talk to the USB variantof the Intersil hfa384x MAC
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file implements functions that correspond to the prism2/hfa384x
+* 802.11 MAC hardware and firmware host interface.
+*
+* The functions can be considered to represent several levels of
+* abstraction.  The lowest level functions are simply C-callable wrappers
+* around the register accesses.  The next higher level represents C-callable
+* prism2 API functions that match the Intersil documentation as closely
+* as is reasonable.  The next higher layer implements common sequences
+* of invokations of the API layer (e.g. write to bap, followed by cmd).
+*
+* Common sequences:
+* hfa384x_drvr_xxx     Highest level abstractions provided by the
+*                      hfa384x code.  They are driver defined wrappers
+*                      for common sequences.  These functions generally
+*                      use the services of the lower levels.
+*
+* hfa384x_drvr_xxxconfig  An example of the drvr level abstraction. These
+*                      functions are wrappers for the RID get/set
+*                      sequence. They  call copy_[to|from]_bap() and
+*                      cmd_access().   These functions operate on the
+*                      RIDs and buffers without validation.  The caller
+*                      is responsible for that.
+*
+* API wrapper functions:
+* hfa384x_cmd_xxx      functions that provide access to the f/w commands.
+*                      The function arguments correspond to each command
+*                      argument, even command arguments that get packed
+*                      into single registers.  These functions _just_
+*                      issue the command by setting the cmd/parm regs
+*                      & reading the status/resp regs.  Additional
+*                      activities required to fully use a command
+*                      (read/write from/to bap, get/set int status etc.)
+*                      are implemented separately.  Think of these as
+*                      C-callable prism2 commands.
+*
+* Lowest Layer Functions:
+* hfa384x_docmd_xxx    These functions implement the sequence required
+*                      to issue any prism2 command.  Primarily used by the
+*                      hfa384x_cmd_xxx functions.
+*
+* hfa384x_bap_xxx      BAP read/write access functions.
+*                      Note: we usually use BAP0 for non-interrupt context
+*                       and BAP1 for interrupt context.
+*
+* hfa384x_dl_xxx       download related functions.
+*
+* Driver State Issues:
+* Note that there are two pairs of functions that manage the
+* 'initialized' and 'running' states of the hw/MAC combo.  The four
+* functions are create(), destroy(), start(), and stop().  create()
+* sets up the data structures required to support the hfa384x_*
+* functions and destroy() cleans them up.  The start() function gets
+* the actual hardware running and enables the interrupts.  The stop()
+* function shuts the hardware down.  The sequence should be:
+* create()
+* start()
+*  .
+*  .  Do interesting things w/ the hardware
+*  .
+* stop()
+* destroy()
+*
+* Note that destroy() can be called without calling stop() first.
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+#define WLAN_DBVAR     prism2_debug
+
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <asm/bitops.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+
+#include "wlan_compat.h"
+
+#if (WLAN_HOSTIF != WLAN_USB)
+#error "This file is specific to USB"
+#endif
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+static int
+wait_for_completion_interruptible(struct completion *x)
+{
+  int ret = 0;
+
+  might_sleep();
+
+  spin_lock_irq(&x->wait.lock);
+  if (!x->done) {
+    DECLARE_WAITQUEUE(wait, current);
+
+    wait.flags |= WQ_FLAG_EXCLUSIVE;
+    __add_wait_queue_tail(&x->wait, &wait);
+    do {
+      if (signal_pending(current)) {
+        ret = -ERESTARTSYS;
+        __remove_wait_queue(&x->wait, &wait);
+        goto out;
+      }
+      __set_current_state(TASK_INTERRUPTIBLE);
+      spin_unlock_irq(&x->wait.lock);
+      schedule();
+      spin_lock_irq(&x->wait.lock);
+    } while (!x->done);
+    __remove_wait_queue(&x->wait, &wait);
+  }
+  x->done--;
+out:
+  spin_unlock_irq(&x->wait.lock);
+
+  return ret;
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
+static void
+usb_init_urb(struct urb *urb)
+{
+       memset(urb, 0, sizeof(*urb));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* tune me! */
+       urb->count = (atomic_t)ATOMIC_INIT(1);
+#endif
+       spin_lock_init(&urb->lock);
+}
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* tune me! */
+#  define SUBMIT_URB(u,f)  usb_submit_urb(u,f)
+#else
+#  define SUBMIT_URB(u,f)  usb_submit_urb(u)
+#endif
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211req.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+enum cmd_mode
+{
+  DOWAIT = 0,
+  DOASYNC
+};
+typedef enum cmd_mode CMD_MODE;
+
+#define THROTTLE_JIFFIES       (HZ/8)
+
+/*================================================================*/
+/* Local Macros */
+
+#define ROUNDUP64(a) (((a)+63)&~63)
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+extern int prism2_debug;
+
+/*================================================================*/
+/* Local Function Declarations */
+
+#ifdef DEBUG_USB
+static void
+dbprint_urb(struct urb* urb);
+#endif
+
+static void
+hfa384x_int_rxmonitor(
+       wlandevice_t *wlandev,
+       hfa384x_usb_rxfrm_t *rxfrm);
+
+static void
+hfa384x_usb_defer(struct work_struct *data);
+
+static int
+submit_rx_urb(hfa384x_t *hw, gfp_t flags);
+
+static int
+submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags);
+
+/*---------------------------------------------------*/
+/* Callbacks */
+#ifdef URB_ONLY_CALLBACK
+static void
+hfa384x_usbout_callback(struct urb *urb);
+static void
+hfa384x_ctlxout_callback(struct urb *urb);
+static void
+hfa384x_usbin_callback(struct urb *urb);
+#else
+static void
+hfa384x_usbout_callback(struct urb *urb, struct pt_regs *regs);
+static void
+hfa384x_ctlxout_callback(struct urb *urb, struct pt_regs *regs);
+static void
+hfa384x_usbin_callback(struct urb *urb, struct pt_regs *regs);
+#endif
+
+static void
+hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
+
+static void
+hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+
+static void
+hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
+
+static void
+hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout);
+
+static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
+                              int urb_status);
+
+/*---------------------------------------------------*/
+/* Functions to support the prism2 usb command queue */
+
+static void
+hfa384x_usbctlxq_run(hfa384x_t *hw);
+
+static void
+hfa384x_usbctlx_reqtimerfn(unsigned long data);
+
+static void
+hfa384x_usbctlx_resptimerfn(unsigned long data);
+
+static void
+hfa384x_usb_throttlefn(unsigned long data);
+
+static void
+hfa384x_usbctlx_completion_task(unsigned long data);
+
+static void
+hfa384x_usbctlx_reaper_task(unsigned long data);
+
+static int
+hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+
+static void
+unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+
+struct usbctlx_completor
+{
+       int (*complete)(struct usbctlx_completor*);
+};
+typedef struct usbctlx_completor usbctlx_completor_t;
+
+static int
+hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
+                              hfa384x_usbctlx_t *ctlx,
+                              usbctlx_completor_t *completor);
+
+static int
+unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+
+static void
+hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
+
+static void
+hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
+
+static int
+usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
+                   hfa384x_cmdresult_t *result);
+
+static void
+usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
+                       hfa384x_rridresult_t *result);
+
+/*---------------------------------------------------*/
+/* Low level req/resp CTLX formatters and submitters */
+static int
+hfa384x_docmd(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       hfa384x_metacmd_t *cmd,
+       ctlx_cmdcb_t cmdcb,
+       ctlx_usercb_t usercb,
+       void    *usercb_data);
+
+static int
+hfa384x_dorrid(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       UINT16  rid,
+       void    *riddata,
+       UINT    riddatalen,
+       ctlx_cmdcb_t cmdcb,
+       ctlx_usercb_t usercb,
+       void    *usercb_data);
+
+static int
+hfa384x_dowrid(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       UINT16  rid,
+       void    *riddata,
+       UINT    riddatalen,
+       ctlx_cmdcb_t cmdcb,
+       ctlx_usercb_t usercb,
+       void    *usercb_data);
+
+static int
+hfa384x_dormem(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       UINT16  page,
+       UINT16  offset,
+       void    *data,
+       UINT    len,
+       ctlx_cmdcb_t cmdcb,
+       ctlx_usercb_t usercb,
+       void    *usercb_data);
+
+static int
+hfa384x_dowmem(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       UINT16  page,
+       UINT16  offset,
+       void    *data,
+       UINT    len,
+       ctlx_cmdcb_t cmdcb,
+       ctlx_usercb_t usercb,
+       void    *usercb_data);
+
+static int
+hfa384x_isgood_pdrcode(UINT16 pdrcode);
+
+/*================================================================*/
+/* Function Definitions */
+static inline const char* ctlxstr(CTLX_STATE s)
+{
+       static const char* ctlx_str[] = {
+               "Initial state",
+               "Complete",
+               "Request failed",
+               "Request pending",
+               "Request packet submitted",
+               "Request packet completed",
+               "Response packet completed"
+       };
+
+       return ctlx_str[s];
+};
+
+
+static inline hfa384x_usbctlx_t*
+get_active_ctlx(hfa384x_t *hw)
+{
+       return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list);
+}
+
+
+#ifdef DEBUG_USB
+void
+dbprint_urb(struct urb* urb)
+{
+       WLAN_LOG_DEBUG(3,"urb->pipe=0x%08x\n", urb->pipe);
+       WLAN_LOG_DEBUG(3,"urb->status=0x%08x\n", urb->status);
+       WLAN_LOG_DEBUG(3,"urb->transfer_flags=0x%08x\n", urb->transfer_flags);
+       WLAN_LOG_DEBUG(3,"urb->transfer_buffer=0x%08x\n", (UINT)urb->transfer_buffer);
+       WLAN_LOG_DEBUG(3,"urb->transfer_buffer_length=0x%08x\n", urb->transfer_buffer_length);
+       WLAN_LOG_DEBUG(3,"urb->actual_length=0x%08x\n", urb->actual_length);
+       WLAN_LOG_DEBUG(3,"urb->bandwidth=0x%08x\n", urb->bandwidth);
+       WLAN_LOG_DEBUG(3,"urb->setup_packet(ctl)=0x%08x\n", (UINT)urb->setup_packet);
+       WLAN_LOG_DEBUG(3,"urb->start_frame(iso/irq)=0x%08x\n", urb->start_frame);
+       WLAN_LOG_DEBUG(3,"urb->interval(irq)=0x%08x\n", urb->interval);
+       WLAN_LOG_DEBUG(3,"urb->error_count(iso)=0x%08x\n", urb->error_count);
+       WLAN_LOG_DEBUG(3,"urb->timeout=0x%08x\n", urb->timeout);
+       WLAN_LOG_DEBUG(3,"urb->context=0x%08x\n", (UINT)urb->context);
+       WLAN_LOG_DEBUG(3,"urb->complete=0x%08x\n", (UINT)urb->complete);
+}
+#endif
+
+
+/*----------------------------------------------------------------
+* submit_rx_urb
+*
+* Listen for input data on the BULK-IN pipe. If the pipe has
+* stalled then schedule it to be reset.
+*
+* Arguments:
+*      hw              device struct
+*      memflags        memory allocation flags
+*
+* Returns:
+*      error code from submission
+*
+* Call context:
+*      Any
+----------------------------------------------------------------*/
+static int
+submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
+{
+       struct sk_buff *skb;
+       int result;
+
+       DBFENTER;
+
+       skb = dev_alloc_skb(sizeof(hfa384x_usbin_t));
+       if (skb == NULL) {
+               result = -ENOMEM;
+               goto done;
+       }
+
+       /* Post the IN urb */
+       usb_fill_bulk_urb(&hw->rx_urb, hw->usb,
+                     hw->endp_in,
+                     skb->data, sizeof(hfa384x_usbin_t),
+                     hfa384x_usbin_callback, hw->wlandev);
+
+       hw->rx_urb_skb = skb;
+
+       result = -ENOLINK;
+       if ( !hw->wlandev->hwremoved && !test_bit(WORK_RX_HALT, &hw->usb_flags)) {
+               result = SUBMIT_URB(&hw->rx_urb, memflags);
+
+               /* Check whether we need to reset the RX pipe */
+               if (result == -EPIPE) {
+                       WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n",
+                                        hw->wlandev->netdev->name);
+                       if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) )
+                               schedule_work(&hw->usb_work);
+               }
+       }
+
+       /* Don't leak memory if anything should go wrong */
+       if (result != 0) {
+               dev_kfree_skb(skb);
+               hw->rx_urb_skb = NULL;
+       }
+
+ done:
+
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* submit_tx_urb
+*
+* Prepares and submits the URB of transmitted data. If the
+* submission fails then it will schedule the output pipe to
+* be reset.
+*
+* Arguments:
+*      hw              device struct
+*      tx_urb          URB of data for tranmission
+*      memflags        memory allocation flags
+*
+* Returns:
+*      error code from submission
+*
+* Call context:
+*      Any
+----------------------------------------------------------------*/
+static int
+submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
+{
+       struct net_device *netdev = hw->wlandev->netdev;
+       int result;
+
+       DBFENTER;
+
+       result = -ENOLINK;
+       if ( netif_running(netdev) ) {
+
+               if ( !hw->wlandev->hwremoved && !test_bit(WORK_TX_HALT, &hw->usb_flags) ) {
+                       result = SUBMIT_URB(tx_urb, memflags);
+
+                       /* Test whether we need to reset the TX pipe */
+                       if (result == -EPIPE) {
+                               WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
+                                                netdev->name);
+                               set_bit(WORK_TX_HALT, &hw->usb_flags);
+                               schedule_work(&hw->usb_work);
+                       } else if (result == 0) {
+                               netif_stop_queue(netdev);
+                       }
+               }
+       }
+
+       DBFEXIT;
+
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa394x_usb_defer
+*
+* There are some things that the USB stack cannot do while
+* in interrupt context, so we arrange this function to run
+* in process context.
+*
+* Arguments:
+*      hw      device structure
+*
+* Returns:
+*      nothing
+*
+* Call context:
+*      process (by design)
+----------------------------------------------------------------*/
+static void
+hfa384x_usb_defer(struct work_struct *data)
+{
+       hfa384x_t *hw = container_of(data, struct hfa384x, usb_work);
+       struct net_device *netdev = hw->wlandev->netdev;
+
+       DBFENTER;
+
+       /* Don't bother trying to reset anything if the plug
+        * has been pulled ...
+        */
+       if ( hw->wlandev->hwremoved ) {
+               DBFEXIT;
+               return;
+       }
+
+       /* Reception has stopped: try to reset the input pipe */
+       if (test_bit(WORK_RX_HALT, &hw->usb_flags)) {
+               int ret;
+
+               usb_kill_urb(&hw->rx_urb);  /* Cannot be holding spinlock! */
+
+               ret = usb_clear_halt(hw->usb, hw->endp_in);
+               if (ret != 0) {
+                       printk(KERN_ERR
+                              "Failed to clear rx pipe for %s: err=%d\n",
+                              netdev->name, ret);
+               } else {
+                       printk(KERN_INFO "%s rx pipe reset complete.\n",
+                                        netdev->name);
+                       clear_bit(WORK_RX_HALT, &hw->usb_flags);
+                       set_bit(WORK_RX_RESUME, &hw->usb_flags);
+               }
+       }
+
+       /* Resume receiving data back from the device. */
+       if ( test_bit(WORK_RX_RESUME, &hw->usb_flags) ) {
+               int ret;
+
+               ret = submit_rx_urb(hw, GFP_KERNEL);
+               if (ret != 0) {
+                       printk(KERN_ERR
+                              "Failed to resume %s rx pipe.\n", netdev->name);
+               } else {
+                       clear_bit(WORK_RX_RESUME, &hw->usb_flags);
+               }
+       }
+
+       /* Transmission has stopped: try to reset the output pipe */
+       if (test_bit(WORK_TX_HALT, &hw->usb_flags)) {
+               int ret;
+
+               usb_kill_urb(&hw->tx_urb);
+               ret = usb_clear_halt(hw->usb, hw->endp_out);
+               if (ret != 0) {
+                       printk(KERN_ERR
+                              "Failed to clear tx pipe for %s: err=%d\n",
+                              netdev->name, ret);
+               } else {
+                       printk(KERN_INFO "%s tx pipe reset complete.\n",
+                                        netdev->name);
+                       clear_bit(WORK_TX_HALT, &hw->usb_flags);
+                       set_bit(WORK_TX_RESUME, &hw->usb_flags);
+
+                       /* Stopping the BULK-OUT pipe also blocked
+                        * us from sending any more CTLX URBs, so
+                        * we need to re-run our queue ...
+                        */
+                       hfa384x_usbctlxq_run(hw);
+               }
+       }
+
+       /* Resume transmitting. */
+       if ( test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags) ) {
+               p80211netdev_wake_queue(hw->wlandev);
+       }
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_create
+*
+* Sets up the hfa384x_t data structure for use.  Note this
+* does _not_ intialize the actual hardware, just the data structures
+* we use to keep track of its state.
+*
+* Arguments:
+*      hw              device structure
+*      irq             device irq number
+*      iobase          i/o base address for register access
+*      membase         memory base address for register access
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+void
+hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
+{
+       DBFENTER;
+
+       memset(hw, 0, sizeof(hfa384x_t));
+       hw->usb = usb;
+
+       /* set up the endpoints */
+       hw->endp_in = usb_rcvbulkpipe(usb, 1);
+       hw->endp_out = usb_sndbulkpipe(usb, 2);
+
+       /* Set up the waitq */
+       init_waitqueue_head(&hw->cmdq);
+
+       /* Initialize the command queue */
+       spin_lock_init(&hw->ctlxq.lock);
+       INIT_LIST_HEAD(&hw->ctlxq.pending);
+       INIT_LIST_HEAD(&hw->ctlxq.active);
+       INIT_LIST_HEAD(&hw->ctlxq.completing);
+       INIT_LIST_HEAD(&hw->ctlxq.reapable);
+
+       /* Initialize the authentication queue */
+       skb_queue_head_init(&hw->authq);
+
+       tasklet_init(&hw->reaper_bh,
+                    hfa384x_usbctlx_reaper_task,
+                    (unsigned long)hw);
+       tasklet_init(&hw->completion_bh,
+                    hfa384x_usbctlx_completion_task,
+                    (unsigned long)hw);
+       INIT_WORK2(&hw->link_bh, prism2sta_processing_defer);
+       INIT_WORK2(&hw->usb_work, hfa384x_usb_defer);
+
+       init_timer(&hw->throttle);
+       hw->throttle.function = hfa384x_usb_throttlefn;
+       hw->throttle.data = (unsigned long)hw;
+
+       init_timer(&hw->resptimer);
+       hw->resptimer.function = hfa384x_usbctlx_resptimerfn;
+       hw->resptimer.data = (unsigned long)hw;
+
+       init_timer(&hw->reqtimer);
+       hw->reqtimer.function = hfa384x_usbctlx_reqtimerfn;
+       hw->reqtimer.data = (unsigned long)hw;
+
+       usb_init_urb(&hw->rx_urb);
+       usb_init_urb(&hw->tx_urb);
+       usb_init_urb(&hw->ctlx_urb);
+
+       hw->link_status = HFA384x_LINK_NOTCONNECTED;
+       hw->state = HFA384x_STATE_INIT;
+
+        INIT_WORK2(&hw->commsqual_bh, prism2sta_commsqual_defer);
+       init_timer(&hw->commsqual_timer);
+       hw->commsqual_timer.data = (unsigned long) hw;
+       hw->commsqual_timer.function = prism2sta_commsqual_timer;
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_destroy
+*
+* Partner to hfa384x_create().  This function cleans up the hw
+* structure so that it can be freed by the caller using a simple
+* kfree.  Currently, this function is just a placeholder.  If, at some
+* point in the future, an hw in the 'shutdown' state requires a 'deep'
+* kfree, this is where it should be done.  Note that if this function
+* is called on a _running_ hw structure, the drvr_stop() function is
+* called.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      nothing, this function is not allowed to fail.
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+void
+hfa384x_destroy( hfa384x_t *hw)
+{
+       struct sk_buff *skb;
+
+       DBFENTER;
+
+       if ( hw->state == HFA384x_STATE_RUNNING ) {
+               hfa384x_drvr_stop(hw);
+       }
+       hw->state = HFA384x_STATE_PREINIT;
+
+       if (hw->scanresults) {
+               kfree(hw->scanresults);
+               hw->scanresults = NULL;
+       }
+
+       /* Now to clean out the auth queue */
+        while ( (skb = skb_dequeue(&hw->authq)) ) {
+                dev_kfree_skb(skb);
+        }
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+ */
+static hfa384x_usbctlx_t* usbctlx_alloc(void)
+{
+       hfa384x_usbctlx_t *ctlx;
+
+       ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+       if (ctlx != NULL)
+       {
+               memset(ctlx, 0, sizeof(*ctlx));
+               init_completion(&ctlx->done);
+       }
+
+       return ctlx;
+}
+
+
+/*----------------------------------------------------------------
+ *
+----------------------------------------------------------------*/
+static int
+usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
+                   hfa384x_cmdresult_t *result)
+{
+       DBFENTER;
+
+       result->status = hfa384x2host_16(cmdresp->status);
+       result->resp0 = hfa384x2host_16(cmdresp->resp0);
+       result->resp1 = hfa384x2host_16(cmdresp->resp1);
+       result->resp2 = hfa384x2host_16(cmdresp->resp2);
+
+       WLAN_LOG_DEBUG(4, "cmdresult:status=0x%04x "
+                         "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n",
+                       result->status,
+                       result->resp0,
+                       result->resp1,
+                       result->resp2);
+
+       DBFEXIT;
+       return (result->status & HFA384x_STATUS_RESULT);
+}
+
+static void
+usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
+                       hfa384x_rridresult_t *result)
+{
+       DBFENTER;
+
+       result->rid = hfa384x2host_16(rridresp->rid);
+       result->riddata = rridresp->data;
+       result->riddata_len = ((hfa384x2host_16(rridresp->frmlen) - 1) * 2);
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* Completor object:
+* This completor must be passed to hfa384x_usbctlx_complete_sync()
+* when processing a CTLX that returns a hfa384x_cmdresult_t structure.
+----------------------------------------------------------------*/
+struct usbctlx_cmd_completor
+{
+       usbctlx_completor_t     head;
+
+       const hfa384x_usb_cmdresp_t     *cmdresp;
+       hfa384x_cmdresult_t     *result;
+};
+typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t;
+
+static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head)
+{
+       usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t*)head;
+       return usbctlx_get_status(complete->cmdresp, complete->result);
+}
+
+static inline usbctlx_completor_t*
+init_cmd_completor(usbctlx_cmd_completor_t *completor,
+                   const hfa384x_usb_cmdresp_t *cmdresp,
+                   hfa384x_cmdresult_t *result)
+{
+       completor->head.complete = usbctlx_cmd_completor_fn;
+       completor->cmdresp = cmdresp;
+       completor->result = result;
+       return &(completor->head);
+}
+
+/*----------------------------------------------------------------
+* Completor object:
+* This completor must be passed to hfa384x_usbctlx_complete_sync()
+* when processing a CTLX that reads a RID.
+----------------------------------------------------------------*/
+struct usbctlx_rrid_completor
+{
+       usbctlx_completor_t     head;
+
+       const hfa384x_usb_rridresp_t    *rridresp;
+       void                    *riddata;
+       UINT                    riddatalen;
+};
+typedef struct usbctlx_rrid_completor usbctlx_rrid_completor_t;
+
+static int usbctlx_rrid_completor_fn(usbctlx_completor_t *head)
+{
+       usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t*)head;
+       hfa384x_rridresult_t rridresult;
+
+       usbctlx_get_rridresult(complete->rridresp, &rridresult);
+
+       /* Validate the length, note body len calculation in bytes */
+       if ( rridresult.riddata_len != complete->riddatalen ) {
+               WLAN_LOG_WARNING(
+                       "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
+                       rridresult.rid,
+                       complete->riddatalen,
+                       rridresult.riddata_len);
+               return -ENODATA;
+       }
+
+       memcpy(complete->riddata,
+              rridresult.riddata,
+              complete->riddatalen);
+       return 0;
+}
+
+static inline usbctlx_completor_t*
+init_rrid_completor(usbctlx_rrid_completor_t *completor,
+                    const hfa384x_usb_rridresp_t *rridresp,
+                    void *riddata,
+                    UINT riddatalen)
+{
+       completor->head.complete = usbctlx_rrid_completor_fn;
+       completor->rridresp = rridresp;
+       completor->riddata = riddata;
+       completor->riddatalen = riddatalen;
+       return &(completor->head);
+}
+
+/*----------------------------------------------------------------
+* Completor object:
+* Interprets the results of a synchronous RID-write
+----------------------------------------------------------------*/
+typedef usbctlx_cmd_completor_t usbctlx_wrid_completor_t;
+#define init_wrid_completor  init_cmd_completor
+
+/*----------------------------------------------------------------
+* Completor object:
+* Interprets the results of a synchronous memory-write
+----------------------------------------------------------------*/
+typedef usbctlx_cmd_completor_t usbctlx_wmem_completor_t;
+#define init_wmem_completor  init_cmd_completor
+
+/*----------------------------------------------------------------
+* Completor object:
+* Interprets the results of a synchronous memory-read
+----------------------------------------------------------------*/
+struct usbctlx_rmem_completor
+{
+        usbctlx_completor_t           head;
+
+        const hfa384x_usb_rmemresp_t  *rmemresp;
+        void                          *data;
+        UINT                          len;
+};
+typedef struct usbctlx_rmem_completor usbctlx_rmem_completor_t;
+
+static int usbctlx_rmem_completor_fn(usbctlx_completor_t *head)
+{
+       usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t*)head;
+
+       WLAN_LOG_DEBUG(4,"rmemresp:len=%d\n", complete->rmemresp->frmlen);
+       memcpy(complete->data, complete->rmemresp->data, complete->len);
+       return 0;
+}
+
+static inline usbctlx_completor_t*
+init_rmem_completor(usbctlx_rmem_completor_t *completor,
+                    hfa384x_usb_rmemresp_t *rmemresp,
+                    void *data,
+                    UINT len)
+{
+       completor->head.complete = usbctlx_rmem_completor_fn;
+       completor->rmemresp = rmemresp;
+       completor->data = data;
+       completor->len = len;
+       return &(completor->head);
+}
+
+/*----------------------------------------------------------------
+* hfa384x_cb_status
+*
+* Ctlx_complete handler for async CMD type control exchanges.
+* mark the hw struct as such.
+*
+* Note: If the handling is changed here, it should probably be
+*       changed in docmd as well.
+*
+* Arguments:
+*      hw              hw struct
+*      ctlx            completed CTLX
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+{
+       DBFENTER;
+
+       if ( ctlx->usercb != NULL ) {
+               hfa384x_cmdresult_t cmdresult;
+
+               if (ctlx->state != CTLX_COMPLETE) {
+                       memset(&cmdresult, 0, sizeof(cmdresult));
+                       cmdresult.status = HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR);
+               } else {
+                       usbctlx_get_status(&ctlx->inbuf.cmdresp, &cmdresult);
+               }
+
+               ctlx->usercb(hw, &cmdresult, ctlx->usercb_data);
+       }
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cb_rrid
+*
+* CTLX completion handler for async RRID type control exchanges.
+*
+* Note: If the handling is changed here, it should probably be
+*       changed in dorrid as well.
+*
+* Arguments:
+*      hw              hw struct
+*      ctlx            completed CTLX
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+{
+       DBFENTER;
+
+       if ( ctlx->usercb != NULL ) {
+               hfa384x_rridresult_t rridresult;
+
+               if (ctlx->state != CTLX_COMPLETE) {
+                       memset(&rridresult, 0, sizeof(rridresult));
+                       rridresult.rid = hfa384x2host_16(ctlx->outbuf.rridreq.rid);
+               } else {
+                       usbctlx_get_rridresult(&ctlx->inbuf.rridresp, &rridresult);
+               }
+
+               ctlx->usercb(hw, &rridresult, ctlx->usercb_data);
+       }
+
+       DBFEXIT;
+}
+
+static inline int
+hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+       return hfa384x_docmd(hw, DOWAIT, cmd, NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_docmd_async(hfa384x_t *hw,
+                    hfa384x_metacmd_t *cmd,
+                    ctlx_cmdcb_t cmdcb,
+                    ctlx_usercb_t usercb,
+                    void *usercb_data)
+{
+       return hfa384x_docmd(hw, DOASYNC, cmd,
+                               cmdcb, usercb, usercb_data);
+}
+
+static inline int
+hfa384x_dorrid_wait(hfa384x_t *hw, UINT16 rid, void *riddata, UINT riddatalen)
+{
+       return hfa384x_dorrid(hw, DOWAIT,
+                             rid, riddata, riddatalen,
+                             NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_dorrid_async(hfa384x_t *hw,
+                     UINT16 rid, void *riddata, UINT riddatalen,
+                     ctlx_cmdcb_t cmdcb,
+                     ctlx_usercb_t usercb,
+                     void *usercb_data)
+{
+       return hfa384x_dorrid(hw, DOASYNC,
+                             rid, riddata, riddatalen,
+                             cmdcb, usercb, usercb_data);
+}
+
+static inline int
+hfa384x_dowrid_wait(hfa384x_t *hw, UINT16 rid, void *riddata, UINT riddatalen)
+{
+       return hfa384x_dowrid(hw, DOWAIT,
+                             rid, riddata, riddatalen,
+                             NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_dowrid_async(hfa384x_t *hw,
+                     UINT16 rid, void *riddata, UINT riddatalen,
+                     ctlx_cmdcb_t cmdcb,
+                     ctlx_usercb_t usercb,
+                     void *usercb_data)
+{
+       return hfa384x_dowrid(hw, DOASYNC,
+                             rid, riddata, riddatalen,
+                             cmdcb, usercb, usercb_data);
+}
+
+static inline int
+hfa384x_dormem_wait(hfa384x_t *hw,
+                    UINT16 page, UINT16 offset, void *data, UINT len)
+{
+       return hfa384x_dormem(hw, DOWAIT,
+                             page, offset, data, len,
+                             NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_dormem_async(hfa384x_t *hw,
+                     UINT16 page, UINT16 offset, void *data, UINT len,
+                     ctlx_cmdcb_t cmdcb,
+                     ctlx_usercb_t usercb,
+                     void *usercb_data)
+{
+       return hfa384x_dormem(hw, DOASYNC,
+                             page, offset, data, len,
+                             cmdcb, usercb, usercb_data);
+}
+
+static inline int
+hfa384x_dowmem_wait(
+        hfa384x_t *hw,
+        UINT16  page,
+        UINT16  offset,
+        void    *data,
+        UINT    len)
+{
+       return hfa384x_dowmem(hw, DOWAIT,
+                                  page, offset, data, len,
+                                 NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_dowmem_async(
+        hfa384x_t *hw,
+        UINT16  page,
+        UINT16  offset,
+        void    *data,
+        UINT    len,
+        ctlx_cmdcb_t cmdcb,
+        ctlx_usercb_t usercb,
+        void    *usercb_data)
+{
+       return hfa384x_dowmem(hw, DOASYNC,
+                                  page, offset, data, len,
+                                 cmdcb, usercb, usercb_data);
+}
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_initialize
+*
+* Issues the initialize command and sets the hw->state based
+* on the result.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int
+hfa384x_cmd_initialize(hfa384x_t *hw)
+{
+       int     result = 0;
+       int     i;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+
+       cmd.cmd = HFA384x_CMDCODE_INIT;
+       cmd.parm0 = 0;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       result = hfa384x_docmd_wait(hw, &cmd);
+
+
+       WLAN_LOG_DEBUG(3,"cmdresp.init: "
+               "status=0x%04x, resp0=0x%04x, "
+               "resp1=0x%04x, resp2=0x%04x\n",
+               cmd.result.status,
+               cmd.result.resp0,
+               cmd.result.resp1,
+               cmd.result.resp2);
+       if ( result == 0 ) {
+               for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+                       hw->port_enabled[i] = 0;
+               }
+       }
+
+        hw->link_status = HFA384x_LINK_NOTCONNECTED;
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_disable
+*
+* Issues the disable command to stop communications on one of
+* the MACs 'ports'.
+*
+* Arguments:
+*      hw              device structure
+*      macport         MAC port number (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
+                 HFA384x_CMD_MACPORT_SET(macport);
+       cmd.parm0 = 0;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       result = hfa384x_docmd_wait(hw, &cmd);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_enable
+*
+* Issues the enable command to enable communications on one of
+* the MACs 'ports'.
+*
+* Arguments:
+*      hw              device structure
+*      macport         MAC port number
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
+                 HFA384x_CMD_MACPORT_SET(macport);
+       cmd.parm0 = 0;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       result = hfa384x_docmd_wait(hw, &cmd);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_notify
+*
+* Sends an info frame to the firmware to alter the behavior
+* of the f/w asynch processes.  Can only be called when the MAC
+* is in the enabled state.
+*
+* Arguments:
+*      hw              device structure
+*      reclaim         [0|1] indicates whether the given FID will
+*                      be handed back (via Alloc event) for reuse.
+*                      (host order)
+*      fid             FID of buffer containing the frame that was
+*                      previously copied to MAC memory via the bap.
+*                      (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*      hw->resp0 will contain the FID being used by async notify
+*      process.  If reclaim==0, resp0 will be the same as the fid
+*      argument.  If reclaim==1, resp0 will be the different.
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid,
+                      void *buf, UINT16 len)
+{
+#if 0
+       int     result = 0;
+       UINT16  cmd;
+       DBFENTER;
+       cmd =   HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) |
+               HFA384x_CMD_RECL_SET(reclaim);
+       result = hfa384x_docmd_wait(hw, cmd);
+
+       DBFEXIT;
+       return result;
+#endif
+return 0;
+}
+
+
+#if 0
+/*----------------------------------------------------------------
+* hfa384x_cmd_inquiry
+*
+* Requests an info frame from the firmware.  The info frame will
+* be delivered asynchronously via the Info event.
+*
+* Arguments:
+*      hw              device structure
+*      fid             FID of the info frame requested. (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ);
+       cmd.parm0 = 0;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       result = hfa384x_docmd_wait(hw, &cmd);
+
+       DBFEXIT;
+       return result;
+}
+#endif
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_monitor
+*
+* Enables the 'monitor mode' of the MAC.  Here's the description of
+* monitor mode that I've received thus far:
+*
+*  "The "monitor mode" of operation is that the MAC passes all
+*  frames for which the PLCP checks are correct. All received
+*  MPDUs are passed to the host with MAC Port = 7, with a
+*  receive status of good, FCS error, or undecryptable. Passing
+*  certain MPDUs is a violation of the 802.11 standard, but useful
+*  for a debugging tool."  Normal communication is not possible
+*  while monitor mode is enabled.
+*
+* Arguments:
+*      hw              device structure
+*      enable          a code (0x0b|0x0f) that enables/disables
+*                      monitor mode. (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
+               HFA384x_CMD_AINFO_SET(enable);
+       cmd.parm0 = 0;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       result = hfa384x_docmd_wait(hw, &cmd);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_download
+*
+* Sets the controls for the MAC controller code/data download
+* process.  The arguments set the mode and address associated
+* with a download.  Note that the aux registers should be enabled
+* prior to setting one of the download enable modes.
+*
+* Arguments:
+*      hw              device structure
+*      mode            0 - Disable programming and begin code exec
+*                      1 - Enable volatile mem programming
+*                      2 - Enable non-volatile mem programming
+*                      3 - Program non-volatile section from NV download
+*                          buffer.
+*                      (host order)
+*      lowaddr
+*      highaddr        For mode 1, sets the high & low order bits of
+*                      the "destination address".  This address will be
+*                      the execution start address when download is
+*                      subsequently disabled.
+*                      For mode 2, sets the high & low order bits of
+*                      the destination in NV ram.
+*                      For modes 0 & 3, should be zero. (host order)
+*                      NOTE: these are CMD format.
+*      codelen         Length of the data to write in mode 2,
+*                      zero otherwise. (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr,
+                               UINT16 highaddr, UINT16 codelen)
+{
+       int     result = 0;
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+       WLAN_LOG_DEBUG(5,
+               "mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n",
+               mode, lowaddr, highaddr, codelen);
+
+       cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) |
+                  HFA384x_CMD_PROGMODE_SET(mode));
+
+       cmd.parm0 = lowaddr;
+       cmd.parm1 = highaddr;
+       cmd.parm2 = codelen;
+
+       result = hfa384x_docmd_wait(hw, &cmd);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_from_aux
+*
+* Copies a collection of bytes from the controller memory.  The
+* Auxiliary port MUST be enabled prior to calling this function.
+* We _might_ be in a download state.
+*
+* Arguments:
+*      hw              device structure
+*      cardaddr        address in hfa384x data space to read
+*      auxctl          address space select
+*      buf             ptr to destination host buffer
+*      len             length of data to transfer (in bytes)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      buf contains the data copied
+*
+* Call context:
+*      process
+*      interrupt
+----------------------------------------------------------------*/
+void
+hfa384x_copy_from_aux(
+       hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
+{
+       DBFENTER;
+       WLAN_LOG_ERROR("not used in USB.\n");
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_to_aux
+*
+* Copies a collection of bytes to the controller memory.  The
+* Auxiliary port MUST be enabled prior to calling this function.
+* We _might_ be in a download state.
+*
+* Arguments:
+*      hw              device structure
+*      cardaddr        address in hfa384x data space to read
+*      auxctl          address space select
+*      buf             ptr to destination host buffer
+*      len             length of data to transfer (in bytes)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      Controller memory now contains a copy of buf
+*
+* Call context:
+*      process
+*      interrupt
+----------------------------------------------------------------*/
+void
+hfa384x_copy_to_aux(
+       hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
+{
+       DBFENTER;
+       WLAN_LOG_ERROR("not used in USB.\n");
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_corereset
+*
+* Perform a reset of the hfa38xx MAC core.  We assume that the hw
+* structure is in its "created" state.  That is, it is initialized
+* with proper values.  Note that if a reset is done after the
+* device has been active for awhile, the caller might have to clean
+* up some leftover cruft in the hw structure.
+*
+* Arguments:
+*      hw              device structure
+*      holdtime        how long (in ms) to hold the reset
+*      settletime      how long (in ms) to wait after releasing
+*                      the reset
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
+{
+#if 0
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+       struct usb_device       *parent = hw->usb->parent;
+       int                     i;
+       int                     port = -1;
+#endif
+#endif
+       int                     result = 0;
+
+
+#define P2_USB_RT_PORT         (USB_TYPE_CLASS | USB_RECIP_OTHER)
+#define P2_USB_FEAT_RESET      4
+#define P2_USB_FEAT_C_RESET    20
+
+       DBFENTER;
+
+#if 0
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+       /* Find the hub port */
+       for ( i = 0; i < parent->maxchild; i++) {
+               if (parent->children[i] == hw->usb) {
+                       port = i;
+                       break;
+               }
+       }
+       if (port < 0) return -ENOENT;
+
+       /* Set and clear the reset */
+       usb_control_msg(parent, usb_sndctrlpipe(parent, 0),
+               USB_REQ_SET_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_RESET,
+               port+1, NULL, 0, 1*HZ);
+       wait_ms(holdtime);
+       usb_control_msg(parent, usb_sndctrlpipe(parent, 0),
+               USB_REQ_CLEAR_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_C_RESET,
+               port+1, NULL, 0, 1*HZ);
+       wait_ms(settletime);
+
+       /* Set the device address */
+       result=usb_set_address(hw->usb);
+       if (result < 0) {
+               WLAN_LOG_ERROR("reset_usbdev: Dev not accepting address, "
+                       "result=%d\n", result);
+               clear_bit(hw->usb->devnum, &hw->usb->bus->devmap.devicemap);
+               hw->usb->devnum = -1;
+               goto done;
+       }
+       /* Let the address settle */
+       wait_ms(20);
+
+       /* Assume we're reusing the original descriptor data */
+
+       /* Set the configuration. */
+       WLAN_LOG_DEBUG(3, "Setting Configuration %d\n",
+               hw->usb->config[0].bConfigurationValue);
+       result=usb_set_configuration(hw->usb, hw->usb->config[0].bConfigurationValue);
+       if ( result ) {
+               WLAN_LOG_ERROR("usb_set_configuration() failed, result=%d.\n",
+                               result);
+               goto done;
+       }
+       /* Let the configuration settle */
+       wait_ms(20);
+
+ done:
+#else
+       result=usb_reset_device(hw->usb);
+       if(result<0) {
+               WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result);
+       }
+#endif
+#endif
+
+       result=usb_reset_device(hw->usb);
+       if(result<0) {
+               WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result);
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_complete_sync
+*
+* Waits for a synchronous CTLX object to complete,
+* and then handles the response.
+*
+* Arguments:
+*      hw              device structure
+*      ctlx            CTLX ptr
+*      completor       functor object to decide what to
+*                      do with the CTLX's result.
+*
+* Returns:
+*      0               Success
+*      -ERESTARTSYS    Interrupted by a signal
+*      -EIO            CTLX failed
+*      -ENODEV         Adapter was unplugged
+*      ???             Result from completor
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
+                                        hfa384x_usbctlx_t *ctlx,
+                                        usbctlx_completor_t *completor)
+{
+       unsigned long flags;
+       int result;
+
+       DBFENTER;
+
+       result = wait_for_completion_interruptible(&ctlx->done);
+
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       /*
+        * We can only handle the CTLX if the USB disconnect
+        * function has not run yet ...
+        */
+       cleanup:
+       if ( hw->wlandev->hwremoved )
+       {
+               spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+               result = -ENODEV;
+       }
+       else if ( result != 0 )
+       {
+               int runqueue = 0;
+
+               /*
+                * We were probably interrupted, so delete
+                * this CTLX asynchronously, kill the timers
+                * and the URB, and then start the next
+                * pending CTLX.
+                *
+                * NOTE: We can only delete the timers and
+                *       the URB if this CTLX is active.
+                */
+               if (ctlx == get_active_ctlx(hw))
+               {
+                       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+                       del_singleshot_timer_sync(&hw->reqtimer);
+                       del_singleshot_timer_sync(&hw->resptimer);
+                       hw->req_timer_done = 1;
+                       hw->resp_timer_done = 1;
+                       usb_kill_urb(&hw->ctlx_urb);
+
+                       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+                       runqueue = 1;
+
+                       /*
+                        * This scenario is so unlikely that I'm
+                        * happy with a grubby "goto" solution ...
+                        */
+                       if ( hw->wlandev->hwremoved )
+                               goto cleanup;
+               }
+
+               /*
+                * The completion task will send this CTLX
+                * to the reaper the next time it runs. We
+                * are no longer in a hurry.
+                */
+               ctlx->reapable = 1;
+               ctlx->state = CTLX_REQ_FAILED;
+               list_move_tail(&ctlx->list, &hw->ctlxq.completing);
+
+               spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+               if (runqueue)
+                       hfa384x_usbctlxq_run(hw);
+       } else {
+               if (ctlx->state == CTLX_COMPLETE) {
+                       result = completor->complete(completor);
+               } else {
+                       WLAN_LOG_WARNING("CTLX[%d] error: state(%s)\n",
+                                        hfa384x2host_16(ctlx->outbuf.type),
+                                        ctlxstr(ctlx->state));
+                       result = -EIO;
+               }
+
+               list_del(&ctlx->list);
+               spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+               kfree(ctlx);
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_docmd
+*
+* Constructs a command CTLX and submits it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+*       need to be carried over to hfa384x_cbcmd() since the handling
+*       is virtually identical.
+*
+* Arguments:
+*      hw              device structure
+*      mode            DOWAIT or DOASYNC
+*       cmd             cmd structure.  Includes all arguments and result
+*                       data points.  All in host order. in host order
+*      cmdcb           command-specific callback
+*      usercb          user callback for async calls, NULL for DOWAIT calls
+*      usercb_data     user supplied data pointer for async calls, NULL
+*                      for DOASYNC calls
+*
+* Returns:
+*      0               success
+*      -EIO            CTLX failure
+*      -ERESTARTSYS    Awakened on signal
+*      >0              command indicated error, Status and Resp0-2 are
+*                      in hw structure.
+*
+* Side effects:
+*
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+static int
+hfa384x_docmd(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       hfa384x_metacmd_t *cmd,
+       ctlx_cmdcb_t    cmdcb,
+       ctlx_usercb_t   usercb,
+       void    *usercb_data)
+{
+       int                     result;
+       hfa384x_usbctlx_t       *ctlx;
+
+       DBFENTER;
+       ctlx = usbctlx_alloc();
+       if ( ctlx == NULL ) {
+               result = -ENOMEM;
+               goto done;
+       }
+
+       /* Initialize the command */
+       ctlx->outbuf.cmdreq.type =      host2hfa384x_16(HFA384x_USB_CMDREQ);
+       ctlx->outbuf.cmdreq.cmd =       host2hfa384x_16(cmd->cmd);
+       ctlx->outbuf.cmdreq.parm0 =     host2hfa384x_16(cmd->parm0);
+       ctlx->outbuf.cmdreq.parm1 =     host2hfa384x_16(cmd->parm1);
+       ctlx->outbuf.cmdreq.parm2 =     host2hfa384x_16(cmd->parm2);
+
+       ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq);
+
+       WLAN_LOG_DEBUG(4, "cmdreq: cmd=0x%04x "
+               "parm0=0x%04x parm1=0x%04x parm2=0x%04x\n",
+               cmd->cmd,
+               cmd->parm0,
+               cmd->parm1,
+               cmd->parm2);
+
+       ctlx->reapable = mode;
+       ctlx->cmdcb = cmdcb;
+       ctlx->usercb = usercb;
+       ctlx->usercb_data = usercb_data;
+
+       result = hfa384x_usbctlx_submit(hw, ctlx);
+       if (result != 0) {
+               kfree(ctlx);
+       } else if (mode == DOWAIT) {
+               usbctlx_cmd_completor_t completor;
+
+               result = hfa384x_usbctlx_complete_sync(
+                            hw, ctlx, init_cmd_completor(&completor,
+                                                         &ctlx->inbuf.cmdresp,
+                                                         &cmd->result) );
+       }
+
+done:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_dorrid
+*
+* Constructs a read rid CTLX and issues it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+*       need to be carried over to hfa384x_cbrrid() since the handling
+*       is virtually identical.
+*
+* Arguments:
+*      hw              device structure
+*      mode            DOWAIT or DOASYNC
+*      rid             Read RID number (host order)
+*      riddata         Caller supplied buffer that MAC formatted RID.data
+*                      record will be written to for DOWAIT calls. Should
+*                      be NULL for DOASYNC calls.
+*      riddatalen      Buffer length for DOWAIT calls. Zero for DOASYNC calls.
+*      cmdcb           command callback for async calls, NULL for DOWAIT calls
+*      usercb          user callback for async calls, NULL for DOWAIT calls
+*      usercb_data     user supplied data pointer for async calls, NULL
+*                      for DOWAIT calls
+*
+* Returns:
+*      0               success
+*      -EIO            CTLX failure
+*      -ERESTARTSYS    Awakened on signal
+*      -ENODATA        riddatalen != macdatalen
+*      >0              command indicated error, Status and Resp0-2 are
+*                      in hw structure.
+*
+* Side effects:
+*
+* Call context:
+*      interrupt (DOASYNC)
+*      process (DOWAIT or DOASYNC)
+----------------------------------------------------------------*/
+static int
+hfa384x_dorrid(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       UINT16  rid,
+       void    *riddata,
+       UINT    riddatalen,
+        ctlx_cmdcb_t cmdcb,
+       ctlx_usercb_t usercb,
+       void    *usercb_data)
+{
+       int                     result;
+       hfa384x_usbctlx_t       *ctlx;
+
+       DBFENTER;
+       ctlx = usbctlx_alloc();
+       if ( ctlx == NULL ) {
+               result = -ENOMEM;
+               goto done;
+       }
+
+       /* Initialize the command */
+       ctlx->outbuf.rridreq.type =   host2hfa384x_16(HFA384x_USB_RRIDREQ);
+       ctlx->outbuf.rridreq.frmlen =
+               host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid));
+       ctlx->outbuf.rridreq.rid =    host2hfa384x_16(rid);
+
+       ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq);
+
+       ctlx->reapable = mode;
+       ctlx->cmdcb = cmdcb;
+       ctlx->usercb = usercb;
+       ctlx->usercb_data = usercb_data;
+
+       /* Submit the CTLX */
+       result = hfa384x_usbctlx_submit(hw, ctlx);
+       if (result != 0) {
+               kfree(ctlx);
+       } else if (mode == DOWAIT) {
+               usbctlx_rrid_completor_t completor;
+
+               result = hfa384x_usbctlx_complete_sync(
+                          hw, ctlx, init_rrid_completor(&completor,
+                                                        &ctlx->inbuf.rridresp,
+                                                        riddata,
+                                                        riddatalen) );
+       }
+
+done:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_dowrid
+*
+* Constructs a write rid CTLX and issues it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+*       need to be carried over to hfa384x_cbwrid() since the handling
+*       is virtually identical.
+*
+* Arguments:
+*      hw              device structure
+*      CMD_MODE        DOWAIT or DOASYNC
+*      rid             RID code
+*      riddata         Data portion of RID formatted for MAC
+*      riddatalen      Length of the data portion in bytes
+*       cmdcb           command callback for async calls, NULL for DOWAIT calls
+*      usercb          user callback for async calls, NULL for DOWAIT calls
+*      usercb_data     user supplied data pointer for async calls
+*
+* Returns:
+*      0               success
+*      -ETIMEDOUT      timed out waiting for register ready or
+*                      command completion
+*      >0              command indicated error, Status and Resp0-2 are
+*                      in hw structure.
+*
+* Side effects:
+*
+* Call context:
+*      interrupt (DOASYNC)
+*      process (DOWAIT or DOASYNC)
+----------------------------------------------------------------*/
+static int
+hfa384x_dowrid(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       UINT16  rid,
+       void    *riddata,
+       UINT    riddatalen,
+       ctlx_cmdcb_t cmdcb,
+       ctlx_usercb_t usercb,
+       void    *usercb_data)
+{
+       int                     result;
+       hfa384x_usbctlx_t       *ctlx;
+
+       DBFENTER;
+       ctlx = usbctlx_alloc();
+       if ( ctlx == NULL ) {
+               result = -ENOMEM;
+               goto done;
+       }
+
+       /* Initialize the command */
+       ctlx->outbuf.wridreq.type =   host2hfa384x_16(HFA384x_USB_WRIDREQ);
+       ctlx->outbuf.wridreq.frmlen = host2hfa384x_16(
+                                       (sizeof(ctlx->outbuf.wridreq.rid) +
+                                       riddatalen + 1) / 2);
+       ctlx->outbuf.wridreq.rid =    host2hfa384x_16(rid);
+       memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen);
+
+       ctlx->outbufsize = sizeof(ctlx->outbuf.wridreq.type) +
+                          sizeof(ctlx->outbuf.wridreq.frmlen) +
+                          sizeof(ctlx->outbuf.wridreq.rid) +
+                          riddatalen;
+
+       ctlx->reapable = mode;
+       ctlx->cmdcb = cmdcb;
+       ctlx->usercb = usercb;
+       ctlx->usercb_data = usercb_data;
+
+       /* Submit the CTLX */
+       result = hfa384x_usbctlx_submit(hw, ctlx);
+       if (result != 0) {
+               kfree(ctlx);
+       } else if (mode == DOWAIT) {
+               usbctlx_wrid_completor_t completor;
+               hfa384x_cmdresult_t wridresult;
+
+               result = hfa384x_usbctlx_complete_sync(
+                              hw,
+                              ctlx,
+                              init_wrid_completor(&completor,
+                                                  &ctlx->inbuf.wridresp,
+                                                  &wridresult) );
+       }
+
+done:
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_dormem
+*
+* Constructs a readmem CTLX and issues it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+*       need to be carried over to hfa384x_cbrmem() since the handling
+*       is virtually identical.
+*
+* Arguments:
+*      hw              device structure
+*      mode            DOWAIT or DOASYNC
+*      page            MAC address space page (CMD format)
+*      offset          MAC address space offset
+*      data            Ptr to data buffer to receive read
+*      len             Length of the data to read (max == 2048)
+*      cmdcb           command callback for async calls, NULL for DOWAIT calls
+*      usercb          user callback for async calls, NULL for DOWAIT calls
+*      usercb_data     user supplied data pointer for async calls
+*
+* Returns:
+*      0               success
+*      -ETIMEDOUT      timed out waiting for register ready or
+*                      command completion
+*      >0              command indicated error, Status and Resp0-2 are
+*                      in hw structure.
+*
+* Side effects:
+*
+* Call context:
+*      interrupt (DOASYNC)
+*      process (DOWAIT or DOASYNC)
+----------------------------------------------------------------*/
+static int
+hfa384x_dormem(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       UINT16  page,
+       UINT16  offset,
+       void    *data,
+       UINT    len,
+       ctlx_cmdcb_t cmdcb,
+       ctlx_usercb_t usercb,
+       void    *usercb_data)
+{
+       int                     result;
+       hfa384x_usbctlx_t       *ctlx;
+
+       DBFENTER;
+       ctlx = usbctlx_alloc();
+       if ( ctlx == NULL ) {
+               result = -ENOMEM;
+               goto done;
+       }
+
+       /* Initialize the command */
+       ctlx->outbuf.rmemreq.type =    host2hfa384x_16(HFA384x_USB_RMEMREQ);
+       ctlx->outbuf.rmemreq.frmlen =  host2hfa384x_16(
+                                       sizeof(ctlx->outbuf.rmemreq.offset) +
+                                       sizeof(ctlx->outbuf.rmemreq.page) +
+                                       len);
+       ctlx->outbuf.rmemreq.offset =   host2hfa384x_16(offset);
+       ctlx->outbuf.rmemreq.page =     host2hfa384x_16(page);
+
+       ctlx->outbufsize = sizeof(ctlx->outbuf.rmemreq);
+
+       WLAN_LOG_DEBUG(4,
+               "type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n",
+               ctlx->outbuf.rmemreq.type,
+               ctlx->outbuf.rmemreq.frmlen,
+               ctlx->outbuf.rmemreq.offset,
+               ctlx->outbuf.rmemreq.page);
+
+       WLAN_LOG_DEBUG(4,"pktsize=%zd\n",
+               ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));
+
+       ctlx->reapable = mode;
+       ctlx->cmdcb = cmdcb;
+       ctlx->usercb = usercb;
+       ctlx->usercb_data = usercb_data;
+
+       result = hfa384x_usbctlx_submit(hw, ctlx);
+       if (result != 0) {
+               kfree(ctlx);
+       } else if ( mode == DOWAIT ) {
+                usbctlx_rmem_completor_t completor;
+
+                result = hfa384x_usbctlx_complete_sync(
+                           hw, ctlx, init_rmem_completor(&completor,
+                                                         &ctlx->inbuf.rmemresp,
+                                                         data,
+                                                         len) );
+       }
+
+done:
+       DBFEXIT;
+       return result;
+}
+
+
+
+/*----------------------------------------------------------------
+* hfa384x_dowmem
+*
+* Constructs a writemem CTLX and issues it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+*       need to be carried over to hfa384x_cbwmem() since the handling
+*       is virtually identical.
+*
+* Arguments:
+*      hw              device structure
+*      mode            DOWAIT or DOASYNC
+*      page            MAC address space page (CMD format)
+*      offset          MAC address space offset
+*      data            Ptr to data buffer containing write data
+*      len             Length of the data to read (max == 2048)
+*      cmdcb           command callback for async calls, NULL for DOWAIT calls
+*      usercb          user callback for async calls, NULL for DOWAIT calls
+*      usercb_data     user supplied data pointer for async calls.
+*
+* Returns:
+*      0               success
+*      -ETIMEDOUT      timed out waiting for register ready or
+*                      command completion
+*      >0              command indicated error, Status and Resp0-2 are
+*                      in hw structure.
+*
+* Side effects:
+*
+* Call context:
+*      interrupt (DOWAIT)
+*      process (DOWAIT or DOASYNC)
+----------------------------------------------------------------*/
+static int
+hfa384x_dowmem(
+       hfa384x_t *hw,
+       CMD_MODE mode,
+       UINT16  page,
+       UINT16  offset,
+       void    *data,
+       UINT    len,
+       ctlx_cmdcb_t cmdcb,
+       ctlx_usercb_t usercb,
+       void    *usercb_data)
+{
+       int                     result;
+       hfa384x_usbctlx_t       *ctlx;
+
+       DBFENTER;
+       WLAN_LOG_DEBUG(5, "page=0x%04x offset=0x%04x len=%d\n",
+               page,offset,len);
+
+       ctlx = usbctlx_alloc();
+       if ( ctlx == NULL ) {
+               result = -ENOMEM;
+               goto done;
+       }
+
+       /* Initialize the command */
+       ctlx->outbuf.wmemreq.type =   host2hfa384x_16(HFA384x_USB_WMEMREQ);
+       ctlx->outbuf.wmemreq.frmlen = host2hfa384x_16(
+                                       sizeof(ctlx->outbuf.wmemreq.offset) +
+                                       sizeof(ctlx->outbuf.wmemreq.page) +
+                                       len);
+       ctlx->outbuf.wmemreq.offset = host2hfa384x_16(offset);
+       ctlx->outbuf.wmemreq.page =   host2hfa384x_16(page);
+       memcpy(ctlx->outbuf.wmemreq.data, data, len);
+
+       ctlx->outbufsize = sizeof(ctlx->outbuf.wmemreq.type) +
+                          sizeof(ctlx->outbuf.wmemreq.frmlen) +
+                          sizeof(ctlx->outbuf.wmemreq.offset) +
+                          sizeof(ctlx->outbuf.wmemreq.page) +
+                          len;
+
+       ctlx->reapable = mode;
+       ctlx->cmdcb = cmdcb;
+       ctlx->usercb = usercb;
+       ctlx->usercb_data = usercb_data;
+
+       result = hfa384x_usbctlx_submit(hw, ctlx);
+       if (result != 0) {
+               kfree(ctlx);
+       } else if ( mode == DOWAIT ) {
+                usbctlx_wmem_completor_t completor;
+                hfa384x_cmdresult_t wmemresult;
+
+                result = hfa384x_usbctlx_complete_sync(
+                               hw,
+                               ctlx,
+                               init_wmem_completor(&completor,
+                                                   &ctlx->inbuf.wmemresp,
+                                                   &wmemresult) );
+       }
+
+done:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_commtallies
+*
+* Send a commtallies inquiry to the MAC.  Note that this is an async
+* call that will result in an info frame arriving sometime later.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      zero            success.
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_commtallies( hfa384x_t *hw )
+{
+       hfa384x_metacmd_t cmd;
+
+       DBFENTER;
+
+       cmd.cmd = HFA384x_CMDCODE_INQ;
+       cmd.parm0 = HFA384x_IT_COMMTALLIES;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+       hfa384x_docmd_async(hw, &cmd, NULL, NULL, NULL);
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_disable
+*
+* Issues the disable command to stop communications on one of
+* the MACs 'ports'.  Only macport 0 is valid  for stations.
+* APs may also disable macports 1-6.  Only ports that have been
+* previously enabled may be disabled.
+*
+* Arguments:
+*      hw              device structure
+*      macport         MAC port number (host order)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport)
+{
+       int     result = 0;
+
+       DBFENTER;
+       if ((!hw->isap && macport != 0) ||
+           (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
+           !(hw->port_enabled[macport]) ){
+               result = -EINVAL;
+       } else {
+               result = hfa384x_cmd_disable(hw, macport);
+               if ( result == 0 ) {
+                       hw->port_enabled[macport] = 0;
+               }
+       }
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_enable
+*
+* Issues the enable command to enable communications on one of
+* the MACs 'ports'.  Only macport 0 is valid  for stations.
+* APs may also enable macports 1-6.  Only ports that are currently
+* disabled may be enabled.
+*
+* Arguments:
+*      hw              device structure
+*      macport         MAC port number
+*
+* Returns:
+*      0               success
+*      >0              f/w reported failure - f/w status code
+*      <0              driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport)
+{
+       int     result = 0;
+
+       DBFENTER;
+       if ((!hw->isap && macport != 0) ||
+           (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
+           (hw->port_enabled[macport]) ){
+               result = -EINVAL;
+       } else {
+               result = hfa384x_cmd_enable(hw, macport);
+               if ( result == 0 ) {
+                       hw->port_enabled[macport] = 1;
+               }
+       }
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_enable
+*
+* Begins the flash download state.  Checks to see that we're not
+* already in a download state and that a port isn't enabled.
+* Sets the download state and retrieves the flash download
+* buffer location, buffer size, and timeout length.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
+{
+       int             result = 0;
+       int             i;
+
+       DBFENTER;
+       /* Check that a port isn't active */
+       for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
+               if ( hw->port_enabled[i] ) {
+                       WLAN_LOG_DEBUG(1,"called when port enabled.\n");
+                       return -EINVAL;
+               }
+       }
+
+       /* Check that we're not already in a download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+               return -EINVAL;
+       }
+
+       /* Retrieve the buffer loc&size and timeout */
+       if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+                               &(hw->bufinfo), sizeof(hw->bufinfo))) ) {
+               return result;
+       }
+       hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
+       hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
+       hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
+       if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+                               &(hw->dltimeout))) ) {
+               return result;
+       }
+       hw->dltimeout = hfa384x2host_16(hw->dltimeout);
+
+       WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+
+       hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_disable
+*
+* Ends the flash download state.  Note that this will cause the MAC
+* firmware to restart.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
+{
+       DBFENTER;
+       /* Check that we're already in the download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+               return -EINVAL;
+       }
+
+       WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+
+       /* There isn't much we can do at this point, so I don't */
+       /*  bother  w/ the return value */
+       hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+       hw->dlstate = HFA384x_DLSTATE_DISABLED;
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_write
+*
+* Performs a FLASH download of a chunk of data. First checks to see
+* that we're in the FLASH download state, then sets the download
+* mode, uses the aux functions to 1) copy the data to the flash
+* buffer, 2) sets the download 'write flash' mode, 3) readback and
+* compare.  Lather rinse, repeat as many times an necessary to get
+* all the given data into flash.
+* When all data has been written using this function (possibly
+* repeatedly), call drvr_flashdl_disable() to end the download state
+* and restart the MAC.
+*
+* Arguments:
+*      hw              device structure
+*      daddr           Card address to write to. (host order)
+*      buf             Ptr to data to write.
+*      len             Length of data (host order).
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_flashdl_write(
+       hfa384x_t       *hw,
+       UINT32          daddr,
+       void            *buf,
+       UINT32          len)
+{
+       int             result = 0;
+       UINT32          dlbufaddr;
+       int             nburns;
+       UINT32          burnlen;
+       UINT32          burndaddr;
+       UINT16          burnlo;
+       UINT16          burnhi;
+       int             nwrites;
+       UINT8           *writebuf;
+       UINT16          writepage;
+       UINT16          writeoffset;
+       UINT32          writelen;
+       int             i;
+       int             j;
+
+       DBFENTER;
+       WLAN_LOG_DEBUG(5,"daddr=0x%08x len=%d\n", daddr, len);
+
+       /* Check that we're in the flash download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+               return -EINVAL;
+       }
+
+       WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr);
+
+       /* Convert to flat address for arithmetic */
+       /* NOTE: dlbuffer RID stores the address in AUX format */
+       dlbufaddr = HFA384x_ADDR_AUX_MKFLAT(
+                       hw->bufinfo.page, hw->bufinfo.offset);
+       WLAN_LOG_DEBUG(5,
+               "dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n",
+               hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
+
+#if 0
+WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);
+#endif
+       /* Calculations to determine how many fills of the dlbuffer to do
+        * and how many USB wmemreq's to do for each fill.  At this point
+        * in time, the dlbuffer size and the wmemreq size are the same.
+        * Therefore, nwrites should always be 1.  The extra complexity
+        * here is a hedge against future changes.
+        */
+
+       /* Figure out how many times to do the flash programming */
+       nburns = len / hw->bufinfo.len;
+       nburns += (len % hw->bufinfo.len) ? 1 : 0;
+
+       /* For each flash program cycle, how many USB wmemreq's are needed? */
+       nwrites = hw->bufinfo.len / HFA384x_USB_RWMEM_MAXLEN;
+       nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0;
+
+       /* For each burn */
+       for ( i = 0; i < nburns; i++) {
+               /* Get the dest address and len */
+               burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
+                               hw->bufinfo.len :
+                               (len - (hw->bufinfo.len * i));
+               burndaddr = daddr + (hw->bufinfo.len * i);
+               burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr);
+               burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr);
+
+               WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n",
+                       burnlen, burndaddr);
+
+               /* Set the download mode */
+               result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
+                               burnlo, burnhi, burnlen);
+               if ( result ) {
+                       WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) "
+                               "cmd failed, result=%d. Aborting d/l\n",
+                               burnlo, burnhi, burnlen, result);
+                       goto exit_proc;
+               }
+
+               /* copy the data to the flash download buffer */
+               for ( j=0; j < nwrites; j++) {
+                       writebuf = buf +
+                               (i*hw->bufinfo.len) +
+                               (j*HFA384x_USB_RWMEM_MAXLEN);
+
+                       writepage = HFA384x_ADDR_CMD_MKPAGE(
+                                       dlbufaddr +
+                                       (j*HFA384x_USB_RWMEM_MAXLEN));
+                       writeoffset = HFA384x_ADDR_CMD_MKOFF(
+                                       dlbufaddr +
+                                       (j*HFA384x_USB_RWMEM_MAXLEN));
+
+                       writelen = burnlen-(j*HFA384x_USB_RWMEM_MAXLEN);
+                       writelen = writelen  > HFA384x_USB_RWMEM_MAXLEN ?
+                                       HFA384x_USB_RWMEM_MAXLEN :
+                                       writelen;
+
+                       result = hfa384x_dowmem_wait( hw,
+                                       writepage,
+                                       writeoffset,
+                                       writebuf,
+                                       writelen );
+#if 0
+
+Comment out for debugging, assume the write was successful.
+                       if (result) {
+                               WLAN_LOG_ERROR(
+                                       "Write to dl buffer failed, "
+                                       "result=0x%04x. Aborting.\n",
+                                       result);
+                               goto exit_proc;
+                       }
+#endif
+
+               }
+
+               /* set the download 'write flash' mode */
+               result = hfa384x_cmd_download(hw,
+                               HFA384x_PROGMODE_NVWRITE,
+                               0,0,0);
+               if ( result ) {
+                       WLAN_LOG_ERROR(
+                               "download(NVWRITE,lo=%x,hi=%x,len=%x) "
+                               "cmd failed, result=%d. Aborting d/l\n",
+                               burnlo, burnhi, burnlen, result);
+                       goto exit_proc;
+               }
+
+               /* TODO: We really should do a readback and compare. */
+       }
+
+exit_proc:
+
+       /* Leave the firmware in the 'post-prog' mode.  flashdl_disable will */
+       /*  actually disable programming mode.  Remember, that will cause the */
+       /*  the firmware to effectively reset itself. */
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_getconfig
+*
+* Performs the sequence necessary to read a config/info item.
+*
+* Arguments:
+*      hw              device structure
+*      rid             config/info record id (host order)
+*      buf             host side record buffer.  Upon return it will
+*                      contain the body portion of the record (minus the
+*                      RID and len).
+*      len             buffer length (in bytes, should match record length)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*      -ENODATA        length mismatch between argument and retrieved
+*                      record.
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
+{
+       int                     result;
+       DBFENTER;
+
+       result = hfa384x_dorrid_wait(hw, rid, buf, len);
+
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+ * hfa384x_drvr_getconfig_async
+ *
+ * Performs the sequence necessary to perform an async read of
+ * of a config/info item.
+ *
+ * Arguments:
+ *       hw              device structure
+ *       rid             config/info record id (host order)
+ *       buf             host side record buffer.  Upon return it will
+ *                       contain the body portion of the record (minus the
+ *                       RID and len).
+ *       len             buffer length (in bytes, should match record length)
+ *       cbfn            caller supplied callback, called when the command
+ *                       is done (successful or not).
+ *       cbfndata        pointer to some caller supplied data that will be
+ *                       passed in as an argument to the cbfn.
+ *
+ * Returns:
+ *       nothing         the cbfn gets a status argument identifying if
+ *                       any errors occur.
+ * Side effects:
+ *       Queues an hfa384x_usbcmd_t for subsequent execution.
+ *
+ * Call context:
+ *       Any
+ ----------------------------------------------------------------*/
+int
+hfa384x_drvr_getconfig_async(
+         hfa384x_t               *hw,
+         UINT16                  rid,
+         ctlx_usercb_t           usercb,
+         void                    *usercb_data)
+{
+         return hfa384x_dorrid_async(hw, rid, NULL, 0,
+                                    hfa384x_cb_rrid, usercb, usercb_data);
+}
+
+/*----------------------------------------------------------------
+ * hfa384x_drvr_setconfig_async
+ *
+ * Performs the sequence necessary to write a config/info item.
+ *
+ * Arguments:
+ *       hw              device structure
+ *       rid             config/info record id (in host order)
+ *       buf             host side record buffer
+ *       len             buffer length (in bytes)
+ *       usercb          completion callback
+ *       usercb_data     completion callback argument
+ *
+ * Returns:
+ *       0               success
+ *       >0              f/w reported error - f/w status code
+ *       <0              driver reported error
+ *
+ * Side effects:
+ *
+ * Call context:
+ *       process
+ ----------------------------------------------------------------*/
+int
+hfa384x_drvr_setconfig_async(
+         hfa384x_t       *hw,
+         UINT16          rid,
+         void            *buf,
+         UINT16          len,
+         ctlx_usercb_t   usercb,
+         void            *usercb_data)
+{
+       return hfa384x_dowrid_async(hw, rid, buf, len,
+                                   hfa384x_cb_status, usercb, usercb_data);
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_handover
+*
+* Sends a handover notification to the MAC.
+*
+* Arguments:
+*      hw              device structure
+*      addr            address of station that's left
+*
+* Returns:
+*      zero            success.
+*      -ERESTARTSYS    received signal while waiting for semaphore.
+*      -EIO            failed to write to bap, or failed in cmd.
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr)
+{
+        DBFENTER;
+       WLAN_LOG_ERROR("Not currently supported in USB!\n");
+       DBFEXIT;
+       return -EIO;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_low_level
+*
+* Write test commands to the card.  Some test commands don't make
+* sense without prior set-up.  For example, continous TX isn't very
+* useful until you set the channel.  That functionality should be
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+* -----------------------------------------------------------------*/
+int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+       int             result;
+       DBFENTER;
+
+       /* Do i need a host2hfa... conversion ? */
+
+       result = hfa384x_docmd_wait(hw, cmd);
+
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_mmi_read
+*
+* Read mmi registers.  mmi is intersil-speak for the baseband
+* processor registers.
+*
+* Arguments:
+*       hw              device structure
+*       register        The test register to be accessed (must be even #).
+*
+* Returns:
+*       0               success
+*       >0              f/w reported error - f/w status code
+*       <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*       process
+----------------------------------------------------------------*/
+int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr, UINT32 *resp)
+{
+#if 0
+        int             result = 0;
+        UINT16  cmd_code = (UINT16) 0x30;
+        UINT16 param = (UINT16) addr;
+        DBFENTER;
+
+        /* Do i need a host2hfa... conversion ? */
+        result = hfa384x_docmd_wait(hw, cmd_code);
+
+        DBFEXIT;
+        return result;
+#endif
+return 0;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_mmi_write
+*
+* Read mmi registers.  mmi is intersil-speak for the baseband
+* processor registers.
+*
+* Arguments:
+*       hw              device structure
+*       addr            The test register to be accessed (must be even #).
+*       data            The data value to write to the register.
+*
+* Returns:
+*       0               success
+*       >0              f/w reported error - f/w status code
+*       <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*       process
+----------------------------------------------------------------*/
+
+int
+hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data)
+{
+#if 0
+        int             result = 0;
+        UINT16  cmd_code = (UINT16) 0x31;
+        UINT16 param0 = (UINT16) addr;
+        UINT16 param1 = (UINT16) data;
+        DBFENTER;
+
+        WLAN_LOG_DEBUG(1,"mmi write : addr = 0x%08lx\n", addr);
+        WLAN_LOG_DEBUG(1,"mmi write : data = 0x%08lx\n", data);
+
+        /* Do i need a host2hfa... conversion ? */
+        result = hfa384x_docmd_wait(hw, cmd_code);
+
+        DBFEXIT;
+        return result;
+#endif
+return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_disable
+*
+* Ends the ram download state.
+*
+* Arguments:
+*      hw              device structure
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
+{
+       DBFENTER;
+       /* Check that we're already in the download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
+               return -EINVAL;
+       }
+
+       WLAN_LOG_DEBUG(3,"ramdl_disable()\n");
+
+       /* There isn't much we can do at this point, so I don't */
+       /*  bother  w/ the return value */
+       hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+       hw->dlstate = HFA384x_DLSTATE_DISABLED;
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_enable
+*
+* Begins the ram download state.  Checks to see that we're not
+* already in a download state and that a port isn't enabled.
+* Sets the download state and calls cmd_download with the
+* ENABLE_VOLATILE subcommand and the exeaddr argument.
+*
+* Arguments:
+*      hw              device structure
+*      exeaddr         the card execution address that will be
+*                       jumped to when ramdl_disable() is called
+*                      (host order).
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr)
+{
+       int             result = 0;
+       UINT16          lowaddr;
+       UINT16          hiaddr;
+       int             i;
+       DBFENTER;
+       /* Check that a port isn't active */
+       for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
+               if ( hw->port_enabled[i] ) {
+                       WLAN_LOG_ERROR(
+                               "Can't download with a macport enabled.\n");
+                       return -EINVAL;
+               }
+       }
+
+       /* Check that we're not already in a download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+               WLAN_LOG_ERROR(
+                       "Download state not disabled.\n");
+               return -EINVAL;
+       }
+
+       WLAN_LOG_DEBUG(3,"ramdl_enable, exeaddr=0x%08x\n", exeaddr);
+
+       /* Call the download(1,addr) function */
+       lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);
+       hiaddr =  HFA384x_ADDR_CMD_MKPAGE(exeaddr);
+
+       result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
+                       lowaddr, hiaddr, 0);
+
+       if ( result == 0) {
+               /* Set the download state */
+               hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
+       } else {
+               WLAN_LOG_DEBUG(1,
+                       "cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
+                       lowaddr,
+                       hiaddr,
+                       result);
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_write
+*
+* Performs a RAM download of a chunk of data. First checks to see
+* that we're in the RAM download state, then uses the [read|write]mem USB
+* commands to 1) copy the data, 2) readback and compare.  The download
+* state is unaffected.  When all data has been written using
+* this function, call drvr_ramdl_disable() to end the download state
+* and restart the MAC.
+*
+* Arguments:
+*      hw              device structure
+*      daddr           Card address to write to. (host order)
+*      buf             Ptr to data to write.
+*      len             Length of data (host order).
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
+{
+       int             result = 0;
+       int             nwrites;
+       UINT8           *data = buf;
+       int             i;
+       UINT32          curraddr;
+       UINT16          currpage;
+       UINT16          curroffset;
+       UINT16          currlen;
+       DBFENTER;
+       /* Check that we're in the ram download state */
+       if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
+               return -EINVAL;
+       }
+
+       WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr);
+
+       /* How many dowmem calls?  */
+       nwrites = len / HFA384x_USB_RWMEM_MAXLEN;
+       nwrites += len % HFA384x_USB_RWMEM_MAXLEN ? 1 : 0;
+
+       /* Do blocking wmem's */
+       for(i=0; i < nwrites; i++) {
+               /* make address args */
+               curraddr = daddr + (i * HFA384x_USB_RWMEM_MAXLEN);
+               currpage = HFA384x_ADDR_CMD_MKPAGE(curraddr);
+               curroffset = HFA384x_ADDR_CMD_MKOFF(curraddr);
+               currlen = len - (i * HFA384x_USB_RWMEM_MAXLEN);
+               if ( currlen > HFA384x_USB_RWMEM_MAXLEN) {
+                       currlen = HFA384x_USB_RWMEM_MAXLEN;
+               }
+
+               /* Do blocking ctlx */
+               result = hfa384x_dowmem_wait( hw,
+                               currpage,
+                               curroffset,
+                               data + (i*HFA384x_USB_RWMEM_MAXLEN),
+                               currlen );
+
+               if (result) break;
+
+               /* TODO: We really should have a readback. */
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_readpda
+*
+* Performs the sequence to read the PDA space.  Note there is no
+* drvr_writepda() function.  Writing a PDA is
+* generally implemented by a calling component via calls to
+* cmd_download and writing to the flash download buffer via the
+* aux regs.
+*
+* Arguments:
+*      hw              device structure
+*      buf             buffer to store PDA in
+*      len             buffer length
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*      -ETIMEOUT       timout waiting for the cmd regs to become
+*                      available, or waiting for the control reg
+*                      to indicate the Aux port is enabled.
+*      -ENODATA        the buffer does NOT contain a valid PDA.
+*                      Either the card PDA is bad, or the auxdata
+*                      reads are giving us garbage.
+
+*
+* Side effects:
+*
+* Call context:
+*      process or non-card interrupt.
+----------------------------------------------------------------*/
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len)
+{
+       int             result = 0;
+       UINT16          *pda = buf;
+       int             pdaok = 0;
+       int             morepdrs = 1;
+       int             currpdr = 0;    /* word offset of the current pdr */
+       size_t          i;
+       UINT16          pdrlen;         /* pdr length in bytes, host order */
+       UINT16          pdrcode;        /* pdr code, host order */
+       UINT16          currpage;
+       UINT16          curroffset;
+       struct pdaloc {
+               UINT32  cardaddr;
+               UINT16  auxctl;
+       } pdaloc[] =
+       {
+               { HFA3842_PDA_BASE,             0},
+               { HFA3841_PDA_BASE,             0},
+               { HFA3841_PDA_BOGUS_BASE,       0}
+       };
+
+       DBFENTER;
+
+       /* Read the pda from each known address.  */
+       for ( i = 0; i < ARRAY_SIZE(pdaloc); i++) {
+               /* Make address */
+               currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr);
+               curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr);
+
+               result = hfa384x_dormem_wait(hw,
+                       currpage,
+                       curroffset,
+                       buf,
+                       len);           /* units of bytes */
+
+               if (result) {
+                       WLAN_LOG_WARNING(
+                                         "Read from index %zd failed, continuing\n",
+                               i );
+                       continue;
+               }
+
+               /* Test for garbage */
+               pdaok = 1;      /* initially assume good */
+               morepdrs = 1;
+               while ( pdaok && morepdrs ) {
+                       pdrlen = hfa384x2host_16(pda[currpdr]) * 2;
+                       pdrcode = hfa384x2host_16(pda[currpdr+1]);
+                       /* Test the record length */
+                       if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
+                               WLAN_LOG_ERROR("pdrlen invalid=%d\n",
+                                       pdrlen);
+                               pdaok = 0;
+                               break;
+                       }
+                       /* Test the code */
+                       if ( !hfa384x_isgood_pdrcode(pdrcode) ) {
+                               WLAN_LOG_ERROR("pdrcode invalid=%d\n",
+                                       pdrcode);
+                               pdaok = 0;
+                               break;
+                       }
+                       /* Test for completion */
+                       if ( pdrcode == HFA384x_PDR_END_OF_PDA) {
+                               morepdrs = 0;
+                       }
+
+                       /* Move to the next pdr (if necessary) */
+                       if ( morepdrs ) {
+                               /* note the access to pda[], need words here */
+                               currpdr += hfa384x2host_16(pda[currpdr]) + 1;
+                       }
+               }
+               if ( pdaok ) {
+                       WLAN_LOG_INFO(
+                               "PDA Read from 0x%08x in %s space.\n",
+                               pdaloc[i].cardaddr,
+                               pdaloc[i].auxctl == 0 ? "EXTDS" :
+                               pdaloc[i].auxctl == 1 ? "NV" :
+                               pdaloc[i].auxctl == 2 ? "PHY" :
+                               pdaloc[i].auxctl == 3 ? "ICSRAM" :
+                               "<bogus auxctl>");
+                       break;
+               }
+       }
+       result = pdaok ? 0 : -ENODATA;
+
+       if ( result ) {
+               WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n");
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_setconfig
+*
+* Performs the sequence necessary to write a config/info item.
+*
+* Arguments:
+*      hw              device structure
+*      rid             config/info record id (in host order)
+*      buf             host side record buffer
+*      len             buffer length (in bytes)
+*
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
+{
+       return hfa384x_dowrid_wait(hw, rid, buf, len);
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_start
+*
+* Issues the MAC initialize command, sets up some data structures,
+* and enables the interrupts.  After this function completes, the
+* low-level stuff should be ready for any/all commands.
+*
+* Arguments:
+*      hw              device structure
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int hfa384x_drvr_start(hfa384x_t *hw)
+{
+       int             result;
+       DBFENTER;
+
+       might_sleep();
+
+       if (usb_clear_halt(hw->usb, hw->endp_in)) {
+               WLAN_LOG_ERROR(
+                       "Failed to reset bulk in endpoint.\n");
+       }
+
+       if (usb_clear_halt(hw->usb, hw->endp_out)) {
+               WLAN_LOG_ERROR(
+                       "Failed to reset bulk out endpoint.\n");
+       }
+
+       /* Synchronous unlink, in case we're trying to restart the driver */
+       usb_kill_urb(&hw->rx_urb);
+
+       /* Post the IN urb */
+       result = submit_rx_urb(hw, GFP_KERNEL);
+       if (result != 0) {
+               WLAN_LOG_ERROR(
+                       "Fatal, failed to submit RX URB, result=%d\n",
+                       result);
+               goto done;
+       }
+
+       /* call initialize */
+       result = hfa384x_cmd_initialize(hw);
+       if (result != 0) {
+               usb_kill_urb(&hw->rx_urb);
+               WLAN_LOG_ERROR(
+                       "cmd_initialize() failed, result=%d\n",
+                       result);
+               goto done;
+       }
+
+       hw->state = HFA384x_STATE_RUNNING;
+
+done:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_stop
+*
+* Shuts down the MAC to the point where it is safe to unload the
+* driver.  Any subsystem that may be holding a data or function
+* ptr into the driver must be cleared/deinitialized.
+*
+* Arguments:
+*      hw              device structure
+* Returns:
+*      0               success
+*      >0              f/w reported error - f/w status code
+*      <0              driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_stop(hfa384x_t *hw)
+{
+       int     result = 0;
+       int     i;
+       DBFENTER;
+
+       might_sleep();
+
+       /* There's no need for spinlocks here. The USB "disconnect"
+        * function sets this "removed" flag and then calls us.
+        */
+       if ( !hw->wlandev->hwremoved ) {
+               /* Call initialize to leave the MAC in its 'reset' state */
+               hfa384x_cmd_initialize(hw);
+
+               /* Cancel the rxurb */
+               usb_kill_urb(&hw->rx_urb);
+       }
+
+       hw->link_status = HFA384x_LINK_NOTCONNECTED;
+       hw->state = HFA384x_STATE_INIT;
+
+       del_timer_sync(&hw->commsqual_timer);
+
+       /* Clear all the port status */
+       for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+               hw->port_enabled[i] = 0;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_txframe
+*
+* Takes a frame from prism2sta and queues it for transmission.
+*
+* Arguments:
+*      hw              device structure
+*      skb             packet buffer struct.  Contains an 802.11
+*                      data frame.
+*       p80211_hdr      points to the 802.11 header for the packet.
+* Returns:
+*      0               Success and more buffs available
+*      1               Success but no more buffs
+*      2               Allocation failure
+*      4               Buffer full or queue busy
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
+
+{
+       int             usbpktlen = sizeof(hfa384x_tx_frame_t);
+       int             result;
+       int             ret;
+       char            *ptr;
+
+       DBFENTER;
+
+       if (hw->tx_urb.status == -EINPROGRESS) {
+               WLAN_LOG_WARNING("TX URB already in use\n");
+               result = 3;
+               goto exit;
+       }
+
+       /* Build Tx frame structure */
+       /* Set up the control field */
+       memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc));
+
+       /* Setup the usb type field */
+       hw->txbuff.type = host2hfa384x_16(HFA384x_USB_TXFRM);
+
+       /* Set up the sw_support field to identify this frame */
+       hw->txbuff.txfrm.desc.sw_support = 0x0123;
+
+/* Tx complete and Tx exception disable per dleach.  Might be causing
+ * buf depletion
+ */
+//#define DOEXC  SLP -- doboth breaks horribly under load, doexc less so.
+#if defined(DOBOTH)
+       hw->txbuff.txfrm.desc.tx_control =
+               HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+               HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
+#elif defined(DOEXC)
+       hw->txbuff.txfrm.desc.tx_control =
+               HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+               HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
+#else
+       hw->txbuff.txfrm.desc.tx_control =
+               HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+               HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
+#endif
+       hw->txbuff.txfrm.desc.tx_control =
+               host2hfa384x_16(hw->txbuff.txfrm.desc.tx_control);
+
+       /* copy the header over to the txdesc */
+       memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr, sizeof(p80211_hdr_t));
+
+       /* if we're using host WEP, increase size by IV+ICV */
+       if (p80211_wep->data) {
+               hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len+8);
+               // hw->txbuff.txfrm.desc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1);
+               usbpktlen+=8;
+       } else {
+               hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len);
+       }
+
+       usbpktlen += skb->len;
+
+       /* copy over the WEP IV if we are using host WEP */
+       ptr = hw->txbuff.txfrm.data;
+       if (p80211_wep->data) {
+               memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv));
+               ptr+= sizeof(p80211_wep->iv);
+               memcpy(ptr, p80211_wep->data, skb->len);
+       } else {
+               memcpy(ptr, skb->data, skb->len);
+       }
+       /* copy over the packet data */
+       ptr+= skb->len;
+
+       /* copy over the WEP ICV if we are using host WEP */
+       if (p80211_wep->data) {
+               memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv));
+       }
+
+       /* Send the USB packet */
+       usb_fill_bulk_urb( &(hw->tx_urb), hw->usb,
+                      hw->endp_out,
+                      &(hw->txbuff), ROUNDUP64(usbpktlen),
+                      hfa384x_usbout_callback, hw->wlandev );
+       hw->tx_urb.transfer_flags |= USB_QUEUE_BULK;
+
+       result = 1;
+       ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC);
+       if ( ret != 0 ) {
+               WLAN_LOG_ERROR(
+                       "submit_tx_urb() failed, error=%d\n", ret);
+               result = 3;
+       }
+
+ exit:
+       DBFEXIT;
+       return result;
+}
+
+void hfa384x_tx_timeout(wlandevice_t *wlandev)
+{
+       hfa384x_t       *hw = wlandev->priv;
+       unsigned long flags;
+
+       DBFENTER;
+
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       if ( !hw->wlandev->hwremoved &&
+            /* Note the bitwise OR, not the logical OR. */
+            ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) |
+              !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) )
+       {
+               schedule_work(&hw->usb_work);
+       }
+
+       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_reaper_task
+*
+* Tasklet to delete dead CTLX objects
+*
+* Arguments:
+*      data    ptr to a hfa384x_t
+*
+* Returns:
+*
+* Call context:
+*      Interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbctlx_reaper_task(unsigned long data)
+{
+       hfa384x_t       *hw = (hfa384x_t*)data;
+       struct list_head *entry;
+       struct list_head *temp;
+       unsigned long   flags;
+
+       DBFENTER;
+
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       /* This list is guaranteed to be empty if someone
+        * has unplugged the adapter.
+        */
+       list_for_each_safe(entry, temp, &hw->ctlxq.reapable) {
+               hfa384x_usbctlx_t       *ctlx;
+
+               ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
+               list_del(&ctlx->list);
+               kfree(ctlx);
+       }
+
+       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_completion_task
+*
+* Tasklet to call completion handlers for returned CTLXs
+*
+* Arguments:
+*      data    ptr to hfa384x_t
+*
+* Returns:
+*      Nothing
+*
+* Call context:
+*      Interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbctlx_completion_task(unsigned long data)
+{
+       hfa384x_t *hw = (hfa384x_t*)data;
+       struct list_head *entry;
+       struct list_head *temp;
+       unsigned long flags;
+
+       int reap = 0;
+
+       DBFENTER;
+
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       /* This list is guaranteed to be empty if someone
+        * has unplugged the adapter ...
+        */
+       list_for_each_safe(entry, temp, &hw->ctlxq.completing) {
+               hfa384x_usbctlx_t *ctlx;
+
+               ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
+
+               /* Call the completion function that this
+                * command was assigned, assuming it has one.
+                */
+               if ( ctlx->cmdcb != NULL ) {
+                       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+                       ctlx->cmdcb(hw, ctlx);
+                       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+                       /* Make sure we don't try and complete
+                        * this CTLX more than once!
+                        */
+                       ctlx->cmdcb = NULL;
+
+                       /* Did someone yank the adapter out
+                        * while our list was (briefly) unlocked?
+                        */
+                       if ( hw->wlandev->hwremoved )
+                       {
+                               reap = 0;
+                               break;
+                       }
+               }
+
+               /*
+                * "Reapable" CTLXs are ones which don't have any
+                * threads waiting for them to die. Hence they must
+                * be delivered to The Reaper!
+                */
+               if ( ctlx->reapable ) {
+                       /* Move the CTLX off the "completing" list (hopefully)
+                        * on to the "reapable" list where the reaper task
+                        * can find it. And "reapable" means that this CTLX
+                        * isn't sitting on a wait-queue somewhere.
+                        */
+                       list_move_tail(&ctlx->list, &hw->ctlxq.reapable);
+                       reap = 1;
+               }
+
+               complete(&ctlx->done);
+       }
+       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+       if (reap)
+               tasklet_schedule(&hw->reaper_bh);
+
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* unlocked_usbctlx_cancel_async
+*
+* Mark the CTLX dead asynchronously, and ensure that the
+* next command on the queue is run afterwards.
+*
+* Arguments:
+*      hw      ptr to the hfa384x_t structure
+*      ctlx    ptr to a CTLX structure
+*
+* Returns:
+*      0       the CTLX's URB is inactive
+* -EINPROGRESS the URB is currently being unlinked
+*
+* Call context:
+*      Either process or interrupt, but presumably interrupt
+----------------------------------------------------------------*/
+static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
+{
+       int ret;
+
+       DBFENTER;
+
+       /*
+        * Try to delete the URB containing our request packet.
+        * If we succeed, then its completion handler will be
+        * called with a status of -ECONNRESET.
+        */
+       hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
+       ret = usb_unlink_urb(&hw->ctlx_urb);
+
+       if (ret != -EINPROGRESS) {
+               /*
+                * The OUT URB had either already completed
+                * or was still in the pending queue, so the
+                * URB's completion function will not be called.
+                * We will have to complete the CTLX ourselves.
+                */
+               ctlx->state = CTLX_REQ_FAILED;
+               unlocked_usbctlx_complete(hw, ctlx);
+               ret = 0;
+       }
+
+       DBFEXIT;
+
+       return ret;
+}
+
+/*----------------------------------------------------------------
+* unlocked_usbctlx_complete
+*
+* A CTLX has completed.  It may have been successful, it may not
+* have been. At this point, the CTLX should be quiescent.  The URBs
+* aren't active and the timers should have been stopped.
+*
+* The CTLX is migrated to the "completing" queue, and the completing
+* tasklet is scheduled.
+*
+* Arguments:
+*      hw              ptr to a hfa384x_t structure
+*      ctlx            ptr to a ctlx structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      Either, assume interrupt
+----------------------------------------------------------------*/
+static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
+{
+       DBFENTER;
+
+       /* Timers have been stopped, and ctlx should be in
+        * a terminal state. Retire it from the "active"
+        * queue.
+        */
+       list_move_tail(&ctlx->list, &hw->ctlxq.completing);
+       tasklet_schedule(&hw->completion_bh);
+
+       switch (ctlx->state) {
+       case CTLX_COMPLETE:
+       case CTLX_REQ_FAILED:
+               /* This are the correct terminating states. */
+               break;
+
+       default:
+               WLAN_LOG_ERROR("CTLX[%d] not in a terminating state(%s)\n",
+                              hfa384x2host_16(ctlx->outbuf.type),
+                              ctlxstr(ctlx->state));
+               break;
+       } /* switch */
+
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlxq_run
+*
+* Checks to see if the head item is running.  If not, starts it.
+*
+* Arguments:
+*      hw      ptr to hfa384x_t
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      any
+----------------------------------------------------------------*/
+static void
+hfa384x_usbctlxq_run(hfa384x_t *hw)
+{
+       unsigned long           flags;
+       DBFENTER;
+
+       /* acquire lock */
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       /* Only one active CTLX at any one time, because there's no
+        * other (reliable) way to match the response URB to the
+        * correct CTLX.
+        *
+        * Don't touch any of these CTLXs if the hardware
+        * has been removed or the USB subsystem is stalled.
+        */
+       if ( !list_empty(&hw->ctlxq.active) ||
+            test_bit(WORK_TX_HALT, &hw->usb_flags) ||
+            hw->wlandev->hwremoved )
+               goto unlock;
+
+       while ( !list_empty(&hw->ctlxq.pending) ) {
+               hfa384x_usbctlx_t       *head;
+               int                     result;
+
+               /* This is the first pending command */
+               head = list_entry(hw->ctlxq.pending.next,
+                                 hfa384x_usbctlx_t,
+                                 list);
+
+               /* We need to split this off to avoid a race condition */
+               list_move_tail(&head->list, &hw->ctlxq.active);
+
+               /* Fill the out packet */
+               usb_fill_bulk_urb( &(hw->ctlx_urb), hw->usb,
+                                  hw->endp_out,
+                                  &(head->outbuf), ROUNDUP64(head->outbufsize),
+                                  hfa384x_ctlxout_callback, hw);
+               hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK;
+
+               /* Now submit the URB and update the CTLX's state
+                */
+               if ((result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC)) == 0) {
+                       /* This CTLX is now running on the active queue */
+                       head->state = CTLX_REQ_SUBMITTED;
+
+                       /* Start the OUT wait timer */
+                       hw->req_timer_done = 0;
+                       hw->reqtimer.expires = jiffies + HZ;
+                       add_timer(&hw->reqtimer);
+
+                       /* Start the IN wait timer */
+                       hw->resp_timer_done = 0;
+                       hw->resptimer.expires = jiffies + 2*HZ;
+                       add_timer(&hw->resptimer);
+
+                       break;
+               }
+
+               if (result == -EPIPE) {
+                       /* The OUT pipe needs resetting, so put
+                        * this CTLX back in the "pending" queue
+                        * and schedule a reset ...
+                        */
+                       WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
+                                        hw->wlandev->netdev->name);
+                       list_move(&head->list, &hw->ctlxq.pending);
+                       set_bit(WORK_TX_HALT, &hw->usb_flags);
+                       schedule_work(&hw->usb_work);
+                       break;
+               }
+
+               if (result == -ESHUTDOWN) {
+                       WLAN_LOG_WARNING("%s urb shutdown!\n",
+                                        hw->wlandev->netdev->name);
+                       break;
+               }
+
+               WLAN_LOG_ERROR("Failed to submit CTLX[%d]: error=%d\n",
+                              hfa384x2host_16(head->outbuf.type), result);
+               unlocked_usbctlx_complete(hw, head);
+       } /* while */
+
+       unlock:
+       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_callback
+*
+* Callback for URBs on the BULKIN endpoint.
+*
+* Arguments:
+*      urb             ptr to the completed urb
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+#ifdef URB_ONLY_CALLBACK
+static void hfa384x_usbin_callback(struct urb *urb)
+#else
+static void hfa384x_usbin_callback(struct urb *urb, struct pt_regs *regs)
+#endif
+{
+       wlandevice_t            *wlandev = urb->context;
+       hfa384x_t               *hw;
+       hfa384x_usbin_t         *usbin = (hfa384x_usbin_t *) urb->transfer_buffer;
+       struct sk_buff          *skb = NULL;
+       int                     result;
+       int                     urb_status;
+       UINT16                  type;
+
+       enum USBIN_ACTION {
+               HANDLE,
+               RESUBMIT,
+               ABORT
+       } action;
+
+       DBFENTER;
+
+       if ( !wlandev ||
+            !wlandev->netdev ||
+            !netif_device_present(wlandev->netdev) )
+               goto exit;
+
+       hw = wlandev->priv;
+       if (!hw)
+               goto exit;
+
+       skb = hw->rx_urb_skb;
+       if (!skb || (skb->data != urb->transfer_buffer)) {
+               BUG();
+       }
+       hw->rx_urb_skb = NULL;
+
+       /* Check for error conditions within the URB */
+       switch (urb->status) {
+       case 0:
+               action = HANDLE;
+
+               /* Check for short packet */
+               if ( urb->actual_length == 0 ) {
+                       ++(wlandev->linux_stats.rx_errors);
+                       ++(wlandev->linux_stats.rx_length_errors);
+                       action = RESUBMIT;
+               }
+               break;
+
+       case -EPIPE:
+               WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n",
+                                wlandev->netdev->name);
+               if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) )
+                       schedule_work(&hw->usb_work);
+               ++(wlandev->linux_stats.rx_errors);
+               action = ABORT;
+               break;
+
+       case -EILSEQ:
+       case -ETIMEDOUT:
+       case -EPROTO:
+               if ( !test_and_set_bit(THROTTLE_RX, &hw->usb_flags) &&
+                    !timer_pending(&hw->throttle) ) {
+                       mod_timer(&hw->throttle, jiffies + THROTTLE_JIFFIES);
+               }
+               ++(wlandev->linux_stats.rx_errors);
+               action = ABORT;
+               break;
+
+       case -EOVERFLOW:
+               ++(wlandev->linux_stats.rx_over_errors);
+               action = RESUBMIT;
+               break;
+
+       case -ENODEV:
+       case -ESHUTDOWN:
+               WLAN_LOG_DEBUG(3,"status=%d, device removed.\n", urb->status);
+               action = ABORT;
+               break;
+
+       case -ENOENT:
+       case -ECONNRESET:
+               WLAN_LOG_DEBUG(3,"status=%d, urb explicitly unlinked.\n", urb->status);
+               action = ABORT;
+               break;
+
+       default:
+               WLAN_LOG_DEBUG(3,"urb status=%d, transfer flags=0x%x\n",
+                                urb->status, urb->transfer_flags);
+               ++(wlandev->linux_stats.rx_errors);
+               action = RESUBMIT;
+               break;
+       }
+
+       urb_status = urb->status;
+
+       if (action != ABORT) {
+               /* Repost the RX URB */
+               result = submit_rx_urb(hw, GFP_ATOMIC);
+
+               if (result != 0) {
+                       WLAN_LOG_ERROR(
+                               "Fatal, failed to resubmit rx_urb. error=%d\n",
+                               result);
+               }
+       }
+
+       /* Handle any USB-IN packet */
+       /* Note: the check of the sw_support field, the type field doesn't
+        *       have bit 12 set like the docs suggest.
+        */
+       type = hfa384x2host_16(usbin->type);
+       if (HFA384x_USB_ISRXFRM(type)) {
+               if (action == HANDLE) {
+                       if (usbin->txfrm.desc.sw_support == 0x0123) {
+                               hfa384x_usbin_txcompl(wlandev, usbin);
+                       } else {
+                               skb_put(skb, sizeof(*usbin));
+                               hfa384x_usbin_rx(wlandev, skb);
+                               skb = NULL;
+                       }
+               }
+               goto exit;
+       }
+       if (HFA384x_USB_ISTXFRM(type)) {
+               if (action == HANDLE)
+                       hfa384x_usbin_txcompl(wlandev, usbin);
+               goto exit;
+       }
+       switch (type) {
+       case HFA384x_USB_INFOFRM:
+               if (action == ABORT)
+                       goto exit;
+               if (action == HANDLE)
+                       hfa384x_usbin_info(wlandev, usbin);
+               break;
+
+       case HFA384x_USB_CMDRESP:
+       case HFA384x_USB_WRIDRESP:
+       case HFA384x_USB_RRIDRESP:
+       case HFA384x_USB_WMEMRESP:
+       case HFA384x_USB_RMEMRESP:
+               /* ALWAYS, ALWAYS, ALWAYS handle this CTLX!!!! */
+               hfa384x_usbin_ctlx(hw, usbin, urb_status);
+               break;
+
+       case HFA384x_USB_BUFAVAIL:
+               WLAN_LOG_DEBUG(3,"Received BUFAVAIL packet, frmlen=%d\n",
+                       usbin->bufavail.frmlen);
+               break;
+
+       case HFA384x_USB_ERROR:
+               WLAN_LOG_DEBUG(3,"Received USB_ERROR packet, errortype=%d\n",
+                       usbin->usberror.errortype);
+               break;
+
+       default:
+               WLAN_LOG_DEBUG(3,"Unrecognized USBIN packet, type=%x, status=%d\n",
+                       usbin->type, urb_status);
+               break;
+       } /* switch */
+
+exit:
+
+       if (skb)
+               dev_kfree_skb(skb);
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_ctlx
+*
+* We've received a URB containing a Prism2 "response" message.
+* This message needs to be matched up with a CTLX on the active
+* queue and our state updated accordingly.
+*
+* Arguments:
+*      hw              ptr to hfa384x_t
+*      usbin           ptr to USB IN packet
+*      urb_status      status of this Bulk-In URB
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
+                              int urb_status)
+{
+       hfa384x_usbctlx_t       *ctlx;
+       int                     run_queue = 0;
+       unsigned long           flags;
+
+       DBFENTER;
+
+retry:
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       /* There can be only one CTLX on the active queue
+        * at any one time, and this is the CTLX that the
+        * timers are waiting for.
+        */
+       if ( list_empty(&hw->ctlxq.active) ) {
+               goto unlock;
+       }
+
+       /* Remove the "response timeout". It's possible that
+        * we are already too late, and that the timeout is
+        * already running. And that's just too bad for us,
+        * because we could lose our CTLX from the active
+        * queue here ...
+        */
+       if (del_timer(&hw->resptimer) == 0) {
+               if (hw->resp_timer_done == 0) {
+                       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+                       goto retry;
+               }
+       }
+       else {
+               hw->resp_timer_done = 1;
+       }
+
+       ctlx = get_active_ctlx(hw);
+
+       if (urb_status != 0) {
+               /*
+                * Bad CTLX, so get rid of it. But we only
+                * remove it from the active queue if we're no
+                * longer expecting the OUT URB to complete.
+                */
+               if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
+                       run_queue = 1;
+       } else {
+               const UINT16 intype = (usbin->type&~host2hfa384x_16(0x8000));
+
+               /*
+                * Check that our message is what we're expecting ...
+                */
+               if (ctlx->outbuf.type != intype) {
+                       WLAN_LOG_WARNING("Expected IN[%d], received IN[%d] - ignored.\n",
+                                        hfa384x2host_16(ctlx->outbuf.type),
+                                        hfa384x2host_16(intype));
+                       goto unlock;
+               }
+
+               /* This URB has succeeded, so grab the data ... */
+               memcpy(&ctlx->inbuf, usbin, sizeof(ctlx->inbuf));
+
+               switch (ctlx->state) {
+               case CTLX_REQ_SUBMITTED:
+                       /*
+                        * We have received our response URB before
+                        * our request has been acknowledged. Odd,
+                        * but our OUT URB is still alive...
+                        */
+                       WLAN_LOG_DEBUG(0, "Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n");
+                       ctlx->state = CTLX_RESP_COMPLETE;
+                       break;
+
+               case CTLX_REQ_COMPLETE:
+                       /*
+                        * This is the usual path: our request
+                        * has already been acknowledged, and
+                        * now we have received the reply too.
+                        */
+                       ctlx->state = CTLX_COMPLETE;
+                       unlocked_usbctlx_complete(hw, ctlx);
+                       run_queue = 1;
+                       break;
+
+               default:
+                       /*
+                        * Throw this CTLX away ...
+                        */
+                       WLAN_LOG_ERROR("Matched IN URB, CTLX[%d] in invalid state(%s)."
+                                      " Discarded.\n",
+                                      hfa384x2host_16(ctlx->outbuf.type),
+                                      ctlxstr(ctlx->state));
+                       if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
+                               run_queue = 1;
+                       break;
+               } /* switch */
+       }
+
+unlock:
+       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+       if (run_queue)
+               hfa384x_usbctlxq_run(hw);
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_txcompl
+*
+* At this point we have the results of a previous transmit.
+*
+* Arguments:
+*      wlandev         wlan device
+*      usbin           ptr to the usb transfer buffer
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+{
+       UINT16                  status;
+       DBFENTER;
+
+       status = hfa384x2host_16(usbin->type); /* yeah I know it says type...*/
+
+       /* Was there an error? */
+       if (HFA384x_TXSTATUS_ISERROR(status)) {
+               prism2sta_ev_txexc(wlandev, status);
+       } else {
+               prism2sta_ev_tx(wlandev, status);
+       }
+       // prism2sta_ev_alloc(wlandev);
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_rx
+*
+* At this point we have a successful received a rx frame packet.
+*
+* Arguments:
+*      wlandev         wlan device
+*      usbin           ptr to the usb transfer buffer
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
+{
+       hfa384x_usbin_t         *usbin = (hfa384x_usbin_t *) skb->data;
+       hfa384x_t               *hw = wlandev->priv;
+       int                     hdrlen;
+       p80211_rxmeta_t         *rxmeta;
+       UINT16                  data_len;
+       UINT16                  fc;
+
+       DBFENTER;
+
+       /* Byte order convert once up front. */
+       usbin->rxfrm.desc.status =
+               hfa384x2host_16(usbin->rxfrm.desc.status);
+       usbin->rxfrm.desc.time =
+               hfa384x2host_32(usbin->rxfrm.desc.time);
+
+       /* Now handle frame based on port# */
+       switch( HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) )
+       {
+       case 0:
+               fc = ieee2host16(usbin->rxfrm.desc.frame_control);
+
+               /* If exclude and we receive an unencrypted, drop it */
+               if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
+                    !WLAN_GET_FC_ISWEP(fc)){
+                       goto done;
+               }
+
+               data_len = hfa384x2host_16(usbin->rxfrm.desc.data_len);
+
+               /* How much header data do we have? */
+               hdrlen = p80211_headerlen(fc);
+
+               /* Pull off the descriptor */
+               skb_pull(skb, sizeof(hfa384x_rx_frame_t));
+
+               /* Now shunt the header block up against the data block
+                * with an "overlapping" copy
+                */
+               memmove(skb_push(skb, hdrlen),
+                       &usbin->rxfrm.desc.frame_control,
+                       hdrlen);
+
+               skb->dev = wlandev->netdev;
+               skb->dev->last_rx = jiffies;
+
+               /* And set the frame length properly */
+               skb_trim(skb, data_len + hdrlen);
+
+               /* The prism2 series does not return the CRC */
+               memset(skb_put(skb, WLAN_CRC_LEN), 0xff, WLAN_CRC_LEN);
+
+               skb_reset_mac_header(skb);
+
+               /* Attach the rxmeta, set some stuff */
+               p80211skb_rxmeta_attach(wlandev, skb);
+               rxmeta = P80211SKB_RXMETA(skb);
+               rxmeta->mactime = usbin->rxfrm.desc.time;
+               rxmeta->rxrate = usbin->rxfrm.desc.rate;
+               rxmeta->signal = usbin->rxfrm.desc.signal - hw->dbmadjust;
+               rxmeta->noise = usbin->rxfrm.desc.silence - hw->dbmadjust;
+
+               prism2sta_ev_rx(wlandev, skb);
+
+               break;
+
+       case 7:
+               if ( ! HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status) ) {
+                       /* Copy to wlansnif skb */
+                       hfa384x_int_rxmonitor( wlandev, &usbin->rxfrm);
+                       dev_kfree_skb(skb);
+               } else {
+                       WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n");
+               }
+               break;
+
+       default:
+               WLAN_LOG_WARNING("Received frame on unsupported port=%d\n",
+                       HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) );
+               goto done;
+               break;
+       }
+
+done:
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_int_rxmonitor
+*
+* Helper function for int_rx.  Handles monitor frames.
+* Note that this function allocates space for the FCS and sets it
+* to 0xffffffff.  The hfa384x doesn't give us the FCS value but the
+* higher layers expect it.  0xffffffff is used as a flag to indicate
+* the FCS is bogus.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      rxfrm           rx descriptor read from card in int_rx
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      Allocates an skb and passes it up via the PF_PACKET interface.
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm)
+{
+       hfa384x_rx_frame_t              *rxdesc = &(rxfrm->desc);
+       UINT                            hdrlen = 0;
+       UINT                            datalen = 0;
+       UINT                            skblen = 0;
+       p80211msg_lnxind_wlansniffrm_t  *msg;
+       UINT8                           *datap;
+       UINT16                          fc;
+       struct sk_buff                  *skb;
+       hfa384x_t                       *hw = wlandev->priv;
+
+
+       DBFENTER;
+       /* Don't forget the status, time, and data_len fields are in host order */
+       /* Figure out how big the frame is */
+       fc = ieee2host16(rxdesc->frame_control);
+       hdrlen = p80211_headerlen(fc);
+       datalen = hfa384x2host_16(rxdesc->data_len);
+
+       /* Allocate an ind message+framesize skb */
+       skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) +
+               hdrlen + datalen + WLAN_CRC_LEN;
+
+       /* sanity check the length */
+       if ( skblen >
+               (sizeof(p80211msg_lnxind_wlansniffrm_t) +
+               WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
+               WLAN_LOG_DEBUG(1, "overlen frm: len=%zd\n",
+                       skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
+       }
+
+       if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
+               WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen);
+               return;
+       }
+
+       /* only prepend the prism header if in the right mode */
+       if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
+           (hw->sniffhdr == 0)) {
+               datap = skb_put(skb, sizeof(p80211msg_lnxind_wlansniffrm_t));
+               msg = (p80211msg_lnxind_wlansniffrm_t*) datap;
+
+               /* Initialize the message members */
+               msg->msgcode = DIDmsg_lnxind_wlansniffrm;
+               msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
+               strcpy(msg->devname, wlandev->name);
+
+               msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+               msg->hosttime.status = 0;
+               msg->hosttime.len = 4;
+               msg->hosttime.data = jiffies;
+
+               msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+               msg->mactime.status = 0;
+               msg->mactime.len = 4;
+               msg->mactime.data = rxdesc->time;
+
+               msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+               msg->channel.status = 0;
+               msg->channel.len = 4;
+               msg->channel.data = hw->sniff_channel;
+
+               msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+               msg->rssi.status = P80211ENUM_msgitem_status_no_value;
+               msg->rssi.len = 4;
+               msg->rssi.data = 0;
+
+               msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
+               msg->sq.status = P80211ENUM_msgitem_status_no_value;
+               msg->sq.len = 4;
+               msg->sq.data = 0;
+
+               msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+               msg->signal.status = 0;
+               msg->signal.len = 4;
+               msg->signal.data = rxdesc->signal;
+
+               msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+               msg->noise.status = 0;
+               msg->noise.len = 4;
+               msg->noise.data = rxdesc->silence;
+
+               msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+               msg->rate.status = 0;
+               msg->rate.len = 4;
+               msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
+
+               msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+               msg->istx.status = 0;
+               msg->istx.len = 4;
+               msg->istx.data = P80211ENUM_truth_false;
+
+               msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+               msg->frmlen.status = 0;
+               msg->frmlen.len = 4;
+               msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN;
+       } else if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
+                  (hw->sniffhdr != 0)) {
+               p80211_caphdr_t         *caphdr;
+               /* The NEW header format! */
+               datap = skb_put(skb, sizeof(p80211_caphdr_t));
+               caphdr = (p80211_caphdr_t*) datap;
+
+               caphdr->version =       htonl(P80211CAPTURE_VERSION);
+               caphdr->length =        htonl(sizeof(p80211_caphdr_t));
+               caphdr->mactime =       __cpu_to_be64(rxdesc->time) * 1000;
+               caphdr->hosttime =      __cpu_to_be64(jiffies);
+               caphdr->phytype =       htonl(4); /* dss_dot11_b */
+               caphdr->channel =       htonl(hw->sniff_channel);
+               caphdr->datarate =      htonl(rxdesc->rate);
+               caphdr->antenna =       htonl(0); /* unknown */
+               caphdr->priority =      htonl(0); /* unknown */
+               caphdr->ssi_type =      htonl(3); /* rssi_raw */
+               caphdr->ssi_signal =    htonl(rxdesc->signal);
+               caphdr->ssi_noise =     htonl(rxdesc->silence);
+               caphdr->preamble =      htonl(0); /* unknown */
+               caphdr->encoding =      htonl(1); /* cck */
+       }
+
+       /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
+       datap = skb_put(skb, hdrlen);
+       memcpy( datap, &(rxdesc->frame_control), hdrlen);
+
+       /* If any, copy the data from the card to the skb */
+       if ( datalen > 0 )
+       {
+               datap = skb_put(skb, datalen);
+               memcpy(datap, rxfrm->data, datalen);
+
+               /* check for unencrypted stuff if WEP bit set. */
+               if (*(datap - hdrlen + 1) & 0x40) // wep set
+                 if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa))
+                   *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header!
+       }
+
+       if (hw->sniff_fcs) {
+               /* Set the FCS */
+               datap = skb_put(skb, WLAN_CRC_LEN);
+               memset( datap, 0xff, WLAN_CRC_LEN);
+       }
+
+       /* pass it back up */
+       prism2sta_ev_rx(wlandev, skb);
+
+       DBFEXIT;
+       return;
+}
+
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_info
+*
+* At this point we have a successful received a Prism2 info frame.
+*
+* Arguments:
+*      wlandev         wlan device
+*      usbin           ptr to the usb transfer buffer
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+{
+       DBFENTER;
+
+       usbin->infofrm.info.framelen = hfa384x2host_16(usbin->infofrm.info.framelen);
+       prism2sta_ev_info(wlandev, &usbin->infofrm.info);
+
+       DBFEXIT;
+}
+
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbout_callback
+*
+* Callback for URBs on the BULKOUT endpoint.
+*
+* Arguments:
+*      urb             ptr to the completed urb
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+#ifdef URB_ONLY_CALLBACK
+static void hfa384x_usbout_callback(struct urb *urb)
+#else
+static void hfa384x_usbout_callback(struct urb *urb, struct pt_regs *regs)
+#endif
+{
+       wlandevice_t            *wlandev = urb->context;
+       hfa384x_usbout_t        *usbout = urb->transfer_buffer;
+       DBFENTER;
+
+#ifdef DEBUG_USB
+       dbprint_urb(urb);
+#endif
+
+       if ( wlandev &&
+            wlandev->netdev ) {
+
+               switch(urb->status) {
+               case 0:
+                       hfa384x_usbout_tx(wlandev, usbout);
+                       break;
+
+               case -EPIPE:
+               {
+                       hfa384x_t *hw = wlandev->priv;
+                       WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
+                                        wlandev->netdev->name);
+                       if ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) )
+                               schedule_work(&hw->usb_work);
+                       ++(wlandev->linux_stats.tx_errors);
+                       break;
+               }
+
+               case -EPROTO:
+               case -ETIMEDOUT:
+               case -EILSEQ:
+               {
+                       hfa384x_t *hw = wlandev->priv;
+
+                       if ( !test_and_set_bit(THROTTLE_TX, &hw->usb_flags)
+                            && !timer_pending(&hw->throttle) ) {
+                               mod_timer(&hw->throttle,
+                                         jiffies + THROTTLE_JIFFIES);
+                       }
+                       ++(wlandev->linux_stats.tx_errors);
+                       netif_stop_queue(wlandev->netdev);
+                       break;
+               }
+
+               case -ENOENT:
+               case -ESHUTDOWN:
+                       /* Ignorable errors */
+                       break;
+
+               default:
+                       WLAN_LOG_INFO("unknown urb->status=%d\n", urb->status);
+                       ++(wlandev->linux_stats.tx_errors);
+                       break;
+               } /* switch */
+       }
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_ctlxout_callback
+*
+* Callback for control data on the BULKOUT endpoint.
+*
+* Arguments:
+*      urb             ptr to the completed urb
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+#ifdef URB_ONLY_CALLBACK
+static void hfa384x_ctlxout_callback(struct urb *urb)
+#else
+static void hfa384x_ctlxout_callback(struct urb *urb, struct pt_regs *regs)
+#endif
+{
+       hfa384x_t       *hw = urb->context;
+       int             delete_resptimer = 0;
+       int             timer_ok = 1;
+       int             run_queue = 0;
+       hfa384x_usbctlx_t       *ctlx;
+       unsigned long   flags;
+
+       DBFENTER;
+
+       WLAN_LOG_DEBUG(3,"urb->status=%d\n", urb->status);
+#ifdef DEBUG_USB
+       dbprint_urb(urb);
+#endif
+       if ( (urb->status == -ESHUTDOWN) ||
+            (urb->status == -ENODEV) ||
+            (hw == NULL) )
+               goto done;
+
+retry:
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       /*
+        * Only one CTLX at a time on the "active" list, and
+        * none at all if we are unplugged. However, we can
+        * rely on the disconnect function to clean everything
+        * up if someone unplugged the adapter.
+        */
+       if ( list_empty(&hw->ctlxq.active) ) {
+               spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+               goto done;
+       }
+
+       /*
+        * Having something on the "active" queue means
+        * that we have timers to worry about ...
+        */
+       if (del_timer(&hw->reqtimer) == 0) {
+               if (hw->req_timer_done == 0) {
+                       /*
+                        * This timer was actually running while we
+                        * were trying to delete it. Let it terminate
+                        * gracefully instead.
+                        */
+                       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+                       goto retry;
+               }
+       }
+       else {
+               hw->req_timer_done = 1;
+       }
+
+       ctlx = get_active_ctlx(hw);
+
+       if ( urb->status == 0 ) {
+               /* Request portion of a CTLX is successful */
+               switch ( ctlx->state ) {
+               case CTLX_REQ_SUBMITTED:
+                       /* This OUT-ACK received before IN */
+                       ctlx->state = CTLX_REQ_COMPLETE;
+                       break;
+
+               case CTLX_RESP_COMPLETE:
+                       /* IN already received before this OUT-ACK,
+                        * so this command must now be complete.
+                        */
+                       ctlx->state = CTLX_COMPLETE;
+                       unlocked_usbctlx_complete(hw, ctlx);
+                       run_queue = 1;
+                       break;
+
+               default:
+                       /* This is NOT a valid CTLX "success" state! */
+                       WLAN_LOG_ERROR(
+                           "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
+                           hfa384x2host_16(ctlx->outbuf.type),
+                           ctlxstr(ctlx->state), urb->status);
+                       break;
+               } /* switch */
+       } else {
+               /* If the pipe has stalled then we need to reset it */
+               if ( (urb->status == -EPIPE) &&
+                     !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) ) {
+                       WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
+                                        hw->wlandev->netdev->name);
+                       schedule_work(&hw->usb_work);
+               }
+
+               /* If someone cancels the OUT URB then its status
+                * should be either -ECONNRESET or -ENOENT.
+                */
+               ctlx->state = CTLX_REQ_FAILED;
+               unlocked_usbctlx_complete(hw, ctlx);
+               delete_resptimer = 1;
+               run_queue = 1;
+       }
+
+ delresp:
+       if (delete_resptimer) {
+               if ((timer_ok = del_timer(&hw->resptimer)) != 0) {
+                       hw->resp_timer_done = 1;
+               }
+       }
+
+       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+       if ( !timer_ok && (hw->resp_timer_done == 0) ) {
+               spin_lock_irqsave(&hw->ctlxq.lock, flags);
+               goto delresp;
+       }
+
+       if (run_queue)
+               hfa384x_usbctlxq_run(hw);
+
+ done:
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_reqtimerfn
+*
+* Timer response function for CTLX request timeouts.  If this
+* function is called, it means that the callback for the OUT
+* URB containing a Prism2.x XXX_Request was never called.
+*
+* Arguments:
+*      data            a ptr to the hfa384x_t
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_usbctlx_reqtimerfn(unsigned long data)
+{
+       hfa384x_t       *hw = (hfa384x_t*)data;
+       unsigned long   flags;
+       DBFENTER;
+
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       hw->req_timer_done = 1;
+
+       /* Removing the hardware automatically empties
+        * the active list ...
+        */
+       if ( !list_empty(&hw->ctlxq.active) )
+       {
+               /*
+                * We must ensure that our URB is removed from
+                * the system, if it hasn't already expired.
+                */
+               hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
+               if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS)
+               {
+                       hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
+
+                       ctlx->state = CTLX_REQ_FAILED;
+
+                       /* This URB was active, but has now been
+                        * cancelled. It will now have a status of
+                        * -ECONNRESET in the callback function.
+                        *
+                        * We are cancelling this CTLX, so we're
+                        * not going to need to wait for a response.
+                        * The URB's callback function will check
+                        * that this timer is truly dead.
+                        */
+                       if (del_timer(&hw->resptimer) != 0)
+                               hw->resp_timer_done = 1;
+               }
+       }
+
+       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_resptimerfn
+*
+* Timer response function for CTLX response timeouts.  If this
+* function is called, it means that the callback for the IN
+* URB containing a Prism2.x XXX_Response was never called.
+*
+* Arguments:
+*      data            a ptr to the hfa384x_t
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_usbctlx_resptimerfn(unsigned long data)
+{
+       hfa384x_t *hw = (hfa384x_t*)data;
+       unsigned long   flags;
+
+       DBFENTER;
+
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       hw->resp_timer_done = 1;
+
+       /* The active list will be empty if the
+        * adapter has been unplugged ...
+        */
+       if ( !list_empty(&hw->ctlxq.active) )
+       {
+               hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
+
+               if ( unlocked_usbctlx_cancel_async(hw, ctlx) == 0 )
+               {
+                       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+                       hfa384x_usbctlxq_run(hw);
+                       goto done;
+               }
+       }
+
+       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ done:
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_usb_throttlefn
+*
+*
+* Arguments:
+*      data    ptr to hw
+*
+* Returns:
+*      Nothing
+*
+* Side effects:
+*
+* Call context:
+*      Interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_usb_throttlefn(unsigned long data)
+{
+       hfa384x_t *hw = (hfa384x_t*)data;
+       unsigned long   flags;
+
+       DBFENTER;
+
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       /*
+        * We need to check BOTH the RX and the TX throttle controls,
+        * so we use the bitwise OR instead of the logical OR.
+        */
+       WLAN_LOG_DEBUG(3, "flags=0x%lx\n", hw->usb_flags);
+       if ( !hw->wlandev->hwremoved &&
+            (
+              (test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) &&
+              !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags))
+              |
+              (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) &&
+               !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags))
+            ) )
+       {
+               schedule_work(&hw->usb_work);
+       }
+
+       spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_submit
+*
+* Called from the doxxx functions to submit a CTLX to the queue
+*
+* Arguments:
+*      hw              ptr to the hw struct
+*      ctlx            ctlx structure to enqueue
+*
+* Returns:
+*      -ENODEV if the adapter is unplugged
+*      0
+*
+* Side effects:
+*
+* Call context:
+*      process or interrupt
+----------------------------------------------------------------*/
+static int
+hfa384x_usbctlx_submit(
+       hfa384x_t               *hw,
+       hfa384x_usbctlx_t       *ctlx)
+{
+       unsigned long flags;
+       int ret;
+
+       DBFENTER;
+
+       spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+       if (hw->wlandev->hwremoved) {
+               spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+               ret = -ENODEV;
+       } else {
+               ctlx->state = CTLX_PENDING;
+               list_add_tail(&ctlx->list, &hw->ctlxq.pending);
+
+               spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+               hfa384x_usbctlxq_run(hw);
+               ret = 0;
+       }
+
+       DBFEXIT;
+       return ret;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbout_tx
+*
+* At this point we have finished a send of a frame.  Mark the URB
+* as available and call ev_alloc to notify higher layers we're
+* ready for more.
+*
+* Arguments:
+*      wlandev         wlan device
+*      usbout          ptr to the usb transfer buffer
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout)
+{
+       DBFENTER;
+
+       prism2sta_ev_alloc(wlandev);
+
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_isgood_pdrcore
+*
+* Quick check of PDR codes.
+*
+* Arguments:
+*      pdrcode         PDR code number (host order)
+*
+* Returns:
+*      zero            not good.
+*      one             is good.
+*
+* Side effects:
+*
+* Call context:
+----------------------------------------------------------------*/
+static int
+hfa384x_isgood_pdrcode(UINT16 pdrcode)
+{
+       switch(pdrcode) {
+       case HFA384x_PDR_END_OF_PDA:
+       case HFA384x_PDR_PCB_PARTNUM:
+       case HFA384x_PDR_PDAVER:
+       case HFA384x_PDR_NIC_SERIAL:
+       case HFA384x_PDR_MKK_MEASUREMENTS:
+       case HFA384x_PDR_NIC_RAMSIZE:
+       case HFA384x_PDR_MFISUPRANGE:
+       case HFA384x_PDR_CFISUPRANGE:
+       case HFA384x_PDR_NICID:
+       case HFA384x_PDR_MAC_ADDRESS:
+       case HFA384x_PDR_REGDOMAIN:
+       case HFA384x_PDR_ALLOWED_CHANNEL:
+       case HFA384x_PDR_DEFAULT_CHANNEL:
+       case HFA384x_PDR_TEMPTYPE:
+       case HFA384x_PDR_IFR_SETTING:
+       case HFA384x_PDR_RFR_SETTING:
+       case HFA384x_PDR_HFA3861_BASELINE:
+       case HFA384x_PDR_HFA3861_SHADOW:
+       case HFA384x_PDR_HFA3861_IFRF:
+       case HFA384x_PDR_HFA3861_CHCALSP:
+       case HFA384x_PDR_HFA3861_CHCALI:
+       case HFA384x_PDR_3842_NIC_CONFIG:
+       case HFA384x_PDR_USB_ID:
+       case HFA384x_PDR_PCI_ID:
+       case HFA384x_PDR_PCI_IFCONF:
+       case HFA384x_PDR_PCI_PMCONF:
+       case HFA384x_PDR_RFENRGY:
+       case HFA384x_PDR_HFA3861_MANF_TESTSP:
+       case HFA384x_PDR_HFA3861_MANF_TESTI:
+               /* code is OK */
+               return 1;
+               break;
+       default:
+               if ( pdrcode < 0x1000 ) {
+                       /* code is OK, but we don't know exactly what it is */
+                       WLAN_LOG_DEBUG(3,
+                               "Encountered unknown PDR#=0x%04x, "
+                               "assuming it's ok.\n",
+                               pdrcode);
+                       return 1;
+               } else {
+                       /* bad code */
+                       WLAN_LOG_DEBUG(3,
+                               "Encountered unknown PDR#=0x%04x, "
+                               "(>=0x1000), assuming it's bad.\n",
+                               pdrcode);
+                       return 0;
+               }
+               break;
+       }
+       return 0; /* avoid compiler warnings */
+}
+
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
new file mode 100644 (file)
index 0000000..68121b9
--- /dev/null
@@ -0,0 +1,683 @@
+/* src/p80211/p80211conv.c
+*
+* Ether/802.11 conversions and packet buffer routines
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file defines the functions that perform Ethernet to/from
+* 802.11 frame conversions.
+*
+* --------------------------------------------------------------------
+*/
+/*================================================================*/
+/* System Includes */
+
+#define __NO_VERSION__         /* prevent the static definition */
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+
+#include <asm/byteorder.h>
+
+#include "version.h"
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211conv.h"
+#include "p80211mgmt.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211ioctl.h"
+#include "p80211req.h"
+
+
+/*================================================================*/
+/* Local Constants */
+
+/*================================================================*/
+/* Local Macros */
+
+
+/*================================================================*/
+/* Local Types */
+
+
+/*================================================================*/
+/* Local Static Definitions */
+
+static UINT8   oui_rfc1042[] = {0x00, 0x00, 0x00};
+static UINT8   oui_8021h[] = {0x00, 0x00, 0xf8};
+
+/*================================================================*/
+/* Local Function Declarations */
+
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* p80211pb_ether_to_80211
+*
+* Uses the contents of the ether frame and the etherconv setting
+* to build the elements of the 802.11 frame.
+*
+* We don't actually set
+* up the frame header here.  That's the MAC's job.  We're only handling
+* conversion of DIXII or 802.3+LLC frames to something that works
+* with 802.11.
+*
+* Note -- 802.11 header is NOT part of the skb.  Likewise, the 802.11
+*         FCS is also not present and will need to be added elsewhere.
+*
+* Arguments:
+*      ethconv         Conversion type to perform
+*      skb             skbuff containing the ether frame
+*       p80211_hdr      802.11 header
+*
+* Returns:
+*      0 on success, non-zero otherwise
+*
+* Call context:
+*      May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+int skb_ether_to_p80211( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
+{
+
+       UINT16          fc;
+       UINT16          proto;
+       wlan_ethhdr_t   e_hdr;
+       wlan_llc_t      *e_llc;
+       wlan_snap_t     *e_snap;
+       int foo;
+
+       DBFENTER;
+       memcpy(&e_hdr, skb->data, sizeof(e_hdr));
+
+       if (skb->len <= 0) {
+               WLAN_LOG_DEBUG(1, "zero-length skb!\n");
+               return 1;
+       }
+
+       if ( ethconv == WLAN_ETHCONV_ENCAP ) { /* simplest case */
+               WLAN_LOG_DEBUG(3, "ENCAP len: %d\n", skb->len);
+               /* here, we don't care what kind of ether frm. Just stick it */
+               /*  in the 80211 payload */
+               /* which is to say, leave the skb alone. */
+       } else {
+               /* step 1: classify ether frame, DIX or 802.3? */
+               proto = ntohs(e_hdr.type);
+               if ( proto <= 1500 ) {
+                       WLAN_LOG_DEBUG(3, "802.3 len: %d\n", skb->len);
+                        /* codes <= 1500 reserved for 802.3 lengths */
+                       /* it's 802.3, pass ether payload unchanged,  */
+
+                       /* trim off ethernet header */
+                       skb_pull(skb, WLAN_ETHHDR_LEN);
+
+                       /*   leave off any PAD octets.  */
+                       skb_trim(skb, proto);
+               } else {
+                       WLAN_LOG_DEBUG(3, "DIXII len: %d\n", skb->len);
+                       /* it's DIXII, time for some conversion */
+
+                       /* trim off ethernet header */
+                       skb_pull(skb, WLAN_ETHHDR_LEN);
+
+                       /* tack on SNAP */
+                       e_snap = (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t));
+                       e_snap->type = htons(proto);
+                       if ( ethconv == WLAN_ETHCONV_8021h && p80211_stt_findproto(proto) ) {
+                               memcpy( e_snap->oui, oui_8021h, WLAN_IEEE_OUI_LEN);
+                       } else {
+                               memcpy( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN);
+                       }
+
+                       /* tack on llc */
+                       e_llc = (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t));
+                       e_llc->dsap = 0xAA;     /* SNAP, see IEEE 802 */
+                       e_llc->ssap = 0xAA;
+                       e_llc->ctl = 0x03;
+
+               }
+       }
+
+       /* Set up the 802.11 header */
+       /* It's a data frame */
+       fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
+                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));
+
+       switch ( wlandev->macmode ) {
+       case WLAN_MACMODE_IBSS_STA:
+               memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
+               memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
+               memcpy(p80211_hdr->a3.a3, wlandev->bssid, WLAN_ADDR_LEN);
+               break;
+       case WLAN_MACMODE_ESS_STA:
+               fc |= host2ieee16(WLAN_SET_FC_TODS(1));
+               memcpy(p80211_hdr->a3.a1, wlandev->bssid, WLAN_ADDR_LEN);
+               memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
+               memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, WLAN_ADDR_LEN);
+               break;
+       case WLAN_MACMODE_ESS_AP:
+               fc |= host2ieee16(WLAN_SET_FC_FROMDS(1));
+               memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
+               memcpy(p80211_hdr->a3.a2, wlandev->bssid, WLAN_ADDR_LEN);
+               memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, WLAN_ADDR_LEN);
+               break;
+       default:
+               WLAN_LOG_ERROR("Error: Converting eth to wlan in unknown mode.\n");
+               return 1;
+               break;
+       }
+
+       p80211_wep->data = NULL;
+
+       if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && (wlandev->hostwep & HOSTWEP_ENCRYPT)) {
+               // XXXX need to pick keynum other than default?
+
+#if 1
+               p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
+#else
+               p80211_wep->data = skb->data;
+#endif
+
+               if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
+                                      skb->len,
+                               (wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK),
+                               p80211_wep->iv, p80211_wep->icv))) {
+                       WLAN_LOG_WARNING("Host en-WEP failed, dropping frame (%d).\n", foo);
+                       return 2;
+               }
+               fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
+       }
+
+
+       //      skb->nh.raw = skb->data;
+
+       p80211_hdr->a3.fc = fc;
+       p80211_hdr->a3.dur = 0;
+       p80211_hdr->a3.seq = 0;
+
+       DBFEXIT;
+       return 0;
+}
+
+/* jkriegl: from orinoco, modified */
+static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
+                              p80211_rxmeta_t *rxmeta)
+{
+        int i;
+
+        /* Gather wireless spy statistics: for each packet, compare the
+         * source address with out list, and if match, get the stats... */
+
+        for (i = 0; i < wlandev->spy_number; i++) {
+
+                if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) {
+                       memcpy(wlandev->spy_address[i], mac, ETH_ALEN);
+                        wlandev->spy_stat[i].level = rxmeta->signal;
+                        wlandev->spy_stat[i].noise = rxmeta->noise;
+                        wlandev->spy_stat[i].qual = (rxmeta->signal > rxmeta->noise) ? \
+                                                     (rxmeta->signal - rxmeta->noise) : 0;
+                        wlandev->spy_stat[i].updated = 0x7;
+                }
+        }
+}
+
+/*----------------------------------------------------------------
+* p80211pb_80211_to_ether
+*
+* Uses the contents of a received 802.11 frame and the etherconv
+* setting to build an ether frame.
+*
+* This function extracts the src and dest address from the 802.11
+* frame to use in the construction of the eth frame.
+*
+* Arguments:
+*      ethconv         Conversion type to perform
+*      skb             Packet buffer containing the 802.11 frame
+*
+* Returns:
+*      0 on success, non-zero otherwise
+*
+* Call context:
+*      May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb)
+{
+       netdevice_t     *netdev = wlandev->netdev;
+       UINT16          fc;
+       UINT            payload_length;
+       UINT            payload_offset;
+       UINT8           daddr[WLAN_ETHADDR_LEN];
+       UINT8           saddr[WLAN_ETHADDR_LEN];
+       p80211_hdr_t    *w_hdr;
+       wlan_ethhdr_t   *e_hdr;
+       wlan_llc_t      *e_llc;
+       wlan_snap_t     *e_snap;
+
+       int foo;
+
+       DBFENTER;
+
+       payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;
+       payload_offset = WLAN_HDR_A3_LEN;
+
+       w_hdr = (p80211_hdr_t *) skb->data;
+
+        /* setup some vars for convenience */
+       fc = ieee2host16(w_hdr->a3.fc);
+       if ( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
+               memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
+               memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
+       } else if( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1) ) {
+               memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
+               memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
+       } else if( (WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
+               memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
+               memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
+       } else {
+               payload_offset = WLAN_HDR_A4_LEN;
+               payload_length -= ( WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN );
+               if (payload_length < 0 ) {
+                       WLAN_LOG_ERROR("A4 frame too short!\n");
+                       return 1;
+               }
+               memcpy(daddr, w_hdr->a4.a3, WLAN_ETHADDR_LEN);
+               memcpy(saddr, w_hdr->a4.a4, WLAN_ETHADDR_LEN);
+       }
+
+       /* perform de-wep if necessary.. */
+       if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) {
+               if (payload_length <= 8) {
+                       WLAN_LOG_ERROR("WEP frame too short (%u).\n",
+                                       skb->len);
+                       return 1;
+               }
+               if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
+                                      payload_length - 8, -1,
+                                      skb->data + payload_offset,
+                                      skb->data + payload_offset + payload_length - 4))) {
+                       /* de-wep failed, drop skb. */
+                       WLAN_LOG_DEBUG(1, "Host de-WEP failed, dropping frame (%d).\n", foo);
+                       wlandev->rx.decrypt_err++;
+                       return 2;
+               }
+
+               /* subtract the IV+ICV length off the payload */
+               payload_length -= 8;
+               /* chop off the IV */
+               skb_pull(skb, 4);
+               /* chop off the ICV. */
+               skb_trim(skb, skb->len - 4);
+
+               wlandev->rx.decrypt++;
+       }
+
+       e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset);
+
+       e_llc = (wlan_llc_t *) (skb->data + payload_offset);
+       e_snap = (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));
+
+       /* Test for the various encodings */
+       if ( (payload_length >= sizeof(wlan_ethhdr_t)) &&
+            ( e_llc->dsap != 0xaa || e_llc->ssap != 0xaa ) &&
+            ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
+            (memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) {
+               WLAN_LOG_DEBUG(3, "802.3 ENCAP len: %d\n", payload_length);
+               /* 802.3 Encapsulated */
+               /* Test for an overlength frame */
+               if ( payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {
+                       /* A bogus length ethfrm has been encap'd. */
+                       /* Is someone trying an oflow attack? */
+                       WLAN_LOG_ERROR("ENCAP frame too large (%d > %d)\n",
+                               payload_length, netdev->mtu + WLAN_ETHHDR_LEN);
+                       return 1;
+               }
+
+               /* Chop off the 802.11 header.  it's already sane. */
+               skb_pull(skb, payload_offset);
+               /* chop off the 802.11 CRC */
+               skb_trim(skb, skb->len - WLAN_CRC_LEN);
+
+       } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
+                  (e_llc->dsap == 0xaa) &&
+                  (e_llc->ssap == 0xaa) &&
+                  (e_llc->ctl == 0x03) &&
+                  (((memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)==0) &&
+                   (ethconv == WLAN_ETHCONV_8021h) &&
+                   (p80211_stt_findproto(ieee2host16(e_snap->type)))) ||
+                   (memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)!=0)))
+       {
+               WLAN_LOG_DEBUG(3, "SNAP+RFC1042 len: %d\n", payload_length);
+               /* it's a SNAP + RFC1042 frame && protocol is in STT */
+               /* build 802.3 + RFC1042 */
+
+               /* Test for an overlength frame */
+               if ( payload_length > netdev->mtu ) {
+                       /* A bogus length ethfrm has been sent. */
+                       /* Is someone trying an oflow attack? */
+                       WLAN_LOG_ERROR("SNAP frame too large (%d > %d)\n",
+                               payload_length, netdev->mtu);
+                       return 1;
+               }
+
+               /* chop 802.11 header from skb. */
+               skb_pull(skb, payload_offset);
+
+               /* create 802.3 header at beginning of skb. */
+               e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
+               memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
+               memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
+               e_hdr->type = htons(payload_length);
+
+               /* chop off the 802.11 CRC */
+               skb_trim(skb, skb->len - WLAN_CRC_LEN);
+
+       }  else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
+                   (e_llc->dsap == 0xaa) &&
+                   (e_llc->ssap == 0xaa) &&
+                   (e_llc->ctl == 0x03) ) {
+               WLAN_LOG_DEBUG(3, "802.1h/RFC1042 len: %d\n", payload_length);
+               /* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */
+               /* build a DIXII + RFC894 */
+
+               /* Test for an overlength frame */
+               if ((payload_length - sizeof(wlan_llc_t) - sizeof(wlan_snap_t))
+                   > netdev->mtu) {
+                       /* A bogus length ethfrm has been sent. */
+                       /* Is someone trying an oflow attack? */
+                       WLAN_LOG_ERROR("DIXII frame too large (%ld > %d)\n",
+                                       (long int) (payload_length - sizeof(wlan_llc_t) -
+                                                   sizeof(wlan_snap_t)),
+                                       netdev->mtu);
+                       return 1;
+               }
+
+               /* chop 802.11 header from skb. */
+               skb_pull(skb, payload_offset);
+
+               /* chop llc header from skb. */
+               skb_pull(skb, sizeof(wlan_llc_t));
+
+               /* chop snap header from skb. */
+               skb_pull(skb, sizeof(wlan_snap_t));
+
+               /* create 802.3 header at beginning of skb. */
+               e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
+               e_hdr->type = e_snap->type;
+               memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
+               memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
+
+               /* chop off the 802.11 CRC */
+               skb_trim(skb, skb->len - WLAN_CRC_LEN);
+       } else {
+               WLAN_LOG_DEBUG(3, "NON-ENCAP len: %d\n", payload_length);
+               /* any NON-ENCAP */
+               /* it's a generic 80211+LLC or IPX 'Raw 802.3' */
+               /*  build an 802.3 frame */
+               /* allocate space and setup hostbuf */
+
+               /* Test for an overlength frame */
+               if ( payload_length > netdev->mtu ) {
+                       /* A bogus length ethfrm has been sent. */
+                       /* Is someone trying an oflow attack? */
+                       WLAN_LOG_ERROR("OTHER frame too large (%d > %d)\n",
+                               payload_length,
+                               netdev->mtu);
+                       return 1;
+               }
+
+               /* Chop off the 802.11 header. */
+               skb_pull(skb, payload_offset);
+
+               /* create 802.3 header at beginning of skb. */
+               e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
+               memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
+               memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
+               e_hdr->type = htons(payload_length);
+
+               /* chop off the 802.11 CRC */
+               skb_trim(skb, skb->len - WLAN_CRC_LEN);
+
+       }
+
+       skb->protocol = eth_type_trans(skb, netdev);
+       skb_reset_mac_header(skb);
+
+        /* jkriegl: process signal and noise as set in hfa384x_int_rx() */
+       /* jkriegl: only process signal/noise if requested by iwspy */
+        if (wlandev->spy_number)
+                orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, P80211SKB_RXMETA(skb));
+
+       /* Free the metadata */
+       p80211skb_rxmeta_detach(skb);
+
+       DBFEXIT;
+       return 0;
+}
+
+/*----------------------------------------------------------------
+* p80211_stt_findproto
+*
+* Searches the 802.1h Selective Translation Table for a given
+* protocol.
+*
+* Arguments:
+*      proto   protocl number (in host order) to search for.
+*
+* Returns:
+*      1 - if the table is empty or a match is found.
+*      0 - if the table is non-empty and a match is not found.
+*
+* Call context:
+*      May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+int p80211_stt_findproto(UINT16 proto)
+{
+       /* Always return found for now.  This is the behavior used by the */
+       /*  Zoom Win95 driver when 802.1h mode is selected */
+       /* TODO: If necessary, add an actual search we'll probably
+                need this to match the CMAC's way of doing things.
+                Need to do some testing to confirm.
+       */
+
+       if (proto == 0x80f3)  /* APPLETALK */
+               return 1;
+
+       return 0;
+}
+
+/*----------------------------------------------------------------
+* p80211skb_rxmeta_detach
+*
+* Disconnects the frmmeta and rxmeta from an skb.
+*
+* Arguments:
+*      wlandev         The wlandev this skb belongs to.
+*      skb             The skb we're attaching to.
+*
+* Returns:
+*      0 on success, non-zero otherwise
+*
+* Call context:
+*      May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+void
+p80211skb_rxmeta_detach(struct sk_buff *skb)
+{
+       p80211_rxmeta_t         *rxmeta;
+       p80211_frmmeta_t        *frmmeta;
+
+       DBFENTER;
+       /* Sanity checks */
+       if ( skb==NULL ) {                      /* bad skb */
+               WLAN_LOG_DEBUG(1, "Called w/ null skb.\n");
+               goto exit;
+       }
+       frmmeta = P80211SKB_FRMMETA(skb);
+       if ( frmmeta == NULL ) {                /* no magic */
+               WLAN_LOG_DEBUG(1, "Called w/ bad frmmeta magic.\n");
+               goto exit;
+       }
+       rxmeta = frmmeta->rx;
+       if ( rxmeta == NULL ) {                 /* bad meta ptr */
+               WLAN_LOG_DEBUG(1, "Called w/ bad rxmeta ptr.\n");
+               goto exit;
+       }
+
+       /* Free rxmeta */
+       kfree(rxmeta);
+
+       /* Clear skb->cb */
+       memset(skb->cb, 0, sizeof(skb->cb));
+exit:
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* p80211skb_rxmeta_attach
+*
+* Allocates a p80211rxmeta structure, initializes it, and attaches
+* it to an skb.
+*
+* Arguments:
+*      wlandev         The wlandev this skb belongs to.
+*      skb             The skb we're attaching to.
+*
+* Returns:
+*      0 on success, non-zero otherwise
+*
+* Call context:
+*      May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+int
+p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
+{
+       int                     result = 0;
+       p80211_rxmeta_t         *rxmeta;
+       p80211_frmmeta_t        *frmmeta;
+
+       DBFENTER;
+
+       /* If these already have metadata, we error out! */
+       if (P80211SKB_RXMETA(skb) != NULL) {
+               WLAN_LOG_ERROR("%s: RXmeta already attached!\n",
+                               wlandev->name);
+               result = 0;
+               goto exit;
+       }
+
+       /* Allocate the rxmeta */
+       rxmeta = kmalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC);
+
+       if ( rxmeta == NULL ) {
+               WLAN_LOG_ERROR("%s: Failed to allocate rxmeta.\n",
+                               wlandev->name);
+               result = 1;
+               goto exit;
+       }
+
+       /* Initialize the rxmeta */
+       memset(rxmeta, 0, sizeof(p80211_rxmeta_t));
+       rxmeta->wlandev = wlandev;
+       rxmeta->hosttime = jiffies;
+
+       /* Overlay a frmmeta_t onto skb->cb */
+       memset(skb->cb, 0, sizeof(p80211_frmmeta_t));
+       frmmeta = (p80211_frmmeta_t*)(skb->cb);
+       frmmeta->magic = P80211_FRMMETA_MAGIC;
+       frmmeta->rx = rxmeta;
+exit:
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* p80211skb_free
+*
+* Frees an entire p80211skb by checking and freeing the meta struct
+* and then freeing the skb.
+*
+* Arguments:
+*      wlandev         The wlandev this skb belongs to.
+*      skb             The skb we're attaching to.
+*
+* Returns:
+*      0 on success, non-zero otherwise
+*
+* Call context:
+*      May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+void
+p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
+{
+       p80211_frmmeta_t        *meta;
+       DBFENTER;
+       meta = P80211SKB_FRMMETA(skb);
+       if ( meta && meta->rx) {
+               p80211skb_rxmeta_detach(skb);
+       } else {
+               WLAN_LOG_ERROR("Freeing an skb (%p) w/ no frmmeta.\n", skb);
+       }
+
+       dev_kfree_skb(skb);
+       DBFEXIT;
+       return;
+}
diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h
new file mode 100644 (file)
index 0000000..3f5ab57
--- /dev/null
@@ -0,0 +1,186 @@
+/* p80211conv.h
+*
+* Ether/802.11 conversions and packet buffer routines
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares the functions, types and macros that perform
+* Ethernet to/from 802.11 frame conversions.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _LINUX_P80211CONV_H
+#define _LINUX_P80211CONV_H
+
+/*================================================================*/
+/* Constants */
+
+#define WLAN_ETHADDR_LEN       6
+#define WLAN_IEEE_OUI_LEN      3
+
+#define WLAN_ETHCONV_ENCAP     1
+#define WLAN_ETHCONV_RFC1042   2
+#define WLAN_ETHCONV_8021h     3
+
+#define WLAN_MIN_ETHFRM_LEN    60
+#define WLAN_MAX_ETHFRM_LEN    1514
+#define WLAN_ETHHDR_LEN                14
+
+#define P80211CAPTURE_VERSION  0x80211001
+
+/*================================================================*/
+/* Macros */
+
+#define        P80211_FRMMETA_MAGIC            0x802110
+
+#define P80211SKB_FRMMETA(s) \
+       (((((p80211_frmmeta_t*)((s)->cb))->magic)==P80211_FRMMETA_MAGIC) ? \
+               ((p80211_frmmeta_t*)((s)->cb)) : \
+               (NULL))
+
+#define P80211SKB_RXMETA(s) \
+       (P80211SKB_FRMMETA((s)) ?  P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t*)(NULL)))
+
+typedef struct p80211_rxmeta
+{
+       struct wlandevice       *wlandev;
+
+       UINT64  mactime;        /* Hi-rez MAC-supplied time value */
+       UINT64  hosttime;       /* Best-rez host supplied time value */
+
+       UINT    rxrate;         /* Receive data rate in 100kbps */
+       UINT    priority;       /* 0-15, 0=contention, 6=CF */
+       INT     signal;         /* An SSI, see p80211netdev.h */
+       INT     noise;          /* An SSI, see p80211netdev.h */
+       UINT    channel;        /* Receive channel (mostly for snifs) */
+       UINT    preamble;       /* P80211ENUM_preambletype_* */
+       UINT    encoding;       /* P80211ENUM_encoding_* */
+
+} p80211_rxmeta_t;
+
+typedef struct p80211_frmmeta
+{
+       UINT                    magic;
+       p80211_rxmeta_t         *rx;
+} p80211_frmmeta_t;
+
+void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb);
+int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb);
+void p80211skb_rxmeta_detach(struct sk_buff *skb);
+
+/*================================================================*/
+/* Types */
+
+/*
+ * Frame capture header.  (See doc/capturefrm.txt)
+ */
+typedef struct p80211_caphdr
+{
+       UINT32          version;
+       UINT32          length;
+       UINT64          mactime;
+       UINT64          hosttime;
+       UINT32          phytype;
+       UINT32          channel;
+       UINT32          datarate;
+       UINT32          antenna;
+       UINT32          priority;
+       UINT32          ssi_type;
+       INT32           ssi_signal;
+       INT32           ssi_noise;
+       UINT32          preamble;
+       UINT32          encoding;
+} p80211_caphdr_t;
+
+/* buffer free method pointer type */
+typedef void (* freebuf_method_t)(void *buf, int size);
+
+typedef struct p80211_metawep {
+       void  *data;
+       UINT8 iv[4];
+       UINT8 icv[4];
+} p80211_metawep_t;
+
+/* local ether header type */
+typedef struct wlan_ethhdr
+{
+       UINT8   daddr[WLAN_ETHADDR_LEN];
+       UINT8   saddr[WLAN_ETHADDR_LEN];
+       UINT16  type;
+} __WLAN_ATTRIB_PACK__ wlan_ethhdr_t;
+
+/* local llc header type */
+typedef struct wlan_llc
+{
+       UINT8   dsap;
+       UINT8   ssap;
+       UINT8   ctl;
+} __WLAN_ATTRIB_PACK__ wlan_llc_t;
+
+/* local snap header type */
+typedef struct wlan_snap
+{
+       UINT8   oui[WLAN_IEEE_OUI_LEN];
+       UINT16  type;
+} __WLAN_ATTRIB_PACK__ wlan_snap_t;
+
+/* Circular include trick */
+struct wlandevice;
+
+/*================================================================*/
+/* Externs */
+
+/*================================================================*/
+/*Function Declarations */
+
+int skb_p80211_to_ether( struct wlandevice *wlandev, UINT32 ethconv,
+                        struct sk_buff *skb);
+int skb_ether_to_p80211( struct wlandevice *wlandev, UINT32 ethconv,
+                        struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+                        p80211_metawep_t *p80211_wep );
+
+int p80211_stt_findproto(UINT16 proto);
+int p80211_stt_addproto(UINT16 proto);
+
+#endif
diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h
new file mode 100644 (file)
index 0000000..b7b0872
--- /dev/null
@@ -0,0 +1,299 @@
+/* p80211hdr.h
+*
+* Macros, types, and functions for handling 802.11 MAC headers
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares the constants and types used in the interface
+* between a wlan driver and the user mode utilities.
+*
+* Note:
+*  - Constant values are always in HOST byte order.  To assign
+*    values to multi-byte fields they _must_ be converted to
+*    ieee byte order.  To retrieve multi-byte values from incoming
+*    frames, they must be converted to host order.
+*
+* All functions declared here are implemented in p80211.c
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211HDR_H
+#define _P80211HDR_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef  _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+
+/*================================================================*/
+/* Constants */
+
+/*--- Sizes -----------------------------------------------*/
+#define WLAN_ADDR_LEN                  6
+#define WLAN_CRC_LEN                   4
+#define WLAN_BSSID_LEN                 6
+#define WLAN_BSS_TS_LEN                        8
+#define WLAN_HDR_A3_LEN                        24
+#define WLAN_HDR_A4_LEN                        30
+#define WLAN_SSID_MAXLEN               32
+#define WLAN_DATA_MAXLEN               2312
+#define WLAN_A3FR_MAXLEN               (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
+#define WLAN_A4FR_MAXLEN               (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
+#define WLAN_BEACON_FR_MAXLEN          (WLAN_HDR_A3_LEN + 334)
+#define WLAN_ATIM_FR_MAXLEN            (WLAN_HDR_A3_LEN + 0)
+#define WLAN_DISASSOC_FR_MAXLEN                (WLAN_HDR_A3_LEN + 2)
+#define WLAN_ASSOCREQ_FR_MAXLEN                (WLAN_HDR_A3_LEN + 48)
+#define WLAN_ASSOCRESP_FR_MAXLEN       (WLAN_HDR_A3_LEN + 16)
+#define WLAN_REASSOCREQ_FR_MAXLEN      (WLAN_HDR_A3_LEN + 54)
+#define WLAN_REASSOCRESP_FR_MAXLEN     (WLAN_HDR_A3_LEN + 16)
+#define WLAN_PROBEREQ_FR_MAXLEN                (WLAN_HDR_A3_LEN + 44)
+#define WLAN_PROBERESP_FR_MAXLEN       (WLAN_HDR_A3_LEN + 78)
+#define WLAN_AUTHEN_FR_MAXLEN          (WLAN_HDR_A3_LEN + 261)
+#define WLAN_DEAUTHEN_FR_MAXLEN                (WLAN_HDR_A3_LEN + 2)
+#define WLAN_WEP_NKEYS                 4
+#define WLAN_WEP_MAXKEYLEN             13
+#define WLAN_CHALLENGE_IE_LEN          130
+#define WLAN_CHALLENGE_LEN             128
+#define WLAN_WEP_IV_LEN                        4
+#define WLAN_WEP_ICV_LEN               4
+
+/*--- Frame Control Field -------------------------------------*/
+/* Frame Types */
+#define WLAN_FTYPE_MGMT                        0x00
+#define WLAN_FTYPE_CTL                 0x01
+#define WLAN_FTYPE_DATA                        0x02
+
+/* Frame subtypes */
+/* Management */
+#define WLAN_FSTYPE_ASSOCREQ           0x00
+#define WLAN_FSTYPE_ASSOCRESP          0x01
+#define WLAN_FSTYPE_REASSOCREQ         0x02
+#define WLAN_FSTYPE_REASSOCRESP                0x03
+#define WLAN_FSTYPE_PROBEREQ           0x04
+#define WLAN_FSTYPE_PROBERESP          0x05
+#define WLAN_FSTYPE_BEACON             0x08
+#define WLAN_FSTYPE_ATIM               0x09
+#define WLAN_FSTYPE_DISASSOC           0x0a
+#define WLAN_FSTYPE_AUTHEN             0x0b
+#define WLAN_FSTYPE_DEAUTHEN           0x0c
+
+/* Control */
+#define WLAN_FSTYPE_BLOCKACKREQ                0x8
+#define WLAN_FSTYPE_BLOCKACK           0x9
+#define WLAN_FSTYPE_PSPOLL             0x0a
+#define WLAN_FSTYPE_RTS                        0x0b
+#define WLAN_FSTYPE_CTS                        0x0c
+#define WLAN_FSTYPE_ACK                        0x0d
+#define WLAN_FSTYPE_CFEND              0x0e
+#define WLAN_FSTYPE_CFENDCFACK         0x0f
+
+/* Data */
+#define WLAN_FSTYPE_DATAONLY           0x00
+#define WLAN_FSTYPE_DATA_CFACK         0x01
+#define WLAN_FSTYPE_DATA_CFPOLL                0x02
+#define WLAN_FSTYPE_DATA_CFACK_CFPOLL  0x03
+#define WLAN_FSTYPE_NULL               0x04
+#define WLAN_FSTYPE_CFACK              0x05
+#define WLAN_FSTYPE_CFPOLL             0x06
+#define WLAN_FSTYPE_CFACK_CFPOLL       0x07
+
+
+/*================================================================*/
+/* Macros */
+
+/*--- FC Macros ----------------------------------------------*/
+/* Macros to get/set the bitfields of the Frame Control Field */
+/*  GET_FC_??? - takes the host byte-order value of an FC     */
+/*               and retrieves the value of one of the        */
+/*               bitfields and moves that value so its lsb is */
+/*               in bit 0.                                    */
+/*  SET_FC_??? - takes a host order value for one of the FC   */
+/*               bitfields and moves it to the proper bit     */
+/*               location for ORing into a host order FC.     */
+/*               To send the FC produced from SET_FC_???,     */
+/*               one must put the bytes in IEEE order.        */
+/*  e.g.                                                      */
+/*     printf("the frame subtype is %x",                      */
+/*                 GET_FC_FTYPE( ieee2host( rx.fc )))         */
+/*                                                            */
+/*     tx.fc = host2ieee( SET_FC_FTYPE(WLAN_FTYP_CTL) |       */
+/*                        SET_FC_FSTYPE(WLAN_FSTYPE_RTS) );   */
+/*------------------------------------------------------------*/
+
+#define WLAN_GET_FC_PVER(n)     (((UINT16)(n)) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n)   ((((UINT16)(n)) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)  ((((UINT16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n)    ((((UINT16)(n)) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n)  ((((UINT16)(n)) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((UINT16)(n)) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n)   ((((UINT16)(n)) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n)  ((((UINT16)(n)) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((UINT16)(n)) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n)   ((((UINT16)(n)) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n)   ((((UINT16)(n)) & (BIT15)) >> 15)
+
+#define WLAN_SET_FC_PVER(n)    ((UINT16)(n))
+#define WLAN_SET_FC_FTYPE(n)   (((UINT16)(n)) << 2)
+#define WLAN_SET_FC_FSTYPE(n)  (((UINT16)(n)) << 4)
+#define WLAN_SET_FC_TODS(n)    (((UINT16)(n)) << 8)
+#define WLAN_SET_FC_FROMDS(n)  (((UINT16)(n)) << 9)
+#define WLAN_SET_FC_MOREFRAG(n) (((UINT16)(n)) << 10)
+#define WLAN_SET_FC_RETRY(n)   (((UINT16)(n)) << 11)
+#define WLAN_SET_FC_PWRMGT(n)  (((UINT16)(n)) << 12)
+#define WLAN_SET_FC_MOREDATA(n) (((UINT16)(n)) << 13)
+#define WLAN_SET_FC_ISWEP(n)   (((UINT16)(n)) << 14)
+#define WLAN_SET_FC_ORDER(n)   (((UINT16)(n)) << 15)
+
+/*--- Duration Macros ----------------------------------------*/
+/* Macros to get/set the bitfields of the Duration Field      */
+/*  - the duration value is only valid when bit15 is zero     */
+/*  - the firmware handles these values, so I'm not going     */
+/*    these macros right now.                                 */
+/*------------------------------------------------------------*/
+
+/*--- Sequence Control  Macros -------------------------------*/
+/* Macros to get/set the bitfields of the Sequence Control    */
+/* Field.                                                     */
+/*------------------------------------------------------------*/
+#define WLAN_GET_SEQ_FRGNUM(n) (((UINT16)(n)) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((UINT16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
+
+/*--- Data ptr macro -----------------------------------------*/
+/* Creates a UINT8* to the data portion of a frame            */
+/* Assumes you're passing in a ptr to the beginning of the hdr*/
+/*------------------------------------------------------------*/
+#define WLAN_HDR_A3_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A3_LEN)
+#define WLAN_HDR_A4_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A4_LEN)
+
+#define DOT11_RATE5_ISBASIC_GET(r)     (((UINT8)(r)) & BIT7)
+
+/*================================================================*/
+/* Types */
+
+/* BSS Timestamp */
+typedef UINT8 wlan_bss_ts_t[WLAN_BSS_TS_LEN];
+
+/* Generic 802.11 Header types */
+
+typedef struct p80211_hdr_a3
+{
+       UINT16  fc;
+       UINT16  dur;
+       UINT8   a1[WLAN_ADDR_LEN];
+       UINT8   a2[WLAN_ADDR_LEN];
+       UINT8   a3[WLAN_ADDR_LEN];
+       UINT16  seq;
+} __WLAN_ATTRIB_PACK__ p80211_hdr_a3_t;
+
+typedef struct p80211_hdr_a4
+{
+       UINT16  fc;
+       UINT16  dur;
+       UINT8   a1[WLAN_ADDR_LEN];
+       UINT8   a2[WLAN_ADDR_LEN];
+       UINT8   a3[WLAN_ADDR_LEN];
+       UINT16  seq;
+       UINT8   a4[WLAN_ADDR_LEN];
+} __WLAN_ATTRIB_PACK__ p80211_hdr_a4_t;
+
+typedef union p80211_hdr
+{
+       p80211_hdr_a3_t         a3;
+       p80211_hdr_a4_t         a4;
+} __WLAN_ATTRIB_PACK__ p80211_hdr_t;
+
+
+/*================================================================*/
+/* Extern Declarations */
+
+
+/*================================================================*/
+/* Function Declarations */
+
+/* Frame and header lenght macros */
+
+#define WLAN_CTL_FRAMELEN(fstype) (\
+       (fstype) == WLAN_FSTYPE_BLOCKACKREQ     ? 24 : \
+       (fstype) == WLAN_FSTYPE_BLOCKACK        ? 152 : \
+       (fstype) == WLAN_FSTYPE_PSPOLL          ? 20 : \
+       (fstype) == WLAN_FSTYPE_RTS             ? 20 : \
+       (fstype) == WLAN_FSTYPE_CTS             ? 14 : \
+       (fstype) == WLAN_FSTYPE_ACK             ? 14 : \
+       (fstype) == WLAN_FSTYPE_CFEND           ? 20 : \
+       (fstype) == WLAN_FSTYPE_CFENDCFACK      ? 20 : 4)
+
+#define WLAN_FCS_LEN                   4
+
+/* ftcl in HOST order */
+inline static UINT16 p80211_headerlen(UINT16 fctl)
+{
+       UINT16 hdrlen = 0;
+
+       switch ( WLAN_GET_FC_FTYPE(fctl) ) {
+       case WLAN_FTYPE_MGMT:
+               hdrlen = WLAN_HDR_A3_LEN;
+               break;
+       case WLAN_FTYPE_DATA:
+               hdrlen = WLAN_HDR_A3_LEN;
+               if ( WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl) ) {
+                       hdrlen += WLAN_ADDR_LEN;
+               }
+               break;
+       case WLAN_FTYPE_CTL:
+               hdrlen = WLAN_CTL_FRAMELEN(WLAN_GET_FC_FSTYPE(fctl)) -
+                       WLAN_FCS_LEN;
+               break;
+       default:
+               hdrlen = WLAN_HDR_A3_LEN;
+       }
+
+       return hdrlen;
+}
+
+#endif /* _P80211HDR_H */
diff --git a/drivers/staging/wlan-ng/p80211ioctl.h b/drivers/staging/wlan-ng/p80211ioctl.h
new file mode 100644 (file)
index 0000000..25b2ea8
--- /dev/null
@@ -0,0 +1,123 @@
+/* p80211ioctl.h
+*
+* Declares constants and types for the p80211 ioctls
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+*  While this file is called 'ioctl' is purpose goes a little beyond
+*  that.  This file defines the types and contants used to implement
+*  the p80211 request/confirm/indicate interfaces on Linux.  The
+*  request/confirm interface is, in fact, normally implemented as an
+*  ioctl.  The indicate interface on the other hand, is implemented
+*  using the Linux 'netlink' interface.
+*
+*  The reason I say that request/confirm is 'normally' implemented
+*  via ioctl is that we're reserving the right to be able to send
+*  request commands via the netlink interface.  This will be necessary
+*  if we ever need to send request messages when there aren't any
+*  wlan network devices present (i.e. sending a message that only p80211
+*  cares about.
+* --------------------------------------------------------------------
+*/
+
+
+#ifndef _P80211IOCTL_H
+#define _P80211IOCTL_H
+
+/*================================================================*/
+/* Constants */
+
+/*----------------------------------------------------------------*/
+/* p80211 ioctl "request" codes.  See argument 2 of ioctl(2). */
+
+#define P80211_IFTEST          (SIOCDEVPRIVATE + 0)
+#define P80211_IFREQ           (SIOCDEVPRIVATE + 1)
+
+/*----------------------------------------------------------------*/
+/* Magic number, a quick test to see we're getting the desired struct */
+
+#define P80211_IOCTL_MAGIC     (0x4a2d464dUL)
+
+/*----------------------------------------------------------------*/
+/* Netlink protocol numbers for the indication interface */
+
+#define P80211_NL_SOCK_IND     NETLINK_USERSOCK
+
+/*----------------------------------------------------------------*/
+/* Netlink multicast bits for different types of messages */
+
+#define P80211_NL_MCAST_GRP_MLME       BIT0    /* Local station messages */
+#define P80211_NL_MCAST_GRP_SNIFF      BIT1    /* Sniffer messages */
+#define P80211_NL_MCAST_GRP_DIST       BIT2    /* Distribution system messages */
+
+/*================================================================*/
+/* Macros */
+
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* A ptr to the following structure type is passed as the third */
+/*  argument to the ioctl system call when issuing a request to */
+/*  the p80211 module. */
+
+typedef struct p80211ioctl_req
+{
+       char    name[WLAN_DEVNAMELEN_MAX];
+       caddr_t data;
+       UINT32  magic;
+       UINT16  len;
+       UINT32  result;
+} __WLAN_ATTRIB_PACK__ p80211ioctl_req_t;
+
+
+/*================================================================*/
+/* Extern Declarations */
+
+
+/*================================================================*/
+/* Function Declarations */
+
+
+#endif /* _P80211IOCTL_H */
diff --git a/drivers/staging/wlan-ng/p80211meta.h b/drivers/staging/wlan-ng/p80211meta.h
new file mode 100644 (file)
index 0000000..5cb3f5a
--- /dev/null
@@ -0,0 +1,169 @@
+/* p80211meta.h
+*
+* Macros, constants, types, and funcs for p80211 metadata
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares some of the constants and types used in various
+* parts of the linux-wlan system.
+*
+* Notes:
+*   - Constant values are always in HOST byte order.
+*
+* All functions and statics declared here are implemented in p80211types.c
+*   --------------------------------------------------------------------
+*/
+
+#ifndef _P80211META_H
+#define _P80211META_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Macros */
+
+/*----------------------------------------------------------------*/
+/* The following macros are used to ensure consistent naming */
+/*  conventions for all the different metadata lists. */
+
+#define MKREQMETANAME(name)            p80211meta_ ## req ## _ ## name
+#define MKINDMETANAME(name)            p80211meta_ ## ind ## _ ## name
+#define MKMIBMETANAME(name)            p80211meta_ ## mib ## _ ## name
+#define MKGRPMETANAME(name)            p80211meta_ ## grp ## _ ## name
+
+#define MKREQMETASIZE(name)            p80211meta_ ## req ## _ ## name ## _ ## size
+#define MKINDMETASIZE(name)            p80211meta_ ## ind ## _ ## name ## _ ## size
+#define MKMIBMETASIZE(name)            p80211meta_ ## mib ## _ ## name ## _ ## size
+#define MKGRPMETASIZE(name)            p80211meta_ ## grp ## _ ## name ## _ ## size
+
+#define GETMETASIZE(aptr)              (**((UINT32**)(aptr)))
+
+/*----------------------------------------------------------------*/
+/* The following ifdef depends on the following defines: */
+/*  P80211_NOINCLUDESTRINGS - if defined, all metadata name fields */
+/*                               are empty strings */
+
+#ifdef P80211_NOINCLUDESTRINGS
+       #define MKITEMNAME(s)   ("")
+#else
+       #define MKITEMNAME(s)   (s)
+#endif
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* The following structure types are used for the metadata */
+/* representation of category list metadata, group list metadata, */
+/* and data item metadata for both Mib and Messages. */
+
+typedef struct p80211meta
+{
+       char                    *name;          /* data item name */
+       UINT32                  did;            /* partial did */
+       UINT32                  flags;          /* set of various flag bits */
+       UINT32                  min;            /* min value of a BOUNDEDINT */
+       UINT32                  max;            /* max value of a BOUNDEDINT */
+
+       UINT32                  maxlen;         /* maxlen of a OCTETSTR or DISPLAYSTR */
+       UINT32                  minlen;         /* minlen of a OCTETSTR or DISPLAYSTR */
+       p80211enum_t            *enumptr;       /* ptr to the enum type for ENUMINT */
+       p80211_totext_t         totextptr;      /* ptr to totext conversion function */
+       p80211_fromtext_t       fromtextptr;    /* ptr to totext conversion function */
+       p80211_valid_t          validfunptr;    /* ptr to totext conversion function */
+} p80211meta_t;
+
+typedef struct grplistitem
+{
+       char            *name;
+       p80211meta_t    *itemlist;
+} grplistitem_t;
+
+typedef struct catlistitem
+{
+       char            *name;
+       grplistitem_t   *grplist;
+} catlistitem_t;
+
+/*================================================================*/
+/* Extern Declarations */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Function Declarations */
+
+/*----------------------------------------------------------------*/
+/* */
+UINT32 p80211_text2did(catlistitem_t *catlist, char *catname, char *grpname, char *itemname);
+UINT32 p80211_text2catdid(catlistitem_t *list, char *name );
+UINT32 p80211_text2grpdid(grplistitem_t *list, char *name );
+UINT32 p80211_text2itemdid(p80211meta_t *list, char *name );
+UINT32 p80211_isvalid_did( catlistitem_t *catlist, UINT32 did );
+UINT32 p80211_isvalid_catdid( catlistitem_t *catlist, UINT32 did );
+UINT32 p80211_isvalid_grpdid( catlistitem_t *catlist, UINT32 did );
+UINT32 p80211_isvalid_itemdid( catlistitem_t *catlist, UINT32 did );
+catlistitem_t *p80211_did2cat( catlistitem_t *catlist, UINT32 did );
+grplistitem_t *p80211_did2grp( catlistitem_t *catlist, UINT32 did );
+p80211meta_t *p80211_did2item( catlistitem_t *catlist, UINT32 did );
+UINT32 p80211item_maxdatalen( struct catlistitem *metalist, UINT32 did );
+UINT32 p80211_metaname2did(struct catlistitem *metalist, char *itemname);
+UINT32 p80211item_getoffset( struct catlistitem *metalist, UINT32 did );
+int p80211item_gettype(p80211meta_t *meta);
+
+#endif /* _P80211META_H */
diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h
new file mode 100644 (file)
index 0000000..2c7f435
--- /dev/null
@@ -0,0 +1,2524 @@
+/* This file is GENERATED AUTOMATICALLY.  DO NOT EDIT OR MODIFY.
+* --------------------------------------------------------------------
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211MKMETADEF_H
+#define _P80211MKMETADEF_H
+
+
+#define DIDmsg_cat_dot11req \
+                       P80211DID_MKSECTION(1)
+#define DIDmsg_dot11req_mibget \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmsg_dot11req_mibget_mibattribute \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_mibget_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_mibset \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2))
+#define DIDmsg_dot11req_mibset_mibattribute \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_mibset_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_powermgmt \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3))
+#define DIDmsg_dot11req_powermgmt_powermgmtmode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_powermgmt_wakeup \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_powermgmt_receivedtims \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_powermgmt_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_scan \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4))
+#define DIDmsg_dot11req_scan_bsstype \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_scan_bssid \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_scan_ssid \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_scan_scantype \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_scan_probedelay \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_scan_channellist \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_scan_minchanneltime \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_scan_maxchanneltime \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_dot11req_scan_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_dot11req_scan_numbss \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_dot11req_scan_append \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_dot11req_scan_results \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5))
+#define DIDmsg_dot11req_scan_results_bssindex \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_signal \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_noise \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_bssid \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_ssid \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_bsstype \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_beaconperiod \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_dtimperiod \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_timestamp \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_localtime \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_fhdwelltime \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(12) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_fhhopset \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(13) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_fhhoppattern \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(14) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_fhhopindex \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(15) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_dschannel \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(16) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpcount \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(17) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpperiod \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(18) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpmaxduration \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(19) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpdurremaining \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(20) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_ibssatimwindow \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(21) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpollable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(22) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpollreq \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(23) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_privacy \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(24) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate1 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(25) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate2 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(26) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate3 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(27) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate4 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(28) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate5 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(29) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate6 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(30) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate7 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(31) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate8 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(32) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate1 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(33) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate2 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(34) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate3 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(35) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate4 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(36) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate5 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(37) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate6 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(38) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate7 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(39) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate8 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(40) | 0x00000000)
+#define DIDmsg_dot11req_join \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6))
+#define DIDmsg_dot11req_join_bssid \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_join_joinfailuretimeout \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate1 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate2 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate3 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate4 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate5 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate6 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate7 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate8 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate1 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate2 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(12) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate3 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(13) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate4 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(14) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate5 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(15) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate6 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(16) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate7 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(17) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate8 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(18) | 0x00000000)
+#define DIDmsg_dot11req_join_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(19) | 0x00000000)
+#define DIDmsg_dot11req_authenticate \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(7))
+#define DIDmsg_dot11req_authenticate_peerstaaddress \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_authenticate_authenticationtype \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_authenticate_authenticationfailuretimeout \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_authenticate_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_deauthenticate \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(8))
+#define DIDmsg_dot11req_deauthenticate_peerstaaddress \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_deauthenticate_reasoncode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_deauthenticate_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_associate \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(9))
+#define DIDmsg_dot11req_associate_peerstaaddress \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_associate_associatefailuretimeout \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_associate_cfpollable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_associate_cfpollreq \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_associate_privacy \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_associate_listeninterval \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_associate_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_reassociate \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(10))
+#define DIDmsg_dot11req_reassociate_newapaddress \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_reassociatefailuretimeout \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_cfpollable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_cfpollreq \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_privacy \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_listeninterval \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_disassociate \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(11))
+#define DIDmsg_dot11req_disassociate_peerstaaddress \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(11) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_disassociate_reasoncode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(11) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_disassociate_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(11) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_reset \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(12))
+#define DIDmsg_dot11req_reset_setdefaultmib \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(12) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_reset_macaddress \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(12) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_reset_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(12) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_start \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13))
+#define DIDmsg_dot11req_start_ssid \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_start_bsstype \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_start_beaconperiod \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_start_dtimperiod \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_start_cfpperiod \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_start_cfpmaxduration \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_start_fhdwelltime \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_start_fhhopset \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_dot11req_start_fhhoppattern \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_dot11req_start_dschannel \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_dot11req_start_ibssatimwindow \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_dot11req_start_probedelay \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(12) | 0x00000000)
+#define DIDmsg_dot11req_start_cfpollable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(13) | 0x00000000)
+#define DIDmsg_dot11req_start_cfpollreq \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(14) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate1 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(15) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate2 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(16) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate3 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(17) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate4 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(18) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate5 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(19) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate6 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(20) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate7 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(21) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate8 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(22) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate1 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(23) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate2 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(24) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate3 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(25) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate4 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(26) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate5 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(27) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate6 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(28) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate7 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(29) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate8 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(30) | 0x00000000)
+#define DIDmsg_dot11req_start_resultcode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(31) | 0x00000000)
+#define DIDmsg_cat_dot11ind \
+                       P80211DID_MKSECTION(2)
+#define DIDmsg_dot11ind_authenticate \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmsg_dot11ind_authenticate_peerstaaddress \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_authenticate_authenticationtype \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11ind_deauthenticate \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2))
+#define DIDmsg_dot11ind_deauthenticate_peerstaaddress \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_deauthenticate_reasoncode \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11ind_associate \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3))
+#define DIDmsg_dot11ind_associate_peerstaaddress \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_associate_aid \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11ind_reassociate \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(4))
+#define DIDmsg_dot11ind_reassociate_peerstaaddress \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_reassociate_aid \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11ind_reassociate_oldapaddress \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11ind_disassociate \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(5))
+#define DIDmsg_dot11ind_disassociate_peerstaaddress \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_disassociate_reasoncode \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_cat_lnxreq \
+                       P80211DID_MKSECTION(3)
+#define DIDmsg_lnxreq_ifstate \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmsg_lnxreq_ifstate_ifstate \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_ifstate_resultcode \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2))
+#define DIDmsg_lnxreq_wlansniff_enable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_channel \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_prismheader \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_wlanheader \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_keepwepflags \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_stripfcs \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_packet_trunc \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_resultcode \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_lnxreq_hostwep \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3))
+#define DIDmsg_lnxreq_hostwep_resultcode \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_hostwep_decrypt \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_hostwep_encrypt \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4))
+#define DIDmsg_lnxreq_commsquality_resultcode \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality_dbm \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality_link \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality_level \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality_noise \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_lnxreq_autojoin \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5))
+#define DIDmsg_lnxreq_autojoin_ssid \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_autojoin_authtype \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_autojoin_resultcode \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_cat_lnxind \
+                       P80211DID_MKSECTION(4)
+#define DIDmsg_lnxind_wlansniffrm \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmsg_lnxind_wlansniffrm_hosttime \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_mactime \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_channel \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_rssi \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_sq \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_signal \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_noise \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_rate \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_istx \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_frmlen \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_lnxind_roam \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(2))
+#define DIDmsg_lnxind_roam_reason \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_cat_p2req \
+                       P80211DID_MKSECTION(5)
+#define DIDmsg_p2req_join \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmsg_p2req_join_bssid \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate3 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate4 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate5 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate6 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate7 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate8 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate3 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(12) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate4 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(13) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate5 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(14) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate6 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(15) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate7 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(16) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate8 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(17) | 0x00000000)
+#define DIDmsg_p2req_join_ssid \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(18) | 0x00000000)
+#define DIDmsg_p2req_join_channel \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(19) | 0x00000000)
+#define DIDmsg_p2req_join_authtype \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(20) | 0x00000000)
+#define DIDmsg_p2req_join_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(21) | 0x00000000)
+#define DIDmsg_p2req_readpda \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2))
+#define DIDmsg_p2req_readpda_pda \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_readpda_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_readcis \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3))
+#define DIDmsg_p2req_readcis_cis \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_readcis_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_auxport_state \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(4))
+#define DIDmsg_p2req_auxport_state_enable \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_auxport_state_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_auxport_read \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5))
+#define DIDmsg_p2req_auxport_read_addr \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_auxport_read_len \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_auxport_read_data \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_auxport_read_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_auxport_write \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6))
+#define DIDmsg_p2req_auxport_write_addr \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_auxport_write_len \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_auxport_write_data \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_auxport_write_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_low_level \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7))
+#define DIDmsg_p2req_low_level_command \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_low_level_param0 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_low_level_param1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_low_level_param2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_low_level_resp0 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_p2req_low_level_resp1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_p2req_low_level_resp2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_p2req_low_level_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_p2req_test_command \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(8))
+#define DIDmsg_p2req_test_command_testcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_test_command_testparam \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_test_command_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_test_command_status \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_test_command_resp0 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_p2req_test_command_resp1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_p2req_test_command_resp2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_p2req_mmi_read \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(9))
+#define DIDmsg_p2req_mmi_read_addr \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_mmi_read_value \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_mmi_read_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_mmi_write \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(10))
+#define DIDmsg_p2req_mmi_write_addr \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_mmi_write_data \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_mmi_write_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_ramdl_state \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(11))
+#define DIDmsg_p2req_ramdl_state_enable \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(11) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_ramdl_state_exeaddr \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(11) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_ramdl_state_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(11) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_ramdl_write \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(12))
+#define DIDmsg_p2req_ramdl_write_addr \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(12) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_ramdl_write_len \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(12) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_ramdl_write_data \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(12) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_ramdl_write_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(12) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_flashdl_state \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(13))
+#define DIDmsg_p2req_flashdl_state_enable \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_flashdl_state_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(13) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_flashdl_write \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(14))
+#define DIDmsg_p2req_flashdl_write_addr \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(14) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_flashdl_write_len \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(14) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_flashdl_write_data \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(14) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_flashdl_write_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(14) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_mm_state \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(15))
+#define DIDmsg_p2req_mm_state_enable \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(15) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_mm_state_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(15) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_dump_state \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(16))
+#define DIDmsg_p2req_dump_state_level \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(16) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_dump_state_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(16) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_channel_info \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(17))
+#define DIDmsg_p2req_channel_info_channellist \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(17) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_channel_info_channeldwelltime \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(17) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_channel_info_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(17) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_channel_info_numchinfo \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(17) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(18))
+#define DIDmsg_p2req_channel_info_results_channel \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(18) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(18) | \
+                       P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_avgnoiselevel \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(18) | \
+                       P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_peaknoiselevel \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(18) | \
+                       P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_bssactive \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(18) | \
+                       P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_pcfactive \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(18) | \
+                       P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_p2req_enable \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(19))
+#define DIDmsg_p2req_enable_resultcode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(19) | \
+                       P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmib_cat_dot11smt \
+                       P80211DID_MKSECTION(1)
+#define DIDmib_dot11smt_p80211Table \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmib_dot11smt_p80211Table_p80211_ifstate \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2))
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11StationID \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11MediumOccupancyLimit \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPollable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPPeriod \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPMaxDuration \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticationResponseTimeOut \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(6) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11PrivacyOptionImplemented \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11PowerManagementMode \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(8) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredSSID \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(9) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(11) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11BeaconPeriod \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(12) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DTIMPeriod \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(13) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11AssociationResponseTimeOut \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(14) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateReason \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(15) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateStation \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(16) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateReason \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(17) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateStation \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(18) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStatus \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(19) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStation \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(20) | 0x10000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3))
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm1 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(1) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable1 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(2) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm2 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(3) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable2 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(4) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm3 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(5) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable3 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(6) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm4 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(7) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable4 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(8) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm5 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(9) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable5 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(10) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm6 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(11) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable6 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(12) | 0x1c000000)
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4))
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(1) | 0x0c000000)
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(2) | 0x0c000000)
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(3) | 0x0c000000)
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3 \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(4) | 0x0c000000)
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5))
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingIndex \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingAddress \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(2) | 0x1c000000)
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingWEPOn \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(3) | 0x1c000000)
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingValue \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(4) | 0x1c000000)
+#define DIDmib_dot11smt_dot11PrivacyTable \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6))
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPKeyMappingLength \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPICVErrorCount \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPExcludedCount \
+                       (P80211DID_MKSECTION(1) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_cat_dot11mac \
+                       P80211DID_MKSECTION(2)
+#define DIDmib_dot11mac_dot11OperationTable \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11MaxReceiveLifetime \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11ManufacturerID \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11ProductID \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2))
+#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFragmentCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastTransmittedFrameCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11FailedCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11RetryCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11MultipleRetryCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11FrameDuplicateCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11RTSSuccessCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11RTSFailureCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11ACKFailureCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11ReceivedFragmentCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(10) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastReceivedFrameCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(11) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11FCSErrorCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(12) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFrameCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(13) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11WEPUndecryptableCount \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(14) | 0x10000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3))
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(2) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(3) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(4) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(5) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(6) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(7) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(8) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(9) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(10) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(11) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(12) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(13) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(14) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(15) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(16) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(17) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(18) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(19) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(20) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(21) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(22) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(23) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(24) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(25) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(26) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(27) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(28) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(29) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(30) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(31) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32 \
+                       (P80211DID_MKSECTION(2) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(32) | 0x1c000000)
+#define DIDmib_cat_dot11phy \
+                       P80211DID_MKSECTION(3)
+#define DIDmib_dot11phy_dot11PhyOperationTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11PHYType \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11CurrentRegDomain \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11TempType \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityPresent \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityEnabled \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyAntennaTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2))
+#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentTxAntenna \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11DiversitySupport \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentRxAntenna \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3))
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11NumberSupportedPowerLevels \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1 \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2 \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3 \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4 \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5 \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6 \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7 \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8 \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4))
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11HopTime \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentChannelNumber \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11MaxDwellTime \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentDwellTime \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentSet \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentPattern \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(6) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentIndex \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(7) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5))
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CCAModeSupported \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentCCAMode \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11EDThreshold \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11ShortPreambleOptionImplemented \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11PBCCOptionImplemented \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyIRTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(6))
+#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMax \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMax \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMin \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMin \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11phy_dot11RegDomainsSupportedTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(7))
+#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportIndex \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportValue \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(2) | 0x14000000)
+#define DIDmib_dot11phy_dot11AntennasListTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(8))
+#define DIDmib_dot11phy_dot11AntennasListTable_dot11AntennaListIndex \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedTxAntenna \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(2) | 0x1c000000)
+#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedRxAntenna \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(3) | 0x1c000000)
+#define DIDmib_dot11phy_dot11AntennasListTable_dot11DiversitySelectionRx \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(8) | \
+                       P80211DID_MKITEM(4) | 0x1c000000)
+#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(9))
+#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxIndex \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxValue \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(9) | \
+                       P80211DID_MKITEM(2) | 0x14000000)
+#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(10))
+#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxIndex \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxValue \
+                       (P80211DID_MKSECTION(3) | \
+                       P80211DID_MKGROUP(10) | \
+                       P80211DID_MKITEM(2) | 0x14000000)
+#define DIDmib_cat_lnx \
+                       P80211DID_MKSECTION(4)
+#define DIDmib_lnx_lnxConfigTable \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmib_lnx_lnxConfigTable_lnxRSNAIE \
+                       (P80211DID_MKSECTION(4) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_cat_p2 \
+                       P80211DID_MKSECTION(5)
+#define DIDmib_p2_p2Table \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1))
+#define DIDmib_p2_p2Table_p2MMTx \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_p2_p2Table_p2EarlyBeacon \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_p2_p2Table_p2ReceivedFrameStatistics \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_p2_p2Table_p2CommunicationTallies \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_p2_p2Table_p2Authenticated \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_p2_p2Table_p2Associated \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_p2_p2Table_p2PowerSaveUserCount \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_p2_p2Table_p2Comment \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(8) | 0x18000000)
+#define DIDmib_p2_p2Table_p2AccessMode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(9) | 0x18000000)
+#define DIDmib_p2_p2Table_p2AccessAllow \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_p2_p2Table_p2AccessDeny \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(11) | 0x18000000)
+#define DIDmib_p2_p2Table_p2ChannelInfoResults \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(1) | \
+                       P80211DID_MKITEM(12) | 0x10000000)
+#define DIDmib_p2_p2Static \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2))
+#define DIDmib_p2_p2Static_p2CnfPortType \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnMACAddress \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfDesiredSSID \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnChannel \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnSSID \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnATIMWindow \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(6) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfSystemScale \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(7) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMaxDataLength \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(8) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(9) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfPMEnabled \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfPMEPS \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(11) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMulticastReceive \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(12) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMaxSleepDuration \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(13) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfPMHoldoverDuration \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(14) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnName \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(15) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnDTIMPeriod \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(16) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(17) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(18) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress3 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(19) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress4 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(20) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress5 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(21) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress6 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(22) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMulticastPMBuffering \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(23) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKeyID \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(24) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey0 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(25) | 0x08000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(26) | 0x08000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(27) | 0x08000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey3 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(28) | 0x08000000)
+#define DIDmib_p2_p2Static_p2CnfWEPFlags \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(29) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfAuthentication \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(30) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMaxAssociatedStations \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(31) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfTxControl \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(32) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfRoamingMode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(33) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfHostAuthentication \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(34) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfRcvCrcError \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(35) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfAltRetryCount \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(36) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfBeaconInterval \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(37) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMediumOccupancyLimit \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(38) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfCFPPeriod \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(39) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfCFPMaxDuration \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(40) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfCFPFlags \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(41) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfSTAPCFInfo \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(42) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfPriorityQUsage \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(43) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfTIMCtrl \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(44) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfThirty2Tally \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(45) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfEnhSecurity \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(46) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfShortPreamble \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(47) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfExcludeLongPreamble \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(48) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfAuthenticationRspTO \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(49) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfBasicRates \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(50) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfSupportedRates \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(2) | \
+                       P80211DID_MKITEM(51) | 0x18000000)
+#define DIDmib_p2_p2Dynamic \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3))
+#define DIDmib_p2_p2Dynamic_p2CreateIBSS \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2PromiscuousMode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold0 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(6) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(7) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(8) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold3 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(9) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold4 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold5 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(11) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold6 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(12) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold0 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(13) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(14) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(15) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold3 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(16) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold4 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(17) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold5 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(18) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold6 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(19) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl0 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(20) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(21) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(22) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl3 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(23) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl4 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(24) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl5 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(25) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl6 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(3) | \
+                       P80211DID_MKITEM(26) | 0x18000000)
+#define DIDmib_p2_p2Behavior \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(4))
+#define DIDmib_p2_p2Behavior_p2TickTime \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(4) | \
+                       P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_p2_p2NIC \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5))
+#define DIDmib_p2_p2NIC_p2MaxLoadTime \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2DLBufferPage \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2DLBufferOffset \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2DLBufferLength \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2PRIIdentity \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2PRISupRange \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2CFIActRanges \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2NICSerialNumber \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2NICIdentity \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2MFISupRange \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(10) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2CFISupRange \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(11) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2ChannelList \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(12) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2RegulatoryDomains \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(13) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2TempType \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(14) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2STAIdentity \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(15) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2STASupRange \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(16) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2MFIActRanges \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(17) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2STACFIActRanges \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(18) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2BuildSequence \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(19) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2PrimaryFWID \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(20) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2SecondaryFWID \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(21) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2TertiaryFWID \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(5) | \
+                       P80211DID_MKITEM(22) | 0x10000000)
+#define DIDmib_p2_p2MAC \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6))
+#define DIDmib_p2_p2MAC_p2PortStatus \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentSSID \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentBSSID \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CommsQuality \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CommsQualityCQ \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CommsQualityASL \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CommsQualityANL \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2dbmCommsQuality \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2dbmCommsQualityCQ \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2dbmCommsQualityASL \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(10) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2dbmCommsQualityANL \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(11) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(12) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentBeaconInterval \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(13) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2StaCurrentScaleThresholds \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(14) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2APCurrentScaleThresholds \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(15) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2ProtocolRspTime \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(16) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2ShortRetryLimit \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(17) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2LongRetryLimit \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(18) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2MaxTransmitLifetime \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(19) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2MaxReceiveLifetime \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(20) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CFPollable \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(21) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2AuthenticationAlgorithms \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(22) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2PrivacyOptionImplemented \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(23) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate1 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(24) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate2 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(25) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate3 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(26) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate4 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(27) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate5 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(28) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate6 \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(29) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2OwnMACAddress \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(6) | \
+                       P80211DID_MKITEM(30) | 0x10000000)
+#define DIDmib_p2_p2Modem \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7))
+#define DIDmib_p2_p2Modem_p2PHYType \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2CurrentChannel \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2CurrentPowerState \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2CCAMode \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2SupportedDataRates \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2TxPowerMax \
+                       (P80211DID_MKSECTION(5) | \
+                       P80211DID_MKGROUP(7) | \
+                       P80211DID_MKITEM(6) | 0x18000000)
+#endif
diff --git a/drivers/staging/wlan-ng/p80211metamib.h b/drivers/staging/wlan-ng/p80211metamib.h
new file mode 100644 (file)
index 0000000..19867fd
--- /dev/null
@@ -0,0 +1,105 @@
+/* p80211metamib.h
+*
+* Macros, const, types, and funcs for p80211 mib metadata
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares some of the constants and types used in various
+* parts of the linux-wlan system.
+*
+* Notes:
+*   - Constant values are always in HOST byte order.
+*
+* All functions and statics declared here are implemented in p80211types.c
+*   --------------------------------------------------------------------
+*/
+
+#ifndef _P80211METAMIB_H
+#define _P80211METAMIB_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Macros */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Extern Declarations */
+
+/*----------------------------------------------------------------*/
+/* The following is the external declaration for the mib */
+/* category metadata list */
+
+extern catlistitem_t mib_catlist[];
+extern UINT32 mib_catlist_size;
+
+
+/*================================================================*/
+/* Function Declarations */
+
+/*----------------------------------------------------------------*/
+/* */
+
+#endif /* _P80211METAMIB_H */
diff --git a/drivers/staging/wlan-ng/p80211metamsg.h b/drivers/staging/wlan-ng/p80211metamsg.h
new file mode 100644 (file)
index 0000000..4d6dfcc
--- /dev/null
@@ -0,0 +1,105 @@
+/* p80211metamsg.h
+*
+* Macros, const, types, and funcs for p80211 msg metadata
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares some of the constants and types used in various
+* parts of the linux-wlan system.
+*
+* Notes:
+*   - Constant values are always in HOST byte order.
+*
+* All functions and statics declared here are implemented in p80211types.c
+*   --------------------------------------------------------------------
+*/
+
+#ifndef _P80211METAMSG_H
+#define _P80211METAMSG_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Macros */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Extern Declarations */
+
+/*----------------------------------------------------------------*/
+/* The following is the external declaration for the message */
+/* category metadata list */
+
+extern catlistitem_t msg_catlist[];
+extern UINT32 msg_catlist_size;
+
+
+/*================================================================*/
+/* Function Declarations */
+
+/*----------------------------------------------------------------*/
+/* */
+
+#endif /* _P80211METAMSG_H */
diff --git a/drivers/staging/wlan-ng/p80211metastruct.h b/drivers/staging/wlan-ng/p80211metastruct.h
new file mode 100644 (file)
index 0000000..715f4b2
--- /dev/null
@@ -0,0 +1,644 @@
+/* This file is GENERATED AUTOMATICALLY.  DO NOT EDIT OR MODIFY.
+* --------------------------------------------------------------------
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211MKMETASTRUCT_H
+#define _P80211MKMETASTRUCT_H
+
+
+typedef struct p80211msg_dot11req_mibget
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_unk392_t     mibattribute    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibget_t;
+
+typedef struct p80211msg_dot11req_mibset
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_unk392_t     mibattribute    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibset_t;
+
+typedef struct p80211msg_dot11req_powermgmt
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     powermgmtmode   ;
+       p80211item_uint32_t     wakeup  ;
+       p80211item_uint32_t     receivedtims    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_powermgmt_t;
+
+typedef struct p80211msg_dot11req_scan
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     bsstype ;
+       p80211item_pstr6_t      bssid   ;
+       UINT8   pad_0C[1]       ;
+       p80211item_pstr32_t     ssid    ;
+       UINT8   pad_1D[3]       ;
+       p80211item_uint32_t     scantype        ;
+       p80211item_uint32_t     probedelay      ;
+       p80211item_pstr14_t     channellist     ;
+       UINT8   pad_2C[1]       ;
+       p80211item_uint32_t     minchanneltime  ;
+       p80211item_uint32_t     maxchanneltime  ;
+       p80211item_uint32_t     resultcode      ;
+       p80211item_uint32_t     numbss  ;
+       p80211item_uint32_t     append  ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_t;
+
+typedef struct p80211msg_dot11req_scan_results
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     bssindex        ;
+       p80211item_uint32_t     resultcode      ;
+       p80211item_uint32_t     signal  ;
+       p80211item_uint32_t     noise   ;
+       p80211item_pstr6_t      bssid   ;
+       UINT8   pad_3C[1]       ;
+       p80211item_pstr32_t     ssid    ;
+       UINT8   pad_4D[3]       ;
+       p80211item_uint32_t     bsstype ;
+       p80211item_uint32_t     beaconperiod    ;
+       p80211item_uint32_t     dtimperiod      ;
+       p80211item_uint32_t     timestamp       ;
+       p80211item_uint32_t     localtime       ;
+       p80211item_uint32_t     fhdwelltime     ;
+       p80211item_uint32_t     fhhopset        ;
+       p80211item_uint32_t     fhhoppattern    ;
+       p80211item_uint32_t     fhhopindex      ;
+       p80211item_uint32_t     dschannel       ;
+       p80211item_uint32_t     cfpcount        ;
+       p80211item_uint32_t     cfpperiod       ;
+       p80211item_uint32_t     cfpmaxduration  ;
+       p80211item_uint32_t     cfpdurremaining ;
+       p80211item_uint32_t     ibssatimwindow  ;
+       p80211item_uint32_t     cfpollable      ;
+       p80211item_uint32_t     cfpollreq       ;
+       p80211item_uint32_t     privacy ;
+       p80211item_uint32_t     basicrate1      ;
+       p80211item_uint32_t     basicrate2      ;
+       p80211item_uint32_t     basicrate3      ;
+       p80211item_uint32_t     basicrate4      ;
+       p80211item_uint32_t     basicrate5      ;
+       p80211item_uint32_t     basicrate6      ;
+       p80211item_uint32_t     basicrate7      ;
+       p80211item_uint32_t     basicrate8      ;
+       p80211item_uint32_t     supprate1       ;
+       p80211item_uint32_t     supprate2       ;
+       p80211item_uint32_t     supprate3       ;
+       p80211item_uint32_t     supprate4       ;
+       p80211item_uint32_t     supprate5       ;
+       p80211item_uint32_t     supprate6       ;
+       p80211item_uint32_t     supprate7       ;
+       p80211item_uint32_t     supprate8       ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_results_t;
+
+typedef struct p80211msg_dot11req_join
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      bssid   ;
+       UINT8   pad_5C[1]       ;
+       p80211item_uint32_t     joinfailuretimeout      ;
+       p80211item_uint32_t     basicrate1      ;
+       p80211item_uint32_t     basicrate2      ;
+       p80211item_uint32_t     basicrate3      ;
+       p80211item_uint32_t     basicrate4      ;
+       p80211item_uint32_t     basicrate5      ;
+       p80211item_uint32_t     basicrate6      ;
+       p80211item_uint32_t     basicrate7      ;
+       p80211item_uint32_t     basicrate8      ;
+       p80211item_uint32_t     operationalrate1        ;
+       p80211item_uint32_t     operationalrate2        ;
+       p80211item_uint32_t     operationalrate3        ;
+       p80211item_uint32_t     operationalrate4        ;
+       p80211item_uint32_t     operationalrate5        ;
+       p80211item_uint32_t     operationalrate6        ;
+       p80211item_uint32_t     operationalrate7        ;
+       p80211item_uint32_t     operationalrate8        ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_join_t;
+
+typedef struct p80211msg_dot11req_authenticate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      peerstaaddress  ;
+       UINT8   pad_6C[1]       ;
+       p80211item_uint32_t     authenticationtype      ;
+       p80211item_uint32_t     authenticationfailuretimeout    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_authenticate_t;
+
+typedef struct p80211msg_dot11req_deauthenticate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      peerstaaddress  ;
+       UINT8   pad_7C[1]       ;
+       p80211item_uint32_t     reasoncode      ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_deauthenticate_t;
+
+typedef struct p80211msg_dot11req_associate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      peerstaaddress  ;
+       UINT8   pad_8C[1]       ;
+       p80211item_uint32_t     associatefailuretimeout ;
+       p80211item_uint32_t     cfpollable      ;
+       p80211item_uint32_t     cfpollreq       ;
+       p80211item_uint32_t     privacy ;
+       p80211item_uint32_t     listeninterval  ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_associate_t;
+
+typedef struct p80211msg_dot11req_reassociate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      newapaddress    ;
+       UINT8   pad_9C[1]       ;
+       p80211item_uint32_t     reassociatefailuretimeout       ;
+       p80211item_uint32_t     cfpollable      ;
+       p80211item_uint32_t     cfpollreq       ;
+       p80211item_uint32_t     privacy ;
+       p80211item_uint32_t     listeninterval  ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reassociate_t;
+
+typedef struct p80211msg_dot11req_disassociate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      peerstaaddress  ;
+       UINT8   pad_10C[1]      ;
+       p80211item_uint32_t     reasoncode      ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_disassociate_t;
+
+typedef struct p80211msg_dot11req_reset
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     setdefaultmib   ;
+       p80211item_pstr6_t      macaddress      ;
+       UINT8   pad_11C[1]      ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reset_t;
+
+typedef struct p80211msg_dot11req_start
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr32_t     ssid    ;
+       UINT8   pad_12D[3]      ;
+       p80211item_uint32_t     bsstype ;
+       p80211item_uint32_t     beaconperiod    ;
+       p80211item_uint32_t     dtimperiod      ;
+       p80211item_uint32_t     cfpperiod       ;
+       p80211item_uint32_t     cfpmaxduration  ;
+       p80211item_uint32_t     fhdwelltime     ;
+       p80211item_uint32_t     fhhopset        ;
+       p80211item_uint32_t     fhhoppattern    ;
+       p80211item_uint32_t     dschannel       ;
+       p80211item_uint32_t     ibssatimwindow  ;
+       p80211item_uint32_t     probedelay      ;
+       p80211item_uint32_t     cfpollable      ;
+       p80211item_uint32_t     cfpollreq       ;
+       p80211item_uint32_t     basicrate1      ;
+       p80211item_uint32_t     basicrate2      ;
+       p80211item_uint32_t     basicrate3      ;
+       p80211item_uint32_t     basicrate4      ;
+       p80211item_uint32_t     basicrate5      ;
+       p80211item_uint32_t     basicrate6      ;
+       p80211item_uint32_t     basicrate7      ;
+       p80211item_uint32_t     basicrate8      ;
+       p80211item_uint32_t     operationalrate1        ;
+       p80211item_uint32_t     operationalrate2        ;
+       p80211item_uint32_t     operationalrate3        ;
+       p80211item_uint32_t     operationalrate4        ;
+       p80211item_uint32_t     operationalrate5        ;
+       p80211item_uint32_t     operationalrate6        ;
+       p80211item_uint32_t     operationalrate7        ;
+       p80211item_uint32_t     operationalrate8        ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_start_t;
+
+typedef struct p80211msg_dot11ind_authenticate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      peerstaaddress  ;
+       UINT8   pad_13C[1]      ;
+       p80211item_uint32_t     authenticationtype      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_authenticate_t;
+
+typedef struct p80211msg_dot11ind_deauthenticate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      peerstaaddress  ;
+       UINT8   pad_14C[1]      ;
+       p80211item_uint32_t     reasoncode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_deauthenticate_t;
+
+typedef struct p80211msg_dot11ind_associate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      peerstaaddress  ;
+       UINT8   pad_15C[1]      ;
+       p80211item_uint32_t     aid     ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_associate_t;
+
+typedef struct p80211msg_dot11ind_reassociate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      peerstaaddress  ;
+       UINT8   pad_16C[1]      ;
+       p80211item_uint32_t     aid     ;
+       p80211item_pstr6_t      oldapaddress    ;
+       UINT8   pad_17C[1]      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_reassociate_t;
+
+typedef struct p80211msg_dot11ind_disassociate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      peerstaaddress  ;
+       UINT8   pad_18C[1]      ;
+       p80211item_uint32_t     reasoncode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_disassociate_t;
+
+typedef struct p80211msg_lnxreq_ifstate
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     ifstate ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_ifstate_t;
+
+typedef struct p80211msg_lnxreq_wlansniff
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     enable  ;
+       p80211item_uint32_t     channel ;
+       p80211item_uint32_t     prismheader     ;
+       p80211item_uint32_t     wlanheader      ;
+       p80211item_uint32_t     keepwepflags    ;
+       p80211item_uint32_t     stripfcs        ;
+       p80211item_uint32_t     packet_trunc    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_wlansniff_t;
+
+typedef struct p80211msg_lnxreq_hostwep
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     resultcode      ;
+       p80211item_uint32_t     decrypt ;
+       p80211item_uint32_t     encrypt ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_hostwep_t;
+
+typedef struct p80211msg_lnxreq_commsquality
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     resultcode      ;
+       p80211item_uint32_t     dbm     ;
+       p80211item_uint32_t     link    ;
+       p80211item_uint32_t     level   ;
+       p80211item_uint32_t     noise   ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_commsquality_t;
+
+typedef struct p80211msg_lnxreq_autojoin
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr32_t     ssid    ;
+       UINT8   pad_19D[3]      ;
+       p80211item_uint32_t     authtype        ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_autojoin_t;
+
+typedef struct p80211msg_lnxind_wlansniffrm
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     hosttime        ;
+       p80211item_uint32_t     mactime ;
+       p80211item_uint32_t     channel ;
+       p80211item_uint32_t     rssi    ;
+       p80211item_uint32_t     sq      ;
+       p80211item_uint32_t     signal  ;
+       p80211item_uint32_t     noise   ;
+       p80211item_uint32_t     rate    ;
+       p80211item_uint32_t     istx    ;
+       p80211item_uint32_t     frmlen  ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_wlansniffrm_t;
+
+typedef struct p80211msg_lnxind_roam
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     reason  ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_roam_t;
+
+typedef struct p80211msg_p2req_join
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_pstr6_t      bssid   ;
+       UINT8   pad_20C[1]      ;
+       p80211item_uint32_t     basicrate1      ;
+       p80211item_uint32_t     basicrate2      ;
+       p80211item_uint32_t     basicrate3      ;
+       p80211item_uint32_t     basicrate4      ;
+       p80211item_uint32_t     basicrate5      ;
+       p80211item_uint32_t     basicrate6      ;
+       p80211item_uint32_t     basicrate7      ;
+       p80211item_uint32_t     basicrate8      ;
+       p80211item_uint32_t     operationalrate1        ;
+       p80211item_uint32_t     operationalrate2        ;
+       p80211item_uint32_t     operationalrate3        ;
+       p80211item_uint32_t     operationalrate4        ;
+       p80211item_uint32_t     operationalrate5        ;
+       p80211item_uint32_t     operationalrate6        ;
+       p80211item_uint32_t     operationalrate7        ;
+       p80211item_uint32_t     operationalrate8        ;
+       p80211item_pstr32_t     ssid    ;
+       UINT8   pad_21D[3]      ;
+       p80211item_uint32_t     channel ;
+       p80211item_uint32_t     authtype        ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_join_t;
+
+typedef struct p80211msg_p2req_readpda
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_unk1024_t    pda     ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readpda_t;
+
+typedef struct p80211msg_p2req_readcis
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_unk1024_t    cis     ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readcis_t;
+
+typedef struct p80211msg_p2req_auxport_state
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     enable  ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_state_t;
+
+typedef struct p80211msg_p2req_auxport_read
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     addr    ;
+       p80211item_uint32_t     len     ;
+       p80211item_unk1024_t    data    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_read_t;
+
+typedef struct p80211msg_p2req_auxport_write
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     addr    ;
+       p80211item_uint32_t     len     ;
+       p80211item_unk1024_t    data    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_write_t;
+
+typedef struct p80211msg_p2req_low_level
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     command ;
+       p80211item_uint32_t     param0  ;
+       p80211item_uint32_t     param1  ;
+       p80211item_uint32_t     param2  ;
+       p80211item_uint32_t     resp0   ;
+       p80211item_uint32_t     resp1   ;
+       p80211item_uint32_t     resp2   ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_low_level_t;
+
+typedef struct p80211msg_p2req_test_command
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     testcode        ;
+       p80211item_uint32_t     testparam       ;
+       p80211item_uint32_t     resultcode      ;
+       p80211item_uint32_t     status  ;
+       p80211item_uint32_t     resp0   ;
+       p80211item_uint32_t     resp1   ;
+       p80211item_uint32_t     resp2   ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_test_command_t;
+
+typedef struct p80211msg_p2req_mmi_read
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     addr    ;
+       p80211item_uint32_t     value   ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_read_t;
+
+typedef struct p80211msg_p2req_mmi_write
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     addr    ;
+       p80211item_uint32_t     data    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_write_t;
+
+typedef struct p80211msg_p2req_ramdl_state
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     enable  ;
+       p80211item_uint32_t     exeaddr ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_state_t;
+
+typedef struct p80211msg_p2req_ramdl_write
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     addr    ;
+       p80211item_uint32_t     len     ;
+       p80211item_unk4096_t    data    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_write_t;
+
+typedef struct p80211msg_p2req_flashdl_state
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     enable  ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_state_t;
+
+typedef struct p80211msg_p2req_flashdl_write
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     addr    ;
+       p80211item_uint32_t     len     ;
+       p80211item_unk4096_t    data    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_write_t;
+
+typedef struct p80211msg_p2req_mm_state
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     enable  ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mm_state_t;
+
+typedef struct p80211msg_p2req_dump_state
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     level   ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_dump_state_t;
+
+typedef struct p80211msg_p2req_channel_info
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     channellist     ;
+       p80211item_uint32_t     channeldwelltime        ;
+       p80211item_uint32_t     resultcode      ;
+       p80211item_uint32_t     numchinfo       ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_t;
+
+typedef struct p80211msg_p2req_channel_info_results
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     channel ;
+       p80211item_uint32_t     resultcode      ;
+       p80211item_uint32_t     avgnoiselevel   ;
+       p80211item_uint32_t     peaknoiselevel  ;
+       p80211item_uint32_t     bssactive       ;
+       p80211item_uint32_t     pcfactive       ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_results_t;
+
+typedef struct p80211msg_p2req_enable
+{
+       UINT32          msgcode ;
+       UINT32          msglen  ;
+       UINT8           devname[WLAN_DEVNAMELEN_MAX]    ;
+       p80211item_uint32_t     resultcode      ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_enable_t;
+
+#endif
diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h
new file mode 100644 (file)
index 0000000..bd4c162
--- /dev/null
@@ -0,0 +1,575 @@
+/* p80211mgmt.h
+*
+* Macros, types, and functions to handle 802.11 mgmt frames
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares the constants and types used in the interface
+* between a wlan driver and the user mode utilities.
+*
+* Notes:
+*  - Constant values are always in HOST byte order.  To assign
+*    values to multi-byte fields they _must_ be converted to
+*    ieee byte order.  To retrieve multi-byte values from incoming
+*    frames, they must be converted to host order.
+*
+*  - The len member of the frame structure does NOT!!! include
+*    the MAC CRC.  Therefore, the len field on rx'd frames should
+*    have 4 subtracted from it.
+*
+* All functions declared here are implemented in p80211.c
+*
+* The types, macros, and functions defined here are primarily
+* used for encoding and decoding management frames.  They are
+* designed to follow these patterns of use:
+*
+* DECODE:
+* 1) a frame of length len is received into buffer b
+* 2) using the hdr structure and macros, we determine the type
+* 3) an appropriate mgmt frame structure, mf, is allocated and zeroed
+* 4) mf.hdr = b
+*    mf.buf = b
+*    mf.len = len
+* 5) call mgmt_decode( mf )
+* 6) the frame field pointers in mf are now set.  Note that any
+*    multi-byte frame field values accessed using the frame field
+*    pointers are in ieee byte order and will have to be converted
+*    to host order.
+*
+* ENCODE:
+* 1) Library client allocates buffer space for maximum length
+*    frame of the desired type
+* 2) Library client allocates a mgmt frame structure, called mf,
+*    of the desired type
+* 3) Set the following:
+*    mf.type = <desired type>
+*    mf.buf = <allocated buffer address>
+* 4) call mgmt_encode( mf )
+* 5) all of the fixed field pointers and fixed length information element
+*    pointers in mf are now set to their respective locations in the
+*    allocated space (fortunately, all variable length information elements
+*    fall at the end of their respective frames).
+* 5a) The length field is set to include the last of the fixed and fixed
+*     length fields.  It may have to be updated for optional or variable
+*      length information elements.
+* 6) Optional and variable length information elements are special cases
+*    and must be handled individually by the client code.
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211MGMT_H
+#define _P80211MGMT_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef  _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+#ifndef  _P80211HDR_H
+#include "p80211hdr.h"
+#endif
+
+
+/*================================================================*/
+/* Constants */
+
+/*-- Information Element IDs --------------------*/
+#define WLAN_EID_SSID          0
+#define WLAN_EID_SUPP_RATES    1
+#define WLAN_EID_FH_PARMS      2
+#define WLAN_EID_DS_PARMS      3
+#define WLAN_EID_CF_PARMS      4
+#define WLAN_EID_TIM           5
+#define WLAN_EID_IBSS_PARMS    6
+/*-- values 7-15 reserved --*/
+#define WLAN_EID_CHALLENGE     16
+/*-- values 17-31 reserved for challenge text extension --*/
+/*-- values 32-255 reserved --*/
+
+/*-- Reason Codes -------------------------------*/
+#define WLAN_MGMT_REASON_RSVD                  0
+#define WLAN_MGMT_REASON_UNSPEC                        1
+#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID    2
+#define WLAN_MGMT_REASON_DEAUTH_LEAVING                3
+#define WLAN_MGMT_REASON_DISASSOC_INACTIVE     4
+#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY      5
+#define WLAN_MGMT_REASON_CLASS2_NONAUTH                6
+#define WLAN_MGMT_REASON_CLASS3_NONASSOC       7
+#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT  8
+#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH    9
+
+/*-- Status Codes -------------------------------*/
+#define WLAN_MGMT_STATUS_SUCCESS               0
+#define WLAN_MGMT_STATUS_UNSPEC_FAILURE                1
+#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED      10
+#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC      11
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC   12
+#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG   13
+#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ         14
+#define WLAN_MGMT_STATUS_CHALLENGE_FAIL                15
+#define WLAN_MGMT_STATUS_AUTH_TIMEOUT          16
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY     17
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES    18
+  /* p80211b additions */
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT  19
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC   20
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY        21
+
+
+
+/*-- Auth Algorithm Field ---------------------------*/
+#define WLAN_AUTH_ALG_OPENSYSTEM               0
+#define WLAN_AUTH_ALG_SHAREDKEY                        1
+
+/*-- Management Frame Field Offsets -------------*/
+/* Note: Not all fields are listed because of variable lengths,   */
+/*       see the code in p80211.c to see how we search for fields */
+/* Note: These offsets are from the start of the frame data       */
+
+#define WLAN_BEACON_OFF_TS                     0
+#define WLAN_BEACON_OFF_BCN_INT                        8
+#define WLAN_BEACON_OFF_CAPINFO                        10
+#define WLAN_BEACON_OFF_SSID                   12
+
+#define WLAN_DISASSOC_OFF_REASON               0
+
+#define WLAN_ASSOCREQ_OFF_CAP_INFO             0
+#define WLAN_ASSOCREQ_OFF_LISTEN_INT           2
+#define WLAN_ASSOCREQ_OFF_SSID                 4
+
+#define WLAN_ASSOCRESP_OFF_CAP_INFO            0
+#define WLAN_ASSOCRESP_OFF_STATUS              2
+#define WLAN_ASSOCRESP_OFF_AID                 4
+#define WLAN_ASSOCRESP_OFF_SUPP_RATES          6
+
+#define WLAN_REASSOCREQ_OFF_CAP_INFO           0
+#define WLAN_REASSOCREQ_OFF_LISTEN_INT         2
+#define WLAN_REASSOCREQ_OFF_CURR_AP            4
+#define WLAN_REASSOCREQ_OFF_SSID               10
+
+#define WLAN_REASSOCRESP_OFF_CAP_INFO          0
+#define WLAN_REASSOCRESP_OFF_STATUS            2
+#define WLAN_REASSOCRESP_OFF_AID               4
+#define WLAN_REASSOCRESP_OFF_SUPP_RATES                6
+
+#define WLAN_PROBEREQ_OFF_SSID                 0
+
+#define WLAN_PROBERESP_OFF_TS                  0
+#define WLAN_PROBERESP_OFF_BCN_INT             8
+#define WLAN_PROBERESP_OFF_CAP_INFO            10
+#define WLAN_PROBERESP_OFF_SSID                        12
+
+#define WLAN_AUTHEN_OFF_AUTH_ALG               0
+#define WLAN_AUTHEN_OFF_AUTH_SEQ               2
+#define WLAN_AUTHEN_OFF_STATUS                 4
+#define WLAN_AUTHEN_OFF_CHALLENGE              6
+
+#define WLAN_DEAUTHEN_OFF_REASON               0
+
+
+/*================================================================*/
+/* Macros */
+
+/*-- Capability Field ---------------------------*/
+#define WLAN_GET_MGMT_CAP_INFO_ESS(n)          ((n) & BIT0)
+#define WLAN_GET_MGMT_CAP_INFO_IBSS(n)         (((n) & BIT1) >> 1)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n)   (((n) & BIT2) >> 2)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n)    (((n) & BIT3) >> 3)
+#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n)      (((n) & BIT4) >> 4)
+  /* p80211b additions */
+#define WLAN_GET_MGMT_CAP_INFO_SHORT(n)                (((n) & BIT5) >> 5)
+#define WLAN_GET_MGMT_CAP_INFO_PBCC(n)         (((n) & BIT6) >> 6)
+#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n)      (((n) & BIT7) >> 7)
+
+#define WLAN_SET_MGMT_CAP_INFO_ESS(n)          (n)
+#define WLAN_SET_MGMT_CAP_INFO_IBSS(n)         ((n) << 1)
+#define WLAN_SET_MGMT_CAP_INFO_CFPOLLABLE(n)   ((n) << 2)
+#define WLAN_SET_MGMT_CAP_INFO_CFPOLLREQ(n)    ((n) << 3)
+#define WLAN_SET_MGMT_CAP_INFO_PRIVACY(n)      ((n) << 4)
+  /* p80211b additions */
+#define WLAN_SET_MGMT_CAP_INFO_SHORT(n)                ((n) << 5)
+#define WLAN_SET_MGMT_CAP_INFO_PBCC(n)         ((n) << 6)
+#define WLAN_SET_MGMT_CAP_INFO_AGILITY(n)      ((n) << 7)
+
+
+/*================================================================*/
+/* Types */
+
+/*-- Information Element Types --------------------*/
+/* prototype structure, all IEs start with these members */
+
+typedef struct wlan_ie
+{
+       UINT8   eid;
+       UINT8   len;
+} __WLAN_ATTRIB_PACK__ wlan_ie_t;
+
+/*-- Service Set Identity (SSID)  -----------------*/
+typedef struct wlan_ie_ssid
+{
+       UINT8   eid;
+       UINT8   len;
+       UINT8   ssid[1];  /* may be zero, ptrs may overlap */
+} __WLAN_ATTRIB_PACK__ wlan_ie_ssid_t;
+
+/*-- Supported Rates  -----------------------------*/
+typedef struct wlan_ie_supp_rates
+{
+       UINT8   eid;
+       UINT8   len;
+       UINT8   rates[1];  /* had better be at LEAST one! */
+} __WLAN_ATTRIB_PACK__ wlan_ie_supp_rates_t;
+
+/*-- FH Parameter Set  ----------------------------*/
+typedef struct wlan_ie_fh_parms
+{
+       UINT8   eid;
+       UINT8   len;
+       UINT16  dwell;
+       UINT8   hopset;
+       UINT8   hoppattern;
+       UINT8   hopindex;
+} __WLAN_ATTRIB_PACK__ wlan_ie_fh_parms_t;
+
+/*-- DS Parameter Set  ----------------------------*/
+typedef struct wlan_ie_ds_parms
+{
+       UINT8   eid;
+       UINT8   len;
+       UINT8   curr_ch;
+} __WLAN_ATTRIB_PACK__ wlan_ie_ds_parms_t;
+
+/*-- CF Parameter Set  ----------------------------*/
+
+typedef struct wlan_ie_cf_parms
+{
+       UINT8   eid;
+       UINT8   len;
+       UINT8   cfp_cnt;
+       UINT8   cfp_period;
+       UINT16  cfp_maxdur;
+       UINT16  cfp_durremaining;
+} __WLAN_ATTRIB_PACK__ wlan_ie_cf_parms_t;
+
+/*-- TIM ------------------------------------------*/
+typedef struct wlan_ie_tim
+{
+       UINT8   eid;
+       UINT8   len;
+       UINT8   dtim_cnt;
+       UINT8   dtim_period;
+       UINT8   bitmap_ctl;
+       UINT8   virt_bm[1];
+} __WLAN_ATTRIB_PACK__ wlan_ie_tim_t;
+
+/*-- IBSS Parameter Set ---------------------------*/
+typedef struct wlan_ie_ibss_parms
+{
+       UINT8   eid;
+       UINT8   len;
+       UINT16  atim_win;
+} __WLAN_ATTRIB_PACK__ wlan_ie_ibss_parms_t;
+
+/*-- Challenge Text  ------------------------------*/
+typedef struct wlan_ie_challenge
+{
+       UINT8   eid;
+       UINT8   len;
+       UINT8   challenge[1];
+} __WLAN_ATTRIB_PACK__ wlan_ie_challenge_t;
+
+/*-------------------------------------------------*/
+/*  Frame Types  */
+
+/* prototype structure, all mgmt frame types will start with these members */
+typedef struct wlan_fr_mgmt
+{
+       UINT16                  type;
+       UINT16                  len;    /* DOES NOT include CRC !!!!*/
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       /*-- info elements ----------*/
+} wlan_fr_mgmt_t;
+
+/*-- Beacon ---------------------------------------*/
+typedef struct wlan_fr_beacon
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       UINT64                  *ts;
+       UINT16                  *bcn_int;
+       UINT16                  *cap_info;
+       /*-- info elements ----------*/
+       wlan_ie_ssid_t          *ssid;
+       wlan_ie_supp_rates_t    *supp_rates;
+       wlan_ie_fh_parms_t      *fh_parms;
+       wlan_ie_ds_parms_t      *ds_parms;
+       wlan_ie_cf_parms_t      *cf_parms;
+       wlan_ie_ibss_parms_t    *ibss_parms;
+       wlan_ie_tim_t           *tim;
+
+} wlan_fr_beacon_t;
+
+
+/*-- IBSS ATIM ------------------------------------*/
+typedef struct wlan_fr_ibssatim
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8*                  buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+
+       /*-- fixed fields -----------*/
+       /*-- info elements ----------*/
+
+       /* this frame type has a null body */
+
+} wlan_fr_ibssatim_t;
+
+/*-- Disassociation -------------------------------*/
+typedef struct wlan_fr_disassoc
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       UINT16                  *reason;
+
+       /*-- info elements ----------*/
+
+} wlan_fr_disassoc_t;
+
+/*-- Association Request --------------------------*/
+typedef struct wlan_fr_assocreq
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8*                  buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       UINT16                  *cap_info;
+       UINT16                  *listen_int;
+       /*-- info elements ----------*/
+       wlan_ie_ssid_t          *ssid;
+       wlan_ie_supp_rates_t    *supp_rates;
+
+} wlan_fr_assocreq_t;
+
+/*-- Association Response -------------------------*/
+typedef struct wlan_fr_assocresp
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       UINT16                  *cap_info;
+       UINT16                  *status;
+       UINT16                  *aid;
+       /*-- info elements ----------*/
+       wlan_ie_supp_rates_t    *supp_rates;
+
+} wlan_fr_assocresp_t;
+
+/*-- Reassociation Request ------------------------*/
+typedef struct wlan_fr_reassocreq
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       UINT16                  *cap_info;
+       UINT16                  *listen_int;
+       UINT8                   *curr_ap;
+       /*-- info elements ----------*/
+       wlan_ie_ssid_t          *ssid;
+       wlan_ie_supp_rates_t    *supp_rates;
+
+} wlan_fr_reassocreq_t;
+
+/*-- Reassociation Response -----------------------*/
+typedef struct wlan_fr_reassocresp
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       UINT16                  *cap_info;
+       UINT16                  *status;
+       UINT16                  *aid;
+       /*-- info elements ----------*/
+       wlan_ie_supp_rates_t    *supp_rates;
+
+} wlan_fr_reassocresp_t;
+
+/*-- Probe Request --------------------------------*/
+typedef struct wlan_fr_probereq
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       /*-- info elements ----------*/
+       wlan_ie_ssid_t          *ssid;
+       wlan_ie_supp_rates_t    *supp_rates;
+
+} wlan_fr_probereq_t;
+
+/*-- Probe Response -------------------------------*/
+typedef struct wlan_fr_proberesp
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       UINT64                  *ts;
+       UINT16                  *bcn_int;
+       UINT16                  *cap_info;
+       /*-- info elements ----------*/
+       wlan_ie_ssid_t          *ssid;
+       wlan_ie_supp_rates_t    *supp_rates;
+       wlan_ie_fh_parms_t      *fh_parms;
+       wlan_ie_ds_parms_t      *ds_parms;
+       wlan_ie_cf_parms_t      *cf_parms;
+       wlan_ie_ibss_parms_t    *ibss_parms;
+} wlan_fr_proberesp_t;
+
+/*-- Authentication -------------------------------*/
+typedef struct wlan_fr_authen
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       UINT16                  *auth_alg;
+       UINT16                  *auth_seq;
+       UINT16                  *status;
+       /*-- info elements ----------*/
+       wlan_ie_challenge_t     *challenge;
+
+} wlan_fr_authen_t;
+
+/*-- Deauthenication -----------------------------*/
+typedef struct wlan_fr_deauthen
+{
+       UINT16                  type;
+       UINT16                  len;
+       UINT8                   *buf;
+       p80211_hdr_t            *hdr;
+       /* used for target specific data, skb in Linux */
+       void                    *priv;
+       /*-- fixed fields -----------*/
+       UINT16                  *reason;
+
+       /*-- info elements ----------*/
+
+} wlan_fr_deauthen_t;
+
+
+/*================================================================*/
+/* Extern Declarations */
+
+
+/*================================================================*/
+/* Function Declarations */
+
+void wlan_mgmt_encode_beacon( wlan_fr_beacon_t  *f );
+void wlan_mgmt_decode_beacon( wlan_fr_beacon_t  *f );
+void wlan_mgmt_encode_disassoc( wlan_fr_disassoc_t  *f );
+void wlan_mgmt_decode_disassoc( wlan_fr_disassoc_t  *f );
+void wlan_mgmt_encode_assocreq( wlan_fr_assocreq_t  *f );
+void wlan_mgmt_decode_assocreq( wlan_fr_assocreq_t  *f );
+void wlan_mgmt_encode_assocresp( wlan_fr_assocresp_t  *f );
+void wlan_mgmt_decode_assocresp( wlan_fr_assocresp_t  *f );
+void wlan_mgmt_encode_reassocreq( wlan_fr_reassocreq_t  *f );
+void wlan_mgmt_decode_reassocreq( wlan_fr_reassocreq_t  *f );
+void wlan_mgmt_encode_reassocresp( wlan_fr_reassocresp_t  *f );
+void wlan_mgmt_decode_reassocresp( wlan_fr_reassocresp_t  *f );
+void wlan_mgmt_encode_probereq( wlan_fr_probereq_t  *f );
+void wlan_mgmt_decode_probereq( wlan_fr_probereq_t  *f );
+void wlan_mgmt_encode_proberesp( wlan_fr_proberesp_t  *f );
+void wlan_mgmt_decode_proberesp( wlan_fr_proberesp_t  *f );
+void wlan_mgmt_encode_authen( wlan_fr_authen_t  *f );
+void wlan_mgmt_decode_authen( wlan_fr_authen_t  *f );
+void wlan_mgmt_encode_deauthen( wlan_fr_deauthen_t  *f );
+void wlan_mgmt_decode_deauthen( wlan_fr_deauthen_t  *f );
+
+
+#endif /* _P80211MGMT_H */
diff --git a/drivers/staging/wlan-ng/p80211mod.c b/drivers/staging/wlan-ng/p80211mod.c
new file mode 100644 (file)
index 0000000..e2c3f63
--- /dev/null
@@ -0,0 +1,216 @@
+/* src/p80211/p80211mod.c
+*
+* Module entry and exit for p80211
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file contains the p80211.o entry and exit points defined for linux
+* kernel modules.
+*
+* Notes:
+* - all module parameters for  p80211.o should be defined here.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25))
+#include <linux/moduleparam.h>
+#endif
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+
+#include "version.h"
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211req.h"
+
+/*================================================================*/
+/* Local Constants */
+
+
+/*================================================================*/
+/* Local Macros */
+
+
+/*================================================================*/
+/* Local Types */
+
+
+/*================================================================*/
+/* Local Static Definitions */
+
+static char *version = "p80211.o: " WLAN_RELEASE;
+
+
+/*----------------------------------------------------------------*/
+/* --Module Parameters */
+
+int wlan_watchdog = 5000;
+module_param(wlan_watchdog, int, 0644);
+MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds");
+
+int wlan_wext_write = 0;
+#if WIRELESS_EXT > 12
+module_param(wlan_wext_write, int, 0644);
+MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
+#endif
+
+#ifdef WLAN_INCLUDE_DEBUG
+int wlan_debug=0;
+module_param(wlan_debug, int, 0644);
+MODULE_PARM_DESC(wlan_debug, "p80211 debug level");
+#endif
+
+MODULE_LICENSE("Dual MPL/GPL");
+
+/*================================================================*/
+/* Local Function Declarations */
+
+int    init_module(void);
+void   cleanup_module(void);
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* init_module
+*
+* Module initialization routine, called once at module load time.
+*
+* Arguments:
+*      none
+*
+* Returns:
+*      0       - success
+*      ~0      - failure, module is unloaded.
+*
+* Side effects:
+*      TODO: define
+*
+* Call context:
+*      process thread (insmod or modprobe)
+----------------------------------------------------------------*/
+int init_module(void)
+{
+        DBFENTER;
+
+#if 0
+        printk(KERN_NOTICE "%s (%s) Loaded\n", version, WLAN_BUILD_DATE);
+#endif
+
+       p80211netdev_startup();
+#ifdef CONFIG_HOTPLUG
+       p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_STARTUP);
+#endif
+
+        DBFEXIT;
+        return 0;
+}
+
+
+/*----------------------------------------------------------------
+* cleanup_module
+*
+* Called at module unload time.  This is our last chance to
+* clean up after ourselves.
+*
+* Arguments:
+*      none
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      TODO: define
+*
+* Call context:
+*      process thread
+*
+----------------------------------------------------------------*/
+void cleanup_module(void)
+{
+        DBFENTER;
+
+#ifdef CONFIG_HOTPLUG
+       p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_SHUTDOWN);
+#endif
+       p80211netdev_shutdown();
+        printk(KERN_NOTICE "%s Unloaded\n", version);
+
+        DBFEXIT;
+        return;
+}
+
+EXPORT_SYMBOL(p80211netdev_hwremoved);
+EXPORT_SYMBOL(register_wlandev);
+EXPORT_SYMBOL(p80211netdev_rx);
+EXPORT_SYMBOL(unregister_wlandev);
+EXPORT_SYMBOL(wlan_setup);
+EXPORT_SYMBOL(wlan_unsetup);
+EXPORT_SYMBOL(p80211_suspend);
+EXPORT_SYMBOL(p80211_resume);
+
+EXPORT_SYMBOL(p80211skb_free);
+EXPORT_SYMBOL(p80211skb_rxmeta_attach);
+
+EXPORT_SYMBOL(p80211wext_event_associated);
diff --git a/drivers/staging/wlan-ng/p80211msg.h b/drivers/staging/wlan-ng/p80211msg.h
new file mode 100644 (file)
index 0000000..c14e9fb
--- /dev/null
@@ -0,0 +1,102 @@
+/* p80211msg.h
+*
+* Macros, constants, types, and funcs for req and ind messages
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211MSG_H
+#define _P80211MSG_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+
+#define MSG_BUFF_LEN           4000
+#define WLAN_DEVNAMELEN_MAX    16
+
+/*================================================================*/
+/* Macros */
+
+/*================================================================*/
+/* Types */
+
+/*--------------------------------------------------------------------*/
+/*----- Message Structure Types --------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Prototype msg type */
+
+typedef struct p80211msg
+{
+       UINT32  msgcode;
+       UINT32  msglen;
+       UINT8   devname[WLAN_DEVNAMELEN_MAX];
+} __WLAN_ATTRIB_PACK__ p80211msg_t;
+
+typedef struct p80211msgd
+{
+       UINT32  msgcode;
+       UINT32  msglen;
+       UINT8   devname[WLAN_DEVNAMELEN_MAX];
+       UINT8   args[0];
+} __WLAN_ATTRIB_PACK__ p80211msgd_t;
+
+/*================================================================*/
+/* Extern Declarations */
+
+
+/*================================================================*/
+/* Function Declarations */
+
+#endif  /* _P80211MSG_H */
+
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
new file mode 100644 (file)
index 0000000..11f84a8
--- /dev/null
@@ -0,0 +1,1502 @@
+/* src/p80211/p80211knetdev.c
+*
+* Linux Kernel net device interface
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* The functions required for a Linux network device are defined here.
+*
+* --------------------------------------------------------------------
+*/
+
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/kmod.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <linux/sockios.h>
+#include <linux/etherdevice.h>
+
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+
+#ifdef SIOCETHTOOL
+#include <linux/ethtool.h>
+#endif
+
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+#endif
+#include <net/net_namespace.h>
+
+/*================================================================*/
+/* Project Includes */
+
+#include "version.h"
+#include "wlan_compat.h"
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211conv.h"
+#include "p80211mgmt.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211ioctl.h"
+#include "p80211req.h"
+#include "p80211metastruct.h"
+#include "p80211metadef.h"
+
+/*================================================================*/
+/* Local Constants */
+
+/*================================================================*/
+/* Local Macros */
+
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+
+#define __NO_VERSION__         /* prevent the static definition */
+
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry   *proc_p80211;
+#endif
+
+/*================================================================*/
+/* Local Function Declarations */
+
+/* Support functions */
+static void p80211netdev_rx_bh(unsigned long arg);
+
+/* netdevice method functions */
+static int p80211knetdev_init( netdevice_t *netdev);
+static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev);
+static int p80211knetdev_open( netdevice_t *netdev);
+static int p80211knetdev_stop( netdevice_t *netdev );
+static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev);
+static void p80211knetdev_set_multicast_list(netdevice_t *dev);
+static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
+static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr);
+static void p80211knetdev_tx_timeout(netdevice_t *netdev);
+static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc);
+
+#ifdef CONFIG_PROC_FS
+static int
+p80211netdev_proc_read(
+       char    *page,
+       char    **start,
+       off_t   offset,
+       int     count,
+       int     *eof,
+       void    *data);
+#endif
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* p80211knetdev_startup
+*
+* Initialize the wlandevice/netdevice part of 802.11 services at
+* load time.
+*
+* Arguments:
+*      none
+*
+* Returns:
+*      nothing
+----------------------------------------------------------------*/
+void p80211netdev_startup(void)
+{
+       DBFENTER;
+
+#ifdef CONFIG_PROC_FS
+       if (init_net.proc_net != NULL) {
+               proc_p80211 = create_proc_entry(
+                               "p80211",
+                               (S_IFDIR|S_IRUGO|S_IXUGO),
+                               init_net.proc_net);
+       }
+#endif
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* p80211knetdev_shutdown
+*
+* Shutdown the wlandevice/netdevice part of 802.11 services at
+* unload time.
+*
+* Arguments:
+*      none
+*
+* Returns:
+*      nothing
+----------------------------------------------------------------*/
+void
+p80211netdev_shutdown(void)
+{
+       DBFENTER;
+#ifdef CONFIG_PROC_FS
+       if (proc_p80211 != NULL) {
+               remove_proc_entry("p80211", init_net.proc_net);
+       }
+#endif
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* p80211knetdev_init
+*
+* Init method for a Linux netdevice.  Called in response to
+* register_netdev.
+*
+* Arguments:
+*      none
+*
+* Returns:
+*      nothing
+----------------------------------------------------------------*/
+static int p80211knetdev_init( netdevice_t *netdev)
+{
+       DBFENTER;
+       /* Called in response to register_netdev */
+       /* This is usually the probe function, but the probe has */
+       /* already been done by the MSD and the create_kdev */
+       /* function.  All we do here is return success */
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_get_stats
+*
+* Statistics retrieval for linux netdevices.  Here we're reporting
+* the Linux i/f level statistics.  Hence, for the primary numbers,
+* we don't want to report the numbers from the MIB.  Eventually,
+* it might be useful to collect some of the error counters though.
+*
+* Arguments:
+*      netdev          Linux netdevice
+*
+* Returns:
+*      the address of the statistics structure
+----------------------------------------------------------------*/
+static struct net_device_stats*
+p80211knetdev_get_stats(netdevice_t *netdev)
+{
+       wlandevice_t    *wlandev = (wlandevice_t*)netdev->priv;
+       DBFENTER;
+
+       /* TODO: review the MIB stats for items that correspond to
+               linux stats */
+
+       DBFEXIT;
+       return &(wlandev->linux_stats);
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_open
+*
+* Linux netdevice open method.  Following a successful call here,
+* the device is supposed to be ready for tx and rx.  In our
+* situation that may not be entirely true due to the state of the
+* MAC below.
+*
+* Arguments:
+*      netdev          Linux network device structure
+*
+* Returns:
+*      zero on success, non-zero otherwise
+----------------------------------------------------------------*/
+static int p80211knetdev_open( netdevice_t *netdev )
+{
+       int             result = 0; /* success */
+       wlandevice_t    *wlandev = (wlandevice_t*)(netdev->priv);
+
+       DBFENTER;
+
+       /* Check to make sure the MSD is running */
+       if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {
+               return -ENODEV;
+       }
+
+       /* Tell the MSD to open */
+       if ( wlandev->open != NULL) {
+               result = wlandev->open(wlandev);
+               if ( result == 0 ) {
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) )
+                       netdev->interrupt = 0;
+#endif
+                       p80211netdev_start_queue(wlandev);
+                       wlandev->state = WLAN_DEVICE_OPEN;
+               }
+       } else {
+               result = -EAGAIN;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_stop
+*
+* Linux netdevice stop (close) method.  Following this call,
+* no frames should go up or down through this interface.
+*
+* Arguments:
+*      netdev          Linux network device structure
+*
+* Returns:
+*      zero on success, non-zero otherwise
+----------------------------------------------------------------*/
+static int p80211knetdev_stop( netdevice_t *netdev )
+{
+       int             result = 0;
+       wlandevice_t    *wlandev = (wlandevice_t*)(netdev->priv);
+
+       DBFENTER;
+
+       if ( wlandev->close != NULL ) {
+               result = wlandev->close(wlandev);
+       }
+
+       p80211netdev_stop_queue(wlandev);
+       wlandev->state = WLAN_DEVICE_CLOSED;
+
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* p80211netdev_rx
+*
+* Frame receive function called by the mac specific driver.
+*
+* Arguments:
+*      wlandev         WLAN network device structure
+*      skb             skbuff containing a full 802.11 frame.
+* Returns:
+*      nothing
+* Side effects:
+*
+----------------------------------------------------------------*/
+void
+p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb )
+{
+       DBFENTER;
+
+       /* Enqueue for post-irq processing */
+       skb_queue_tail(&wlandev->nsd_rxq, skb);
+
+       tasklet_schedule(&wlandev->rx_bh);
+
+        DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* p80211netdev_rx_bh
+*
+* Deferred processing of all received frames.
+*
+* Arguments:
+*      wlandev         WLAN network device structure
+*      skb             skbuff containing a full 802.11 frame.
+* Returns:
+*      nothing
+* Side effects:
+*
+----------------------------------------------------------------*/
+static void p80211netdev_rx_bh(unsigned long arg)
+{
+       wlandevice_t *wlandev = (wlandevice_t *) arg;
+       struct sk_buff *skb = NULL;
+       netdevice_t     *dev = wlandev->netdev;
+       p80211_hdr_a3_t *hdr;
+       UINT16 fc;
+
+        DBFENTER;
+
+       /* Let's empty our our queue */
+       while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+               if (wlandev->state == WLAN_DEVICE_OPEN) {
+
+                       if (dev->type != ARPHRD_ETHER) {
+                               /* RAW frame; we shouldn't convert it */
+                               // XXX Append the Prism Header here instead.
+
+                               /* set up various data fields */
+                               skb->dev = dev;
+                               skb_reset_mac_header(skb);
+                               skb->ip_summed = CHECKSUM_NONE;
+                               skb->pkt_type = PACKET_OTHERHOST;
+                               skb->protocol = htons(ETH_P_80211_RAW);
+                               dev->last_rx = jiffies;
+
+                               wlandev->linux_stats.rx_packets++;
+                               wlandev->linux_stats.rx_bytes += skb->len;
+                               netif_rx_ni(skb);
+                               continue;
+                       } else {
+                               hdr = (p80211_hdr_a3_t *)skb->data;
+                               fc = ieee2host16(hdr->fc);
+                               if (p80211_rx_typedrop(wlandev, fc)) {
+                                       dev_kfree_skb(skb);
+                                       continue;
+                               }
+
+                               /* perform mcast filtering */
+                               if (wlandev->netdev->flags & IFF_ALLMULTI) {
+                                       /* allow my local address through */
+                                       if (memcmp(hdr->a1, wlandev->netdev->dev_addr, WLAN_ADDR_LEN) != 0) {
+                                               /* but reject anything else that isn't multicast */
+                                               if (!(hdr->a1[0] & 0x01)) {
+                                                       dev_kfree_skb(skb);
+                                                       continue;
+                                               }
+                                       }
+                               }
+
+                               if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {
+                                       skb->dev->last_rx = jiffies;
+                                       wlandev->linux_stats.rx_packets++;
+                                       wlandev->linux_stats.rx_bytes += skb->len;
+                                       netif_rx_ni(skb);
+                                       continue;
+                               }
+                               WLAN_LOG_DEBUG(1, "p80211_to_ether failed.\n");
+                       }
+               }
+               dev_kfree_skb(skb);
+       }
+
+        DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_hard_start_xmit
+*
+* Linux netdevice method for transmitting a frame.
+*
+* Arguments:
+*      skb     Linux sk_buff containing the frame.
+*      netdev  Linux netdevice.
+*
+* Side effects:
+*      If the lower layers report that buffers are full. netdev->tbusy
+*      will be set to prevent higher layers from sending more traffic.
+*
+*      Note: If this function returns non-zero, higher layers retain
+*            ownership of the skb.
+*
+* Returns:
+*      zero on success, non-zero on failure.
+----------------------------------------------------------------*/
+static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev)
+{
+       int             result = 0;
+       int             txresult = -1;
+       wlandevice_t    *wlandev = (wlandevice_t*)netdev->priv;
+       p80211_hdr_t    p80211_hdr;
+       p80211_metawep_t p80211_wep;
+
+       DBFENTER;
+
+       if (skb == NULL) {
+               return 0;
+       }
+
+        if (wlandev->state != WLAN_DEVICE_OPEN) {
+               result = 1;
+               goto failed;
+       }
+
+       memset(&p80211_hdr, 0, sizeof(p80211_hdr_t));
+       memset(&p80211_wep, 0, sizeof(p80211_metawep_t));
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+       if ( test_and_set_bit(0, (void*)&(netdev->tbusy)) != 0 ) {
+               /* We've been called w/ tbusy set, has the tx */
+               /* path stalled?   */
+               WLAN_LOG_DEBUG(1, "called when tbusy set\n");
+               result = 1;
+               goto failed;
+       }
+#else
+       if ( netif_queue_stopped(netdev) ) {
+               WLAN_LOG_DEBUG(1, "called when queue stopped.\n");
+               result = 1;
+               goto failed;
+       }
+
+       netif_stop_queue(netdev);
+
+       /* No timeout handling here, 2.3.38+ kernels call the
+        * timeout function directly.
+        * TODO: Add timeout handling.
+       */
+#endif
+
+       /* Check to see that a valid mode is set */
+       switch( wlandev->macmode ) {
+       case WLAN_MACMODE_IBSS_STA:
+       case WLAN_MACMODE_ESS_STA:
+       case WLAN_MACMODE_ESS_AP:
+               break;
+       default:
+               /* Mode isn't set yet, just drop the frame
+                * and return success .
+                * TODO: we need a saner way to handle this
+                */
+               if(skb->protocol != ETH_P_80211_RAW) {
+                       p80211netdev_start_queue(wlandev);
+                       WLAN_LOG_NOTICE(
+                               "Tx attempt prior to association, frame dropped.\n");
+                       wlandev->linux_stats.tx_dropped++;
+                       result = 0;
+                       goto failed;
+               }
+               break;
+       }
+
+       /* Check for raw transmits */
+       if(skb->protocol == ETH_P_80211_RAW) {
+               if (!capable(CAP_NET_ADMIN)) {
+                       result = 1;
+                       goto failed;
+               }
+               /* move the header over */
+               memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr_t));
+               skb_pull(skb, sizeof(p80211_hdr_t));
+       } else {
+               if ( skb_ether_to_p80211(wlandev, wlandev->ethconv, skb, &p80211_hdr, &p80211_wep) != 0 ) {
+                       /* convert failed */
+                       WLAN_LOG_DEBUG(1, "ether_to_80211(%d) failed.\n",
+                                       wlandev->ethconv);
+                       result = 1;
+                       goto failed;
+               }
+       }
+       if ( wlandev->txframe == NULL ) {
+               result = 1;
+               goto failed;
+       }
+
+       netdev->trans_start = jiffies;
+
+       wlandev->linux_stats.tx_packets++;
+       /* count only the packet payload */
+       wlandev->linux_stats.tx_bytes += skb->len;
+
+       txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
+
+       if ( txresult == 0) {
+               /* success and more buf */
+               /* avail, re: hw_txdata */
+               p80211netdev_wake_queue(wlandev);
+               result = 0;
+       } else if ( txresult == 1 ) {
+               /* success, no more avail */
+               WLAN_LOG_DEBUG(3, "txframe success, no more bufs\n");
+               /* netdev->tbusy = 1;  don't set here, irqhdlr */
+               /*   may have already cleared it */
+               result = 0;
+       } else if ( txresult == 2 ) {
+               /* alloc failure, drop frame */
+               WLAN_LOG_DEBUG(3, "txframe returned alloc_fail\n");
+               result = 1;
+       } else {
+               /* buffer full or queue busy, drop frame. */
+               WLAN_LOG_DEBUG(3, "txframe returned full or busy\n");
+               result = 1;
+       }
+
+ failed:
+       /* Free up the WEP buffer if it's not the same as the skb */
+       if ((p80211_wep.data) && (p80211_wep.data != skb->data))
+               kfree(p80211_wep.data);
+
+       /* we always free the skb here, never in a lower level. */
+       if (!result)
+               dev_kfree_skb(skb);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_set_multicast_list
+*
+* Called from higher lavers whenever there's a need to set/clear
+* promiscuous mode or rewrite the multicast list.
+*
+* Arguments:
+*      none
+*
+* Returns:
+*      nothing
+----------------------------------------------------------------*/
+static void p80211knetdev_set_multicast_list(netdevice_t *dev)
+{
+       wlandevice_t    *wlandev = (wlandevice_t*)dev->priv;
+
+       DBFENTER;
+
+       /* TODO:  real multicast support as well */
+
+       if (wlandev->set_multicast_list)
+               wlandev->set_multicast_list(wlandev, dev);
+
+       DBFEXIT;
+}
+
+#ifdef SIOCETHTOOL
+
+static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
+{
+       UINT32 ethcmd;
+       struct ethtool_drvinfo info;
+       struct ethtool_value edata;
+
+       memset(&info, 0, sizeof(info));
+       memset(&edata, 0, sizeof(edata));
+
+       if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+               return -EFAULT;
+
+       switch (ethcmd) {
+       case ETHTOOL_GDRVINFO:
+               info.cmd = ethcmd;
+               snprintf(info.driver, sizeof(info.driver), "p80211_%s",
+                        wlandev->nsdname);
+               snprintf(info.version, sizeof(info.version), "%s",
+                        WLAN_RELEASE);
+
+               // info.fw_version
+               // info.bus_info
+
+               if (copy_to_user(useraddr, &info, sizeof(info)))
+                       return -EFAULT;
+               return 0;
+#ifdef ETHTOOL_GLINK
+       case ETHTOOL_GLINK:
+               edata.cmd = ethcmd;
+
+               if (wlandev->linkstatus &&
+                   (wlandev->macmode != WLAN_MACMODE_NONE)) {
+                       edata.data = 1;
+               } else {
+                       edata.data = 0;
+               }
+
+               if (copy_to_user(useraddr, &edata, sizeof(edata)))
+                        return -EFAULT;
+               return 0;
+       }
+#endif
+
+       return -EOPNOTSUPP;
+}
+
+#endif
+
+/*----------------------------------------------------------------
+* p80211knetdev_do_ioctl
+*
+* Handle an ioctl call on one of our devices.  Everything Linux
+* ioctl specific is done here.  Then we pass the contents of the
+* ifr->data to the request message handler.
+*
+* Arguments:
+*      dev     Linux kernel netdevice
+*      ifr     Our private ioctl request structure, typed for the
+*              generic struct ifreq so we can use ptr to func
+*              w/o cast.
+*
+* Returns:
+*      zero on success, a negative errno on failure.  Possible values:
+*              -ENETDOWN Device isn't up.
+*              -EBUSY  cmd already in progress
+*              -ETIME  p80211 cmd timed out (MSD may have its own timers)
+*              -EFAULT memory fault copying msg from user buffer
+*              -ENOMEM unable to allocate kernel msg buffer
+*              -ENOSYS bad magic, it the cmd really for us?
+*              -EINTR  sleeping on cmd, awakened by signal, cmd cancelled.
+*
+* Call Context:
+*      Process thread (ioctl caller).  TODO: SMP support may require
+*      locks.
+----------------------------------------------------------------*/
+static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
+{
+       int                     result = 0;
+       p80211ioctl_req_t       *req = (p80211ioctl_req_t*)ifr;
+       wlandevice_t            *wlandev = (wlandevice_t*)dev->priv;
+       UINT8                   *msgbuf;
+       DBFENTER;
+
+       WLAN_LOG_DEBUG(2, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
+
+#if WIRELESS_EXT < 13
+       /* Is this a wireless extensions ioctl? */
+       if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
+               if ((result = p80211wext_support_ioctl(dev, ifr, cmd))
+                   != (-EOPNOTSUPP)) {
+                       goto bail;
+               }
+       }
+#endif
+
+#ifdef SIOCETHTOOL
+       if (cmd == SIOCETHTOOL) {
+               result = p80211netdev_ethtool(wlandev, (void __user *) ifr->ifr_data);
+               goto bail;
+       }
+#endif
+
+       /* Test the magic, assume ifr is good if it's there */
+       if ( req->magic != P80211_IOCTL_MAGIC ) {
+               result = -ENOSYS;
+               goto bail;
+       }
+
+       if ( cmd == P80211_IFTEST ) {
+               result = 0;
+               goto bail;
+       } else if ( cmd != P80211_IFREQ ) {
+               result = -ENOSYS;
+               goto bail;
+       }
+
+       /* Allocate a buf of size req->len */
+       if ((msgbuf = kmalloc( req->len, GFP_KERNEL))) {
+               if ( copy_from_user( msgbuf, (void __user *) req->data, req->len) ) {
+                       result = -EFAULT;
+               } else {
+                       result = p80211req_dorequest( wlandev, msgbuf);
+               }
+
+               if ( result == 0 ) {
+                       if ( copy_to_user( (void __user *) req->data, msgbuf, req->len)) {
+                               result = -EFAULT;
+                       }
+               }
+               kfree(msgbuf);
+       } else {
+               result = -ENOMEM;
+       }
+bail:
+       DBFEXIT;
+
+       return result; /* If allocate,copyfrom or copyto fails, return errno */
+}
+
+/*----------------------------------------------------------------
+* p80211knetdev_set_mac_address
+*
+* Handles the ioctl for changing the MACAddress of a netdevice
+*
+* references: linux/netdevice.h and drivers/net/net_init.c
+*
+* NOTE: [MSM] We only prevent address changes when the netdev is
+* up.  We don't control anything based on dot11 state.  If the
+* address is changed on a STA that's currently associated, you
+* will probably lose the ability to send and receive data frames.
+* Just be aware.  Therefore, this should usually only be done
+* prior to scan/join/auth/assoc.
+*
+* Arguments:
+*      dev     netdevice struct
+*      addr    the new MACAddress (a struct)
+*
+* Returns:
+*      zero on success, a negative errno on failure.  Possible values:
+*              -EBUSY  device is bussy (cmd not possible)
+*              -and errors returned by: p80211req_dorequest(..)
+*
+* by: Collin R. Mulliner <collin@mulliner.org>
+----------------------------------------------------------------*/
+static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
+{
+       struct sockaddr                 *new_addr = addr;
+       p80211msg_dot11req_mibset_t     dot11req;
+       p80211item_unk392_t             *mibattr;
+       p80211item_pstr6_t              *macaddr;
+       p80211item_uint32_t             *resultcode;
+       int result = 0;
+
+       DBFENTER;
+       /* If we're running, we don't allow MAC address changes */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+       if ( dev->start) {
+               return -EBUSY;
+       }
+#else
+       if (netif_running(dev)) {
+               return -EBUSY;
+       }
+#endif
+
+       /* Set up some convenience pointers. */
+       mibattr = &dot11req.mibattribute;
+       macaddr = (p80211item_pstr6_t*)&mibattr->data;
+       resultcode = &dot11req.resultcode;
+
+       /* Set up a dot11req_mibset */
+       memset(&dot11req, 0, sizeof(p80211msg_dot11req_mibset_t));
+       dot11req.msgcode = DIDmsg_dot11req_mibset;
+       dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t);
+       memcpy(dot11req.devname,
+               ((wlandevice_t*)(dev->priv))->name,
+               WLAN_DEVNAMELEN_MAX - 1);
+
+       /* Set up the mibattribute argument */
+       mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
+       mibattr->status = P80211ENUM_msgitem_status_data_ok;
+       mibattr->len = sizeof(mibattr->data);
+
+       macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress;
+       macaddr->status = P80211ENUM_msgitem_status_data_ok;
+       macaddr->len = sizeof(macaddr->data);
+       macaddr->data.len = WLAN_ADDR_LEN;
+       memcpy(&macaddr->data.data, new_addr->sa_data, WLAN_ADDR_LEN);
+
+       /* Set up the resultcode argument */
+       resultcode->did = DIDmsg_dot11req_mibset_resultcode;
+       resultcode->status = P80211ENUM_msgitem_status_no_value;
+       resultcode->len = sizeof(resultcode->data);
+       resultcode->data = 0;
+
+       /* now fire the request */
+       result = p80211req_dorequest(dev->priv, (UINT8*)&dot11req);
+
+       /* If the request wasn't successful, report an error and don't
+        * change the netdev address
+        */
+       if ( result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
+               WLAN_LOG_ERROR(
+               "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
+               result = -EADDRNOTAVAIL;
+       } else {
+               /* everything's ok, change the addr in netdev */
+               memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len);
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
+{
+       DBFENTER;
+       // 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
+       // and another 8 for wep.
+        if ( (new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
+                return -EINVAL;
+
+        dev->mtu = new_mtu;
+
+       DBFEXIT;
+
+        return 0;
+}
+
+
+
+/*----------------------------------------------------------------
+* wlan_setup
+*
+* Roughly matches the functionality of ether_setup.  Here
+* we set up any members of the wlandevice structure that are common
+* to all devices.  Additionally, we allocate a linux 'struct device'
+* and perform the same setup as ether_setup.
+*
+* Note: It's important that the caller have setup the wlandev->name
+*      ptr prior to calling this function.
+*
+* Arguments:
+*      wlandev         ptr to the wlandev structure for the
+*                      interface.
+* Returns:
+*      zero on success, non-zero otherwise.
+* Call Context:
+*      Should be process thread.  We'll assume it might be
+*      interrupt though.  When we add support for statically
+*      compiled drivers, this function will be called in the
+*      context of the kernel startup code.
+----------------------------------------------------------------*/
+int wlan_setup(wlandevice_t *wlandev)
+{
+       int             result = 0;
+       netdevice_t     *dev;
+
+       DBFENTER;
+
+       /* Set up the wlandev */
+       wlandev->state = WLAN_DEVICE_CLOSED;
+       wlandev->ethconv = WLAN_ETHCONV_8021h;
+       wlandev->macmode = WLAN_MACMODE_NONE;
+
+       /* Set up the rx queue */
+       skb_queue_head_init(&wlandev->nsd_rxq);
+       tasklet_init(&wlandev->rx_bh,
+                    p80211netdev_rx_bh,
+                    (unsigned long)wlandev);
+
+       /* Allocate and initialize the struct device */
+       dev = kmalloc(sizeof(netdevice_t), GFP_ATOMIC);
+       if ( dev == NULL ) {
+               WLAN_LOG_ERROR("Failed to alloc netdev.\n");
+               result = 1;
+       } else {
+               memset( dev, 0, sizeof(netdevice_t));
+               ether_setup(dev);
+               wlandev->netdev = dev;
+               dev->priv = wlandev;
+               dev->hard_start_xmit =  p80211knetdev_hard_start_xmit;
+               dev->get_stats =        p80211knetdev_get_stats;
+#ifdef HAVE_PRIVATE_IOCTL
+               dev->do_ioctl =         p80211knetdev_do_ioctl;
+#endif
+#ifdef HAVE_MULTICAST
+               dev->set_multicast_list = p80211knetdev_set_multicast_list;
+#endif
+               dev->init =             p80211knetdev_init;
+               dev->open =             p80211knetdev_open;
+               dev->stop =             p80211knetdev_stop;
+
+#ifdef CONFIG_NET_WIRELESS
+#if ((WIRELESS_EXT < 17) && (WIRELESS_EXT < 21))
+               dev->get_wireless_stats = p80211wext_get_wireless_stats;
+#endif
+#if WIRELESS_EXT > 12
+               dev->wireless_handlers = &p80211wext_handler_def;
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+               dev->tbusy = 1;
+               dev->start = 0;
+#else
+               netif_stop_queue(dev);
+#endif
+#ifdef HAVE_CHANGE_MTU
+               dev->change_mtu = wlan_change_mtu;
+#endif
+#ifdef HAVE_SET_MAC_ADDR
+               dev->set_mac_address =  p80211knetdev_set_mac_address;
+#endif
+#ifdef HAVE_TX_TIMEOUT
+               dev->tx_timeout      =  &p80211knetdev_tx_timeout;
+               dev->watchdog_timeo  =  (wlan_watchdog * HZ) / 1000;
+#endif
+               netif_carrier_off(dev);
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* wlan_unsetup
+*
+* This function is paired with the wlan_setup routine.  It should
+* be called after unregister_wlandev.  Basically, all it does is
+* free the 'struct device' that's associated with the wlandev.
+* We do it here because the 'struct device' isn't allocated
+* explicitly in the driver code, it's done in wlan_setup.  To
+* do the free in the driver might seem like 'magic'.
+*
+* Arguments:
+*      wlandev         ptr to the wlandev structure for the
+*                      interface.
+* Returns:
+*      zero on success, non-zero otherwise.
+* Call Context:
+*      Should be process thread.  We'll assume it might be
+*      interrupt though.  When we add support for statically
+*      compiled drivers, this function will be called in the
+*      context of the kernel startup code.
+----------------------------------------------------------------*/
+int wlan_unsetup(wlandevice_t *wlandev)
+{
+       int             result = 0;
+
+       DBFENTER;
+
+       tasklet_kill(&wlandev->rx_bh);
+
+       if (wlandev->netdev == NULL ) {
+               WLAN_LOG_ERROR("called without wlandev->netdev set.\n");
+               result = 1;
+       } else {
+               free_netdev(wlandev->netdev);
+               wlandev->netdev = NULL;
+       }
+
+       DBFEXIT;
+       return 0;
+}
+
+
+
+/*----------------------------------------------------------------
+* register_wlandev
+*
+* Roughly matches the functionality of register_netdev.  This function
+* is called after the driver has successfully probed and set up the
+* resources for the device.  It's now ready to become a named device
+* in the Linux system.
+*
+* First we allocate a name for the device (if not already set), then
+* we call the Linux function register_netdevice.
+*
+* Arguments:
+*      wlandev         ptr to the wlandev structure for the
+*                      interface.
+* Returns:
+*      zero on success, non-zero otherwise.
+* Call Context:
+*      Can be either interrupt or not.
+----------------------------------------------------------------*/
+int register_wlandev(wlandevice_t *wlandev)
+{
+       int             i = 0;
+       netdevice_t     *dev = wlandev->netdev;
+
+       DBFENTER;
+
+       i = dev_alloc_name(wlandev->netdev, "wlan%d");
+       if (i >= 0) {
+               i = register_netdev(wlandev->netdev);
+       }
+       if (i != 0) {
+               return -EIO;
+       }
+
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) )
+       dev->name = wlandev->name;
+#else
+       strcpy(wlandev->name, dev->name);
+#endif
+
+#ifdef CONFIG_PROC_FS
+       if (proc_p80211) {
+               wlandev->procdir = proc_mkdir(wlandev->name, proc_p80211);
+               if ( wlandev->procdir )
+                       wlandev->procwlandev =
+                               create_proc_read_entry("wlandev", 0,
+                                                      wlandev->procdir,
+                                                      p80211netdev_proc_read,
+                                                      wlandev);
+               if (wlandev->nsd_proc_read)
+                       create_proc_read_entry("nsd", 0,
+                                              wlandev->procdir,
+                                              wlandev->nsd_proc_read,
+                                              wlandev);
+       }
+#endif
+
+#ifdef CONFIG_HOTPLUG
+       p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REGISTER);
+#endif
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* unregister_wlandev
+*
+* Roughly matches the functionality of unregister_netdev.  This
+* function is called to remove a named device from the system.
+*
+* First we tell linux that the device should no longer exist.
+* Then we remove it from the list of known wlan devices.
+*
+* Arguments:
+*      wlandev         ptr to the wlandev structure for the
+*                      interface.
+* Returns:
+*      zero on success, non-zero otherwise.
+* Call Context:
+*      Can be either interrupt or not.
+----------------------------------------------------------------*/
+int unregister_wlandev(wlandevice_t *wlandev)
+{
+       struct sk_buff *skb;
+
+       DBFENTER;
+
+#ifdef CONFIG_HOTPLUG
+       p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REMOVE);
+#endif
+
+#ifdef CONFIG_PROC_FS
+       if ( wlandev->procwlandev ) {
+               remove_proc_entry("wlandev", wlandev->procdir);
+       }
+       if ( wlandev->nsd_proc_read ) {
+               remove_proc_entry("nsd", wlandev->procdir);
+       }
+       if (wlandev->procdir) {
+               remove_proc_entry(wlandev->name, proc_p80211);
+       }
+#endif
+
+       unregister_netdev(wlandev->netdev);
+
+       /* Now to clean out the rx queue */
+       while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+               dev_kfree_skb(skb);
+       }
+
+       DBFEXIT;
+       return 0;
+}
+
+#ifdef CONFIG_PROC_FS
+/*----------------------------------------------------------------
+* proc_read
+*
+* Read function for /proc/net/p80211/<device>/wlandev
+*
+* Arguments:
+*      buf
+*      start
+*      offset
+*      count
+*      eof
+*      data
+* Returns:
+*      zero on success, non-zero otherwise.
+* Call Context:
+*      Can be either interrupt or not.
+----------------------------------------------------------------*/
+static int
+p80211netdev_proc_read(
+       char    *page,
+       char    **start,
+       off_t   offset,
+       int     count,
+       int     *eof,
+       void    *data)
+{
+       char     *p = page;
+       wlandevice_t *wlandev = (wlandevice_t *) data;
+
+       DBFENTER;
+       if (offset != 0) {
+               *eof = 1;
+               goto exit;
+       }
+
+       p += sprintf(p, "p80211 version: %s (%s)\n\n",
+                    WLAN_RELEASE, WLAN_BUILD_DATE);
+       p += sprintf(p, "name       : %s\n", wlandev->name);
+       p += sprintf(p, "nsd name   : %s\n", wlandev->nsdname);
+       p += sprintf(p, "address    : %02x:%02x:%02x:%02x:%02x:%02x\n",
+                    wlandev->netdev->dev_addr[0], wlandev->netdev->dev_addr[1], wlandev->netdev->dev_addr[2],
+                    wlandev->netdev->dev_addr[3], wlandev->netdev->dev_addr[4], wlandev->netdev->dev_addr[5]);
+       p += sprintf(p, "nsd caps   : %s%s%s%s%s%s%s%s%s%s\n",
+                    (wlandev->nsdcaps & P80211_NSDCAP_HARDWAREWEP) ? "wep_hw " : "",
+                    (wlandev->nsdcaps & P80211_NSDCAP_TIEDWEP) ? "wep_tied " : "",
+                    (wlandev->nsdcaps & P80211_NSDCAP_NOHOSTWEP) ? "wep_hw_only " : "",
+                    (wlandev->nsdcaps & P80211_NSDCAP_PBCC) ? "pbcc " : "",
+                    (wlandev->nsdcaps & P80211_NSDCAP_SHORT_PREAMBLE) ? "short_preamble " : "",
+                    (wlandev->nsdcaps & P80211_NSDCAP_AGILITY) ? "agility " : "",
+                    (wlandev->nsdcaps & P80211_NSDCAP_AP_RETRANSMIT) ? "ap_retransmit " : "",
+                    (wlandev->nsdcaps & P80211_NSDCAP_HWFRAGMENT) ? "hw_frag " : "",
+                    (wlandev->nsdcaps & P80211_NSDCAP_AUTOJOIN) ? "autojoin " : "",
+                    (wlandev->nsdcaps & P80211_NSDCAP_NOSCAN) ? "" : "scan ");
+
+
+       p += sprintf(p, "bssid      : %02x:%02x:%02x:%02x:%02x:%02x\n",
+                    wlandev->bssid[0], wlandev->bssid[1], wlandev->bssid[2],
+                    wlandev->bssid[3], wlandev->bssid[4], wlandev->bssid[5]);
+
+       p += sprintf(p, "Enabled    : %s%s\n",
+                    (wlandev->shortpreamble) ? "short_preamble " : "",
+                    (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) ? "privacy" : "");
+
+
+ exit:
+       DBFEXIT;
+       return (p - page);
+}
+#endif
+
+/*----------------------------------------------------------------
+* p80211netdev_hwremoved
+*
+* Hardware removed notification. This function should be called
+* immediately after an MSD has detected that the underlying hardware
+* has been yanked out from under us.  The primary things we need
+* to do are:
+*   - Mark the wlandev
+*   - Prevent any further traffic from the knetdev i/f
+*   - Prevent any further requests from mgmt i/f
+*   - If there are any waitq'd mgmt requests or mgmt-frame exchanges,
+*     shut them down.
+*   - Call the MSD hwremoved function.
+*
+* The remainder of the cleanup will be handled by unregister().
+* Our primary goal here is to prevent as much tickling of the MSD
+* as possible since the MSD is already in a 'wounded' state.
+*
+* TODO: As new features are added, this function should be
+*       updated.
+*
+* Arguments:
+*      wlandev         WLAN network device structure
+* Returns:
+*      nothing
+* Side effects:
+*
+* Call context:
+*      Usually interrupt.
+----------------------------------------------------------------*/
+void p80211netdev_hwremoved(wlandevice_t *wlandev)
+{
+       DBFENTER;
+       wlandev->hwremoved = 1;
+       if ( wlandev->state == WLAN_DEVICE_OPEN) {
+               p80211netdev_stop_queue(wlandev);
+       }
+
+       netif_device_detach(wlandev->netdev);
+
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* p80211_rx_typedrop
+*
+* Classifies the frame, increments the appropriate counter, and
+* returns 0|1|2 indicating whether the driver should handle, ignore, or
+* drop the frame
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      fc              frame control field
+*
+* Returns:
+*      zero if the frame should be handled by the driver,
+*       one if the frame should be ignored
+*       anything else means we drop it.
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc)
+{
+       UINT16  ftype;
+       UINT16  fstype;
+       int     drop = 0;
+       /* Classify frame, increment counter */
+       ftype = WLAN_GET_FC_FTYPE(fc);
+       fstype = WLAN_GET_FC_FSTYPE(fc);
+#if 0
+       WLAN_LOG_DEBUG(4,
+               "rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype);
+#endif
+       switch ( ftype ) {
+       case WLAN_FTYPE_MGMT:
+               if ((wlandev->netdev->flags & IFF_PROMISC) ||
+                       (wlandev->netdev->flags & IFF_ALLMULTI)) {
+                       drop = 1;
+                       break;
+               }
+               WLAN_LOG_DEBUG(3, "rx'd mgmt:\n");
+               wlandev->rx.mgmt++;
+               switch( fstype ) {
+               case WLAN_FSTYPE_ASSOCREQ:
+                       /* printk("assocreq"); */
+                       wlandev->rx.assocreq++;
+                       break;
+               case WLAN_FSTYPE_ASSOCRESP:
+                       /* printk("assocresp"); */
+                       wlandev->rx.assocresp++;
+                       break;
+               case WLAN_FSTYPE_REASSOCREQ:
+                       /* printk("reassocreq"); */
+                       wlandev->rx.reassocreq++;
+                       break;
+               case WLAN_FSTYPE_REASSOCRESP:
+                       /* printk("reassocresp"); */
+                       wlandev->rx.reassocresp++;
+                       break;
+               case WLAN_FSTYPE_PROBEREQ:
+                       /* printk("probereq"); */
+                       wlandev->rx.probereq++;
+                       break;
+               case WLAN_FSTYPE_PROBERESP:
+                       /* printk("proberesp"); */
+                       wlandev->rx.proberesp++;
+                       break;
+               case WLAN_FSTYPE_BEACON:
+                       /* printk("beacon"); */
+                       wlandev->rx.beacon++;
+                       break;
+               case WLAN_FSTYPE_ATIM:
+                       /* printk("atim"); */
+                       wlandev->rx.atim++;
+                       break;
+               case WLAN_FSTYPE_DISASSOC:
+                       /* printk("disassoc"); */
+                       wlandev->rx.disassoc++;
+                       break;
+               case WLAN_FSTYPE_AUTHEN:
+                       /* printk("authen"); */
+                       wlandev->rx.authen++;
+                       break;
+               case WLAN_FSTYPE_DEAUTHEN:
+                       /* printk("deauthen"); */
+                       wlandev->rx.deauthen++;
+                       break;
+               default:
+                       /* printk("unknown"); */
+                       wlandev->rx.mgmt_unknown++;
+                       break;
+               }
+               /* printk("\n"); */
+               drop = 2;
+               break;
+
+       case WLAN_FTYPE_CTL:
+               if ((wlandev->netdev->flags & IFF_PROMISC) ||
+                       (wlandev->netdev->flags & IFF_ALLMULTI)) {
+                       drop = 1;
+                       break;
+               }
+               WLAN_LOG_DEBUG(3, "rx'd ctl:\n");
+               wlandev->rx.ctl++;
+               switch( fstype ) {
+               case WLAN_FSTYPE_PSPOLL:
+                       /* printk("pspoll"); */
+                       wlandev->rx.pspoll++;
+                       break;
+               case WLAN_FSTYPE_RTS:
+                       /* printk("rts"); */
+                       wlandev->rx.rts++;
+                       break;
+               case WLAN_FSTYPE_CTS:
+                       /* printk("cts"); */
+                       wlandev->rx.cts++;
+                       break;
+               case WLAN_FSTYPE_ACK:
+                       /* printk("ack"); */
+                       wlandev->rx.ack++;
+                       break;
+               case WLAN_FSTYPE_CFEND:
+                       /* printk("cfend"); */
+                       wlandev->rx.cfend++;
+                       break;
+               case WLAN_FSTYPE_CFENDCFACK:
+                       /* printk("cfendcfack"); */
+                       wlandev->rx.cfendcfack++;
+                       break;
+               default:
+                       /* printk("unknown"); */
+                       wlandev->rx.ctl_unknown++;
+                       break;
+               }
+               /* printk("\n"); */
+               drop = 2;
+               break;
+
+       case WLAN_FTYPE_DATA:
+               wlandev->rx.data++;
+               switch( fstype ) {
+               case WLAN_FSTYPE_DATAONLY:
+                       wlandev->rx.dataonly++;
+                       break;
+               case WLAN_FSTYPE_DATA_CFACK:
+                       wlandev->rx.data_cfack++;
+                       break;
+               case WLAN_FSTYPE_DATA_CFPOLL:
+                       wlandev->rx.data_cfpoll++;
+                       break;
+               case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
+                       wlandev->rx.data__cfack_cfpoll++;
+                       break;
+               case WLAN_FSTYPE_NULL:
+                       WLAN_LOG_DEBUG(3, "rx'd data:null\n");
+                       wlandev->rx.null++;
+                       break;
+               case WLAN_FSTYPE_CFACK:
+                       WLAN_LOG_DEBUG(3, "rx'd data:cfack\n");
+                       wlandev->rx.cfack++;
+                       break;
+               case WLAN_FSTYPE_CFPOLL:
+                       WLAN_LOG_DEBUG(3, "rx'd data:cfpoll\n");
+                       wlandev->rx.cfpoll++;
+                       break;
+               case WLAN_FSTYPE_CFACK_CFPOLL:
+                       WLAN_LOG_DEBUG(3, "rx'd data:cfack_cfpoll\n");
+                       wlandev->rx.cfack_cfpoll++;
+                       break;
+               default:
+                       /* printk("unknown"); */
+                       wlandev->rx.data_unknown++;
+                       break;
+               }
+
+               break;
+       }
+       return drop;
+}
+
+#ifdef CONFIG_HOTPLUG
+/* Notify userspace when a netdevice event occurs,
+ * by running '/sbin/hotplug net' with certain
+ * environment variables set.
+ */
+int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action)
+{
+        char *argv[3], *envp[7], ifname[12 + IFNAMSIZ], action_str[32];
+       char nsdname[32], wlan_wext[32];
+        int i;
+
+       if (wlandev) {
+               sprintf(ifname, "INTERFACE=%s", wlandev->name);
+               sprintf(nsdname, "NSDNAME=%s", wlandev->nsdname);
+       } else {
+               sprintf(ifname, "INTERFACE=null");
+               sprintf(nsdname, "NSDNAME=null");
+       }
+
+       sprintf(wlan_wext, "WLAN_WEXT=%s", wlan_wext_write ? "y" : "");
+        sprintf(action_str, "ACTION=%s", action);
+
+        i = 0;
+        argv[i++] = hotplug_path;
+        argv[i++] = "wlan";
+        argv[i] = NULL;
+
+        i = 0;
+        /* minimal command environment */
+        envp [i++] = "HOME=/";
+        envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+        envp [i++] = ifname;
+        envp [i++] = action_str;
+        envp [i++] = nsdname;
+        envp [i++] = wlan_wext;
+        envp [i] = NULL;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62))
+        return call_usermodehelper(argv [0], argv, envp);
+#else
+        return call_usermodehelper(argv [0], argv, envp, 0);
+#endif
+}
+
+#endif
+
+
+void    p80211_suspend(wlandevice_t *wlandev)
+{
+       DBFENTER;
+
+#ifdef CONFIG_HOTPLUG
+       p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_SUSPEND);
+#endif
+
+       DBFEXIT;
+}
+
+void    p80211_resume(wlandevice_t *wlandev)
+{
+       DBFENTER;
+
+#ifdef CONFIG_HOTPLUG
+       p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_RESUME);
+#endif
+
+       DBFEXIT;
+}
+
+static void p80211knetdev_tx_timeout( netdevice_t *netdev)
+{
+       wlandevice_t    *wlandev = (wlandevice_t*)netdev->priv;
+       DBFENTER;
+
+       if (wlandev->tx_timeout) {
+               wlandev->tx_timeout(wlandev);
+       } else {
+               WLAN_LOG_WARNING("Implement tx_timeout for %s\n",
+                                wlandev->nsdname);
+               p80211netdev_wake_queue(wlandev);
+       }
+
+       DBFEXIT;
+}
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
new file mode 100644 (file)
index 0000000..9b2e0cd
--- /dev/null
@@ -0,0 +1,336 @@
+/* p80211netdev.h
+*
+* WLAN net device structure and functions
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares the structure type that represents each wlan
+* interface.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _LINUX_P80211NETDEV_H
+#define _LINUX_P80211NETDEV_H
+
+#include <linux/interrupt.h>
+#include <linux/wireless.h>
+
+/*================================================================*/
+/* Constants */
+
+#define WLAN_DEVICE_CLOSED     0
+#define WLAN_DEVICE_OPEN       1
+
+#define WLAN_MACMODE_NONE      0
+#define WLAN_MACMODE_IBSS_STA  1
+#define WLAN_MACMODE_ESS_STA   2
+#define WLAN_MACMODE_ESS_AP    3
+
+/* MSD States */
+#define WLAN_MSD_START                 -1
+#define WLAN_MSD_DRIVERLOADED          0
+#define WLAN_MSD_HWPRESENT_PENDING     1
+#define WLAN_MSD_HWFAIL                        2
+#define WLAN_MSD_HWPRESENT             3
+#define WLAN_MSD_FWLOAD_PENDING                4
+#define WLAN_MSD_FWLOAD                        5
+#define WLAN_MSD_RUNNING_PENDING       6
+#define WLAN_MSD_RUNNING               7
+
+#ifndef ETH_P_ECONET
+#define ETH_P_ECONET   0x0018    /* needed for 2.2.x kernels */
+#endif
+
+#define ETH_P_80211_RAW        (ETH_P_ECONET + 1)
+
+#ifndef ARPHRD_IEEE80211
+#define ARPHRD_IEEE80211 801     /* kernel 2.4.6 */
+#endif
+
+#ifndef ARPHRD_IEEE80211_PRISM  /* kernel 2.4.18 */
+#define ARPHRD_IEEE80211_PRISM 802
+#endif
+
+/*--- NSD Capabilities Flags ------------------------------*/
+#define P80211_NSDCAP_HARDWAREWEP           0x01  /* hardware wep engine */
+#define P80211_NSDCAP_TIEDWEP               0x02  /* can't decouple en/de */
+#define P80211_NSDCAP_NOHOSTWEP             0x04  /* must use hardware wep */
+#define P80211_NSDCAP_PBCC                  0x08  /* hardware supports PBCC */
+#define P80211_NSDCAP_SHORT_PREAMBLE        0x10  /* hardware supports */
+#define P80211_NSDCAP_AGILITY               0x20  /* hardware supports */
+#define P80211_NSDCAP_AP_RETRANSMIT         0x40  /* nsd handles retransmits */
+#define P80211_NSDCAP_HWFRAGMENT            0x80  /* nsd handles frag/defrag */
+#define P80211_NSDCAP_AUTOJOIN              0x100  /* nsd does autojoin */
+#define P80211_NSDCAP_NOSCAN                0x200  /* nsd can scan */
+
+/*================================================================*/
+/* Macros */
+
+/*================================================================*/
+/* Types */
+
+/* Received frame statistics */
+typedef struct p80211_frmrx_t
+{
+       UINT32  mgmt;
+       UINT32  assocreq;
+       UINT32  assocresp;
+       UINT32  reassocreq;
+       UINT32  reassocresp;
+       UINT32  probereq;
+       UINT32  proberesp;
+       UINT32  beacon;
+       UINT32  atim;
+       UINT32  disassoc;
+       UINT32  authen;
+       UINT32  deauthen;
+       UINT32  mgmt_unknown;
+       UINT32  ctl;
+       UINT32  pspoll;
+       UINT32  rts;
+       UINT32  cts;
+       UINT32  ack;
+       UINT32  cfend;
+       UINT32  cfendcfack;
+       UINT32  ctl_unknown;
+       UINT32  data;
+       UINT32  dataonly;
+       UINT32  data_cfack;
+       UINT32  data_cfpoll;
+       UINT32  data__cfack_cfpoll;
+       UINT32  null;
+       UINT32  cfack;
+       UINT32  cfpoll;
+       UINT32  cfack_cfpoll;
+       UINT32  data_unknown;
+       UINT32  decrypt;
+       UINT32  decrypt_err;
+} p80211_frmrx_t;
+
+#ifdef WIRELESS_EXT
+/* called by /proc/net/wireless */
+struct iw_statistics* p80211wext_get_wireless_stats(netdevice_t *dev);
+/* wireless extensions' ioctls */
+int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
+#if WIRELESS_EXT > 12
+extern struct iw_handler_def p80211wext_handler_def;
+#endif
+
+int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
+
+#endif /* wireless extensions */
+
+/* WEP stuff */
+#define NUM_WEPKEYS 4
+#define MAX_KEYLEN 32
+
+#define HOSTWEP_DEFAULTKEY_MASK (BIT1|BIT0)
+#define HOSTWEP_DECRYPT  BIT4
+#define HOSTWEP_ENCRYPT  BIT5
+#define HOSTWEP_PRIVACYINVOKED BIT6
+#define HOSTWEP_EXCLUDEUNENCRYPTED BIT7
+
+extern int wlan_watchdog;
+extern int wlan_wext_write;
+
+/* WLAN device type */
+typedef struct wlandevice
+{
+       struct wlandevice       *next;          /* link for list of devices */
+       void                    *priv;          /* private data for MSD */
+
+       /* Subsystem State */
+       char            name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev()*/
+       char            *nsdname;
+
+       UINT32          state;          /* Device I/F state (open/closed) */
+       UINT32          msdstate;       /* state of underlying driver */
+       UINT32          hwremoved;      /* Has the hw been yanked out? */
+
+       /* Hardware config */
+       UINT            irq;
+       UINT            iobase;
+       UINT            membase;
+       UINT32          nsdcaps;  /* NSD Capabilities flags */
+
+       /* Config vars */
+       UINT            ethconv;
+
+       /* device methods (init by MSD, used by p80211 */
+       int             (*open)(struct wlandevice *wlandev);
+       int             (*close)(struct wlandevice *wlandev);
+       void            (*reset)(struct wlandevice *wlandev );
+       int             (*txframe)(struct wlandevice *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+       int             (*mlmerequest)(struct wlandevice *wlandev, p80211msg_t *msg);
+       int             (*set_multicast_list)(struct wlandevice *wlandev,
+                                             netdevice_t *dev);
+       void            (*tx_timeout)(struct wlandevice *wlandev);
+
+#ifdef CONFIG_PROC_FS
+       int             (*nsd_proc_read)(char *page, char **start, off_t offset, int count, int *eof, void *data);
+#endif
+
+       /* 802.11 State */
+       UINT8           bssid[WLAN_BSSID_LEN];
+       p80211pstr32_t  ssid;
+       UINT32          macmode;
+       int             linkstatus;
+       int             shortpreamble;  /* C bool */
+
+       /* WEP State */
+       UINT8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN];
+       UINT8 wep_keylens[NUM_WEPKEYS];
+       int   hostwep;
+
+       /* Request/Confirm i/f state (used by p80211) */
+       unsigned long           request_pending; /* flag, access atomically */
+
+       /* netlink socket */
+       /* queue for indications waiting for cmd completion */
+       /* Linux netdevice and support */
+       netdevice_t             *netdev;        /* ptr to linux netdevice */
+       struct net_device_stats linux_stats;
+
+#ifdef CONFIG_PROC_FS
+       /* Procfs support */
+       struct proc_dir_entry   *procdir;
+       struct proc_dir_entry   *procwlandev;
+#endif
+
+       /* Rx bottom half */
+       struct tasklet_struct   rx_bh;
+
+       struct sk_buff_head     nsd_rxq;
+
+       /* 802.11 device statistics */
+       struct p80211_frmrx_t   rx;
+
+/* compatibility to wireless extensions */
+#ifdef WIRELESS_EXT
+       struct iw_statistics    wstats;
+
+       /* jkriegl: iwspy fields */
+        UINT8                  spy_number;
+        char                   spy_address[IW_MAX_SPY][ETH_ALEN];
+        struct iw_quality       spy_stat[IW_MAX_SPY];
+
+#endif
+
+} wlandevice_t;
+
+/* WEP stuff */
+int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen);
+int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv);
+int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv);
+
+/*================================================================*/
+/* Externs */
+
+/*================================================================*/
+/* Function Declarations */
+
+void   p80211netdev_startup(void);
+void   p80211netdev_shutdown(void);
+int    wlan_setup(wlandevice_t *wlandev);
+int    wlan_unsetup(wlandevice_t *wlandev);
+int    register_wlandev(wlandevice_t *wlandev);
+int    unregister_wlandev(wlandevice_t *wlandev);
+void   p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void   p80211netdev_hwremoved(wlandevice_t *wlandev);
+void    p80211_suspend(wlandevice_t *wlandev);
+void    p80211_resume(wlandevice_t *wlandev);
+
+/*================================================================*/
+/* Function Definitions */
+
+static inline void
+p80211netdev_stop_queue(wlandevice_t *wlandev)
+{
+       if ( !wlandev ) return;
+       if ( !wlandev->netdev ) return;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+       wlandev->netdev->tbusy = 1;
+       wlandev->netdev->start = 0;
+#else
+       netif_stop_queue(wlandev->netdev);
+#endif
+}
+
+static inline void
+p80211netdev_start_queue(wlandevice_t *wlandev)
+{
+       if ( !wlandev ) return;
+       if ( !wlandev->netdev ) return;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+       wlandev->netdev->tbusy = 0;
+       wlandev->netdev->start = 1;
+#else
+       netif_start_queue(wlandev->netdev);
+#endif
+}
+
+static inline void
+p80211netdev_wake_queue(wlandevice_t *wlandev)
+{
+       if ( !wlandev ) return;
+       if ( !wlandev->netdev ) return;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+       wlandev->netdev->tbusy = 0;
+       mark_bh(NET_BH);
+#else
+       netif_wake_queue(wlandev->netdev);
+#endif
+}
+
+#ifdef CONFIG_HOTPLUG
+#define WLAN_HOTPLUG_REGISTER "register"
+#define WLAN_HOTPLUG_REMOVE   "remove"
+#define WLAN_HOTPLUG_STARTUP  "startup"
+#define WLAN_HOTPLUG_SHUTDOWN "shutdown"
+#define WLAN_HOTPLUG_SUSPEND "suspend"
+#define WLAN_HOTPLUG_RESUME "resume"
+int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action);
+#endif
+
+#endif
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
new file mode 100644 (file)
index 0000000..0233abe
--- /dev/null
@@ -0,0 +1,329 @@
+/* src/p80211/p80211req.c
+*
+* Request/Indication/MacMgmt interface handling functions
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file contains the functions, types, and macros to support the
+* MLME request interface that's implemented via the device ioctls.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <net/sock.h>
+#include <linux/netlink.h>
+
+#include "version.h"
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211ioctl.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "p80211req.h"
+
+/*================================================================*/
+/* Local Constants */
+
+/* Maximum amount of time we'll wait for a request to complete */
+#define P80211REQ_MAXTIME      3*HZ    /* 3 seconds */
+
+/*================================================================*/
+/* Local Macros */
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+
+/*================================================================*/
+/* Local Function Declarations */
+
+static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg);
+static int p80211req_mibset_mibget(wlandevice_t *wlandev, p80211msg_dot11req_mibget_t *mib_msg, int isget);
+
+/*================================================================*/
+/* Function Definitions */
+
+
+/*----------------------------------------------------------------
+* p80211req_dorequest
+*
+* Handles an MLME reqest/confirm message.
+*
+* Arguments:
+*      wlandev         WLAN device struct
+*      msgbuf          Buffer containing a request message
+*
+* Returns:
+*      0 on success, an errno otherwise
+*
+* Call context:
+*      Potentially blocks the caller, so it's a good idea to
+*      not call this function from an interrupt context.
+----------------------------------------------------------------*/
+int p80211req_dorequest( wlandevice_t *wlandev, UINT8 *msgbuf)
+{
+       int             result = 0;
+       p80211msg_t     *msg = (p80211msg_t*)msgbuf;
+
+       DBFENTER;
+
+       /* Check to make sure the MSD is running */
+       if (
+       !((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
+       msg->msgcode == DIDmsg_lnxreq_ifstate) ||
+       wlandev->msdstate == WLAN_MSD_RUNNING ||
+       wlandev->msdstate == WLAN_MSD_FWLOAD) ) {
+               return -ENODEV;
+       }
+
+       /* Check Permissions */
+       if (!capable(CAP_NET_ADMIN) &&
+           (msg->msgcode != DIDmsg_dot11req_mibget)) {
+               WLAN_LOG_ERROR("%s: only dot11req_mibget allowed for non-root.\n", wlandev->name);
+               return -EPERM;
+       }
+
+       /* Check for busy status */
+       if ( test_and_set_bit(1, &(wlandev->request_pending))) {
+               return -EBUSY;
+       }
+
+       /* Allow p80211 to look at msg and handle if desired. */
+       /* So far, all p80211 msgs are immediate, no waitq/timer necessary */
+       /* This may change. */
+       p80211req_handlemsg(wlandev, msg);
+
+       /* Pass it down to wlandev via wlandev->mlmerequest */
+       if ( wlandev->mlmerequest != NULL )
+               wlandev->mlmerequest(wlandev, msg);
+
+       clear_bit( 1, &(wlandev->request_pending));
+       DBFEXIT;
+       return result;  /* if result==0, msg->status still may contain an err */
+}
+
+/*----------------------------------------------------------------
+* p80211req_handlemsg
+*
+* p80211 message handler.  Primarily looks for messages that
+* belong to p80211 and then dispatches the appropriate response.
+* TODO: we don't do anything yet.  Once the linuxMIB is better
+*      defined we'll need a get/set handler.
+*
+* Arguments:
+*      wlandev         WLAN device struct
+*      msg             message structure
+*
+* Returns:
+*      nothing (any results are set in the status field of the msg)
+*
+* Call context:
+*      Process thread
+----------------------------------------------------------------*/
+static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg)
+{
+        DBFENTER;
+
+       switch (msg->msgcode) {
+
+       case DIDmsg_lnxreq_hostwep: {
+               p80211msg_lnxreq_hostwep_t *req = (p80211msg_lnxreq_hostwep_t*) msg;
+               wlandev->hostwep &= ~(HOSTWEP_DECRYPT|HOSTWEP_ENCRYPT);
+               if (req->decrypt.data == P80211ENUM_truth_true)
+                       wlandev->hostwep |= HOSTWEP_DECRYPT;
+               if (req->encrypt.data == P80211ENUM_truth_true)
+                       wlandev->hostwep |= HOSTWEP_ENCRYPT;
+
+               break;
+       }
+       case DIDmsg_dot11req_mibget:
+       case DIDmsg_dot11req_mibset: {
+               int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
+               p80211msg_dot11req_mibget_t  *mib_msg = (p80211msg_dot11req_mibget_t *) msg;
+               p80211req_mibset_mibget (wlandev, mib_msg, isget);
+       }
+       default:
+               // XXX do nothing!
+               ;
+       } /* switch msg->msgcode */
+
+       DBFEXIT;
+
+       return;
+}
+
+static int p80211req_mibset_mibget(wlandevice_t *wlandev,
+                                  p80211msg_dot11req_mibget_t *mib_msg,
+                                  int isget)
+{
+       p80211itemd_t   *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
+       p80211pstrd_t  *pstr = (p80211pstrd_t*) mibitem->data;
+       UINT8 *key = mibitem->data + sizeof(p80211pstrd_t);
+
+       DBFENTER;
+
+       switch (mibitem->did) {
+       case DIDmib_dot11smt_p80211Table_p80211_ifstate: {
+               UINT32 *data = (UINT32 *) mibitem->data;
+               if (isget)
+                       switch (wlandev->msdstate) {
+                       case WLAN_MSD_HWPRESENT:
+                               *data = P80211ENUM_ifstate_disable;
+                               break;
+                       case WLAN_MSD_FWLOAD:
+                               *data = P80211ENUM_ifstate_fwload;
+                               break;
+                       case WLAN_MSD_RUNNING:
+                               *data = P80211ENUM_ifstate_enable;
+                               break;
+                       default:
+                               *data = P80211ENUM_ifstate_enable;
+                       }
+               break;
+       }
+       case DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled: {
+               UINT32 *data = (UINT32 *) mibitem->data;
+
+               if (isget)
+                       *data = wlandev->shortpreamble;
+               else
+                       wlandev->shortpreamble = *data;
+               break;
+       }
+       case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0: {
+               if (!isget)
+                       wep_change_key(wlandev, 0, key, pstr->len);
+               break;
+       }
+       case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1: {
+               if (!isget)
+                       wep_change_key(wlandev, 1, key, pstr->len);
+               break;
+       }
+       case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2: {
+               if (!isget)
+                       wep_change_key(wlandev, 2, key, pstr->len);
+               break;
+       }
+       case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3: {
+               if (!isget)
+                       wep_change_key(wlandev, 3, key, pstr->len);
+               break;
+       }
+       case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID: {
+               UINT32 *data = (UINT32 *) mibitem->data;
+
+               if (isget) {
+                       *data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
+                       } else {
+                               wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK);
+
+                               wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK);
+                       }
+               break;
+       }
+       case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked: {
+               UINT32 *data = (UINT32 *) mibitem->data;
+
+               if (isget) {
+                       if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
+                               *data = P80211ENUM_truth_true;
+                       else
+                               *data = P80211ENUM_truth_false;
+               } else {
+                               wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED);
+                               if (*data == P80211ENUM_truth_true)
+                                       wlandev->hostwep |= HOSTWEP_PRIVACYINVOKED;
+               }
+               break;
+       }
+       case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted: {
+               UINT32 *data = (UINT32 *) mibitem->data;
+
+               if (isget) {
+                       if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
+                               *data = P80211ENUM_truth_true;
+                       else
+                               *data = P80211ENUM_truth_false;
+               } else {
+                       wlandev->hostwep &= ~(HOSTWEP_EXCLUDEUNENCRYPTED);
+                       if (*data == P80211ENUM_truth_true)
+                               wlandev->hostwep |= HOSTWEP_EXCLUDEUNENCRYPTED;
+               }
+               break;
+       }
+       default:
+               // XXXX do nothing!
+               ;
+       }
+
+       DBFEXIT;
+       return 0;
+}
+
diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h
new file mode 100644 (file)
index 0000000..54abdce
--- /dev/null
@@ -0,0 +1,68 @@
+/* p80211req.h
+*
+* Request handling functions
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _LINUX_P80211REQ_H
+#define _LINUX_P80211REQ_H
+
+/*================================================================*/
+/* Constants */
+
+/*================================================================*/
+/* Macros */
+
+/*================================================================*/
+/* Types */
+
+/*================================================================*/
+/* Externs */
+
+/*================================================================*/
+/* Function Declarations */
+
+int    p80211req_dorequest(wlandevice_t *wlandev, UINT8 *msgbuf);
+
+#endif
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
new file mode 100644 (file)
index 0000000..811b0ce
--- /dev/null
@@ -0,0 +1,675 @@
+/* p80211types.h
+*
+* Macros, constants, types, and funcs for p80211 data types
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares some of the constants and types used in various
+* parts of the linux-wlan system.
+*
+* Notes:
+*   - Constant values are always in HOST byte order.
+*
+* All functions and statics declared here are implemented in p80211types.c
+*   --------------------------------------------------------------------
+*/
+
+#ifndef _P80211TYPES_H
+#define _P80211TYPES_H
+
+/*================================================================*/
+/* System Includes */
+/*================================================================*/
+
+/*================================================================*/
+/* Project Includes */
+/*================================================================*/
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+/*================================================================*/
+
+/*----------------------------------------------------------------*/
+/* p80211 data type codes used for MIB items and message */
+/* arguments. The various metadata structures provide additional */
+/* information about these types. */
+
+#define P80211_TYPE_OCTETSTR           1       /* pascal array of bytes */
+#define P80211_TYPE_DISPLAYSTR         2       /* pascal array of bytes containing ascii */
+#define P80211_TYPE_INT                        4       /* UINT32 min and max limited by 32 bits */
+#define P80211_TYPE_ENUMINT            5       /* UINT32 holding a numeric
+                                                  code that can be mapped
+                                                  to a textual name */
+#define P80211_TYPE_UNKDATA            6       /* Data item containing an
+                                                  unknown data type */
+#define P80211_TYPE_INTARRAY           7       /* Array of 32-bit integers. */
+#define P80211_TYPE_BITARRAY           8       /* Array of bits. */
+#define P80211_TYPE_MACARRAY           9       /* Array of MAC addresses. */
+
+/*----------------------------------------------------------------*/
+/* The following constants are indexes into the Mib Category List */
+/* and the Message Category List */
+
+/* Mib Category List */
+#define P80211_MIB_CAT_DOT11SMT                1
+#define P80211_MIB_CAT_DOT11MAC                2
+#define P80211_MIB_CAT_DOT11PHY                3
+
+#define P80211SEC_DOT11SMT             P80211_MIB_CAT_DOT11SMT
+#define P80211SEC_DOT11MAC             P80211_MIB_CAT_DOT11MAC
+#define P80211SEC_DOT11PHY             P80211_MIB_CAT_DOT11PHY
+
+/* Message Category List */
+#define P80211_MSG_CAT_DOT11REQ                1
+#define P80211_MSG_CAT_DOT11IND                2
+/* #define P80211_MSG_CAT_DOT11CFM             3 (doesn't exist at this time) */
+
+#define P80211SEC_DOT11REQ             P80211_MSG_CAT_DOT11REQ
+#define P80211SEC_DOT11IND             P80211_MSG_CAT_DOT11IND
+/* #define P80211SEC_DOT11CFM          P80211_MSG_CAT_DOT11CFM  (doesn't exist at this time */
+
+
+
+/*----------------------------------------------------------------*/
+/* p80211 DID field codes that represent access type and */
+/* is_table status. */
+
+#define P80211DID_ACCESS_READ          0x10000000
+#define P80211DID_ACCESS_WRITE         0x08000000
+#define P80211DID_WRITEONLY            0x00000001
+#define P80211DID_READONLY             0x00000002
+#define P80211DID_READWRITE            0x00000003
+#define P80211DID_ISTABLE_FALSE                0
+#define P80211DID_ISTABLE_TRUE         1
+
+/*----------------------------------------------------------------*/
+/* p80211 enumeration constants.  The value to text mappings for */
+/*  these is in p80211types.c.  These defines were generated */
+/*  from the mappings. */
+
+/* error codes for lookups */
+#define P80211ENUM_BAD                         0xffffffffUL
+#define P80211ENUM_BADSTR                      "P80211ENUM_BAD"
+
+#define P80211ENUM_truth_false                 0
+#define P80211ENUM_truth_true                  1
+#define P80211ENUM_ifstate_disable             0
+#define P80211ENUM_ifstate_fwload              1
+#define P80211ENUM_ifstate_enable              2
+#define P80211ENUM_powermgmt_active            1
+#define P80211ENUM_powermgmt_powersave         2
+#define P80211ENUM_bsstype_infrastructure      1
+#define P80211ENUM_bsstype_independent         2
+#define P80211ENUM_bsstype_any                 3
+#define P80211ENUM_authalg_opensystem          1
+#define P80211ENUM_authalg_sharedkey           2
+#define P80211ENUM_phytype_fhss                        1
+#define P80211ENUM_phytype_dsss                        2
+#define P80211ENUM_phytype_irbaseband          3
+#define P80211ENUM_temptype_commercial         1
+#define P80211ENUM_temptype_industrial         2
+#define P80211ENUM_regdomain_fcc               16
+#define P80211ENUM_regdomain_doc               32
+#define P80211ENUM_regdomain_etsi              48
+#define P80211ENUM_regdomain_spain             49
+#define P80211ENUM_regdomain_france            50
+#define P80211ENUM_regdomain_mkk               64
+#define P80211ENUM_ccamode_edonly              1
+#define P80211ENUM_ccamode_csonly              2
+#define P80211ENUM_ccamode_edandcs             4
+#define P80211ENUM_ccamode_cswithtimer         8
+#define P80211ENUM_ccamode_hrcsanded           16
+#define P80211ENUM_diversity_fixedlist         1
+#define P80211ENUM_diversity_notsupported      2
+#define P80211ENUM_diversity_dynamic           3
+#define P80211ENUM_scantype_active             1
+#define P80211ENUM_scantype_passive            2
+#define P80211ENUM_scantype_both               3
+#define P80211ENUM_resultcode_success          1
+#define P80211ENUM_resultcode_invalid_parameters       2
+#define P80211ENUM_resultcode_not_supported    3
+#define P80211ENUM_resultcode_timeout          4
+#define P80211ENUM_resultcode_too_many_req     5
+#define P80211ENUM_resultcode_refused          6
+#define P80211ENUM_resultcode_bss_already      7
+#define P80211ENUM_resultcode_invalid_access   8
+#define P80211ENUM_resultcode_invalid_mibattribute     9
+#define P80211ENUM_resultcode_cant_set_readonly_mib    10
+#define P80211ENUM_resultcode_implementation_failure   11
+#define P80211ENUM_resultcode_cant_get_writeonly_mib   12
+#define P80211ENUM_reason_unspec_reason                1
+#define P80211ENUM_reason_auth_not_valid       2
+#define P80211ENUM_reason_deauth_lv_ss         3
+#define P80211ENUM_reason_inactivity           4
+#define P80211ENUM_reason_ap_overload          5
+#define P80211ENUM_reason_class23_err          6
+#define P80211ENUM_reason_class3_err           7
+#define P80211ENUM_reason_disas_lv_ss          8
+#define P80211ENUM_reason_asoc_not_auth                9
+#define P80211ENUM_status_successful           0
+#define P80211ENUM_status_unspec_failure       1
+#define P80211ENUM_status_unsup_cap            10
+#define P80211ENUM_status_reasoc_no_asoc       11
+#define P80211ENUM_status_fail_other           12
+#define P80211ENUM_status_unspt_alg            13
+#define P80211ENUM_status_auth_seq_fail                14
+#define P80211ENUM_status_chlng_fail           15
+#define P80211ENUM_status_auth_timeout         16
+#define P80211ENUM_status_ap_full              17
+#define P80211ENUM_status_unsup_rate           18
+#define P80211ENUM_status_unsup_shortpreamble  19
+#define P80211ENUM_status_unsup_pbcc           20
+#define P80211ENUM_status_unsup_agility                21
+#define P80211ENUM_msgitem_status_data_ok              0
+#define P80211ENUM_msgitem_status_no_value             1
+#define P80211ENUM_msgitem_status_invalid_itemname     2
+#define P80211ENUM_msgitem_status_invalid_itemdata     3
+#define P80211ENUM_msgitem_status_missing_itemdata     4
+#define P80211ENUM_msgitem_status_incomplete_itemdata  5
+#define P80211ENUM_msgitem_status_invalid_msg_did      6
+#define P80211ENUM_msgitem_status_invalid_mib_did      7
+#define P80211ENUM_msgitem_status_missing_conv_func    8
+#define P80211ENUM_msgitem_status_string_too_long      9
+#define P80211ENUM_msgitem_status_data_out_of_range    10
+#define P80211ENUM_msgitem_status_string_too_short     11
+#define P80211ENUM_msgitem_status_missing_valid_func   12
+#define P80211ENUM_msgitem_status_unknown              13
+#define P80211ENUM_msgitem_status_invalid_did          14
+#define P80211ENUM_msgitem_status_missing_print_func   15
+
+#define P80211ENUM_lnxroam_reason_unknown        0
+#define P80211ENUM_lnxroam_reason_beacon         1
+#define P80211ENUM_lnxroam_reason_signal         2
+#define P80211ENUM_lnxroam_reason_txretry        3
+#define P80211ENUM_lnxroam_reason_notjoined      4
+
+#define P80211ENUM_p2preamble_long               0
+#define P80211ENUM_p2preamble_short              2
+#define P80211ENUM_p2preamble_mixed              3
+
+/*----------------------------------------------------------------*/
+/* p80211 max length constants for the different pascal strings. */
+
+#define MAXLEN_PSTR6           (6)     /* pascal array of 6 bytes */
+#define MAXLEN_PSTR14          (14)    /* pascal array of 14 bytes */
+#define MAXLEN_PSTR32          (32)    /* pascal array of 32 bytes */
+#define MAXLEN_PSTR255         (255)   /* pascal array of 255 bytes */
+#define MAXLEN_MIBATTRIBUTE    (392)   /* maximum mibattribute */
+                                       /* where the size of the DATA itself */
+                                       /* is a DID-LEN-DATA triple */
+                                       /* with a max size of 4+4+384 */
+
+#define P80211_SET_INT(item, value) do { \
+       (item).data   = (value); \
+       (item).status = P80211ENUM_msgitem_status_data_ok; \
+       } while(0)
+/*----------------------------------------------------------------*/
+/* string constants */
+
+#define NOT_SET                        "NOT_SET"
+#define NOT_SUPPORTED          "NOT_SUPPORTED"
+#define UNKNOWN_DATA           "UNKNOWN_DATA"
+
+
+/*--------------------------------------------------------------------*/
+/*  Metadata flags  */
+
+/* MSM: Do these belong in p80211meta.h? I'm not sure. */
+
+#define ISREQUIRED             (0x80000000UL)
+#define ISREQUEST              (0x40000000UL)
+#define ISCONFIRM              (0x20000000UL)
+
+
+/*================================================================*/
+/* Macros */
+
+/*--------------------------------------------------------------------*/
+/* The following macros are used to manipulate the 'flags' field in   */
+/*  the metadata.  These are only used when the metadata is for       */
+/*  command arguments to determine if the data item is required, and  */
+/*  whether the metadata item is for a request command, confirm       */
+/*  command or both.                                                  */
+/*--------------------------------------------------------------------*/
+/* MSM: Do these belong in p80211meta.h?  I'm not sure */
+
+#define P80211ITEM_SETFLAGS(q, r, c)   ( q | r | c )
+
+#define P80211ITEM_ISREQUIRED(flags)   (((UINT32)(flags & ISREQUIRED)) >> 31 )
+#define P80211ITEM_ISREQUEST(flags)    (((UINT32)(flags & ISREQUEST)) >> 30 )
+#define P80211ITEM_ISCONFIRM(flags)    (((UINT32)(flags & ISCONFIRM)) >> 29 )
+
+/*----------------------------------------------------------------*/
+/* The following macro creates a name for an enum */
+
+#define MKENUMNAME(name) p80211enum_ ## name
+
+/*----------------------------------------------------------------
+* The following constants and macros are used to construct and
+* deconstruct the Data ID codes.  The coding is as follows:
+*
+*     ...rwtnnnnnnnniiiiiiggggggssssss      s - Section
+*                                           g - Group
+*                                           i - Item
+*                                           n - Index
+*                                           t - Table flag
+*                                           w - Write flag
+*                                           r - Read flag
+*                                           . - Unused
+*/
+
+#define P80211DID_INVALID              0xffffffffUL
+#define P80211DID_VALID                        0x00000000UL
+
+#define P80211DID_LSB_SECTION          (0)
+#define P80211DID_LSB_GROUP            (6)
+#define P80211DID_LSB_ITEM             (12)
+#define P80211DID_LSB_INDEX            (18)
+#define P80211DID_LSB_ISTABLE          (26)
+#define P80211DID_LSB_ACCESS           (27)
+
+#define P80211DID_MASK_SECTION         (0x0000003fUL)
+#define P80211DID_MASK_GROUP           (0x0000003fUL)
+#define P80211DID_MASK_ITEM            (0x0000003fUL)
+#define P80211DID_MASK_INDEX           (0x000000ffUL)
+#define P80211DID_MASK_ISTABLE         (0x00000001UL)
+#define P80211DID_MASK_ACCESS          (0x00000003UL)
+
+
+#define P80211DID_MK(a,m,l)    ((((UINT32)(a)) & (m)) << (l))
+
+#define P80211DID_MKSECTION(a) P80211DID_MK(a, \
+                                       P80211DID_MASK_SECTION, \
+                                       P80211DID_LSB_SECTION )
+#define P80211DID_MKGROUP(a)   P80211DID_MK(a, \
+                                       P80211DID_MASK_GROUP, \
+                                       P80211DID_LSB_GROUP )
+#define P80211DID_MKITEM(a)    P80211DID_MK(a, \
+                                       P80211DID_MASK_ITEM, \
+                                       P80211DID_LSB_ITEM )
+#define P80211DID_MKINDEX(a)   P80211DID_MK(a, \
+                                       P80211DID_MASK_INDEX, \
+                                       P80211DID_LSB_INDEX )
+#define P80211DID_MKISTABLE(a) P80211DID_MK(a, \
+                                       P80211DID_MASK_ISTABLE, \
+                                       P80211DID_LSB_ISTABLE )
+
+
+#define P80211DID_MKID(s,g,i,n,t,a)    (P80211DID_MKSECTION(s) | \
+                                               P80211DID_MKGROUP(g) | \
+                                               P80211DID_MKITEM(i) | \
+                                               P80211DID_MKINDEX(n) | \
+                                               P80211DID_MKISTABLE(t) | \
+                                               (a) )
+
+
+#define P80211DID_GET(a,m,l)   ((((UINT32)(a)) >> (l)) & (m))
+
+#define P80211DID_SECTION(a)   P80211DID_GET(a, \
+                                       P80211DID_MASK_SECTION, \
+                                       P80211DID_LSB_SECTION)
+#define P80211DID_GROUP(a)     P80211DID_GET(a, \
+                                       P80211DID_MASK_GROUP, \
+                                       P80211DID_LSB_GROUP)
+#define P80211DID_ITEM(a)      P80211DID_GET(a, \
+                                       P80211DID_MASK_ITEM, \
+                                       P80211DID_LSB_ITEM)
+#define P80211DID_INDEX(a)     P80211DID_GET(a, \
+                                       P80211DID_MASK_INDEX, \
+                                       P80211DID_LSB_INDEX)
+#define P80211DID_ISTABLE(a)   P80211DID_GET(a, \
+                                       P80211DID_MASK_ISTABLE, \
+                                       P80211DID_LSB_ISTABLE)
+#define P80211DID_ACCESS(a)    P80211DID_GET(a, \
+                                       P80211DID_MASK_ACCESS, \
+                                       P80211DID_LSB_ACCESS)
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* The following structure types are used for the represenation */
+/*  of ENUMINT type metadata. */
+
+typedef struct p80211enumpair
+{
+       UINT32                  val;
+       char                    *name;
+} p80211enumpair_t;
+
+typedef struct p80211enum
+{
+       INT                     nitems;
+       p80211enumpair_t        *list;
+} p80211enum_t;
+
+/*----------------------------------------------------------------*/
+/* The following structure types are used to store data items in */
+/*  messages. */
+
+/* Template pascal string */
+typedef struct p80211pstr
+{
+       UINT8           len;
+} __WLAN_ATTRIB_PACK__ p80211pstr_t;
+
+typedef struct p80211pstrd
+{
+       UINT8           len;
+       UINT8           data[0];
+} __WLAN_ATTRIB_PACK__ p80211pstrd_t;
+
+/* Maximum pascal string */
+typedef struct p80211pstr255
+{
+       UINT8           len;
+       UINT8           data[MAXLEN_PSTR255];
+} __WLAN_ATTRIB_PACK__ p80211pstr255_t;
+
+/* pascal string for macaddress and bssid */
+typedef struct p80211pstr6
+{
+       UINT8           len;
+       UINT8           data[MAXLEN_PSTR6];
+} __WLAN_ATTRIB_PACK__ p80211pstr6_t;
+
+/* pascal string for channel list */
+typedef struct p80211pstr14
+{
+       UINT8           len;
+       UINT8           data[MAXLEN_PSTR14];
+} __WLAN_ATTRIB_PACK__ p80211pstr14_t;
+
+/* pascal string for ssid */
+typedef struct p80211pstr32
+{
+       UINT8           len;
+       UINT8           data[MAXLEN_PSTR32];
+} __WLAN_ATTRIB_PACK__ p80211pstr32_t;
+
+/* MAC address array */
+typedef struct p80211macarray
+{
+       UINT32          cnt;
+       UINT8           data[1][MAXLEN_PSTR6];
+} __WLAN_ATTRIB_PACK__ p80211macarray_t;
+
+/* prototype template */
+typedef struct p80211item
+{
+       UINT32          did;
+       UINT16          status;
+       UINT16          len;
+} __WLAN_ATTRIB_PACK__ p80211item_t;
+
+/* prototype template w/ data item */
+typedef struct p80211itemd
+{
+       UINT32          did;
+       UINT16          status;
+       UINT16          len;
+       UINT8           data[0];
+} __WLAN_ATTRIB_PACK__ p80211itemd_t;
+
+/* message data item for INT, BOUNDEDINT, ENUMINT */
+typedef struct p80211item_uint32
+{
+       UINT32          did;
+       UINT16          status;
+       UINT16          len;
+       UINT32          data;
+} __WLAN_ATTRIB_PACK__ p80211item_uint32_t;
+
+/* message data item for OCTETSTR, DISPLAYSTR */
+typedef struct p80211item_pstr6
+{
+       UINT32          did;
+       UINT16          status;
+       UINT16          len;
+       p80211pstr6_t   data;
+} __WLAN_ATTRIB_PACK__ p80211item_pstr6_t;
+
+/* message data item for OCTETSTR, DISPLAYSTR */
+typedef struct p80211item_pstr14
+{
+       UINT32                  did;
+       UINT16                  status;
+       UINT16                  len;
+       p80211pstr14_t          data;
+} __WLAN_ATTRIB_PACK__ p80211item_pstr14_t;
+
+/* message data item for OCTETSTR, DISPLAYSTR */
+typedef struct p80211item_pstr32
+{
+       UINT32                  did;
+       UINT16                  status;
+       UINT16                  len;
+       p80211pstr32_t          data;
+} __WLAN_ATTRIB_PACK__ p80211item_pstr32_t;
+
+/* message data item for OCTETSTR, DISPLAYSTR */
+typedef struct p80211item_pstr255
+{
+       UINT32                  did;
+       UINT16                  status;
+       UINT16                  len;
+       p80211pstr255_t         data;
+} __WLAN_ATTRIB_PACK__ p80211item_pstr255_t;
+
+/* message data item for UNK 392, namely mib items */
+typedef struct  p80211item_unk392
+{
+       UINT32          did;
+       UINT16          status;
+       UINT16          len;
+       UINT8           data[MAXLEN_MIBATTRIBUTE];
+} __WLAN_ATTRIB_PACK__ p80211item_unk392_t;
+
+/* message data item for UNK 1025, namely p2 pdas */
+typedef struct  p80211item_unk1024
+{
+       UINT32          did;
+       UINT16          status;
+       UINT16          len;
+       UINT8           data[1024];
+}  __WLAN_ATTRIB_PACK__ p80211item_unk1024_t;
+
+/* message data item for UNK 4096, namely p2 download chunks */
+typedef struct  p80211item_unk4096
+{
+       UINT32          did;
+       UINT16          status;
+       UINT16          len;
+       UINT8           data[4096];
+}  __WLAN_ATTRIB_PACK__ p80211item_unk4096_t;
+
+struct catlistitem;
+
+/*----------------------------------------------------------------*/
+/* The following structure type is used to represent all of the */
+/*  metadata items.  Some components may choose to use more, */
+/*  less or different metadata items. */
+
+typedef void (*p80211_totext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf);
+typedef void (*p80211_fromtext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf);
+typedef UINT32 (*p80211_valid_t)( struct catlistitem *, UINT32 did, UINT8* itembuf);
+
+
+/*================================================================*/
+/* Extern Declarations */
+
+/*----------------------------------------------------------------*/
+/* Enumeration Lists */
+/*  The following are the external declarations */
+/*  for all enumerations  */
+
+extern p80211enum_t MKENUMNAME(truth);
+extern p80211enum_t MKENUMNAME(ifstate);
+extern p80211enum_t MKENUMNAME(powermgmt);
+extern p80211enum_t MKENUMNAME(bsstype);
+extern p80211enum_t MKENUMNAME(authalg);
+extern p80211enum_t MKENUMNAME(phytype);
+extern p80211enum_t MKENUMNAME(temptype);
+extern p80211enum_t MKENUMNAME(regdomain);
+extern p80211enum_t MKENUMNAME(ccamode);
+extern p80211enum_t MKENUMNAME(diversity);
+extern p80211enum_t MKENUMNAME(scantype);
+extern p80211enum_t MKENUMNAME(resultcode);
+extern p80211enum_t MKENUMNAME(reason);
+extern p80211enum_t MKENUMNAME(status);
+extern p80211enum_t MKENUMNAME(msgcode);
+extern p80211enum_t MKENUMNAME(msgitem_status);
+
+extern p80211enum_t MKENUMNAME(lnxroam_reason);
+
+extern p80211enum_t MKENUMNAME(p2preamble);
+
+/*================================================================*/
+/* Function Declarations */
+
+/*----------------------------------------------------------------*/
+/* The following declare some utility functions for use with the */
+/*  p80211enum_t type. */
+
+UINT32 p80211enum_text2int(p80211enum_t *ep, char *text);
+UINT32 p80211enum_int2text(p80211enum_t *ep, UINT32 val, char *text);
+void p80211_error2text(int err_code, char *err_str);
+
+/*----------------------------------------------------------------*/
+/* The following declare some utility functions for use with the */
+/*  p80211item_t and p80211meta_t types. */
+
+/*----------------------------------------------------------------*/
+/* The following declare functions that perform validation and    */
+/* text to binary conversions based on the metadata for interface */
+/* and MIB data items.                                            */
+/*----------------------------------------------------------------*/
+
+/*-- DISPLAYSTR ------------------------------------------------------*/
+/* pstr ==> cstr */
+void p80211_totext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* cstr ==> pstr */
+void p80211_fromtext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of a displaystr binary value */
+UINT32 p80211_isvalid_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- OCTETSTR --------------------------------------------------------*/
+/* pstr ==> "xx:xx:...." */
+void p80211_totext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* "xx:xx:...." ==> pstr */
+void p80211_fromtext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of an octetstr binary value */
+UINT32 p80211_isvalid_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- INT -------------------------------------------------------------*/
+/* UINT32 ==> %d */
+void p80211_totext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* %d ==> UINT32 */
+void p80211_fromtext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of an int's binary value (always successful) */
+UINT32 p80211_isvalid_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- ENUMINT ---------------------------------------------------------*/
+/* UINT32 ==> <valuename> */
+void p80211_totext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* <valuename> ==> UINT32 */
+void p80211_fromtext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of an enum's binary value */
+UINT32 p80211_isvalid_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- INTARRAY --------------------------------------------------------*/
+/* UINT32[] => %d,%d,%d,... */
+void p80211_totext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* %d,%d,%d,... ==> UINT32[] */
+void p80211_fromtext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of an integer array's value */
+UINT32 p80211_isvalid_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- BITARRAY --------------------------------------------------------*/
+/* UINT32 ==> %d,%d,%d,... */
+void p80211_totext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* %d,%d,%d,... ==> UINT32 */
+void p80211_fromtext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of a bit array's value */
+UINT32 p80211_isvalid_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- MACARRAY --------------------------------------------------------*/
+void p80211_totext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+void p80211_fromtext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of a MAC address array's value */
+UINT32 p80211_isvalid_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- MIBATTRIUBTE ------------------------------------------------------*/
+/* <mibvalue> ==> <textual representation identified in MIB metadata> */
+void p80211_totext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+void p80211_totext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+
+/* <textual representation identified in MIB metadata> ==> <mibvalue> */
+void p80211_fromtext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+void p80211_fromtext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of a mibitem's binary value */
+UINT32 p80211_isvalid_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+UINT32 p80211_isvalid_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+#endif /* _P80211TYPES_H */
+
diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c
new file mode 100644 (file)
index 0000000..53fe298
--- /dev/null
@@ -0,0 +1,317 @@
+/* src/p80211/p80211wep.c
+*
+* WEP encode/decode for P80211.
+*
+* Copyright (C) 2002 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+
+#include "version.h"
+#include "wlan_compat.h"
+
+// #define WEP_DEBUG
+
+/*================================================================*/
+/* Project Includes */
+
+#include "version.h"
+#include "p80211hdr.h"
+#include "p80211types.h"
+#include "p80211msg.h"
+#include "p80211conv.h"
+#include "p80211netdev.h"
+
+/*================================================================*/
+/* Local Constants */
+
+#define SSWAP(a,b) {UINT8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
+#define WEP_KEY(x)       (((x) & 0xC0) >> 6)
+
+/*================================================================*/
+/* Local Macros */
+
+
+/*================================================================*/
+/* Local Types */
+
+
+/*================================================================*/
+/* Local Static Definitions */
+
+static const UINT32 wep_crc32_table[256] = {
+        0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+        0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+        0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+        0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+        0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+        0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+        0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+        0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+        0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+        0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+        0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+        0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+        0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+        0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+        0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+        0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+        0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+        0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+        0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+        0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+        0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+        0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+        0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+        0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+        0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+        0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+        0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+        0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+        0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+        0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+        0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+        0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+        0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+        0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+        0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+        0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+        0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+        0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+        0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+        0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+        0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+        0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+        0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+        0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+        0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+        0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+        0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+        0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+        0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+        0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+        0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+        0x2d02ef8dL
+};
+
+/*================================================================*/
+/* Local Function Declarations */
+
+/*================================================================*/
+/* Function Definitions */
+
+/* keylen in bytes! */
+
+int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen)
+{
+       if (keylen < 0)  return -1;
+       if (keylen >= MAX_KEYLEN) return -1;
+       if (key == NULL) return -1;
+       if (keynum < 0)  return -1;
+       if (keynum >= NUM_WEPKEYS) return -1;
+
+
+#ifdef WEP_DEBUG
+       printk(KERN_DEBUG "WEP key %d len %d = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]);
+#endif
+
+       wlandev->wep_keylens[keynum] = keylen;
+       memcpy(wlandev->wep_keys[keynum], key, keylen);
+
+       return 0;
+}
+
+/*
+  4-byte IV at start of buffer, 4-byte ICV at end of buffer.
+  if successful, buf start is payload begin, length -= 8;
+ */
+int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv)
+{
+       UINT32 i, j, k, crc, keylen;
+       UINT8 s[256], key[64], c_crc[4];
+       UINT8 keyidx;
+
+       /* Needs to be at least 8 bytes of payload */
+       if (len <= 0) return -1;
+
+       /* initialize the first bytes of the key from the IV */
+       key[0] = iv[0];
+       key[1] = iv[1];
+       key[2] = iv[2];
+       keyidx = WEP_KEY(iv[3]);
+
+       if (key_override >= 0)
+               keyidx = key_override;
+
+       if (keyidx >= NUM_WEPKEYS) return -2;
+
+       keylen = wlandev->wep_keylens[keyidx];
+
+       if (keylen == 0) return -3;
+
+       /* copy the rest of the key over from the designated key */
+       memcpy(key+3, wlandev->wep_keys[keyidx], keylen);
+
+       keylen+=3;  /* add in IV bytes */
+
+#ifdef WEP_DEBUG
+       printk(KERN_DEBUG "D %d: %02x %02x %02x (%d %d) %02x:%02x:%02x:%02x:%02x\n", len, key[0], key[1], key[2], keyidx, keylen, key[3], key[4], key[5], key[6], key[7]);
+#endif
+
+       /* set up the RC4 state */
+       for (i = 0; i < 256; i++)
+               s[i] = i;
+       j = 0;
+       for (i = 0; i < 256; i++) {
+               j = (j + s[i] + key[i % keylen]) & 0xff;
+               SSWAP(i,j);
+       }
+
+       /* Apply the RC4 to the data, update the CRC32 */
+       crc = ~0;
+       i = j = 0;
+       for (k = 0; k < len; k++) {
+               i = (i+1) & 0xff;
+               j = (j+s[i]) & 0xff;
+               SSWAP(i,j);
+               buf[k] ^= s[(s[i] + s[j]) & 0xff];
+               crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
+       }
+       crc = ~crc;
+
+       /* now let's check the crc */
+       c_crc[0] = crc;
+       c_crc[1] = crc >> 8;
+       c_crc[2] = crc >> 16;
+       c_crc[3] = crc >> 24;
+
+       for (k = 0; k < 4; k++) {
+               i = (i + 1) & 0xff;
+               j = (j+s[i]) & 0xff;
+               SSWAP(i,j);
+               if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k])
+                       return -(4 | (k << 4)) ; /* ICV mismatch */
+       }
+
+       return 0;
+}
+
+/* encrypts in-place. */
+int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv)
+{
+       UINT32 i, j, k, crc, keylen;
+       UINT8 s[256], key[64];
+
+       /* no point in WEPping an empty frame */
+       if (len <= 0) return -1;
+
+       /* we need to have a real key.. */
+       if (keynum >= NUM_WEPKEYS) return -2;
+       keylen = wlandev->wep_keylens[keynum];
+       if (keylen <= 0) return -3;
+
+       /* use a random IV.  And skip known weak ones. */
+       get_random_bytes(iv, 3);
+       while ((iv[1] == 0xff) && (iv[0] >= 3) && (iv[0] < keylen))
+               get_random_bytes(iv, 3);
+
+       iv[3] = (keynum & 0x03) << 6;
+
+       key[0] = iv[0];
+       key[1] = iv[1];
+       key[2] = iv[2];
+
+       /* copy the rest of the key over from the designated key */
+       memcpy(key+3, wlandev->wep_keys[keynum], keylen);
+
+       keylen+=3;  /* add in IV bytes */
+
+#ifdef WEP_DEBUG
+       printk(KERN_DEBUG "E %d (%d/%d %d) %02x %02x %02x %02x:%02x:%02x:%02x:%02x\n", len,  iv[3], keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]);
+#endif
+
+       /* set up the RC4 state */
+       for (i = 0; i < 256; i++)
+               s[i] = i;
+       j = 0;
+       for (i = 0; i < 256; i++) {
+               j = (j + s[i] + key[i % keylen]) & 0xff;
+               SSWAP(i,j);
+       }
+
+       /* Update CRC32 then apply RC4 to the data */
+       crc = ~0;
+       i = j = 0;
+       for (k = 0; k < len; k++) {
+               crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
+               i = (i+1) & 0xff;
+               j = (j+s[i]) & 0xff;
+               SSWAP(i,j);
+               dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff];
+       }
+       crc = ~crc;
+
+       /* now let's encrypt the crc */
+       icv[0] = crc;
+       icv[1] = crc >> 8;
+       icv[2] = crc >> 16;
+       icv[3] = crc >> 24;
+
+       for (k = 0; k < 4; k++) {
+               i = (i + 1) & 0xff;
+               j = (j+s[i]) & 0xff;
+               SSWAP(i,j);
+               icv[k] ^= s[(s[i] + s[j]) & 0xff];
+       }
+
+       return 0;
+}
diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c
new file mode 100644 (file)
index 0000000..906ba43
--- /dev/null
@@ -0,0 +1,2048 @@
+/* src/p80211/p80211wext.c
+*
+* Glue code to make linux-wlan-ng a happy wireless extension camper.
+*
+* original author:  Reyk Floeter <reyk@synack.de>
+* Completely re-written by Solomon Peachy <solomon@linux-wlan.com>
+*
+* Copyright (C) 2002 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+#endif
+#include <linux/if_arp.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+
+/*================================================================*/
+/* Project Includes */
+
+#include "version.h"
+#include "wlan_compat.h"
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211conv.h"
+#include "p80211mgmt.h"
+#include "p80211msg.h"
+#include "p80211metastruct.h"
+#include "p80211metadef.h"
+#include "p80211netdev.h"
+#include "p80211ioctl.h"
+#include "p80211req.h"
+
+static int p80211wext_giwrate(netdevice_t *dev,
+                             struct iw_request_info *info,
+                             struct iw_param *rrq, char *extra);
+static int p80211wext_giwessid(netdevice_t *dev,
+                              struct iw_request_info *info,
+                              struct iw_point *data, char *essid);
+/* compatibility to wireless extensions */
+#ifdef WIRELESS_EXT
+
+static UINT8 p80211_mhz_to_channel(UINT16 mhz)
+{
+       if (mhz >= 5000) {
+               return ((mhz - 5000) / 5);
+       }
+
+       if (mhz == 2482)
+               return 14;
+
+       if (mhz >= 2407) {
+               return ((mhz - 2407) / 5);
+       }
+
+       return 0;
+}
+
+static UINT16 p80211_channel_to_mhz(UINT8 ch, int dot11a)
+{
+
+       if (ch == 0)
+               return 0;
+       if (ch > 200)
+               return 0;
+
+       /* 5G */
+
+       if (dot11a) {
+               return (5000 + (5 * ch));
+       }
+
+       /* 2.4G */
+
+       if (ch == 14)
+               return 2484;
+
+       if ((ch < 14) && (ch > 0)) {
+               return (2407 + (5 * ch));
+       }
+
+       return 0;
+}
+
+/* taken from orinoco.c ;-) */
+static const long p80211wext_channel_freq[] = {
+       2412, 2417, 2422, 2427, 2432, 2437, 2442,
+       2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+#define NUM_CHANNELS (sizeof(p80211wext_channel_freq) / sizeof(p80211wext_channel_freq[0]))
+
+/* steal a spare bit to store the shared/opensystems state. should default to open if not set */
+#define HOSTWEP_SHAREDKEY BIT3
+
+
+/** function declarations =============== */
+
+static int qual_as_percent(int snr ) {
+  if ( snr <= 0 )
+    return 0;
+  if ( snr <= 40 )
+    return snr*5/2;
+  return 100;
+}
+
+
+
+
+static int p80211wext_dorequest(wlandevice_t *wlandev, UINT32 did, UINT32 data)
+{
+       p80211msg_dot11req_mibset_t     msg;
+       p80211item_uint32_t             mibitem;
+       int     result;
+
+       DBFENTER;
+
+       msg.msgcode = DIDmsg_dot11req_mibset;
+       mibitem.did = did;
+       mibitem.data = data;
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       DBFEXIT;
+       return result;
+}
+
+static int p80211wext_autojoin(wlandevice_t *wlandev)
+{
+       p80211msg_lnxreq_autojoin_t     msg;
+       struct iw_point                 data;
+       char ssid[IW_ESSID_MAX_SIZE];
+
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       /* Get ESSID */
+       result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
+         msg.authtype.data = P80211ENUM_authalg_sharedkey;
+       else
+         msg.authtype.data = P80211ENUM_authalg_opensystem;
+
+       msg.msgcode = DIDmsg_lnxreq_autojoin;
+
+       /* Trim the last '\0' to fit the SSID format */
+
+       if (data.length && ssid[data.length-1] == '\0') {
+               data.length = data.length - 1;
+       }
+
+       memcpy(msg.ssid.data.data, ssid, data.length);
+       msg.ssid.data.len = data.length;
+
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+exit:
+
+       DBFEXIT;
+       return err;
+
+}
+
+/* called by /proc/net/wireless */
+struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev)
+{
+       p80211msg_lnxreq_commsquality_t  quality;
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       struct iw_statistics* wstats = &wlandev->wstats;
+       int retval;
+
+       DBFENTER;
+       /* Check */
+       if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) )
+               return NULL;
+
+       /* XXX Only valid in station mode */
+       wstats->status = 0;
+
+       /* build request message */
+       quality.msgcode = DIDmsg_lnxreq_commsquality;
+       quality.dbm.data = P80211ENUM_truth_true;
+       quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
+
+       /* send message to nsd */
+       if ( wlandev->mlmerequest == NULL )
+               return NULL;
+
+       retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality);
+
+       wstats->qual.qual = qual_as_percent(quality.link.data);    /* overall link quality */
+       wstats->qual.level = quality.level.data;  /* instant signal level */
+       wstats->qual.noise = quality.noise.data;  /* instant noise level */
+
+#if WIRELESS_EXT > 18
+       wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+#else
+       wstats->qual.updated = 7;
+#endif
+       wstats->discard.code = wlandev->rx.decrypt_err;
+       wstats->discard.nwid = 0;
+       wstats->discard.misc = 0;
+
+#if WIRELESS_EXT > 11
+       wstats->discard.fragment = 0;  // incomplete fragments
+       wstats->discard.retries = 0;   // tx retries.
+       wstats->miss.beacon = 0;
+#endif
+
+       DBFEXIT;
+
+       return wstats;
+}
+
+static int p80211wext_giwname(netdevice_t *dev,
+                             struct iw_request_info *info,
+                             char *name, char *extra)
+{
+       struct iw_param rate;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       result = p80211wext_giwrate(dev, NULL, &rate, NULL);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       switch (rate.value) {
+       case 1000000:
+       case 2000000:
+               strcpy(name, "IEEE 802.11-DS");
+               break;
+       case 5500000:
+       case 11000000:
+               strcpy(name, "IEEE 802.11-b");
+               break;
+       }
+exit:
+       DBFEXIT;
+       return err;
+}
+
+static int p80211wext_giwfreq(netdevice_t *dev,
+                             struct iw_request_info *info,
+                             struct iw_freq *freq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       msg.msgcode = DIDmsg_dot11req_mibget;
+       mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+       if (mibitem.data > NUM_CHANNELS) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       /* convert into frequency instead of a channel */
+       freq->e = 1;
+       freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000;
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+static int p80211wext_siwfreq(netdevice_t *dev,
+                             struct iw_request_info *info,
+                             struct iw_freq *freq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       if (!wlan_wext_write) {
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+       msg.msgcode = DIDmsg_dot11req_mibset;
+       mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
+       mibitem.status = P80211ENUM_msgitem_status_data_ok;
+
+       if ( (freq->e == 0) && (freq->m <= 1000) )
+               mibitem.data = freq->m;
+       else
+               mibitem.data = p80211_mhz_to_channel(freq->m);
+
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+#if WIRELESS_EXT > 8
+
+static int p80211wext_giwmode(netdevice_t *dev,
+                             struct iw_request_info *info,
+                             __u32 *mode, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+       DBFENTER;
+
+       switch (wlandev->macmode) {
+       case WLAN_MACMODE_IBSS_STA:
+               *mode = IW_MODE_ADHOC;
+               break;
+       case WLAN_MACMODE_ESS_STA:
+               *mode = IW_MODE_INFRA;
+               break;
+       case WLAN_MACMODE_ESS_AP:
+               *mode = IW_MODE_MASTER;
+               break;
+       default:
+               /* Not set yet. */
+               *mode = IW_MODE_AUTO;
+       }
+
+       DBFEXIT;
+       return 0;
+}
+
+static int p80211wext_siwmode(netdevice_t *dev,
+                             struct iw_request_info *info,
+                             __u32 *mode, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int     result;
+       int     err = 0;
+
+       DBFENTER;
+
+       if (!wlan_wext_write) {
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+       if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
+           *mode != IW_MODE_MASTER) {
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+       /* Operation mode is the same with current mode */
+       if (*mode == wlandev->macmode)
+               goto exit;
+
+       switch (*mode) {
+       case IW_MODE_ADHOC:
+               wlandev->macmode = WLAN_MACMODE_IBSS_STA;
+               break;
+       case IW_MODE_INFRA:
+               wlandev->macmode = WLAN_MACMODE_ESS_STA;
+               break;
+       case IW_MODE_MASTER:
+               wlandev->macmode = WLAN_MACMODE_ESS_AP;
+               break;
+       default:
+               /* Not set yet. */
+               WLAN_LOG_INFO("Operation mode: %d not support\n", *mode);
+               return -EOPNOTSUPP;
+       }
+
+       /* Set Operation mode to the PORT TYPE RID */
+
+#warning "get rid of p2mib here"
+
+       msg.msgcode = DIDmsg_dot11req_mibset;
+       mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;
+       mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result)
+               err = -EFAULT;
+
+ exit:
+       DBFEXIT;
+
+       return err;
+}
+
+
+static int p80211wext_giwrange(netdevice_t *dev,
+                              struct iw_request_info *info,
+                              struct iw_point *data, char *extra)
+{
+        struct iw_range *range = (struct iw_range *) extra;
+       int i, val;
+
+       DBFENTER;
+
+       // for backward compatability set size & zero everything we don't understand
+       data->length = sizeof(*range);
+       memset(range,0,sizeof(*range));
+
+#if WIRELESS_EXT > 9
+       range->txpower_capa = IW_TXPOW_DBM;
+       // XXX what about min/max_pmp, min/max_pmt, etc.
+#endif
+
+#if WIRELESS_EXT > 10
+       range->we_version_compiled = WIRELESS_EXT;
+       range->we_version_source = 13;
+
+       range->retry_capa = IW_RETRY_LIMIT;
+       range->retry_flags = IW_RETRY_LIMIT;
+       range->min_retry = 0;
+       range->max_retry = 255;
+#endif /* WIRELESS_EXT > 10 */
+
+#if WIRELESS_EXT > 16
+        range->event_capa[0] = (IW_EVENT_CAPA_K_0 |  //mode/freq/ssid
+                                IW_EVENT_CAPA_MASK(SIOCGIWAP) |
+                                IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
+        range->event_capa[1] = IW_EVENT_CAPA_K_1;  //encode
+        range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |
+                                IW_EVENT_CAPA_MASK(IWEVCUSTOM) );
+#endif
+
+       range->num_channels = NUM_CHANNELS;
+
+       /* XXX need to filter against the regulatory domain &| active set */
+       val = 0;
+       for (i = 0; i < NUM_CHANNELS ; i++) {
+               range->freq[val].i = i + 1;
+               range->freq[val].m = p80211wext_channel_freq[i] * 100000;
+               range->freq[val].e = 1;
+               val++;
+       }
+
+       range->num_frequency = val;
+
+       /* Max of /proc/net/wireless */
+       range->max_qual.qual = 100;
+       range->max_qual.level = 0;
+       range->max_qual.noise = 0;
+       range->sensitivity = 3;
+       // XXX these need to be nsd-specific!
+
+       range->min_rts = 0;
+       range->max_rts = 2347;
+       range->min_frag = 256;
+       range->max_frag = 2346;
+
+       range->max_encoding_tokens = NUM_WEPKEYS;
+       range->num_encoding_sizes = 2;
+       range->encoding_size[0] = 5;
+       range->encoding_size[1] = 13;
+
+       // XXX what about num_bitrates/throughput?
+       range->num_bitrates = 0;
+
+       /* estimated max throughput */
+       // XXX need to cap it if we're running at ~2Mbps..
+       range->throughput = 5500000;
+
+       DBFEXIT;
+       return 0;
+}
+#endif
+
+static int p80211wext_giwap(netdevice_t *dev,
+                           struct iw_request_info *info,
+                           struct sockaddr *ap_addr, char *extra)
+{
+
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+       DBFENTER;
+
+       memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN);
+       ap_addr->sa_family = ARPHRD_ETHER;
+
+       DBFEXIT;
+       return 0;
+}
+
+#if WIRELESS_EXT > 8
+static int p80211wext_giwencode(netdevice_t *dev,
+                               struct iw_request_info *info,
+                               struct iw_point *erq, char *key)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       int err = 0;
+       int i;
+
+       DBFENTER;
+
+       if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
+               erq->flags = IW_ENCODE_ENABLED;
+       else
+               erq->flags = IW_ENCODE_DISABLED;
+
+       if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
+               erq->flags |= IW_ENCODE_RESTRICTED;
+       else
+               erq->flags |= IW_ENCODE_OPEN;
+
+       i = (erq->flags & IW_ENCODE_INDEX) - 1;
+
+       if (i == -1)
+               i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
+
+       if ((i < 0) || (i >= NUM_WEPKEYS)) {
+               err = -EINVAL;
+               goto exit;
+       }
+
+       erq->flags |= i + 1;
+
+       /* copy the key from the driver cache as the keys are read-only MIBs */
+       erq->length = wlandev->wep_keylens[i];
+       memcpy(key, wlandev->wep_keys[i], erq->length);
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+static int p80211wext_siwencode(netdevice_t *dev,
+                               struct iw_request_info *info,
+                               struct iw_point *erq, char *key)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211msg_dot11req_mibset_t     msg;
+       p80211item_pstr32_t             pstr;
+
+       int err = 0;
+       int result = 0;
+       int enable = 0;
+       int i;
+
+       DBFENTER;
+       if (!wlan_wext_write) {
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+       /* Check the Key index first. */
+       if((i = (erq->flags & IW_ENCODE_INDEX))) {
+
+               if ((i < 1) || (i > NUM_WEPKEYS)) {
+                       err = -EINVAL;
+                       goto exit;
+               }
+               else
+                       i--;
+
+               result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, i);
+
+               if (result) {
+                       err = -EFAULT;
+                       goto exit;
+               }
+               else {
+                       enable = 1;
+               }
+
+       }
+       else {
+               // Do not thing when no Key Index
+       }
+
+       /* Check if there is no key information in the iwconfig request */
+       if((erq->flags & IW_ENCODE_NOKEY) == 0 && enable == 1) {
+
+               /*------------------------------------------------------------
+                * If there is WEP Key for setting, check the Key Information
+                * and then set it to the firmware.
+                -------------------------------------------------------------*/
+
+               if (erq->length > 0) {
+
+                       /* copy the key from the driver cache as the keys are read-only MIBs */
+                       wlandev->wep_keylens[i] = erq->length;
+                       memcpy(wlandev->wep_keys[i], key, erq->length);
+
+                       /* Prepare data struture for p80211req_dorequest. */
+                       memcpy(pstr.data.data, key, erq->length);
+                       pstr.data.len = erq->length;
+
+                       switch(i)
+                       {
+                               case 0:
+                                       pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+                                       break;
+
+                               case 1:
+                                       pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+                                       break;
+
+                               case 2:
+                                       pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+                                       break;
+
+                               case 3:
+                                       pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+                                       break;
+
+                               default:
+                                       err = -EINVAL;
+                                       goto exit;
+                       }
+
+                       msg.msgcode = DIDmsg_dot11req_mibset;
+                       memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
+                       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+                       if (result) {
+                               err = -EFAULT;
+                               goto exit;
+                       }
+               }
+
+       }
+
+       /* Check the PrivacyInvoked flag */
+       if (erq->flags & IW_ENCODE_DISABLED) {
+               result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
+       }
+       else if((erq->flags & IW_ENCODE_ENABLED) || enable == 1) {
+               result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
+       }
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       /* Check the ExcludeUnencrypted flag */
+       if (erq->flags & IW_ENCODE_RESTRICTED) {
+               result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
+       }
+       else if (erq->flags & IW_ENCODE_OPEN) {
+               result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
+       }
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+ exit:
+
+       DBFEXIT;
+       return err;
+}
+
+static int p80211wext_giwessid(netdevice_t *dev,
+                              struct iw_request_info *info,
+                              struct iw_point *data, char *essid)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+       DBFENTER;
+
+       if (wlandev->ssid.len) {
+               data->length = wlandev->ssid.len;
+               data->flags = 1;
+               memcpy(essid, wlandev->ssid.data, data->length);
+               essid[data->length] = 0;
+#if (WIRELESS_EXT < 21)
+               data->length++;
+#endif
+       } else {
+               memset(essid, 0, sizeof(wlandev->ssid.data));
+               data->length = 0;
+               data->flags = 0;
+       }
+
+       DBFEXIT;
+       return 0;
+}
+
+static int p80211wext_siwessid(netdevice_t *dev,
+                              struct iw_request_info *info,
+                              struct iw_point *data, char *essid)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211msg_lnxreq_autojoin_t     msg;
+
+       int result;
+       int err = 0;
+       int length = data->length;
+
+       DBFENTER;
+
+       if (!wlan_wext_write) {
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+
+       if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
+         msg.authtype.data = P80211ENUM_authalg_sharedkey;
+       else
+         msg.authtype.data = P80211ENUM_authalg_opensystem;
+
+       msg.msgcode = DIDmsg_lnxreq_autojoin;
+
+#if (WIRELESS_EXT < 21)
+       if (length) length--;
+#endif
+
+       /* Trim the last '\0' to fit the SSID format */
+
+       if (length && essid[length-1] == '\0') {
+         length--;
+       }
+
+       memcpy(msg.ssid.data.data, essid, length);
+       msg.ssid.data.len = length;
+
+       WLAN_LOG_DEBUG(1,"autojoin_ssid for %s \n",essid);
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+        WLAN_LOG_DEBUG(1,"autojoin_ssid %d\n",result);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+
+static int p80211wext_siwcommit(netdevice_t *dev,
+                               struct iw_request_info *info,
+                               struct iw_point *data, char *essid)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       int err = 0;
+
+       DBFENTER;
+
+       if (!wlan_wext_write) {
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+       /* Auto Join */
+       err = p80211wext_autojoin(wlandev);
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+
+static int p80211wext_giwrate(netdevice_t *dev,
+                             struct iw_request_info *info,
+                             struct iw_param *rrq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       msg.msgcode = DIDmsg_dot11req_mibget;
+       mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate;
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+       rrq->fixed = 0;   /* can it change? */
+       rrq->disabled = 0;
+       rrq->value = 0;
+
+#define                HFA384x_RATEBIT_1                       ((UINT16)1)
+#define                HFA384x_RATEBIT_2                       ((UINT16)2)
+#define                HFA384x_RATEBIT_5dot5                   ((UINT16)4)
+#define                HFA384x_RATEBIT_11                      ((UINT16)8)
+
+       switch (mibitem.data) {
+       case HFA384x_RATEBIT_1:
+               rrq->value = 1000000;
+               break;
+       case HFA384x_RATEBIT_2:
+               rrq->value = 2000000;
+               break;
+       case HFA384x_RATEBIT_5dot5:
+               rrq->value = 5500000;
+               break;
+       case HFA384x_RATEBIT_11:
+               rrq->value = 11000000;
+               break;
+       default:
+               err = -EINVAL;
+       }
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+static int p80211wext_giwrts(netdevice_t *dev,
+                            struct iw_request_info *info,
+                            struct iw_param *rts, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       msg.msgcode = DIDmsg_dot11req_mibget;
+       mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+       rts->value = mibitem.data;
+       rts->disabled = (rts->value == 2347);
+       rts->fixed = 1;
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+
+static int p80211wext_siwrts(netdevice_t *dev,
+                            struct iw_request_info *info,
+                            struct iw_param *rts, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       if (!wlan_wext_write) {
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+       msg.msgcode = DIDmsg_dot11req_mibget;
+       mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
+       if (rts->disabled)
+               mibitem.data = 2347;
+       else
+               mibitem.data = rts->value;
+
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+static int p80211wext_giwfrag(netdevice_t *dev,
+                             struct iw_request_info *info,
+                             struct iw_param *frag, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       msg.msgcode = DIDmsg_dot11req_mibget;
+       mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+       frag->value = mibitem.data;
+       frag->disabled = (frag->value == 2346);
+       frag->fixed = 1;
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+static int p80211wext_siwfrag(netdevice_t *dev,
+                             struct iw_request_info *info,
+                             struct iw_param *frag, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       if (!wlan_wext_write) {
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+       msg.msgcode = DIDmsg_dot11req_mibset;
+       mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
+
+       if (frag->disabled)
+               mibitem.data = 2346;
+       else
+               mibitem.data = frag->value;
+
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+#endif  /* WIRELESS_EXT > 8 */
+
+#if WIRELESS_EXT > 10
+
+#ifndef IW_RETRY_LONG
+#define IW_RETRY_LONG IW_RETRY_MAX
+#endif
+
+#ifndef IW_RETRY_SHORT
+#define IW_RETRY_SHORT IW_RETRY_MIN
+#endif
+
+static int p80211wext_giwretry(netdevice_t *dev,
+                              struct iw_request_info *info,
+                              struct iw_param *rrq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+       UINT16 shortretry, longretry, lifetime;
+
+       DBFENTER;
+
+       msg.msgcode = DIDmsg_dot11req_mibget;
+       mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
+
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+       shortretry = mibitem.data;
+
+       mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
+
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+       longretry = mibitem.data;
+
+       mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+       lifetime = mibitem.data;
+
+       rrq->disabled = 0;
+
+       if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+               rrq->flags = IW_RETRY_LIFETIME;
+               rrq->value = lifetime * 1024;
+       } else {
+               if (rrq->flags & IW_RETRY_LONG) {
+                       rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
+                       rrq->value = longretry;
+               } else {
+                       rrq->flags = IW_RETRY_LIMIT;
+                       rrq->value = shortretry;
+                       if (shortretry != longretry)
+                               rrq->flags |= IW_RETRY_SHORT;
+               }
+       }
+
+ exit:
+       DBFEXIT;
+       return err;
+
+}
+
+static int p80211wext_siwretry(netdevice_t *dev,
+                              struct iw_request_info *info,
+                              struct iw_param *rrq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       if (!wlan_wext_write) {
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+       if (rrq->disabled) {
+               err = -EINVAL;
+               goto exit;
+       }
+
+       msg.msgcode = DIDmsg_dot11req_mibset;
+
+       if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+               mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+               mibitem.data =  rrq->value /= 1024;
+
+               memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+               result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+               if (result) {
+                       err = -EFAULT;
+                       goto exit;
+               }
+       } else {
+               if (rrq->flags & IW_RETRY_LONG) {
+                       mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
+                       mibitem.data = rrq->value;
+
+                       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+                       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+                       if (result) {
+                               err = -EFAULT;
+                               goto exit;
+                       }
+               }
+
+               if (rrq->flags & IW_RETRY_SHORT) {
+                       mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
+                       mibitem.data = rrq->value;
+
+                       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+                       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+                       if (result) {
+                               err = -EFAULT;
+                               goto exit;
+                       }
+               }
+       }
+
+ exit:
+       DBFEXIT;
+       return err;
+
+}
+
+#endif /* WIRELESS_EXT > 10 */
+
+#if WIRELESS_EXT > 9
+static int p80211wext_siwtxpow(netdevice_t *dev,
+                               struct iw_request_info *info,
+                               struct iw_param *rrq, char *extra)
+{
+        wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+        p80211item_uint32_t             mibitem;
+        p80211msg_dot11req_mibset_t     msg;
+        int result;
+        int err = 0;
+
+        DBFENTER;
+
+       if (!wlan_wext_write) {
+                err = (-EOPNOTSUPP);
+                goto exit;
+        }
+
+        msg.msgcode = DIDmsg_dot11req_mibset;
+
+        switch (rrq->value) {
+
+          case 1 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1; break;
+          case 2 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2; break;
+          case 3 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3; break;
+          case 4 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4; break;
+          case 5 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5; break;
+          case 6 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6; break;
+          case 7 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7; break;
+          case 8 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;
+          default: mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;
+       }
+
+        memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+        result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+        if (result) {
+                err = -EFAULT;
+                goto exit;
+        }
+
+ exit:
+        DBFEXIT;
+        return err;
+}
+
+static int p80211wext_giwtxpow(netdevice_t *dev,
+                              struct iw_request_info *info,
+                              struct iw_param *rrq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211item_uint32_t             mibitem;
+       p80211msg_dot11req_mibset_t     msg;
+       int result;
+       int err = 0;
+
+       DBFENTER;
+
+       msg.msgcode = DIDmsg_dot11req_mibget;
+       mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
+
+       memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+       if (result) {
+               err = -EFAULT;
+               goto exit;
+       }
+
+       memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+       // XXX handle OFF by setting disabled = 1;
+
+       rrq->flags = 0; // IW_TXPOW_DBM;
+       rrq->disabled = 0;
+       rrq->fixed = 0;
+       rrq->value = mibitem.data;
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+#endif /* WIRELESS_EXT > 9 */
+
+static int p80211wext_siwspy(netdevice_t *dev,
+                            struct iw_request_info *info,
+                            struct iw_point *srq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+        struct sockaddr address[IW_MAX_SPY];
+        int number = srq->length;
+        int i;
+
+       DBFENTER;
+
+       /* Copy the data from the input buffer */
+       memcpy(address, extra, sizeof(struct sockaddr)*number);
+
+        wlandev->spy_number = 0;
+
+        if (number > 0) {
+
+                /* extract the addresses */
+                for (i = 0; i < number; i++) {
+
+                        memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN);
+               }
+
+                /* reset stats */
+                memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
+
+                /* set number of addresses */
+                wlandev->spy_number = number;
+        }
+
+       DBFEXIT;
+       return 0;
+}
+
+/* jkriegl: from orinoco, modified */
+static int p80211wext_giwspy(netdevice_t *dev,
+                            struct iw_request_info *info,
+                            struct iw_point *srq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+        struct sockaddr address[IW_MAX_SPY];
+        struct iw_quality spy_stat[IW_MAX_SPY];
+        int number;
+        int i;
+
+       DBFENTER;
+
+        number = wlandev->spy_number;
+
+        if (number > 0) {
+
+                /* populate address and spy struct's */
+                for (i = 0; i < number; i++) {
+                        memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN);
+                        address[i].sa_family = AF_UNIX;
+                       memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality));
+                }
+
+               /* reset update flag */
+                for (i=0; i < number; i++)
+                        wlandev->spy_stat[i].updated = 0;
+        }
+
+        /* push stuff to user space */
+        srq->length = number;
+       memcpy(extra, address, sizeof(struct sockaddr)*number);
+       memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number);
+
+       DBFEXIT;
+       return 0;
+}
+
+static int prism2_result2err (int prism2_result)
+{
+       int err = 0;
+
+       switch (prism2_result) {
+               case P80211ENUM_resultcode_invalid_parameters:
+                       err = -EINVAL;
+                       break;
+               case P80211ENUM_resultcode_implementation_failure:
+                       err = -EIO;
+                       break;
+               case P80211ENUM_resultcode_not_supported:
+                       err = -EOPNOTSUPP;
+                       break;
+               default:
+                       err = 0;
+                       break;
+       }
+
+       return err;
+}
+
+#if WIRELESS_EXT > 13
+static int p80211wext_siwscan(netdevice_t *dev,
+                            struct iw_request_info *info,
+                            struct iw_point *srq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211msg_dot11req_scan_t       msg;
+       int result;
+       int err = 0;
+       int i = 0;
+
+       DBFENTER;
+
+       if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
+               WLAN_LOG_ERROR("Can't scan in AP mode\n");
+               err = (-EOPNOTSUPP);
+               goto exit;
+       }
+
+       memset(&msg, 0x00, sizeof(p80211msg_dot11req_scan_t));
+       msg.msgcode = DIDmsg_dot11req_scan;
+       msg.bsstype.data = P80211ENUM_bsstype_any;
+
+       memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t));
+       msg.bssid.data.len = 6;
+
+       msg.scantype.data = P80211ENUM_scantype_active;
+       msg.probedelay.data = 0;
+
+       for (i = 1; i <= 14; i++)
+               msg.channellist.data.data[i-1] = i;
+       msg.channellist.data.len = 14;
+
+       msg.maxchanneltime.data = 250;
+       msg.minchanneltime.data = 200;
+
+       result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+       if (result)
+               err = prism2_result2err (msg.resultcode.data);
+
+ exit:
+       DBFEXIT;
+       return err;
+}
+
+
+/* Helper to translate scan into Wireless Extensions scan results.
+ * Inspired by the prism54 code, which was in turn inspired by the
+ * airo driver code.
+ */
+static char *
+wext_translate_bss(struct iw_request_info *info, char *current_ev,
+                  char *end_buf, p80211msg_dot11req_scan_results_t *bss)
+{
+       struct iw_event iwe;    /* Temporary buffer */
+
+       /* The first entry must be the MAC address */
+       memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN);
+       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+       iwe.cmd = SIOCGIWAP;
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+
+       /* The following entries will be displayed in the same order we give them */
+
+       /* The ESSID. */
+       if (bss->ssid.data.len > 0) {
+               char essid[IW_ESSID_MAX_SIZE + 1];
+               int size;
+
+               size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len);
+               memset(&essid, 0, sizeof (essid));
+               memcpy(&essid, bss->ssid.data.data, size);
+               WLAN_LOG_DEBUG(1, " essid size = %d\n", size);
+               iwe.u.data.length = size;
+               iwe.u.data.flags = 1;
+               iwe.cmd = SIOCGIWESSID;
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &essid[0]);
+               WLAN_LOG_DEBUG(1, " essid size OK.\n");
+       }
+
+       switch (bss->bsstype.data) {
+               case P80211ENUM_bsstype_infrastructure:
+                       iwe.u.mode = IW_MODE_MASTER;
+                       break;
+
+               case P80211ENUM_bsstype_independent:
+                       iwe.u.mode = IW_MODE_ADHOC;
+                       break;
+
+               default:
+                       iwe.u.mode = 0;
+                       break;
+       }
+       iwe.cmd = SIOCGIWMODE;
+       if (iwe.u.mode)
+               current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+
+       /* Encryption capability */
+       if (bss->privacy.data == P80211ENUM_truth_true)
+               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+       else
+               iwe.u.data.flags = IW_ENCODE_DISABLED;
+       iwe.u.data.length = 0;
+       iwe.cmd = SIOCGIWENCODE;
+       current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL);
+
+       /* Add frequency. (short) bss->channel is the frequency in MHz */
+       iwe.u.freq.m = bss->dschannel.data;
+       iwe.u.freq.e = 0;
+       iwe.cmd = SIOCGIWFREQ;
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+
+       /* Add quality statistics */
+       iwe.u.qual.level = bss->signal.data;
+       iwe.u.qual.noise = bss->noise.data;
+       /* do a simple SNR for quality */
+       iwe.u.qual.qual = qual_as_percent(bss->signal.data - bss->noise.data);
+       iwe.cmd = IWEVQUAL;
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+
+       return current_ev;
+}
+
+
+static int p80211wext_giwscan(netdevice_t *dev,
+                            struct iw_request_info *info,
+                            struct iw_point *srq, char *extra)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       p80211msg_dot11req_scan_results_t       msg;
+       int result = 0;
+       int err = 0;
+       int i = 0;
+       int scan_good = 0;
+       char *current_ev = extra;
+
+       DBFENTER;
+
+       /* Since wireless tools doesn't really have a way of passing how
+        * many scan results results there were back here, keep grabbing them
+        * until we fail.
+        */
+       do {
+               memset(&msg, 0, sizeof(msg));
+               msg.msgcode = DIDmsg_dot11req_scan_results;
+               msg.bssindex.data = i;
+
+               result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+               if ((result != 0) ||
+                   (msg.resultcode.data != P80211ENUM_resultcode_success)) {
+                       break;
+               }
+
+               current_ev = wext_translate_bss(info, current_ev, extra + IW_SCAN_MAX_DATA, &msg);
+               scan_good = 1;
+               i++;
+       } while (i < IW_MAX_AP);
+
+       srq->length = (current_ev - extra);
+       srq->flags = 0; /* todo */
+
+       if (result && !scan_good)
+               err = prism2_result2err (msg.resultcode.data);
+
+       DBFEXIT;
+       return err;
+}
+#endif
+
+/*****************************************************/
+//extra wireless extensions stuff to support NetworkManager (I hope)
+
+#if WIRELESS_EXT > 17
+/* SIOCSIWENCODEEXT */
+static int p80211wext_set_encodeext(struct net_device *dev,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+  wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+  struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+       p80211msg_dot11req_mibset_t     msg;
+       p80211item_pstr32_t             *pstr;
+
+  int result = 0;
+  struct iw_point *encoding = &wrqu->encoding;
+  int idx = encoding->flags & IW_ENCODE_INDEX;
+
+  WLAN_LOG_DEBUG(1,"set_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
+
+
+  if ( ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY ) {
+    // set default key ? I'm not sure if this the the correct thing to do here
+
+    if ( idx ) {
+      if (idx < 1 || idx > NUM_WEPKEYS) {
+       return -EINVAL;
+      } else
+       idx--;
+    }
+    WLAN_LOG_DEBUG(1,"setting default key (%d)\n",idx);
+    result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, idx);
+    if ( result )
+      return -EFAULT;
+  }
+
+
+  if ( ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY ) {
+    if ( ! ext->alg & IW_ENCODE_ALG_WEP) {
+      WLAN_LOG_DEBUG(1,"asked to set a non wep key :(");
+      return -EINVAL;
+    }
+    if (idx) {
+      if (idx <1 || idx > NUM_WEPKEYS)
+       return -EINVAL;
+      else
+       idx--;
+    }
+    WLAN_LOG_DEBUG(1,"Set WEP key (%d)\n",idx);
+    wlandev->wep_keylens[idx] = ext->key_len;
+    memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
+
+    memset( &msg,0,sizeof(msg));
+    pstr = (p80211item_pstr32_t*)&msg.mibattribute.data;
+    memcpy(pstr->data.data, ext->key,ext->key_len);
+    pstr->data.len = ext->key_len;
+    switch (idx) {
+    case 0:
+      pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+      break;
+    case 1:
+      pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+      break;
+    case 2:
+      pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+      break;
+    case 3:
+      pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+      break;
+    default:
+      break;
+    }
+    msg.msgcode = DIDmsg_dot11req_mibset;
+    result = p80211req_dorequest(wlandev,(UINT8*)&msg);
+    WLAN_LOG_DEBUG(1,"result (%d)\n",result);
+  }
+  return result;
+}
+
+/* SIOCGIWENCODEEXT */
+static int p80211wext_get_encodeext(struct net_device *dev,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+
+       struct iw_point *encoding = &wrqu->encoding;
+       int result = 0;
+       int max_len;
+       int idx;
+
+       DBFENTER;
+
+       WLAN_LOG_DEBUG(1,"get_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
+
+
+       max_len = encoding->length - sizeof(*ext);
+       if ( max_len <= 0) {
+               WLAN_LOG_DEBUG(1,"get_encodeext max_len [%d] invalid\n",max_len);
+               result = -EINVAL;
+               goto exit;
+       }
+       idx = encoding->flags & IW_ENCODE_INDEX;
+
+       WLAN_LOG_DEBUG(1,"get_encode_ext index [%d]\n",idx);
+
+       if (idx) {
+               if (idx < 1 || idx > NUM_WEPKEYS ) {
+                       WLAN_LOG_DEBUG(1,"get_encode_ext invalid key index [%d]\n",idx);
+                       result = -EINVAL;
+                       goto exit;
+               }
+               idx--;
+       } else {
+               /* default key ? not sure what to do */
+               /* will just use key[0] for now ! FIX ME */
+       }
+
+       encoding->flags = idx + 1;
+       memset(ext,0,sizeof(*ext));
+
+       ext->alg = IW_ENCODE_ALG_WEP;
+       ext->key_len = wlandev->wep_keylens[idx];
+       memcpy( ext->key, wlandev->wep_keys[idx] , ext->key_len );
+
+       encoding->flags |= IW_ENCODE_ENABLED;
+exit:
+       DBFEXIT;
+
+       return result;
+}
+
+
+/* SIOCSIWAUTH */
+static int p80211_wext_set_iwauth (struct net_device *dev,
+                                  struct iw_request_info *info,
+                                  union iwreq_data *wrqu, char *extra)
+{
+  wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+  struct iw_param *param = &wrqu->param;
+  int result =0;
+
+  WLAN_LOG_DEBUG(1,"set_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
+
+  switch (param->flags & IW_AUTH_INDEX) {
+  case IW_AUTH_DROP_UNENCRYPTED:
+    WLAN_LOG_DEBUG(1,"drop_unencrypted %d\n",param->value);
+    if (param->value)
+      result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
+    else
+      result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
+    break;
+
+  case IW_AUTH_PRIVACY_INVOKED:
+    WLAN_LOG_DEBUG(1,"privacy invoked %d\n",param->value);
+    if ( param->value)
+      result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
+    else
+      result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
+
+    break;
+
+  case IW_AUTH_80211_AUTH_ALG:
+    if ( param->value & IW_AUTH_ALG_OPEN_SYSTEM ) {
+      WLAN_LOG_DEBUG(1,"set open_system\n");
+      wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
+    } else if ( param->value & IW_AUTH_ALG_SHARED_KEY) {
+      WLAN_LOG_DEBUG(1,"set shared key\n");
+      wlandev->hostwep |= HOSTWEP_SHAREDKEY;
+    } else {
+      /* don't know what to do know :( */
+      WLAN_LOG_DEBUG(1,"unknown AUTH_ALG (%d)\n",param->value);
+      result = -EINVAL;
+    }
+    break;
+
+  default:
+    break;
+  }
+
+
+
+  return result;
+}
+
+/* SIOCSIWAUTH */
+static int p80211_wext_get_iwauth (struct net_device *dev,
+                                  struct iw_request_info *info,
+                                  union iwreq_data *wrqu, char *extra)
+{
+  wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+  struct iw_param *param = &wrqu->param;
+  int result =0;
+
+  WLAN_LOG_DEBUG(1,"get_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
+
+  switch (param->flags & IW_AUTH_INDEX) {
+  case IW_AUTH_DROP_UNENCRYPTED:
+    param->value = wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED?1:0;
+    break;
+
+  case IW_AUTH_PRIVACY_INVOKED:
+    param->value = wlandev->hostwep & HOSTWEP_PRIVACYINVOKED?1:0;
+    break;
+
+  case IW_AUTH_80211_AUTH_ALG:
+    param->value = wlandev->hostwep & HOSTWEP_SHAREDKEY?IW_AUTH_ALG_SHARED_KEY:IW_AUTH_ALG_OPEN_SYSTEM;
+    break;
+
+
+  default:
+    break;
+  }
+
+
+
+  return result;
+}
+
+
+#endif
+
+
+
+
+
+
+/*****************************************************/
+
+
+
+
+
+/*
+typedef int (*iw_handler)(netdevice_t *dev, struct iw_request_info *info,
+                          union iwreq_data *wrqu, char *extra);
+*/
+
+#if WIRELESS_EXT > 12
+static iw_handler p80211wext_handlers[] =  {
+       (iw_handler) p80211wext_siwcommit,              /* SIOCSIWCOMMIT */
+       (iw_handler) p80211wext_giwname,                /* SIOCGIWNAME */
+       (iw_handler) NULL,                              /* SIOCSIWNWID */
+       (iw_handler) NULL,                              /* SIOCGIWNWID */
+       (iw_handler) p80211wext_siwfreq,                /* SIOCSIWFREQ */
+       (iw_handler) p80211wext_giwfreq,                /* SIOCGIWFREQ */
+       (iw_handler) p80211wext_siwmode,                /* SIOCSIWMODE */
+       (iw_handler) p80211wext_giwmode,                /* SIOCGIWMODE */
+       (iw_handler) NULL,                              /* SIOCSIWSENS */
+       (iw_handler) NULL,                              /* SIOCGIWSENS */
+       (iw_handler) NULL, /* not used */               /* SIOCSIWRANGE */
+       (iw_handler) p80211wext_giwrange,               /* SIOCGIWRANGE */
+       (iw_handler) NULL, /* not used */               /* SIOCSIWPRIV */
+       (iw_handler) NULL, /* kernel code */            /* SIOCGIWPRIV */
+       (iw_handler) NULL, /* not used */               /* SIOCSIWSTATS */
+       (iw_handler) NULL, /* kernel code */            /* SIOCGIWSTATS */
+       (iw_handler) p80211wext_siwspy,                 /* SIOCSIWSPY */
+       (iw_handler) p80211wext_giwspy,                 /* SIOCGIWSPY */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* SIOCSIWAP */
+       (iw_handler) p80211wext_giwap,                  /* SIOCGIWAP */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* SIOCGIWAPLIST */
+#if WIRELESS_EXT > 13
+       (iw_handler) p80211wext_siwscan,                        /* SIOCSIWSCAN */
+       (iw_handler) p80211wext_giwscan,                        /* SIOCGIWSCAN */
+#else /* WIRELESS_EXT > 13 */
+       (iw_handler) NULL,      /* null */              /* SIOCSIWSCAN */
+       (iw_handler) NULL,      /* null */              /* SIOCGIWSCAN */
+#endif /* WIRELESS_EXT > 13 */
+       (iw_handler) p80211wext_siwessid,               /* SIOCSIWESSID */
+       (iw_handler) p80211wext_giwessid,               /* SIOCGIWESSID */
+       (iw_handler) NULL,                              /* SIOCSIWNICKN */
+       (iw_handler) p80211wext_giwessid,               /* SIOCGIWNICKN */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* SIOCSIWRATE */
+       (iw_handler) p80211wext_giwrate,                /* SIOCGIWRATE */
+       (iw_handler) p80211wext_siwrts,                 /* SIOCSIWRTS */
+       (iw_handler) p80211wext_giwrts,                 /* SIOCGIWRTS */
+       (iw_handler) p80211wext_siwfrag,                /* SIOCSIWFRAG */
+       (iw_handler) p80211wext_giwfrag,                /* SIOCGIWFRAG */
+       (iw_handler) p80211wext_siwtxpow,               /* SIOCSIWTXPOW */
+       (iw_handler) p80211wext_giwtxpow,               /* SIOCGIWTXPOW */
+       (iw_handler) p80211wext_siwretry,               /* SIOCSIWRETRY */
+       (iw_handler) p80211wext_giwretry,               /* SIOCGIWRETRY */
+       (iw_handler) p80211wext_siwencode,              /* SIOCSIWENCODE */
+       (iw_handler) p80211wext_giwencode,              /* SIOCGIWENCODE */
+       (iw_handler) NULL,                              /* SIOCSIWPOWER */
+       (iw_handler) NULL,                              /* SIOCGIWPOWER */
+#if WIRELESS_EXT > 17
+/* WPA operations */
+
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL, /* SIOCSIWGENIE      set generic IE */
+       (iw_handler) NULL, /* SIOCGIWGENIE      get generic IE */
+       (iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH     set authentication mode params */
+       (iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH     get authentication mode params */
+
+       (iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT  set encoding token & mode */
+       (iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT  get encoding token & mode */
+       (iw_handler) NULL, /* SIOCSIWPMKSA      PMKSA cache operation */
+#endif
+};
+
+struct iw_handler_def p80211wext_handler_def = {
+       .num_standard = sizeof(p80211wext_handlers) / sizeof(iw_handler),
+       .num_private = 0,
+       .num_private_args = 0,
+        .standard = p80211wext_handlers,
+       .private = NULL,
+       .private_args = NULL,
+#if WIRELESS_EXT > 16
+       .get_wireless_stats = p80211wext_get_wireless_stats
+#endif
+};
+
+#endif
+
+/* wireless extensions' ioctls */
+int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
+{
+       wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+#if WIRELESS_EXT < 13
+       struct iwreq *iwr = (struct iwreq*)ifr;
+#endif
+
+       p80211item_uint32_t             mibitem;
+       int err = 0;
+
+       DBFENTER;
+
+       mibitem.status = P80211ENUM_msgitem_status_data_ok;
+
+       if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {
+               err = -ENODEV;
+               goto exit;
+       }
+
+       WLAN_LOG_DEBUG(1, "Received wireless extension ioctl #%d.\n", cmd);
+
+       switch (cmd) {
+#if WIRELESS_EXT < 13
+       case SIOCSIWNAME:  /* unused  */
+               err = (-EOPNOTSUPP);
+               break;
+       case SIOCGIWNAME: /* get name == wireless protocol */
+                err = p80211wext_giwname(dev, NULL, (char *) &iwr->u, NULL);
+               break;
+       case SIOCSIWNWID:
+       case SIOCGIWNWID:
+               err = (-EOPNOTSUPP);
+               break;
+       case SIOCSIWFREQ: /* set channel */
+                err = p80211wext_siwfreq(dev, NULL, &(iwr->u.freq), NULL);
+               break;
+       case SIOCGIWFREQ: /* get channel */
+                err = p80211wext_giwfreq(dev, NULL, &(iwr->u.freq), NULL);
+               break;
+       case SIOCSIWRANGE:
+       case SIOCSIWPRIV:
+       case SIOCSIWAP: /* set access point MAC addresses (BSSID) */
+               err = (-EOPNOTSUPP);
+               break;
+
+       case SIOCGIWAP: /* get access point MAC addresses (BSSID) */
+                err = p80211wext_giwap(dev, NULL, &(iwr->u.ap_addr), NULL);
+               break;
+
+#if WIRELESS_EXT > 8
+       case SIOCSIWMODE: /* set operation mode */
+       case SIOCSIWESSID: /* set SSID (network name) */
+       case SIOCSIWRATE: /* set default bit rate (bps) */
+               err = (-EOPNOTSUPP);
+               break;
+
+       case SIOCGIWMODE: /* get operation mode */
+               err = p80211wext_giwmode(dev, NULL, &iwr->u.mode, NULL);
+
+               break;
+       case SIOCGIWNICKN: /* get node name/nickname */
+       case SIOCGIWESSID: /* get SSID */
+               if(iwr->u.essid.pointer) {
+                        char ssid[IW_ESSID_MAX_SIZE+1];
+                       memset(ssid, 0, sizeof(ssid));
+
+                       err = p80211wext_giwessid(dev, NULL, &iwr->u.essid, ssid);
+                       if(copy_to_user(iwr->u.essid.pointer, ssid, sizeof(ssid)))
+                               err = (-EFAULT);
+               }
+               break;
+       case SIOCGIWRATE:
+                err = p80211wext_giwrate(dev, NULL, &iwr->u.bitrate, NULL);
+               break;
+       case SIOCGIWRTS:
+               err = p80211wext_giwrts(dev, NULL, &iwr->u.rts, NULL);
+               break;
+       case SIOCGIWFRAG:
+               err = p80211wext_giwfrag(dev, NULL, &iwr->u.rts, NULL);
+               break;
+       case SIOCGIWENCODE:
+               if (!capable(CAP_NET_ADMIN))
+                       err = -EPERM;
+               else if (iwr->u.encoding.pointer) {
+                       char keybuf[MAX_KEYLEN];
+                       err = p80211wext_giwencode(dev, NULL,
+                                                    &iwr->u.encoding, keybuf);
+                       if (copy_to_user(iwr->u.encoding.pointer, keybuf,
+                                        iwr->u.encoding.length))
+                               err = -EFAULT;
+               }
+               break;
+       case SIOCGIWAPLIST:
+       case SIOCSIWRTS:
+       case SIOCSIWFRAG:
+       case SIOCSIWSENS:
+       case SIOCGIWSENS:
+       case SIOCSIWNICKN: /* set node name/nickname */
+       case SIOCSIWENCODE: /* set encoding token & mode */
+       case SIOCSIWSPY:
+       case SIOCGIWSPY:
+       case SIOCSIWPOWER:
+       case SIOCGIWPOWER:
+       case SIOCGIWPRIV:
+               err = (-EOPNOTSUPP);
+               break;
+       case SIOCGIWRANGE:
+               if(iwr->u.data.pointer != NULL) {
+                        struct iw_range range;
+                        err = p80211wext_giwrange(dev, NULL, &iwr->u.data,
+                                                 (char *) &range);
+                       /* Push that up to the caller */
+                       if (copy_to_user(iwr->u.data.pointer, &range, sizeof(range)))
+                               err = -EFAULT;
+               }
+               break;
+#endif /* WIRELESS_EXT > 8 */
+#if WIRELESS_EXT > 9
+       case SIOCSIWTXPOW:
+               err = (-EOPNOTSUPP);
+               break;
+       case SIOCGIWTXPOW:
+               err = p80211wext_giwtxpow(dev, NULL, &iwr->u.txpower, NULL);
+               break;
+#endif /* WIRELESS_EXT > 9 */
+#if WIRELESS_EXT > 10
+       case SIOCSIWRETRY:
+               err = (-EOPNOTSUPP);
+               break;
+       case SIOCGIWRETRY:
+               err = p80211wext_giwretry(dev, NULL, &iwr->u.retry, NULL);
+               break;
+#endif /* WIRELESS_EXT > 10 */
+
+#endif /* WIRELESS_EXT <= 12 */
+
+       default:
+               err = (-EOPNOTSUPP);
+               break;
+       }
+
+ exit:
+       DBFEXIT;
+       return (err);
+}
+
+int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
+{
+        union iwreq_data data;
+
+        DBFENTER;
+
+#if WIRELESS_EXT > 13
+        /* Send the association state first */
+        data.ap_addr.sa_family = ARPHRD_ETHER;
+        if (assoc) {
+                memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN);
+        } else {
+                memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN);
+        }
+
+        if (wlan_wext_write)
+                wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
+
+        if (!assoc) goto done;
+
+        // XXX send association data, like IEs, etc etc.
+#endif
+ done:
+        DBFEXIT;
+        return 0;
+}
+
+
+#endif /* compatibility to wireless extensions */
+
+
+
+
diff --git a/drivers/staging/wlan-ng/prism2_cs.c b/drivers/staging/wlan-ng/prism2_cs.c
new file mode 100644 (file)
index 0000000..63ce565
--- /dev/null
@@ -0,0 +1,1487 @@
+#define WLAN_HOSTIF WLAN_PCMCIA
+#include "hfa384x.c"
+#include "prism2mgmt.c"
+#include "prism2mib.c"
+#include "prism2sta.c"
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21) )
+#if (WLAN_CPU_FAMILY == WLAN_Ix86)
+#ifndef CONFIG_ISA
+#warning "You may need to enable ISA support in your kernel."
+#endif
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
+static u_int   irq_mask = 0xdeb8;              /* Interrupt mask */
+static int     irq_list[4] = { -1 };           /* Interrupt list */
+#endif
+static u_int   prism2_ignorevcc=1;             /* Boolean, if set, we
+                                                * ignore what the Vcc
+                                                * is set to and what the CIS
+                                                * says.
+                                                */
+module_param( prism2_ignorevcc, int, 0644);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))
+static int numlist = 4;
+module_param_array(irq_list, int, numlist, 0444);
+#else
+module_param_array(irq_list, int, NULL, 0444);
+#endif
+module_param( irq_mask, int, 0644);
+#endif
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+static int prism2_cs_suspend(struct pcmcia_device *pdev);
+static int prism2_cs_resume(struct pcmcia_device *pdev);
+static void prism2_cs_remove(struct pcmcia_device *pdev);
+static int prism2_cs_probe(struct pcmcia_device *pdev);
+#else
+dev_link_t     *prism2sta_attach(void);
+static void    prism2sta_detach(dev_link_t *link);
+static void    prism2sta_config(dev_link_t *link);
+static void    prism2sta_release(u_long arg);
+static int     prism2sta_event (event_t event, int priority, event_callback_args_t *args);
+
+static dev_link_t      *dev_list = NULL;       /* head of instance list */
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
+/*----------------------------------------------------------------
+* cs_error
+*
+* Utility function to print card services error messages.
+*
+* Arguments:
+*      handle  client handle identifying this CS client
+*      func    CS function number that generated the error
+*      ret     CS function return code
+*
+* Returns:
+*      nothing
+* Side effects:
+*
+* Call context:
+*      process thread
+*      interrupt
+----------------------------------------------------------------*/
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+#if (defined(CS_RELEASE_CODE) && (CS_RELEASE_CODE < 0x2911))
+       CardServices(ReportError, dev_info, (void *)func, (void *)ret);
+#else
+       error_info_t err = { func, ret };
+       pcmcia_report_error(handle, &err);
+#endif
+}
+#else // kernel_version
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+static struct pcmcia_device_id prism2_cs_ids[] = {
+       PCMCIA_DEVICE_PROD_ID12("INTERSIL",  "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), // Intersil PRISM2 Reference Design 11Mb/s 802.11b WLAN Card
+       PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), // Compaq WL100/200 11Mb/s 802.11b WLAN Card
+       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), // Compaq iPaq HNW-100 11Mb/s 802.11b WLAN Card
+       PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), // Samsung SWL2000-N 11Mb/s 802.11b WLAN Card
+       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), // Z-Com XI300 11Mb/s 802.11b WLAN Card
+       PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High",  "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), // ZoomAir 4100 11Mb/s 802.11b WLAN Card
+       PCMCIA_DEVICE_PROD_ID123("Instant Wireless ",  " Network PC CARD",  "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), // Linksys WPC11 11Mbps 802.11b WLAN Card
+       PCMCIA_DEVICE_PROD_ID123("Addtron",  "AWP-100 Wireless PCMCIA",  "Version 01.02", 0xe6ec52ce, 0x8649af2, 0x4b74baa0), // Addtron AWP-100 11Mbps 802.11b WLAN Card
+       PCMCIA_DEVICE_PROD_ID123("D",  "Link DWL-650 11Mbps WLAN Card",  "Version 01.02", 0x71b18589, 0xb6f1b0ab, 0x4b74baa0), // D-Link DWL-650 11Mbps 802.11b WLAN Card
+       PCMCIA_DEVICE_PROD_ID123("SMC",  "SMC2632W",  "Version 01.02", 0xc4f8b18b, 0x474a1f2a, 0x4b74baa0), // SMC 2632W 11Mbps 802.11b WLAN Card
+       PCMCIA_DEVICE_PROD_ID1234("Intersil",  "PRISM 2_5 PCMCIA ADAPTER",  "ISL37300P",  "Eval-RevA", 0x4b801a17, 0x6345a0bf, 0xc9049a39, 0xc23adc0e), // BroMax Freeport 11Mbps 802.11b WLAN Card (Prism 2.5)
+       PCMCIA_DEVICE_PROD_ID123("U.S. Robotics",  "IEEE 802.11b PC-CARD",  "Version 01.02", 0xc7b8df9d, 0x1700d087, 0x4b74baa0), // U.S. Robotics IEEE 802.11b PC-CARD
+       PCMCIA_DEVICE_PROD_ID12("Digital Data Communications",  "WPC-0100", 0xfdd73470, 0xe0b6f146), // Level-One WPC-0100
+       PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), // Bromax OEM 11Mbps 802.11b WLAN Card (Prism 2.5)
+       PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), // Bromax OEM 11Mbps 802.11b WLAN Card (Prism 3)
+       PCMCIA_DEVICE_PROD_ID12("corega K.K.",  "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), // corega K.K. Wireless LAN PCC-11
+       PCMCIA_DEVICE_PROD_ID12("corega K.K.",  "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), // corega K.K. Wireless LAN PCCA-11
+       PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), // CONTEC FLEXSCAN/FX-DDS110-PCC
+       PCMCIA_DEVICE_PROD_ID12("PLANEX",  "GeoWave/GW-NS110", 0x209f40ab, 0x46263178), // PLANEX GeoWave/GW-NS110
+       PCMCIA_DEVICE_PROD_ID123("OEM",  "PRISM2 IEEE 802.11 PC-Card",  "Version 01.02", 0xfea54c90, 0x48f2bdd6, 0x4b74baa0), // Ambicom WL1100 11Mbps 802.11b WLAN Card
+       PCMCIA_DEVICE_PROD_ID123("LeArtery",  "SYNCBYAIR 11Mbps Wireless LAN PC Card",  "Version 01.02", 0x7e3b326a, 0x49893e92, 0x4b74baa0), // LeArtery SYNCBYAIR 11Mbps 802.11b WLAN Card
+PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), // Intermec MobileLAN 11Mbps 802.11b WLAN Card
+       PCMCIA_DEVICE_PROD_ID123("NETGEAR MA401 Wireless PC",  "Card",  "Version 01.00", 0xa37434e9, 0x9762e8f1, 0xa57adb8c), // NETGEAR MA401 11Mbps 802.11 WLAN Card
+       PCMCIA_DEVICE_PROD_ID1234("Intersil",  "PRISM Freedom PCMCIA Adapter",  "ISL37100P",  "Eval-RevA", 0x4b801a17, 0xf222ec2d, 0x630d52b2, 0xc23adc0e), // Intersil PRISM Freedom 11mbps 802.11 WLAN Card
+       PCMCIA_DEVICE_PROD_ID123("OTC",  "Wireless AirEZY 2411-PCC WLAN Card",  "Version 01.02", 0x4ac44287, 0x235a6bed, 0x4b74baa0), // OTC Wireless AirEZY 2411-PCC 11Mbps 802.11 WLAN Card
+       PCMCIA_DEVICE_PROD_ID1234("802.11",  "11Mbps Wireless LAN Card",  "v08C1",  ""   , 0xb67a610e, 0x655aa7b7, 0x264b451a, 0x0), // Dynalink L11HDT 11Mbps 802.11 WLAN Card
+       PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), // Dynalink L11HDT 11Mbps 802.11 WLAN Card
+       PCMCIA_DEVICE_PROD_ID12("PROXIM",  "RangeLAN-DS/LAN PC CARD", 0xc6536a5e, 0x3f35797d), // PROXIM RangeLAN-DS/LAN PC CARD
+       PCMCIA_DEVICE_PROD_ID1234("ACTIONTEC",  "PRISM Wireless LAN PC Card",  "0381",  "RevA", 0x393089da, 0xa71e69d5, 0x90471fa9, 0x57a66194), // ACTIONTEC PRISM Wireless LAN PC Card
+       PCMCIA_DEVICE_MANF_CARD(0x1668, 0x0101), // ACTIONTEC PRISM Wireless LAN PC Card
+       PCMCIA_DEVICE_PROD_ID12("3Com",  "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), // 3Com AirConnect 3CRWE737A
+       PCMCIA_DEVICE_PROD_ID12("3Com",  "3CRWE777A AirConnect Wireless LAN PCI Card"  , 0x41240e5b, 0xafc7c33e), // 3Com AirConnect 3CRWE777A
+       PCMCIA_DEVICE_PROD_ID12("ASUS",  "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), // ASUS WL-100 802.11b WLAN  PC Card
+       PCMCIA_DEVICE_PROD_ID12("ASUS",  "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), // ASUS WL-110 802.11b WLAN CF Card
+       PCMCIA_DEVICE_PROD_ID12("BUFFALO",  "WLI-CF-S11G", 0x2decece3, 0x82067c18), // BUFFALO WLI-CF-S11G 802.11b WLAN Card
+       PCMCIA_DEVICE_PROD_ID1234("The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P", "RevA", 0xa5f472c2, 0x9c05598d, 0xc9049a39, 0x57a66194), // Linksys WCF11 11Mbps 802.11b WLAN Card (Prism 2.5)
+       PCMCIA_DEVICE_PROD_ID1234("Linksys",  "Wireless CompactFlash Card",  "",  "", 0x733cc81, 0xc52f395, 0x0, 0x0), // Linksys WCF12 11Mbps 802.11b WLAN Card (Prism 3)
+       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), // Linksys WCF12 11Mbps 802.11b WLAN Card (Prism 3)
+       PCMCIA_DEVICE_PROD_ID1234("NETGEAR MA401RA Wireless PC",  "Card",  "ISL37300P",  "Eval-RevA", 0x306467f, 0x9762e8f1, 0xc9049a39, 0xc23adc0e), // NETGEAR MA401RA 11Mbps 802.11 WLAN Card
+       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), // D-Link DCF-660W  11Mbps 802.11b WLAN Card
+       PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001), // Microsoft Wireless Notebook Adapter MN-520
+       PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), // AnyPoint(TM) Wireless II PC Card
+       PCMCIA_DEVICE_PROD_ID1234("D",  "Link DRC-650 11Mbps WLAN Card",  "Version 01.02",  "" , 0x71b18589, 0xf144e3ac, 0x4b74baa0, 0x0), // D-Link DRC-650 802.11b WLAN Card
+       PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), // Adaptec AWN-8030
+       PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7110), // D-Link DWL-650 rev P 802.11b WLAN card
+       // PCMCIA_DEVICE_PROD_ID1234("D-Link",  "DWL-650 Wireless PC Card RevP",  "ISL37101P-10",  "A3", 0x1a424a1c, 0x6ea57632, 0xdd97a26b, 0x56b21f52), // D-Link DWL-650 rev P 802.11b WLAN card
+       PCMCIA_DEVICE_PROD_ID123("INTERSIL",   "I-GATE 11M PC Card / PC Card plus",  "Version 01.02", 0x74c5e40d, 0x8304ff77, 0x4b74baa0), // I-Gate 11M PC Card
+       PCMCIA_DEVICE_PROD_ID1234("BENQ",  "AWL100 PCMCIA ADAPTER",  "ISL37300P",  "Eval-RevA", 0x35dadc74, 0x1f7fedb, 0xc9049a39, 0xc23adc0e), // benQ AWL100 802.11b WLAN Card
+       PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), // benQ AWL100 802.11b WLAN Card
+       // PCMCIA_DEVICE_PROD_ID1("INTERSIL", 0x74c5e40d), // Intersil Prism 2 card
+       // PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), // Intersil Prism 2 card
+
+       PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, prism2_cs_ids);
+#endif
+
+static struct pcmcia_driver prism2_cs_driver = {
+       .drv = {
+               .name = "prism2_cs",
+       },
+       .owner = THIS_MODULE,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+       .suspend = prism2_cs_suspend,
+       .resume = prism2_cs_resume,
+       .remove = prism2_cs_remove,
+       .probe = prism2_cs_probe,
+       .id_table = prism2_cs_ids,
+#else
+       .attach = prism2sta_attach,
+       .detach = prism2sta_detach,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+       .id_table = prism2_cs_ids,
+       .event =  prism2sta_event,
+#endif // > 2.6.12
+#endif // <= 2.6.15
+};
+#endif /* kernel_version */
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#define CS_CHECK(fn, ret) \
+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+#define CFG_CHECK(fn, retf) \
+do { int ret = (retf); \
+if (ret != 0) { \
+        WLAN_LOG_DEBUG(1, "CardServices(" #fn ") returned %d\n", ret); \
+        cs_error(pdev, fn, ret); \
+        goto next_entry; \
+} \
+} while (0)
+
+static void prism2_cs_remove(struct pcmcia_device *pdev)
+{
+       struct wlandevice  *wlandev;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+        dev_link_t *link = dev_to_instance(pdev);
+#endif
+
+       DBFENTER;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       wlandev = pdev->priv;
+#else
+       wlandev = link->priv;
+#endif
+
+       if (wlandev) {
+               p80211netdev_hwremoved(wlandev);
+               unregister_wlandev(wlandev);
+               wlan_unsetup(wlandev);
+               if (wlandev->priv) {
+                       hfa384x_t *hw = wlandev->priv;
+                       wlandev->priv = NULL;
+                       if (hw) {
+                               hfa384x_destroy(hw);
+                               kfree(hw);
+                       }
+               }
+               kfree(wlandev);
+       }
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       pdev->priv = NULL;
+        pcmcia_disable_device(pdev);
+#else
+        if (link->state & DEV_CONFIG) {
+               if (link->win)
+                       pcmcia_release_window(link->win);
+               pcmcia_release_configuration(link->handle);
+               if (link->io.NumPorts1)
+                       pcmcia_release_io(link->handle, &link->io);
+               if (link->irq.AssignedIRQ)
+                       pcmcia_release_irq(link->handle, &link->irq);
+
+               link->state &= ~DEV_CONFIG;
+       }
+
+       link->priv = NULL;
+       kfree(link);
+#endif
+
+       DBFEXIT;
+       return;
+}
+
+static int prism2_cs_suspend(struct pcmcia_device *pdev)
+{
+       struct wlandevice  *wlandev;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+        dev_link_t *link = dev_to_instance(pdev);
+#endif
+
+       DBFENTER;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       wlandev = pdev->priv;
+       prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+#else
+       wlandev = link->priv;
+
+        link->state |= DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+               prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+               pcmcia_release_configuration(link->handle);
+       }
+#endif
+
+       DBFEXIT;
+
+       return 0;
+}
+
+static int prism2_cs_resume(struct pcmcia_device *pdev)
+{
+       struct wlandevice  *wlandev;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+        dev_link_t *link = dev_to_instance(pdev);
+#endif
+
+       DBFENTER;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       wlandev = pdev->priv;
+       // XXX do something here?
+#else
+       wlandev = link->priv;
+        link->state &= ~DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+                pcmcia_request_configuration(link->handle, &link->conf);
+               // XXX do something here?
+       }
+#endif
+
+
+       DBFEXIT;
+
+       return 0;
+}
+
+static int prism2_cs_probe(struct pcmcia_device *pdev)
+{
+       int rval = 0;
+       struct wlandevice *wlandev = NULL;
+       hfa384x_t *hw = NULL;
+
+        config_info_t socketconf;
+        cisparse_t *parse = NULL;
+       tuple_t tuple;
+       uint8_t buf[64];
+        int last_fn, last_ret;
+        cistpl_cftable_entry_t dflt = { 0 };
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+       dev_link_t *link;
+#endif
+
+       DBFENTER;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       /* Set up interrupt type */
+        pdev->conf.IntType = INT_MEMORY_AND_IO;
+#else
+        link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
+        if (link == NULL)
+                return -ENOMEM;
+        memset(link, 0, sizeof(dev_link_t));
+
+        link->conf.Vcc = 33;
+        link->conf.IntType = INT_MEMORY_AND_IO;
+
+        link->handle = pdev;
+        pdev->instance = link;
+        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+
+#endif
+
+       // VCC crap?
+        parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
+
+       wlandev = create_wlan();
+       if (!wlandev || !parse) {
+               WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+               rval = -EIO;
+               goto failed;
+       }
+       hw = wlandev->priv;
+
+       if ( wlan_setup(wlandev) != 0 ) {
+               WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+               rval = -EIO;
+               goto failed;
+       }
+
+       /* Initialize the hw struct for now */
+       hfa384x_create(hw, 0, 0, NULL);
+       hw->wlandev = wlandev;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       hw->pdev = pdev;
+       pdev->priv = wlandev;
+#else
+       hw->link = link;
+       link->priv = wlandev;
+#endif
+
+        tuple.DesiredTuple = CISTPL_CONFIG;
+        tuple.Attributes = 0;
+        tuple.TupleData = buf;
+        tuple.TupleDataMax = sizeof(buf);
+        tuple.TupleOffset = 0;
+        CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
+        CS_CHECK(GetTupleData, pcmcia_get_tuple_data(pdev, &tuple));
+        CS_CHECK(ParseTuple, pcmcia_parse_tuple(pdev, &tuple, parse));
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+        pdev->conf.ConfigBase = parse->config.base;
+        pdev->conf.Present = parse->config.rmask[0];
+#else
+        link->conf.ConfigBase = parse->config.base;
+        link->conf.Present = parse->config.rmask[0];
+
+       link->conf.Vcc = socketconf.Vcc;
+#endif
+        CS_CHECK(GetConfigurationInfo,
+                 pcmcia_get_configuration_info(pdev, &socketconf));
+
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
+        for (;;) {
+               cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
+                CFG_CHECK(GetTupleData,
+                           pcmcia_get_tuple_data(pdev, &tuple));
+                CFG_CHECK(ParseTuple,
+                           pcmcia_parse_tuple(pdev, &tuple, parse));
+
+                if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+                        dflt = *cfg;
+                if (cfg->index == 0)
+                        goto next_entry;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+                pdev->conf.ConfigIndex = cfg->index;
+#else
+                link->conf.ConfigIndex = cfg->index;
+#endif
+
+                /* Does this card need audio output? */
+                if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+                        pdev->conf.Attributes |= CONF_ENABLE_SPKR;
+                        pdev->conf.Status = CCSR_AUDIO_ENA;
+#else
+                        link->conf.Attributes |= CONF_ENABLE_SPKR;
+                        link->conf.Status = CCSR_AUDIO_ENA;
+#endif
+                }
+
+                /* Use power settings for Vcc and Vpp if present */
+                /*  Note that the CIS values need to be rescaled */
+                if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+                        if (socketconf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
+                            10000 && !prism2_ignorevcc) {
+                                WLAN_LOG_DEBUG(1, "  Vcc mismatch - skipping"
+                                       " this entry\n");
+                                goto next_entry;
+                        }
+                } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
+                        if (socketconf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
+                            10000 && !prism2_ignorevcc) {
+                                WLAN_LOG_DEBUG(1, "  Vcc (default) mismatch "
+                                       "- skipping this entry\n");
+                                goto next_entry;
+                        }
+                }
+
+                if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+                        pdev->conf.Vpp =
+                                cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+#else
+                        link->conf.Vpp1 = link->conf.Vpp2 =
+                                cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+#endif
+                } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+                        pdev->conf.Vpp =
+                                dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
+#else
+                        link->conf.Vpp1 = link->conf.Vpp2 =
+                                dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
+#endif
+               }
+
+               /* Do we need to allocate an interrupt? */
+               /* HACK: due to a bad CIS....we ALWAYS need an interrupt */
+               /* if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+               pdev->conf.Attributes |= CONF_ENABLE_IRQ;
+#else
+               link->conf.Attributes |= CONF_ENABLE_IRQ;
+#endif
+
+               /* IO window settings */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+               pdev->io.NumPorts1 = pdev->io.NumPorts2 = 0;
+               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+                       pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+                       if (!(io->flags & CISTPL_IO_8BIT))
+                               pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+                       if (!(io->flags & CISTPL_IO_16BIT))
+                               pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+                       pdev->io.BasePort1 = io->win[0].base;
+                       if  ( pdev->io.BasePort1 != 0 ) {
+                               WLAN_LOG_WARNING(
+                               "Brain damaged CIS: hard coded iobase="
+                               "0x%x, try letting pcmcia_cs decide...\n",
+                               pdev->io.BasePort1 );
+                               pdev->io.BasePort1 = 0;
+                       }
+                       pdev->io.NumPorts1 = io->win[0].len;
+                       if (io->nwin > 1) {
+                               pdev->io.Attributes2 = pdev->io.Attributes1;
+                               pdev->io.BasePort2 = io->win[1].base;
+                               pdev->io.NumPorts2 = io->win[1].len;
+                       }
+               }
+               /* This reserves IO space but doesn't actually enable it */
+               CFG_CHECK(RequestIO, pcmcia_request_io(pdev, &pdev->io));
+#else
+               link->io.NumPorts1 = link->io.NumPorts2 = 0;
+               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+                       if (!(io->flags & CISTPL_IO_8BIT))
+                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+                       if (!(io->flags & CISTPL_IO_16BIT))
+                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+                       link->io.BasePort1 = io->win[0].base;
+                       if  ( link->io.BasePort1 != 0 ) {
+                               WLAN_LOG_WARNING(
+                               "Brain damaged CIS: hard coded iobase="
+                               "0x%x, try letting pcmcia_cs decide...\n",
+                               link->io.BasePort1 );
+                               link->io.BasePort1 = 0;
+                       }
+                       link->io.NumPorts1 = io->win[0].len;
+                       if (io->nwin > 1) {
+                               link->io.Attributes2 = link->io.Attributes1;
+                               link->io.BasePort2 = io->win[1].base;
+                               link->io.NumPorts2 = io->win[1].len;
+                       }
+               }
+               /* This reserves IO space but doesn't actually enable it */
+               CFG_CHECK(RequestIO, pcmcia_request_io(pdev, &link->io));
+#endif
+               /* If we got this far, we're cool! */
+               break;
+
+       next_entry:
+               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+                       dflt = *cfg;
+               CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(pdev, &tuple));
+
+       }
+
+       /* Let pcmcia know the device name */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       pdev->dev_node = &hw->node;
+#else
+       link->dev = &hw->node;
+#endif
+
+       /* Register the network device and get assigned a name */
+       SET_MODULE_OWNER(wlandev->netdev);
+       SET_NETDEV_DEV(wlandev->netdev,  &handle_to_dev(pdev));
+       if (register_wlandev(wlandev) != 0) {
+               WLAN_LOG_NOTICE("prism2sta_cs: register_wlandev() failed.\n");
+               goto failed;
+       }
+
+       strcpy(hw->node.dev_name, wlandev->name);
+
+       /* Allocate an interrupt line.  Note that this does not assign a */
+       /* handler to the interrupt, unless the 'Handler' member of the */
+       /* irq structure is initialized. */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       if (pdev->conf.Attributes & CONF_ENABLE_IRQ) {
+               pdev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+               pdev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+               pdev->irq.Handler = hfa384x_interrupt;
+               pdev->irq.Instance = wlandev;
+               CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
+       }
+#else
+       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+               link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+               link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+               link->irq.Handler = hfa384x_interrupt;
+               link->irq.Instance = wlandev;
+               CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &link->irq));
+       }
+#endif
+
+       /* This actually configures the PCMCIA socket -- setting up */
+       /* the I/O windows and the interrupt mapping, and putting the */
+       /* card and host interface into "Memory and IO" mode. */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
+#else
+       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &link->conf));
+#endif
+
+       /* Fill the netdevice with this info */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       wlandev->netdev->irq = pdev->irq.AssignedIRQ;
+       wlandev->netdev->base_addr = pdev->io.BasePort1;
+#else
+       wlandev->netdev->irq = link->irq.AssignedIRQ;
+       wlandev->netdev->base_addr = link->io.BasePort1;
+#endif
+
+       /* And the rest of the hw structure */
+       hw->irq = wlandev->netdev->irq;
+       hw->iobase = wlandev->netdev->base_addr;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+       link->state |= DEV_CONFIG;
+       link->state &= ~DEV_CONFIG_PENDING;
+#endif
+
+       /* And now we're done! */
+       wlandev->msdstate = WLAN_MSD_HWPRESENT;
+
+       goto done;
+
+ cs_failed:
+        cs_error(pdev, last_fn, last_ret);
+
+failed:
+       // wlandev, hw, etc etc..
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       pdev->priv = NULL;
+#else
+       pdev->instance = NULL;
+       if (link) {
+               link->priv = NULL;
+               kfree(link);
+       }
+#endif
+       if (wlandev) {
+               wlan_unsetup(wlandev);
+               if (wlandev->priv) {
+                       hw = wlandev->priv;
+                       wlandev->priv = NULL;
+                       if (hw) {
+                               hfa384x_destroy(hw);
+                               kfree(hw);
+                       }
+               }
+               kfree(wlandev);
+       }
+
+done:
+       if (parse) kfree(parse);
+
+       DBFEXIT;
+       return rval;
+}
+#else  // <= 2.6.15
+#define CS_CHECK(fn, ret) \
+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+#define CFG_CHECK(fn, retf) \
+do { int ret = (retf); \
+if (ret != 0) { \
+        WLAN_LOG_DEBUG(1, "CardServices(" #fn ") returned %d\n", ret); \
+        cs_error(link->handle, fn, ret); \
+        goto next_entry; \
+} \
+} while (0)
+
+/*----------------------------------------------------------------
+* prism2sta_attach
+*
+* Half of the attach/detach pair.  Creates and registers a device
+* instance with Card Services.  In this case, it also creates the
+* wlandev structure and device private structure.  These are
+* linked to the device instance via its priv member.
+*
+* Arguments:
+*      none
+*
+* Returns:
+*      A valid ptr to dev_link_t on success, NULL otherwise
+*
+* Side effects:
+*
+*
+* Call context:
+*      process thread (insmod/init_module/register_pccard_driver)
+----------------------------------------------------------------*/
+dev_link_t *prism2sta_attach(void)
+{
+       client_reg_t            client_reg;
+       int                     result;
+       dev_link_t              *link = NULL;
+       wlandevice_t            *wlandev = NULL;
+       hfa384x_t               *hw = NULL;
+
+       DBFENTER;
+
+       /* Alloc our structures */
+       link =          kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+
+       if (!link || ((wlandev = create_wlan()) == NULL)) {
+               WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+               result = -EIO;
+               goto failed;
+       }
+       hw = wlandev->priv;
+
+       /* Clear all the structs */
+       memset(link, 0, sizeof(struct dev_link_t));
+
+       if ( wlan_setup(wlandev) != 0 ) {
+               WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+               result = -EIO;
+               goto failed;
+       }
+
+       /* Initialize the hw struct for now */
+       hfa384x_create(hw, 0, 0, NULL);
+       hw->wlandev = wlandev;
+
+       /* Initialize the PC card device object. */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+       init_timer(&link->release);
+       link->release.function = &prism2sta_release;
+       link->release.data = (u_long)link;
+#endif
+       link->conf.IntType = INT_MEMORY_AND_IO;
+       link->priv = wlandev;
+#if (defined(CS_RELEASE_CODE) && (CS_RELEASE_CODE < 0x2911))
+       link->irq.Instance = wlandev;
+#endif
+
+       /* Link in to the list of devices managed by this driver */
+       link->next = dev_list;
+       dev_list = link;
+
+       /* Register with Card Services */
+       client_reg.dev_info = &dev_info;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
+       client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
+       client_reg.EventMask =
+               CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+               CS_EVENT_RESET_REQUEST |
+               CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+               CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+       client_reg.event_handler = &prism2sta_event;
+#endif
+
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+
+       result = pcmcia_register_client(&link->handle, &client_reg);
+       if (result != 0) {
+               cs_error(link->handle, RegisterClient, result);
+               prism2sta_detach(link);
+               return NULL;
+       }
+
+       goto done;
+
+ failed:
+       if (link)       kfree(link);
+       if (wlandev)    kfree(wlandev);
+       if (hw)         kfree(hw);
+       link = NULL;
+
+ done:
+       DBFEXIT;
+       return link;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_detach
+*
+* Remove one of the device instances managed by this driver.
+*   Search the list for the given instance,
+*   check our flags for a waiting timer'd release call
+*   call release
+*   Deregister the instance with Card Services
+*   (netdevice) unregister the network device.
+*   unlink the instance from the list
+*   free the link, priv, and priv->priv memory
+* Note: the dev_list variable is a driver scoped static used to
+*      maintain a list of device instances managed by this
+*      driver.
+*
+* Arguments:
+*      link    ptr to the instance to detach
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      the link structure is gone, the netdevice is gone
+*
+* Call context:
+*      Might be interrupt, don't block.
+----------------------------------------------------------------*/
+void prism2sta_detach(dev_link_t *link)
+{
+       dev_link_t              **linkp;
+       wlandevice_t            *wlandev;
+       hfa384x_t               *hw;
+
+       DBFENTER;
+
+       /* Locate prev device structure */
+       for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
+               if (*linkp == link) break;
+       }
+
+       if (*linkp != NULL) {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+               unsigned long   flags;
+               /* Get rid of any timer'd release call */
+               save_flags(flags);
+               cli();
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+               if (link->state & DEV_RELEASE_PENDING) {
+                       del_timer_sync(&link->release);
+                       link->state &= ~DEV_RELEASE_PENDING;
+               }
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+               restore_flags(flags);
+#endif
+
+               /* If link says we're still config'd, call release */
+               if (link->state & DEV_CONFIG) {
+                       prism2sta_release((u_long)link);
+                       if (link->state & DEV_STALE_CONFIG) {
+                               link->state |= DEV_STALE_LINK;
+                               return;
+                       }
+               }
+
+               /* Tell Card Services we're not around any more */
+               if (link->handle) {
+                       pcmcia_deregister_client(link->handle);
+               }
+
+               /* Unlink device structure, free bits */
+               *linkp = link->next;
+               if ( link->priv != NULL ) {
+                       wlandev = (wlandevice_t*)link->priv;
+                       p80211netdev_hwremoved(wlandev);
+                       if (link->dev != NULL) {
+                               unregister_wlandev(wlandev);
+                       }
+                       wlan_unsetup(wlandev);
+                       if (wlandev->priv) {
+                               hw = wlandev->priv;
+                               wlandev->priv = NULL;
+                               if (hw) {
+                                       hfa384x_destroy(hw);
+                                       kfree(hw);
+                               }
+                       }
+                       link->priv = NULL;
+                       kfree(wlandev);
+               }
+               kfree(link);
+       }
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_config
+*
+* Half of the config/release pair.  Usually called in response to
+* a card insertion event.  At this point, we _know_ there's some
+* physical device present.  That means we can start poking around
+* at the CIS and at any device specific config data we want.
+*
+* Note the gotos and the macros.  I recoded this once without
+* them, and it got incredibly ugly.  It's actually simpler with
+* them.
+*
+* Arguments:
+*      link    the dev_link_t structure created in attach that
+*              represents this device instance.
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      Resources (irq, io, mem) are allocated
+*      The pcmcia dev_link->node->name is set
+*      (For netcards) The device structure is finished and,
+*        most importantly, registered.  This means that there
+*        is now a _named_ device that can be configured from
+*        userland.
+*
+* Call context:
+*      May be called from a timer.  Don't block!
+----------------------------------------------------------------*/
+#define CS_CHECK(fn, ret) \
+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+#define CFG_CHECK(fn, retf) \
+do { int ret = (retf); \
+if (ret != 0) { \
+        WLAN_LOG_DEBUG(1, "CardServices(" #fn ") returned %d\n", ret); \
+        cs_error(link->handle, fn, ret); \
+        goto next_entry; \
+} \
+} while (0)
+
+void prism2sta_config(dev_link_t *link)
+{
+       client_handle_t         handle;
+       wlandevice_t            *wlandev;
+       hfa384x_t               *hw;
+       int                     last_fn;
+       int                     last_ret;
+       tuple_t                 tuple;
+       cisparse_t              parse;
+       config_info_t           socketconf;
+       UINT8                   buf[64];
+       int                     minVcc = 0;
+       int                     maxVcc = 0;
+       cistpl_cftable_entry_t  dflt = { 0 };
+
+       DBFENTER;
+
+       handle = link->handle;
+       wlandev = (wlandevice_t*)link->priv;
+       hw = wlandev->priv;
+
+       /* Collect the config register info */
+       tuple.DesiredTuple = CISTPL_CONFIG;
+       tuple.Attributes = 0;
+       tuple.TupleData = buf;
+       tuple.TupleDataMax = sizeof(buf);
+       tuple.TupleOffset = 0;
+       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+       CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.Present = parse.config.rmask[0];
+
+       /* Configure card */
+       link->state |= DEV_CONFIG;
+
+       /* Acquire the current socket config (need Vcc setting) */
+       CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &socketconf));
+
+       /* Loop through the config table entries until we find one that works */
+       /* Assumes a complete and valid CIS */
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       while (1) {
+               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+               CFG_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+               CFG_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+
+               if (cfg->index == 0) goto next_entry;
+               link->conf.ConfigIndex = cfg->index;
+
+               /* Lets print out the Vcc that the controller+pcmcia-cs set
+                * for us, cause that's what we're going to use.
+                */
+               WLAN_LOG_DEBUG(1,"Initial Vcc=%d/10v\n", socketconf.Vcc);
+               if (prism2_ignorevcc) {
+                       link->conf.Vcc = socketconf.Vcc;
+                       goto skipvcc;
+               }
+
+               /* Use power settings for Vcc and Vpp if present */
+               /* Note that the CIS values need to be rescaled */
+               if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
+                       WLAN_LOG_DEBUG(1, "Vcc obtained from curtupl.VNOM\n");
+                       minVcc = maxVcc =
+                               cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
+               } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
+                       WLAN_LOG_DEBUG(1, "Vcc set from dflt.VNOM\n");
+                       minVcc = maxVcc =
+                               dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
+               } else if ((cfg->vcc.present & (1<<CISTPL_POWER_VMAX)) &&
+                          (cfg->vcc.present & (1<<CISTPL_POWER_VMIN)) ) {
+                       WLAN_LOG_DEBUG(1, "Vcc set from curtupl(VMIN,VMAX)\n");                 minVcc = cfg->vcc.param[CISTPL_POWER_VMIN]/10000;
+                       maxVcc = cfg->vcc.param[CISTPL_POWER_VMAX]/10000;
+               } else if ((dflt.vcc.present & (1<<CISTPL_POWER_VMAX)) &&
+                          (dflt.vcc.present & (1<<CISTPL_POWER_VMIN)) ) {
+                       WLAN_LOG_DEBUG(1, "Vcc set from dflt(VMIN,VMAX)\n");
+                       minVcc = dflt.vcc.param[CISTPL_POWER_VMIN]/10000;
+                       maxVcc = dflt.vcc.param[CISTPL_POWER_VMAX]/10000;
+               }
+
+               if ( socketconf.Vcc >= minVcc && socketconf.Vcc <= maxVcc) {
+                       link->conf.Vcc = socketconf.Vcc;
+               } else {
+                       /* [MSM]: Note that I've given up trying to change
+                        * the Vcc if a change is indicated.  It seems the
+                        * system&socketcontroller&card vendors can't seem
+                        * to get it right, so I'm tired of trying to hack
+                        * my way around it.  pcmcia-cs does its best using
+                        * the voltage sense pins but sometimes the controller
+                        * lies.  Then, even if we have a good read on the VS
+                        * pins, some system designs will silently ignore our
+                        * requests to set the voltage.  Additionally, some
+                        * vendors have 3.3v indicated on their sense pins,
+                        * but 5v specified in the CIS or vice-versa.  I've
+                        * had it.  My only recommendation is "let the buyer
+                        * beware".  Your system might supply 5v to a 3v card
+                        * (possibly causing damage) or a 3v capable system
+                        * might supply 5v to a 3v capable card (wasting
+                        * precious battery life).
+                        * My only recommendation (if you care) is to get
+                        * yourself an extender card (I don't know where, I
+                        * have only one myself) and a meter and test it for
+                        * yourself.
+                        */
+                       goto next_entry;
+               }
+skipvcc:
+               WLAN_LOG_DEBUG(1, "link->conf.Vcc=%d\n", link->conf.Vcc);
+
+               /* Do we need to allocate an interrupt? */
+               /* HACK: due to a bad CIS....we ALWAYS need an interrupt */
+               /* if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) */
+                       link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+               /* IO window settings */
+               link->io.NumPorts1 = link->io.NumPorts2 = 0;
+               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+                       if (!(io->flags & CISTPL_IO_8BIT))
+                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+                       if (!(io->flags & CISTPL_IO_16BIT))
+                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+                       link->io.BasePort1 = io->win[0].base;
+                       if  ( link->io.BasePort1 != 0 ) {
+                               WLAN_LOG_WARNING(
+                               "Brain damaged CIS: hard coded iobase="
+                               "0x%x, try letting pcmcia_cs decide...\n",
+                               link->io.BasePort1 );
+                               link->io.BasePort1 = 0;
+                       }
+                       link->io.NumPorts1 = io->win[0].len;
+                       if (io->nwin > 1) {
+                               link->io.Attributes2 = link->io.Attributes1;
+                               link->io.BasePort2 = io->win[1].base;
+                               link->io.NumPorts2 = io->win[1].len;
+                       }
+               }
+
+               /* This reserves IO space but doesn't actually enable it */
+               CFG_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
+
+               /* If we got this far, we're cool! */
+               break;
+
+next_entry:
+               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+                       dflt = *cfg;
+               CS_CHECK(GetNextTuple,
+                         pcmcia_get_next_tuple(handle, &tuple));
+       }
+
+       /* Allocate an interrupt line.  Note that this does not assign a */
+       /* handler to the interrupt, unless the 'Handler' member of the */
+       /* irq structure is initialized. */
+       if (link->conf.Attributes & CONF_ENABLE_IRQ)
+       {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
+               int                     i;
+               link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
+               if (irq_list[0] == -1)
+                       link->irq.IRQInfo2 = irq_mask;
+               else
+                       for (i=0; i<4; i++)
+                               link->irq.IRQInfo2 |= 1 << irq_list[i];
+#else
+               link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+#endif
+               link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+               link->irq.Handler = hfa384x_interrupt;
+               link->irq.Instance = wlandev;
+               CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+       }
+
+       /* This actually configures the PCMCIA socket -- setting up */
+       /* the I/O windows and the interrupt mapping, and putting the */
+       /* card and host interface into "Memory and IO" mode. */
+       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+
+       /* Fill the netdevice with this info */
+       wlandev->netdev->irq = link->irq.AssignedIRQ;
+       wlandev->netdev->base_addr = link->io.BasePort1;
+
+       /* Report what we've done */
+       WLAN_LOG_INFO("%s: index 0x%02x: Vcc %d.%d",
+               dev_info, link->conf.ConfigIndex,
+               link->conf.Vcc/10, link->conf.Vcc%10);
+       if (link->conf.Vpp1)
+               printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
+       if (link->conf.Attributes & CONF_ENABLE_IRQ)
+               printk(", irq %d", link->irq.AssignedIRQ);
+       if (link->io.NumPorts1)
+               printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1);
+       if (link->io.NumPorts2)
+               printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1);
+       printk("\n");
+
+       link->state &= ~DEV_CONFIG_PENDING;
+
+       /* Let pcmcia know the device name */
+       link->dev = &hw->node;
+
+       /* Register the network device and get assigned a name */
+       SET_MODULE_OWNER(wlandev->netdev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) )
+       SET_NETDEV_DEV(wlandev->netdev,  &handle_to_dev(link->handle));
+#endif
+       if (register_wlandev(wlandev) != 0) {
+               WLAN_LOG_NOTICE("prism2sta_cs: register_wlandev() failed.\n");
+               goto failed;
+       }
+
+       strcpy(hw->node.dev_name, wlandev->name);
+
+       /* Any device custom config/query stuff should be done here */
+       /* For a netdevice, we should at least grab the mac address */
+
+       return;
+cs_failed:
+       cs_error(link->handle, last_fn, last_ret);
+       WLAN_LOG_ERROR("NextTuple failure? It's probably a Vcc mismatch.\n");
+
+failed:
+       prism2sta_release((u_long)link);
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_release
+*
+* Half of the config/release pair.  Usually called in response to
+* a card ejection event.  Checks to make sure no higher layers
+* are still (or think they are) using the card via the link->open
+* field.
+*
+* NOTE: Don't forget to increment the link->open variable in the
+*  device_open method, and decrement it in the device_close
+*  method.
+*
+* Arguments:
+*      arg     a generic 32 bit variable.  It's the value that
+*              we assigned to link->release.data in sta_attach().
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      All resources should be released after this function
+*      executes and finds the device !open.
+*
+* Call context:
+*      Possibly in a timer context.  Don't do anything that'll
+*      block.
+----------------------------------------------------------------*/
+void prism2sta_release(u_long arg)
+{
+        dev_link_t     *link = (dev_link_t *)arg;
+
+       DBFENTER;
+
+       /* First thing we should do is get the MSD back to the
+        * HWPRESENT state.  I.e. everything quiescent.
+        */
+       prism2sta_ifstate(link->priv, P80211ENUM_ifstate_disable);
+
+        if (link->open) {
+               /* TODO: I don't think we're even using this bit of code
+                * and I don't think it's hurting us at the moment.
+                */
+                WLAN_LOG_DEBUG(1,
+                       "prism2sta_cs: release postponed, '%s' still open\n",
+                       link->dev->dev_name);
+                link->state |= DEV_STALE_CONFIG;
+                return;
+        }
+
+        pcmcia_release_configuration(link->handle);
+        pcmcia_release_io(link->handle, &link->io);
+        pcmcia_release_irq(link->handle, &link->irq);
+
+        link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
+
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_event
+*
+* Handler for card services events.
+*
+* Arguments:
+*      event           The event code
+*      priority        hi/low - REMOVAL is the only hi
+*      args            ptr to card services struct containing info about
+*                      pcmcia status
+*
+* Returns:
+*      Zero on success, non-zero otherwise
+*
+* Side effects:
+*
+*
+* Call context:
+*      Both interrupt and process thread, depends on the event.
+----------------------------------------------------------------*/
+static int
+prism2sta_event (
+       event_t event,
+       int priority,
+       event_callback_args_t *args)
+{
+       int                     result = 0;
+       dev_link_t              *link = (dev_link_t *) args->client_data;
+       wlandevice_t            *wlandev = (wlandevice_t*)link->priv;
+       hfa384x_t               *hw = NULL;
+
+       DBFENTER;
+
+       if (wlandev) hw = wlandev->priv;
+
+       switch (event)
+       {
+       case CS_EVENT_CARD_INSERTION:
+               WLAN_LOG_DEBUG(5,"event is INSERTION\n");
+               link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+               prism2sta_config(link);
+               if (!(link->state & DEV_CONFIG)) {
+                       wlandev->netdev->irq = 0;
+                       WLAN_LOG_ERROR(
+                               "%s: Initialization failed!\n", dev_info);
+                       wlandev->msdstate = WLAN_MSD_HWFAIL;
+                       break;
+               }
+
+               /* Fill in the rest of the hw struct */
+               hw->irq = wlandev->netdev->irq;
+               hw->iobase = wlandev->netdev->base_addr;
+               hw->link = link;
+
+               if (prism2_doreset) {
+                       result = hfa384x_corereset(hw,
+                                       prism2_reset_holdtime,
+                                       prism2_reset_settletime, 0);
+                       if ( result ) {
+                               WLAN_LOG_ERROR(
+                                       "corereset() failed, result=%d.\n",
+                                       result);
+                               wlandev->msdstate = WLAN_MSD_HWFAIL;
+                               break;
+                       }
+               }
+
+#if 0
+               /*
+                * TODO: test_hostif() not implemented yet.
+                */
+               result = hfa384x_test_hostif(hw);
+               if (result) {
+                       WLAN_LOG_ERROR(
+                       "test_hostif() failed, result=%d.\n", result);
+                       wlandev->msdstate = WLAN_MSD_HWFAIL;
+                       break;
+               }
+#endif
+               wlandev->msdstate = WLAN_MSD_HWPRESENT;
+               break;
+
+       case CS_EVENT_CARD_REMOVAL:
+               WLAN_LOG_DEBUG(5,"event is REMOVAL\n");
+               link->state &= ~DEV_PRESENT;
+
+               if (wlandev) {
+                       p80211netdev_hwremoved(wlandev);
+               }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+               if (link->state & DEV_CONFIG)
+               {
+                       link->release.expires = jiffies + (HZ/20);
+                       add_timer(&link->release);
+               }
+#endif
+               break;
+       case CS_EVENT_RESET_REQUEST:
+               WLAN_LOG_DEBUG(5,"event is RESET_REQUEST\n");
+               WLAN_LOG_NOTICE(
+                       "prism2 card reset not supported "
+                       "due to post-reset user mode configuration "
+                       "requirements.\n");
+               WLAN_LOG_NOTICE(
+                       "  From user mode, use "
+                       "'cardctl suspend;cardctl resume' "
+                       "instead.\n");
+               break;
+       case CS_EVENT_RESET_PHYSICAL:
+       case CS_EVENT_CARD_RESET:
+               WLAN_LOG_WARNING("Rx'd CS_EVENT_RESET_xxx, should not "
+                       "be possible since RESET_REQUEST was denied.\n");
+               break;
+
+       case CS_EVENT_PM_SUSPEND:
+               WLAN_LOG_DEBUG(5,"event is SUSPEND\n");
+               link->state |= DEV_SUSPEND;
+               if (link->state & DEV_CONFIG)
+               {
+                       prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+                       pcmcia_release_configuration(link->handle);
+               }
+               break;
+
+       case CS_EVENT_PM_RESUME:
+               WLAN_LOG_DEBUG(5,"event is RESUME\n");
+               link->state &= ~DEV_SUSPEND;
+               if (link->state & DEV_CONFIG) {
+                       pcmcia_request_configuration(link->handle, &link->conf);
+               }
+               break;
+       }
+
+       DBFEXIT;
+       return 0;  /* noone else does anthing with the return value */
+}
+#endif // <= 2.6.15
+
+
+
+int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
+{
+       int             result = 0;
+       conf_reg_t      reg;
+       UINT8           corsave;
+       DBFENTER;
+
+       WLAN_LOG_DEBUG(3, "Doing reset via CardServices().\n");
+
+       /* Collect COR */
+       reg.Function = 0;
+       reg.Action = CS_READ;
+       reg.Offset = CISREG_COR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+       result = pcmcia_access_configuration_register(
+                       hw->link->handle,
+                       &reg);
+#endif
+       if (result != CS_SUCCESS ) {
+               WLAN_LOG_ERROR(
+                       ":0: AccessConfigurationRegister(CS_READ) failed,"
+                       "result=%d.\n", result);
+               result = -EIO;
+       }
+       corsave = reg.Value;
+
+       /* Write reset bit (BIT7) */
+       reg.Value |= BIT7;
+       reg.Action = CS_WRITE;
+       reg.Offset = CISREG_COR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+       result = pcmcia_access_configuration_register(
+                       hw->link->handle,
+                       &reg);
+#endif
+       if (result != CS_SUCCESS ) {
+               WLAN_LOG_ERROR(
+                       ":1: AccessConfigurationRegister(CS_WRITE) failed,"
+                       "result=%d.\n", result);
+               result = -EIO;
+       }
+
+       /* Hold for holdtime */
+       mdelay(holdtime);
+
+       if (genesis) {
+               reg.Value = genesis;
+               reg.Action = CS_WRITE;
+               reg.Offset = CISREG_CCSR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+               result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+               result = pcmcia_access_configuration_register(
+                                     hw->link->handle,
+                                     &reg);
+#endif
+               if (result != CS_SUCCESS ) {
+                       WLAN_LOG_ERROR(
+                               ":1: AccessConfigurationRegister(CS_WRITE) failed,"
+                               "result=%d.\n", result);
+                       result = -EIO;
+               }
+       }
+
+       /* Hold for holdtime */
+       mdelay(holdtime);
+
+       /* Clear reset bit */
+       reg.Value &= ~BIT7;
+       reg.Action = CS_WRITE;
+       reg.Offset = CISREG_COR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+       result = pcmcia_access_configuration_register(
+                                     hw->link->handle,
+                                     &reg);
+#endif
+       if (result != CS_SUCCESS ) {
+               WLAN_LOG_ERROR(
+                       ":2: AccessConfigurationRegister(CS_WRITE) failed,"
+                       "result=%d.\n", result);
+               result = -EIO;
+               goto done;
+       }
+
+       /* Wait for settletime */
+       mdelay(settletime);
+
+       /* Set non-reset bits back what they were */
+       reg.Value = corsave;
+       reg.Action = CS_WRITE;
+       reg.Offset = CISREG_COR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+       result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+       result = pcmcia_access_configuration_register(
+                                     hw->link->handle,
+                                     &reg);
+#endif
+       if (result != CS_SUCCESS ) {
+               WLAN_LOG_ERROR(
+                       ":2: AccessConfigurationRegister(CS_WRITE) failed,"
+                       "result=%d.\n", result);
+               result = -EIO;
+               goto done;
+       }
+
+done:
+       DBFEXIT;
+       return result;
+}
+
+#ifdef MODULE
+
+static int __init prism2cs_init(void)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
+       servinfo_t      serv;
+#endif
+
+       DBFENTER;
+
+        WLAN_LOG_NOTICE("%s Loaded\n", version);
+        WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
+       pcmcia_get_card_services_info(&serv);
+       if ( serv.Revision != CS_RELEASE_CODE )
+       {
+               printk(KERN_NOTICE"%s: CardServices release does not match!\n", dev_info);
+               return -1;
+       }
+
+       /* This call will result in a call to prism2sta_attach */
+       /*   and eventually prism2sta_detach */
+       register_pccard_driver( &dev_info, &prism2sta_attach, &prism2sta_detach);
+#else
+       pcmcia_register_driver(&prism2_cs_driver);
+#endif
+
+       DBFEXIT;
+       return 0;
+}
+
+static void __exit prism2cs_cleanup(void)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
+        dev_link_t *link = dev_list;
+        dev_link_t *nlink;
+        DBFENTER;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
+       for (link=dev_list; link != NULL; link = nlink) {
+               nlink = link->next;
+               if ( link->state & DEV_CONFIG ) {
+                       prism2sta_release((u_long)link);
+               }
+               prism2sta_detach(link); /* remember detach() frees link */
+       }
+#endif
+
+       unregister_pccard_driver( &dev_info);
+#else
+       pcmcia_unregister_driver(&prism2_cs_driver);
+#endif
+
+        printk(KERN_NOTICE "%s Unloaded\n", version);
+
+        DBFEXIT;
+        return;
+}
+
+module_init(prism2cs_init);
+module_exit(prism2cs_cleanup);
+
+#endif // MODULE
+
diff --git a/drivers/staging/wlan-ng/prism2_pci.c b/drivers/staging/wlan-ng/prism2_pci.c
new file mode 100644 (file)
index 0000000..afe32df
--- /dev/null
@@ -0,0 +1,332 @@
+#define WLAN_HOSTIF WLAN_PCI
+#include "hfa384x.c"
+#include "prism2mgmt.c"
+#include "prism2mib.c"
+#include "prism2sta.c"
+
+#define PCI_SIZE               0x1000          /* Memory size - 4K bytes */
+
+/* ISL3874A 11Mb/s WLAN controller */
+#define PCIVENDOR_INTERSIL     0x1260UL
+#define PCIDEVICE_ISL3874      0x3873UL /* [MSM] yeah I know...the ID says
+                                           3873. Trust me, it's a 3874. */
+
+/* Samsung SWL-2210P 11Mb/s WLAN controller (uses ISL3874A) */
+#define PCIVENDOR_SAMSUNG      0x167dUL
+#define PCIDEVICE_SWL_2210P    0xa000UL
+
+#define PCIVENDOR_NETGEAR      0x1385UL /* for MA311 */
+
+/* PCI Class & Sub-Class code, Network-'Other controller' */
+#define PCI_CLASS_NETWORK_OTHERS 0x280
+
+
+/*----------------------------------------------------------------
+* prism2sta_probe_pci
+*
+* Probe routine called when a PCI device w/ matching ID is found.
+* The ISL3874 implementation uses the following map:
+*   BAR0: Prism2.x registers memory mapped, size=4k
+* Here's the sequence:
+*   - Allocate the PCI resources.
+*   - Read the PCMCIA attribute memory to make sure we have a WLAN card
+*   - Reset the MAC
+*   - Initialize the netdev and wlan data
+*   - Initialize the MAC
+*
+* Arguments:
+*      pdev            ptr to pci device structure containing info about
+*                      pci configuration.
+*      id              ptr to the device id entry that matched this device.
+*
+* Returns:
+*      zero            - success
+*      negative        - failed
+*
+* Side effects:
+*
+*
+* Call context:
+*      process thread
+*
+----------------------------------------------------------------*/
+static int __devinit
+prism2sta_probe_pci(
+       struct pci_dev *pdev,
+       const struct pci_device_id *id)
+{
+       int             result;
+       phys_t          phymem = 0;
+       void            __iomem *mem = NULL;
+        wlandevice_t    *wlandev = NULL;
+       hfa384x_t       *hw = NULL;
+
+       DBFENTER;
+
+       /* Enable the pci device */
+       if (pci_enable_device(pdev)) {
+               WLAN_LOG_ERROR("%s: pci_enable_device() failed.\n", dev_info);
+               result = -EIO;
+               goto fail;
+       }
+
+       /* Figure out our resources */
+       phymem = pci_resource_start(pdev, 0);
+
+        if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) {
+               printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n");
+               result = -EIO;
+               goto fail;
+        }
+
+       mem = ioremap(phymem, PCI_SIZE);
+       if ( mem == 0 ) {
+               WLAN_LOG_ERROR("%s: ioremap() failed.\n", dev_info);
+               result = -EIO;
+               goto fail;
+       }
+
+       /* Log the device */
+        WLAN_LOG_INFO("A Prism2.5 PCI device found, "
+               "phymem:0x%llx, irq:%d, mem:0x%p\n",
+               (unsigned long long)phymem, pdev->irq, mem);
+
+       if ((wlandev = create_wlan()) == NULL) {
+               WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+               result = -EIO;
+               goto fail;
+       }
+       hw = wlandev->priv;
+
+       if ( wlan_setup(wlandev) != 0 ) {
+               WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+               result = -EIO;
+               goto fail;
+       }
+
+       /* Setup netdevice's ability to report resources
+        * Note: the netdevice was allocated by wlan_setup()
+        */
+        wlandev->netdev->irq = pdev->irq;
+        wlandev->netdev->mem_start = (unsigned long) mem;
+        wlandev->netdev->mem_end = wlandev->netdev->mem_start +
+               pci_resource_len(pdev, 0);
+
+       /* Initialize the hw data */
+        hfa384x_create(hw, wlandev->netdev->irq, 0, mem);
+       hw->wlandev = wlandev;
+
+       /* Register the wlandev, this gets us a name and registers the
+        * linux netdevice.
+        */
+       SET_MODULE_OWNER(wlandev->netdev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+       SET_NETDEV_DEV(wlandev->netdev, &(pdev->dev));
+#endif
+        if ( register_wlandev(wlandev) != 0 ) {
+               WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
+               result = -EIO;
+               goto fail;
+        }
+
+#if 0
+       /* TODO: Move this and an irq test into an hfa384x_testif() routine.
+        */
+       outw(PRISM2STA_MAGIC, HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
+       reg=inw( HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
+       if ( reg != PRISM2STA_MAGIC ) {
+               WLAN_LOG_ERROR("MAC register access test failed!\n");
+               result = -EIO;
+               goto fail;
+       }
+#endif
+
+       /* Do a chip-level reset on the MAC */
+       if (prism2_doreset) {
+               result = hfa384x_corereset(hw,
+                               prism2_reset_holdtime,
+                               prism2_reset_settletime, 0);
+               if (result != 0) {
+                       WLAN_LOG_ERROR(
+                               "%s: hfa384x_corereset() failed.\n",
+                               dev_info);
+                       unregister_wlandev(wlandev);
+                       hfa384x_destroy(hw);
+                       result = -EIO;
+                       goto fail;
+               }
+       }
+
+        pci_set_drvdata(pdev, wlandev);
+
+       /* Shouldn't actually hook up the IRQ until we
+        * _know_ things are alright.  A test routine would help.
+        */
+               request_irq(wlandev->netdev->irq, hfa384x_interrupt,
+               SA_SHIRQ, wlandev->name, wlandev);
+
+       wlandev->msdstate = WLAN_MSD_HWPRESENT;
+
+       result = 0;
+       goto done;
+
+ fail:
+       pci_set_drvdata(pdev, NULL);
+       if (wlandev)    kfree(wlandev);
+       if (hw)         kfree(hw);
+        if (mem)        iounmap(mem);
+       pci_release_regions(pdev);
+        pci_disable_device(pdev);
+
+ done:
+       DBFEXIT;
+       return result;
+}
+
+static void __devexit prism2sta_remove_pci(struct pci_dev *pdev)
+{
+               wlandevice_t            *wlandev;
+       hfa384x_t       *hw;
+
+       wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
+       hw = wlandev->priv;
+
+       p80211netdev_hwremoved(wlandev);
+
+       /* reset hardware */
+       prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+
+        if (pdev->irq)
+               free_irq(pdev->irq, wlandev);
+
+       unregister_wlandev(wlandev);
+
+       /* free local stuff */
+       if (hw) {
+               hfa384x_destroy(hw);
+               kfree(hw);
+       }
+
+       iounmap((void __iomem *)wlandev->netdev->mem_start);
+       wlan_unsetup(wlandev);
+
+       pci_release_regions(pdev);
+        pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+
+       kfree(wlandev);
+}
+
+
+static struct pci_device_id pci_id_tbl[] = {
+       {
+               PCIVENDOR_INTERSIL, PCIDEVICE_ISL3874,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller"
+       },
+       {
+               PCIVENDOR_INTERSIL, 0x3872,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"Intersil Prism2.5 ISL3872 11Mb/s WLAN Controller"
+       },
+        {
+               PCIVENDOR_SAMSUNG, PCIDEVICE_SWL_2210P,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"Samsung MagicLAN SWL-2210P 11Mb/s WLAN Controller"
+       },
+       { /* for NetGear MA311 */
+               PCIVENDOR_NETGEAR, 0x3872,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"Netgear MA311 WLAN Controller"
+       },
+       {
+               0, 0, 0, 0, 0, 0, 0
+       }
+};
+
+MODULE_DEVICE_TABLE(pci, pci_id_tbl);
+
+/* Function declared here because of ptr reference below */
+static int  __devinit prism2sta_probe_pci(struct pci_dev *pdev,
+                               const struct pci_device_id *id);
+static void  __devexit prism2sta_remove_pci(struct pci_dev *pdev);
+
+static struct pci_driver prism2_pci_drv_id = {
+        .name = "prism2_pci",
+        .id_table = pci_id_tbl,
+        .probe = prism2sta_probe_pci,
+        .remove = prism2sta_remove_pci,
+#ifdef CONFIG_PM
+        .suspend = prism2sta_suspend_pci,
+        .resume = prism2sta_resume_pci,
+#endif
+};
+
+#ifdef MODULE
+
+static int __init prism2pci_init(void)
+{
+        WLAN_LOG_NOTICE("%s Loaded\n", version);
+       return pci_module_init(&prism2_pci_drv_id);
+};
+
+static void __exit prism2pci_cleanup(void)
+{
+       pci_unregister_driver(&prism2_pci_drv_id);
+};
+
+module_init(prism2pci_init);
+module_exit(prism2pci_cleanup);
+
+#endif
+
+int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
+{
+       int             result = 0;
+       unsigned long   timeout;
+       UINT16  reg;
+       DBFENTER;
+
+       /* Assert reset and wait awhile
+        * (note: these delays are _really_ long, but they appear to be
+        *        necessary.)
+        */
+       hfa384x_setreg(hw, 0xc5, HFA384x_PCICOR);
+       timeout = jiffies + HZ/4;
+       while(time_before(jiffies, timeout)) udelay(5);
+
+       if (genesis) {
+               hfa384x_setreg(hw, genesis, HFA384x_PCIHCR);
+               timeout = jiffies + HZ/4;
+               while(time_before(jiffies, timeout)) udelay(5);
+       }
+
+       /* Clear the reset and wait some more
+        */
+       hfa384x_setreg(hw, 0x45, HFA384x_PCICOR);
+       timeout = jiffies + HZ/2;
+       while(time_before(jiffies, timeout)) udelay(5);
+
+       /* Wait for f/w to complete initialization (CMD:BUSY == 0)
+        */
+       timeout = jiffies + 2*HZ;
+       reg = hfa384x_getreg(hw, HFA384x_CMD);
+       while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) {
+               reg = hfa384x_getreg(hw, HFA384x_CMD);
+               udelay(10);
+       }
+       if (HFA384x_CMD_ISBUSY(reg)) {
+               WLAN_LOG_WARNING("corereset: Timed out waiting for cmd register.\n");
+               result=1;
+       }
+       DBFEXIT;
+       return result;
+}
diff --git a/drivers/staging/wlan-ng/prism2_plx.c b/drivers/staging/wlan-ng/prism2_plx.c
new file mode 100644 (file)
index 0000000..320443f
--- /dev/null
@@ -0,0 +1,472 @@
+#define WLAN_HOSTIF WLAN_PLX
+#include "hfa384x.c"
+#include "prism2mgmt.c"
+#include "prism2mib.c"
+#include "prism2sta.c"
+
+#define PLX_ATTR_SIZE  0x1000  /* Attribute memory size - 4K bytes */
+#define COR_OFFSET     0x3e0   /* COR attribute offset of Prism2 PC card */
+#define COR_VALUE      0x41    /* Enable PC card with irq in level trigger */
+#define PLX_INTCSR     0x4c    /* Interrupt Control and Status Register */
+#define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */
+#define PLX_MIN_ATTR_LEN 512    /* at least 2 x 256 is needed for CIS */
+
+/* 3Com 3CRW777A (PLX) board ID */
+#define PCIVENDOR_3COM       0x10B7
+#define PCIDEVICE_AIRCONNECT 0x7770
+
+/* Eumitcom PCI WL11000 PCI Adapter (PLX) board device+vendor ID */
+#define PCIVENDOR_EUMITCOM     0x1638UL
+#define PCIDEVICE_WL11000      0x1100UL
+
+/* Global Sun Tech GL24110P PCI Adapter (PLX) board device+vendor ID */
+#define PCIVENDOR_GLOBALSUN    0x16abUL
+#define PCIDEVICE_GL24110P     0x1101UL
+#define PCIDEVICE_GL24110P_ALT 0x1102UL
+
+/* Netgear MA301 PCI Adapter (PLX) board device+vendor ID */
+#define PCIVENDOR_NETGEAR      0x1385UL
+#define PCIDEVICE_MA301                0x4100UL
+
+/* US Robotics USR2410 PCI Adapter (PLX) board device+vendor ID */
+#define        PCIVENDOR_USROBOTICS    0x16ecUL
+#define PCIDEVICE_USR2410       0x3685UL
+
+/* Linksys WPC11 card with the WDT11 adapter (PLX) board device+vendor ID */
+#define        PCIVENDOR_Linksys       0x16abUL
+#define PCIDEVICE_Wpc11Wdt11    0x1102UL
+
+/* National Datacomm Corp SOHOware Netblaster II PCI */
+#define PCIVENDOR_NDC          0x15e8UL
+#define PCIDEVICE_NCP130_PLX   0x0130UL
+#define PCIDEVICE_NCP130_ASIC  0x0131UL
+
+/* NDC NCP130_PLX is also sold by Corega. Their name is CGWLPCIA11 */
+#define PCIVENDOR_COREGA       PCIVENDOR_NDC
+#define PCIDEVICE_CGWLPCIA11   PCIDEVICE_NCP130_PLX
+
+/* PCI Class & Sub-Class code, Network-'Other controller' */
+#define PCI_CLASS_NETWORK_OTHERS 0x280
+
+/*----------------------------------------------------------------
+* prism2sta_probe_plx
+*
+* Probe routine called when a PCI device w/ matching ID is found.
+* This PLX implementation uses the following map:
+*   BAR0: Unused
+*   BAR1: ????
+*   BAR2: PCMCIA attribute memory
+*   BAR3: PCMCIA i/o space
+* Here's the sequence:
+*   - Allocate the PCI resources.
+*   - Read the PCMCIA attribute memory to make sure we have a WLAN card
+*   - Reset the MAC using the PCMCIA COR
+*   - Initialize the netdev and wlan data
+*   - Initialize the MAC
+*
+* Arguments:
+*      pdev            ptr to pci device structure containing info about
+*                      pci configuration.
+*      id              ptr to the device id entry that matched this device.
+*
+* Returns:
+*      zero            - success
+*      negative        - failed
+*
+* Side effects:
+*
+*
+* Call context:
+*      process thread
+*
+----------------------------------------------------------------*/
+static int __devinit
+prism2sta_probe_plx(
+       struct pci_dev                  *pdev,
+       const struct pci_device_id      *id)
+{
+       int             result;
+        phys_t pccard_ioaddr;
+       phys_t  pccard_attr_mem;
+        unsigned int    pccard_attr_len;
+       void __iomem *attr_mem = NULL;
+       UINT32          plx_addr;
+        wlandevice_t    *wlandev = NULL;
+       hfa384x_t       *hw = NULL;
+       int             reg;
+        u32            regic;
+
+       if (pci_enable_device(pdev))
+               return -EIO;
+
+       /* TMC7160 boards are special */
+       if ((pdev->vendor == PCIVENDOR_NDC) &&
+           (pdev->device == PCIDEVICE_NCP130_ASIC)) {
+               unsigned long delay;
+
+               pccard_attr_mem = 0;
+               pccard_ioaddr = pci_resource_start(pdev, 1);
+
+               outb(0x45, pccard_ioaddr);
+               delay = jiffies + 1*HZ;
+               while (time_before(jiffies, delay));
+
+               if (inb(pccard_ioaddr) != 0x45) {
+                       WLAN_LOG_ERROR("Initialize the TMC7160 failed. (0x%x)\n", inb(pccard_ioaddr));
+                       return -EIO;
+               }
+
+               pccard_ioaddr = pci_resource_start(pdev, 2);
+               prism2_doreset = 0;
+
+               WLAN_LOG_INFO("NDC NCP130 with TMC716(ASIC) PCI interface device found at io:0x%x, irq:%d\n", pccard_ioaddr, pdev->irq);
+               goto init;
+       }
+
+       /* Collect the resource requirements */
+       pccard_attr_mem = pci_resource_start(pdev, 2);
+       pccard_attr_len = pci_resource_len(pdev, 2);
+        if (pccard_attr_len < PLX_MIN_ATTR_LEN)
+               return -EIO;
+
+       pccard_ioaddr = pci_resource_start(pdev, 3);
+
+       /* bjoern: We need to tell the card to enable interrupts, in
+        * case the serial eprom didn't do this already. See the
+        * PLX9052 data book, p8-1 and 8-24 for reference.
+        * [MSM]: This bit of code came from the orinoco_cs driver.
+        */
+       plx_addr = pci_resource_start(pdev, 1);
+
+       regic = 0;
+       regic = inl(plx_addr+PLX_INTCSR);
+       if(regic & PLX_INTCSR_INTEN) {
+               WLAN_LOG_DEBUG(1,
+                       "%s: Local Interrupt already enabled\n", dev_info);
+       } else {
+               regic |= PLX_INTCSR_INTEN;
+               outl(regic, plx_addr+PLX_INTCSR);
+               regic = inl(plx_addr+PLX_INTCSR);
+               if(!(regic & PLX_INTCSR_INTEN)) {
+                       WLAN_LOG_ERROR(
+                               "%s: Couldn't enable Local Interrupts\n",
+                               dev_info);
+                       return -EIO;
+               }
+       }
+
+       /* These assignments are here in case of future mappings for
+        * io space and irq that might be similar to ioremap
+        */
+        if (!request_mem_region(pccard_attr_mem, pci_resource_len(pdev, 2), "Prism2")) {
+               WLAN_LOG_ERROR("%s: Couldn't reserve PCI memory region\n", dev_info);
+               return -EIO;
+        }
+
+       attr_mem = ioremap(pccard_attr_mem, pccard_attr_len);
+
+       WLAN_LOG_INFO("A PLX PCI/PCMCIA interface device found, "
+               "phymem:0x%llx, phyio=0x%x, irq:%d, "
+               "mem: 0x%lx\n",
+               (unsigned long long)pccard_attr_mem, pccard_ioaddr, pdev->irq,
+               (unsigned long)attr_mem);
+
+       /* Verify whether PC card is present.
+        * [MSM] This needs improvement, the right thing to do is
+        * probably to walk the CIS looking for the vendor and product
+        * IDs.  It would be nice if this could be tied in with the
+        * etc/pcmcia/wlan-ng.conf file.  Any volunteers?  ;-)
+        */
+       if (
+       readb(attr_mem + 0) != 0x01 || readb(attr_mem + 2) != 0x03 ||
+       readb(attr_mem + 4) != 0x00 || readb(attr_mem + 6) != 0x00 ||
+       readb(attr_mem + 8) != 0xFF || readb(attr_mem + 10) != 0x17 ||
+       readb(attr_mem + 12) != 0x04 || readb(attr_mem + 14) != 0x67) {
+               WLAN_LOG_ERROR("Prism2 PC card CIS is invalid.\n");
+               return -EIO;
+        }
+        WLAN_LOG_INFO("A PCMCIA WLAN adapter was found.\n");
+
+        /* Write COR to enable PC card */
+       writeb(COR_VALUE, attr_mem + COR_OFFSET);
+       reg = readb(attr_mem + COR_OFFSET);
+
+ init:
+
+       /*
+        * Now do everything the same as a PCI device
+        * [MSM] TODO: We could probably factor this out of pcmcia/pci/plx
+        * and perhaps usb.  Perhaps a task for another day.......
+        */
+
+       if ((wlandev = create_wlan()) == NULL) {
+               WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+               result = -EIO;
+               goto failed;
+       }
+
+       hw = wlandev->priv;
+
+       if ( wlan_setup(wlandev) != 0 ) {
+               WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+               result = -EIO;
+               goto failed;
+       }
+
+       /* Setup netdevice's ability to report resources
+        * Note: the netdevice was allocated by wlan_setup()
+        */
+        wlandev->netdev->irq = pdev->irq;
+        wlandev->netdev->base_addr = pccard_ioaddr;
+        wlandev->netdev->mem_start = (unsigned long)attr_mem;
+        wlandev->netdev->mem_end = (unsigned long)attr_mem + pci_resource_len(pdev, 0);
+
+       /* Initialize the hw data */
+        hfa384x_create(hw, wlandev->netdev->irq, pccard_ioaddr, attr_mem);
+       hw->wlandev = wlandev;
+
+       /* Register the wlandev, this gets us a name and registers the
+        * linux netdevice.
+        */
+       SET_MODULE_OWNER(wlandev->netdev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+       SET_NETDEV_DEV(wlandev->netdev, &(pdev->dev));
+#endif
+        if ( register_wlandev(wlandev) != 0 ) {
+               WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
+               result = -EIO;
+               goto failed;
+        }
+
+#if 0
+       /* TODO: Move this and an irq test into an hfa384x_testif() routine.
+        */
+       outw(PRISM2STA_MAGIC, HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
+       reg=inw( HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
+       if ( reg != PRISM2STA_MAGIC ) {
+               WLAN_LOG_ERROR("MAC register access test failed!\n");
+               result = -EIO;
+               goto failed;
+       }
+#endif
+
+       /* Do a chip-level reset on the MAC */
+       if (prism2_doreset) {
+               result = hfa384x_corereset(hw,
+                               prism2_reset_holdtime,
+                               prism2_reset_settletime, 0);
+               if (result != 0) {
+                       unregister_wlandev(wlandev);
+                       hfa384x_destroy(hw);
+                       WLAN_LOG_ERROR(
+                               "%s: hfa384x_corereset() failed.\n",
+                               dev_info);
+                       result = -EIO;
+                       goto failed;
+               }
+       }
+
+       pci_set_drvdata(pdev, wlandev);
+
+       /* Shouldn't actually hook up the IRQ until we
+        * _know_ things are alright.  A test routine would help.
+        */
+               request_irq(wlandev->netdev->irq, hfa384x_interrupt,
+               SA_SHIRQ, wlandev->name, wlandev);
+
+       wlandev->msdstate = WLAN_MSD_HWPRESENT;
+
+       result = 0;
+
+       goto done;
+
+ failed:
+
+       pci_set_drvdata(pdev, NULL);
+       if (wlandev)    kfree(wlandev);
+       if (hw)         kfree(hw);
+        if (attr_mem)        iounmap(attr_mem);
+       pci_release_regions(pdev);
+        pci_disable_device(pdev);
+
+ done:
+       DBFEXIT;
+        return result;
+}
+
+static void __devexit prism2sta_remove_plx(struct pci_dev *pdev)
+{
+               wlandevice_t            *wlandev;
+       hfa384x_t               *hw;
+
+       wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
+       hw = wlandev->priv;
+
+       p80211netdev_hwremoved(wlandev);
+
+       /* reset hardware */
+       prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+
+        if (pdev->irq)
+               free_irq(pdev->irq, wlandev);
+
+       unregister_wlandev(wlandev);
+
+       /* free local stuff */
+       if (hw) {
+               hfa384x_destroy(hw);
+               kfree(hw);
+       }
+
+       iounmap((void __iomem *)wlandev->netdev->mem_start);
+       wlan_unsetup(wlandev);
+
+       pci_release_regions(pdev);
+        pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+
+       kfree(wlandev);
+}
+
+static struct pci_device_id plx_id_tbl[] = {
+       {
+               PCIVENDOR_EUMITCOM, PCIDEVICE_WL11000,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"Eumitcom WL11000 PCI(PLX) card"
+       },
+       {
+               PCIVENDOR_GLOBALSUN, PCIDEVICE_GL24110P,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"Global Sun Tech GL24110P PCI(PLX) card"
+       },
+       {
+               PCIVENDOR_GLOBALSUN, PCIDEVICE_GL24110P_ALT,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"Global Sun Tech GL24110P PCI(PLX) card"
+       },
+       {
+               PCIVENDOR_NETGEAR, PCIDEVICE_MA301,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"Global Sun Tech GL24110P PCI(PLX) card"
+       },
+       {
+               PCIVENDOR_USROBOTICS, PCIDEVICE_USR2410,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"US Robotics USR2410 PCI(PLX) card"
+       },
+       {
+               PCIVENDOR_Linksys, PCIDEVICE_Wpc11Wdt11,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"Linksys WPC11 with WDT11 PCI(PLX) adapter"
+       },
+       {
+               PCIVENDOR_NDC, PCIDEVICE_NCP130_PLX,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"NDC Netblaster II PCI(PLX)"
+       },
+       {
+               PCIVENDOR_NDC, PCIDEVICE_NCP130_ASIC,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"NDC Netblaster II PCI(TMC7160)"
+       },
+       {
+               PCIVENDOR_3COM, PCIDEVICE_AIRCONNECT,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               /* Driver data, we just put the name here */
+               (unsigned long)"3Com AirConnect PCI 802.11b 11Mb/s WLAN Controller"
+       },
+       {
+               0, 0, 0, 0, 0, 0, 0
+       }
+};
+
+MODULE_DEVICE_TABLE(pci, plx_id_tbl);
+
+/* Function declared here because of ptr reference below */
+static int __devinit prism2sta_probe_plx(struct pci_dev *pdev,
+                                        const struct pci_device_id *);
+static void __devexit prism2sta_remove_plx(struct pci_dev *pdev);
+
+static struct pci_driver prism2_plx_drv_id = {
+        .name = "prism2_plx",
+        .id_table = plx_id_tbl,
+        .probe = prism2sta_probe_plx,
+        .remove = prism2sta_remove_plx,
+#ifdef CONFIG_PM
+        .suspend = prism2sta_suspend_pci,
+        .resume = prism2sta_resume_pci,
+#endif
+};
+
+#ifdef MODULE
+
+static int __init prism2plx_init(void)
+{
+        WLAN_LOG_NOTICE("%s Loaded\n", version);
+       return pci_module_init(&prism2_plx_drv_id);
+};
+
+static void __exit prism2plx_cleanup(void)
+{
+       pci_unregister_driver(&prism2_plx_drv_id);
+};
+
+module_init(prism2plx_init);
+module_exit(prism2plx_cleanup);
+
+#endif // MODULE
+
+
+int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
+{
+       int             result = 0;
+
+#define COR_OFFSET     0x3e0   /* COR attribute offset of Prism2 PC card */
+#define COR_VALUE      0x41    /* Enable PC card with irq in level trigger */
+
+#define HCR_OFFSET     0x3e2   /* HCR attribute offset of Prism2 PC card */
+
+       UINT8           corsave;
+       DBFENTER;
+
+       WLAN_LOG_DEBUG(3, "Doing reset via direct COR access.\n");
+
+       /* Collect COR */
+       corsave = readb(hw->membase + COR_OFFSET);
+       /* Write reset bit (BIT7) */
+       writeb(corsave | BIT7, hw->membase + COR_OFFSET);
+       /* Hold for holdtime */
+       mdelay(holdtime);
+
+       if (genesis) {
+               writeb(genesis, hw->membase + HCR_OFFSET);
+               /* Hold for holdtime */
+               mdelay(holdtime);
+       }
+
+       /* Clear reset bit */
+       writeb(corsave & ~BIT7, hw->membase + COR_OFFSET);
+       /* Wait for settletime */
+       mdelay(settletime);
+       /* Set non-reset bits back what they were */
+       writeb(corsave, hw->membase + COR_OFFSET);
+       DBFEXIT;
+       return result;
+}
diff --git a/drivers/staging/wlan-ng/prism2_usb.c b/drivers/staging/wlan-ng/prism2_usb.c
new file mode 100644 (file)
index 0000000..e45be23
--- /dev/null
@@ -0,0 +1,361 @@
+#define WLAN_HOSTIF WLAN_USB
+#include "hfa384x_usb.c"
+#include "prism2mgmt.c"
+#include "prism2mib.c"
+#include "prism2sta.c"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+#error "prism2_usb requires at least a 2.4.x kernel!"
+#endif
+
+#define PRISM_USB_DEVICE(vid, pid, name) \
+           USB_DEVICE(vid, pid),  \
+           .driver_info = (unsigned long) name
+
+static struct usb_device_id usb_prism_tbl[] = {
+       {PRISM_USB_DEVICE(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS")},
+       {PRISM_USB_DEVICE(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11")},
+       {PRISM_USB_DEVICE(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x049f, 0x0033, "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
+       {PRISM_USB_DEVICE(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
+       {PRISM_USB_DEVICE(0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
+       {PRISM_USB_DEVICE(0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
+       {PRISM_USB_DEVICE(0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")},
+       {PRISM_USB_DEVICE(0x0967, 0x0204, "Acer Warplink USB Adapter")},
+       {PRISM_USB_DEVICE(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")},
+       {PRISM_USB_DEVICE(0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")},
+       {PRISM_USB_DEVICE(0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")},
+       {PRISM_USB_DEVICE(0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")},
+       {PRISM_USB_DEVICE(0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")},
+       {PRISM_USB_DEVICE(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")},
+        {PRISM_USB_DEVICE(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
+       {PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")},
+        {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
+//     {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")},
+       {PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")},
+       {PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")},
+       {PRISM_USB_DEVICE(0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")},
+       {PRISM_USB_DEVICE(0x50c2, 0x4013, "Averatec USB WLAN Adapter")},
+       {PRISM_USB_DEVICE(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter")},
+       {PRISM_USB_DEVICE(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter")},
+       {PRISM_USB_DEVICE(0x2821, 0x3300, "Hawking HighDB USB Adapter")},
+       {PRISM_USB_DEVICE(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")},
+       {PRISM_USB_DEVICE(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter")},
+       {PRISM_USB_DEVICE(0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")},
+       {PRISM_USB_DEVICE(0x0bb2, 0x0302, "Ambit Microsystems Corp.")},
+       {PRISM_USB_DEVICE(0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")},
+       {PRISM_USB_DEVICE(0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")},
+       { /* terminator */ }
+};
+
+MODULE_DEVICE_TABLE(usb, usb_prism_tbl);
+
+/*----------------------------------------------------------------
+* prism2sta_probe_usb
+*
+* Probe routine called by the USB subsystem.
+*
+* Arguments:
+*      dev             ptr to the usb_device struct
+*      ifnum           interface number being offered
+*
+* Returns:
+*      NULL            - we're not claiming the device+interface
+*      non-NULL        - we are claiming the device+interface and
+*                        this is a ptr to the data we want back
+*                        when disconnect is called.
+*
+* Side effects:
+*
+* Call context:
+*      I'm not sure, assume it's interrupt.
+*
+----------------------------------------------------------------*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static void __devinit *prism2sta_probe_usb(
+       struct usb_device *dev,
+       unsigned int ifnum,
+       const struct usb_device_id *id)
+#else
+static int prism2sta_probe_usb(
+       struct usb_interface *interface,
+       const struct usb_device_id *id)
+#endif
+{
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+       struct usb_interface *interface;
+#else
+       struct usb_device *dev;
+#endif
+
+       wlandevice_t    *wlandev = NULL;
+       hfa384x_t       *hw = NULL;
+       int              result = 0;
+
+       DBFENTER;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+       interface = &dev->actconfig->interface[ifnum];
+#else
+       dev = interface_to_usbdev(interface);
+#endif
+
+
+       if ((wlandev = create_wlan()) == NULL) {
+               WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+               result = -EIO;
+               goto failed;
+       }
+       hw = wlandev->priv;
+
+       if ( wlan_setup(wlandev) != 0 ) {
+               WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+               result = -EIO;
+               goto failed;
+       }
+
+       /* Initialize the hw data */
+       hfa384x_create(hw, dev);
+       hw->wlandev = wlandev;
+
+       /* Register the wlandev, this gets us a name and registers the
+        * linux netdevice.
+        */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+       SET_NETDEV_DEV(wlandev->netdev, &(interface->dev));
+#endif
+        if ( register_wlandev(wlandev) != 0 ) {
+               WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
+               result = -EIO;
+               goto failed;
+        }
+
+       /* Do a chip-level reset on the MAC */
+       if (prism2_doreset) {
+               result = hfa384x_corereset(hw,
+                               prism2_reset_holdtime,
+                               prism2_reset_settletime, 0);
+               if (result != 0) {
+                       unregister_wlandev(wlandev);
+                       hfa384x_destroy(hw);
+                       result = -EIO;
+                       WLAN_LOG_ERROR(
+                               "%s: hfa384x_corereset() failed.\n",
+                               dev_info);
+                       goto failed;
+               }
+       }
+
+#ifndef NEW_MODULE_CODE
+       usb_inc_dev_use(dev);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+       usb_get_dev(dev);
+#endif
+
+       wlandev->msdstate = WLAN_MSD_HWPRESENT;
+
+       goto done;
+
+ failed:
+       if (wlandev)    kfree(wlandev);
+       if (hw)         kfree(hw);
+       wlandev = NULL;
+
+ done:
+       DBFEXIT;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+       return wlandev;
+#else
+       usb_set_intfdata(interface, wlandev);
+       return result;
+#endif
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_disconnect_usb
+*
+* Called when a device previously claimed by probe is removed
+* from the USB.
+*
+* Arguments:
+*      dev             ptr to the usb_device struct
+*      ptr             ptr returned by probe() when the device
+*                       was claimed.
+*
+* Returns:
+*      Nothing
+*
+* Side effects:
+*
+* Call context:
+*      process
+----------------------------------------------------------------*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static void __devexit
+prism2sta_disconnect_usb(struct usb_device *dev, void *ptr)
+#else
+static void
+prism2sta_disconnect_usb(struct usb_interface *interface)
+#endif
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+       wlandevice_t            *wlandev;
+#else
+       wlandevice_t            *wlandev = (wlandevice_t*)ptr;
+#endif
+
+        DBFENTER;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+       wlandev = (wlandevice_t *) usb_get_intfdata(interface);
+#endif
+
+       if ( wlandev != NULL ) {
+               LIST_HEAD(cleanlist);
+               struct list_head        *entry;
+               struct list_head        *temp;
+               unsigned long           flags;
+
+               hfa384x_t               *hw = wlandev->priv;
+
+               if (!hw)
+                       goto exit;
+
+               spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+               p80211netdev_hwremoved(wlandev);
+               list_splice_init(&hw->ctlxq.reapable, &cleanlist);
+               list_splice_init(&hw->ctlxq.completing, &cleanlist);
+               list_splice_init(&hw->ctlxq.pending, &cleanlist);
+               list_splice_init(&hw->ctlxq.active, &cleanlist);
+
+               spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+               /* There's no hardware to shutdown, but the driver
+                * might have some tasks or tasklets that must be
+                * stopped before we can tear everything down.
+                */
+               prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+
+               del_singleshot_timer_sync(&hw->throttle);
+               del_singleshot_timer_sync(&hw->reqtimer);
+               del_singleshot_timer_sync(&hw->resptimer);
+
+               /* Unlink all the URBs. This "removes the wheels"
+                * from the entire CTLX handling mechanism.
+                */
+               usb_kill_urb(&hw->rx_urb);
+               usb_kill_urb(&hw->tx_urb);
+               usb_kill_urb(&hw->ctlx_urb);
+
+               tasklet_kill(&hw->completion_bh);
+               tasklet_kill(&hw->reaper_bh);
+
+               flush_scheduled_work();
+
+               /* Now we complete any outstanding commands
+                * and tell everyone who is waiting for their
+                * responses that we have shut down.
+                */
+               list_for_each(entry, &cleanlist) {
+                       hfa384x_usbctlx_t       *ctlx;
+
+                       ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
+                       complete(&ctlx->done);
+               }
+
+               /* Give any outstanding synchronous commands
+                * a chance to complete. All they need to do
+                * is "wake up", so that's easy.
+                * (I'd like a better way to do this, really.)
+                */
+               msleep(100);
+
+               /* Now delete the CTLXs, because no-one else can now. */
+               list_for_each_safe(entry, temp, &cleanlist) {
+                       hfa384x_usbctlx_t *ctlx;
+
+                       ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
+                       kfree(ctlx);
+               }
+
+               /* Unhook the wlandev */
+               unregister_wlandev(wlandev);
+               wlan_unsetup(wlandev);
+
+#ifndef NEW_MODULE_CODE
+               usb_dec_dev_use(hw->usb);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+               usb_put_dev(hw->usb);
+#endif
+
+               hfa384x_destroy(hw);
+               kfree(hw);
+
+               kfree(wlandev);
+       }
+
+ exit:
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+       usb_set_intfdata(interface, NULL);
+#endif
+       DBFEXIT;
+}
+
+
+static struct usb_driver prism2_usb_driver = {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,19)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
+       .owner = THIS_MODULE,
+#endif
+       .name = "prism2_usb",
+       .probe = prism2sta_probe_usb,
+       .disconnect = prism2sta_disconnect_usb,
+       .id_table = usb_prism_tbl,
+       /* fops, minor? */
+};
+
+#ifdef MODULE
+
+static int __init prism2usb_init(void)
+{
+        DBFENTER;
+
+        WLAN_LOG_NOTICE("%s Loaded\n", version);
+        WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info);
+
+       /* This call will result in calls to prism2sta_probe_usb. */
+       return usb_register(&prism2_usb_driver);
+
+       DBFEXIT;
+};
+
+static void __exit prism2usb_cleanup(void)
+{
+        DBFENTER;
+
+       usb_deregister(&prism2_usb_driver);
+
+        printk(KERN_NOTICE "%s Unloaded\n", version);
+
+       DBFEXIT;
+};
+
+module_init(prism2usb_init);
+module_exit(prism2usb_cleanup);
+
+#endif // module
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
new file mode 100644 (file)
index 0000000..c975025
--- /dev/null
@@ -0,0 +1,2956 @@
+/* src/prism2/driver/prism2mgmt.c
+*
+* Management request handler functions.
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* The functions in this file handle management requests sent from
+* user mode.
+*
+* Most of these functions have two separate blocks of code that are
+* conditional on whether this is a station or an AP.  This is used
+* to separate out the STA and AP responses to these management primitives.
+* It's a choice (good, bad, indifferent?) to have the code in the same
+* place so it's clear that the same primitive is implemented in both
+* cases but has different behavior.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+#define WLAN_DBVAR     prism2_debug
+
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/if_arp.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <linux/random.h>
+
+#if (WLAN_HOSTIF == WLAN_USB)
+#include <linux/usb.h>
+#endif
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/cisreg.h>
+#endif
+
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+
+/*================================================================*/
+/* Local Macros */
+
+/* Converts 802.11 format rate specifications to prism2 */
+#define p80211rate_to_p2bit(n) ((((n)&~BIT7) == 2) ? BIT0 : \
+                                (((n)&~BIT7) == 4) ? BIT1 : \
+                                (((n)&~BIT7) == 11) ? BIT2 : \
+                                (((n)&~BIT7) == 22) ? BIT3 : 0)
+
+/*================================================================*/
+/* Local Types */
+
+
+/*================================================================*/
+/* Local Static Definitions */
+
+
+/*================================================================*/
+/* Local Function Declarations */
+
+
+/*================================================================*/
+/* Function Definitions */
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_powermgmt
+*
+* Set the power management state of this station's MAC.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_dot11req_powermgmt_t  *msg = msgp;
+
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+               /*
+                * Set CNFPMENABLED (on or off)
+                * Set CNFMULTICASTRX (if PM on, otherwise clear)
+                * Spout a notice stating that SleepDuration and
+                * HoldoverDuration and PMEPS also have an impact.
+                */
+               /* Powermgmt is currently unsupported for STA */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       } else {
+
+               /*** ACCESS POINT ***/
+
+               /* Powermgmt is never supported for AP */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_scan
+*
+* Initiate a scan for BSSs.
+*
+* This function corresponds to MLME-scan.request and part of
+* MLME-scan.confirm.  As far as I can tell in the standard, there
+* are no restrictions on when a scan.request may be issued.  We have
+* to handle in whatever state the driver/MAC happen to be.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_dot11req_scan_t       *msg = msgp;
+        UINT16                  roamingmode, word;
+       int                     i, timeout;
+       int                     istmpenable = 0;
+
+        hfa384x_HostScanRequest_data_t  scanreq;
+
+       DBFENTER;
+
+        if (hw->ap) {
+                WLAN_LOG_ERROR("Prism2 in AP mode cannot perform scans.\n");
+                result = 1;
+                msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+                goto exit;
+        }
+
+        /* gatekeeper check */
+        if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+                                     hw->ident_sta_fw.minor,
+                                     hw->ident_sta_fw.variant) <
+            HFA384x_FIRMWARE_VERSION(1,3,2)) {
+               WLAN_LOG_ERROR("HostScan not supported with current firmware (<1.3.2).\n");
+                result = 1;
+                msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+               goto exit;
+       }
+
+        memset(&scanreq, 0, sizeof(scanreq));
+
+        /* save current roaming mode */
+        result = hfa384x_drvr_getconfig16(hw,
+                        HFA384x_RID_CNFROAMINGMODE, &roamingmode);
+        if ( result ) {
+                WLAN_LOG_ERROR("getconfig(ROAMMODE) failed. result=%d\n",
+                                result);
+                msg->resultcode.data =
+                        P80211ENUM_resultcode_implementation_failure;
+                goto exit;
+        }
+
+        /* drop into mode 3 for the scan */
+        result = hfa384x_drvr_setconfig16(hw,
+                        HFA384x_RID_CNFROAMINGMODE,
+                       HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+        if ( result ) {
+                WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n",
+                                result);
+                msg->resultcode.data =
+                        P80211ENUM_resultcode_implementation_failure;
+                goto exit;
+        }
+
+        /* active or passive? */
+        if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+                                     hw->ident_sta_fw.minor,
+                                     hw->ident_sta_fw.variant) >
+            HFA384x_FIRMWARE_VERSION(1,5,0)) {
+                if (msg->scantype.data != P80211ENUM_scantype_active) {
+                        word = host2hfa384x_16(msg->maxchanneltime.data);
+                } else {
+                        word = 0;
+                }
+                result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word);
+                if ( result ) {
+                        WLAN_LOG_WARNING("Passive scan not supported with "
+                                         "current firmware.  (<1.5.1)\n");
+                }
+        }
+
+       /* set up the txrate to be 2MBPS. Should be fastest basicrate... */
+       word = HFA384x_RATEBIT_2;
+       scanreq.txRate = host2hfa384x_16(word);
+
+        /* set up the channel list */
+        word = 0;
+        for (i = 0; i < msg->channellist.data.len; i++) {
+                UINT8 channel = msg->channellist.data.data[i];
+                if (channel > 14) continue;
+                /* channel 1 is BIT0 ... channel 14 is BIT13 */
+                word |= (1 << (channel-1));
+        }
+        scanreq.channelList = host2hfa384x_16(word);
+
+        /* set up the ssid, if present. */
+        scanreq.ssid.len = host2hfa384x_16(msg->ssid.data.len);
+        memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
+
+       /* Enable the MAC port if it's not already enabled  */
+       result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word);
+       if ( result ) {
+               WLAN_LOG_ERROR("getconfig(PORTSTATUS) failed. "
+                               "result=%d\n", result);
+               msg->resultcode.data =
+                       P80211ENUM_resultcode_implementation_failure;
+               goto exit;
+       }
+       if (word == HFA384x_PORTSTATUS_DISABLED) {
+               UINT16 wordbuf[17];
+
+               result = hfa384x_drvr_setconfig16(hw,
+                       HFA384x_RID_CNFROAMINGMODE,
+                       HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+               if ( result ) {
+                       WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result);
+                       msg->resultcode.data =
+                               P80211ENUM_resultcode_implementation_failure;
+                       goto exit;
+               }
+               /* Construct a bogus SSID and assign it to OwnSSID and
+                * DesiredSSID
+                */
+               wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN);
+               get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN);
+               result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
+                               wordbuf, HFA384x_RID_CNFOWNSSID_LEN);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set OwnSSID.\n");
+                       msg->resultcode.data =
+                               P80211ENUM_resultcode_implementation_failure;
+                       goto exit;
+               }
+               result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
+                               wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set DesiredSSID.\n");
+                       msg->resultcode.data =
+                               P80211ENUM_resultcode_implementation_failure;
+                       goto exit;
+               }
+               /* bsstype */
+               result = hfa384x_drvr_setconfig16(hw,
+                               HFA384x_RID_CNFPORTTYPE,
+                               HFA384x_PORTTYPE_IBSS);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set CNFPORTTYPE.\n");
+                       msg->resultcode.data =
+                               P80211ENUM_resultcode_implementation_failure;
+                       goto exit;
+               }
+               /* ibss options */
+               result = hfa384x_drvr_setconfig16(hw,
+                               HFA384x_RID_CREATEIBSS,
+                               HFA384x_CREATEIBSS_JOINCREATEIBSS);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set CREATEIBSS.\n");
+                       msg->resultcode.data =
+                               P80211ENUM_resultcode_implementation_failure;
+                       goto exit;
+               }
+               result = hfa384x_drvr_enable(hw, 0);
+               if ( result ) {
+                       WLAN_LOG_ERROR("drvr_enable(0) failed. "
+                                       "result=%d\n", result);
+                       msg->resultcode.data =
+                       P80211ENUM_resultcode_implementation_failure;
+                       goto exit;
+               }
+               istmpenable = 1;
+       }
+
+        /* Figure out our timeout first Kus, then HZ */
+        timeout = msg->channellist.data.len * msg->maxchanneltime.data;
+       timeout = (timeout * HZ)/1000;
+
+        /* Issue the scan request */
+        hw->scanflag = 0;
+
+       WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq));
+
+        result = hfa384x_drvr_setconfig( hw,
+                        HFA384x_RID_HOSTSCAN, &scanreq,
+                        sizeof(hfa384x_HostScanRequest_data_t));
+        if ( result ) {
+                WLAN_LOG_ERROR("setconfig(SCANREQUEST) failed. result=%d\n",
+                                result);
+                msg->resultcode.data =
+                        P80211ENUM_resultcode_implementation_failure;
+                goto exit;
+        }
+
+        /* sleep until info frame arrives */
+        wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
+
+       msg->numbss.status = P80211ENUM_msgitem_status_data_ok;
+       if (hw->scanflag == -1)
+               hw->scanflag = 0;
+
+       msg->numbss.data = hw->scanflag;
+
+        hw->scanflag = 0;
+
+       /* Disable port if we temporarily enabled it. */
+       if (istmpenable) {
+               result = hfa384x_drvr_disable(hw, 0);
+               if ( result ) {
+                       WLAN_LOG_ERROR("drvr_disable(0) failed. "
+                                       "result=%d\n", result);
+                       msg->resultcode.data =
+                       P80211ENUM_resultcode_implementation_failure;
+                       goto exit;
+               }
+       }
+
+       /* restore original roaming mode */
+       result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE,
+                                         roamingmode);
+        if ( result ) {
+                WLAN_LOG_ERROR("setconfig(ROAMMODE) failed. result=%d\n",
+                                result);
+                msg->resultcode.data =
+                        P80211ENUM_resultcode_implementation_failure;
+                goto exit;
+        }
+
+        result = 0;
+        msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ exit:
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_scan_results
+*
+* Retrieve the BSS description for one of the BSSs identified in
+* a scan.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+        p80211msg_dot11req_scan_results_t       *req;
+       hfa384x_t               *hw = wlandev->priv;
+       hfa384x_HScanResultSub_t *item = NULL;
+
+       int count;
+
+       DBFENTER;
+
+        req = (p80211msg_dot11req_scan_results_t *) msgp;
+
+       req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+       if (hw->ap) {
+               result = 1;
+               req->resultcode.data = P80211ENUM_resultcode_not_supported;
+               goto exit;
+       }
+
+       if (! hw->scanresults) {
+               WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n");
+               result = 2;
+               req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+               goto exit;
+       }
+
+        count = (hw->scanresults->framelen - 3) / 32;
+       if (count > 32)  count = 32;
+
+       if (req->bssindex.data >= count) {
+               WLAN_LOG_DEBUG(0, "requested index (%d) out of range (%d)\n",
+                               req->bssindex.data, count);
+               result = 2;
+               req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+               goto exit;
+       }
+
+       item = &(hw->scanresults->info.hscanresult.result[req->bssindex.data]);
+       /* signal and noise */
+       req->signal.status = P80211ENUM_msgitem_status_data_ok;
+       req->noise.status = P80211ENUM_msgitem_status_data_ok;
+       req->signal.data = hfa384x2host_16(item->sl);
+       req->noise.data = hfa384x2host_16(item->anl);
+
+       /* BSSID */
+       req->bssid.status = P80211ENUM_msgitem_status_data_ok;
+       req->bssid.data.len = WLAN_BSSID_LEN;
+       memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN);
+
+       /* SSID */
+       req->ssid.status = P80211ENUM_msgitem_status_data_ok;
+       req->ssid.data.len = hfa384x2host_16(item->ssid.len);
+       memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
+
+       /* supported rates */
+        for (count = 0; count < 10 ; count++)
+                if (item->supprates[count] == 0)
+                        break;
+
+#define REQBASICRATE(N) \
+       if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \
+               req->basicrate ## N .data = item->supprates[(N)-1]; \
+               req->basicrate ## N .status = P80211ENUM_msgitem_status_data_ok; \
+       }
+
+       REQBASICRATE(1);
+       REQBASICRATE(2);
+       REQBASICRATE(3);
+       REQBASICRATE(4);
+       REQBASICRATE(5);
+       REQBASICRATE(6);
+       REQBASICRATE(7);
+       REQBASICRATE(8);
+
+#define REQSUPPRATE(N) \
+       if (count >= N) { \
+               req->supprate ## N .data = item->supprates[(N)-1]; \
+               req->supprate ## N .status = P80211ENUM_msgitem_status_data_ok; \
+       }
+
+       REQSUPPRATE(1);
+       REQSUPPRATE(2);
+       REQSUPPRATE(3);
+       REQSUPPRATE(4);
+       REQSUPPRATE(5);
+       REQSUPPRATE(6);
+       REQSUPPRATE(7);
+       REQSUPPRATE(8);
+
+       /* beacon period */
+       req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
+       req->beaconperiod.data = hfa384x2host_16(item->bcnint);
+
+       /* timestamps */
+       req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
+       req->timestamp.data = jiffies;
+       req->localtime.status = P80211ENUM_msgitem_status_data_ok;
+       req->localtime.data = jiffies;
+
+       /* atim window */
+       req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
+       req->ibssatimwindow.data = hfa384x2host_16(item->atim);
+
+       /* Channel */
+       req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
+       req->dschannel.data = hfa384x2host_16(item->chid);
+
+       /* capinfo bits */
+       count = hfa384x2host_16(item->capinfo);
+
+       /* privacy flag */
+       req->privacy.status = P80211ENUM_msgitem_status_data_ok;
+       req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count);
+
+       /* cfpollable */
+       req->cfpollable.status = P80211ENUM_msgitem_status_data_ok;
+       req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count);
+
+       /* cfpollreq */
+       req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok;
+       req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
+
+       /* bsstype */
+       req->bsstype.status =  P80211ENUM_msgitem_status_data_ok;
+       req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
+               P80211ENUM_bsstype_infrastructure :
+               P80211ENUM_bsstype_independent;
+
+       // item->proberesp_rate
+/*
+       req->fhdwelltime
+       req->fhhopset
+       req->fhhoppattern
+       req->fhhopindex
+        req->cfpdurremaining
+*/
+
+       result = 0;
+       req->resultcode.data = P80211ENUM_resultcode_success;
+
+ exit:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_join
+*
+* Join a BSS whose BSS description was previously obtained with
+* a scan.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_join(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_dot11req_join_t       *msg = msgp;
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+               /* TODO: Implement after scan */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       } else {
+
+               /*** ACCESS POINT ***/
+
+               /* Never supported by APs */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_p2_join
+*
+* Join a specific BSS
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_join_t  *msg = msgp;
+       UINT16                  reg;
+       p80211pstrd_t           *pstr;
+       UINT8                   bytebuf[256];
+       hfa384x_bytestr_t       *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
+        hfa384x_JoinRequest_data_t     joinreq;
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               wlandev->macmode = WLAN_MACMODE_NONE;
+
+               /*** STATION ***/
+               /* Set the PortType */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+
+               /* ess port */
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set Port Type\n");
+                       goto failed;
+               }
+
+               /* Set the auth type */
+               if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
+                       reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
+               } else {
+                       reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
+               }
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set Authentication\n");
+                       goto failed;
+               }
+
+               /* Turn off all roaming */
+               hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, 3);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to Turn off Roaming\n");
+                       goto failed;
+               }
+
+               /* Basic rates */
+                reg = 0;
+               if ( msg->basicrate1.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg = p80211rate_to_p2bit(msg->basicrate1.data);
+               }
+               if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->basicrate2.data);
+               }
+               if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->basicrate3.data);
+               }
+               if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->basicrate4.data);
+               }
+               if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->basicrate5.data);
+               }
+               if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->basicrate6.data);
+               }
+               if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->basicrate7.data);
+               }
+               if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->basicrate8.data);
+               }
+               if( reg == 0)
+                        reg = 0x03;
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, reg);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", reg);
+                       goto failed;
+               }
+
+               /* Operational rates (supprates and txratecontrol) */
+               reg = 0;
+               if ( msg->operationalrate1.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg = p80211rate_to_p2bit(msg->operationalrate1.data);
+               }
+               if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->operationalrate2.data);
+               }
+               if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->operationalrate3.data);
+               }
+               if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->operationalrate4.data);
+               }
+               if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->operationalrate5.data);
+               }
+               if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->operationalrate6.data);
+               }
+               if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->operationalrate7.data);
+               }
+               if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+                       reg |= p80211rate_to_p2bit(msg->operationalrate8.data);
+               }
+               if( reg == 0)
+                        reg = 0x0f;
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, reg);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set supprates=%d.\n", reg);
+                       goto failed;
+               }
+
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set txrates=%d.\n", reg);
+                       goto failed;
+               }
+
+               /* Set the ssid */
+               memset(bytebuf, 0, 256);
+               pstr = (p80211pstrd_t*)&(msg->ssid.data);
+               prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+               result = hfa384x_drvr_setconfig(
+                       hw, HFA384x_RID_CNFDESIREDSSID,
+                       bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set SSID\n");
+                       goto failed;
+               }
+
+               /* Enable the Port */
+               result = hfa384x_cmd_enable(hw, 0);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+                       goto failed;
+               }
+
+               /* Fill in the join request */
+               joinreq.channel = msg->channel.data;
+               memcpy( joinreq.bssid, ((unsigned char *) &msg->bssid.data) + 1, WLAN_BSSID_LEN);
+               hw->joinreq = joinreq;
+               hw->join_ap = 1;
+
+               /* Send the join request */
+               result = hfa384x_drvr_setconfig( hw,
+                       HFA384x_RID_JOINREQUEST,
+                       &joinreq, HFA384x_RID_JOINREQUEST_LEN);
+                if(result != 0) {
+                       WLAN_LOG_ERROR("Join request failed, result=%d.\n", result);
+                       goto failed;
+               }
+
+       } else {
+
+               /*** ACCESS POINT ***/
+
+               /* Never supported by APs */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       }
+
+        goto done;
+failed:
+       WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
+       msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+
+done:
+        result = 0;
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_authenticate
+*
+* Station should be begin an authentication exchange.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_dot11req_authenticate_t       *msg = msgp;
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+               /* TODO: Decide how we're going to handle this one w/ Prism2 */
+               /*       It could be entertaining since Prism2 doesn't have  */
+               /*       an explicit way to control this */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       } else {
+
+               /*** ACCESS POINT ***/
+
+               /* Never supported by APs */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_deauthenticate
+*
+* Send a deauthenticate notification.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_dot11req_deauthenticate_t     *msg = msgp;
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+               /* TODO: Decide how we're going to handle this one w/ Prism2 */
+               /*       It could be entertaining since Prism2 doesn't have  */
+               /*       an explicit way to control this */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       } else {
+
+               /*** ACCESS POINT ***/
+               hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data);
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_associate
+*
+* Associate with an ESS.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       int                     result = 0;
+       p80211msg_dot11req_associate_t  *msg = msgp;
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+#if 0
+               /* Set the TxRates */
+               reg = 0x000f;
+               hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg);
+#endif
+
+               /* Set the PortType */
+               /* ess port */
+               hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1);
+
+               /* Enable the Port */
+               hfa384x_drvr_enable(hw, 0);
+
+               /* Set the resultcode */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+
+       } else {
+
+               /*** ACCESS POINT ***/
+
+               /* Never supported on AP */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_reassociate
+*
+* Renew association because of a BSS change.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_dot11req_reassociate_t        *msg = msgp;
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+               /* TODO: Not supported yet...not sure how we're going to do it */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       } else {
+
+               /*** ACCESS POINT ***/
+
+               /* Never supported on AP */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_disassociate
+*
+* Send a disassociation notification.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_dot11req_disassociate_t       *msg = msgp;
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+               /* TODO: Not supported yet...not sure how to do it */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       } else {
+
+               /*** ACCESS POINT ***/
+               hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data);
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_reset
+*
+* Reset the MAC and MSD.  The p80211 layer has it's own handling
+* that should be done before and after this function.
+* Procedure:
+*   - disable system interrupts ??
+*   - disable MAC interrupts
+*   - restore system interrupts
+*   - issue the MAC initialize command
+*   - clear any MSD level state (including timers, queued events,
+*     etc.).  Note that if we're removing timer'd/queue events, we may
+*     need to have remained in the system interrupt disabled state.
+*     We should be left in the same state that we're in following
+*     driver initialization.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer, MAY BE NULL! for a driver local
+*                      call.
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread, commonly wlanctl, but might be rmmod/pci_close.
+----------------------------------------------------------------*/
+int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_dot11req_reset_t      *msg = msgp;
+       DBFENTER;
+
+       /*
+        * This is supported on both AP and STA and it's not allowed
+        * to fail.
+        */
+       if ( msgp ) {
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+               WLAN_LOG_INFO("dot11req_reset: the macaddress and "
+                       "setdefaultmib arguments are currently unsupported.\n");
+       }
+
+       /*
+        * If we got this far, the MSD must be in the MSDRUNNING state
+        * therefore, we must stop and then restart the hw/MAC combo.
+        */
+       hfa384x_drvr_stop(hw);
+       result = hfa384x_drvr_start(hw);
+       if (result != 0) {
+               WLAN_LOG_ERROR("dot11req_reset: Initialize command failed,"
+                               " bad things will happen from here.\n");
+               return 0;
+       }
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_start
+*
+* Start a BSS.  Any station can do this for IBSS, only AP for ESS.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_dot11req_start_t      *msg = msgp;
+
+       p80211pstrd_t           *pstr;
+       UINT8                   bytebuf[80];
+       hfa384x_bytestr_t       *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
+       hfa384x_PCFInfo_data_t  *pcfinfo = (hfa384x_PCFInfo_data_t*)bytebuf;
+       UINT16                  word;
+       DBFENTER;
+
+       wlandev->macmode = WLAN_MACMODE_NONE;
+
+       /* Set the SSID */
+       memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
+
+       if (!hw->ap) {
+               /*** ADHOC IBSS ***/
+               /* see if current f/w is less than 8c3 */
+               if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+                                            hw->ident_sta_fw.minor,
+                                            hw->ident_sta_fw.variant) <
+                   HFA384x_FIRMWARE_VERSION(0,8,3)) {
+                       /* Ad-Hoc not quite supported on Prism2 */
+                       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+                       msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+                       goto done;
+               }
+
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+               /*** STATION ***/
+               /* Set the REQUIRED config items */
+               /* SSID */
+               pstr = (p80211pstrd_t*)&(msg->ssid.data);
+               prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+               result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
+                               bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set CnfOwnSSID\n");
+                       goto failed;
+               }
+               result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
+                               bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set CnfDesiredSSID\n");
+                       goto failed;
+               }
+
+               /* bsstype - we use the default in the ap firmware */
+               /* IBSS port */
+               hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0);
+
+               /* beacon period */
+               word = msg->beaconperiod.data;
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word);
+                       goto failed;
+               }
+
+               /* dschannel */
+               word = msg->dschannel.data;
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set channel=%d.\n", word);
+                       goto failed;
+               }
+               /* Basic rates */
+               word = p80211rate_to_p2bit(msg->basicrate1.data);
+               if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->basicrate2.data);
+               }
+               if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->basicrate3.data);
+               }
+               if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->basicrate4.data);
+               }
+               if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->basicrate5.data);
+               }
+               if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->basicrate6.data);
+               }
+               if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->basicrate7.data);
+               }
+               if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->basicrate8.data);
+               }
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word);
+                       goto failed;
+               }
+
+               /* Operational rates (supprates and txratecontrol) */
+               word = p80211rate_to_p2bit(msg->operationalrate1.data);
+               if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->operationalrate2.data);
+               }
+               if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->operationalrate3.data);
+               }
+               if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->operationalrate4.data);
+               }
+               if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->operationalrate5.data);
+               }
+               if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->operationalrate6.data);
+               }
+               if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->operationalrate7.data);
+               }
+               if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+                       word |= p80211rate_to_p2bit(msg->operationalrate8.data);
+               }
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word);
+                       goto failed;
+               }
+
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word);
+                       goto failed;
+               }
+
+               /* Set the macmode so the frame setup code knows what to do */
+               if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) {
+                       wlandev->macmode = WLAN_MACMODE_IBSS_STA;
+                       /* lets extend the data length a bit */
+                       hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
+               }
+
+               /* Enable the Port */
+               result = hfa384x_drvr_enable(hw, 0);
+               if ( result ) {
+                       WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+                       goto failed;
+               }
+
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+
+               goto done;
+       }
+
+       /*** ACCESS POINT ***/
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+       /* Validate the command, if BSStype=infra is the tertiary loaded? */
+       if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) {
+               WLAN_LOG_ERROR("AP driver cannot create IBSS.\n");
+               goto failed;
+       } else if ( hw->cap_sup_sta.id != 5) {
+               WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n");
+               goto failed;
+       }
+
+       /* Set the REQUIRED config items */
+       /* SSID */
+       pstr = (p80211pstrd_t*)&(msg->ssid.data);
+       prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+       result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
+                               bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to set SSID, result=0x%04x\n", result);
+               goto failed;
+       }
+
+       /* bsstype - we use the default in the ap firmware */
+
+       /* beacon period */
+       word = msg->beaconperiod.data;
+       result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word);
+               goto failed;
+       }
+
+       /* dschannel */
+       word = msg->dschannel.data;
+       result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to set channel=%d.\n", word);
+               goto failed;
+       }
+       /* Basic rates */
+       word = p80211rate_to_p2bit(msg->basicrate1.data);
+       if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->basicrate2.data);
+       }
+       if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->basicrate3.data);
+       }
+       if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->basicrate4.data);
+       }
+       if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->basicrate5.data);
+       }
+       if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->basicrate6.data);
+       }
+       if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->basicrate7.data);
+       }
+       if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->basicrate8.data);
+       }
+       result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word);
+               goto failed;
+       }
+
+       /* Operational rates (supprates and txratecontrol) */
+       word = p80211rate_to_p2bit(msg->operationalrate1.data);
+       if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->operationalrate2.data);
+       }
+       if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->operationalrate3.data);
+       }
+       if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->operationalrate4.data);
+       }
+       if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->operationalrate5.data);
+       }
+       if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->operationalrate6.data);
+       }
+       if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->operationalrate7.data);
+       }
+       if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+               word |= p80211rate_to_p2bit(msg->operationalrate8.data);
+       }
+       result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word);
+               goto failed;
+       }
+       result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL0, word);
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word);
+               goto failed;
+       }
+
+       /* ibssatimwindow */
+       if (msg->ibssatimwindow.status == P80211ENUM_msgitem_status_data_ok) {
+               WLAN_LOG_INFO("prism2mgmt_start: atimwindow not used in "
+                              "Infrastructure mode, ignored.\n");
+       }
+
+       /* DTIM period */
+       word = msg->dtimperiod.data;
+       result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNDTIMPER, word);
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to set dtim period=%d.\n", word);
+               goto failed;
+       }
+
+       /* probedelay */
+       if (msg->probedelay.status == P80211ENUM_msgitem_status_data_ok) {
+               WLAN_LOG_INFO("prism2mgmt_start: probedelay not "
+                              "supported in prism2, ignored.\n");
+       }
+
+       /* cfpollable, cfpollreq, cfpperiod, cfpmaxduration */
+       if (msg->cfpollable.data == P80211ENUM_truth_true &&
+           msg->cfpollreq.data == P80211ENUM_truth_true ) {
+               WLAN_LOG_ERROR("cfpollable=cfpollreq=true is illegal.\n");
+               result = -1;
+               goto failed;
+       }
+
+       /* read the PCFInfo and update */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFAPPCFINFO,
+                                       pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN);
+       if ( result ) {
+               WLAN_LOG_INFO("prism2mgmt_start: read(pcfinfo) failed, "
+                               "assume it's "
+                               "not supported, pcf settings ignored.\n");
+               goto pcf_skip;
+       }
+       if ((msg->cfpollable.data == P80211ENUM_truth_false &&
+            msg->cfpollreq.data == P80211ENUM_truth_false) ) {
+               pcfinfo->MediumOccupancyLimit = 0;
+               pcfinfo->CFPPeriod = 0;
+               pcfinfo->CFPMaxDuration = 0;
+               pcfinfo->CFPFlags &= host2hfa384x_16((UINT16)~BIT0);
+
+               if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok ||
+                    msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok ) {
+                       WLAN_LOG_WARNING(
+                               "Setting cfpperiod or cfpmaxduration when "
+                               "cfpollable and cfreq are false is pointless.\n");
+               }
+       }
+       if ((msg->cfpollable.data == P80211ENUM_truth_true ||
+            msg->cfpollreq.data == P80211ENUM_truth_true) ) {
+               if ( msg->cfpollable.data == P80211ENUM_truth_true) {
+                       pcfinfo->CFPFlags |= host2hfa384x_16((UINT16)BIT0);
+               }
+
+               if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok) {
+                       pcfinfo->CFPPeriod = msg->cfpperiod.data;
+                       pcfinfo->CFPPeriod = host2hfa384x_16(pcfinfo->CFPPeriod);
+               }
+
+               if ( msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok) {
+                       pcfinfo->CFPMaxDuration = msg->cfpmaxduration.data;
+                       pcfinfo->CFPMaxDuration = host2hfa384x_16(pcfinfo->CFPMaxDuration);
+                       pcfinfo->MediumOccupancyLimit = pcfinfo->CFPMaxDuration;
+               }
+       }
+       result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFAPPCFINFO,
+                                       pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN);
+       if ( result ) {
+               WLAN_LOG_ERROR("write(pcfinfo) failed.\n");
+               goto failed;
+       }
+
+pcf_skip:
+       /* Set the macmode so the frame setup code knows what to do */
+       if ( msg->bsstype.data == P80211ENUM_bsstype_infrastructure ) {
+               wlandev->macmode = WLAN_MACMODE_ESS_AP;
+               /* lets extend the data length a bit */
+               hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
+       }
+
+       /* Set the BSSID to the same as our MAC */
+       memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN);
+
+       /* Enable the Port */
+       result = hfa384x_drvr_enable(hw, 0);
+       if ( result ) {
+               WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+               goto failed;
+       }
+
+       msg->resultcode.data = P80211ENUM_resultcode_success;
+
+       goto done;
+failed:
+       WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
+       msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+
+done:
+       result = 0;
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_enable
+*
+* Start a BSS.  Any station can do this for IBSS, only AP for ESS.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_enable_t        *msg = msgp;
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+               /* Ad-Hoc not quite supported on Prism2 */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+               goto done;
+       }
+
+       /*** ACCESS POINT ***/
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+       /* Is the tertiary loaded? */
+       if ( hw->cap_sup_sta.id != 5) {
+               WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n");
+               goto failed;
+       }
+
+       /* Set the macmode so the frame setup code knows what to do */
+       wlandev->macmode = WLAN_MACMODE_ESS_AP;
+
+       /* Set the BSSID to the same as our MAC */
+       memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN);
+
+       /* Enable the Port */
+       result = hfa384x_drvr_enable(hw, 0);
+       if ( result ) {
+               WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+               goto failed;
+       }
+
+       msg->resultcode.data = P80211ENUM_resultcode_success;
+
+       goto done;
+failed:
+       msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+
+done:
+       result = 0;
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_readpda
+*
+* Collect the PDA data and put it in the message.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_readpda_t       *msg = msgp;
+       int                             result;
+       DBFENTER;
+
+       /* We only support collecting the PDA when in the FWLOAD
+        * state.
+        */
+       if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+               WLAN_LOG_ERROR(
+                       "PDA may only be read "
+                       "in the fwload state.\n");
+               msg->resultcode.data =
+                       P80211ENUM_resultcode_implementation_failure;
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       } else {
+               /*  Call drvr_readpda(), it handles the auxport enable
+                *  and validating the returned PDA.
+                */
+               result = hfa384x_drvr_readpda(
+                       hw,
+                       msg->pda.data,
+                       HFA384x_PDA_LEN_MAX);
+               if (result) {
+                       WLAN_LOG_ERROR(
+                               "hfa384x_drvr_readpda() failed, "
+                               "result=%d\n",
+                               result);
+
+                       msg->resultcode.data =
+                               P80211ENUM_resultcode_implementation_failure;
+                       msg->resultcode.status =
+                               P80211ENUM_msgitem_status_data_ok;
+                       DBFEXIT;
+                       return 0;
+               }
+               msg->pda.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       }
+
+       DBFEXIT;
+       return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_readcis
+*
+* Collect the CIS data and put it in the message.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_readcis_t       *msg = msgp;
+
+       DBFENTER;
+
+        memset(msg->cis.data, 0, sizeof(msg->cis.data));
+
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CIS,
+                                       msg->cis.data, HFA384x_RID_CIS_LEN);
+       if ( result ) {
+               WLAN_LOG_INFO("prism2mgmt_readcis: read(cis) failed.\n");
+               msg->cis.status = P80211ENUM_msgitem_status_no_value;
+               msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+
+               }
+       else {
+               msg->cis.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+               }
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+       DBFEXIT;
+       return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_auxport_state
+*
+* Enables/Disables the card's auxiliary port.  Should be called
+* before and after a sequence of auxport_read()/auxport_write()
+* calls.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp)
+{
+       p80211msg_p2req_auxport_state_t *msg = msgp;
+
+#if (WLAN_HOSTIF != WLAN_USB)
+       hfa384x_t               *hw = wlandev->priv;
+       DBFENTER;
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       if (msg->enable.data == P80211ENUM_truth_true) {
+               if ( hfa384x_cmd_aux_enable(hw, 0) ) {
+                       msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+               } else {
+                       msg->resultcode.data = P80211ENUM_resultcode_success;
+               }
+       } else {
+               hfa384x_cmd_aux_disable(hw);
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+       }
+
+#else /* !USB */
+       DBFENTER;
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+
+#endif /* WLAN_HOSTIF != WLAN_USB */
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_auxport_read
+*
+* Copies data from the card using the auxport.  The auxport must
+* have previously been enabled.  Note: this is not the way to
+* do downloads, see the [ram|flash]dl functions.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp)
+{
+#if (WLAN_HOSTIF != WLAN_USB)
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_auxport_read_t  *msg = msgp;
+       UINT32                  addr;
+       UINT32                  len;
+       UINT8*                  buf;
+       UINT32                  maxlen = sizeof(msg->data.data);
+       DBFENTER;
+
+       if ( hw->auxen ) {
+               addr = msg->addr.data;
+               len = msg->len.data;
+               buf = msg->data.data;
+               if ( len <= maxlen ) {  /* max read/write size */
+                       hfa384x_copy_from_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len);
+                       msg->resultcode.data = P80211ENUM_resultcode_success;
+               } else {
+                       WLAN_LOG_DEBUG(1,"Attempt to read > maxlen from auxport.\n");
+                       msg->resultcode.data = P80211ENUM_resultcode_refused;
+               }
+
+       } else {
+               msg->resultcode.data = P80211ENUM_resultcode_refused;
+       }
+       msg->data.status = P80211ENUM_msgitem_status_data_ok;
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+       DBFEXIT;
+       return 0;
+#else
+       DBFENTER;
+
+       WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n");
+
+       DBFEXIT;
+       return 0;
+#endif
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_auxport_write
+*
+* Copies data to the card using the auxport.  The auxport must
+* have previously been enabled.  Note: this is not the way to
+* do downloads, see the [ram|flash]dl functions.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp)
+{
+#if (WLAN_HOSTIF != WLAN_USB)
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_auxport_write_t *msg = msgp;
+       UINT32                  addr;
+       UINT32                  len;
+       UINT8*                  buf;
+       UINT32                  maxlen = sizeof(msg->data.data);
+       DBFENTER;
+
+       if ( hw->auxen ) {
+               addr = msg->addr.data;
+               len = msg->len.data;
+               buf = msg->data.data;
+               if ( len <= maxlen ) {  /* max read/write size */
+                       hfa384x_copy_to_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len);
+               } else {
+                       WLAN_LOG_DEBUG(1,"Attempt to write > maxlen from auxport.\n");
+                       msg->resultcode.data = P80211ENUM_resultcode_refused;
+               }
+
+       } else {
+               msg->resultcode.data = P80211ENUM_resultcode_refused;
+       }
+       msg->data.status = P80211ENUM_msgitem_status_data_ok;
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+       DBFEXIT;
+       return 0;
+#else
+       DBFENTER;
+       WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n");
+       DBFEXIT;
+       return 0;
+#endif
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_low_level
+*
+* Puts the card into the desired test mode.
+*
+* Arguments:
+*       wlandev         wlan device structure
+*       msgp            ptr to msg buffer
+*
+* Returns:
+*       0       success and done
+*       <0      success, but we're waiting for something to finish.
+*       >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*       process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+        p80211msg_p2req_low_level_t     *msg = msgp;
+       hfa384x_metacmd_t cmd;
+        DBFENTER;
+
+        msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+        /* call some routine to execute the test command */
+       cmd.cmd = (UINT16) msg->command.data;
+       cmd.parm0 = (UINT16) msg->param0.data;
+       cmd.parm1 = (UINT16) msg->param1.data;
+       cmd.parm2 = (UINT16) msg->param2.data;
+
+        hfa384x_drvr_low_level(hw,&cmd);
+
+        msg->resp0.data = (UINT32) cmd.result.resp0;
+        msg->resp1.data = (UINT32) cmd.result.resp1;
+        msg->resp2.data = (UINT32) cmd.result.resp2;
+
+        msg->resultcode.data = P80211ENUM_resultcode_success;
+
+        DBFEXIT;
+        return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_test_command
+*
+* Puts the card into the desired test mode.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_test_command_t  *msg = msgp;
+       hfa384x_metacmd_t cmd;
+
+        DBFENTER;
+
+       cmd.cmd = ((UINT16) msg->testcode.data) << 8 | 0x38;
+       cmd.parm0 = (UINT16) msg->testparam.data;
+       cmd.parm1 = 0;
+       cmd.parm2 = 0;
+
+        /* call some routine to execute the test command */
+
+        hfa384x_drvr_low_level(hw,&cmd);
+
+        msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+        msg->resultcode.data = P80211ENUM_resultcode_success;
+
+        msg->status.status = P80211ENUM_msgitem_status_data_ok;
+        msg->status.data = cmd.result.status;
+        msg->resp0.status = P80211ENUM_msgitem_status_data_ok;
+        msg->resp0.data = cmd.result.resp0;
+        msg->resp1.status = P80211ENUM_msgitem_status_data_ok;
+        msg->resp1.data = cmd.result.resp1;
+        msg->resp2.status = P80211ENUM_msgitem_status_data_ok;
+        msg->resp2.data = cmd.result.resp2;
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_mmi_read
+*
+* Read from one of the MMI registers.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_mmi_read_t      *msg = msgp;
+       UINT32 resp = 0;
+
+       DBFENTER;
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+       /* call some routine to execute the test command */
+
+       hfa384x_drvr_mmi_read(hw, msg->addr.data, &resp);
+
+       /* I'm not sure if this is "architecturally" correct, but it
+           is expedient. */
+
+       msg->value.status = P80211ENUM_msgitem_status_data_ok;
+       msg->value.data = resp;
+       msg->resultcode.data = P80211ENUM_resultcode_success;
+
+       DBFEXIT;
+       return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_mmi_write
+*
+* Write a data value to one of the MMI registers.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_mmi_write_t     *msg = msgp;
+       DBFENTER;
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+       /* call some routine to execute the test command */
+
+       hfa384x_drvr_mmi_write(hw, msg->addr.data, msg->data.data);
+
+       msg->resultcode.data = P80211ENUM_resultcode_success;
+
+       DBFEXIT;
+       return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_ramdl_state
+*
+* Establishes the beginning/end of a card RAM download session.
+*
+* It is expected that the ramdl_write() function will be called
+* one or more times between the 'enable' and 'disable' calls to
+* this function.
+*
+* Note: This function should not be called when a mac comm port
+*       is active.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_ramdl_state_t   *msg = msgp;
+       DBFENTER;
+
+       if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+               WLAN_LOG_ERROR(
+                       "ramdl_state(): may only be called "
+                       "in the fwload state.\n");
+               msg->resultcode.data =
+                       P80211ENUM_resultcode_implementation_failure;
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               DBFEXIT;
+               return 0;
+       }
+
+       /*
+       ** Note: Interrupts are locked out if this is an AP and are NOT
+       ** locked out if this is a station.
+       */
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       if  ( msg->enable.data == P80211ENUM_truth_true ) {
+               if ( hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data) ) {
+                       msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+               } else {
+                       msg->resultcode.data = P80211ENUM_resultcode_success;
+               }
+       } else {
+               hfa384x_drvr_ramdl_disable(hw);
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+       }
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_ramdl_write
+*
+* Writes a buffer to the card RAM using the download state.  This
+* is for writing code to card RAM.  To just read or write raw data
+* use the aux functions.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_ramdl_write_t   *msg = msgp;
+       UINT32                  addr;
+       UINT32                  len;
+       UINT8                   *buf;
+       DBFENTER;
+
+       if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+               WLAN_LOG_ERROR(
+                       "ramdl_write(): may only be called "
+                       "in the fwload state.\n");
+               msg->resultcode.data =
+                       P80211ENUM_resultcode_implementation_failure;
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               DBFEXIT;
+               return 0;
+       }
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       /* first validate the length */
+       if  ( msg->len.data > sizeof(msg->data.data) ) {
+               msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters;
+               return 0;
+       }
+       /* call the hfa384x function to do the write */
+       addr = msg->addr.data;
+       len = msg->len.data;
+       buf = msg->data.data;
+       if ( hfa384x_drvr_ramdl_write(hw, addr, buf, len) ) {
+               msg->resultcode.data = P80211ENUM_resultcode_refused;
+
+       }
+       msg->resultcode.data = P80211ENUM_resultcode_success;
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_flashdl_state
+*
+* Establishes the beginning/end of a card Flash download session.
+*
+* It is expected that the flashdl_write() function will be called
+* one or more times between the 'enable' and 'disable' calls to
+* this function.
+*
+* Note: This function should not be called when a mac comm port
+*       is active.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_flashdl_state_t *msg = msgp;
+       DBFENTER;
+
+       if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+               WLAN_LOG_ERROR(
+                       "flashdl_state(): may only be called "
+                       "in the fwload state.\n");
+               msg->resultcode.data =
+                       P80211ENUM_resultcode_implementation_failure;
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               DBFEXIT;
+               return 0;
+       }
+
+       /*
+       ** Note: Interrupts are locked out if this is an AP and are NOT
+       ** locked out if this is a station.
+       */
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       if  ( msg->enable.data == P80211ENUM_truth_true ) {
+               if ( hfa384x_drvr_flashdl_enable(hw) ) {
+                       msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+               } else {
+                       msg->resultcode.data = P80211ENUM_resultcode_success;
+               }
+       } else {
+               hfa384x_drvr_flashdl_disable(hw);
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+               /* NOTE: At this point, the MAC is in the post-reset
+                * state and the driver is in the fwload state.
+                * We need to get the MAC back into the fwload
+                * state.  To do this, we set the nsdstate to HWPRESENT
+                * and then call the ifstate function to redo everything
+                * that got us into the fwload state.
+                */
+               wlandev->msdstate = WLAN_MSD_HWPRESENT;
+               result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload);
+               if (result != P80211ENUM_resultcode_success) {
+                       WLAN_LOG_ERROR("prism2sta_ifstate(fwload) failed,"
+                               "P80211ENUM_resultcode=%d\n", result);
+                       msg->resultcode.data =
+                               P80211ENUM_resultcode_implementation_failure;
+                       result = -1;
+               }
+       }
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_flashdl_write
+*
+*
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       p80211msg_p2req_flashdl_write_t *msg = msgp;
+       UINT32                  addr;
+       UINT32                  len;
+       UINT8                   *buf;
+       DBFENTER;
+
+       if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+               WLAN_LOG_ERROR(
+                       "flashdl_write(): may only be called "
+                       "in the fwload state.\n");
+               msg->resultcode.data =
+                       P80211ENUM_resultcode_implementation_failure;
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               DBFEXIT;
+               return 0;
+       }
+
+       /*
+       ** Note: Interrupts are locked out if this is an AP and are NOT
+       ** locked out if this is a station.
+       */
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       /* first validate the length */
+       if  ( msg->len.data > sizeof(msg->data.data) ) {
+               msg->resultcode.status =
+                       P80211ENUM_resultcode_invalid_parameters;
+               return 0;
+       }
+       /* call the hfa384x function to do the write */
+       addr = msg->addr.data;
+       len = msg->len.data;
+       buf = msg->data.data;
+       if ( hfa384x_drvr_flashdl_write(hw, addr, buf, len) ) {
+               msg->resultcode.data = P80211ENUM_resultcode_refused;
+
+       }
+       msg->resultcode.data = P80211ENUM_resultcode_success;
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_dump_state
+*
+* Dumps the driver's and hardware's current state via the kernel
+* log at KERN_NOTICE level.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp)
+{
+       p80211msg_p2req_dump_state_t    *msg = msgp;
+       int                             result = 0;
+
+#if (WLAN_HOSTIF != WLAN_USB)
+       hfa384x_t               *hw = wlandev->priv;
+       UINT16                          auxbuf[15];
+       DBFENTER;
+
+       WLAN_LOG_NOTICE("prism2 driver and hardware state:\n");
+       if  ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {
+               WLAN_LOG_ERROR("aux_enable failed, result=%d\n", result);
+               goto failed;
+       }
+       hfa384x_copy_from_aux(hw,
+               0x01e2,
+               HFA384x_AUX_CTL_EXTDS,
+               auxbuf,
+               sizeof(auxbuf));
+       hfa384x_cmd_aux_disable(hw);
+       WLAN_LOG_NOTICE("  cmac: FreeBlocks=%d\n", auxbuf[5]);
+       WLAN_LOG_NOTICE("  cmac: IntEn=0x%02x EvStat=0x%02x\n",
+               hfa384x_getreg(hw, HFA384x_INTEN),
+               hfa384x_getreg(hw, HFA384x_EVSTAT));
+
+       #ifdef USE_FID_STACK
+       WLAN_LOG_NOTICE("  drvr: txfid_top=%d stacksize=%d\n",
+               hw->txfid_top,HFA384x_DRVR_FIDSTACKLEN_MAX);
+       #else
+       WLAN_LOG_NOTICE("  drvr: txfid_head=%d txfid_tail=%d txfid_N=%d\n",
+               hw->txfid_head, hw->txfid_tail, hw->txfid_N);
+       #endif
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       msg->resultcode.data = P80211ENUM_resultcode_success;
+
+#else /* (WLAN_HOSTIF == WLAN_USB) */
+
+       DBFENTER;
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+       goto failed;
+
+#endif /* (WLAN_HOSTIF != WLAN_USB) */
+
+failed:
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_channel_info
+*
+* Issues a ChannelInfoRequest.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp)
+{
+       p80211msg_p2req_channel_info_t  *msg=msgp;
+       hfa384x_t                       *hw = wlandev->priv;
+       int                             result, i, n=0;
+       UINT16                          channel_mask=0;
+       hfa384x_ChannelInfoRequest_data_t       chinforeq;
+       // unsigned long                        now;
+
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+               /* Not supported in STA f/w */
+               P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported);
+               goto done;
+       }
+
+       /*** ACCESS POINT ***/
+
+#define CHINFO_TIMEOUT 2
+
+       P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success);
+
+       /* setting default value for channellist = all channels */
+       if (!msg->channellist.data) {
+               P80211_SET_INT(msg->channellist, 0x00007FFE);
+       }
+       /* setting default value for channeldwelltime = 100 ms */
+       if (!msg->channeldwelltime.data) {
+               P80211_SET_INT(msg->channeldwelltime, 100);
+       }
+       channel_mask = (UINT16) (msg->channellist.data >> 1);
+       for (i=0, n=0; i < 14; i++) {
+               if (channel_mask & (1<<i)) {
+                       n++;
+               }
+       }
+       P80211_SET_INT(msg->numchinfo, n);
+       chinforeq.channelList = host2hfa384x_16(channel_mask);
+       chinforeq.channelDwellTime = host2hfa384x_16(msg->channeldwelltime.data);
+
+       atomic_set(&hw->channel_info.done, 1);
+
+       result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CHANNELINFOREQUEST,
+                                        &chinforeq, HFA384x_RID_CHANNELINFOREQUEST_LEN);
+       if ( result ) {
+               WLAN_LOG_ERROR("setconfig(CHANNELINFOREQUEST) failed. result=%d\n",
+                               result);
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+               goto done;
+       }
+       /*
+       now = jiffies;
+       while (atomic_read(&hw->channel_info.done) != 1) {
+               if ((jiffies - now) > CHINFO_TIMEOUT*HZ) {
+                       WLAN_LOG_NOTICE("ChannelInfo results not received in %d seconds, aborting.\n",
+                                       CHINFO_TIMEOUT);
+                       msg->resultcode.data = P80211ENUM_resultcode_timeout;
+                       goto done;
+               }
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(HZ/4);
+               current->state = TASK_RUNNING;
+       }
+       */
+
+done:
+
+       DBFEXIT;
+       return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_channel_info_results
+*
+* Returns required ChannelInfo result.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t                       *hw = wlandev->priv;
+
+       p80211msg_p2req_channel_info_results_t  *msg=msgp;
+       int                             result=0;
+       int             channel;
+
+       DBFENTER;
+
+       if (!hw->ap) {
+
+               /*** STATION ***/
+
+               /* Not supported in STA f/w */
+               P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported);
+               goto done;
+       }
+
+       /*** ACCESS POINT ***/
+
+       switch (atomic_read(&hw->channel_info.done)) {
+       case 0: msg->resultcode.status = P80211ENUM_msgitem_status_no_value;
+               goto done;
+       case 1: msg->resultcode.status = P80211ENUM_msgitem_status_incomplete_itemdata;
+               goto done;
+       }
+
+       P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success);
+       channel=msg->channel.data-1;
+
+       if (channel < 0 || ! (hw->channel_info.results.scanchannels & 1<<channel) ) {
+               msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+               goto done;
+       }
+       WLAN_LOG_DEBUG(2, "chinfo_results: channel %d, avg/peak level=%d/%d dB, active=%d\n",
+                       channel+1,
+                       hw->channel_info.results.result[channel].anl,
+                       hw->channel_info.results.result[channel].pnl,
+                       hw->channel_info.results.result[channel].active
+               );
+       P80211_SET_INT(msg->avgnoiselevel, hw->channel_info.results.result[channel].anl);
+       P80211_SET_INT(msg->peaknoiselevel, hw->channel_info.results.result[channel].pnl);
+       P80211_SET_INT(msg->bssactive, hw->channel_info.results.result[channel].active &
+               HFA384x_CHINFORESULT_BSSACTIVE
+                ? P80211ENUM_truth_true
+                : P80211ENUM_truth_false) ;
+       P80211_SET_INT(msg->pcfactive, hw->channel_info.results.result[channel].active &
+               HFA384x_CHINFORESULT_PCFACTIVE
+                ? P80211ENUM_truth_true
+                : P80211ENUM_truth_false) ;
+
+done:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_autojoin
+*
+* Associate with an ESS.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t                       *hw = wlandev->priv;
+       int                     result = 0;
+       UINT16                  reg;
+       UINT16                  port_type;
+       p80211msg_lnxreq_autojoin_t     *msg = msgp;
+       p80211pstrd_t           *pstr;
+       UINT8                   bytebuf[256];
+       hfa384x_bytestr_t       *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
+       DBFENTER;
+
+       wlandev->macmode = WLAN_MACMODE_NONE;
+
+       /* Set the SSID */
+       memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
+
+       if (hw->ap) {
+
+               /*** ACCESS POINT ***/
+
+               /* Never supported on AP */
+               msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+               goto done;
+       }
+
+       /* Disable the Port */
+       hfa384x_drvr_disable(hw, 0);
+
+       /*** STATION ***/
+       /* Set the TxRates */
+       hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f);
+
+       /* Set the auth type */
+       if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
+               reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
+       } else {
+               reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
+       }
+       hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
+
+       /* Set the ssid */
+       memset(bytebuf, 0, 256);
+       pstr = (p80211pstrd_t*)&(msg->ssid.data);
+       prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+        result = hfa384x_drvr_setconfig(
+                       hw, HFA384x_RID_CNFDESIREDSSID,
+                       bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
+#if 0
+       /* we can use the new-fangled auto-unknown mode if the firmware
+          is 1.3.3 or newer */
+       if (HFA384x_FIRMARE_VERSION(hw->ident_sta_fw.major,
+                                   hw->ident_sta_fw.minor,
+                                   hw->ident_sta_fw.variant) >=
+           HFA384x_FIRMWARE_VERSION(1,3,3)) {
+               /* Set up the IBSS options */
+               reg =  HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS;
+               hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, reg);
+
+               /* Set the PortType */
+               port_type = HFA384x_PORTTYPE_IBSS;
+       } else {
+               port_type = HFA384x_PORTTYPE_BSS;
+       }
+#else
+       port_type = HFA384x_PORTTYPE_BSS;
+#endif
+       /* Set the PortType */
+       hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type);
+
+       /* Enable the Port */
+       hfa384x_drvr_enable(hw, 0);
+
+       /* Set the resultcode */
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       msg->resultcode.data = P80211ENUM_resultcode_success;
+
+done:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_wlansniff
+*
+* Start or stop sniffing.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
+{
+       int                     result = 0;
+       p80211msg_lnxreq_wlansniff_t    *msg = msgp;
+
+       hfa384x_t                       *hw = wlandev->priv;
+       UINT16                  word;
+
+       DBFENTER;
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       switch (msg->enable.data)
+       {
+       case P80211ENUM_truth_false:
+               /* Confirm that we're in monitor mode */
+               if ( wlandev->netdev->type == ARPHRD_ETHER ) {
+                       msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+                       result = 0;
+                       goto exit;
+               }
+               /* Disable monitor mode */
+               result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE);
+               if ( result ) {
+                       WLAN_LOG_DEBUG(1,
+                               "failed to disable monitor mode, result=%d\n",
+                               result);
+                       goto failed;
+               }
+               /* Disable port 0 */
+               result = hfa384x_drvr_disable(hw, 0);
+               if ( result ) {
+                       WLAN_LOG_DEBUG(1,
+                       "failed to disable port 0 after sniffing, result=%d\n",
+                       result);
+                       goto failed;
+               }
+               /* Clear the driver state */
+               wlandev->netdev->type = ARPHRD_ETHER;
+
+               /* Restore the wepflags */
+               result = hfa384x_drvr_setconfig16(hw,
+                               HFA384x_RID_CNFWEPFLAGS,
+                               hw->presniff_wepflags);
+               if ( result ) {
+                       WLAN_LOG_DEBUG(1,
+                       "failed to restore wepflags=0x%04x, result=%d\n",
+                       hw->presniff_wepflags,
+                       result);
+                       goto failed;
+               }
+
+               /* Set the port to its prior type and enable (if necessary) */
+               if (hw->presniff_port_type != 0 ) {
+                       word = hw->presniff_port_type;
+                       result = hfa384x_drvr_setconfig16(hw,
+                               HFA384x_RID_CNFPORTTYPE, word);
+                       if ( result ) {
+                               WLAN_LOG_DEBUG(1,
+                               "failed to restore porttype, result=%d\n",
+                               result);
+                               goto failed;
+                       }
+
+                       /* Enable the port */
+                       result = hfa384x_drvr_enable(hw, 0);
+                       if ( result ) {
+                               WLAN_LOG_DEBUG(1, "failed to enable port to presniff setting, result=%d\n", result);
+                               goto failed;
+                       }
+               } else {
+                       result = hfa384x_drvr_disable(hw, 0);
+
+               }
+
+               WLAN_LOG_INFO("monitor mode disabled\n");
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+               result = 0;
+               goto exit;
+               break;
+       case P80211ENUM_truth_true:
+               /* Disable the port (if enabled), only check Port 0 */
+               if ( hw->port_enabled[0]) {
+                       if (wlandev->netdev->type == ARPHRD_ETHER) {
+                               /* Save macport 0 state */
+                               result = hfa384x_drvr_getconfig16(hw,
+                                                                 HFA384x_RID_CNFPORTTYPE,
+                                                                 &(hw->presniff_port_type));
+                               if ( result ) {
+                                       WLAN_LOG_DEBUG(1,"failed to read porttype, result=%d\n", result);
+                                       goto failed;
+                               }
+                               /* Save the wepflags state */
+                               result = hfa384x_drvr_getconfig16(hw,
+                                                                 HFA384x_RID_CNFWEPFLAGS,
+                                                                 &(hw->presniff_wepflags));
+                               if ( result ) {
+                                       WLAN_LOG_DEBUG(1,"failed to read wepflags, result=%d\n", result);
+                                       goto failed;
+                               }
+                               hfa384x_drvr_stop(hw);
+                               result = hfa384x_drvr_start(hw);
+                               if ( result ) {
+                                       WLAN_LOG_DEBUG(1,
+                                                      "failed to restart the card for sniffing, result=%d\n",
+                                                      result);
+                                       goto failed;
+                               }
+                       } else {
+                               /* Disable the port */
+                               result = hfa384x_drvr_disable(hw, 0);
+                               if ( result ) {
+                                       WLAN_LOG_DEBUG(1,
+                                                      "failed to enable port for sniffing, result=%d\n",
+                                                      result);
+                                       goto failed;
+                               }
+                       }
+               } else {
+                       hw->presniff_port_type = 0;
+               }
+
+               /* Set the channel we wish to sniff  */
+               word = msg->channel.data;
+               result = hfa384x_drvr_setconfig16(hw,
+                                                 HFA384x_RID_CNFOWNCHANNEL, word);
+               hw->sniff_channel=word;
+
+               if ( result ) {
+                       WLAN_LOG_DEBUG(1,
+                                      "failed to set channel %d, result=%d\n",
+                                              word,
+                                      result);
+                       goto failed;
+               }
+
+               /* Now if we're already sniffing, we can skip the rest */
+               if (wlandev->netdev->type != ARPHRD_ETHER) {
+                       /* Set the port type to pIbss */
+                       word = HFA384x_PORTTYPE_PSUEDOIBSS;
+                       result = hfa384x_drvr_setconfig16(hw,
+                                                         HFA384x_RID_CNFPORTTYPE, word);
+                       if ( result ) {
+                               WLAN_LOG_DEBUG(1,
+                                              "failed to set porttype %d, result=%d\n",
+                                              word,
+                                              result);
+                               goto failed;
+                       }
+                       if ((msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && (msg->keepwepflags.data != P80211ENUM_truth_true)) {
+                               /* Set the wepflags for no decryption */
+                               word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
+                                       HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
+                               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFWEPFLAGS, word);
+                       }
+
+                       if ( result ) {
+                               WLAN_LOG_DEBUG(1,
+                                              "failed to set wepflags=0x%04x, result=%d\n",
+                                              word,
+                                              result);
+                               goto failed;
+                       }
+               }
+
+               /* Do we want to strip the FCS in monitor mode? */
+               if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok) && (msg->stripfcs.data == P80211ENUM_truth_true)) {
+                       hw->sniff_fcs = 0;
+               } else {
+                       hw->sniff_fcs = 1;
+               }
+
+               /* Do we want to truncate the packets? */
+               if (msg->packet_trunc.status == P80211ENUM_msgitem_status_data_ok) {
+                       hw->sniff_truncate = msg->packet_trunc.data;
+               } else {
+                       hw->sniff_truncate = 0;
+               }
+
+               /* Enable the port */
+               result = hfa384x_drvr_enable(hw, 0);
+               if ( result ) {
+                       WLAN_LOG_DEBUG(1,
+                       "failed to enable port for sniffing, result=%d\n",
+                       result);
+                       goto failed;
+               }
+               /* Enable monitor mode */
+               result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE);
+               if ( result ) {
+                       WLAN_LOG_DEBUG(1,
+                       "failed to enable monitor mode, result=%d\n",
+                       result);
+                       goto failed;
+               }
+
+               if (wlandev->netdev->type == ARPHRD_ETHER) {
+                       WLAN_LOG_INFO("monitor mode enabled\n");
+               }
+
+               /* Set the driver state */
+               /* Do we want the prism2 header? */
+               if ((msg->prismheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->prismheader.data == P80211ENUM_truth_true)) {
+                       hw->sniffhdr = 0;
+                       wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
+               } else if ((msg->wlanheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->wlanheader.data == P80211ENUM_truth_true)) {
+                       hw->sniffhdr = 1;
+                       wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
+               } else {
+                       wlandev->netdev->type = ARPHRD_IEEE80211;
+               }
+
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+               result = 0;
+               goto exit;
+               break;
+       default:
+               msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+               result = 0;
+               goto exit;
+               break;
+       }
+
+failed:
+       msg->resultcode.data = P80211ENUM_resultcode_refused;
+       result = 0;
+exit:
+
+       DBFEXIT;
+       return result;
+}
diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h
new file mode 100644 (file)
index 0000000..733fd99
--- /dev/null
@@ -0,0 +1,182 @@
+/* prism2mgmt.h
+*
+* Declares the mgmt command handler functions
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file contains the constants and data structures for interaction
+* with the hfa384x Wireless LAN (WLAN) Media Access Contoller (MAC).
+* The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset.
+*
+* [Implementation and usage notes]
+*
+* [References]
+*   CW10 Programmer's Manual v1.5
+*   IEEE 802.11 D10.0
+*
+*    --------------------------------------------------------------------
+*/
+
+#ifndef _PRISM2MGMT_H
+#define _PRISM2MGMT_H
+
+
+/*=============================================================*/
+/*------ Constants --------------------------------------------*/
+
+/*=============================================================*/
+/*------ Macros -----------------------------------------------*/
+
+/*=============================================================*/
+/*------ Types and their related constants --------------------*/
+
+/*=============================================================*/
+/*------ Static variable externs ------------------------------*/
+
+#if (WLAN_HOSTIF != WLAN_USB)
+extern int      prism2_bap_timeout;
+extern int     prism2_irq_evread_max;
+#endif
+extern int     prism2_debug;
+extern int      prism2_reset_holdtime;
+extern int      prism2_reset_settletime;
+/*=============================================================*/
+/*--- Function Declarations -----------------------------------*/
+/*=============================================================*/
+
+UINT32
+prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate);
+
+void
+prism2sta_ev_dtim(wlandevice_t *wlandev);
+void
+prism2sta_ev_infdrop(wlandevice_t *wlandev);
+void
+prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+void
+prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status);
+void
+prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status);
+void
+prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void
+prism2sta_ev_alloc(wlandevice_t *wlandev);
+
+
+int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_join(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_start(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_mm_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp);
+
+/*---------------------------------------------------------------
+* conversion functions going between wlan message data types and
+* Prism2 data types
+---------------------------------------------------------------*/
+/* byte area conversion functions*/
+void prism2mgmt_pstr2bytearea(UINT8 *bytearea, p80211pstrd_t *pstr);
+void prism2mgmt_bytearea2pstr(UINT8 *bytearea, p80211pstrd_t *pstr, int len);
+
+/* byte string conversion functions*/
+void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
+void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
+
+/* integer conversion functions */
+void prism2mgmt_prism2int2p80211int(UINT16 *prism2int, UINT32 *wlanint);
+void prism2mgmt_p80211int2prism2int(UINT16 *prism2int, UINT32 *wlanint);
+
+/* enumerated integer conversion functions */
+void prism2mgmt_prism2enum2p80211enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid);
+void prism2mgmt_p80211enum2prism2enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid);
+
+/* functions to convert a bit area to/from an Operational Rate Set */
+void prism2mgmt_get_oprateset(UINT16 *rate, p80211pstrd_t *pstr);
+void prism2mgmt_set_oprateset(UINT16 *rate, p80211pstrd_t *pstr);
+
+/* functions to convert Group Addresses */
+void prism2mgmt_get_grpaddr(UINT32 did,
+       p80211pstrd_t *pstr, hfa384x_t *priv );
+int prism2mgmt_set_grpaddr(UINT32 did,
+       UINT8 *prism2buf, p80211pstrd_t *pstr, hfa384x_t *priv );
+int prism2mgmt_get_grpaddr_index( UINT32 did );
+
+void prism2sta_processing_defer(struct work_struct *data);
+
+void prism2sta_commsqual_defer(struct work_struct *data);
+void prism2sta_commsqual_timer(unsigned long data);
+
+/*=============================================================*/
+/*--- Inline Function Definitions (if supported) --------------*/
+/*=============================================================*/
+
+
+
+#endif
diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c
new file mode 100644 (file)
index 0000000..268fd9b
--- /dev/null
@@ -0,0 +1,3799 @@
+/* src/prism2/driver/prism2mib.c
+*
+* Management request for mibset/mibget
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* The functions in this file handle the mibset/mibget management
+* functions.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+#define WLAN_DBVAR     prism2_debug
+
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+
+#include "wlan_compat.h"
+
+//#if (WLAN_HOSTIF == WLAN_PCMCIA)
+//#include <pcmcia/version.h>
+//#include <pcmcia/cs_types.h>
+//#include <pcmcia/cs.h>
+//#include <pcmcia/cistpl.h>
+//#include <pcmcia/ds.h>
+//#include <pcmcia/cisreg.h>
+//#endif
+//
+//#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI))
+//#include <linux/ioport.h>
+//#include <linux/pci.h>
+//endif
+
+//#if (WLAN_HOSTIF == WLAN_USB)
+#include <linux/usb.h>
+//#endif
+
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+#define MIB_TMP_MAXLEN    200    /* Max length of RID record (in bytes). */
+
+/*================================================================*/
+/* Local Types */
+
+#define  F_AP         0x1        /* MIB is supported on Access Points. */
+#define  F_STA        0x2        /* MIB is supported on stations. */
+#define  F_READ       0x4        /* MIB may be read. */
+#define  F_WRITE      0x8        /* MIB may be written. */
+
+typedef struct mibrec
+{
+    UINT32   did;
+    UINT16   flag;
+    UINT16   parm1;
+    UINT16   parm2;
+    UINT16   parm3;
+    int      (*func)(struct mibrec                *mib,
+                     int                          isget,
+                     wlandevice_t                 *wlandev,
+                     hfa384x_t                    *hw,
+                     p80211msg_dot11req_mibset_t  *msg,
+                     void                         *data);
+} mibrec_t;
+
+/*================================================================*/
+/* Local Function Declarations */
+
+static int prism2mib_bytestr2pstr(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_bytearea2pstr(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_uint32(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_uint32array(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_uint32offset(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_truth(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_preamble(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_flag(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_appcfinfoflag(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_regulatorydomains(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_wepdefaultkey(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_powermanagement(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_privacyinvoked(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_excludeunencrypted(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_fragmentationthreshold(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_operationalrateset(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_groupaddress(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_fwid(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_authalg(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_authalgenable(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static int prism2mib_priv(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data);
+
+static void prism2mib_priv_authlist(
+hfa384x_t      *hw,
+prism2sta_authlist_t  *list);
+
+static void prism2mib_priv_accessmode(
+hfa384x_t         *hw,
+UINT32            mode);
+
+static void prism2mib_priv_accessallow(
+hfa384x_t         *hw,
+p80211macarray_t  *macarray);
+
+static void prism2mib_priv_accessdeny(
+hfa384x_t         *hw,
+p80211macarray_t  *macarray);
+
+static void prism2mib_priv_deauthenticate(
+hfa384x_t         *hw,
+UINT8             *addr);
+
+/*================================================================*/
+/* Local Static Definitions */
+
+static mibrec_t mibtab[] = {
+
+    /* dot11smt MIB's */
+
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11StationID,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11MediumOccupancyLimit,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 0,
+          prism2mib_uint32offset },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPollable,
+          F_STA | F_READ,
+          HFA384x_RID_CFPOLLABLE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPPeriod,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 1,
+          prism2mib_uint32offset },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPMaxDuration,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 2,
+          prism2mib_uint32offset },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticationResponseTimeOut,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFAUTHRSPTIMEOUT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11PrivacyOptionImplemented,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_PRIVACYOPTIMP, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11PowerManagementMode,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFPMENABLED, 0, 0,
+          prism2mib_powermanagement },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredSSID,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFDESIREDSSID, HFA384x_RID_CNFDESIREDSSID_LEN, 0,
+          prism2mib_bytestr2pstr },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL, 0, 0,
+          prism2mib_operationalrateset },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL0, 0, 0,
+          prism2mib_operationalrateset },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11BeaconPeriod,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFAPBCNINT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11DTIMPeriod,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFOWNDTIMPER, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11smt_dot11StationConfigTable_dot11AssociationResponseTimeOut,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_PROTOCOLRSPTIME, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm1,
+          F_AP | F_STA | F_READ,
+          1, 0, 0,
+          prism2mib_authalg },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm2,
+          F_AP | F_STA | F_READ,
+          2, 0, 0,
+          prism2mib_authalg },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm3,
+          F_AP | F_STA | F_READ,
+          3, 0, 0,
+          prism2mib_authalg },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm4,
+          F_AP | F_STA | F_READ,
+          4, 0, 0,
+          prism2mib_authalg },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm5,
+          F_AP | F_STA | F_READ,
+          5, 0, 0,
+          prism2mib_authalg },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm6,
+          F_AP | F_STA | F_READ,
+          6, 0, 0,
+          prism2mib_authalg },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable1,
+          F_AP | F_STA | F_READ | F_WRITE,
+          1, 0, 0,
+          prism2mib_authalgenable },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable2,
+          F_AP | F_STA | F_READ | F_WRITE,
+          2, 0, 0,
+          prism2mib_authalgenable },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable3,
+          F_AP | F_STA | F_READ | F_WRITE,
+          3, 0, 0,
+          prism2mib_authalgenable },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable4,
+          F_AP | F_STA | F_READ | F_WRITE,
+          4, 0, 0,
+          prism2mib_authalgenable },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable5,
+          F_AP | F_STA | F_READ | F_WRITE,
+          5, 0, 0,
+          prism2mib_authalgenable },
+    { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable6,
+          F_AP | F_STA | F_READ | F_WRITE,
+          6, 0, 0,
+          prism2mib_authalgenable },
+    { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
+          F_AP | F_STA | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
+          prism2mib_wepdefaultkey },
+    { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1,
+          F_AP | F_STA | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
+          prism2mib_wepdefaultkey },
+    { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2,
+          F_AP | F_STA | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
+          prism2mib_wepdefaultkey },
+    { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3,
+          F_AP | F_STA | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
+          prism2mib_wepdefaultkey },
+    { DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
+          prism2mib_privacyinvoked },
+    { DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
+          prism2mib_excludeunencrypted },
+    { DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFSHORTPREAMBLE, 0, 0,
+          prism2mib_preamble },
+
+    /* dot11mac MIB's */
+
+    { DIDmib_dot11mac_dot11OperationTable_dot11MACAddress,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH0, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_LONGRETRYLIMIT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH0, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_MAXTXLIFETIME, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11mac_dot11OperationTable_dot11MaxReceiveLifetime,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_MAXRXLIFETIME, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+    { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32,
+          F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_groupaddress },
+
+    /* dot11phy MIB's */
+
+    { DIDmib_dot11phy_dot11PhyOperationTable_dot11PHYType,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_PHYTYPE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11phy_dot11PhyOperationTable_dot11TempType,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_TEMPTYPE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+          F_STA | F_READ,
+          HFA384x_RID_CURRENTCHANNEL, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+          F_AP | F_READ,
+          HFA384x_RID_CNFOWNCHANNEL, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentCCAMode,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_CCAMODE, 0, 0,
+          prism2mib_uint32 },
+
+    /* p2Table MIB's */
+
+    { DIDmib_p2_p2Table_p2MMTx,
+          F_AP | F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2EarlyBeacon,
+          F_AP | F_READ | F_WRITE,
+          BIT7, 0, 0,
+          prism2mib_appcfinfoflag },
+    { DIDmib_p2_p2Table_p2ReceivedFrameStatistics,
+          F_AP | F_STA | F_READ,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2CommunicationTallies,
+          F_AP | F_STA | F_READ,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2Authenticated,
+          F_AP | F_READ,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2Associated,
+          F_AP | F_READ,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2PowerSaveUserCount,
+          F_AP | F_READ,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2Comment,
+          F_AP | F_STA | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2AccessMode,
+          F_AP | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2AccessAllow,
+          F_AP | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2AccessDeny,
+          F_AP | F_READ | F_WRITE,
+          0, 0, 0,
+          prism2mib_priv },
+    { DIDmib_p2_p2Table_p2ChannelInfoResults,
+          F_AP | F_READ,
+          0, 0, 0,
+          prism2mib_priv },
+
+    /* p2Static MIB's */
+
+    { DIDmib_p2_p2Static_p2CnfPortType,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFPORTTYPE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfOwnMACAddress,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2Static_p2CnfDesiredSSID,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFDESIREDSSID, HFA384x_RID_CNFDESIREDSSID_LEN, 0,
+          prism2mib_bytestr2pstr },
+    { DIDmib_p2_p2Static_p2CnfOwnChannel,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFOWNCHANNEL, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfOwnSSID,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFOWNSSID, HFA384x_RID_CNFOWNSSID_LEN, 0,
+          prism2mib_bytestr2pstr },
+    { DIDmib_p2_p2Static_p2CnfOwnATIMWindow,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFOWNATIMWIN, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfSystemScale,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFSYSSCALE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfMaxDataLength,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFMAXDATALEN, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfWDSAddress,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFWDSADDR, HFA384x_RID_CNFWDSADDR_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2Static_p2CnfPMEnabled,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFPMENABLED, 0, 0,
+          prism2mib_truth },
+    { DIDmib_p2_p2Static_p2CnfPMEPS,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFPMEPS, 0, 0,
+          prism2mib_truth },
+    { DIDmib_p2_p2Static_p2CnfMulticastReceive,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFMULTICASTRX, 0, 0,
+          prism2mib_truth },
+    { DIDmib_p2_p2Static_p2CnfMaxSleepDuration,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFMAXSLEEPDUR, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfPMHoldoverDuration,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFPMHOLDDUR, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfOwnName,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFOWNNAME, HFA384x_RID_CNFOWNNAME_LEN, 0,
+          prism2mib_bytestr2pstr },
+    { DIDmib_p2_p2Static_p2CnfOwnDTIMPeriod,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFOWNDTIMPER, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfWDSAddress1,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFWDSADDR1, HFA384x_RID_CNFWDSADDR1_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2Static_p2CnfWDSAddress2,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFWDSADDR2, HFA384x_RID_CNFWDSADDR2_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2Static_p2CnfWDSAddress3,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFWDSADDR3, HFA384x_RID_CNFWDSADDR3_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2Static_p2CnfWDSAddress4,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFWDSADDR4, HFA384x_RID_CNFWDSADDR4_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2Static_p2CnfWDSAddress5,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFWDSADDR5, HFA384x_RID_CNFWDSADDR5_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2Static_p2CnfWDSAddress6,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFWDSADDR6, HFA384x_RID_CNFWDSADDR6_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2Static_p2CnfMulticastPMBuffering,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFMCASTPMBUFF, 0, 0,
+          prism2mib_truth },
+    { DIDmib_p2_p2Static_p2CnfWEPDefaultKeyID,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfWEPDefaultKey0,
+          F_AP | F_STA | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
+          prism2mib_wepdefaultkey },
+    { DIDmib_p2_p2Static_p2CnfWEPDefaultKey1,
+          F_AP | F_STA | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
+          prism2mib_wepdefaultkey },
+    { DIDmib_p2_p2Static_p2CnfWEPDefaultKey2,
+          F_AP | F_STA | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
+          prism2mib_wepdefaultkey },
+    { DIDmib_p2_p2Static_p2CnfWEPDefaultKey3,
+          F_AP | F_STA | F_WRITE,
+          HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
+          prism2mib_wepdefaultkey },
+    { DIDmib_p2_p2Static_p2CnfWEPFlags,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFWEPFLAGS, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfAuthentication,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFAUTHENTICATION, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfMaxAssociatedStations,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFMAXASSOCSTATIONS, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfTxControl,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFTXCONTROL, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfRoamingMode,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFROAMINGMODE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfHostAuthentication,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFHOSTAUTHASSOC, 0, 0,
+          prism2mib_truth },
+    { DIDmib_p2_p2Static_p2CnfRcvCrcError,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFRCVCRCERROR, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfAltRetryCount,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFALTRETRYCNT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfBeaconInterval,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFAPBCNINT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfMediumOccupancyLimit,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 0,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2Static_p2CnfCFPPeriod,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 1,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2Static_p2CnfCFPMaxDuration,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 2,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2Static_p2CnfCFPFlags,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 3,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2Static_p2CnfSTAPCFInfo,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFSTAPCFINFO, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfPriorityQUsage,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFPRIORITYQUSAGE, HFA384x_RID_CNFPRIOQUSAGE_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2Static_p2CnfTIMCtrl,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFTIMCTRL, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfThirty2Tally,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFTHIRTY2TALLY, 0, 0,
+          prism2mib_truth },
+    { DIDmib_p2_p2Static_p2CnfEnhSecurity,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFENHSECURITY, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfShortPreamble,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFSHORTPREAMBLE, 0, 0,
+          prism2mib_preamble },
+    { DIDmib_p2_p2Static_p2CnfExcludeLongPreamble,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_CNFEXCLONGPREAMBLE, 0, 0,
+          prism2mib_truth },
+    { DIDmib_p2_p2Static_p2CnfAuthenticationRspTO,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFAUTHRSPTIMEOUT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfBasicRates,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFBASICRATES, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Static_p2CnfSupportedRates,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFSUPPRATES, 0, 0,
+          prism2mib_uint32 },
+
+    /* p2Dynamic MIB's */
+
+    { DIDmib_p2_p2Dynamic_p2CreateIBSS,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CREATEIBSS, 0, 0,
+          prism2mib_truth },
+    { DIDmib_p2_p2Dynamic_p2FragmentationThreshold,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_p2_p2Dynamic_p2RTSThreshold,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2TxRateControl,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2PromiscuousMode,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_PROMISCMODE, 0, 0,
+          prism2mib_truth },
+    { DIDmib_p2_p2Dynamic_p2FragmentationThreshold0,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH0, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_p2_p2Dynamic_p2FragmentationThreshold1,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH1, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_p2_p2Dynamic_p2FragmentationThreshold2,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH2, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_p2_p2Dynamic_p2FragmentationThreshold3,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH3, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_p2_p2Dynamic_p2FragmentationThreshold4,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH4, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_p2_p2Dynamic_p2FragmentationThreshold5,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH5, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_p2_p2Dynamic_p2FragmentationThreshold6,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_FRAGTHRESH6, 0, 0,
+          prism2mib_fragmentationthreshold },
+    { DIDmib_p2_p2Dynamic_p2RTSThreshold0,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH0, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2RTSThreshold1,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH1, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2RTSThreshold2,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH2, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2RTSThreshold3,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH3, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2RTSThreshold4,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH4, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2RTSThreshold5,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH5, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2RTSThreshold6,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_RTSTHRESH6, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2TxRateControl0,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL0, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2TxRateControl1,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL1, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2TxRateControl2,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL2, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2TxRateControl3,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL3, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2TxRateControl4,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL4, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2TxRateControl5,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL5, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Dynamic_p2TxRateControl6,
+          F_AP | F_READ | F_WRITE,
+          HFA384x_RID_TXRATECNTL6, 0, 0,
+          prism2mib_uint32 },
+
+    /* p2Behavior MIB's */
+
+    { DIDmib_p2_p2Behavior_p2TickTime,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_ITICKTIME, 0, 0,
+          prism2mib_uint32 },
+
+    /* p2NIC MIB's */
+
+    { DIDmib_p2_p2NIC_p2MaxLoadTime,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_MAXLOADTIME, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2NIC_p2DLBufferPage,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 0,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2NIC_p2DLBufferOffset,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 1,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2NIC_p2DLBufferLength,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 2,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2NIC_p2PRIIdentity,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_PRIIDENTITY, HFA384x_RID_PRIIDENTITY_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2PRISupRange,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_PRISUPRANGE, HFA384x_RID_PRISUPRANGE_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2CFIActRanges,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_PRI_CFIACTRANGES, HFA384x_RID_CFIACTRANGES_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2BuildSequence,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_BUILDSEQ, HFA384x_RID_BUILDSEQ_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2PrimaryFWID,
+          F_AP | F_STA | F_READ,
+          0, 0, 0,
+          prism2mib_fwid },
+    { DIDmib_p2_p2NIC_p2SecondaryFWID,
+          F_AP | F_STA | F_READ,
+          0, 0, 0,
+          prism2mib_fwid },
+    { DIDmib_p2_p2NIC_p2TertiaryFWID,
+          F_AP | F_READ,
+          0, 0, 0,
+          prism2mib_fwid },
+    { DIDmib_p2_p2NIC_p2NICSerialNumber,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_NICSERIALNUMBER, HFA384x_RID_NICSERIALNUMBER_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2NIC_p2NICIdentity,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_NICIDENTITY, HFA384x_RID_NICIDENTITY_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2MFISupRange,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_MFISUPRANGE, HFA384x_RID_MFISUPRANGE_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2CFISupRange,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_CFISUPRANGE, HFA384x_RID_CFISUPRANGE_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2ChannelList,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_CHANNELLIST, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2NIC_p2RegulatoryDomains,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_REGULATORYDOMAINS, HFA384x_RID_REGULATORYDOMAINS_LEN, 0,
+          prism2mib_regulatorydomains },
+    { DIDmib_p2_p2NIC_p2TempType,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_TEMPTYPE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2NIC_p2STAIdentity,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_STAIDENTITY, HFA384x_RID_STAIDENTITY_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2STASupRange,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_STASUPRANGE, HFA384x_RID_STASUPRANGE_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2MFIActRanges,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_STA_MFIACTRANGES, HFA384x_RID_MFIACTRANGES_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2NIC_p2STACFIActRanges,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_STA_CFIACTRANGES, HFA384x_RID_CFIACTRANGES2_LEN, 0,
+          prism2mib_uint32array },
+
+    /* p2MAC MIB's */
+
+    { DIDmib_p2_p2MAC_p2PortStatus,
+          F_STA | F_READ,
+          HFA384x_RID_PORTSTATUS, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2CurrentSSID,
+          F_STA | F_READ,
+          HFA384x_RID_CURRENTSSID, HFA384x_RID_CURRENTSSID_LEN, 0,
+          prism2mib_bytestr2pstr },
+    { DIDmib_p2_p2MAC_p2CurrentBSSID,
+          F_STA | F_READ,
+          HFA384x_RID_CURRENTBSSID, HFA384x_RID_CURRENTBSSID_LEN, 0,
+          prism2mib_bytearea2pstr },
+    { DIDmib_p2_p2MAC_p2CommsQuality,
+          F_STA | F_READ,
+          HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2MAC_p2CommsQualityCQ,
+          F_STA | F_READ,
+          HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2MAC_p2CommsQualityASL,
+          F_STA | F_READ,
+          HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 1,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2MAC_p2CommsQualityANL,
+          F_STA | F_READ,
+          HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 2,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2MAC_p2dbmCommsQuality,
+          F_STA | F_READ,
+          HFA384x_RID_DBMCOMMSQUALITY, HFA384x_RID_DBMCOMMSQUALITY_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2MAC_p2dbmCommsQualityCQ,
+          F_STA | F_READ,
+          HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2MAC_p2dbmCommsQualityASL,
+          F_STA | F_READ,
+          HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 1,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2MAC_p2dbmCommsQualityANL,
+          F_STA | F_READ,
+          HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 2,
+          prism2mib_uint32offset },
+    { DIDmib_p2_p2MAC_p2CurrentTxRate,
+          F_STA | F_READ,
+          HFA384x_RID_CURRENTTXRATE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2CurrentBeaconInterval,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_CURRENTBCNINT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2StaCurrentScaleThresholds,
+          F_STA | F_READ,
+          HFA384x_RID_CURRENTSCALETHRESH, HFA384x_RID_STACURSCALETHRESH_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2MAC_p2APCurrentScaleThresholds,
+          F_AP | F_READ,
+          HFA384x_RID_CURRENTSCALETHRESH, HFA384x_RID_APCURSCALETHRESH_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2MAC_p2ProtocolRspTime,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_PROTOCOLRSPTIME, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2ShortRetryLimit,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2LongRetryLimit,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_LONGRETRYLIMIT, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2MaxTransmitLifetime,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_MAXTXLIFETIME, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2MaxReceiveLifetime,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_MAXRXLIFETIME, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2CFPollable,
+          F_STA | F_READ,
+          HFA384x_RID_CFPOLLABLE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2AuthenticationAlgorithms,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_AUTHALGORITHMS, HFA384x_RID_AUTHALGORITHMS_LEN, 0,
+          prism2mib_uint32array },
+    { DIDmib_p2_p2MAC_p2PrivacyOptionImplemented,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_PRIVACYOPTIMP, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2CurrentTxRate1,
+          F_AP | F_READ,
+          HFA384x_RID_CURRENTTXRATE1, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2CurrentTxRate2,
+          F_AP | F_READ,
+          HFA384x_RID_CURRENTTXRATE2, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2CurrentTxRate3,
+          F_AP | F_READ,
+          HFA384x_RID_CURRENTTXRATE3, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2CurrentTxRate4,
+          F_AP | F_READ,
+          HFA384x_RID_CURRENTTXRATE4, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2CurrentTxRate5,
+          F_AP | F_READ,
+          HFA384x_RID_CURRENTTXRATE5, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2CurrentTxRate6,
+          F_AP | F_READ,
+          HFA384x_RID_CURRENTTXRATE6, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2MAC_p2OwnMACAddress,
+          F_AP | F_READ,
+          HFA384x_RID_OWNMACADDRESS, HFA384x_RID_OWNMACADDRESS_LEN, 0,
+          prism2mib_bytearea2pstr },
+
+    /* p2Modem MIB's */
+
+    { DIDmib_p2_p2Modem_p2PHYType,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_PHYTYPE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Modem_p2CurrentChannel,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_CURRENTCHANNEL, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Modem_p2CurrentPowerState,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_CURRENTPOWERSTATE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Modem_p2CCAMode,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_CCAMODE, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Modem_p2TxPowerMax,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_TXPOWERMAX, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
+          F_AP | F_STA | F_READ | F_WRITE,
+          HFA384x_RID_TXPOWERMAX, 0, 0,
+          prism2mib_uint32 },
+    { DIDmib_p2_p2Modem_p2SupportedDataRates,
+          F_AP | F_STA | F_READ,
+          HFA384x_RID_SUPPORTEDDATARATES, HFA384x_RID_SUPPORTEDDATARATES_LEN, 0,
+          prism2mib_bytestr2pstr },
+
+    /* And finally, lnx mibs */
+    { DIDmib_lnx_lnxConfigTable_lnxRSNAIE,
+          F_STA | F_READ | F_WRITE,
+          HFA384x_RID_CNFWPADATA, 0, 0,
+          prism2mib_priv },
+    { 0, 0, 0, 0, 0, NULL}};
+
+/*----------------------------------------------------------------
+These MIB's are not supported at this time:
+
+DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityPresent
+DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityEnabled
+DIDmib_dot11phy_dot11PhyDSSSTable_dot11PBCCOptionImplemented
+DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportIndex
+DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxIndex
+DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxValue
+DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxIndex
+DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxValue
+
+DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportValue
+TODO: need to investigate why wlan has this as enumerated and Prism2 has this
+      as btye str.
+
+DIDmib_dot11phy_dot11PhyDSSSTable_dot11ShortPreambleOptionImplemented
+TODO: Find out the firmware version number(s) for identifying
+      whether the firmware is capable of short preamble. TRUE or FALSE
+      will be returned based on the version of the firmware.
+
+WEP Key mappings aren't supported in the f/w.
+DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingIndex
+DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingAddress
+DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingWEPOn
+DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingValue
+DIDmib_dot11smt_dot11PrivacyTable_dot11WEPKeyMappingLength
+
+TODO: implement counters.
+DIDmib_dot11smt_dot11PrivacyTable_dot11WEPICVErrorCount
+DIDmib_dot11smt_dot11PrivacyTable_dot11WEPExcludedCount
+DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFragmentCount
+DIDmib_dot11mac_dot11CountersTable_dot11MulticastTransmittedFrameCount
+DIDmib_dot11mac_dot11CountersTable_dot11FailedCount
+DIDmib_dot11mac_dot11CountersTable_dot11RetryCount
+DIDmib_dot11mac_dot11CountersTable_dot11MultipleRetryCount
+DIDmib_dot11mac_dot11CountersTable_dot11FrameDuplicateCount
+DIDmib_dot11mac_dot11CountersTable_dot11RTSSuccessCount
+DIDmib_dot11mac_dot11CountersTable_dot11RTSFailureCount
+DIDmib_dot11mac_dot11CountersTable_dot11ACKFailureCount
+DIDmib_dot11mac_dot11CountersTable_dot11ReceivedFragmentCount
+DIDmib_dot11mac_dot11CountersTable_dot11MulticastReceivedFrameCount
+DIDmib_dot11mac_dot11CountersTable_dot11FCSErrorCount
+DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFrameCount
+DIDmib_dot11mac_dot11CountersTable_dot11WEPUndecryptableCount
+
+TODO: implement sane values for these.
+DIDmib_dot11mac_dot11OperationTable_dot11ManufacturerID
+DIDmib_dot11mac_dot11OperationTable_dot11ProductID
+
+Not too worried about these at the moment.
+DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentTxAntenna
+DIDmib_dot11phy_dot11PhyAntennaTable_dot11DiversitySupport
+DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentRxAntenna
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11NumberSupportedPowerLevels
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel
+
+Ummm, FH and IR don't apply
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11HopTime
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentChannelNumber
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11MaxDwellTime
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentDwellTime
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentSet
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentPattern
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentIndex
+DIDmib_dot11phy_dot11PhyDSSSTable_dot11CCAModeSupported
+DIDmib_dot11phy_dot11PhyDSSSTable_dot11EDThreshold
+DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMax
+DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMax
+DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMin
+DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMin
+
+We just don't have enough antennas right now to worry about this.
+DIDmib_dot11phy_dot11AntennasListTable_dot11AntennaListIndex
+DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedTxAntenna
+DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedRxAntenna
+DIDmib_dot11phy_dot11AntennasListTable_dot11DiversitySelectionRx
+
+------------------------------------------------------------------*/
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* prism2mgmt_mibset_mibget
+*
+* Set the value of a mib item.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0      success, but we're waiting for something to finish.
+*      >0      an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+
+int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
+{
+       hfa384x_t               *hw = wlandev->priv;
+       int                     result, isget;
+       mibrec_t                *mib;
+       UINT16                  which;
+
+       p80211msg_dot11req_mibset_t     *msg = msgp;
+       p80211itemd_t                   *mibitem;
+
+       DBFENTER;
+
+       msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+       msg->resultcode.data = P80211ENUM_resultcode_success;
+
+       /*
+       ** Determine if this is an Access Point or a station.
+       */
+
+       which = hw->ap ? F_AP : F_STA;
+
+       /*
+       ** Find the MIB in the MIB table.  Note that a MIB may be in the
+       ** table twice...once for an AP and once for a station.  Make sure
+       ** to get the correct one.  Note that DID=0 marks the end of the
+       ** MIB table.
+       */
+
+       mibitem = (p80211itemd_t *) msg->mibattribute.data;
+
+       for (mib = mibtab; mib->did != 0; mib++)
+               if (mib->did == mibitem->did && (mib->flag & which))
+                       break;
+
+       if (mib->did == 0) {
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+               goto done;
+       }
+
+       /*
+       ** Determine if this is a "mibget" or a "mibset".  If this is a
+       ** "mibget", then make sure that the MIB may be read.  Otherwise,
+       ** this is a "mibset" so make make sure that the MIB may be written.
+       */
+
+       isget = (msg->msgcode == DIDmsg_dot11req_mibget);
+
+       if (isget) {
+               if (!(mib->flag & F_READ)) {
+                       msg->resultcode.data =
+                               P80211ENUM_resultcode_cant_get_writeonly_mib;
+                       goto done;
+               }
+       } else {
+               if (!(mib->flag & F_WRITE)) {
+                       msg->resultcode.data =
+                               P80211ENUM_resultcode_cant_set_readonly_mib;
+                       goto done;
+               }
+       }
+
+       /*
+       ** Execute the MIB function.  If things worked okay, then make
+       ** sure that the MIB function also worked okay.  If so, and this
+       ** is a "mibget", then the status value must be set for both the
+       ** "mibattribute" parameter and the mib item within the data
+       ** portion of the "mibattribute".
+       */
+
+       result = mib->func(mib, isget, wlandev, hw, msg,
+                          (void *) mibitem->data);
+
+       if (msg->resultcode.data == P80211ENUM_resultcode_success) {
+               if (result != 0) {
+                       WLAN_LOG_DEBUG(1, "get/set failure, result=%d\n",
+                                       result);
+                       msg->resultcode.data =
+                                P80211ENUM_resultcode_implementation_failure;
+               } else {
+                       if (isget) {
+                               msg->mibattribute.status =
+                                       P80211ENUM_msgitem_status_data_ok;
+                               mibitem->status =
+                                       P80211ENUM_msgitem_status_data_ok;
+                       }
+               }
+       }
+
+done:
+       DBFEXIT;
+
+       return(0);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_bytestr2pstr
+*
+* Get/set pstr data to/from a byte string.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Number of bytes of RID data.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_bytestr2pstr(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int                result;
+       p80211pstrd_t      *pstr = (p80211pstrd_t*) data;
+       UINT8              bytebuf[MIB_TMP_MAXLEN];
+       hfa384x_bytestr_t  *p2bytestr = (hfa384x_bytestr_t*) bytebuf;
+
+       DBFENTER;
+
+       if (isget) {
+               result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
+               prism2mgmt_bytestr2pstr(p2bytestr, pstr);
+       } else {
+               memset(bytebuf, 0, mib->parm2);
+               prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+               result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_bytearea2pstr
+*
+* Get/set pstr data to/from a byte area.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Number of bytes of RID data.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_bytearea2pstr(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int            result;
+       p80211pstrd_t  *pstr = (p80211pstrd_t*) data;
+       UINT8          bytebuf[MIB_TMP_MAXLEN];
+
+       DBFENTER;
+
+       if (isget) {
+               result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
+               prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2);
+       } else {
+               memset(bytebuf, 0, mib->parm2);
+               prism2mgmt_pstr2bytearea(bytebuf, pstr);
+               result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_uint32
+*
+* Get/set uint32 data.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_uint32(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32*) data;
+       UINT8   bytebuf[MIB_TMP_MAXLEN];
+       UINT16  *wordbuf = (UINT16*) bytebuf;
+
+       DBFENTER;
+
+       if (isget) {
+               result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+               *uint32 = *wordbuf;
+               /* [MSM] Removed, getconfig16 returns the value in host order.
+                * prism2mgmt_prism2int2p80211int(wordbuf, uint32);
+                */
+       } else {
+               /* [MSM] Removed, setconfig16 expects host order.
+                * prism2mgmt_p80211int2prism2int(wordbuf, uint32);
+                */
+               *wordbuf = *uint32;
+               result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_uint32array
+*
+* Get/set an array of uint32 data.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Number of bytes of RID data.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_uint32array(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32 *) data;
+       UINT8   bytebuf[MIB_TMP_MAXLEN];
+       UINT16  *wordbuf = (UINT16*) bytebuf;
+       int     i, cnt;
+
+       DBFENTER;
+
+       cnt = mib->parm2 / sizeof(UINT16);
+
+       if (isget) {
+               result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2);
+               for (i = 0; i < cnt; i++)
+                       prism2mgmt_prism2int2p80211int(wordbuf+i, uint32+i);
+       } else {
+               for (i = 0; i < cnt; i++)
+                       prism2mgmt_p80211int2prism2int(wordbuf+i, uint32+i);
+               result = hfa384x_drvr_setconfig(hw, mib->parm1, wordbuf, mib->parm2);
+               }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_uint32offset
+*
+* Get/set a single element in an array of uint32 data.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Number of bytes of RID data.
+*       parm3    Element index.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_uint32offset(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32*) data;
+       UINT8   bytebuf[MIB_TMP_MAXLEN];
+       UINT16  *wordbuf = (UINT16*) bytebuf;
+       UINT16  cnt;
+
+       DBFENTER;
+
+       cnt = mib->parm2 / sizeof(UINT16);
+
+       result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2);
+       if (result == 0) {
+               if (isget) {
+                       if (mib->parm3 < cnt)
+                               prism2mgmt_prism2int2p80211int(wordbuf+mib->parm3, uint32);
+                       else
+                               *uint32 = 0;
+               } else {
+                       if (mib->parm3 < cnt) {
+                               prism2mgmt_p80211int2prism2int(wordbuf+mib->parm3, uint32);
+                               result = hfa384x_drvr_setconfig(hw, mib->parm1, wordbuf, mib->parm2);
+                       }
+               }
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_truth
+*
+* Get/set truth data.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_truth(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32*) data;
+       UINT8   bytebuf[MIB_TMP_MAXLEN];
+       UINT16  *wordbuf = (UINT16*) bytebuf;
+
+       DBFENTER;
+
+       if (isget) {
+               result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+               *uint32 = (*wordbuf) ?
+                               P80211ENUM_truth_true : P80211ENUM_truth_false;
+       } else {
+               *wordbuf = ((*uint32) == P80211ENUM_truth_true) ? 1 : 0;
+               result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_flag
+*
+* Get/set a flag.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Bit to get/set.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_flag(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32*) data;
+       UINT8   bytebuf[MIB_TMP_MAXLEN];
+       UINT16  *wordbuf = (UINT16*) bytebuf;
+       UINT32  flags;
+
+       DBFENTER;
+
+       result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+       if (result == 0) {
+               /* [MSM] Removed, getconfig16 returns the value in host order.
+                * prism2mgmt_prism2int2p80211int(wordbuf, &flags);
+                */
+               flags = *wordbuf;
+               if (isget) {
+                       *uint32 = (flags & mib->parm2) ?
+                               P80211ENUM_truth_true : P80211ENUM_truth_false;
+               } else {
+                       if ((*uint32) == P80211ENUM_truth_true)
+                               flags |= mib->parm2;
+                       else
+                               flags &= ~mib->parm2;
+                       /* [MSM] Removed, setconfig16 expects host order.
+                        * prism2mgmt_p80211int2prism2int(wordbuf, &flags);
+                        */
+                       *wordbuf = flags;
+                       result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+               }
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_appcfinfoflag
+*
+* Get/set a single flag in the APPCFINFO record.
+*
+* MIB record parameters:
+*       parm1    Bit to get/set.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_appcfinfoflag(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32*) data;
+       UINT8   bytebuf[MIB_TMP_MAXLEN];
+       UINT16  *wordbuf = (UINT16*) bytebuf;
+       UINT16  word;
+
+       DBFENTER;
+
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFAPPCFINFO,
+                                       bytebuf, HFA384x_RID_CNFAPPCFINFO_LEN);
+       if (result == 0) {
+               if (isget) {
+                       *uint32 = (hfa384x2host_16(wordbuf[3]) & mib->parm1) ?
+                               P80211ENUM_truth_true : P80211ENUM_truth_false;
+               } else {
+                       word = hfa384x2host_16(wordbuf[3]);
+                       word = ((*uint32) == P80211ENUM_truth_true) ?
+                               (word | mib->parm1) : (word & ~mib->parm1);
+                       wordbuf[3] = host2hfa384x_16(word);
+                       result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFAPPCFINFO,
+                                       bytebuf, HFA384x_RID_CNFAPPCFINFO_LEN);
+               }
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_regulatorydomains
+*
+* Get regulatory domain data.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Number of bytes of RID data.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_regulatorydomains(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int            result;
+       UINT32         cnt;
+       p80211pstrd_t  *pstr = (p80211pstrd_t*) data;
+       UINT8          bytebuf[MIB_TMP_MAXLEN];
+       UINT16         *wordbuf = (UINT16*) bytebuf;
+
+       DBFENTER;
+
+       result = 0;
+
+       if (isget) {
+               result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2);
+               prism2mgmt_prism2int2p80211int(wordbuf, &cnt);
+               pstr->len = (UINT8) cnt;
+               memcpy(pstr->data, &wordbuf[1], pstr->len);
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_wepdefaultkey
+*
+* Get/set WEP default keys.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Number of bytes of RID data.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_wepdefaultkey(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int            result;
+       p80211pstrd_t  *pstr = (p80211pstrd_t*) data;
+       UINT8          bytebuf[MIB_TMP_MAXLEN];
+       UINT16         len;
+
+       DBFENTER;
+
+       if (isget) {
+               result = 0;    /* Should never happen. */
+       } else {
+               len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN :
+                                       HFA384x_RID_CNFWEPDEFAULTKEY_LEN;
+               memset(bytebuf, 0, len);
+               prism2mgmt_pstr2bytearea(bytebuf, pstr);
+               result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len);
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_powermanagement
+*
+* Get/set 802.11 power management value.  Note that this is defined differently
+* by 802.11 and Prism2:
+*
+*       Meaning     802.11       Prism2
+*        active       1           false
+*      powersave      2           true
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_powermanagement(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32*) data;
+       UINT32  value;
+
+       DBFENTER;
+
+       if (isget) {
+               result = prism2mib_uint32(mib, isget, wlandev, hw, msg, &value);
+               *uint32 = (value == 0) ? 1 : 2;
+       } else {
+               value = ((*uint32) == 1) ? 0 : 1;
+               result = prism2mib_uint32(mib, isget, wlandev, hw, msg, &value);
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_preamble
+*
+* Get/set Prism2 short preamble
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_preamble(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32*) data;
+       UINT8   bytebuf[MIB_TMP_MAXLEN];
+       UINT16  *wordbuf = (UINT16*) bytebuf;
+
+       DBFENTER;
+
+       if (isget) {
+               result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+               *uint32 = *wordbuf;
+       } else {
+               *wordbuf = *uint32;
+               result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_privacyinvoked
+*
+* Get/set the dot11PrivacyInvoked value.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Bit value for PrivacyInvoked flag.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_privacyinvoked(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+
+       DBFENTER;
+
+       if (wlandev->hostwep & HOSTWEP_DECRYPT) {
+               if (wlandev->hostwep & HOSTWEP_DECRYPT)
+                       mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
+               if (wlandev->hostwep & HOSTWEP_ENCRYPT)
+                       mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_TXCRYPT;
+       }
+
+       result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_excludeunencrypted
+*
+* Get/set the dot11ExcludeUnencrypted value.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Bit value for ExcludeUnencrypted flag.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_excludeunencrypted(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+
+       DBFENTER;
+
+       result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_fragmentationthreshold
+*
+* Get/set the fragmentation threshold.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_fragmentationthreshold(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32*) data;
+
+       DBFENTER;
+
+       if (!isget)
+               if ((*uint32) % 2) {
+                       WLAN_LOG_WARNING("Attempt to set odd number "
+                                         "FragmentationThreshold\n");
+                       msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+                       return(0);
+               }
+
+       result = prism2mib_uint32(mib, isget, wlandev, hw, msg, data);
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_operationalrateset
+*
+* Get/set the operational rate set.
+*
+* MIB record parameters:
+*       parm1    Prism2 RID value.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_operationalrateset(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int            result;
+       p80211pstrd_t  *pstr = (p80211pstrd_t *) data;
+       UINT8          bytebuf[MIB_TMP_MAXLEN];
+       UINT16         *wordbuf = (UINT16*) bytebuf;
+
+       DBFENTER;
+
+       if (isget) {
+               result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+               prism2mgmt_get_oprateset(wordbuf, pstr);
+       } else {
+               prism2mgmt_set_oprateset(wordbuf, pstr);
+               result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+               result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, *wordbuf);
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_groupaddress
+*
+* Get/set the dot11GroupAddressesTable.
+*
+* MIB record parameters:
+*       parm1    Not used.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_groupaddress(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int            result;
+       p80211pstrd_t  *pstr = (p80211pstrd_t *) data;
+       UINT8          bytebuf[MIB_TMP_MAXLEN];
+       UINT16         len;
+
+       DBFENTER;
+
+       /* TODO: fix this.  f/w doesn't support mcast filters */
+
+       if (isget) {
+               prism2mgmt_get_grpaddr(mib->did, pstr, hw);
+               return(0);
+       }
+
+       result = prism2mgmt_set_grpaddr(mib->did, bytebuf, pstr, hw);
+       if (result != 0) {
+               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+               return(result);
+       }
+
+       if (hw->dot11_grpcnt <= MAX_PRISM2_GRP_ADDR) {
+               len = hw->dot11_grpcnt * WLAN_ADDR_LEN;
+               memcpy(bytebuf, hw->dot11_grp_addr[0], len);
+               result = hfa384x_drvr_setconfig(hw, HFA384x_RID_GROUPADDR, bytebuf, len);
+
+               /*
+               ** Turn off promiscuous mode if count is equal to MAX.  We may
+               ** have been at a higher count in promiscuous mode and need to
+               ** turn it off.
+               */
+
+               /* but only if we're not already in promisc mode. :) */
+               if ((hw->dot11_grpcnt == MAX_PRISM2_GRP_ADDR) &&
+                   !( wlandev->netdev->flags & IFF_PROMISC)) {
+                       result = hfa384x_drvr_setconfig16(hw,
+                                            HFA384x_RID_PROMISCMODE, 0);
+               }
+       } else {
+
+               /*
+               ** Clear group addresses in card and set to promiscuous mode.
+               */
+
+               memset(bytebuf, 0, sizeof(bytebuf));
+               result = hfa384x_drvr_setconfig(hw, HFA384x_RID_GROUPADDR,
+                                               bytebuf, 0);
+               if (result == 0) {
+                       result = hfa384x_drvr_setconfig16(hw,
+                                       HFA384x_RID_PROMISCMODE, 1);
+               }
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_fwid
+*
+* Get the firmware ID.
+*
+* MIB record parameters:
+*       parm1    Not used.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_fwid(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int             result;
+       p80211pstrd_t   *pstr = (p80211pstrd_t *) data;
+       hfa384x_FWID_t  fwid;
+
+       DBFENTER;
+
+       if (isget) {
+               result = hfa384x_drvr_getconfig(hw, HFA384x_RID_FWID,
+                                               &fwid, HFA384x_RID_FWID_LEN);
+               if (mib->did == DIDmib_p2_p2NIC_p2PrimaryFWID) {
+                       fwid.primary[HFA384x_FWID_LEN - 1] = '\0';
+                       pstr->len = strlen(fwid.primary);
+                       memcpy(pstr->data, fwid.primary, pstr->len);
+               } else {
+                       fwid.secondary[HFA384x_FWID_LEN - 1] = '\0';
+                       pstr->len = strlen(fwid.secondary);
+                       memcpy(pstr->data, fwid.secondary, pstr->len);
+               }
+       } else
+               result = 0;     /* Should never happen. */
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_authalg
+*
+* Get values from the AuhtenticationAlgorithmsTable.
+*
+* MIB record parameters:
+*       parm1    Table index (1-6).
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_authalg(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       UINT32  *uint32 = (UINT32*) data;
+
+       DBFENTER;
+
+       /* MSM: pkx supplied code that  code queries RID FD4D....but the f/w's
+         *  results are bogus. Therefore, we have to simulate the appropriate
+         *  results here in the driver based on our knowledge of existing MAC
+         *  features.  That's the whole point behind this ugly function.
+         */
+
+       if (isget) {
+               msg->resultcode.data = P80211ENUM_resultcode_success;
+               switch (mib->parm1) {
+                       case 1: /* Open System */
+                               *uint32 = P80211ENUM_authalg_opensystem;
+                               break;
+                       case 2: /* SharedKey */
+                               *uint32 = P80211ENUM_authalg_sharedkey;
+                               break;
+                       default:
+                               *uint32 = 0;
+                               msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+                               break;
+               }
+       }
+
+       DBFEXIT;
+       return(0);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_authalgenable
+*
+* Get/set the enable values from the AuhtenticationAlgorithmsTable.
+*
+* MIB record parameters:
+*       parm1    Table index (1-6).
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_authalgenable(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       int     result;
+       UINT32  *uint32 = (UINT32*) data;
+
+       int     index;
+       UINT16  cnf_auth;
+       UINT16  mask;
+
+       DBFENTER;
+
+       index = mib->parm1 - 1;
+
+       result = hfa384x_drvr_getconfig16( hw,
+                       HFA384x_RID_CNFAUTHENTICATION, &cnf_auth);
+       WLAN_LOG_DEBUG(2,"cnfAuthentication0=%d, index=%d\n", cnf_auth, index);
+
+       if (isget) {
+               if ( index == 0 || index == 1 ) {
+                       *uint32 = (cnf_auth & (1<<index)) ?
+                               P80211ENUM_truth_true: P80211ENUM_truth_false;
+               } else {
+                       *uint32 = P80211ENUM_truth_false;
+                       msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+               }
+       } else {
+               if ( index == 0 || index == 1 ) {
+                       mask = 1 << index;
+                       if (*uint32==P80211ENUM_truth_true ) {
+                               cnf_auth |= mask;
+                       } else {
+                               cnf_auth &= ~mask;
+                       }
+                       result = hfa384x_drvr_setconfig16( hw,
+                                       HFA384x_RID_CNFAUTHENTICATION, cnf_auth);
+                       WLAN_LOG_DEBUG(2,"cnfAuthentication:=%d\n", cnf_auth);
+                       if ( result ) {
+                               WLAN_LOG_DEBUG(1,"Unable to set p2cnfAuthentication to %d\n", cnf_auth);
+                               msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+                       }
+               } else {
+                       msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+               }
+       }
+
+       DBFEXIT;
+       return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv
+*
+* Get/set values in the "priv" data structure.
+*
+* MIB record parameters:
+*       parm1    Not used.
+*       parm2    Not used.
+*       parm3    Not used.
+*
+* Arguments:
+*       mib      MIB record.
+*       isget    MIBGET/MIBSET flag.
+*       wlandev  wlan device structure.
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       msg      Message structure.
+*       data     Data buffer.
+*
+* Returns:
+*       0   - Success.
+*       ~0  - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_priv(
+mibrec_t                     *mib,
+int                          isget,
+wlandevice_t                 *wlandev,
+hfa384x_t                    *hw,
+p80211msg_dot11req_mibset_t  *msg,
+void                         *data)
+{
+       UINT32            *uint32 = (UINT32*) data;
+       p80211pstrd_t     *pstr = (p80211pstrd_t*) data;
+       p80211macarray_t  *macarray = (p80211macarray_t *) data;
+
+       int  i, cnt, result, done;
+
+       prism2sta_authlist_t  old;
+
+       /*
+       ** "test" is a lot longer than necessary but who cares?  ...as long as
+       ** it is long enough!
+       */
+
+       UINT8  test[sizeof(wlandev->rx) + sizeof(hw->tallies)];
+
+       DBFENTER;
+
+       switch (mib->did) {
+       case DIDmib_p2_p2Table_p2ReceivedFrameStatistics:
+
+               /*
+               ** Note: The values in this record are changed by the
+               ** interrupt handler and therefore cannot be guaranteed
+               ** to be stable while they are being copied.  However,
+               ** the interrupt handler will take priority over this
+               ** code.  Hence, if the same values are copied twice,
+               ** then we are ensured that the values have not been
+               ** changed.  If they have, then just try again.  Don't
+               ** try more than 10 times...if we still haven't got it,
+               ** then the values we do have are probably good enough.
+               ** This scheme for copying values is used in order to
+               ** prevent having to block the interrupt handler while
+               ** we copy the values.
+               */
+
+               if (isget)
+                       for (i = 0; i < 10; i++) {
+                               memcpy(data, &wlandev->rx, sizeof(wlandev->rx));
+                               memcpy(test, &wlandev->rx, sizeof(wlandev->rx));
+                               if (memcmp(data, test, sizeof(wlandev->rx)) == 0) break;
+                       }
+
+               break;
+
+       case DIDmib_p2_p2Table_p2CommunicationTallies:
+
+               /*
+               ** Note: The values in this record are changed by the
+               ** interrupt handler and therefore cannot be guaranteed
+               ** to be stable while they are being copied.  See the
+               ** note above about copying values.
+               */
+
+               if (isget) {
+                       result = hfa384x_drvr_commtallies(hw);
+
+                       /* ?????? We need to wait a bit here for the */
+                       /*   tallies to get updated. ?????? */
+                       /* MSM: TODO: The right way to do this is to
+                        *      add a "commtallie" wait queue to the
+                        *      priv structure that gets run every time
+                        *      we receive a commtally info frame.
+                        *      This process would sleep on that
+                        *      queue and get awakened when the
+                        *      the requested info frame arrives.
+                        *      Don't have time to do and test this
+                        *      right now.
+                        */
+
+                       /* Ugh, this is nasty. */
+                       for (i = 0; i < 10; i++) {
+                               memcpy(data,
+                                      &hw->tallies,
+                                      sizeof(hw->tallies));
+                               memcpy(test,
+                                      &hw->tallies,
+                                      sizeof(hw->tallies));
+                               if ( memcmp(data,
+                                           test,
+                                           sizeof(hw->tallies)) == 0)
+                                       break;
+                       }
+               }
+
+               break;
+
+       case DIDmib_p2_p2Table_p2Authenticated:
+
+               if (isget) {
+                       prism2mib_priv_authlist(hw, &old);
+
+                       macarray->cnt = 0;
+                       for (i = 0; i < old.cnt; i++) {
+                               if (!old.assoc[i]) {
+                                       memcpy(macarray->data[macarray->cnt], old.addr[i], WLAN_ADDR_LEN);
+                                       macarray->cnt++;
+                               }
+                       }
+               }
+
+               break;
+
+       case DIDmib_p2_p2Table_p2Associated:
+
+               if (isget) {
+                       prism2mib_priv_authlist(hw, &old);
+
+                       macarray->cnt = 0;
+                       for (i = 0; i < old.cnt; i++) {
+                               if (old.assoc[i]) {
+                                       memcpy(macarray->data[macarray->cnt], old.addr[i], WLAN_ADDR_LEN);
+                                       macarray->cnt++;
+                               }
+                       }
+               }
+
+               break;
+
+       case DIDmib_p2_p2Table_p2PowerSaveUserCount:
+
+               if (isget)
+                       *uint32 = hw->psusercount;
+
+               break;
+
+       case DIDmib_p2_p2Table_p2Comment:
+
+               if (isget) {
+                       pstr->len = strlen(hw->comment);
+                       memcpy(pstr->data, hw->comment, pstr->len);
+               } else {
+                       cnt = pstr->len;
+                       if (cnt < 0) cnt = 0;
+                       if (cnt >= sizeof(hw->comment))
+                               cnt = sizeof(hw->comment)-1;
+                       memcpy(hw->comment, pstr->data, cnt);
+                       pstr->data[cnt] = '\0';
+               }
+
+               break;
+
+       case DIDmib_p2_p2Table_p2AccessMode:
+
+               if (isget)
+                       *uint32 = hw->accessmode;
+               else
+                       prism2mib_priv_accessmode(hw, *uint32);
+
+               break;
+
+       case DIDmib_p2_p2Table_p2AccessAllow:
+
+               if (isget) {
+                       macarray->cnt = hw->allow.cnt;
+                       memcpy(macarray->data, hw->allow.addr,
+                              macarray->cnt*WLAN_ADDR_LEN);
+               } else {
+                       prism2mib_priv_accessallow(hw, macarray);
+               }
+
+               break;
+
+       case DIDmib_p2_p2Table_p2AccessDeny:
+
+               if (isget) {
+                       macarray->cnt = hw->deny.cnt;
+                       memcpy(macarray->data, hw->deny.addr,
+                              macarray->cnt*WLAN_ADDR_LEN);
+               } else {
+                       prism2mib_priv_accessdeny(hw, macarray);
+               }
+
+               break;
+
+       case DIDmib_p2_p2Table_p2ChannelInfoResults:
+
+               if (isget) {
+                       done = atomic_read(&hw->channel_info.done);
+                       if (done == 0) {
+                               msg->resultcode.status = P80211ENUM_msgitem_status_no_value;
+                               break;
+                       }
+                       if (done == 1) {
+                               msg->resultcode.status = P80211ENUM_msgitem_status_incomplete_itemdata;
+                               break;
+                       }
+
+                       for (i = 0; i < 14; i++, uint32 += 5) {
+                               uint32[0] = i+1;
+                               uint32[1] = hw->channel_info.results.result[i].anl;
+                               uint32[2] = hw->channel_info.results.result[i].pnl;
+                               uint32[3] = (hw->channel_info.results.result[i].active & HFA384x_CHINFORESULT_BSSACTIVE) ? 1 : 0;
+                               uint32[4] = (hw->channel_info.results.result[i].active & HFA384x_CHINFORESULT_PCFACTIVE) ? 1 : 0;
+                       }
+               }
+
+               break;
+
+       case DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType:
+
+               if (isget)
+                       *uint32 = hw->dot11_desired_bss_type;
+               else
+                       hw->dot11_desired_bss_type = *uint32;
+
+               break;
+
+       case DIDmib_lnx_lnxConfigTable_lnxRSNAIE: {
+               hfa384x_WPAData_t wpa;
+               if (isget) {
+                       hfa384x_drvr_getconfig( hw, HFA384x_RID_CNFWPADATA,
+                                               (UINT8 *) &wpa, sizeof(wpa));
+                       pstr->len = hfa384x2host_16(wpa.datalen);
+                       memcpy(pstr->data, wpa.data, pstr->len);
+               } else {
+                       wpa.datalen = host2hfa384x_16(pstr->len);
+                       memcpy(wpa.data, pstr->data, pstr->len);
+
+                       result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFWPADATA,
+                               (UINT8 *) &wpa, sizeof(wpa));
+               }
+               break;
+       }
+       default:
+               WLAN_LOG_ERROR("Unhandled DID 0x%08x\n", mib->did);
+       }
+
+       DBFEXIT;
+       return(0);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_authlist
+*
+* Get a copy of the list of authenticated stations.
+*
+* Arguments:
+*       priv     "priv" structure.
+*       list     List of authenticated stations.
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_authlist(
+hfa384x_t             *hw,
+prism2sta_authlist_t  *list)
+{
+       prism2sta_authlist_t  test;
+       int                   i;
+
+       DBFENTER;
+
+       /*
+       ** Note: The values in this record are changed by the interrupt
+       ** handler and therefore cannot be guaranteed to be stable while
+       ** they are being copied.  However, the interrupt handler will
+       ** take priority over this code.  Hence, if the same values are
+       ** copied twice, then we are ensured that the values have not
+       ** been changed.  If they have, then just try again.  Don't try
+       ** more than 10 times...the list of authenticated stations is
+       ** unlikely to be changing frequently enough that we can't get
+       ** a snapshot in 10 tries.  Don't try more than this so that we
+       ** don't risk locking-up for long periods of time.  If we still
+       ** haven't got the snapshot, then generate an error message and
+       ** return an empty list (since this is the only valid list that
+       ** we can guarentee).  This scheme for copying values is used in
+       ** order to prevent having to block the interrupt handler while
+       ** we copy the values.
+       */
+
+       for (i = 0; i < 10; i++) {
+               memcpy(list, &hw->authlist, sizeof(prism2sta_authlist_t));
+               memcpy(&test, &hw->authlist, sizeof(prism2sta_authlist_t));
+               if (memcmp(list, &test, sizeof(prism2sta_authlist_t)) == 0)
+                       break;
+       }
+
+       if (i >= 10) {
+               list->cnt = 0;
+               WLAN_LOG_ERROR("Could not obtain snapshot of authenticated stations.\n");
+               }
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_accessmode
+*
+* Set the Access Mode.
+*
+* Arguments:
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       mode     New access mode.
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_accessmode(
+hfa384x_t         *hw,
+UINT32            mode)
+{
+       prism2sta_authlist_t  old;
+       int                   i, j, deauth;
+       UINT8                 *addr;
+
+       DBFENTER;
+
+       /*
+       ** If the mode is not changing or it is changing to "All", then it's
+       ** okay to go ahead without a lot of messing around.  Otherwise, the
+       ** access mode is changing in a way that may leave some stations
+       ** authenticated which should not be authenticated.  It will be
+       ** necessary to de-authenticate these stations.
+       */
+
+       if (mode == WLAN_ACCESS_ALL || mode == hw->accessmode) {
+               hw->accessmode = mode;
+               return;
+       }
+
+       /*
+       ** Switch to the new access mode.  Once this is done, then the interrupt
+       ** handler (which uses this value) will be prevented from authenticating
+       ** ADDITIONAL stations which should not be authenticated.  Then get a
+       ** copy of the current list of authenticated stations.
+       */
+
+       hw->accessmode = mode;
+
+       prism2mib_priv_authlist(hw, &old);
+
+       /*
+       ** Now go through the list of previously authenticated stations (some
+       ** of which might de-authenticate themselves while we are processing it
+       ** but that is okay).  Any station which no longer matches the access
+       ** mode, must be de-authenticated.
+       */
+
+       for (i = 0; i < old.cnt; i++) {
+               addr = old.addr[i];
+
+               if (mode == WLAN_ACCESS_NONE)
+                       deauth = 1;
+               else {
+                       if (mode == WLAN_ACCESS_ALLOW) {
+                               for (j = 0; j < hw->allow.cnt; j++)
+                                       if (memcmp(addr, hw->allow.addr[j],
+                                                       WLAN_ADDR_LEN) == 0)
+                                               break;
+                               deauth = (j >= hw->allow.cnt);
+                       } else {
+                               for (j = 0; j < hw->deny.cnt; j++)
+                                       if (memcmp(addr, hw->deny.addr[j],
+                                                       WLAN_ADDR_LEN) == 0)
+                                               break;
+                               deauth = (j < hw->deny.cnt);
+                       }
+               }
+
+               if (deauth) prism2mib_priv_deauthenticate(hw, addr);
+       }
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_accessallow
+*
+* Change the list of allowed MAC addresses.
+*
+* Arguments:
+*       priv      "priv" structure.
+*       hw        "hw" structure.
+*       macarray  New array of MAC addresses.
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_accessallow(
+hfa384x_t         *hw,
+p80211macarray_t  *macarray)
+{
+       prism2sta_authlist_t  old;
+       int                   i, j;
+
+       DBFENTER;
+
+       /*
+       ** Change the access list.  Note that the interrupt handler may be in
+       ** the middle of using the access list!!!  Since the interrupt handler
+       ** will always have priority over this process and this is the only
+       ** process that will modify the list, this problem can be handled as
+       ** follows:
+       **
+       **    1. Set the "modify" flag.
+       **    2. Change the first copy of the list.
+       **    3. Clear the "modify" flag.
+       **    4. Change the backup copy of the list.
+       **
+       ** The interrupt handler will check the "modify" flag.  If NOT set, then
+       ** the first copy of the list is valid and may be used.  Otherwise, the
+       ** first copy is being changed but the backup copy is valid and may be
+       ** used.  Doing things this way prevents having to have the interrupt
+       ** handler block while the list is being updated.
+       */
+
+       hw->allow.modify = 1;
+
+       hw->allow.cnt = macarray->cnt;
+       memcpy(hw->allow.addr, macarray->data, macarray->cnt*WLAN_ADDR_LEN);
+
+       hw->allow.modify = 0;
+
+       hw->allow.cnt1 = macarray->cnt;
+       memcpy(hw->allow.addr1, macarray->data, macarray->cnt*WLAN_ADDR_LEN);
+
+       /*
+       ** If the current access mode is "Allow", then changing the access
+       ** list may leave some stations authenticated which should not be
+       ** authenticated.  It will be necessary to de-authenticate these
+       ** stations.  Otherwise, the list can be changed without a lot of fuss.
+       */
+
+       if (hw->accessmode == WLAN_ACCESS_ALLOW) {
+
+               /*
+               ** Go through the list of authenticated stations (some of
+               ** which might de-authenticate themselves while we are
+               ** processing it but that is okay).  Any station which is
+               ** no longer in the list of allowed stations, must be
+               ** de-authenticated.
+               */
+
+               prism2mib_priv_authlist(hw, &old);
+
+               for (i = 0; i < old.cnt; i++) {
+                       for (j = 0; j < hw->allow.cnt; j++)
+                               if (memcmp(old.addr[i], hw->allow.addr[j],
+                                                       WLAN_ADDR_LEN) == 0)
+                                       break;
+                       if (j >= hw->allow.cnt)
+                               prism2mib_priv_deauthenticate(hw, old.addr[i]);
+               }
+       }
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_accessdeny
+*
+* Change the list of denied MAC addresses.
+*
+* Arguments:
+*       priv      "priv" structure.
+*       hw        "hw" structure.
+*       macarray  New array of MAC addresses.
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_accessdeny(
+hfa384x_t         *hw,
+p80211macarray_t  *macarray)
+{
+       prism2sta_authlist_t  old;
+       int                   i, j;
+
+       DBFENTER;
+
+       /*
+       ** Change the access list.  Note that the interrupt handler may be in
+       ** the middle of using the access list!!!  Since the interrupt handler
+       ** will always have priority over this process and this is the only
+       ** process that will modify the list, this problem can be handled as
+       ** follows:
+       **
+       **    1. Set the "modify" flag.
+       **    2. Change the first copy of the list.
+       **    3. Clear the "modify" flag.
+       **    4. Change the backup copy of the list.
+       **
+       ** The interrupt handler will check the "modify" flag.  If NOT set, then
+       ** the first copy of the list is valid and may be used.  Otherwise, the
+       ** first copy is being changed but the backup copy is valid and may be
+       ** used.  Doing things this way prevents having to have the interrupt
+       ** handler block while the list is being updated.
+       */
+
+       hw->deny.modify = 1;
+
+       hw->deny.cnt = macarray->cnt;
+       memcpy(hw->deny.addr, macarray->data, macarray->cnt*WLAN_ADDR_LEN);
+
+       hw->deny.modify = 0;
+
+       hw->deny.cnt1 = macarray->cnt;
+       memcpy(hw->deny.addr1, macarray->data, macarray->cnt*WLAN_ADDR_LEN);
+
+       /*
+       ** If the current access mode is "Deny", then changing the access
+       ** list may leave some stations authenticated which should not be
+       ** authenticated.  It will be necessary to de-authenticate these
+       ** stations.  Otherwise, the list can be changed without a lot of fuss.
+       */
+
+       if (hw->accessmode == WLAN_ACCESS_DENY) {
+
+               /*
+               ** Go through the list of authenticated stations (some of
+               ** which might de-authenticate themselves while we are
+               ** processing it but that is okay).  Any station which is
+               ** now in the list of denied stations, must be de-authenticated.
+               */
+
+               prism2mib_priv_authlist(hw, &old);
+
+               for (i = 0; i < old.cnt; i++)
+                       for (j = 0; j < hw->deny.cnt; j++)
+                               if (memcmp(old.addr[i], hw->deny.addr[j],
+                                                        WLAN_ADDR_LEN) == 0) {
+                                       prism2mib_priv_deauthenticate(hw, old.addr[i]);
+                                       break;
+                               }
+       }
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_deauthenticate
+*
+* De-authenticate a station.  This is done by sending a HandoverAddress
+* information frame to the firmware.  This should work, according to
+* Intersil.
+*
+* Arguments:
+*       priv     "priv" structure.
+*       hw       "hw" structure.
+*       addr     MAC address of station to be de-authenticated.
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_deauthenticate(
+hfa384x_t         *hw,
+UINT8             *addr)
+{
+       DBFENTER;
+       hfa384x_drvr_handover(hw, addr);
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_pstr2bytestr
+*
+* Convert the pstr data in the WLAN message structure into an hfa384x
+* byte string format.
+*
+* Arguments:
+*      bytestr         hfa384x byte string data type
+*      pstr            wlan message data
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
+{
+       DBFENTER;
+
+       bytestr->len = host2hfa384x_16((UINT16)(pstr->len));
+       memcpy(bytestr->data, pstr->data, pstr->len);
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_pstr2bytearea
+*
+* Convert the pstr data in the WLAN message structure into an hfa384x
+* byte area format.
+*
+* Arguments:
+*      bytearea        hfa384x byte area data type
+*      pstr            wlan message data
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_pstr2bytearea(UINT8 *bytearea, p80211pstrd_t *pstr)
+{
+       DBFENTER;
+
+       memcpy(bytearea, pstr->data, pstr->len);
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_bytestr2pstr
+*
+* Convert the data in an hfa384x byte string format into a
+* pstr in the WLAN message.
+*
+* Arguments:
+*      bytestr         hfa384x byte string data type
+*      msg             wlan message
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
+{
+       DBFENTER;
+
+       pstr->len = (UINT8)(hfa384x2host_16((UINT16)(bytestr->len)));
+       memcpy(pstr->data, bytestr->data, pstr->len);
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_bytearea2pstr
+*
+* Convert the data in an hfa384x byte area format into a pstr
+* in the WLAN message.
+*
+* Arguments:
+*      bytearea        hfa384x byte area data type
+*      msg             wlan message
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_bytearea2pstr(UINT8 *bytearea, p80211pstrd_t *pstr, int len)
+{
+       DBFENTER;
+
+       pstr->len = (UINT8)len;
+       memcpy(pstr->data, bytearea, len);
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_prism2int2p80211int
+*
+* Convert an hfa384x integer into a wlan integer
+*
+* Arguments:
+*      prism2enum      pointer to hfa384x integer
+*      wlanenum        pointer to p80211 integer
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_prism2int2p80211int(UINT16 *prism2int, UINT32 *wlanint)
+{
+       DBFENTER;
+
+       *wlanint = (UINT32)hfa384x2host_16(*prism2int);
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_p80211int2prism2int
+*
+* Convert a wlan integer into an hfa384x integer
+*
+* Arguments:
+*      prism2enum      pointer to hfa384x integer
+*      wlanenum        pointer to p80211 integer
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_p80211int2prism2int(UINT16 *prism2int, UINT32 *wlanint)
+{
+       DBFENTER;
+
+       *prism2int = host2hfa384x_16((UINT16)(*wlanint));
+       DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_prism2enum2p80211enum
+*
+* Convert the hfa384x enumerated int into a p80211 enumerated int
+*
+* Arguments:
+*      prism2enum      pointer to hfa384x integer
+*      wlanenum        pointer to p80211 integer
+*      rid             hfa384x record id
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_prism2enum2p80211enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid)
+{
+       DBFENTER;
+
+       /* At the moment, the need for this functionality hasn't
+       presented itself. All the wlan enumerated values are
+       a 1-to-1 match against the Prism2 enumerated values*/
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_p80211enum2prism2enum
+*
+* Convert the p80211 enumerated int into an hfa384x enumerated int
+*
+* Arguments:
+*      prism2enum      pointer to hfa384x integer
+*      wlanenum        pointer to p80211 integer
+*      rid             hfa384x record id
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_p80211enum2prism2enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid)
+{
+       DBFENTER;
+
+       /* At the moment, the need for this functionality hasn't
+       presented itself. All the wlan enumerated values are
+       a 1-to-1 match against the Prism2 enumerated values*/
+       DBFEXIT;
+       return;
+}
+
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_get_oprateset
+*
+* Convert the hfa384x bit area into a wlan octet string.
+*
+* Arguments:
+*      rate            Prism2 bit area
+*      pstr            wlan octet string
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_get_oprateset(UINT16 *rate, p80211pstrd_t *pstr)
+{
+       UINT8   len;
+       UINT8   *datarate;
+
+       DBFENTER;
+
+       len = 0;
+       datarate = pstr->data;
+
+       /* 1 Mbps */
+       if ( BIT0 & (*rate) ) {
+               len += (UINT8)1;
+               *datarate = (UINT8)2;
+               datarate++;
+       }
+
+       /* 2 Mbps */
+       if ( BIT1 & (*rate) ) {
+               len += (UINT8)1;
+               *datarate = (UINT8)4;
+               datarate++;
+       }
+
+       /* 5.5 Mbps */
+       if ( BIT2 & (*rate) ) {
+               len += (UINT8)1;
+               *datarate = (UINT8)11;
+               datarate++;
+       }
+
+       /* 11 Mbps */
+       if ( BIT3 & (*rate) ) {
+               len += (UINT8)1;
+               *datarate = (UINT8)22;
+               datarate++;
+       }
+
+       pstr->len = len;
+
+       DBFEXIT;
+       return;
+}
+
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_set_oprateset
+*
+* Convert the wlan octet string into an hfa384x bit area.
+*
+* Arguments:
+*      rate            Prism2 bit area
+*      pstr            wlan octet string
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_set_oprateset(UINT16 *rate, p80211pstrd_t *pstr)
+{
+       UINT8   *datarate;
+       int     i;
+
+       DBFENTER;
+
+       *rate = 0;
+
+       datarate = pstr->data;
+
+       for ( i=0; i < pstr->len; i++, datarate++ ) {
+               switch (*datarate) {
+               case 2: /* 1 Mbps */
+                       *rate |= BIT0;
+                       break;
+               case 4: /* 2 Mbps */
+                       *rate |= BIT1;
+                       break;
+               case 11: /* 5.5 Mbps */
+                       *rate |= BIT2;
+                       break;
+               case 22: /* 11 Mbps */
+                       *rate |= BIT3;
+                       break;
+               default:
+                       WLAN_LOG_DEBUG(1, "Unrecoginzed Rate of %d\n",
+                               *datarate);
+                       break;
+               }
+       }
+
+       DBFEXIT;
+       return;
+}
+
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_get_grpaddr
+*
+* Retrieves a particular group address from the list of
+* group addresses.
+*
+* Arguments:
+*      did             mibitem did
+*      pstr            wlan octet string
+*      priv            prism2 driver private data structure
+*
+* Returns:
+*      Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_get_grpaddr(UINT32 did, p80211pstrd_t *pstr,
+       hfa384x_t *hw )
+{
+       int     index;
+
+       DBFENTER;
+
+       index = prism2mgmt_get_grpaddr_index(did);
+
+       if ( index >= 0 ) {
+               pstr->len = WLAN_ADDR_LEN;
+               memcpy(pstr->data, hw->dot11_grp_addr[index],
+                       WLAN_ADDR_LEN);
+       }
+
+       DBFEXIT;
+       return;
+}
+
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_set_grpaddr
+*
+* Convert the wlan octet string into an hfa384x bit area.
+*
+* Arguments:
+*      did             mibitem did
+*      buf
+*      groups
+*
+* Returns:
+*      0       Success
+*      !0      Error
+*
+----------------------------------------------------------------*/
+int prism2mgmt_set_grpaddr(UINT32 did, UINT8 *prism2buf,
+       p80211pstrd_t *pstr, hfa384x_t *hw )
+{
+       UINT8   no_addr[WLAN_ADDR_LEN];
+       int     index;
+
+       DBFENTER;
+
+       memset(no_addr, 0, WLAN_ADDR_LEN);
+       if (memcmp(no_addr, pstr->data, WLAN_ADDR_LEN) != 0) {
+
+               /*
+               ** The address is NOT 0 so we are "adding" an address to the
+               ** group address list.  Check to make sure we aren't trying
+               ** to add more than the maximum allowed number of group
+               ** addresses in the list.  The new address is added to the
+               ** end of the list regardless of the DID used to add the
+               ** address.
+               */
+
+               if (hw->dot11_grpcnt >= MAX_GRP_ADDR) return(-1);
+
+               memcpy(hw->dot11_grp_addr[hw->dot11_grpcnt], pstr->data,
+                                                                WLAN_ADDR_LEN);
+               hw->dot11_grpcnt += 1;
+       } else {
+
+               /*
+               ** The address is 0.  Interpret this as "deleting" an address
+               ** from the group address list.  Get the address index from
+               ** the DID.  If this is within the range of used addresses,
+               ** then delete the specified address by shifting all following
+               ** addresses down.  Then clear the last address (which should
+               ** now be unused).  If the address index is NOT within the
+               ** range of used addresses, then just ignore the address.
+               */
+
+               index = prism2mgmt_get_grpaddr_index(did);
+               if (index >= 0 && index < hw->dot11_grpcnt) {
+                       hw->dot11_grpcnt -= 1;
+                       memmove(hw->dot11_grp_addr[index],
+                               hw->dot11_grp_addr[index + 1],
+                               ((hw->dot11_grpcnt)-index) * WLAN_ADDR_LEN);
+                       memset(hw->dot11_grp_addr[hw->dot11_grpcnt], 0,
+                                                                WLAN_ADDR_LEN);
+               }
+       }
+
+       DBFEXIT;
+       return(0);
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_get_grpaddr_index
+*
+* Gets the index in the group address list based on the did.
+*
+* Arguments:
+*      did             mibitem did
+*
+* Returns:
+*      >= 0    If valid did
+*      < 0     If not valid did
+*
+----------------------------------------------------------------*/
+int prism2mgmt_get_grpaddr_index( UINT32 did )
+{
+       int     index;
+
+       DBFENTER;
+
+       index = -1;
+
+       switch (did) {
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1:
+               index = 0;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2:
+               index = 1;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3:
+               index = 2;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4:
+               index = 3;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5:
+               index = 4;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6:
+               index = 5;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7:
+               index = 6;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8:
+               index = 7;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9:
+               index = 8;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10:
+               index = 9;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11:
+               index = 10;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12:
+               index = 11;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13:
+               index = 12;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14:
+               index = 13;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15:
+               index = 14;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16:
+               index = 15;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17:
+               index = 16;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18:
+               index = 17;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19:
+               index = 18;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20:
+               index = 19;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21:
+               index = 20;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22:
+               index = 21;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23:
+               index = 22;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24:
+               index = 23;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25:
+               index = 24;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26:
+               index = 25;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27:
+               index = 26;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28:
+               index = 27;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29:
+               index = 28;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30:
+               index = 29;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31:
+               index = 30;
+               break;
+       case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32:
+               index = 31;
+               break;
+       }
+
+       DBFEXIT;
+       return index;
+}
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
new file mode 100644 (file)
index 0000000..18aa15f
--- /dev/null
@@ -0,0 +1,2502 @@
+/* src/prism2/driver/prism2sta.c
+*
+* Implements the station functionality for prism2
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file implements the module and linux pcmcia routines for the
+* prism2 driver.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+#define WLAN_DBVAR     prism2_debug
+
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25))
+#include <linux/moduleparam.h>
+#endif
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include <linux/tqueue.h>
+#else
+#include <linux/workqueue.h>
+#endif
+
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <linux/if_arp.h>
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/cisreg.h>
+#endif
+
+#include "wlan_compat.h"
+
+#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI))
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#endif
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211req.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+/*================================================================*/
+/* Local Macros */
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#define DRIVER_SUFFIX  "_cs"
+#elif (WLAN_HOSTIF == WLAN_PLX)
+#define DRIVER_SUFFIX  "_plx"
+typedef char* dev_info_t;
+#elif (WLAN_HOSTIF == WLAN_PCI)
+#define DRIVER_SUFFIX  "_pci"
+typedef char* dev_info_t;
+#elif (WLAN_HOSTIF == WLAN_USB)
+#define DRIVER_SUFFIX  "_usb"
+typedef char* dev_info_t;
+#else
+#error "HOSTIF unsupported or undefined!"
+#endif
+
+static char            *version = "prism2" DRIVER_SUFFIX ".o: " WLAN_RELEASE;
+static dev_info_t      dev_info = "prism2" DRIVER_SUFFIX;
+
+#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI)
+#ifdef CONFIG_PM
+static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state);
+static int prism2sta_resume_pci(struct pci_dev *pdev);
+#endif
+#endif
+
+#if (WLAN_HOSTIF == WLAN_PCI)
+
+#endif /* WLAN_PCI */
+
+static wlandevice_t *create_wlan(void);
+
+/*----------------------------------------------------------------*/
+/* --Module Parameters */
+
+int      prism2_reset_holdtime=30;     /* Reset hold time in ms */
+int     prism2_reset_settletime=100;   /* Reset settle time in ms */
+
+#if (WLAN_HOSTIF == WLAN_USB)
+static int     prism2_doreset=0;               /* Do a reset at init? */
+#else
+static int      prism2_doreset=1;              /* Do a reset at init? */
+int             prism2_bap_timeout=1000;        /* BAP timeout */
+int            prism2_irq_evread_max=20;       /* Maximum number of
+                                                * ev_reads (loops)
+                                                * in irq handler
+                                                */
+#endif
+
+#ifdef WLAN_INCLUDE_DEBUG
+int prism2_debug=0;
+module_param( prism2_debug, int, 0644);
+MODULE_PARM_DESC(prism2_debug, "prism2 debugging");
+#endif
+
+module_param( prism2_doreset, int, 0644);
+MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization");
+
+module_param( prism2_reset_holdtime, int, 0644);
+MODULE_PARM_DESC( prism2_reset_holdtime, "reset hold time in ms");
+module_param( prism2_reset_settletime, int, 0644);
+MODULE_PARM_DESC( prism2_reset_settletime, "reset settle time in ms");
+
+#if (WLAN_HOSTIF != WLAN_USB)
+module_param( prism2_bap_timeout, int, 0644);
+MODULE_PARM_DESC(prism2_bap_timeout, "BufferAccessPath Timeout in 10*n us");
+module_param( prism2_irq_evread_max, int, 0644);
+MODULE_PARM_DESC( prism2_irq_evread_max, "Maximim number of event reads in interrupt handler");
+#endif
+
+MODULE_LICENSE("Dual MPL/GPL");
+
+/*================================================================*/
+/* Local Function Declarations */
+
+static int     prism2sta_open(wlandevice_t *wlandev);
+static int     prism2sta_close(wlandevice_t *wlandev);
+static void    prism2sta_reset(wlandevice_t *wlandev );
+static int      prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+static int     prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg);
+static int     prism2sta_getcardinfo(wlandevice_t *wlandev);
+static int     prism2sta_globalsetup(wlandevice_t *wlandev);
+static int      prism2sta_setmulticast(wlandevice_t *wlandev,
+                                      netdevice_t *dev);
+
+static void    prism2sta_inf_handover(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void    prism2sta_inf_tallies(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void     prism2sta_inf_hostscanresults(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void    prism2sta_inf_scanresults(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void    prism2sta_inf_chinforesults(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void    prism2sta_inf_linkstatus(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void    prism2sta_inf_assocstatus(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void    prism2sta_inf_authreq(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void    prism2sta_inf_authreq_defer(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void    prism2sta_inf_psusercnt(
+                       wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+
+#ifdef CONFIG_PROC_FS
+static int
+prism2sta_proc_read(
+       char    *page,
+       char    **start,
+       off_t   offset,
+       int     count,
+       int     *eof,
+       void    *data);
+#endif
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* dmpmem
+*
+* Debug utility function to dump memory to the kernel debug log.
+*
+* Arguments:
+*      buf     ptr data we want dumped
+*      len     length of data
+*
+* Returns:
+*      nothing
+* Side effects:
+*
+* Call context:
+*      process thread
+*      interrupt
+----------------------------------------------------------------*/
+inline void dmpmem(void *buf, int n)
+{
+       int c;
+       for ( c= 0; c < n; c++) {
+               if ( (c % 16) == 0 ) printk(KERN_DEBUG"dmp[%d]: ", c);
+               printk("%02x ", ((UINT8*)buf)[c]);
+               if ( (c % 16) == 15 ) printk("\n");
+       }
+       if ( (c % 16) != 0 ) printk("\n");
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_open
+*
+* WLAN device open method.  Called from p80211netdev when kernel
+* device open (start) method is called in response to the
+* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
+* from clear to set.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      0       success
+*      >0      f/w reported error
+*      <0      driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+static int prism2sta_open(wlandevice_t *wlandev)
+{
+       DBFENTER;
+
+#ifdef ANCIENT_MODULE_CODE
+       MOD_INC_USE_COUNT;
+#endif
+
+       /* We don't currently have to do anything else.
+        * The setup of the MAC should be subsequently completed via
+        * the mlme commands.
+        * Higher layers know we're ready from dev->start==1 and
+        * dev->tbusy==0.  Our rx path knows to pass up received/
+        * frames because of dev->flags&IFF_UP is true.
+        */
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_close
+*
+* WLAN device close method.  Called from p80211netdev when kernel
+* device close method is called in response to the
+* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
+* from set to clear.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      0       success
+*      >0      f/w reported error
+*      <0      driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+static int prism2sta_close(wlandevice_t *wlandev)
+{
+       DBFENTER;
+
+#ifdef ANCIENT_MODULE_CODE
+       MOD_DEC_USE_COUNT;
+#endif
+
+       /* We don't currently have to do anything else.
+        * Higher layers know we're not ready from dev->start==0 and
+        * dev->tbusy==1.  Our rx path knows to not pass up received
+        * frames because of dev->flags&IFF_UP is false.
+        */
+
+       DBFEXIT;
+       return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_reset
+*
+* Not currently implented.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      none
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+static void prism2sta_reset(wlandevice_t *wlandev )
+{
+       DBFENTER;
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_txframe
+*
+* Takes a frame from p80211 and queues it for transmission.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      pb              packet buffer struct.  Contains an 802.11
+*                      data frame.
+*       p80211_hdr      points to the 802.11 header for the packet.
+* Returns:
+*      0               Success and more buffs available
+*      1               Success but no more buffs
+*      2               Allocation failure
+*      4               Buffer full or queue busy
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
+                            p80211_hdr_t *p80211_hdr,
+                            p80211_metawep_t *p80211_wep)
+{
+       hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       int                     result;
+       DBFENTER;
+
+       /* If necessary, set the 802.11 WEP bit */
+       if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == HOSTWEP_PRIVACYINVOKED) {
+               p80211_hdr->a3.fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
+       }
+
+       result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep);
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_mlmerequest
+*
+* wlan command message handler.  All we do here is pass the message
+* over to the prism2sta_mgmt_handler.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msg             wlan command message
+* Returns:
+*      0               success
+*      <0              successful acceptance of message, but we're
+*                      waiting for an async process to finish before
+*                      we're done with the msg.  When the asynch
+*                      process is done, we'll call the p80211
+*                      function p80211req_confirm() .
+*      >0              An error occurred while we were handling
+*                      the message.
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+
+       int result = 0;
+       DBFENTER;
+
+       switch( msg->msgcode )
+       {
+       case DIDmsg_dot11req_mibget :
+               WLAN_LOG_DEBUG(2,"Received mibget request\n");
+               result = prism2mgmt_mibset_mibget(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_mibset :
+               WLAN_LOG_DEBUG(2,"Received mibset request\n");
+               result = prism2mgmt_mibset_mibget(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_powermgmt :
+               WLAN_LOG_DEBUG(2,"Received powermgmt request\n");
+               result = prism2mgmt_powermgmt(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_scan :
+               WLAN_LOG_DEBUG(2,"Received scan request\n");
+               result = prism2mgmt_scan(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_scan_results :
+               WLAN_LOG_DEBUG(2,"Received scan_results request\n");
+               result = prism2mgmt_scan_results(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_join :
+               WLAN_LOG_DEBUG(2,"Received join request\n");
+               result = prism2mgmt_join(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_authenticate :
+               WLAN_LOG_DEBUG(2,"Received authenticate request\n");
+               result = prism2mgmt_authenticate(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_deauthenticate :
+               WLAN_LOG_DEBUG(2,"Received mlme deauthenticate request\n");
+               result = prism2mgmt_deauthenticate(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_associate :
+               WLAN_LOG_DEBUG(2,"Received mlme associate request\n");
+               result = prism2mgmt_associate(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_reassociate :
+               WLAN_LOG_DEBUG(2,"Received mlme reassociate request\n");
+               result = prism2mgmt_reassociate(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_disassociate :
+               WLAN_LOG_DEBUG(2,"Received mlme disassociate request\n");
+               result = prism2mgmt_disassociate(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_reset :
+               WLAN_LOG_DEBUG(2,"Received mlme reset request\n");
+               result = prism2mgmt_reset(wlandev, msg);
+               break;
+       case DIDmsg_dot11req_start :
+               WLAN_LOG_DEBUG(2,"Received mlme start request\n");
+               result = prism2mgmt_start(wlandev, msg);
+               break;
+       /*
+        * Prism2 specific messages
+        */
+       case DIDmsg_p2req_join :
+               WLAN_LOG_DEBUG(2,"Received p2 join request\n");
+               result = prism2mgmt_p2_join(wlandev, msg);
+               break;
+               case DIDmsg_p2req_readpda :
+               WLAN_LOG_DEBUG(2,"Received mlme readpda request\n");
+               result = prism2mgmt_readpda(wlandev, msg);
+               break;
+       case DIDmsg_p2req_readcis :
+               WLAN_LOG_DEBUG(2,"Received mlme readcis request\n");
+               result = prism2mgmt_readcis(wlandev, msg);
+               break;
+       case DIDmsg_p2req_auxport_state :
+               WLAN_LOG_DEBUG(2,"Received mlme auxport_state request\n");
+               result = prism2mgmt_auxport_state(wlandev, msg);
+               break;
+       case DIDmsg_p2req_auxport_read :
+               WLAN_LOG_DEBUG(2,"Received mlme auxport_read request\n");
+               result = prism2mgmt_auxport_read(wlandev, msg);
+               break;
+       case DIDmsg_p2req_auxport_write :
+               WLAN_LOG_DEBUG(2,"Received mlme auxport_write request\n");
+               result = prism2mgmt_auxport_write(wlandev, msg);
+               break;
+       case DIDmsg_p2req_low_level :
+               WLAN_LOG_DEBUG(2,"Received mlme low_level request\n");
+               result = prism2mgmt_low_level(wlandev, msg);
+               break;
+        case DIDmsg_p2req_test_command :
+                WLAN_LOG_DEBUG(2,"Received mlme test_command request\n");
+                result = prism2mgmt_test_command(wlandev, msg);
+                break;
+        case DIDmsg_p2req_mmi_read :
+                WLAN_LOG_DEBUG(2,"Received mlme mmi_read request\n");
+                result = prism2mgmt_mmi_read(wlandev, msg);
+                break;
+        case DIDmsg_p2req_mmi_write :
+                WLAN_LOG_DEBUG(2,"Received mlme mmi_write request\n");
+                result = prism2mgmt_mmi_write(wlandev, msg);
+                break;
+       case DIDmsg_p2req_ramdl_state :
+               WLAN_LOG_DEBUG(2,"Received mlme ramdl_state request\n");
+               result = prism2mgmt_ramdl_state(wlandev, msg);
+               break;
+       case DIDmsg_p2req_ramdl_write :
+               WLAN_LOG_DEBUG(2,"Received mlme ramdl_write request\n");
+               result = prism2mgmt_ramdl_write(wlandev, msg);
+               break;
+       case DIDmsg_p2req_flashdl_state :
+               WLAN_LOG_DEBUG(2,"Received mlme flashdl_state request\n");
+               result = prism2mgmt_flashdl_state(wlandev, msg);
+               break;
+       case DIDmsg_p2req_flashdl_write :
+               WLAN_LOG_DEBUG(2,"Received mlme flashdl_write request\n");
+               result = prism2mgmt_flashdl_write(wlandev, msg);
+               break;
+       case DIDmsg_p2req_dump_state :
+               WLAN_LOG_DEBUG(2,"Received mlme dump_state request\n");
+               result = prism2mgmt_dump_state(wlandev, msg);
+               break;
+       case DIDmsg_p2req_channel_info :
+               WLAN_LOG_DEBUG(2,"Received mlme channel_info request\n");
+               result = prism2mgmt_channel_info(wlandev, msg);
+               break;
+       case DIDmsg_p2req_channel_info_results :
+               WLAN_LOG_DEBUG(2,"Received mlme channel_info_results request\n");
+               result = prism2mgmt_channel_info_results(wlandev, msg);
+               break;
+       /*
+        * Linux specific messages
+        */
+       case DIDmsg_lnxreq_hostwep :
+               break;   // ignore me.
+        case DIDmsg_lnxreq_ifstate :
+               {
+               p80211msg_lnxreq_ifstate_t      *ifstatemsg;
+                WLAN_LOG_DEBUG(2,"Received mlme ifstate request\n");
+               ifstatemsg = (p80211msg_lnxreq_ifstate_t*)msg;
+                result = prism2sta_ifstate(wlandev, ifstatemsg->ifstate.data);
+               ifstatemsg->resultcode.status =
+                       P80211ENUM_msgitem_status_data_ok;
+               ifstatemsg->resultcode.data = result;
+               result = 0;
+               }
+                break;
+        case DIDmsg_lnxreq_wlansniff :
+                WLAN_LOG_DEBUG(2,"Received mlme wlansniff request\n");
+                result = prism2mgmt_wlansniff(wlandev, msg);
+                break;
+       case DIDmsg_lnxreq_autojoin :
+               WLAN_LOG_DEBUG(2,"Received mlme autojoin request\n");
+               result = prism2mgmt_autojoin(wlandev, msg);
+               break;
+       case DIDmsg_p2req_enable :
+               WLAN_LOG_DEBUG(2,"Received mlme enable request\n");
+               result = prism2mgmt_enable(wlandev, msg);
+               break;
+       case DIDmsg_lnxreq_commsquality: {
+               p80211msg_lnxreq_commsquality_t *qualmsg;
+
+               WLAN_LOG_DEBUG(2,"Received commsquality request\n");
+
+               if (hw->ap)
+                       break;
+
+               qualmsg = (p80211msg_lnxreq_commsquality_t*) msg;
+
+               qualmsg->link.status = P80211ENUM_msgitem_status_data_ok;
+               qualmsg->level.status = P80211ENUM_msgitem_status_data_ok;
+               qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok;
+
+
+               qualmsg->link.data = hfa384x2host_16(hw->qual.CQ_currBSS);
+               qualmsg->level.data = hfa384x2host_16(hw->qual.ASL_currBSS);
+               qualmsg->noise.data = hfa384x2host_16(hw->qual.ANL_currFC);
+
+               break;
+       }
+       default:
+               WLAN_LOG_WARNING("Unknown mgmt request message 0x%08x", msg->msgcode);
+               break;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ifstate
+*
+* Interface state.  This is the primary WLAN interface enable/disable
+* handler.  Following the driver/load/deviceprobe sequence, this
+* function must be called with a state of "enable" before any other
+* commands will be accepted.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      A p80211 message resultcode value.
+*
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+UINT32 prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       UINT32                  result;
+       DBFENTER;
+
+       result = P80211ENUM_resultcode_implementation_failure;
+
+       WLAN_LOG_DEBUG(2, "Current MSD state(%d), requesting(%d)\n",
+                         wlandev->msdstate, ifstate);
+       switch (ifstate)
+       {
+       case P80211ENUM_ifstate_fwload:
+               switch (wlandev->msdstate) {
+               case WLAN_MSD_HWPRESENT:
+                       wlandev->msdstate = WLAN_MSD_FWLOAD_PENDING;
+                       /*
+                        * Initialize the device+driver sufficiently
+                        * for firmware loading.
+                        */
+#if (WLAN_HOSTIF != WLAN_USB)
+                       result=hfa384x_cmd_initialize(hw);
+#else
+                       if ((result=hfa384x_drvr_start(hw))) {
+                               WLAN_LOG_ERROR(
+                                       "hfa384x_drvr_start() failed,"
+                                       "result=%d\n", (int)result);
+                               result =
+                               P80211ENUM_resultcode_implementation_failure;
+                               wlandev->msdstate = WLAN_MSD_HWPRESENT;
+                               break;
+                       }
+#endif
+                       wlandev->msdstate = WLAN_MSD_FWLOAD;
+                       result = P80211ENUM_resultcode_success;
+                       break;
+               case WLAN_MSD_FWLOAD:
+                       hfa384x_cmd_initialize(hw);
+                       result = P80211ENUM_resultcode_success;
+                       break;
+               case WLAN_MSD_RUNNING:
+                       WLAN_LOG_WARNING(
+                               "Cannot enter fwload state from enable state,"
+                               "you must disable first.\n");
+                       result = P80211ENUM_resultcode_invalid_parameters;
+                       break;
+               case WLAN_MSD_HWFAIL:
+               default:
+                       /* probe() had a problem or the msdstate contains
+                        * an unrecognized value, there's nothing we can do.
+                        */
+                       result = P80211ENUM_resultcode_implementation_failure;
+                       break;
+               }
+               break;
+       case P80211ENUM_ifstate_enable:
+               switch (wlandev->msdstate) {
+               case WLAN_MSD_HWPRESENT:
+               case WLAN_MSD_FWLOAD:
+                       wlandev->msdstate = WLAN_MSD_RUNNING_PENDING;
+                       /* Initialize the device+driver for full
+                        * operation. Note that this might me an FWLOAD to
+                        * to RUNNING transition so we must not do a chip
+                        * or board level reset.  Note that on failure,
+                        * the MSD state is set to HWPRESENT because we
+                        * can't make any assumptions about the state
+                        * of the hardware or a previous firmware load.
+                        */
+                       if ((result=hfa384x_drvr_start(hw))) {
+                               WLAN_LOG_ERROR(
+                                       "hfa384x_drvr_start() failed,"
+                                       "result=%d\n", (int)result);
+                               result =
+                               P80211ENUM_resultcode_implementation_failure;
+                               wlandev->msdstate = WLAN_MSD_HWPRESENT;
+                               break;
+                       }
+
+                       if ((result=prism2sta_getcardinfo(wlandev))) {
+                               WLAN_LOG_ERROR(
+                                       "prism2sta_getcardinfo() failed,"
+                                       "result=%d\n", (int)result);
+                               result =
+                               P80211ENUM_resultcode_implementation_failure;
+                               hfa384x_drvr_stop(hw);
+                               wlandev->msdstate = WLAN_MSD_HWPRESENT;
+                               break;
+                       }
+                       if ((result=prism2sta_globalsetup(wlandev))) {
+                               WLAN_LOG_ERROR(
+                                       "prism2sta_globalsetup() failed,"
+                                       "result=%d\n", (int)result);
+                               result =
+                               P80211ENUM_resultcode_implementation_failure;
+                               hfa384x_drvr_stop(hw);
+                               wlandev->msdstate = WLAN_MSD_HWPRESENT;
+                               break;
+                       }
+                       wlandev->msdstate = WLAN_MSD_RUNNING;
+                       hw->join_ap = 0;
+                       hw->join_retries = 60;
+                       result = P80211ENUM_resultcode_success;
+                       break;
+               case WLAN_MSD_RUNNING:
+                       /* Do nothing, we're already in this state.*/
+                       result = P80211ENUM_resultcode_success;
+                       break;
+               case WLAN_MSD_HWFAIL:
+               default:
+                       /* probe() had a problem or the msdstate contains
+                        * an unrecognized value, there's nothing we can do.
+                        */
+                       result = P80211ENUM_resultcode_implementation_failure;
+                       break;
+               }
+               break;
+       case P80211ENUM_ifstate_disable:
+               switch (wlandev->msdstate) {
+               case WLAN_MSD_HWPRESENT:
+                       /* Do nothing, we're already in this state.*/
+                       result = P80211ENUM_resultcode_success;
+                       break;
+               case WLAN_MSD_FWLOAD:
+               case WLAN_MSD_RUNNING:
+                       wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING;
+                       /*
+                        * TODO: Shut down the MAC completely. Here a chip
+                        * or board level reset is probably called for.
+                        * After a "disable" _all_ results are lost, even
+                        * those from a fwload.
+                        */
+                       if (!wlandev->hwremoved)
+                               netif_carrier_off(wlandev->netdev);
+
+                       hfa384x_drvr_stop(hw);
+
+                       wlandev->macmode = WLAN_MACMODE_NONE;
+                       wlandev->msdstate = WLAN_MSD_HWPRESENT;
+                       result = P80211ENUM_resultcode_success;
+                       break;
+               case WLAN_MSD_HWFAIL:
+               default:
+                       /* probe() had a problem or the msdstate contains
+                        * an unrecognized value, there's nothing we can do.
+                        */
+                       result = P80211ENUM_resultcode_implementation_failure;
+                       break;
+               }
+               break;
+       default:
+               result = P80211ENUM_resultcode_invalid_parameters;
+               break;
+       }
+
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_getcardinfo
+*
+* Collect the NICID, firmware version and any other identifiers
+* we'd like to have in host-side data structures.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      0       success
+*      >0      f/w reported error
+*      <0      driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      Either.
+----------------------------------------------------------------*/
+static int prism2sta_getcardinfo(wlandevice_t *wlandev)
+{
+       int                     result = 0;
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       UINT16                  temp;
+       UINT8                   snum[HFA384x_RID_NICSERIALNUMBER_LEN];
+       char                    pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
+
+       DBFENTER;
+
+       /* Collect version and compatibility info */
+       /*  Some are critical, some are not */
+       /* NIC identity */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY,
+                       &hw->ident_nic, sizeof(hfa384x_compident_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve NICIDENTITY\n");
+               goto failed;
+       }
+
+       /* get all the nic id fields in host byte order */
+       hw->ident_nic.id = hfa384x2host_16(hw->ident_nic.id);
+       hw->ident_nic.variant = hfa384x2host_16(hw->ident_nic.variant);
+       hw->ident_nic.major = hfa384x2host_16(hw->ident_nic.major);
+       hw->ident_nic.minor = hfa384x2host_16(hw->ident_nic.minor);
+
+       WLAN_LOG_INFO( "ident: nic h/w: id=0x%02x %d.%d.%d\n",
+                       hw->ident_nic.id, hw->ident_nic.major,
+                       hw->ident_nic.minor, hw->ident_nic.variant);
+
+       /* Primary f/w identity */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY,
+                       &hw->ident_pri_fw, sizeof(hfa384x_compident_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve PRIIDENTITY\n");
+               goto failed;
+       }
+
+       /* get all the private fw id fields in host byte order */
+       hw->ident_pri_fw.id = hfa384x2host_16(hw->ident_pri_fw.id);
+       hw->ident_pri_fw.variant = hfa384x2host_16(hw->ident_pri_fw.variant);
+       hw->ident_pri_fw.major = hfa384x2host_16(hw->ident_pri_fw.major);
+       hw->ident_pri_fw.minor = hfa384x2host_16(hw->ident_pri_fw.minor);
+
+       WLAN_LOG_INFO( "ident: pri f/w: id=0x%02x %d.%d.%d\n",
+                       hw->ident_pri_fw.id, hw->ident_pri_fw.major,
+                       hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
+
+       /* Station (Secondary?) f/w identity */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY,
+                       &hw->ident_sta_fw, sizeof(hfa384x_compident_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve STAIDENTITY\n");
+               goto failed;
+       }
+
+       if (hw->ident_nic.id < 0x8000) {
+               WLAN_LOG_ERROR("FATAL: Card is not an Intersil Prism2/2.5/3\n");
+               result = -1;
+               goto failed;
+       }
+
+       /* get all the station fw id fields in host byte order */
+       hw->ident_sta_fw.id = hfa384x2host_16(hw->ident_sta_fw.id);
+       hw->ident_sta_fw.variant = hfa384x2host_16(hw->ident_sta_fw.variant);
+       hw->ident_sta_fw.major = hfa384x2host_16(hw->ident_sta_fw.major);
+       hw->ident_sta_fw.minor = hfa384x2host_16(hw->ident_sta_fw.minor);
+
+       /* strip out the 'special' variant bits */
+       hw->mm_mods = hw->ident_sta_fw.variant & (BIT14 | BIT15);
+       hw->ident_sta_fw.variant &= ~((UINT16)(BIT14 | BIT15));
+
+       if  ( hw->ident_sta_fw.id == 0x1f ) {
+               hw->ap = 0;
+               WLAN_LOG_INFO(
+                       "ident: sta f/w: id=0x%02x %d.%d.%d\n",
+                       hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+                       hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+       } else {
+               hw->ap = 1;
+               WLAN_LOG_INFO(
+                       "ident:  ap f/w: id=0x%02x %d.%d.%d\n",
+                       hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+                       hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+       }
+
+       /* Compatibility range, Modem supplier */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE,
+                       &hw->cap_sup_mfi, sizeof(hfa384x_caplevel_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve MFISUPRANGE\n");
+               goto failed;
+       }
+
+       /* get all the Compatibility range, modem interface supplier
+       fields in byte order */
+       hw->cap_sup_mfi.role = hfa384x2host_16(hw->cap_sup_mfi.role);
+       hw->cap_sup_mfi.id = hfa384x2host_16(hw->cap_sup_mfi.id);
+       hw->cap_sup_mfi.variant = hfa384x2host_16(hw->cap_sup_mfi.variant);
+       hw->cap_sup_mfi.bottom = hfa384x2host_16(hw->cap_sup_mfi.bottom);
+       hw->cap_sup_mfi.top = hfa384x2host_16(hw->cap_sup_mfi.top);
+
+       WLAN_LOG_INFO(
+               "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+               hw->cap_sup_mfi.role, hw->cap_sup_mfi.id,
+               hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom,
+               hw->cap_sup_mfi.top);
+
+       /* Compatibility range, Controller supplier */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE,
+                       &hw->cap_sup_cfi, sizeof(hfa384x_caplevel_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve CFISUPRANGE\n");
+               goto failed;
+       }
+
+       /* get all the Compatibility range, controller interface supplier
+       fields in byte order */
+       hw->cap_sup_cfi.role = hfa384x2host_16(hw->cap_sup_cfi.role);
+       hw->cap_sup_cfi.id = hfa384x2host_16(hw->cap_sup_cfi.id);
+       hw->cap_sup_cfi.variant = hfa384x2host_16(hw->cap_sup_cfi.variant);
+       hw->cap_sup_cfi.bottom = hfa384x2host_16(hw->cap_sup_cfi.bottom);
+       hw->cap_sup_cfi.top = hfa384x2host_16(hw->cap_sup_cfi.top);
+
+       WLAN_LOG_INFO(
+               "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+               hw->cap_sup_cfi.role, hw->cap_sup_cfi.id,
+               hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom,
+               hw->cap_sup_cfi.top);
+
+       /* Compatibility range, Primary f/w supplier */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE,
+                       &hw->cap_sup_pri, sizeof(hfa384x_caplevel_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve PRISUPRANGE\n");
+               goto failed;
+       }
+
+       /* get all the Compatibility range, primary firmware supplier
+       fields in byte order */
+       hw->cap_sup_pri.role = hfa384x2host_16(hw->cap_sup_pri.role);
+       hw->cap_sup_pri.id = hfa384x2host_16(hw->cap_sup_pri.id);
+       hw->cap_sup_pri.variant = hfa384x2host_16(hw->cap_sup_pri.variant);
+       hw->cap_sup_pri.bottom = hfa384x2host_16(hw->cap_sup_pri.bottom);
+       hw->cap_sup_pri.top = hfa384x2host_16(hw->cap_sup_pri.top);
+
+       WLAN_LOG_INFO(
+               "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+               hw->cap_sup_pri.role, hw->cap_sup_pri.id,
+               hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom,
+               hw->cap_sup_pri.top);
+
+       /* Compatibility range, Station f/w supplier */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE,
+                       &hw->cap_sup_sta, sizeof(hfa384x_caplevel_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve STASUPRANGE\n");
+               goto failed;
+       }
+
+       /* get all the Compatibility range, station firmware supplier
+       fields in byte order */
+       hw->cap_sup_sta.role = hfa384x2host_16(hw->cap_sup_sta.role);
+       hw->cap_sup_sta.id = hfa384x2host_16(hw->cap_sup_sta.id);
+       hw->cap_sup_sta.variant = hfa384x2host_16(hw->cap_sup_sta.variant);
+       hw->cap_sup_sta.bottom = hfa384x2host_16(hw->cap_sup_sta.bottom);
+       hw->cap_sup_sta.top = hfa384x2host_16(hw->cap_sup_sta.top);
+
+       if ( hw->cap_sup_sta.id == 0x04 ) {
+               WLAN_LOG_INFO(
+               "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+               hw->cap_sup_sta.role, hw->cap_sup_sta.id,
+               hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
+               hw->cap_sup_sta.top);
+       } else {
+               WLAN_LOG_INFO(
+               "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+               hw->cap_sup_sta.role, hw->cap_sup_sta.id,
+               hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
+               hw->cap_sup_sta.top);
+       }
+
+       /* Compatibility range, primary f/w actor, CFI supplier */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES,
+                       &hw->cap_act_pri_cfi, sizeof(hfa384x_caplevel_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve PRI_CFIACTRANGES\n");
+               goto failed;
+       }
+
+       /* get all the Compatibility range, primary f/w actor, CFI supplier
+       fields in byte order */
+       hw->cap_act_pri_cfi.role = hfa384x2host_16(hw->cap_act_pri_cfi.role);
+       hw->cap_act_pri_cfi.id = hfa384x2host_16(hw->cap_act_pri_cfi.id);
+       hw->cap_act_pri_cfi.variant = hfa384x2host_16(hw->cap_act_pri_cfi.variant);
+       hw->cap_act_pri_cfi.bottom = hfa384x2host_16(hw->cap_act_pri_cfi.bottom);
+       hw->cap_act_pri_cfi.top = hfa384x2host_16(hw->cap_act_pri_cfi.top);
+
+       WLAN_LOG_INFO(
+               "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+               hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id,
+               hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom,
+               hw->cap_act_pri_cfi.top);
+
+       /* Compatibility range, sta f/w actor, CFI supplier */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES,
+                       &hw->cap_act_sta_cfi, sizeof(hfa384x_caplevel_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve STA_CFIACTRANGES\n");
+               goto failed;
+       }
+
+       /* get all the Compatibility range, station f/w actor, CFI supplier
+       fields in byte order */
+       hw->cap_act_sta_cfi.role = hfa384x2host_16(hw->cap_act_sta_cfi.role);
+       hw->cap_act_sta_cfi.id = hfa384x2host_16(hw->cap_act_sta_cfi.id);
+       hw->cap_act_sta_cfi.variant = hfa384x2host_16(hw->cap_act_sta_cfi.variant);
+       hw->cap_act_sta_cfi.bottom = hfa384x2host_16(hw->cap_act_sta_cfi.bottom);
+       hw->cap_act_sta_cfi.top = hfa384x2host_16(hw->cap_act_sta_cfi.top);
+
+       WLAN_LOG_INFO(
+               "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+               hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id,
+               hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom,
+               hw->cap_act_sta_cfi.top);
+
+       /* Compatibility range, sta f/w actor, MFI supplier */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES,
+                       &hw->cap_act_sta_mfi, sizeof(hfa384x_caplevel_t));
+       if ( result ) {
+               WLAN_LOG_ERROR("Failed to retrieve STA_MFIACTRANGES\n");
+               goto failed;
+       }
+
+       /* get all the Compatibility range, station f/w actor, MFI supplier
+       fields in byte order */
+       hw->cap_act_sta_mfi.role = hfa384x2host_16(hw->cap_act_sta_mfi.role);
+       hw->cap_act_sta_mfi.id = hfa384x2host_16(hw->cap_act_sta_mfi.id);
+       hw->cap_act_sta_mfi.variant = hfa384x2host_16(hw->cap_act_sta_mfi.variant);
+       hw->cap_act_sta_mfi.bottom = hfa384x2host_16(hw->cap_act_sta_mfi.bottom);
+       hw->cap_act_sta_mfi.top = hfa384x2host_16(hw->cap_act_sta_mfi.top);
+
+       WLAN_LOG_INFO(
+               "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+               hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id,
+               hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom,
+               hw->cap_act_sta_mfi.top);
+
+       /* Serial Number */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER,
+                       snum, HFA384x_RID_NICSERIALNUMBER_LEN);
+       if ( !result ) {
+               wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN,
+                               pstr, sizeof(pstr));
+               WLAN_LOG_INFO("Prism2 card SN: %s\n", pstr);
+       } else {
+               WLAN_LOG_ERROR("Failed to retrieve Prism2 Card SN\n");
+               goto failed;
+       }
+
+       /* Collect the MAC address */
+       result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR,
+               wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
+       if ( result != 0 ) {
+               WLAN_LOG_ERROR("Failed to retrieve mac address\n");
+               goto failed;
+       }
+
+       /* short preamble is always implemented */
+       wlandev->nsdcaps |= P80211_NSDCAP_SHORT_PREAMBLE;
+
+       /* find out if hardware wep is implemented */
+       hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp);
+       if (temp)
+               wlandev->nsdcaps |= P80211_NSDCAP_HARDWAREWEP;
+
+       /* get the dBm Scaling constant */
+       hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp);
+       hw->dbmadjust = temp;
+
+       /* Only enable scan by default on newer firmware */
+        if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+                                     hw->ident_sta_fw.minor,
+                                     hw->ident_sta_fw.variant) <
+           HFA384x_FIRMWARE_VERSION(1,5,5)) {
+               wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN;
+       }
+
+       /* TODO: Set any internally managed config items */
+
+       goto done;
+failed:
+       WLAN_LOG_ERROR("Failed, result=%d\n", result);
+done:
+       DBFEXIT;
+       return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_globalsetup
+*
+* Set any global RIDs that we want to set at device activation.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      0       success
+*      >0      f/w reported error
+*      <0      driver reported error
+*
+* Side effects:
+*
+* Call context:
+*      process thread
+----------------------------------------------------------------*/
+static int prism2sta_globalsetup(wlandevice_t *wlandev)
+{
+       hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+
+       /* Set the maximum frame size */
+       return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN,
+                                           WLAN_DATA_MAXLEN);
+}
+
+static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
+{
+       int result = 0;
+       hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+
+       UINT16  promisc;
+
+       DBFENTER;
+
+       /* If we're not ready, what's the point? */
+       if ( hw->state != HFA384x_STATE_RUNNING )
+               goto exit;
+
+       /* If we're an AP, do nothing here */
+       if (hw->ap)
+               goto exit;
+
+       if ( (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0 )
+               promisc = P80211ENUM_truth_true;
+       else
+               promisc = P80211ENUM_truth_false;
+
+       result = hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, promisc);
+
+       /* XXX TODO: configure the multicast list */
+       // CLEAR_HW_MULTICAST_LIST
+       // struct dev_mc_list element = dev->mc_list;
+       // while (element != null) {
+       //  HW_ADD_MULTICAST_ADDR(element->dmi_addr, dmi_addrlen)
+       //  element = element->next;
+       // }
+
+ exit:
+       DBFEXIT;
+       return result;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_handover
+*
+* Handles the receipt of a Handover info frame. Should only be present
+* in APs only.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+{
+       DBFENTER;
+       WLAN_LOG_DEBUG(2,"received infoframe:HANDOVER (unhandled)\n");
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_inf_tallies
+*
+* Handles the receipt of a CommTallies info frame.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_tallies(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       UINT16                  *src16;
+       UINT32                  *dst;
+       UINT32                  *src32;
+       int                     i;
+       int                     cnt;
+
+       DBFENTER;
+
+       /*
+       ** Determine if these are 16-bit or 32-bit tallies, based on the
+       ** record length of the info record.
+       */
+
+       cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(UINT32);
+       if (inf->framelen > 22) {
+               dst   = (UINT32 *) &hw->tallies;
+               src32 = (UINT32 *) &inf->info.commtallies32;
+               for (i = 0; i < cnt; i++, dst++, src32++)
+                       *dst += hfa384x2host_32(*src32);
+       } else {
+               dst   = (UINT32 *) &hw->tallies;
+               src16 = (UINT16 *) &inf->info.commtallies16;
+               for (i = 0; i < cnt; i++, dst++, src16++)
+                       *dst += hfa384x2host_16(*src16);
+       }
+
+       DBFEXIT;
+
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_scanresults
+*
+* Handles the receipt of a Scan Results info frame.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
+                                     hfa384x_InfFrame_t *inf)
+{
+
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       int                     nbss;
+       hfa384x_ScanResult_t    *sr = &(inf->info.scanresult);
+       int                     i;
+       hfa384x_JoinRequest_data_t      joinreq;
+       int                     result;
+       DBFENTER;
+
+       /* Get the number of results, first in bytes, then in results */
+       nbss = (inf->framelen * sizeof(UINT16)) -
+               sizeof(inf->infotype) -
+               sizeof(inf->info.scanresult.scanreason);
+       nbss /= sizeof(hfa384x_ScanResultSub_t);
+
+       /* Print em */
+       WLAN_LOG_DEBUG(1,"rx scanresults, reason=%d, nbss=%d:\n",
+               inf->info.scanresult.scanreason, nbss);
+       for ( i = 0; i < nbss; i++) {
+               WLAN_LOG_DEBUG(1, "chid=%d anl=%d sl=%d bcnint=%d\n",
+                       sr->result[i].chid,
+                       sr->result[i].anl,
+                       sr->result[i].sl,
+                       sr->result[i].bcnint);
+               WLAN_LOG_DEBUG(1, "  capinfo=0x%04x proberesp_rate=%d\n",
+                       sr->result[i].capinfo,
+                       sr->result[i].proberesp_rate);
+       }
+       /* issue a join request */
+       joinreq.channel = sr->result[0].chid;
+       memcpy( joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN);
+       result = hfa384x_drvr_setconfig( hw,
+                       HFA384x_RID_JOINREQUEST,
+                       &joinreq, HFA384x_RID_JOINREQUEST_LEN);
+       if (result) {
+               WLAN_LOG_ERROR("setconfig(joinreq) failed, result=%d\n", result);
+       }
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_hostscanresults
+*
+* Handles the receipt of a Scan Results info frame.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
+                                         hfa384x_InfFrame_t *inf)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       int                     nbss;
+       DBFENTER;
+
+       nbss = (inf->framelen - 3) / 32;
+       WLAN_LOG_DEBUG(1, "Received %d hostscan results\n", nbss);
+
+       if (nbss > 32)
+               nbss = 32;
+
+       if (hw->scanresults)
+               kfree(hw->scanresults);
+
+       hw->scanresults = kmalloc(sizeof(hfa384x_InfFrame_t), GFP_ATOMIC);
+       memcpy(hw->scanresults, inf, sizeof(hfa384x_InfFrame_t));
+
+       if (nbss == 0)
+               nbss = -1;
+
+        /* Notify/wake the sleeping caller. */
+        hw->scanflag = nbss;
+        wake_up_interruptible(&hw->cmdq);
+
+       DBFEXIT;
+};
+
+/*----------------------------------------------------------------
+* prism2sta_inf_chinforesults
+*
+* Handles the receipt of a Channel Info Results info frame.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
+                                       hfa384x_InfFrame_t *inf)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       unsigned int            i, n;
+
+       DBFENTER;
+       hw->channel_info.results.scanchannels =
+               hfa384x2host_16(inf->info.chinforesult.scanchannels);
+#if 0
+       memcpy(&inf->info.chinforesult, &hw->channel_info.results, sizeof(hfa384x_ChInfoResult_t));
+#endif
+
+       for (i=0, n=0; i<HFA384x_CHINFORESULT_MAX; i++) {
+               if (hw->channel_info.results.scanchannels & (1<<i)) {
+                       int     channel=hfa384x2host_16(inf->info.chinforesult.result[n].chid)-1;
+                       hfa384x_ChInfoResultSub_t *chinforesult=&hw->channel_info.results.result[channel];
+                       chinforesult->chid   = channel;
+                       chinforesult->anl    = hfa384x2host_16(inf->info.chinforesult.result[n].anl);
+                       chinforesult->pnl    = hfa384x2host_16(inf->info.chinforesult.result[n].pnl);
+                       chinforesult->active = hfa384x2host_16(inf->info.chinforesult.result[n].active);
+                       WLAN_LOG_DEBUG(2, "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
+                                       channel+1,
+                                       chinforesult->active &
+                                       HFA384x_CHINFORESULT_BSSACTIVE ? "signal" : "noise",
+                                       chinforesult->anl, chinforesult->pnl,
+                                       chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0
+                       );
+                       n++;
+               }
+       }
+       atomic_set(&hw->channel_info.done, 2);
+
+       hw->channel_info.count = n;
+       DBFEXIT;
+       return;
+}
+
+void prism2sta_processing_defer(struct work_struct *data)
+{
+       hfa384x_t               *hw = container_of(data, struct hfa384x, link_bh);
+       wlandevice_t            *wlandev = hw->wlandev;
+       hfa384x_bytestr32_t ssid;
+       int                     result;
+
+       DBFENTER;
+       /* First let's process the auth frames */
+       {
+               struct sk_buff          *skb;
+               hfa384x_InfFrame_t *inf;
+
+               while ( (skb = skb_dequeue(&hw->authq)) ) {
+                       inf = (hfa384x_InfFrame_t *) skb->data;
+                       prism2sta_inf_authreq_defer(wlandev, inf);
+               }
+
+       }
+
+       /* Now let's handle the linkstatus stuff */
+       if (hw->link_status == hw->link_status_new)
+               goto failed;
+
+       hw->link_status = hw->link_status_new;
+
+       switch(hw->link_status) {
+       case HFA384x_LINK_NOTCONNECTED:
+               /* I'm currently assuming that this is the initial link
+                * state.  It should only be possible immediately
+                * following an Enable command.
+                * Response:
+                * Block Transmits, Ignore receives of data frames
+                */
+               netif_carrier_off(wlandev->netdev);
+
+               WLAN_LOG_INFO("linkstatus=NOTCONNECTED (unhandled)\n");
+               break;
+
+       case HFA384x_LINK_CONNECTED:
+               /* This one indicates a successful scan/join/auth/assoc.
+                * When we have the full MLME complement, this event will
+                * signify successful completion of both mlme_authenticate
+                * and mlme_associate.  State management will get a little
+                * ugly here.
+                * Response:
+                * Indicate authentication and/or association
+                * Enable Transmits, Receives and pass up data frames
+                */
+
+               netif_carrier_on(wlandev->netdev);
+
+               /* If we are joining a specific AP, set our state and reset retries */
+               if(hw->join_ap == 1)
+                       hw->join_ap = 2;
+               hw->join_retries = 60;
+
+               /* Don't call this in monitor mode */
+               if ( wlandev->netdev->type == ARPHRD_ETHER ) {
+                       UINT16                  portstatus;
+
+                       WLAN_LOG_INFO("linkstatus=CONNECTED\n");
+
+                       /* For non-usb devices, we can use the sync versions */
+                       /* Collect the BSSID, and set state to allow tx */
+
+                       result = hfa384x_drvr_getconfig(hw,
+                                                       HFA384x_RID_CURRENTBSSID,
+                                                       wlandev->bssid, WLAN_BSSID_LEN);
+                       if ( result ) {
+                               WLAN_LOG_DEBUG(1,
+                                              "getconfig(0x%02x) failed, result = %d\n",
+                                              HFA384x_RID_CURRENTBSSID, result);
+                               goto failed;
+                       }
+
+                       result = hfa384x_drvr_getconfig(hw,
+                                                       HFA384x_RID_CURRENTSSID,
+                                                       &ssid, sizeof(ssid));
+                       if ( result ) {
+                               WLAN_LOG_DEBUG(1,
+                                              "getconfig(0x%02x) failed, result = %d\n",
+                                              HFA384x_RID_CURRENTSSID, result);
+                               goto failed;
+                       }
+                       prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
+                                               (p80211pstrd_t *) &wlandev->ssid);
+
+                       /* Collect the port status */
+                       result = hfa384x_drvr_getconfig16(hw,
+                                                         HFA384x_RID_PORTSTATUS, &portstatus);
+                       if ( result ) {
+                               WLAN_LOG_DEBUG(1,
+                                              "getconfig(0x%02x) failed, result = %d\n",
+                                              HFA384x_RID_PORTSTATUS, result);
+                               goto failed;
+                       }
+                       wlandev->macmode =
+                               (portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
+                               WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
+
+                       /* Get the ball rolling on the comms quality stuff */
+                       prism2sta_commsqual_defer(&hw->commsqual_bh);
+               }
+               break;
+
+       case HFA384x_LINK_DISCONNECTED:
+               /* This one indicates that our association is gone.  We've
+                * lost connection with the AP and/or been disassociated.
+                * This indicates that the MAC has completely cleared it's
+                * associated state.  We * should send a deauth indication
+                * (implying disassoc) up * to the MLME.
+                * Response:
+                * Indicate Deauthentication
+                * Block Transmits, Ignore receives of data frames
+                */
+               if(hw->join_ap == 2)
+               {
+                       hfa384x_JoinRequest_data_t      joinreq;
+                       joinreq = hw->joinreq;
+                       /* Send the join request */
+                       hfa384x_drvr_setconfig( hw,
+                               HFA384x_RID_JOINREQUEST,
+                               &joinreq, HFA384x_RID_JOINREQUEST_LEN);
+                       WLAN_LOG_INFO("linkstatus=DISCONNECTED (re-submitting join)\n");
+               } else {
+                       if (wlandev->netdev->type == ARPHRD_ETHER)
+                               WLAN_LOG_INFO("linkstatus=DISCONNECTED (unhandled)\n");
+               }
+               wlandev->macmode = WLAN_MACMODE_NONE;
+
+               netif_carrier_off(wlandev->netdev);
+
+               break;
+
+       case HFA384x_LINK_AP_CHANGE:
+               /* This one indicates that the MAC has decided to and
+                * successfully completed a change to another AP.  We
+                * should probably implement a reassociation indication
+                * in response to this one.  I'm thinking that the the
+                * p80211 layer needs to be notified in case of
+                * buffering/queueing issues.  User mode also needs to be
+                * notified so that any BSS dependent elements can be
+                * updated.
+                * associated state.  We * should send a deauth indication
+                * (implying disassoc) up * to the MLME.
+                * Response:
+                * Indicate Reassociation
+                * Enable Transmits, Receives and pass up data frames
+                */
+               WLAN_LOG_INFO("linkstatus=AP_CHANGE\n");
+
+               result = hfa384x_drvr_getconfig(hw,
+                                               HFA384x_RID_CURRENTBSSID,
+                                               wlandev->bssid, WLAN_BSSID_LEN);
+               if ( result ) {
+                       WLAN_LOG_DEBUG(1,
+                                      "getconfig(0x%02x) failed, result = %d\n",
+                                      HFA384x_RID_CURRENTBSSID, result);
+                       goto failed;
+               }
+
+               result = hfa384x_drvr_getconfig(hw,
+                                               HFA384x_RID_CURRENTSSID,
+                                               &ssid, sizeof(ssid));
+               if ( result ) {
+                       WLAN_LOG_DEBUG(1,
+                                      "getconfig(0x%02x) failed, result = %d\n",
+                                      HFA384x_RID_CURRENTSSID, result);
+                       goto failed;
+               }
+               prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
+                                       (p80211pstrd_t *) &wlandev->ssid);
+
+
+               hw->link_status = HFA384x_LINK_CONNECTED;
+               netif_carrier_on(wlandev->netdev);
+
+               break;
+
+       case HFA384x_LINK_AP_OUTOFRANGE:
+               /* This one indicates that the MAC has decided that the
+                * AP is out of range, but hasn't found a better candidate
+                * so the MAC maintains its "associated" state in case
+                * we get back in range.  We should block transmits and
+                * receives in this state.  Do we need an indication here?
+                * Probably not since a polling user-mode element would
+                * get this status from from p2PortStatus(FD40). What about
+                * p80211?
+                * Response:
+                * Block Transmits, Ignore receives of data frames
+                */
+               WLAN_LOG_INFO("linkstatus=AP_OUTOFRANGE (unhandled)\n");
+
+               netif_carrier_off(wlandev->netdev);
+
+               break;
+
+       case HFA384x_LINK_AP_INRANGE:
+               /* This one indicates that the MAC has decided that the
+                * AP is back in range.  We continue working with our
+                * existing association.
+                * Response:
+                * Enable Transmits, Receives and pass up data frames
+                */
+               WLAN_LOG_INFO("linkstatus=AP_INRANGE\n");
+
+               hw->link_status = HFA384x_LINK_CONNECTED;
+               netif_carrier_on(wlandev->netdev);
+
+               break;
+
+       case HFA384x_LINK_ASSOCFAIL:
+               /* This one is actually a peer to CONNECTED.  We've
+                * requested a join for a given SSID and optionally BSSID.
+                * We can use this one to indicate authentication and
+                * association failures.  The trick is going to be
+                * 1) identifying the failure, and 2) state management.
+                * Response:
+                * Disable Transmits, Ignore receives of data frames
+                */
+               if(hw->join_ap && --hw->join_retries > 0)
+               {
+                       hfa384x_JoinRequest_data_t      joinreq;
+                       joinreq = hw->joinreq;
+                       /* Send the join request */
+                       hfa384x_drvr_setconfig( hw,
+                               HFA384x_RID_JOINREQUEST,
+                               &joinreq, HFA384x_RID_JOINREQUEST_LEN);
+                       WLAN_LOG_INFO("linkstatus=ASSOCFAIL (re-submitting join)\n");
+               } else {
+                       WLAN_LOG_INFO("linkstatus=ASSOCFAIL (unhandled)\n");
+               }
+
+               netif_carrier_off(wlandev->netdev);
+
+               break;
+
+       default:
+               /* This is bad, IO port problems? */
+               WLAN_LOG_WARNING(
+                       "unknown linkstatus=0x%02x\n", hw->link_status);
+               goto failed;
+               break;
+       }
+
+       wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
+#ifdef WIRELESS_EXT
+       p80211wext_event_associated(wlandev, wlandev->linkstatus);
+#endif
+
+ failed:
+       DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_linkstatus
+*
+* Handles the receipt of a Link Status info frame.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
+                                    hfa384x_InfFrame_t *inf)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+
+       DBFENTER;
+
+       hw->link_status_new = hfa384x2host_16(inf->info.linkstatus.linkstatus);
+
+       schedule_work(&hw->link_bh);
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_assocstatus
+*
+* Handles the receipt of an Association Status info frame. Should
+* be present in APs only.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
+                                     hfa384x_InfFrame_t *inf)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       hfa384x_AssocStatus_t   rec;
+       int                     i;
+
+       DBFENTER;
+
+       memcpy(&rec, &inf->info.assocstatus, sizeof(rec));
+       rec.assocstatus = hfa384x2host_16(rec.assocstatus);
+       rec.reason      = hfa384x2host_16(rec.reason);
+
+       /*
+       ** Find the address in the list of authenticated stations.  If it wasn't
+       ** found, then this address has not been previously authenticated and
+       ** something weird has happened if this is anything other than an
+       ** "authentication failed" message.  If the address was found, then
+       ** set the "associated" flag for that station, based on whether the
+       ** station is associating or losing its association.  Something weird
+       ** has also happened if we find the address in the list of authenticated
+       ** stations but we are getting an "authentication failed" message.
+       */
+
+       for (i = 0; i < hw->authlist.cnt; i++)
+               if (memcmp(rec.sta_addr, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
+                       break;
+
+       if (i >= hw->authlist.cnt) {
+               if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL)
+                       WLAN_LOG_WARNING("assocstatus info frame received for non-authenticated station.\n");
+       } else {
+               hw->authlist.assoc[i] =
+                       (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||
+                        rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);
+
+               if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL)
+                       WLAN_LOG_WARNING("authfail assocstatus info frame received for authenticated station.\n");
+       }
+
+       DBFEXIT;
+
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_authreq
+*
+* Handles the receipt of an Authentication Request info frame. Should
+* be present in APs only.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+*
+----------------------------------------------------------------*/
+static void prism2sta_inf_authreq(wlandevice_t *wlandev,
+                                 hfa384x_InfFrame_t *inf)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       struct sk_buff *skb;
+
+       DBFENTER;
+
+       skb = dev_alloc_skb(sizeof(*inf));
+       if (skb) {
+               skb_put(skb, sizeof(*inf));
+               memcpy(skb->data, inf, sizeof(*inf));
+               skb_queue_tail(&hw->authq, skb);
+               schedule_work(&hw->link_bh);
+       }
+
+       DBFEXIT;
+}
+
+static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
+                                       hfa384x_InfFrame_t *inf)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+       hfa384x_authenticateStation_data_t  rec;
+
+       int    i, added, result, cnt;
+       UINT8  *addr;
+
+       DBFENTER;
+
+       /*
+       ** Build the AuthenticateStation record.  Initialize it for denying
+       ** authentication.
+       */
+
+       memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN);
+       rec.status = P80211ENUM_status_unspec_failure;
+
+       /*
+       ** Authenticate based on the access mode.
+       */
+
+       switch (hw->accessmode) {
+               case WLAN_ACCESS_NONE:
+
+                       /*
+                       ** Deny all new authentications.  However, if a station
+                       ** is ALREADY authenticated, then accept it.
+                       */
+
+                       for (i = 0; i < hw->authlist.cnt; i++)
+                               if (memcmp(rec.address, hw->authlist.addr[i],
+                                               WLAN_ADDR_LEN) == 0) {
+                                       rec.status = P80211ENUM_status_successful;
+                                       break;
+                               }
+
+                       break;
+
+               case WLAN_ACCESS_ALL:
+
+                       /*
+                       ** Allow all authentications.
+                       */
+
+                       rec.status = P80211ENUM_status_successful;
+                       break;
+
+               case WLAN_ACCESS_ALLOW:
+
+                       /*
+                       ** Only allow the authentication if the MAC address
+                       ** is in the list of allowed addresses.
+                       **
+                       ** Since this is the interrupt handler, we may be here
+                       ** while the access list is in the middle of being
+                       ** updated.  Choose the list which is currently okay.
+                       ** See "prism2mib_priv_accessallow()" for details.
+                       */
+
+                       if (hw->allow.modify == 0) {
+                               cnt  = hw->allow.cnt;
+                               addr = hw->allow.addr[0];
+                       } else {
+                               cnt  = hw->allow.cnt1;
+                               addr = hw->allow.addr1[0];
+                       }
+
+                       for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
+                               if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
+                                       rec.status = P80211ENUM_status_successful;
+                                       break;
+                               }
+
+                       break;
+
+               case WLAN_ACCESS_DENY:
+
+                       /*
+                       ** Allow the authentication UNLESS the MAC address is
+                       ** in the list of denied addresses.
+                       **
+                       ** Since this is the interrupt handler, we may be here
+                       ** while the access list is in the middle of being
+                       ** updated.  Choose the list which is currently okay.
+                       ** See "prism2mib_priv_accessdeny()" for details.
+                       */
+
+                       if (hw->deny.modify == 0) {
+                               cnt  = hw->deny.cnt;
+                               addr = hw->deny.addr[0];
+                       } else {
+                               cnt  = hw->deny.cnt1;
+                               addr = hw->deny.addr1[0];
+                       }
+
+                       rec.status = P80211ENUM_status_successful;
+
+                       for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
+                               if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
+                                       rec.status = P80211ENUM_status_unspec_failure;
+                                       break;
+                               }
+
+                       break;
+       }
+
+       /*
+       ** If the authentication is okay, then add the MAC address to the list
+       ** of authenticated stations.  Don't add the address if it is already in
+       ** the list.  (802.11b does not seem to disallow a station from issuing
+       ** an authentication request when the station is already authenticated.
+       ** Does this sort of thing ever happen?  We might as well do the check
+       ** just in case.)
+       */
+
+       added = 0;
+
+       if (rec.status == P80211ENUM_status_successful) {
+               for (i = 0; i < hw->authlist.cnt; i++)
+                       if (memcmp(rec.address, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
+                               break;
+
+               if (i >= hw->authlist.cnt) {
+                       if (hw->authlist.cnt >= WLAN_AUTH_MAX) {
+                               rec.status = P80211ENUM_status_ap_full;
+                       } else {
+                               memcpy(hw->authlist.addr[hw->authlist.cnt],
+                                       rec.address, WLAN_ADDR_LEN);
+                               hw->authlist.cnt++;
+                               added = 1;
+                       }
+               }
+       }
+
+       /*
+       ** Send back the results of the authentication.  If this doesn't work,
+       ** then make sure to remove the address from the authenticated list if
+       ** it was added.
+       */
+
+       rec.status = host2hfa384x_16(rec.status);
+       rec.algorithm = inf->info.authreq.algorithm;
+
+       result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA,
+                                                       &rec, sizeof(rec));
+       if (result) {
+               if (added) hw->authlist.cnt--;
+               WLAN_LOG_ERROR("setconfig(authenticatestation) failed, result=%d\n", result);
+       }
+
+       DBFEXIT;
+
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_inf_psusercnt
+*
+* Handles the receipt of a PowerSaveUserCount info frame. Should
+* be present in APs only.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
+                                   hfa384x_InfFrame_t *inf)
+{
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+
+       DBFENTER;
+
+       hw->psusercount = hfa384x2host_16(inf->info.psusercnt.usercnt);
+
+       DBFEXIT;
+
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_ev_dtim
+*
+* Handles the DTIM early warning event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_dtim(wlandevice_t *wlandev)
+{
+#if 0
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+#endif
+       DBFENTER;
+       WLAN_LOG_DEBUG(3, "DTIM event, currently unhandled.\n");
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_infdrop
+*
+* Handles the InfDrop event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_infdrop(wlandevice_t *wlandev)
+{
+#if 0
+        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+#endif
+       DBFENTER;
+       WLAN_LOG_DEBUG(3, "Info frame dropped due to card mem low.\n");
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_info
+*
+* Handles the Info event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      inf             ptr to a generic info frame
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+{
+       DBFENTER;
+       inf->infotype = hfa384x2host_16(inf->infotype);
+       /* Dispatch */
+       switch ( inf->infotype ) {
+               case HFA384x_IT_HANDOVERADDR:
+                       prism2sta_inf_handover(wlandev, inf);
+                       break;
+               case HFA384x_IT_COMMTALLIES:
+                       prism2sta_inf_tallies(wlandev, inf);
+                       break;
+               case HFA384x_IT_HOSTSCANRESULTS:
+                        prism2sta_inf_hostscanresults(wlandev, inf);
+                        break;
+               case HFA384x_IT_SCANRESULTS:
+                       prism2sta_inf_scanresults(wlandev, inf);
+                       break;
+               case HFA384x_IT_CHINFORESULTS:
+                       prism2sta_inf_chinforesults(wlandev, inf);
+                       break;
+               case HFA384x_IT_LINKSTATUS:
+                       prism2sta_inf_linkstatus(wlandev, inf);
+                       break;
+               case HFA384x_IT_ASSOCSTATUS:
+                       prism2sta_inf_assocstatus(wlandev, inf);
+                       break;
+               case HFA384x_IT_AUTHREQ:
+                       prism2sta_inf_authreq(wlandev, inf);
+                       break;
+               case HFA384x_IT_PSUSERCNT:
+                       prism2sta_inf_psusercnt(wlandev, inf);
+                       break;
+               case HFA384x_IT_KEYIDCHANGED:
+                       WLAN_LOG_WARNING("Unhandled IT_KEYIDCHANGED\n");
+                       break;
+               case HFA384x_IT_ASSOCREQ:
+                       WLAN_LOG_WARNING("Unhandled IT_ASSOCREQ\n");
+                       break;
+               case HFA384x_IT_MICFAILURE:
+                       WLAN_LOG_WARNING("Unhandled IT_MICFAILURE\n");
+                       break;
+               default:
+                       WLAN_LOG_WARNING(
+                               "Unknown info type=0x%02x\n", inf->infotype);
+                       break;
+       }
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_txexc
+*
+* Handles the TxExc event.  A Transmit Exception event indicates
+* that the MAC's TX process was unsuccessful - so the packet did
+* not get transmitted.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      status          tx frame status word
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status)
+{
+       DBFENTER;
+
+       WLAN_LOG_DEBUG(3, "TxExc status=0x%x.\n", status);
+
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_tx
+*
+* Handles the Tx event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      status          tx frame status word
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status)
+{
+       DBFENTER;
+       WLAN_LOG_DEBUG(4, "Tx Complete, status=0x%04x\n", status);
+       /* update linux network stats */
+       wlandev->linux_stats.tx_packets++;
+       DBFEXIT;
+       return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_rx
+*
+* Handles the Rx event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
+{
+       DBFENTER;
+
+       p80211netdev_rx(wlandev, skb);
+
+       DBFEXIT;
+       return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_ev_alloc
+*
+* Handles the Alloc event.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_alloc(wlandevice_t *wlandev)
+{
+       DBFENTER;
+
+       p80211netdev_wake_queue(wlandev);
+
+       DBFEXIT;
+       return;
+}
+
+#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI)
+#ifdef CONFIG_PM
+static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state)
+{
+               wlandevice_t            *wlandev;
+
+       wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
+
+       /* reset hardware */
+       if (wlandev) {
+               prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+               p80211_suspend(wlandev);
+       }
+
+       // call a netif_device_detach(wlandev->netdev) ?
+
+       return 0;
+}
+
+static int prism2sta_resume_pci (struct pci_dev *pdev)
+{
+               wlandevice_t            *wlandev;
+
+       wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
+
+       if (wlandev) {
+               prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+               p80211_resume(wlandev);
+       }
+
+        return 0;
+}
+#endif
+#endif
+
+/*----------------------------------------------------------------
+* create_wlan
+*
+* Called at module init time.  This creates the wlandevice_t structure
+* and initializes it with relevant bits.
+*
+* Arguments:
+*      none
+*
+* Returns:
+*      the created wlandevice_t structure.
+*
+* Side effects:
+*      also allocates the priv/hw structures.
+*
+* Call context:
+*      process thread
+*
+----------------------------------------------------------------*/
+static wlandevice_t *create_wlan(void)
+{
+        wlandevice_t    *wlandev = NULL;
+       hfa384x_t       *hw = NULL;
+
+       /* Alloc our structures */
+       wlandev =       kmalloc(sizeof(wlandevice_t), GFP_KERNEL);
+       hw =            kmalloc(sizeof(hfa384x_t), GFP_KERNEL);
+
+       if (!wlandev || !hw) {
+               WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+               if (wlandev)    kfree(wlandev);
+               if (hw)         kfree(hw);
+               return NULL;
+       }
+
+       /* Clear all the structs */
+       memset(wlandev, 0, sizeof(wlandevice_t));
+       memset(hw, 0, sizeof(hfa384x_t));
+
+       /* Initialize the network device object. */
+       wlandev->nsdname = dev_info;
+       wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING;
+       wlandev->priv = hw;
+       wlandev->open = prism2sta_open;
+       wlandev->close = prism2sta_close;
+       wlandev->reset = prism2sta_reset;
+#ifdef CONFIG_PROC_FS
+       wlandev->nsd_proc_read = prism2sta_proc_read;
+#endif
+       wlandev->txframe = prism2sta_txframe;
+       wlandev->mlmerequest = prism2sta_mlmerequest;
+       wlandev->set_multicast_list = prism2sta_setmulticast;
+       wlandev->tx_timeout = hfa384x_tx_timeout;
+
+       wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT |
+                          P80211_NSDCAP_AUTOJOIN;
+
+       /* Initialize the device private data stucture. */
+        hw->dot11_desired_bss_type = 1;
+
+       return wlandev;
+}
+
+#ifdef CONFIG_PROC_FS
+static int
+prism2sta_proc_read(
+       char    *page,
+       char    **start,
+       off_t   offset,
+       int     count,
+       int     *eof,
+       void    *data)
+{
+       char     *p = page;
+       wlandevice_t *wlandev = (wlandevice_t *) data;
+       hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+
+       UINT16 hwtype = 0;
+
+       DBFENTER;
+       if (offset != 0) {
+               *eof = 1;
+               goto exit;
+       }
+
+       // XXX 0x0001 for prism2.5/3, 0x0000 for prism2.
+       hwtype = BIT0;
+
+#if (WLAN_HOSTIF != WLAN_USB)
+       if (hw->isram16)
+               hwtype |= BIT1;
+#endif
+
+#if (WLAN_HOSTIF == WLAN_PCI)
+       hwtype |= BIT2;
+#endif
+
+#define PRISM2_CVS_ID "$Id: prism2sta.c 1826 2007-03-19 15:37:00Z pizza $"
+
+       p += sprintf(p, "# %s version %s (%s) '%s'\n\n",
+                    dev_info,
+                    WLAN_RELEASE, WLAN_BUILD_DATE, PRISM2_CVS_ID);
+
+       p += sprintf(p, "# nic h/w: id=0x%02x %d.%d.%d\n",
+                    hw->ident_nic.id, hw->ident_nic.major,
+                    hw->ident_nic.minor, hw->ident_nic.variant);
+
+       p += sprintf(p, "# pri f/w: id=0x%02x %d.%d.%d\n",
+                    hw->ident_pri_fw.id, hw->ident_pri_fw.major,
+                    hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
+
+       if (hw->ident_sta_fw.id == 0x1f) {
+               p += sprintf(p, "# sta f/w: id=0x%02x %d.%d.%d\n",
+                            hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+                            hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+       } else {
+               p += sprintf(p, "# ap f/w: id=0x%02x %d.%d.%d\n",
+                            hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+                            hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+       }
+
+#if (WLAN_HOSTIF != WLAN_USB)
+       p += sprintf(p, "# initial nic hw type, needed for SSF ramdl\n");
+       p += sprintf(p, "initnichw=%04x\n", hwtype);
+#endif
+
+ exit:
+       DBFEXIT;
+       return (p - page);
+}
+#endif
+
+void prism2sta_commsqual_defer(struct work_struct *data)
+{
+       hfa384x_t               *hw = container_of(data, struct hfa384x, commsqual_bh);
+        wlandevice_t            *wlandev = hw->wlandev;
+       hfa384x_bytestr32_t ssid;
+       int result = 0;
+
+       DBFENTER;
+
+       if (hw->wlandev->hwremoved)
+               goto done;
+
+       /* we don't care if we're in AP mode */
+       if ((wlandev->macmode == WLAN_MACMODE_NONE) ||
+           (wlandev->macmode == WLAN_MACMODE_ESS_AP)) {
+               goto done;
+       }
+
+       /* It only makes sense to poll these in non-IBSS */
+       if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) {
+               result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DBMCOMMSQUALITY,
+                                               &hw->qual,
+                                               HFA384x_RID_DBMCOMMSQUALITY_LEN);
+
+               if (result) {
+                       WLAN_LOG_ERROR("error fetching commsqual\n");
+                       goto done;
+               }
+
+               // qual.CQ_currBSS; // link
+               // ASL_currBSS;  // level
+               // qual.ANL_currFC; // noise
+
+               WLAN_LOG_DEBUG(3, "commsqual %d %d %d\n",
+                              hfa384x2host_16(hw->qual.CQ_currBSS),
+                              hfa384x2host_16(hw->qual.ASL_currBSS),
+                              hfa384x2host_16(hw->qual.ANL_currFC));
+       }
+
+       /* Lastly, we need to make sure the BSSID didn't change on us */
+       result = hfa384x_drvr_getconfig(hw,
+                                       HFA384x_RID_CURRENTBSSID,
+                                       wlandev->bssid, WLAN_BSSID_LEN);
+       if ( result ) {
+               WLAN_LOG_DEBUG(1,
+                              "getconfig(0x%02x) failed, result = %d\n",
+                              HFA384x_RID_CURRENTBSSID, result);
+               goto done;
+       }
+
+       result = hfa384x_drvr_getconfig(hw,
+                                       HFA384x_RID_CURRENTSSID,
+                                       &ssid, sizeof(ssid));
+       if ( result ) {
+               WLAN_LOG_DEBUG(1,
+                              "getconfig(0x%02x) failed, result = %d\n",
+                              HFA384x_RID_CURRENTSSID, result);
+               goto done;
+       }
+       prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
+                               (p80211pstrd_t *) &wlandev->ssid);
+
+
+       /* Reschedule timer */
+       mod_timer(&hw->commsqual_timer, jiffies + HZ);
+
+ done:
+       DBFEXIT;
+}
+
+void prism2sta_commsqual_timer(unsigned long data)
+{
+        hfa384x_t               *hw = (hfa384x_t *) data;
+
+       DBFENTER;
+
+       schedule_work(&hw->commsqual_bh);
+
+       DBFEXIT;
+}
diff --git a/drivers/staging/wlan-ng/version.h b/drivers/staging/wlan-ng/version.h
new file mode 100644 (file)
index 0000000..305f882
--- /dev/null
@@ -0,0 +1,64 @@
+/* src/include/wlan/version.h
+*
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+#ifndef _WLAN_VERSION_H
+#define _WLAN_VERSION_H
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
+
+/* WLAN_HOSTIF (generally set on the command line, not detected) */
+#define WLAN_NONE                       0
+#define WLAN_PCMCIA                     1
+#define WLAN_ISA                        2
+#define WLAN_PCI                        3
+#define WLAN_USB                        4
+#define WLAN_PLX                        5
+#define WLAN_SLAVE                      6
+#define WLAN_RELEASE   "0.2.8"
+#define WLAN_RELEASE_CODE 0x000208
+#define WLAN_BUILD_DATE "Thu Oct  2 11:04:42 PDT 2008"
+
+#endif
diff --git a/drivers/staging/wlan-ng/wlan_compat.h b/drivers/staging/wlan-ng/wlan_compat.h
new file mode 100644 (file)
index 0000000..1702657
--- /dev/null
@@ -0,0 +1,757 @@
+/* wlan_compat.h
+*
+* Types and macros to aid in portability
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+*   The contents of this file are subject to the Mozilla Public
+*   License Version 1.1 (the "License"); you may not use this file
+*   except in compliance with the License. You may obtain a copy of
+*   the License at http://www.mozilla.org/MPL/
+*
+*   Software distributed under the License is distributed on an "AS
+*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*   implied. See the License for the specific language governing
+*   rights and limitations under the License.
+*
+*   Alternatively, the contents of this file may be used under the
+*   terms of the GNU Public License version 2 (the "GPL"), in which
+*   case the provisions of the GPL are applicable instead of the
+*   above.  If you wish to allow the use of your version of this file
+*   only under the terms of the GPL and not to allow others to use
+*   your version of this file under the MPL, indicate your decision
+*   by deleting the provisions above and replace them with the notice
+*   and other provisions required by the GPL.  If you do not delete
+*   the provisions above, a recipient may use your version of this
+*   file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _WLAN_COMPAT_H
+#define _WLAN_COMPAT_H
+
+/*=============================================================*/
+/*------ Establish Platform Identity --------------------------*/
+/*=============================================================*/
+/* Key macros: */
+/* WLAN_CPU_FAMILY */
+       #define WLAN_Ix86                       1
+       #define WLAN_PPC                        2
+       #define WLAN_Ix96                       3
+       #define WLAN_ARM                        4
+       #define WLAN_ALPHA                      5
+       #define WLAN_MIPS                       6
+       #define WLAN_HPPA                       7
+       #define WLAN_SPARC                      8
+       #define WLAN_SH                         9
+       #define WLAN_x86_64                     10
+/* WLAN_SYSARCH */
+       #define WLAN_PCAT                       1
+       #define WLAN_MBX                        2
+       #define WLAN_RPX                        3
+       #define WLAN_LWARCH                     4
+       #define WLAN_PMAC                       5
+       #define WLAN_SKIFF                      6
+       #define WLAN_BITSY                      7
+       #define WLAN_ALPHAARCH                  7
+       #define WLAN_MIPSARCH                   9
+       #define WLAN_HPPAARCH                   10
+       #define WLAN_SPARCARCH                  11
+       #define WLAN_SHARCH                     12
+
+/* Note: the PLX HOSTIF above refers to some vendors implementations for */
+/*       PCI.  It's a PLX chip that is a PCI to PCMCIA adapter, but it   */
+/*       isn't a real PCMCIA host interface adapter providing all the    */
+/*       card&socket services.                                           */
+
+#if (defined(CONFIG_PPC) || defined(CONFIG_8xx) || defined(__powerpc__))
+#ifndef __ppc__
+#define __ppc__
+#endif
+#endif
+
+#if defined(__KERNEL__)
+
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+
+#if defined(__x86_64__)
+       #define WLAN_CPU_FAMILY         WLAN_x86_64
+       #define WLAN_SYSARCH            WLAN_PCAT
+#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
+       #define WLAN_CPU_FAMILY         WLAN_Ix86
+       #define WLAN_SYSARCH            WLAN_PCAT
+#elif defined(__ppc__)
+       #define WLAN_CPU_FAMILY         WLAN_PPC
+       #if defined(CONFIG_MBX)
+               #define WLAN_SYSARCH    WLAN_MBX
+       #elif defined(CONFIG_RPXLITE)
+               #define WLAN_SYSARCH    WLAN_RPX
+       #elif defined(CONFIG_RPXCLASSIC)
+               #define WLAN_SYSARCH    WLAN_RPX
+       #else
+               #define WLAN_SYSARCH    WLAN_PMAC
+       #endif
+#elif defined(__arm__)
+       #define WLAN_CPU_FAMILY         WLAN_ARM
+       #define WLAN_SYSARCH            WLAN_SKIFF
+#elif defined(__alpha__)
+       #define WLAN_CPU_FAMILY         WLAN_ALPHA
+       #define WLAN_SYSARCH            WLAN_ALPHAARCH
+#elif defined(__mips__)
+       #define WLAN_CPU_FAMILY         WLAN_MIPS
+       #define WLAN_SYSARCH            WLAN_MIPSARCH
+#elif defined(__hppa__)
+       #define WLAN_CPU_FAMILY         WLAN_HPPA
+       #define WLAN_SYSARCH            WLAN_HPPAARCH
+#elif defined(__sparc__)
+        #define WLAN_CPU_FAMILY         WLAN_SPARC
+        #define WLAN_SYSARCH            WLAN_SPARC
+#elif defined(__sh__)
+        #define WLAN_CPU_FAMILY         WLAN_SH
+        #define WLAN_SYSARCH            WLAN_SHARCH
+        #ifndef __LITTLE_ENDIAN__
+        #define __LITTLE_ENDIAN__
+        #endif
+#else
+       #error "No CPU identified!"
+#endif
+#endif /* __KERNEL__ */
+
+/*
+   Some big endian machines implicitly do all I/O in little endian mode.
+
+   In particular:
+          Linux/PPC on PowerMacs (PCI)
+         Arm/Intel Xscale (PCI)
+
+   This may also affect PLX boards and other BE &| PPC platforms;
+   as new ones are discovered, add them below.
+*/
+
+#if defined(WLAN_HOSTIF)
+#if ((WLAN_HOSTIF == WLAN_PCI) || (WLAN_HOSTIF == WLAN_PLX))
+#if ((WLAN_SYSARCH == WLAN_SKIFF) || (WLAN_SYSARCH == WLAN_PMAC) || (WLAN_SYSARCH == WLAN_SPARC))
+#define REVERSE_ENDIAN
+#endif
+#endif
+#endif
+
+/*=============================================================*/
+/*------ Bit settings -----------------------------------------*/
+/*=============================================================*/
+
+#define BIT0   0x00000001
+#define BIT1   0x00000002
+#define BIT2   0x00000004
+#define BIT3   0x00000008
+#define BIT4   0x00000010
+#define BIT5   0x00000020
+#define BIT6   0x00000040
+#define BIT7   0x00000080
+#define BIT8   0x00000100
+#define BIT9   0x00000200
+#define BIT10  0x00000400
+#define BIT11  0x00000800
+#define BIT12  0x00001000
+#define BIT13  0x00002000
+#define BIT14  0x00004000
+#define BIT15  0x00008000
+#define BIT16  0x00010000
+#define BIT17  0x00020000
+#define BIT18  0x00040000
+#define BIT19  0x00080000
+#define BIT20  0x00100000
+#define BIT21  0x00200000
+#define BIT22  0x00400000
+#define BIT23  0x00800000
+#define BIT24  0x01000000
+#define BIT25  0x02000000
+#define BIT26  0x04000000
+#define BIT27  0x08000000
+#define BIT28  0x10000000
+#define BIT29  0x20000000
+#define BIT30  0x40000000
+#define BIT31  0x80000000
+
+#include <linux/types.h>
+
+typedef u_int8_t       UINT8;
+typedef u_int16_t      UINT16;
+typedef u_int32_t      UINT32;
+
+typedef int8_t         INT8;
+typedef int16_t                INT16;
+typedef int32_t                INT32;
+
+typedef unsigned int    UINT;
+typedef signed int      INT;
+
+typedef u_int64_t      UINT64;
+typedef int64_t                INT64;
+
+#define UINT8_MAX      (0xffUL)
+#define UINT16_MAX     (0xffffUL)
+#define UINT32_MAX     (0xffffffffUL)
+
+#define INT8_MAX       (0x7fL)
+#define INT16_MAX      (0x7fffL)
+#define INT32_MAX      (0x7fffffffL)
+
+/*=============================================================*/
+/*------ Compiler Portability Macros --------------------------*/
+/*=============================================================*/
+#define __WLAN_ATTRIB_PACK__           __attribute__ ((packed))
+
+/*=============================================================*/
+/*------ OS Portability Macros --------------------------------*/
+/*=============================================================*/
+
+#ifndef WLAN_DBVAR
+#define WLAN_DBVAR     wlan_debug
+#endif
+
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+#  if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8))
+#    include <linux/hardirq.h>
+#  else
+#    include <asm/hardirq.h>
+#  endif
+#elif defined(__KERNEL__)
+#  define PREEMPT_MASK  (0x000000FFUL)
+#  define preempt_count() (0UL)
+#endif
+
+#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __FUNCTION__ , ##args);
+
+#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __FUNCTION__ , ##args);
+
+#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __FUNCTION__ , ##args);
+
+#define WLAN_LOG_INFO(args... ) printk(KERN_INFO args)
+
+#if defined(WLAN_INCLUDE_DEBUG)
+       #define WLAN_ASSERT(c) if ((!(c)) && WLAN_DBVAR >= 1) { \
+               WLAN_LOG_DEBUG(1, "Assertion failure!\n"); }
+       #define WLAN_HEX_DUMP( l, x, p, n)      if( WLAN_DBVAR >= (l) ){ \
+               int __i__; \
+               printk(KERN_DEBUG x ":"); \
+               for( __i__=0; __i__ < (n); __i__++) \
+                       printk( " %02x", ((UINT8*)(p))[__i__]); \
+               printk("\n"); }
+       #define DBFENTER { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"---->\n"); } }
+       #define DBFEXIT  { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"<----\n"); } }
+
+       #define WLAN_LOG_DEBUG(l,x,args...) if ( WLAN_DBVAR >= (l)) printk(KERN_DEBUG "%s(%lu): " x ,  __FUNCTION__, (preempt_count() & PREEMPT_MASK), ##args );
+#else
+       #define WLAN_ASSERT(c)
+       #define WLAN_HEX_DUMP( l, s, p, n)
+       #define DBFENTER
+       #define DBFEXIT
+
+       #define WLAN_LOG_DEBUG(l, s, args...)
+#endif
+
+#ifdef CONFIG_SMP
+#define __SMP__                        1
+#endif
+
+#if defined(__KERNEL__)
+
+#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)))
+#define URB_ONLY_CALLBACK
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#define PT_REGS    , struct pt_regs *regs
+#else
+#define PT_REGS
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
+#  define del_singleshot_timer_sync(a)  del_timer_sync(a)
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17))
+#define CONFIG_NETLINK         1
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
+#define kfree_s(a, b)  kfree((a))
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18))
+#ifndef init_waitqueue_head
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,0,16))
+#define init_waitqueue_head(p)  (*(p) = NULL)
+#else
+#define init_waitqueue_head(p)  init_waitqueue(p)
+#endif
+typedef struct wait_queue *wait_queue_head_t;
+typedef struct wait_queue wait_queue_t;
+#define set_current_state(b)  { current->state = (b); mb(); }
+#define init_waitqueue_entry(a, b) { (a)->task = current; }
+#endif
+#endif
+
+#ifndef wait_event_interruptible_timeout
+// retval == 0; signal met; we're good.
+// retval < 0; interrupted by signal.
+// retval > 0; timed out.
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))  // fixme?
+
+#define __wait_event_interruptible_timeout(wq, condition, ret)            \
+do {                                                                      \
+          wait_queue_t __wait;                                            \
+          init_waitqueue_entry(&__wait, current);                         \
+                                                                         \
+          add_wait_queue(&wq, &__wait);                                   \
+          for (;;) {                                                      \
+                  set_current_state(TASK_INTERRUPTIBLE);                  \
+                  if (condition)                                          \
+                          break;                                          \
+                  if (!signal_pending(current)) {                         \
+                          ret = schedule_timeout(ret)    ;                \
+                          if (!ret)                                       \
+                                 break;                                   \
+                          continue;                                       \
+                  }                                                       \
+                  ret = -ERESTARTSYS;                                     \
+                  break;                                                  \
+          }                                                               \
+          set_current_state(TASK_RUNNING);                                \
+          remove_wait_queue(&wq, &__wait);                                \
+} while (0)
+
+#else // 2.2
+
+
+#define __wait_event_interruptible_timeout(wq, condition, ret)          \
+do {                                                                    \
+        struct wait_queue __wait;                                       \
+                                                                        \
+        __wait.task = current;                                          \
+        add_wait_queue(&wq, &__wait);                                   \
+        for (;;) {                                                      \
+                current->state = TASK_INTERRUPTIBLE;                    \
+                if (condition)                                          \
+                        break;                                          \
+                if (!signal_pending(current)) {                         \
+                        ret = schedule_timeout(ret);                    \
+                        if (!ret)                                       \
+                               break;                                   \
+                        continue;                                       \
+                }                                                       \
+                ret = -ERESTARTSYS;                                     \
+                break;                                                  \
+        }                                                               \
+        current->state = TASK_RUNNING;                                  \
+        remove_wait_queue(&wq, &__wait);                                \
+} while (0)
+
+#endif  // version >= 2.4
+
+#define wait_event_interruptible_timeout(wq, condition, timeout)         \
+({                                                                       \
+       long __ret = timeout;                                             \
+       if (!(condition))                                                 \
+               __wait_event_interruptible_timeout(wq, condition, __ret); \
+       __ret;                                                            \
+})
+
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
+#ifdef _LINUX_LIST_H
+
+static inline void list_move_tail(struct list_head *list,
+          struct list_head *head)
+{
+        __list_del(list->prev, list->next);
+        list_add_tail(list, head);
+}
+
+static inline void __list_splice(struct list_head *list,
+                                struct list_head *head)
+{
+      struct list_head *first = list->next;
+      struct list_head *last = list->prev;
+      struct list_head *at = head->next;
+
+      first->prev = head;
+      head->next = first;
+
+      last->next = at;
+      at->prev = last;
+}
+
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+      __list_del(list->prev, list->next);
+      list_add(list, head);
+}
+
+static inline void list_splice_init(struct list_head *list,
+            struct list_head *head)
+{
+       if (!list_empty(list)) {
+               __list_splice(list, head);
+               INIT_LIST_HEAD(list);
+       }
+}
+
+
+#endif  // LIST_H
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,90))
+#define spin_lock(l)            do { } while (0)
+#define spin_unlock(l)          do { } while (0)
+#define spin_lock_irqsave(l,f)  do { save_flags(f); cli(); } while (0)
+#define spin_unlock_irqrestore(l,f) do { restore_flags(f); } while (0)
+#define spin_lock_init(s)       do { } while (0)
+#define spin_trylock(l)         (1)
+typedef int spinlock_t;
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) // XXX ???
+#define spin_lock_bh         spin_lock
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+#ifdef CONFIG_SMP
+#define spin_is_locked(x)       (*(volatile char *)(&(x)->lock) <= 0)
+#else
+#define spin_is_locked(l)       (0)
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,28))
+#define __user
+#define __iomem
+#endif
+
+#ifdef _LINUX_PROC_FS_H
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,25))
+
+extern inline struct proc_dir_entry *
+create_proc_read_entry(const char *name, mode_t mode,
+                       struct proc_dir_entry *base,
+                       read_proc_t *read_proc, void *data)
+{
+    struct proc_dir_entry *res = create_proc_entry(name, mode, base);
+    if (res) {
+        res->read_proc = read_proc;
+        res->data = data;
+    }
+    return res;
+}
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29))
+#ifndef proc_mkdir
+#define proc_mkdir(name, root) create_proc_entry(name, S_IFDIR, root)
+#endif
+#endif
+#endif /* _LINUX_PROC_FS_H */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#ifndef INIT_TQUEUE
+#define PREPARE_TQUEUE(_tq, _routine, _data)                    \
+        do {                                                    \
+                (_tq)->routine = _routine;                      \
+                (_tq)->data = _data;                            \
+        } while (0)
+#define INIT_TQUEUE(_tq, _routine, _data)                       \
+        do {                                                    \
+                INIT_LIST_HEAD(&(_tq)->list);                   \
+                (_tq)->sync = 0;                                \
+                PREPARE_TQUEUE((_tq), (_routine), (_data));     \
+        } while (0)
+#endif
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({                     \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);   \
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#ifndef INIT_WORK
+#define work_struct tq_struct
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+#define schedule_work(a)   queue_task(a, &tq_scheduler)
+#else
+#define schedule_work(a)  schedule_task(a)
+#endif
+
+#define flush_scheduled_work  flush_scheduled_tasks
+#define INIT_WORK2(_wq, _routine)  INIT_TQUEUE(_wq, (void (*)(void *))_routine, _wq)
+#endif
+
+#else // >= 2.5 kernel
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#define INIT_WORK2(_wq, _routine)      INIT_WORK(_wq, (void (*)(void *))_routine, _wq)
+#else
+#define INIT_WORK2(_wq, _routine)      INIT_WORK(_wq, _routine)
+#endif
+
+#endif // >= 2.5 kernel
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38))
+typedef struct device netdevice_t;
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4))
+typedef struct net_device netdevice_t;
+#else
+#undef netdevice_t
+typedef struct net_device netdevice_t;
+#endif
+
+#ifdef WIRELESS_EXT
+#if (WIRELESS_EXT < 13)
+struct iw_request_info
+{
+        __u16           cmd;            /* Wireless Extension command */
+        __u16           flags;          /* More to come ;-) */
+};
+#endif
+#endif
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,18))
+#define MODULE_PARM(a,b)        extern int __bogus_decl
+#define MODULE_AUTHOR(a)        extern int __bogus_decl
+#define MODULE_DESCRIPTION(a)   extern int __bogus_decl
+#define MODULE_SUPPORTED_DEVICE(a) extern int __bogus_decl
+#undef  GET_USE_COUNT
+#define GET_USE_COUNT(m)        mod_use_count_
+#endif
+
+#ifndef MODULE_OWNER
+#define MODULE_OWNER(a)         extern int __bogus_decl
+#define ANCIENT_MODULE_CODE
+#endif
+
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(m)       extern int __bogus_decl
+#endif
+
+/* TODO:  Do we care about this? */
+#ifndef MODULE_DEVICE_TABLE
+#define MODULE_DEVICE_TABLE(foo,bar)
+#endif
+
+#define wlan_minutes2ticks(a) ((a)*(wlan_ticks_per_sec *  60))
+#define wlan_seconds2ticks(a) ((a)*(wlan_ticks_per_sec))
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47))
+#define NEW_MODULE_CODE
+#ifdef ANCIENT_MODULE_CODE
+#undef ANCIENT_MODULE_CODE
+#endif
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25))
+#define module_param(name, type, perm)                                       \
+        static inline void *__check_existence_##name(void) { return &name; } \
+        MODULE_PARM(name, _MODULE_PARM_STRING_ ## type)
+
+#define _MODULE_PARM_STRING_byte "b"
+#define _MODULE_PARM_STRING_short "h"
+#define _MODULE_PARM_STRING_ushort "h"
+#define _MODULE_PARM_STRING_int "i"
+#define _MODULE_PARM_STRING_uint "i"
+#define _MODULE_PARM_STRING_long "l"
+#define _MODULE_PARM_STRING_ulong "l"
+#define _MODULE_PARM_STRING_bool "i"
+#endif
+
+/* linux < 2.5.69 */
+#ifndef IRQ_NONE
+typedef void irqreturn_t;
+#define IRQ_NONE
+#define IRQ_HANDLED
+#define IRQ_RETVAL(x)
+#endif
+
+#ifndef in_atomic
+#define in_atomic()  0
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
+#define URB_ASYNC_UNLINK 0
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
+#define URB_ASYNC_UNLINK  USB_ASYNC_UNLINK
+#define usb_fill_bulk_urb  FILL_BULK_URB
+#define usb_kill_urb  usb_unlink_urb
+#else
+#define USB_QUEUE_BULK 0
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11))
+typedef u32 pm_message_t;
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9))
+#define hotplug_path  "/etc/hotplug/wlan.agent"
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#define free_netdev(x)       kfree(x)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
+#define eth_hdr(x)           (x)->mac.ethernet
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+#define del_timer_sync(a)       del_timer(a)
+#endif
+
+#ifndef might_sleep
+#define might_sleep(a)   do { } while (0)
+#endif
+
+/* Apparently 2.4.2 ethtool is quite different, maybe newer too? */
+#if (defined(SIOETHTOOL) && !defined(ETHTOOL_GDRVINFO))
+#undef SIOETHTOOL
+#endif
+
+// pcmcia-cs stuff
+#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) && \
+     !defined(pcmcia_access_configuration_register))
+#define pcmcia_access_configuration_register(handle, reg) \
+        CardServices(AccessConfigurationRegister, handle, reg)
+#define pcmcia_register_client(handle, reg) \
+        CardServices(RegisterClient, handle, reg)
+#define pcmcia_deregister_client(handle) \
+        CardServices(DeregisterClient, handle)
+#define pcmcia_get_first_tuple(handle, tuple) \
+        CardServices(GetFirstTuple, handle, tuple)
+#define pcmcia_get_next_tuple(handle, tuple) \
+        CardServices(GetNextTuple, handle, tuple)
+#define pcmcia_get_tuple_data(handle, tuple) \
+        CardServices(GetTupleData, handle, tuple)
+#define pcmcia_parse_tuple(handle, tuple, parse) \
+        CardServices(ParseTuple, handle, tuple, parse)
+#define pcmcia_get_configuration_info(handle, config) \
+        CardServices(GetConfigurationInfo, handle, config)
+#define pcmcia_request_io(handle, req) \
+        CardServices(RequestIO, handle, req)
+#define pcmcia_request_irq(handle, req) \
+        CardServices(RequestIRQ, handle, req)
+#define pcmcia_request_configuration(handle, req) \
+        CardServices(RequestConfiguration, handle, req)
+#define pcmcia_release_configuration(handle) \
+        CardServices(ReleaseConfiguration, handle)
+#define pcmcia_release_io(handle, req) \
+        CardServices(ReleaseIO, handle, req)
+#define pcmcia_release_irq(handle, req) \
+        CardServices(ReleaseIRQ, handle, req)
+#define pcmcia_release_window(win) \
+        CardServices(ReleaseWindow, win)
+#define pcmcia_get_card_services_info(info) \
+        CardServices(GetCardServicesInfo, info)
+#define pcmcia_report_error(handle, err) \
+        CardServices(ReportError, handle, err)
+#endif
+
+#endif /* __KERNEL__ */
+
+/*=============================================================*/
+/*------ Hardware Portability Macros --------------------------*/
+/*=============================================================*/
+
+#define ieee2host16(n) __le16_to_cpu(n)
+#define ieee2host32(n) __le32_to_cpu(n)
+#define host2ieee16(n) __cpu_to_le16(n)
+#define host2ieee32(n) __cpu_to_le32(n)
+
+#if (WLAN_CPU_FAMILY != WLAN_MIPS)
+typedef UINT32 phys_t;
+#endif
+
+#if (WLAN_CPU_FAMILY == WLAN_PPC)
+       #define wlan_inw(a)                     in_be16((unsigned short *)((a)+_IO_BASE))
+       #define wlan_inw_le16_to_cpu(a)         inw((a))
+       #define wlan_outw(v,a)                  out_be16((unsigned short *)((a)+_IO_BASE), (v))
+       #define wlan_outw_cpu_to_le16(v,a)      outw((v),(a))
+#else
+       #define wlan_inw(a)                     inw((a))
+       #define wlan_inw_le16_to_cpu(a)         __cpu_to_le16(inw((a)))
+       #define wlan_outw(v,a)                  outw((v),(a))
+       #define wlan_outw_cpu_to_le16(v,a)      outw(__cpu_to_le16((v)),(a))
+#endif
+
+/*=============================================================*/
+/*--- General Macros ------------------------------------------*/
+/*=============================================================*/
+
+#define wlan_max(a, b) (((a) > (b)) ? (a) : (b))
+#define wlan_min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define wlan_isprint(c)        (((c) > (0x19)) && ((c) < (0x7f)))
+
+#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a)))
+
+/* Create a string of printable chars from something that might not be */
+/* It's recommended that the str be 4*len + 1 bytes long */
+#define wlan_mkprintstr(buf, buflen, str, strlen) \
+{ \
+       int i = 0; \
+       int j = 0; \
+       memset(str, 0, (strlen)); \
+       for (i = 0; i < (buflen); i++) { \
+               if ( wlan_isprint((buf)[i]) ) { \
+                       (str)[j] = (buf)[i]; \
+                       j++; \
+               } else { \
+                       (str)[j] = '\\'; \
+                       (str)[j+1] = 'x'; \
+                       (str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \
+                       (str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \
+                       j += 4; \
+               } \
+       } \
+}
+
+/*=============================================================*/
+/*--- Variables -----------------------------------------------*/
+/*=============================================================*/
+
+#ifdef WLAN_INCLUDE_DEBUG
+extern int wlan_debug;
+#endif
+
+extern int wlan_ethconv;               /* What's the default ethconv? */
+
+/*=============================================================*/
+/*--- Functions -----------------------------------------------*/
+/*=============================================================*/
+#endif /* _WLAN_COMPAT_H */
+